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 interned_string empty_string;
8936
8937 if (!t)
8938 return empty_string;
8939
8940 const decl_base* d = dynamic_cast<const decl_base*>(t);
8941 if (!d)
8942 {
8943 const function_type* fn_type = is_function_type(t);
8944 if (!fn_type)
8945 return empty_string;
8946 return fn_type->get_cached_name(internal);
8947 }
8948
8949 const environment&env = d->get_environment();
8950
8951 // All anonymous types of a given kind get to have the same internal
8952 // name for internal purpose. This to allow them to be compared
8953 // among themselves during type canonicalization.
8954 if (internal)
8955 {
8956 if (d->get_is_anonymous() && !is_type_decl(t))
8957 {
8958 // Note that anonymous type_decl that are used for
8959 // enumerators are not handled here because they don't have
8960 // generic internal type names.
8961 string r;
8962 r += get_generic_anonymous_internal_type_name(d);
8963 return t->get_environment().intern(r);
8964 }
8965
8966 if (is_typedef(t))
8967 return d->get_name();
8968
8969 if (qualified)
8970 return d->get_qualified_name(internal);
8971
8972 return env.intern(get_internal_real_type_name(t));
8973 }
8974
8975 if (d->get_is_anonymous())
8976 {
8978 return env.intern
8980 /*one_line=*/true,
8981 internal, qualified));
8982 }
8983
8984 if (qualified)
8985 return d->get_qualified_name(internal);
8986 return d->get_name();
8987}
8988
8989/// Get the name of a given type and return a copy of it.
8990///
8991/// @param t the type to consider.
8992///
8993/// @param qualified if true then return the qualified name of the
8994/// type.
8995///
8996/// @param internal set to true if the call is intended for an
8997/// internal use (for technical use inside the library itself), false
8998/// otherwise. If you don't know what this is for, then set it to
8999/// false.
9000///
9001/// @return a copy of the type name if the type has a name, or the
9002/// empty string if it does not.
9004get_type_name(const type_base& t, bool qualified, bool internal)
9005{return get_type_name(&t, qualified, internal);}
9006
9007/// Get the name of the pointer to a given type.
9008///
9009/// @param pointed_to_type the pointed-to-type to consider.
9010///
9011/// @param qualified this is true if the resulting name should be of a
9012/// pointer to a *fully-qualified* pointed-to-type.
9013///
9014/// @param internal true if the name is for libabigail-internal
9015/// purposes.
9016///
9017/// @return the name (string representation) of the pointer.
9020 bool qualified, bool internal)
9021{
9022 const environment& env = pointed_to_type.get_environment();
9023 string tn = get_type_name(pointed_to_type, qualified, internal);
9024 tn = tn + "*";
9025
9026 return env.intern(tn);
9027}
9028
9029/// Get the name of the reference to a given type.
9030///
9031/// @param pointed_to_type the pointed-to-type to consider.
9032///
9033/// @param qualified this is true if the resulting name should be of a
9034/// reference to a *fully-qualified* pointed-to-type.
9035///
9036/// @param internal true if the name is for libabigail-internal
9037/// purposes.
9038///
9039/// @return the name (string representation) of the reference.
9042 bool lvalue_reference,
9043 bool qualified, bool internal)
9044{
9045 const environment& env = pointed_to_type.get_environment();
9046
9047 string name = get_type_name(pointed_to_type, qualified, internal);
9048 if (lvalue_reference)
9049 name = name + "&";
9050 else
9051 name = name + "&&";
9052
9053 return env.intern(name);
9054}
9055
9056/// Get the name of a qualified type, given the underlying type and
9057/// its qualifiers.
9058///
9059/// @param underlying_type the underlying type to consider.
9060///
9061/// @param quals the CV qualifiers of the name.
9062///
9063/// @param qualified true if we should consider the fully qualified
9064/// name of @p underlying_type.
9065///
9066/// @param internal true if the result is to be used for
9067/// libabigail-internal purposes.
9068///
9069/// @return the name (string representation) of the qualified type.
9071get_name_of_qualified_type(const type_base_sptr& underlying_type,
9073 bool qualified, bool internal)
9074{
9075 const environment& env = underlying_type->get_environment();
9076
9077 string quals_repr = get_string_representation_of_cv_quals(quals);
9078 string name = get_type_name(underlying_type, qualified, internal);
9079
9080 if (quals_repr.empty() && internal)
9081 // We are asked to return the internal name, that might be used
9082 // for type canonicalization. For that canonicalization, we need
9083 // to make a difference between a no-op qualified type which
9084 // underlying type is foo (the qualified type is named "none
9085 // foo"), and the name of foo, which is just "foo".
9086 //
9087 // Please remember that this has to be kept in sync with what is
9088 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
9089 // change this code here, please change that code there too.
9090 quals_repr = "";
9091
9092 if (!quals_repr.empty())
9093 {
9094 if (is_pointer_type(peel_qualified_type(underlying_type))
9095 || is_reference_type(peel_qualified_type(underlying_type)))
9096 {
9097 name += " ";
9098 name += quals_repr;
9099 }
9100 else
9101 name = quals_repr + " " + name;
9102 }
9103
9104 return env.intern(name);
9105}
9106
9107/// Get the name of a given function type and return a copy of it.
9108///
9109/// @param fn_type the function type to consider.
9110///
9111/// @param internal set to true if the call is intended for an
9112/// internal use (for technical use inside the library itself), false
9113/// otherwise. If you don't know what this is for, then set it to
9114/// false.
9115///
9116/// @return a copy of the function type name
9119 bool internal)
9120{return get_function_type_name(fn_type.get(), internal);}
9121
9122/// Get the name of a given function type and return a copy of it.
9123///
9124/// @param fn_type the function type to consider.
9125///
9126/// @param internal set to true if the call is intended for an
9127/// internal use (for technical use inside the library itself), false
9128/// otherwise. If you don't know what this is for, then set it to
9129/// false.
9130///
9131/// @return a copy of the function type name
9134 bool internal)
9135{
9136 ABG_ASSERT(fn_type);
9137
9138 if (const method_type* method = is_method_type(fn_type))
9139 return get_method_type_name(method, internal);
9140
9141 return get_function_type_name(*fn_type, internal);
9142}
9143
9144/// Get the name of a given function type and return a copy of it.
9145///
9146/// @param fn_type the function type to consider.
9147///
9148/// @param internal set to true if the call is intended for an
9149/// internal use (for technical use inside the library itself), false
9150/// otherwise. If you don't know what this is for, then set it to
9151/// false.
9152///
9153/// @return a copy of the function type name
9156 bool internal)
9157{
9158 std::ostringstream o;
9159 // When the function name is used for internal purposes (e.g, for
9160 // canonicalization), we want its representation to stay the same,
9161 // regardless of typedefs. So let's strip typedefs from the return
9162 // type.
9163 type_base_sptr return_type = fn_type.get_return_type();
9164 const environment& env = fn_type.get_environment();
9165
9166 o << get_type_name(return_type, /*qualified=*/true, internal) << " ";
9167 stream_pretty_representation_of_fn_parms(fn_type, o,
9168 /*qualified=*/true,
9169 internal);
9170 return env.intern(o.str());
9171}
9172
9173/// Get the ID of a function, or, if the ID can designate several
9174/// different functions, get its pretty representation.
9175///
9176/// @param fn the function to consider
9177///
9178/// @return the function ID of pretty representation of @p fn.
9181{
9182 ABG_ASSERT(fn);
9183
9184 interned_string result = fn->get_environment().intern(fn->get_id());
9185
9186 if (const corpus *c = fn->get_corpus())
9187 {
9189 c->get_exported_decls_builder();
9190 if (b->fn_id_maps_to_several_fns(fn))
9191 result = fn->get_environment().intern(fn->get_pretty_representation());
9192 }
9193
9194 return result;
9195}
9196
9197/// Get the name of a given method type and return a copy of it.
9198///
9199/// @param fn_type the function type to consider.
9200///
9201/// @param internal set to true if the call is intended for an
9202/// internal use (for technical use inside the library itself), false
9203/// otherwise. If you don't know what this is for, then set it to
9204/// false.
9205///
9206/// @return a copy of the function type name
9209 bool internal)
9210{return get_method_type_name(fn_type.get(), internal);}
9211
9212/// Get the name of a given method type and return a copy of it.
9213///
9214/// @param fn_type the function type to consider.
9215///
9216/// @param internal set to true if the call is intended for an
9217/// internal use (for technical use inside the library itself), false
9218/// otherwise. If you don't know what this is for, then set it to
9219/// false.
9220///
9221/// @return a copy of the function type name
9224 bool internal)
9225{
9226 if (fn_type)
9227 return get_method_type_name(*fn_type, internal);
9228
9229 return interned_string();
9230}
9231
9232/// Get the name of a given method type and return a copy of it.
9233///
9234/// @param fn_type the function type to consider.
9235///
9236/// @param internal set to true if the call is intended for an
9237/// internal use (for technical use inside the library itself), false
9238/// otherwise. If you don't know what this is for, then set it to
9239/// false.
9240///
9241/// @return a copy of the function type name
9244 bool internal)
9245{
9246 std::ostringstream o;
9247 // When the function name is used for internal purposes (e.g, for
9248 // canonicalization), we want its representation to stay the same,
9249 // regardless of typedefs. So let's strip typedefs from the return
9250 // type.
9251 type_base_sptr return_type = fn_type.get_return_type();
9252
9253 const environment& env = fn_type.get_environment();
9254
9255 if (return_type)
9256 o << get_type_name(return_type, /*qualified=*/true, internal);
9257 else
9258 // There are still some abixml files out there in which "void"
9259 // can be expressed as an empty type.
9260 o << "void";
9261
9262 class_or_union_sptr class_type = fn_type.get_class_type();
9263 ABG_ASSERT(class_type);
9264
9265 o << " (" << class_type->get_qualified_name(internal) << "::*) ";
9266 stream_pretty_representation_of_fn_parms(fn_type, o,
9267 /*qualified=*/true,
9268 internal);
9269
9270 return env.intern(o.str());
9271}
9272
9273/// Build and return a copy of the pretty representation of an ABI
9274/// artifact that could be either a type of a decl.
9275///
9276/// param tod the ABI artifact to consider.
9277///
9278/// @param internal set to true if the call is intended for an
9279/// internal use (for technical use inside the library itself), false
9280/// otherwise. If you don't know what this is for, then set it to
9281/// false.
9282///
9283/// @return a copy of the pretty representation of an ABI artifact
9284/// that could be either a type of a decl.
9285string
9287{
9288 string result;
9289
9290 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9291 result = get_pretty_representation(t, internal);
9292 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9293 result = get_pretty_representation(d, internal);
9294 else
9295 // We should never reach this point
9296 abort();
9297
9298 return result;
9299}
9300
9301/// Build and return a copy of the pretty representation of an ABI
9302/// artifact that could be either a type of a decl.
9303///
9304/// param tod the ABI artifact to consider.
9305///
9306/// @param internal set to true if the call is intended for an
9307/// internal use (for technical use inside the library itself), false
9308/// otherwise. If you don't know what this is for, then set it to
9309/// false.
9310///
9311/// @return a copy of the pretty representation of an ABI artifact
9312/// that could be either a type of a decl.
9313string
9315{return get_pretty_representation(tod.get(), internal);}
9316
9317/// Get a copy of the pretty representation of a decl.
9318///
9319/// @param d the decl to consider.
9320///
9321/// @param internal set to true if the call is intended for an
9322/// internal use (for technical use inside the library itself), false
9323/// otherwise. If you don't know what this is for, then set it to
9324/// false.
9325///
9326/// @return the pretty representation of the decl.
9327string
9328get_pretty_representation(const decl_base* d, bool internal)
9329{
9330 if (!d)
9331 return "";
9332 return d->get_pretty_representation(internal);
9333}
9334
9335/// Get a copy of the pretty representation of a type.
9336///
9337/// @param d the type to consider.
9338///
9339/// @param internal set to true if the call is intended for an
9340/// internal use (for technical use inside the library itself), false
9341/// otherwise. If you don't know what this is for, then set it to
9342/// false.
9343///
9344/// @return the pretty representation of the type.
9345string
9346get_pretty_representation(const type_base* t, bool internal)
9347{
9348 if (!t)
9349 return "void";
9350 if (const function_type* fn_type = is_function_type(t))
9351 return get_pretty_representation(fn_type, internal);
9352
9353 const decl_base* d = get_type_declaration(t);
9354 ABG_ASSERT(d);
9355 return get_pretty_representation(d, internal);
9356}
9357
9358/// Get a copy of the pretty representation of a decl.
9359///
9360/// @param d the decl to consider.
9361///
9362/// @param internal set to true if the call is intended for an
9363/// internal use (for technical use inside the library itself), false
9364/// otherwise. If you don't know what this is for, then set it to
9365/// false.
9366///
9367/// @return the pretty representation of the decl.
9368string
9369get_pretty_representation(const decl_base_sptr& d, bool internal)
9370{return get_pretty_representation(d.get(), internal);}
9371
9372/// Get a copy of the pretty representation of a type.
9373///
9374/// @param d the type to consider.
9375///
9376/// @param internal set to true if the call is intended for an
9377/// internal use (for technical use inside the library itself), false
9378/// otherwise. If you don't know what this is for, then set it to
9379/// false.
9380///
9381/// @return the pretty representation of the type.
9382string
9383get_pretty_representation(const type_base_sptr& t, bool internal)
9384{return get_pretty_representation(t.get(), internal);}
9385
9386/// Get the pretty representation of a function type.
9387///
9388/// @param fn_type the function type to consider.
9389///
9390/// @param internal set to true if the call is intended for an
9391/// internal use (for technical use inside the library itself), false
9392/// otherwise. If you don't know what this is for, then set it to
9393/// false.
9394///
9395/// @return the string represenation of the function type.
9396string
9398 bool internal)
9399{return get_pretty_representation(fn_type.get(), internal);}
9400
9401/// Get the pretty representation of a function type.
9402///
9403/// @param fn_type the function type to consider.
9404///
9405/// @param internal set to true if the call is intended for an
9406/// internal use (for technical use inside the library itself), false
9407/// otherwise. If you don't know what this is for, then set it to
9408/// false.
9409///
9410/// @return the string represenation of the function type.
9411string
9412get_pretty_representation(const function_type* fn_type, bool internal)
9413{
9414 if (!fn_type)
9415 return "void";
9416
9417 if (const method_type* method = is_method_type(fn_type))
9418 return get_pretty_representation(method, internal);
9419
9420 return get_pretty_representation(*fn_type, internal);
9421}
9422
9423/// Get the pretty representation of a function type.
9424///
9425/// @param fn_type the function type to consider.
9426///
9427/// @param internal set to true if the call is intended for an
9428/// internal use (for technical use inside the library itself), false
9429/// otherwise. If you don't know what this is for, then set it to
9430/// false.
9431///
9432/// @return the string represenation of the function type.
9433string
9434get_pretty_representation(const function_type& fn_type, bool internal)
9435{
9436 std::ostringstream o;
9437 o << "function type " << get_function_type_name(fn_type, internal);
9438 return o.str();
9439}
9440
9441/// Get the pretty representation of a method type.
9442///
9443/// @param method the method type to consider.
9444///
9445/// @param internal set to true if the call is intended for an
9446/// internal use (for technical use inside the library itself), false
9447/// otherwise. If you don't know what this is for, then set it to
9448/// false.
9449///
9450/// @return the string represenation of the method type.
9451string
9452get_pretty_representation(const method_type& method, bool internal)
9453{
9454 std::ostringstream o;
9455 o << "method type " << get_method_type_name(method, internal);
9456 return o.str();
9457}
9458
9459/// Get the pretty representation of a method type.
9460///
9461/// @param method the method type to consider.
9462///
9463/// @param internal set to true if the call is intended for an
9464/// internal use (for technical use inside the library itself), false
9465/// otherwise. If you don't know what this is for, then set it to
9466/// false.
9467///
9468/// @return the string represenation of the method type.
9469string
9470get_pretty_representation(const method_type* method, bool internal)
9471{
9472 if (!method)
9473 return "void";
9474 return get_pretty_representation(*method, internal);
9475}
9476
9477/// Get the pretty representation of a method type.
9478///
9479/// @param method the method type to consider.
9480///
9481/// @param internal set to true if the call is intended for an
9482/// internal use (for technical use inside the library itself), false
9483/// otherwise. If you don't know what this is for, then set it to
9484/// false.
9485///
9486/// @return the string represenation of the method type.
9487string
9489{return get_pretty_representation(method.get(), internal);}
9490
9491/// Get the flat representation of an instance of @ref class_or_union
9492/// type.
9493///
9494/// The flat representation of a given @ref class_or_union type is the
9495/// actual definition of the type, for instance:
9496///
9497/// struct foo {int a; char b;}
9498///
9499///@param cou the instance of @ref class_or_union to consider.
9500///
9501///@param indent the identation spaces to use in the representation.
9502///
9503///@param one_line if true, then the flat representation stands on one
9504///line. Otherwise, it stands on multiple lines.
9505///
9506///@return the resulting flat representation.
9507string
9509 const string& indent,
9510 bool one_line,
9511 bool internal,
9512 bool qualified_names)
9513{
9514 string repr;
9515 string local_indent = " ";
9516
9517 if (class_decl* clazz = is_class_type(&cou))
9518 {
9519 repr = indent;
9520 if (!internal && clazz->is_struct())
9521 repr += "struct";
9522 else
9523 repr += "class";
9524 }
9525 else if (is_union_type(cou))
9526 repr = indent + "union";
9527 else
9528 return "";
9529
9530 repr += " ";
9531
9532 string name = cou.get_qualified_name();
9533
9534 if (!cou.get_is_anonymous())
9535 repr += name;
9536
9537 if (cou.priv_->is_printing_flat_representation())
9538 {
9539 // We have just detected a cycle while walking the sub-tree
9540 // of this class or union type for the purpose of printing
9541 // its flat representation. We need to get out of here
9542 // pronto or else we'll be spinning endlessly.
9543 repr += "{}";
9544 return repr;
9545 }
9546
9547 // Let's mark this class or union type to signify that we started
9548 // walking its sub-tree. This is to detect potential cycles and
9549 // avoid looping endlessly.
9551
9552 repr += "{";
9553
9554 if (!one_line)
9555 repr += "\n";
9556
9557 string real_indent;
9559 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9560 dm != dmems.end();
9561 ++dm)
9562 {
9563 if (dm != dmems.begin())
9564 {
9565 if (one_line)
9566 real_indent = " ";
9567 else
9568 real_indent = "\n" + indent + local_indent;
9569 }
9570
9572 repr +=
9575 real_indent, one_line, internal, qualified_names);
9576 else
9577 {
9578 if (one_line)
9579 {
9580 if (dm != dmems.begin())
9581 repr += real_indent;
9582 repr += (*dm)->get_pretty_representation(internal,
9583 qualified_names);
9584 }
9585 else
9586 repr +=
9587 real_indent+ (*dm)->get_pretty_representation(internal,
9588 qualified_names);
9589 }
9590 repr += ";";
9591 }
9592
9593 if (one_line)
9594 repr += "}";
9595 else
9596 repr += indent + "}";
9597
9598 // Let's unmark this class or union type to signify that we are done
9599 // walking its sub-tree. This was to detect potential cycles and
9600 // avoid looping endlessly.
9602
9603 return repr;
9604}
9605
9606/// Get the flat representation of an instance of @ref class_or_union
9607/// type.
9608///
9609/// The flat representation of a given @ref class_or_union type is the
9610/// actual definition of the type, for instance:
9611///
9612/// struct foo {int a; char b;}
9613///
9614///@param cou the instance of @ref class_or_union to consider.
9615///
9616///@param indent the identation spaces to use in the representation.
9617///
9618///@param one_line if true, then the flat representation stands on one
9619///line. Otherwise, it stands on multiple lines.
9620///
9621///@return the resulting flat representation.
9622string
9624 const string& indent,
9625 bool one_line,
9626 bool internal,
9627 bool qualified_names)
9628{
9629 if (cou)
9630 return get_class_or_union_flat_representation(*cou, indent, one_line,
9631 internal, qualified_names);
9632 return "";
9633}
9634
9635/// Get the flat representation of an instance of @ref class_or_union
9636/// type.
9637///
9638/// The flat representation of a given @ref class_or_union type is the
9639/// actual definition of the type, for instance:
9640///
9641/// struct foo {int a; char b;}
9642///
9643///@param cou the instance of @ref class_or_union to consider.
9644///
9645///@param indent the identation spaces to use in the representation.
9646///
9647///@param one_line if true, then the flat representation stands on one
9648///line. Otherwise, it stands on multiple lines.
9649///
9650///@return the resulting flat representation.
9651string
9652get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9653 const string& indent,
9654 bool one_line,
9655 bool internal,
9656 bool qualified_names)
9658 indent,
9659 one_line,
9660 internal,
9661 qualified_names);}
9662
9663/// Get the flat representation of an instance of @ref enum_type_decl
9664/// type.
9665///
9666/// The flat representation of a given @ref enum_type_decl type is the
9667/// actual definition of the type, for instance:
9668///
9669/// enum {E_0 =0, E_1 = 1}
9670///
9671///@param enum_type the enum type to consider.
9672///
9673///@param indent the identation spaces to use in the representation.
9674///
9675///@param one_line if true, then the flat representation stands on one
9676///line. Otherwise, it stands on multiple lines.
9677///
9678///@param qualified_names use qualified names when applicable.
9679///Typically, if this is true, the name of the enum is going to be
9680///qualified.
9681///
9682///@return the resulting flat representation.
9683string
9685 const string& indent, bool one_line,
9686 bool qualified_names)
9687{
9688 string repr;
9689 std::ostringstream o;
9690 string local_indent = " ";
9691
9692 repr = indent + "enum ";
9693
9694 if (!enum_type.get_is_anonymous())
9695 o << (qualified_names
9696 ? enum_type.get_qualified_name()
9697 : enum_type.get_name()) + " ";
9698
9699 o << "{";
9700
9701 if (!one_line)
9702 o << "\n";
9703
9704 for (const auto &enumerator : enum_type.get_sorted_enumerators())
9705 {
9706 if (!one_line)
9707 o << "\n" + indent;
9708
9709 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
9710 }
9711
9712 if (!one_line)
9713 o << "\n" + indent << "}";
9714 else
9715 o << "}";
9716
9717 repr =o.str();
9718
9719 return repr;
9720}
9721
9722/// Get the flat representation of an instance of @ref enum_type_decl
9723/// type.
9724///
9725/// The flat representation of a given @ref enum_type_decl type is the
9726/// actual definition of the type, for instance:
9727///
9728/// enum {E_0 =0, E_1 = 1}
9729///
9730///@param enum_type the enum type to consider.
9731///
9732///@param indent the identation spaces to use in the representation.
9733///
9734///@param one_line if true, then the flat representation stands on one
9735///line. Otherwise, it stands on multiple lines.
9736///
9737///@param qualified_names use qualified names when applicable.
9738///Typically, if this is true, the name of the enum is going to be
9739///qualified.
9740///
9741///@return the resulting flat representation.
9742string
9744 const string& indent, bool one_line,
9745 bool qualified_names)
9746{
9747 if (!enum_type)
9748 return "";
9749
9750 return get_enum_flat_representation(*enum_type, indent,
9751 one_line, qualified_names);
9752}
9753
9754/// Get the flat representation of an instance of @ref enum_type_decl
9755/// type.
9756///
9757/// The flat representation of a given @ref enum_type_decl type is the
9758/// actual definition of the type, for instance:
9759///
9760/// enum {E_0 =0, E_1 = 1}
9761///
9762///@param enum_type the enum type to consider.
9763///
9764///@param indent the identation spaces to use in the representation.
9765///
9766///@param one_line if true, then the flat representation stands on one
9767///line. Otherwise, it stands on multiple lines.
9768///
9769///@param qualified_names use qualified names when applicable.
9770///Typically, if this is true, the name of the enum is going to be
9771///qualified.
9772///
9773///@return the resulting flat representation.
9774string
9776 const string& indent, bool one_line,
9777 bool qualified_names)
9778{
9779 return get_enum_flat_representation(enum_type.get(),
9780 indent, one_line,
9781 qualified_names);
9782}
9783
9784/// Get the flat representation of an instance of @ref enum_type_decl
9785/// type.
9786///
9787/// The flat representation of a given @ref enum_type_decl type is the
9788/// actual definition of the type, for instance:
9789///
9790/// enum {E_0 =0, E_1 = 1}
9791///
9792///@param enum_type the enum type to consider.
9793///
9794///@param indent the identation spaces to use in the representation.
9795///
9796///@param one_line if true, then the flat representation stands on one
9797///line. Otherwise, it stands on multiple lines.
9798///
9799///@param qualified_names use qualified names when applicable.
9800///Typically, if this is true, the name of the enum is going to be
9801///qualified.
9802///
9803///@return the resulting flat representation.
9804string
9806 const string& indent,
9807 bool one_line,
9808 bool internal,
9809 bool qualified_name)
9810
9811{
9812 string repr;
9813 if (const class_or_union* cou = is_class_or_union_type(&coe))
9814 repr = get_class_or_union_flat_representation(cou, indent, one_line,
9815 internal, qualified_name);
9816 else if (const enum_type_decl* enom = is_enum_type(&coe))
9817 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9818
9819 return repr;
9820}
9821
9822/// Get the textual representation of a type for debugging purposes.
9823///
9824/// If the type is a class/union, this shows the data members, virtual
9825/// member functions, size, pointer value of its canonical type, etc.
9826/// Otherwise, this just shows the name of the artifact as returned by
9827/// type_or_decl_base:get_pretty_representation().
9828///
9829/// @param artifact the artifact to show a debugging representation of.
9830///
9831/// @return a debugging string representation of @p artifact.
9832string
9834{
9835 string nil_str;
9836 if (!artifact)
9837 return nil_str;
9838
9839 class_or_union * c = is_class_or_union_type(artifact);
9840 if (c)
9841 {
9842 class_decl *clazz = is_class_type(c);
9843 string name = c->get_qualified_name();
9844 std::ostringstream o;
9845 if (clazz)
9846 {
9847 if (clazz->is_struct())
9848 o << "struct ";
9849 else
9850 o << "class ";
9851 }
9852 else if (is_union_type(c))
9853 o << "union ";
9854 o << name;
9855
9856 if (clazz)
9857 {
9858 if (!clazz->get_base_specifiers().empty())
9859 o << " :" << std::endl;
9860 for (auto &b : clazz->get_base_specifiers())
9861 {
9862 o << " ";
9863 if (b->get_is_virtual())
9864 o << "virtual ";
9865 o << b->get_base_class()->get_qualified_name()
9866 << " // hash: ";
9867 hash_t h = peek_hash_value(*b->get_base_class());
9868 if (h)
9869 o << std::hex << *h << std::dec;
9870 else
9871 o << "none";
9872 o << std::endl;
9873 }
9874 }
9875 o << std::endl
9876 << "{"
9877 << " // size in bits: " << c->get_size_in_bits() << "\n"
9878 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9879 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9880 << " // translation unit: "
9881 << (c->get_translation_unit()
9883 : nil_str)
9884 << std::endl
9885 << " // @: " << std::hex << is_type(c)
9886 << ", @canonical: " << c->get_canonical_type().get() << std::dec << "\n"
9887 << " // hash: " ;
9888
9889 hash_t h = peek_hash_value(*c);
9890 if (h)
9891 o << std::hex << *h << std::dec;
9892 else
9893 o << "none";
9894 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*c);
9895 o << "\n\n";
9896
9897
9898 for (auto member_type : c->get_sorted_member_types())
9899 {
9900 o << " "
9901 << member_type->get_pretty_representation(/*internal=*/false,
9902 /*qualified=*/false)
9903 << ";";
9904 if (member_type->get_canonical_type())
9905 {
9906 o << " // uses canonical type: '@"
9907 << std::hex << member_type->get_canonical_type().get() << "'";
9908 o << " / h:";
9909 hash_t h = peek_hash_value(*member_type);
9910 o << std::hex << *h << std::dec;
9911 if (get_canonical_type_index(*member_type))
9912 o << "#" << get_canonical_type_index(*member_type);
9913 }
9914 o << "\n";
9915 }
9916
9917 if (!c->get_sorted_member_types().empty())
9918 o << std::endl;
9919
9920 for (auto m : c->get_data_members())
9921 {
9922 type_base_sptr t = m->get_type();
9924
9925 o << " "
9926 << m->get_pretty_representation(/*internal=*/false,
9927 /*qualified=*/false)
9928 << ";";
9929
9930 if (t && t->get_canonical_type())
9931 o << " // uses canonical type '@"
9932 << std::hex << t->get_canonical_type().get() << "'";
9933
9934 o << "/ h:";
9935 hash_t h = peek_hash_value(*m->get_type());
9936 if (h)
9937 o << std::hex << *h << std::dec;
9938 else
9939 o << "none";
9940 o << std::endl;
9941 }
9942
9943 if (!c->get_data_members().empty())
9944 o << std::endl;
9945
9946 if (clazz && clazz->has_vtable())
9947 {
9948 o << " // virtual member functions\n\n";
9949 for (auto f : clazz->get_virtual_mem_fns())
9950 {
9951 o << " " << f->get_pretty_representation(/*internal=*/false,
9952 /*qualified=*/false)
9953 << " // voffset: " << get_member_function_vtable_offset(f)
9954 << ", h: ";
9955 hash_t h = peek_hash_value(*f->get_type());
9956 if (h)
9957 o << std::hex << *h << std::dec;
9958 else
9959 o << "none";
9960 o << ";" << std::endl;
9961 }
9962 }
9963
9964 o << "};" << std::endl;
9965
9966 return o.str();
9967 }
9968 else if (const enum_type_decl* e = is_enum_type(artifact))
9969 {
9970 string name = e->get_qualified_name();
9971 std::ostringstream o;
9972 o << "enum " << name
9973 << " : "
9974 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9975 true)
9976 << "\n"
9977 << "{\n"
9978 << " // size in bits: " << e->get_size_in_bits() << "\n"
9979 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9980 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9981 << " // translation unit: "
9982 << e->get_translation_unit()->get_absolute_path() << "\n"
9983 << " // @: " << std::hex << is_type(e)
9984 << ", @canonical: " << e->get_canonical_type().get() << std::dec << "\n"
9985 << " // hash: ";
9986
9987 hash_t h = peek_hash_value(*e);
9988 if (h)
9989 o << std::hex << *h << std::dec;
9990 else
9991 o << "none";
9992 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*e);
9993 o << "\n\n";
9994
9995 for (const auto &enom : e->get_enumerators())
9996 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9997
9998 o << "};\n";
9999
10000 return o.str();
10001 }
10002 else if (type_base *t = is_type(artifact))
10003 {
10004 std::ostringstream o;
10005 o << t->get_pretty_representation(/*internal=*/true,
10006 /*qualified=*/true)
10007 << " // cti: " << get_canonical_type_index(*t)
10008 << "\n";
10009 return o.str();
10010 }
10011
10012 return artifact->get_pretty_representation(/*internal=*/true,
10013 /*qualified=*/true);
10014}
10015
10016/// Get a given data member, referred to by its name, of a class type.
10017///
10018/// @param clazz the class to consider.
10019///
10020/// @param member_name name of the data member to get.
10021///
10022/// @return the resulting data member or nullptr if none was found.
10024get_data_member(class_or_union *clazz, const char* member_name)
10025{
10026 if (!clazz)
10027 return var_decl_sptr();
10028 return clazz->find_data_member(member_name);
10029}
10030
10031/// Get a given data member, referred to by its name, of a class type.
10032///
10033/// @param clazz the class to consider.
10034///
10035/// @param member_name name of the data member to get.
10036///
10037/// @return the resulting data member or nullptr if none was found.
10039get_data_member(type_base *clazz, const char* member_name)
10040{return get_data_member(is_class_or_union_type(clazz), member_name);}
10041
10042/// Get the non-artificial (natural) location of a decl.
10043///
10044/// If the decl doesn't have a natural location then return its
10045/// artificial one.
10046///
10047/// @param decl the decl to consider.
10048///
10049/// @return the natural location @p decl if it has one; otherwise,
10050/// return its artificial one.
10051const location&
10053{
10054 ABG_ASSERT(decl);
10055
10056 if (decl->get_location())
10057 return decl->get_location();
10058 return decl->get_artificial_location();
10059}
10060
10061/// Get the artificial location of a decl.
10062///
10063/// If the decl doesn't have an artificial location then return its
10064/// natural one.
10065///
10066/// @param decl the decl to consider.
10067///
10068/// @return the artificial location @p decl if it has one; otherwise,
10069/// return its natural one.
10070const location&
10072{
10073 ABG_ASSERT(decl);
10074
10075 if (decl->has_artificial_location())
10076 return decl->get_artificial_location();
10077 return decl->get_location();
10078}
10079
10080/// Emit a textual representation of an artifact to std error stream
10081/// for debugging purposes.
10082///
10083/// This is useful to invoke from within a command line debugger like
10084/// GDB to help make sense of a given ABI artifact.
10085///
10086/// @param artifact the ABI artifact to emit the debugging
10087/// representation for.
10088///
10089/// @return the artifact @p artifact.
10091debug(const type_or_decl_base* artifact)
10092{
10093 std::cerr << get_debug_representation(artifact) << std::endl;
10094 return const_cast<type_or_decl_base*>(artifact);
10095}
10096
10097/// Emit a textual representation of an artifact to std error stream
10098/// for debugging purposes.
10099///
10100/// This is useful to invoke from within a command line debugger like
10101/// GDB to help make sense of a given ABI artifact.
10102///
10103/// @param artifact the ABI artifact to emit the debugging
10104/// representation for.
10105///
10106/// @return the artifact @p artifact.
10107type_base*
10108debug(const type_base* artifact)
10109{
10110 debug(static_cast<const type_or_decl_base*>(artifact));
10111 return const_cast<type_base*>(artifact);
10112}
10113
10114/// Emit a textual representation of an artifact to std error stream
10115/// for debugging purposes.
10116///
10117/// This is useful to invoke from within a command line debugger like
10118/// GDB to help make sense of a given ABI artifact.
10119///
10120/// @param artifact the ABI artifact to emit the debugging
10121/// representation for.
10122///
10123/// @return the artifact @p artifact.
10124decl_base*
10125debug(const decl_base* artifact)
10126{
10127 debug(static_cast<const type_or_decl_base*>(artifact));
10128 return const_cast<decl_base*>(artifact);
10129}
10130
10131/// Test if two ABI artifacts are equal.
10132///
10133/// This can be useful when used from the command line of a debugger
10134/// like GDB.
10135///
10136/// @param l the first ABI artifact to consider in the comparison.
10137///
10138/// @param r the second ABI artifact to consider in the comparison.
10139///
10140/// @return true iff @p l equals @p r.
10141bool
10143{
10144 if (!!l != !!r)
10145 return false;
10146 if (!l && !r)
10147 return true;
10148
10149 return (*l == *r);
10150}
10151
10152/// Emit a trace of a comparison operand stack.
10153///
10154/// @param vect the operand stack to emit the trace for.
10155///
10156/// @param o the output stream to emit the trace to.
10157static void
10158debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
10159{
10160 for (auto t : vect)
10161 {
10162 o << "|" << t->get_pretty_representation()
10163 << "@" << std::hex << t << std::dec;
10164 }
10165 if (!vect.empty())
10166 o << "|";
10167}
10168
10169/// Construct a trace of the two comparison operand stacks.
10170///
10171/// @param the environment in which the comparison operand stacks are.
10172///
10173/// @return a string representing the trace.
10174static string
10175print_comp_stack(const environment& env)
10176{
10177 std::ostringstream o;
10178 o << "left-operands: ";
10179 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
10180 o << "\n" << "right-operands: ";
10181 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10182 o << "\n";
10183 return o.str();
10184}
10185
10186/// Emit a trace of the two comparison operands stack on the standard
10187/// error stream.
10188///
10189/// @param env the environment the comparison operands stack belong
10190/// to.
10191void
10193{
10194 std::cerr << print_comp_stack(env);
10195 std::cerr << std::endl;
10196}
10197
10198/// By looking at the language of the TU a given ABI artifact belongs
10199/// to, test if the ONE Definition Rule should apply.
10200///
10201/// To date, it applies to c++, java and ada.
10202///
10203/// @param artifact the ABI artifact to consider.
10204///
10205/// @return true iff the One Definition Rule should apply.
10206bool
10208{
10209 if (!artifact.get_translation_unit())
10210 return false;
10211
10213 artifact.get_translation_unit()->get_language();
10214
10216 || is_java_language(l)
10217 || is_ada_language(l))
10218 return true;
10219
10220 return false;
10221}
10222
10223/// Get the declaration for a given type.
10224///
10225/// @param t the type to consider.
10226///
10227/// @return the declaration for the type to return.
10228const decl_base*
10230{return dynamic_cast<const decl_base*>(t);}
10231
10232/// Get the declaration for a given type.
10233///
10234/// @param t the type to consider.
10235///
10236/// @return the declaration for the type to return.
10237decl_base*
10239{return dynamic_cast<decl_base*>(t);}
10240
10241/// Get the declaration for a given type.
10242///
10243/// @param t the type to consider.
10244///
10245/// @return the declaration for the type to return.
10246decl_base_sptr
10247get_type_declaration(const type_base_sptr t)
10248{return dynamic_pointer_cast<decl_base>(t);}
10249
10250/// Test if two classes have the same layout.
10251///
10252/// Test if all the types and offsets of the members are equal,
10253/// regardless of their access modifiers.
10254///
10255/// @param f the first class to take into account.
10256///
10257/// @param s the second class to take into account.
10258///
10259/// @return true iff @p s and @p f are class types with the same
10260/// layout.
10261bool
10262classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
10263{
10266
10267 if (!fc
10268 || !sc
10269 || (fc->get_qualified_name() != sc->get_qualified_name())
10270 || (fc->get_size_in_bits() != sc->get_size_in_bits())
10271 || (fc->get_data_members().size() != sc->get_data_members().size()))
10272 return false;
10273
10274 if (*fc == *sc)
10275 return true;
10276
10277 // Compare the types and offsets of data members one by one.
10278 for (auto f_decl_it = fc->get_data_members().begin(),
10279 s_decl_it = sc->get_data_members().begin();
10280 (f_decl_it != fc->get_data_members().end()
10281 && s_decl_it != sc->get_data_members().end());
10282 ++f_decl_it, ++s_decl_it)
10283 {
10284 var_decl_sptr dm1 = *f_decl_it, dm2 = *s_decl_it;
10285 type_base_sptr dm1_type = dm1->get_type(), dm2_type = dm2->get_type();
10286
10287 if (*dm1_type != *dm2_type
10289 return false;
10290 }
10291
10292 // Compare the layout of base types
10293 for (auto f_bs_it = fc->get_base_specifiers().begin(),
10294 s_bs_it = sc->get_base_specifiers().end();
10295 (f_bs_it != fc->get_base_specifiers().end()
10296 && s_bs_it != sc->get_base_specifiers().end());
10297 ++f_bs_it, ++s_bs_it)
10298 {
10299 class_decl::base_spec_sptr f_bs = *f_bs_it, s_bs = *s_bs_it;
10300 if ((f_bs->get_is_virtual() != s_bs->get_is_virtual())
10301 || (f_bs->get_offset_in_bits() != s_bs->get_offset_in_bits()))
10302 return false;
10303
10304 class_decl_sptr fb = f_bs->get_base_class(), sb = s_bs->get_base_class();
10305 if (!classes_have_same_layout(fb, sb))
10306 return false;
10307 }
10308
10309 if (fc->has_vtable() != sc->has_vtable())
10310 return false;
10311
10312 // Compare virtual function types
10313 if (fc->has_vtable())
10314 {
10315 if (fc->get_virtual_mem_fns().size() > sc->get_virtual_mem_fns().size())
10316 // Some virtual member function got removed. Bad.
10317 return false;
10318
10319 for (auto it1 = fc->get_virtual_mem_fns().begin(),
10320 it2 = sc->get_virtual_mem_fns().begin();
10321 (it1 != fc->get_virtual_mem_fns().end()
10322 && it2 != sc->get_virtual_mem_fns().end());
10323 ++it1, ++it2)
10324 {
10325 method_decl_sptr method1 = *it1;
10326 method_decl_sptr method2 = *it2;
10327
10330 || types_are_compatible(method1->get_type(),
10331 method2->get_type()))
10332 return false;
10333 }
10334 }
10335
10336 return true;
10337}
10338
10339/// Test if two types are equal modulo a typedef or CV qualifiers.
10340///
10341/// Type A and B are compatible if
10342///
10343/// - A and B are equal
10344/// - or A and B are integral types with harmless name change
10345/// - or if one type is a typedef of the other one.
10346/// - or if one type is the CV qualified version of the other
10347/// - or if A and B are classes with the same layout.
10348/// - or if A and B are pointers, references or arrays of
10349/// compatible types
10350///
10351/// @param type1 the first type to consider.
10352///
10353/// @param type2 the second type to consider.
10354///
10355/// @return true iff @p type1 and @p type2 are compatible.
10356bool
10357types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
10358{
10359 if (!type1 || !type2)
10360 return false;
10361
10362 if (type1 == type2 || *type1 == *type2)
10363 return true;
10364
10365 type_base_sptr t1 = peel_qualified_or_typedef_type(type1);
10366 type_base_sptr t2 = peel_qualified_or_typedef_type(type2);
10367
10368 if (t1 && t2 && *t1 == *t2)
10369 return true;
10370
10372 return true;
10373
10374 if (is_pointer_type(t1) && is_pointer_type(t2))
10375 {
10376 t1 = is_pointer_type(t1)->get_pointed_to_type();
10377 t2 = is_pointer_type(t2)->get_pointed_to_type();
10378 return types_are_compatible(t1, t2);
10379 }
10380
10381 if (is_reference_type(t1) && is_reference_type(t2))
10382 {
10383 t1 = is_reference_type(t1)->get_pointed_to_type();
10384 t2 = is_reference_type(t2)->get_pointed_to_type();
10385 return types_are_compatible(t1, t2);
10386 }
10387
10388 if (is_array_type(t1) && is_array_type(t2))
10389 {
10392 type_base_sptr e1 = a1->get_element_type();
10393 type_base_sptr e2 = a2->get_element_type();
10396
10397 if ((a1->get_size_in_bits() != a2->get_size_in_bits())
10398 || (a1->get_dimension_count() != a2->get_dimension_count())
10399 || !types_are_compatible(e1, e2))
10400 return false;
10401
10402 return true;
10403 }
10404
10405 if (function_type_sptr fn_type1 = is_function_type(t1))
10406 if (function_type_sptr fn_type2 = is_function_type(t2))
10407 {
10408 // Compare return types
10409 if (!types_are_compatible(fn_type1->get_return_type(),
10410 fn_type2->get_return_type()))
10411 return false;
10412
10413 // Compare parameter types, omitting the implicit parameter to
10414 // avoid infinite recursion when we are being called from
10415 // classes_have_same_layout on classes with virtual member
10416 // functions.
10417 if (fn_type1->get_parameters().size()
10418 != fn_type2->get_parameters().size())
10419 return false;
10420
10421 for (auto p1 = fn_type1->get_first_non_implicit_parm(),
10422 p2 = fn_type2->get_first_non_implicit_parm();
10423 (p1 != fn_type1->get_parameters().end()
10424 && p2 != fn_type2->get_parameters().end());
10425 ++p1, ++p2)
10426 if (!types_are_compatible((*p1)->get_type(),
10427 (*p2)->get_type()))
10428 return false;
10429 }
10430
10431 if (classes_have_same_layout(t1, t2))
10432 return true;
10433
10434 return false;
10435}
10436
10437/// Test if two types are equal modulo a typedef.
10438///
10439/// Type A and B are compatible if
10440///
10441/// - A and B are equal
10442/// - or if one type is a typedef of the other one.
10443///
10444/// @param type1 the declaration of the first type to consider.
10445///
10446/// @param type2 the declaration of the second type to consider.
10447///
10448/// @return true iff @p type1 and @p type2 are compatible.
10449bool
10450types_are_compatible(const decl_base_sptr d1,
10451 const decl_base_sptr d2)
10452{return types_are_compatible(is_type(d1), is_type(d2));}
10453
10454/// Return the translation unit a declaration belongs to.
10455///
10456/// @param decl the declaration to consider.
10457///
10458/// @return the resulting translation unit, or null if the decl is not
10459/// yet added to a translation unit.
10462{
10463 translation_unit* result =
10464 const_cast<translation_unit*>(t.get_translation_unit());
10465
10466 if (result)
10467 return result;
10468
10469 if (decl_base* decl = is_decl(&t))
10470 {
10471 scope_decl* scope = decl->get_scope();
10472 while (scope)
10473 {
10474 result = scope->get_translation_unit();
10475 if (result)
10476 break;
10477 scope = scope->get_scope();
10478 }
10479 }
10480
10481 return result;
10482}
10483
10484/// Return the translation unit a declaration belongs to.
10485///
10486/// @param decl the declaration to consider.
10487///
10488/// @return the resulting translation unit, or null if the decl is not
10489/// yet added to a translation unit.
10492{return decl ? get_translation_unit(*decl) : nullptr;}
10493
10494/// Return the translation unit a declaration belongs to.
10495///
10496/// @param decl the declaration to consider.
10497///
10498/// @return the resulting translation unit, or null if the decl is not
10499/// yet added to a translation unit.
10502{return get_translation_unit(decl.get());}
10503
10504/// Tests whether if a given scope is the global scope.
10505///
10506/// @param scope the scope to consider.
10507///
10508/// @return true iff the current scope is the global one.
10509bool
10511{return !!dynamic_cast<const global_scope*>(&scope);}
10512
10513/// Tests whether if a given scope is the global scope.
10514///
10515/// @param scope the scope to consider.
10516///
10517/// @return the @ref global_scope* representing the scope @p scope or
10518/// 0 if @p scope is not a global scope.
10519const global_scope*
10521{return dynamic_cast<const global_scope*>(scope);}
10522
10523/// Tests whether if a given scope is the global scope.
10524///
10525/// @param scope the scope to consider.
10526///
10527/// @return true iff the current scope is the global one.
10528bool
10529is_global_scope(const shared_ptr<scope_decl>scope)
10530{return is_global_scope(scope.get());}
10531
10532/// Tests whether a given declaration is at global scope.
10533///
10534/// @param decl the decl to consider.
10535///
10536/// @return true iff decl is at global scope.
10537bool
10539{return (is_global_scope(decl.get_scope()));}
10540
10541/// Tests whether a given declaration is at global scope.
10542///
10543/// @param decl the decl to consider.
10544///
10545/// @return true iff decl is at global scope.
10546bool
10547is_at_global_scope(const decl_base_sptr decl)
10548{return (decl && is_global_scope(decl->get_scope()));}
10549
10550/// Tests whether a given declaration is at global scope.
10551///
10552/// @param decl the decl to consider.
10553///
10554/// @return true iff decl is at global scope.
10555bool
10557{return is_at_global_scope(*decl);}
10558
10559/// Tests whether a given decl is at class scope.
10560///
10561/// @param decl the decl to consider.
10562///
10563/// @return true iff decl is at class scope.
10565is_at_class_scope(const decl_base_sptr decl)
10566{return is_at_class_scope(decl.get());}
10567
10568/// Tests whether a given decl is at class scope.
10569///
10570/// @param decl the decl to consider.
10571///
10572/// @return true iff decl is at class scope.
10575{
10576 if (!decl)
10577 return 0;
10578
10579 return is_at_class_scope(*decl);
10580}
10581
10582/// Tests whether a given decl is at class scope.
10583///
10584/// @param decl the decl to consider.
10585///
10586/// @return true iff decl is at class scope.
10589{
10590 scope_decl* scope = decl.get_scope();
10591 if (class_or_union* cl = is_class_type(scope))
10592 return cl;
10593 if (class_or_union* cl = is_union_type(scope))
10594 return cl;
10595 return 0;
10596}
10597
10598/// Find a data member inside an anonymous data member.
10599///
10600/// An anonymous data member has a type which is a class or union.
10601/// This function looks for a data member inside the type of that
10602/// anonymous data member.
10603///
10604/// @param anon_dm the anonymous data member to consider.
10605///
10606/// @param name the name of the data member to look for.
10609 const string& name)
10610{
10611 const class_or_union* containing_class_or_union =
10613
10614 if (!containing_class_or_union)
10615 return var_decl_sptr();
10616
10617 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10618 return result;
10619}
10620
10621/// Tests whether a given decl is at template scope.
10622///
10623/// Note that only template parameters , types that are compositions,
10624/// and template patterns (function or class) can be at template scope.
10625///
10626/// @param decl the decl to consider.
10627///
10628/// @return true iff the decl is at template scope.
10629bool
10630is_at_template_scope(const shared_ptr<decl_base> decl)
10631{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10632
10633/// Tests whether a decl is a template parameter.
10634///
10635/// @param decl the decl to consider.
10636///
10637/// @return true iff decl is a template parameter.
10638bool
10639is_template_parameter(const shared_ptr<decl_base> decl)
10640{
10641 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10642 || dynamic_pointer_cast<non_type_tparameter>(decl)
10643 || dynamic_pointer_cast<template_tparameter>(decl)));
10644}
10645
10646/// Test whether a declaration is a @ref function_decl.
10647///
10648/// @param d the declaration to test for.
10649///
10650/// @return a shared pointer to @ref function_decl if @p d is a @ref
10651/// function_decl. Otherwise, a nil shared pointer.
10654{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10655
10656/// Test whether a declaration is a @ref function_decl.
10657///
10658/// @param d the declaration to test for.
10659///
10660/// @return true if @p d is a function_decl.
10661bool
10663{return is_function_decl(&d);}
10664
10665/// Test whether a declaration is a @ref function_decl.
10666///
10667/// @param d the declaration to test for.
10668///
10669/// @return a shared pointer to @ref function_decl if @p d is a @ref
10670/// function_decl. Otherwise, a nil shared pointer.
10673{return dynamic_pointer_cast<function_decl>(d);}
10674
10675/// Test whether a declaration is a @ref function_decl.
10676///
10677/// @param d the declaration to test for.
10678///
10679/// @return a pointer to @ref function_decl if @p d is a @ref
10680/// function_decl. Otherwise, a nil shared pointer.
10683{
10684 return dynamic_cast<function_decl::parameter*>
10685 (const_cast<type_or_decl_base*>(tod));
10686}
10687
10688/// Test whether an ABI artifact is a @ref function_decl.
10689///
10690/// @param tod the declaration to test for.
10691///
10692/// @return a pointer to @ref function_decl if @p d is a @ref
10693/// function_decl. Otherwise, a nil shared pointer.
10696{return dynamic_pointer_cast<function_decl::parameter>(tod);}
10697
10698/// Test if an ABI artifact is a declaration.
10699///
10700/// @param d the artifact to consider.
10701///
10702/// @param return the declaration sub-object of @p d if it's a
10703/// declaration, or NULL if it is not.
10704decl_base*
10706{
10707 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10708 {
10709 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10710 // The artifact is a decl-only (like a function or a
10711 // variable). That is, it's not a type that also has a
10712 // declaration. In this case, we are in the fast path and we
10713 // have a pointer to the decl sub-object handy. Just return
10714 // it ...
10715 return reinterpret_cast<decl_base*>
10716 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10717
10718 // ... Otherwise, we are in the slow path, which is that the
10719 // artifact is a type which has a declaration. In that case,
10720 // let's use the slow dynamic_cast because we don't have the
10721 // pointer to the decl sub-object handily present.
10722 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10723 }
10724 return 0;
10725}
10726
10727/// Test if an ABI artifact is a declaration.
10728///
10729/// @param d the artifact to consider.
10730///
10731/// @param return the declaration sub-object of @p d if it's a
10732/// declaration, or NULL if it is not.
10733decl_base_sptr
10735{return dynamic_pointer_cast<decl_base>(d);}
10736
10737/// Test if an ABI artifact is a declaration.
10738///
10739/// This is done using a slow path that uses dynamic_cast.
10740///
10741/// @param d the artifact to consider.
10742///
10743/// @param return the declaration sub-object of @p d if it's a
10744decl_base*
10746{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10747
10748/// Test if an ABI artifact is a declaration.
10749///
10750/// This is done using a slow path that uses dynamic_cast.
10751///
10752/// @param d the artifact to consider.
10753///
10754/// @param return the declaration sub-object of @p d if it's a
10755decl_base_sptr
10757{return dynamic_pointer_cast<decl_base>(t);}
10758
10759/// Test whether a declaration is a type.
10760///
10761/// @param d the IR artefact to test for.
10762///
10763/// @return true if the artifact is a type, false otherwise.
10764bool
10766{
10767 if (dynamic_cast<const type_base*>(&tod))
10768 return true;
10769 return false;
10770}
10771
10772/// Test whether a declaration is a type.
10773///
10774/// @param d the IR artefact to test for.
10775///
10776/// @return true if the artifact is a type, false otherwise.
10777type_base*
10779{
10780 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10781 return reinterpret_cast<type_base*>
10782 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10783
10784 return 0;
10785}
10786
10787/// Test whether a declaration is a type.
10788///
10789/// @param d the IR artefact to test for.
10790///
10791/// @return true if the artifact is a type, false otherwise.
10792type_base_sptr
10794{return dynamic_pointer_cast<type_base>(tod);}
10795
10796/// Test whether a declaration is a type.
10797///
10798/// @param d the declaration to test for.
10799///
10800/// @return true if the declaration is a type, false otherwise.
10801
10802/// Test if a given type is anonymous.
10803///
10804/// Note that this function considers that an anonymous class that is
10805/// named by a typedef is not anonymous anymore. This is the C idiom:
10806///
10807/// typedef struct {int member;} s_type;
10808///
10809/// The typedef s_type becomes the name of the originally anonymous
10810/// struct.
10811///
10812/// @param t the type to consider.
10813///
10814/// @return true iff @p t is anonymous.
10815bool
10817{
10818 const decl_base* d = get_type_declaration(t);
10819 if (d)
10820 if (d->get_is_anonymous())
10821 {
10823 {
10824 // An anonymous class that is named by a typedef is not
10825 // considered anonymous anymore.
10826 if (!cou->get_naming_typedef())
10827 return true;
10828 }
10829 else
10830 return true;
10831 }
10832 return false;
10833}
10834
10835/// Test if a given type is anonymous.
10836///
10837/// @param t the type to consider.
10838///
10839/// @return true iff @p t is anonymous.
10840bool
10841is_anonymous_type(const type_base_sptr& t)
10842{return is_anonymous_type(t.get());}
10843
10844/// Test if a type is a neither a pointer, an array nor a function
10845/// type.
10846///
10847/// @param t the type to consider.
10848///
10849/// @return true if the @p t is NOT a pointer, an array nor a
10850/// function.
10851bool
10852is_npaf_type(const type_base_sptr& t)
10853{
10854 if (!(is_pointer_type(t)
10855 || is_array_type(t)
10856 || is_function_type(t)
10857 || is_ptr_to_mbr_type(t)))
10858 return true;
10859 return false;
10860}
10861
10862/// Test whether a type is a type_decl (a builtin type).
10863///
10864/// @return the type_decl* for @t if it's type_decl, otherwise, return
10865/// nil.
10866const type_decl*
10868{return dynamic_cast<const type_decl*>(t);}
10869
10870/// Test whether a type is a type_decl (a builtin type).
10871///
10872/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10873/// return nil.
10876{return dynamic_pointer_cast<type_decl>(t);}
10877
10878/// Test if a type is a real type.
10879///
10880/// @param t the type to test.
10881///
10882/// @return the real type @p t can be converted to, or nil if @p
10883/// is not a real type.
10884type_decl*
10886{
10887 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10888 if (!type)
10889 return nullptr;
10890
10891 real_type int_type;
10892 if (!parse_real_type(type->get_name(), int_type))
10893 return nullptr;
10894
10895 return type;
10896}
10897
10898/// Test if a type is a real type.
10899///
10900/// @param t the type to test.
10901///
10902/// @return the real type @p t can be converted to, or nil if @p is
10903/// not a real type.
10906{
10907 const type_decl_sptr type = is_type_decl(t);
10908 if (!type)
10909 return type_decl_sptr();
10910
10911 real_type int_type;
10912 if (!parse_real_type(type->get_name(), int_type))
10913 return type_decl_sptr();
10914
10915 return type;
10916}
10917
10918/// Test if a type is an integral type.
10919///
10920/// @param t the type to test.
10921///
10922/// @return the integral type @p t can be converted to, or nil if @p
10923/// is not an integral type.
10924type_decl*
10926{
10927 type_decl* type = is_real_type(t);
10928 if (!type)
10929 return nullptr;
10930
10931 real_type rt;
10932 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10935 return nullptr;
10936
10937 return type;
10938}
10939
10940/// Test if a type is an integral type.
10941///
10942/// @param t the type to test.
10943///
10944/// @return the integral type @p t can be converted to, or nil if @p
10945/// is not an integral type.
10948{
10949 type_decl_sptr type = is_real_type(t);
10950 if (!type)
10951 return type;
10952
10953 real_type rt;
10954 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10957 return type_decl_sptr();
10958
10959 return type;
10960}
10961
10962/// Test whether a type is a typedef.
10963///
10964/// @param t the type to test for.
10965///
10966/// @return the typedef declaration of the @p t, or NULL if it's not a
10967/// typedef.
10970{return dynamic_pointer_cast<typedef_decl>(t);}
10971
10972/// Test whether a type is a typedef.
10973///
10974/// @param t the declaration of the type to test for.
10975///
10976/// @return the typedef declaration of the @p t, or NULL if it's not a
10977/// typedef.
10978const typedef_decl*
10980{return dynamic_cast<const typedef_decl*>(t);}
10981
10982/// Test whether a type is a typedef.
10983///
10984/// @param t the declaration of the type to test for.
10985///
10986/// @return the typedef declaration of the @p t, or NULL if it's not a
10987/// typedef.
10990{return dynamic_cast<typedef_decl*>(t);}
10991
10992/// Test whether a type is a typedef.
10993///
10994/// @param t the declaration of the type to test for.
10995///
10996/// @return the typedef declaration of the @p t, or NULL if it's not a
10997/// typedef.
10998const typedef_decl*
11000{return dynamic_cast<const typedef_decl*>(t);}
11001/// Test if a type is an enum. This function looks through typedefs.
11002///
11003/// @parm t the type to consider.
11004///
11005/// @return the enum_decl if @p t is an @ref enum_decl or null
11006/// otherwise.
11008is_compatible_with_enum_type(const type_base_sptr& t)
11009{
11010 if (!t)
11011 return enum_type_decl_sptr();
11012
11013 // Normally we should strip typedefs entirely, but this is
11014 // potentially costly, especially on binaries with huge changesets
11015 // like the Linux Kernel. So we just get the leaf types for now.
11016 //
11017 // Maybe there should be an option by which users accepts to pay the
11018 // CPU usage toll in exchange for finer filtering?
11019
11020 // type_base_sptr ty = strip_typedef(t);
11021 type_base_sptr ty = peel_typedef_type(t);;
11022 return is_enum_type(ty);
11023}
11024
11025/// Test if a type is an enum. This function looks through typedefs.
11026///
11027/// @parm t the type to consider.
11028///
11029/// @return the enum_decl if @p t is an @ref enum_decl or null
11030/// otherwise.
11032is_compatible_with_enum_type(const decl_base_sptr& t)
11034
11035/// Test if a decl is an enum_type_decl
11036///
11037/// @param d the decl to test for.
11038///
11039/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
11040const enum_type_decl*
11042{return dynamic_cast<const enum_type_decl*>(d);}
11043
11044/// Test if a decl is an enum_type_decl
11045///
11046/// @param d the decl to test for.
11047///
11048/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
11051{return dynamic_pointer_cast<enum_type_decl>(d);}
11052
11053/// Test if a type is a class. This function looks through typedefs.
11054///
11055/// @parm t the type to consider.
11056///
11057/// @return the class_decl if @p t is a class_decl or null otherwise.
11059is_compatible_with_class_type(const type_base_sptr& t)
11060{
11061 if (!t)
11062 return class_decl_sptr();
11063
11064 // Normally we should strip typedefs entirely, but this is
11065 // potentially costly, especially on binaries with huge changesets
11066 // like the Linux Kernel. So we just get the leaf types for now.
11067 //
11068 // Maybe there should be an option by which users accepts to pay the
11069 // CPU usage toll in exchange for finer filtering?
11070
11071 // type_base_sptr ty = strip_typedef(t);
11072 type_base_sptr ty = peel_typedef_type(t);
11073 return is_class_type(ty);
11074}
11075
11076/// Test if a type is a class. This function looks through typedefs.
11077///
11078/// @parm t the type to consider.
11079///
11080/// @return the class_decl if @p t is a class_decl or null otherwise.
11082is_compatible_with_class_type(const decl_base_sptr& t)
11084
11085/// Test whether a type is a class.
11086///
11087/// @parm t the type to consider.
11088///
11089/// @return true iff @p t is a class_decl.
11090bool
11092{return is_class_type(&t);}
11093
11094/// Test whether a type is a class.
11095///
11096/// @parm t the type to consider.
11097///
11098/// @return the class_decl if @p t is a class_decl or null otherwise.
11101{
11102 if (!t)
11103 return 0;
11104
11105 if (t->kind() & type_or_decl_base::CLASS_TYPE)
11106 return reinterpret_cast<class_decl*>
11107 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
11108
11109 return 0;
11110}
11111
11112/// Test whether a type is a class.
11113///
11114/// @parm t the type to consider.
11115///
11116/// @return the class_decl if @p t is a class_decl or null otherwise.
11119{return dynamic_pointer_cast<class_decl>(d);}
11120
11121/// Test if the last data member of a class is an array with
11122/// non-finite data member.
11123///
11124/// The flexible data member idiom is a well known C idiom:
11125/// https://en.wikipedia.org/wiki/Flexible_array_member.
11126///
11127/// @param klass the class to consider.
11128///
11129/// @return the data member which type is a flexible array, if any, or
11130/// nil.
11133{
11134 var_decl_sptr nil;
11136 if (dms.empty())
11137 return nil;
11138
11139 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11140 {// The type of the last data member is an array.
11141 if (array->is_non_finite())
11142 // The array has a non-finite size. We are thus looking at a
11143 // flexible array data member. Let's return it.
11144 return dms.back();
11145 }
11146
11147 return nil;
11148}
11149
11150/// Test if the last data member of a class is an array with
11151/// non-finite data member.
11152///
11153/// The flexible data member idiom is a well known C idiom:
11154/// https://en.wikipedia.org/wiki/Flexible_array_member.
11155///
11156/// @param klass the class to consider.
11157///
11158/// @return the data member which type is a flexible array, if any, or
11159/// nil.
11162{
11163 if (!klass)
11164 return var_decl_sptr();
11165
11166 return has_flexible_array_data_member(*klass);
11167}
11168
11169/// Test if the last data member of a class is an array with
11170/// non-finite data member.
11171///
11172/// The flexible data member idiom is a well known C idiom:
11173/// https://en.wikipedia.org/wiki/Flexible_array_member.
11174///
11175/// @param klass the class to consider.
11176///
11177/// @return the data member which type is a flexible array, if any, or
11178/// nil.
11181{return has_flexible_array_data_member(klass.get());}
11182
11183/// Test if the last data member of a class is an array with
11184/// one element.
11185///
11186/// An array with one element is a way to mimic the flexible data
11187/// member idiom that was later standardized in C99.
11188///
11189/// To learn more about the flexible data member idiom, please
11190/// consider reading :
11191/// https://en.wikipedia.org/wiki/Flexible_array_member.
11192///
11193/// The various ways of representing that idiom pre-standardization
11194/// are presented in this article:
11195/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11196///
11197/// @param klass the class to consider.
11198///
11199/// @return the data member which type is a fake flexible array, if
11200/// any, or nil.
11203{
11204 var_decl_sptr nil;
11206 if (dms.empty())
11207 return nil;
11208
11209 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11210 {// The type of the last data member is an array.
11211 if (array->get_subranges().size() == 1
11212 && array->get_subranges()[0]->get_length() == 1)
11213 // The array has a size of one. We are thus looking at a
11214 // "fake" flexible array data member. Let's return it.
11215 return dms.back();
11216 }
11217
11218 return nil;
11219}
11220
11221/// Test if the last data member of a class is an array with
11222/// one element.
11223///
11224/// An array with one element is a way to mimic the flexible data
11225/// member idiom that was later standardized in C99.
11226///
11227/// To learn more about the flexible data member idiom, please
11228/// consider reading :
11229/// https://en.wikipedia.org/wiki/Flexible_array_member.
11230///
11231/// The various ways of representing that idiom pre-standardization
11232/// are presented in this article:
11233/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11234///
11235/// @param klass the class to consider.
11236///
11237/// @return the data member which type is a fake flexible array, if
11238/// any, or nil.
11242
11243/// Test if the last data member of a class is an array with
11244/// one element.
11245///
11246/// An array with one element is a way to mimic the flexible data
11247/// member idiom that was later standardized in C99.
11248///
11249/// To learn more about the flexible data member idiom, please
11250/// consider reading :
11251/// https://en.wikipedia.org/wiki/Flexible_array_member.
11252///
11253/// The various ways of representing that idiom pre-standardization
11254/// are presented in this article:
11255/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11256///
11257/// @param klass the class to consider.
11258///
11259/// @return the data member which type is a fake flexible array, if
11260/// any, or nil.
11263{return has_fake_flexible_array_data_member(klass.get());}
11264
11265/// Test wheter a type is a declaration-only class.
11266///
11267/// @param t the type to considier.
11268///
11269/// @param look_through_decl_only if true, then look through the
11270/// decl-only class to see if it actually has a class definition in
11271/// the same ABI corpus.
11272///
11273/// @return true iff @p t is a declaration-only class.
11274bool
11277{
11278 if (class_or_union *klass = is_class_or_union_type(t))
11279 {
11281 klass = look_through_decl_only_class(klass);
11282 return klass->get_is_declaration_only();
11283 }
11284 return false;
11285}
11286
11287/// Test wheter a type is a declaration-only class.
11288///
11289/// @param t the type to considier.
11290///
11291/// @param look_through_decl_only if true, then look through the
11292/// decl-only class to see if it actually has a class definition in
11293/// the same ABI corpus.
11294///
11295/// @return true iff @p t is a declaration-only class.
11296bool
11300
11301/// Test wheter a type is a declaration-only class.
11302///
11303/// @param t the type to considier.
11304///
11305/// @param look_through_decl_only if true, then look through the
11306/// decl-only class to see if it actually has a class definition in
11307/// the same ABI corpus.
11308///
11309/// @return true iff @p t is a declaration-only class.
11310bool
11311is_declaration_only_class_type(const type_base_sptr& t,
11314
11315/// Test if a type is a @ref class_or_union.
11316///
11317/// @param t the type to consider.
11318///
11319/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11320/// nil otherwise.
11323{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
11324
11325/// Test if a type is a @ref class_or_union.
11326///
11327/// @param t the type to consider.
11328///
11329/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11330/// nil otherwise.
11331shared_ptr<class_or_union>
11332is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
11333{return dynamic_pointer_cast<class_or_union>(t);}
11334
11335/// Test if two class or union types are of the same kind.
11336///
11337/// @param first the first type to consider.
11338///
11339/// @param second the second type to consider.
11340///
11341/// @return true iff @p first is of the same kind as @p second.
11342bool
11344 const class_or_union* second)
11345{
11346 if ((is_class_type(first) && is_class_type(second))
11347 || (is_union_type(first) && is_union_type(second)))
11348 return true;
11349
11350 return false;
11351}
11352
11353/// Test if two class or union types are of the same kind.
11354///
11355/// @param first the first type to consider.
11356///
11357/// @param second the second type to consider.
11358///
11359/// @return true iff @p first is of the same kind as @p second.
11360bool
11361class_or_union_types_of_same_kind(const class_or_union_sptr& first,
11362 const class_or_union_sptr& second)
11363{return class_or_union_types_of_same_kind(first.get(), second.get());}
11364
11365/// Test if a type is a @ref union_decl.
11366///
11367/// @param t the type to consider.
11368///
11369/// @return true iff @p t is a union_decl.
11370bool
11372{return is_union_type(&t);}
11373
11374/// Test if a type is a @ref union_decl.
11375///
11376/// @param t the type to consider.
11377///
11378/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11379/// otherwise.
11382{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
11383
11384/// Test if a type is a @ref union_decl.
11385///
11386/// @param t the type to consider.
11387///
11388/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11389/// otherwise.
11390union_decl_sptr
11391is_union_type(const shared_ptr<type_or_decl_base>& t)
11392{return dynamic_pointer_cast<union_decl>(t);}
11393
11394/// Test whether a type is a pointer_type_def.
11395///
11396/// @param t the type to test.
11397///
11398/// @param look_through_decl_only if this is true, then look through
11399/// qualified types to see if the underlying type is a
11400/// pointer_type_def.
11401///
11402/// @return the @ref pointer_type_def_sptr if @p t is a
11403/// pointer_type_def, null otherwise.
11404const pointer_type_def*
11406 bool look_through_qualifiers)
11407{
11408 if (!t)
11409 return 0;
11410
11411 const type_base* type = is_type(t);
11412 if (look_through_qualifiers)
11413 type = peel_qualified_type(is_type(t));
11414
11415 return dynamic_cast<pointer_type_def*>(const_cast<type_base*>(type));
11416}
11417
11418/// Test whether a type is a pointer_type_def.
11419///
11420/// @param t the type to test.
11421///
11422/// @param look_through_decl_only if this is true, then look through
11423/// qualified types to see if the underlying type is a
11424/// pointer_type_def.
11425///
11426/// @return the @ref pointer_type_def_sptr if @p t is a
11427/// pointer_type_def, null otherwise.
11430 bool look_through_qualifiers)
11431{
11432 type_base_sptr type = is_type(t);
11433 if (look_through_qualifiers)
11434 type = peel_qualified_type(type);
11435 return dynamic_pointer_cast<pointer_type_def>(type);
11436}
11437
11438/// Test if a type is a pointer to function type.
11439///
11440/// @param t the type to consider.
11441///
11442/// @return the @ref pointer_type_def_sptr iff @p t is a pointer to
11443/// function type.
11445is_pointer_to_function_type(const type_base_sptr& t)
11446{
11448 {
11449 if (is_function_type(p->get_pointed_to_type()))
11450 return p;
11451 }
11452 return pointer_type_def_sptr();
11453}
11454
11455/// Test if a type is a pointer to array type.
11456///
11457/// @param t the type to consider.
11458///
11459/// @return the pointer_type_def_sptr iff @p t is a pointer to array
11460/// type.
11462is_pointer_to_array_type(const type_base_sptr& t)
11463{
11465 {
11466 if (is_array_type(p->get_pointed_to_type()))
11467 return p;
11468 }
11469 return pointer_type_def_sptr();
11470}
11471
11472/// Test if we are looking at a pointer to a
11473/// neither-a-pointer-to-an-array-nor-a-function type.
11474///
11475/// @param t the type to consider.
11476///
11477/// @return the @ref pointer_type_def_sptr type iff @p t is a
11478/// neither-a-pointer-an-array-nor-a-function type.
11480is_pointer_to_npaf_type(const type_base_sptr& t)
11481{
11483 {
11484 if (is_npaf_type(p->get_pointed_to_type()))
11485 return p;
11486 }
11487 return pointer_type_def_sptr();
11488}
11489
11490/// Test if we are looking at a pointer to pointer to member type.
11491///
11492/// @param t the type to consider.
11493///
11494/// @return the @ref pointer_type_def_sptr type iff @p t is a pointer
11495/// to pointer to member type.
11497is_pointer_to_ptr_to_mbr_type(const type_base_sptr& t)
11498{
11500 {
11501 if (is_ptr_to_mbr_type(p->get_pointed_to_type()))
11502 return p;
11503 }
11504 return pointer_type_def_sptr();
11505}
11506
11507/// Test if a type is a typedef, pointer or reference to a decl-only
11508/// class/union.
11509///
11510/// This looks into qualified types too.
11511///
11512/// @param t the type to consider.
11513///
11514/// @return true iff @p t is a type is a typedef, pointer or reference
11515/// to a decl-only class/union.
11516bool
11518{
11519 const type_base * type =
11520 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11521
11523 /*look_through_decl_only=*/true))
11524 return true;
11525
11526 return false;
11527}
11528
11529/// Test if a type is a typedef of a class or union type, or a typedef
11530/// of a qualified class or union type.
11531///
11532/// Note that if the type is directly a class or union type, the
11533/// function returns true as well.
11534///
11535/// @param t the type to consider.
11536///
11537/// @return true iff @p t is a typedef of a class or union type, or a
11538/// typedef of a qualified class or union type.
11539bool
11541{
11542 if (!t)
11543 return false;
11544
11547 return true;
11548
11549return false;
11550}
11551
11552/// Test if a type is a typedef of a class or union type, or a typedef
11553/// of a qualified class or union type.
11554///
11555/// Note that if the type is directly a class or union type, the
11556/// function returns true as well.
11557///
11558/// @param t the type to consider.
11559///
11560/// @return true iff @p t is a typedef of a class or union type, or a
11561/// typedef of a qualified class or union type.
11562bool
11565
11566/// Test whether a type is a reference_type_def.
11567///
11568/// @param t the type to test.
11569///
11570/// @param look_through_decl_only if this is true, then look through
11571/// qualified types to see if the underlying type is a
11572/// reference_type_def.
11573///
11574/// @return the @ref reference_type_def_sptr if @p t is a
11575/// reference_type_def, null otherwise.
11578 bool look_through_qualifiers)
11579{
11580 const type_base* type = is_type(t);
11581 if (!type)
11582 return nullptr;
11583
11584 if (look_through_qualifiers)
11585 type = peel_qualified_type(type);
11586 return dynamic_cast<reference_type_def*>(const_cast<type_base*>(type));
11587}
11588
11589/// Test whether a type is a reference_type_def.
11590///
11591/// @param t the type to test.
11592///
11593/// @param look_through_decl_only if this is true, then look through
11594/// qualified types to see if the underlying type is a
11595/// reference_type_def.
11596///
11597/// @return the @ref reference_type_def_sptr if @p t is a
11598/// reference_type_def, null otherwise.
11599const reference_type_def*
11601 bool look_through_qualifiers)
11602{
11603 const type_base* type = is_type(t);
11604
11605 if (look_through_qualifiers)
11606 type = peel_qualified_type(type);
11607 return dynamic_cast<const reference_type_def*>(type);
11608}
11609
11610/// Test whether a type is a reference_type_def.
11611///
11612/// @param t the type to test.
11613///
11614/// @param look_through_decl_only if this is true, then look through
11615/// qualified types to see if the underlying type is a
11616/// reference_type_def.
11617///
11618/// @return the @ref reference_type_def_sptr if @p t is a
11619/// reference_type_def, null otherwise.
11622 bool look_through_qualifiers)
11623{
11624 type_base_sptr type = is_type(t);
11625 if (look_through_qualifiers)
11626 type = peel_qualified_type(type);
11627 return dynamic_pointer_cast<reference_type_def>(type);
11628}
11629
11630/// Test whether a type is a @ref ptr_to_mbr_type.
11631///
11632/// @param t the type to test.
11633///
11634/// @return the @ref ptr_to_mbr_type* if @p t is a @ref
11635/// ptr_to_mbr_type type, null otherwise.
11636const ptr_to_mbr_type*
11638 bool look_through_qualifiers)
11639{
11640 const type_base* type = is_type(t);
11641 if (look_through_qualifiers)
11642 type = peel_qualified_type(type);
11643 return dynamic_cast<const ptr_to_mbr_type*>(type);
11644}
11645
11646/// Test whether a type is a @ref ptr_to_mbr_type_sptr.
11647///
11648/// @param t the type to test.
11649///
11650/// @param look_through_decl_only if this is true, then look through
11651/// qualified types to see if the underlying type is a
11652/// ptr_to_mbr_type..
11653///
11654/// @return the @ref ptr_to_mbr_type_sptr if @p t is a @ref
11655/// ptr_to_mbr_type type, null otherwise.
11658 bool look_through_qualifiers)
11659{
11660 type_base_sptr type = is_type(t);
11661 if (look_through_qualifiers)
11662 type = peel_qualified_type(type);
11663 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
11664}
11665
11666/// Test if a type is equivalent to a pointer to void type.
11667///
11668/// Note that this looks trough typedefs or CV qualifiers to look for
11669/// the void pointer.
11670///
11671/// @param type the type to consider.
11672///
11673/// @return the actual void pointer if @p is eqivalent to a void
11674/// pointer or NULL if it's not.
11675const type_base*
11677{
11678 type = peel_qualified_or_typedef_type(type);
11679
11680 const pointer_type_def * t = is_pointer_type(type);
11681 if (!t)
11682 return 0;
11683
11684 // Look through typedefs in the pointed-to type as well.
11685 type_base * ty = t->get_pointed_to_type().get();
11687 if (ty && ty->get_environment().is_void_type(ty))
11688 return ty;
11689
11690 return 0;
11691}
11692
11693/// Test if a type is equivalent to a pointer to void type.
11694///
11695/// Note that this looks trough typedefs or CV qualifiers to look for
11696/// the void pointer.
11697///
11698/// @param type the type to consider.
11699///
11700/// @return the actual void pointer if @p is eqivalent to a void
11701/// pointer or NULL if it's not.
11702const type_base*
11704{return is_void_pointer_type_equivalent(&type);}
11705
11706/// Test if a type is a pointer to void type.
11707///
11708/// @param type the type to consider.
11709///
11710/// @return the actual void pointer if @p is a void pointer or NULL if
11711/// it's not.
11712const type_base*
11714{
11715 if (!t)
11716 return nullptr;
11717
11718 if (t->get_environment().get_void_pointer_type().get() == t)
11719 return t;
11720
11721 const pointer_type_def* ptr = is_pointer_type(t);
11722 if (!ptr)
11723 return nullptr;
11724
11726 return t;
11727
11728 return nullptr;
11729}
11730
11731/// Test if a type is a pointer to void type.
11732///
11733/// @param type the type to consider.
11734///
11735/// @return the actual void pointer if @p is a void pointer or NULL if
11736/// it's not.
11737const type_base_sptr
11738is_void_pointer_type(const type_base_sptr& t)
11739{
11740 type_base_sptr nil;
11741 if (!t)
11742 return nil;
11743
11744 if (t->get_environment().get_void_pointer_type().get() == t.get())
11745 return t;
11746
11747 const pointer_type_def* ptr = is_pointer_type(t.get());
11748 if (!ptr)
11749 return nil;
11750
11751 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11752 return t;
11753
11754 return nil;
11755}
11756
11757/// Test whether a type is a reference_type_def.
11758///
11759/// @param t the type to test.
11760///
11761/// @return the @ref reference_type_def_sptr if @p t is a
11762/// reference_type_def, null otherwise.
11765{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11766
11767/// Test whether a type is a qualified_type_def.
11768///
11769/// @param t the type to test.
11770///
11771/// @return the @ref qualified_type_def_sptr if @p t is a
11772/// qualified_type_def, null otherwise.
11773qualified_type_def_sptr
11775{return dynamic_pointer_cast<qualified_type_def>(t);}
11776
11777/// Test whether a type is a function_type.
11778///
11779/// @param t the type to test.
11780///
11781/// @return the @ref function_type_sptr if @p t is a
11782/// function_type, null otherwise.
11785{return dynamic_pointer_cast<function_type>(t);}
11786
11787/// Test whether a type is a function_type.
11788///
11789/// @param t the type to test.
11790///
11791/// @return the @ref function_type_sptr if @p t is a
11792/// function_type, null otherwise.
11795{return dynamic_cast<function_type*>(t);}
11796
11797/// Test whether a type is a function_type.
11798///
11799/// @param t the type to test.
11800///
11801/// @return the @ref function_type_sptr if @p t is a
11802/// function_type, null otherwise.
11803const function_type*
11805{return dynamic_cast<const function_type*>(t);}
11806
11807/// Test whether a type is a method_type.
11808///
11809/// @param t the type to test.
11810///
11811/// @return the @ref method_type_sptr if @p t is a
11812/// method_type, null otherwise.
11815{return dynamic_pointer_cast<method_type>(t);}
11816
11817/// Test whether a type is a method_type.
11818///
11819/// @param t the type to test.
11820///
11821/// @return the @ref method_type_sptr if @p t is a
11822/// method_type, null otherwise.
11823const method_type*
11825{return dynamic_cast<const method_type*>(t);}
11826
11827/// Test whether a type is a method_type.
11828///
11829/// @param t the type to test.
11830///
11831/// @return the @ref method_type_sptr if @p t is a
11832/// method_type, null otherwise.
11835{return dynamic_cast<method_type*>(t);}
11836
11837/// If a class (or union) is a decl-only class, get its definition.
11838/// Otherwise, just return the initial class.
11839///
11840/// @param the_class the class (or union) to consider.
11841///
11842/// @return either the definition of the class, or the class itself.
11846
11847/// If a class (or union) is a decl-only class, get its definition.
11848/// Otherwise, just return the initial class.
11849///
11850/// @param the_class the class (or union) to consider.
11851///
11852/// @return either the definition of the class, or the class itself.
11853class_or_union_sptr
11856
11857/// If a class (or union) is a decl-only class, get its definition.
11858/// Otherwise, just return the initial class.
11859///
11860/// @param klass the class (or union) to consider.
11861///
11862/// @return either the definition of the class, or the class itself.
11863class_or_union_sptr
11864look_through_decl_only_class(class_or_union_sptr klass)
11866
11867/// If an enum is a decl-only enum, get its definition.
11868/// Otherwise, just return the initial enum.
11869///
11870/// @param the_enum the enum to consider.
11871///
11872/// @return either the definition of the enum, or the enum itself.
11875{return is_enum_type(look_through_decl_only(the_enum));}
11876
11877/// If an enum is a decl-only enum, get its definition.
11878/// Otherwise, just return the initial enum.
11879///
11880/// @param enom the enum to consider.
11881///
11882/// @return either the definition of the enum, or the enum itself.
11885{return is_enum_type(look_through_decl_only(enom));}
11886
11887/// If a decl is decl-only get its definition. Otherwise, just return nil.
11888///
11889/// @param d the decl to consider.
11890///
11891/// @return either the definition of the decl, or nil.
11892decl_base_sptr
11894{
11895 decl_base_sptr decl;
11898
11899 if (!decl)
11900 return decl;
11901
11902 while (decl->get_is_declaration_only()
11903 && decl->get_definition_of_declaration())
11904 decl = decl->get_definition_of_declaration();
11905
11906 return decl;
11907}
11908
11909/// If a decl is decl-only enum, get its definition. Otherwise, just
11910/// return the initial decl.
11911///
11912/// @param d the decl to consider.
11913///
11914/// @return either the definition of the enum, or the decl itself.
11915decl_base*
11917{
11918 if (!d)
11919 return d;
11920
11921 decl_base* result = look_through_decl_only(*d).get();
11922 if (!result)
11923 result = d;
11924
11925 return result;
11926}
11927
11928/// If a decl is decl-only get its definition. Otherwise, just return nil.
11929///
11930/// @param d the decl to consider.
11931///
11932/// @return either the definition of the decl, or nil.
11933decl_base_sptr
11934look_through_decl_only(const decl_base_sptr& d)
11935{
11936 if (!d)
11937 return d;
11938
11939 decl_base_sptr result = look_through_decl_only(*d);
11940 if (!result)
11941 result = d;
11942
11943 return result;
11944}
11945
11946/// If a type is is decl-only, then get its definition. Otherwise,
11947/// just return the initial type.
11948///
11949/// @param d the decl to consider.
11950///
11951/// @return either the definition of the decl, or the initial type.
11952type_base*
11954{
11955 decl_base* d = is_decl(t);
11956 if (!d)
11957 return t;
11959 return is_type(d);
11960}
11961
11962/// If a type is is decl-only, then get its definition. Otherwise,
11963/// just return the initial type.
11964///
11965/// @param d the decl to consider.
11966///
11967/// @return either the definition of the decl, or the initial type.
11968type_base_sptr
11969look_through_decl_only_type(const type_base_sptr& t)
11970{
11971 decl_base_sptr d = is_decl(t);
11972 if (!d)
11973 return t;
11975 return is_type(d);
11976}
11977
11978/// Tests if a declaration is a variable declaration.
11979///
11980/// @param decl the decl to test.
11981///
11982/// @return the var_decl_sptr iff decl is a variable declaration; nil
11983/// otherwise.
11984var_decl*
11986{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
11987
11988/// Tests if a declaration is a variable declaration.
11989///
11990/// @param decl the decl to test.
11991///
11992/// @return the var_decl_sptr iff decl is a variable declaration; nil
11993/// otherwise.
11996{return dynamic_pointer_cast<var_decl>(decl);}
11997
11998/// Tests if a declaration is a namespace declaration.
11999///
12000/// @param d the decalration to consider.
12001///
12002/// @return the namespace declaration if @p d is a namespace.
12004is_namespace(const decl_base_sptr& d)
12005{return dynamic_pointer_cast<namespace_decl>(d);}
12006
12007/// Tests if a declaration is a namespace declaration.
12008///
12009/// @param d the decalration to consider.
12010///
12011/// @return the namespace declaration if @p d is a namespace.
12014{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
12015
12016/// Tests whether a decl is a template parameter composition type.
12017///
12018/// @param decl the declaration to consider.
12019///
12020/// @return true iff decl is a template parameter composition type.
12021bool
12022is_template_parm_composition_type(const shared_ptr<decl_base> decl)
12023{
12024 return (decl
12025 && is_at_template_scope(decl)
12026 && is_type(decl)
12027 && !is_template_parameter(decl));
12028}
12029
12030/// Test whether a decl is the pattern of a function template.
12031///
12032/// @param decl the decl to consider.
12033///
12034/// @return true iff decl is the pattern of a function template.
12035bool
12036is_function_template_pattern(const shared_ptr<decl_base> decl)
12037{
12038 return (decl
12039 && dynamic_pointer_cast<function_decl>(decl)
12040 && dynamic_cast<template_decl*>(decl->get_scope()));
12041}
12042
12043/// Test if a type is an array_type_def.
12044///
12045/// @param type the type to consider.
12046///
12047/// @return true iff @p type is an array_type_def.
12050 bool look_through_qualifiers)
12051{
12052 const type_base* t = is_type(type);
12053
12054 if (look_through_qualifiers)
12055 t = peel_qualified_type(t);
12056 return dynamic_cast<array_type_def*>(const_cast<type_base*>(t));
12057}
12058
12059/// Test if a type is an array_type_def.
12060///
12061/// @param type the type to consider.
12062///
12063/// @return true iff @p type is an array_type_def.
12066 bool look_through_qualifiers)
12067{
12068 type_base_sptr t = is_type(type);
12069
12070 if (look_through_qualifiers)
12071 t = peel_qualified_type(t);
12072 return dynamic_pointer_cast<array_type_def>(t);
12073}
12074
12075/// Tests if the element of a given array is a qualified type.
12076///
12077/// @param array the array type to consider.
12078///
12079/// @return the qualified element of the array iff it's a qualified
12080/// type. Otherwise, return a nil object.
12081qualified_type_def_sptr
12083{
12084 if (!array)
12085 return qualified_type_def_sptr();
12086
12087 return is_qualified_type(array->get_element_type());
12088}
12089
12090/// Test if an array type is an array to a qualified element type.
12091///
12092/// @param type the array type to consider.
12093///
12094/// @return true the array @p type iff it's an array to a qualified
12095/// element type.
12097is_array_of_qualified_element(const type_base_sptr& type)
12098{
12099 if (array_type_def_sptr array = is_array_type(type))
12101 return array;
12102
12103 return array_type_def_sptr();
12104}
12105
12106/// Test if a type is a typedef of an array.
12107///
12108/// Note that the function looks through qualified and typedefs types
12109/// of the underlying type of the current typedef. In other words, if
12110/// we are looking at a typedef of a CV-qualified array, or at a
12111/// typedef of a CV-qualified typedef of an array, this function will
12112/// still return TRUE.
12113///
12114/// @param t the type to consider.
12115///
12116/// @return true if t is a typedef which underlying type is an array.
12117/// That array might be either cv-qualified array or a typedef'ed
12118/// array, or a combination of both.
12120is_typedef_of_array(const type_base_sptr& t)
12121{
12122 array_type_def_sptr result;
12123
12124 if (typedef_decl_sptr typdef = is_typedef(t))
12125 {
12126 type_base_sptr u =
12127 peel_qualified_or_typedef_type(typdef->get_underlying_type());
12128 result = is_array_type(u);
12129 }
12130
12131 return result;
12132}
12133
12134/// Test if a type is an array_type_def::subrange_type.
12135///
12136/// @param type the type to consider.
12137///
12138/// @return the array_type_def::subrange_type which @p type is a type
12139/// of, or nil if it's not of that type.
12142{
12143 return dynamic_cast<array_type_def::subrange_type*>
12144 (const_cast<type_or_decl_base*>(type));
12145}
12146
12147/// Test if a type is an array_type_def::subrange_type.
12148///
12149/// @param type the type to consider.
12150///
12151/// @return the array_type_def::subrange_type which @p type is a type
12152/// of, or nil if it's not of that type.
12155{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
12156
12157/// Tests whether a decl is a template.
12158///
12159/// @param decl the decl to consider.
12160///
12161/// @return true iff decl is a function template, class template, or
12162/// template template parameter.
12163bool
12164is_template_decl(const decl_base_sptr& decl)
12165{return decl && dynamic_pointer_cast<template_decl>(decl);}
12166
12167/// This enum describe the kind of entity to lookup, while using the
12168/// lookup API.
12170{
12171 LOOKUP_ENTITY_TYPE,
12172 LOOKUP_ENTITY_VAR,
12173};
12174
12175/// Find the first relevant delimiter (the "::" string) in a fully
12176/// qualified C++ type name, starting from a given position. The
12177/// delimiter returned separates a type name from the name of its
12178/// context.
12179///
12180/// This is supposed to work correctly on names in cases like this:
12181///
12182/// foo<ns1::name1, ns2::name2>
12183///
12184/// In that case when called with with parameter @p begin set to 0, no
12185/// delimiter is returned, because the type name in this case is:
12186/// 'foo<ns1::name1, ns2::name2>'.
12187///
12188/// But in this case:
12189///
12190/// foo<p1, bar::name>::some_type
12191///
12192/// The "::" returned is the one right before 'some_type'.
12193///
12194/// @param fqn the fully qualified name of the type to consider.
12195///
12196/// @param begin the position from which to look for the delimiter.
12197///
12198/// @param delim_pos out parameter. Is set to the position of the
12199/// delimiter iff the function returned true.
12200///
12201/// @return true iff the function found and returned the delimiter.
12202static bool
12203find_next_delim_in_cplus_type(const string& fqn,
12204 size_t begin,
12205 size_t& delim_pos)
12206{
12207 int angle_count = 0;
12208 bool found = false;
12209 size_t i = begin;
12210 for (; i < fqn.size(); ++i)
12211 {
12212 if (fqn[i] == '<')
12213 ++angle_count;
12214 else if (fqn[i] == '>')
12215 --angle_count;
12216 else if (i + 1 < fqn.size()
12217 && !angle_count
12218 && fqn[i] == ':'
12219 && fqn[i+1] == ':')
12220 {
12221 delim_pos = i;
12222 found = true;
12223 break;
12224 }
12225 }
12226 return found;
12227}
12228
12229/// Decompose a fully qualified name into the list of its components.
12230///
12231/// @param fqn the fully qualified name to decompose.
12232///
12233/// @param comps the resulting list of component to fill.
12234void
12235fqn_to_components(const string& fqn,
12236 list<string>& comps)
12237{
12238 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
12239 do
12240 {
12241 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
12242 comp_end = fqn_size;
12243
12244 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
12245 comps.push_back(comp);
12246
12247 comp_begin = comp_end + 2;
12248 if (comp_begin >= fqn_size)
12249 break;
12250 } while (true);
12251}
12252
12253/// Turn a set of qualified name components (that name a type) into a
12254/// qualified name string.
12255///
12256/// @param comps the name components
12257///
12258/// @return the resulting string, which would be the qualified name of
12259/// a type.
12260string
12261components_to_type_name(const list<string>& comps)
12262{
12263 string result;
12264 for (list<string>::const_iterator c = comps.begin();
12265 c != comps.end();
12266 ++c)
12267 if (c == comps.begin())
12268 result = *c;
12269 else
12270 result += "::" + *c;
12271 return result;
12272}
12273
12274/// This predicate returns true if a given container iterator points
12275/// to the last element of the container, false otherwise.
12276///
12277/// @tparam T the type of the container of the iterator.
12278///
12279/// @param container the container the iterator points into.
12280///
12281/// @param i the iterator to consider.
12282///
12283/// @return true iff the iterator points to the last element of @p
12284/// container.
12285template<typename T>
12286static bool
12287iterator_is_last(T& container,
12288 typename T::const_iterator i)
12289{
12290 typename T::const_iterator next = i;
12291 ++next;
12292 return (next == container.end());
12293}
12294
12295//--------------------------------
12296// <type and decls lookup stuff>
12297// ------------------------------
12298
12299/// Lookup all the type*s* that have a given fully qualified name.
12300///
12301/// @param type_name the fully qualified name of the type to
12302/// lookup.
12303///
12304/// @param type_map the map to look into.
12305///
12306/// @return the vector containing the types named @p type_name. If
12307/// the lookup didn't yield any type, then this function returns nil.
12308static const type_base_wptrs_type*
12309lookup_types_in_map(const interned_string& type_name,
12310 const istring_type_base_wptrs_map_type& type_map)
12311{
12312 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12313 if (i != type_map.end())
12314 return &i->second;
12315 return 0;
12316}
12317
12318/// Lookup a type (with a given name) in a map that associates a type
12319/// name to a type. If there are several types with a given name,
12320/// then try to return the first one that is not decl-only.
12321/// Otherwise, return the last of such types, that is, the last one
12322/// that got registered.
12323///
12324/// @tparam TypeKind the type of the type this function is supposed to
12325/// return.
12326///
12327/// @param type_name the name of the type to lookup.
12328///
12329/// @param type_map the map in which to look.
12330///
12331/// @return a shared_ptr to the type found. If no type was found or
12332/// if the type found was not of type @p TypeKind then the function
12333/// returns nil.
12334template <class TypeKind>
12335static shared_ptr<TypeKind>
12336lookup_type_in_map(const interned_string& type_name,
12337 const istring_type_base_wptrs_map_type& type_map)
12338{
12339 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12340 if (i != type_map.end())
12341 {
12342 // Walk the types that have the name "type_name" and return the
12343 // first one that is not declaration-only ...
12344 for (auto j : i->second)
12345 {
12346 type_base_sptr t(j);
12347 decl_base_sptr d = is_decl(t);
12348 if (d && !d->get_is_declaration_only())
12349 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
12350 }
12351 // ... or return the last type with the name "type_name" that
12352 // was recorded. It's likely to be declaration-only if we
12353 // reached this point.
12354 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
12355 }
12356 return shared_ptr<TypeKind>();
12357}
12358
12359/// Lookup a basic type from a translation unit.
12360///
12361/// This is done by looking the type up in the type map that is
12362/// maintained in the translation unit. So this is as fast as
12363/// possible.
12364///
12365/// @param type_name the name of the basic type to look for.
12366///
12367/// @param tu the translation unit to look into.
12368///
12369/// @return the basic type found or nil if no basic type was found.
12372{
12373 return lookup_type_in_map<type_decl>(type_name,
12374 tu.get_types().basic_types());
12375}
12376
12377/// Lookup a basic type from a translation unit.
12378///
12379/// This is done by looking the type up in the type map that is
12380/// maintained in the translation unit. So this is as fast as
12381/// possible.
12382///
12383/// @param type_name the name of the basic type to look for.
12384///
12385/// @param tu the translation unit to look into.
12386///
12387/// @return the basic type found or nil if no basic type was found.
12389lookup_basic_type(const string& type_name, const translation_unit& tu)
12390{
12391 const environment& env = tu.get_environment();
12392
12393 interned_string s = env.intern(type_name);
12394 return lookup_basic_type(s, tu);
12395}
12396
12397/// Lookup a class type from a translation unit.
12398///
12399/// This is done by looking the type up in the type map that is
12400/// maintained in the translation unit. So this is as fast as
12401/// possible.
12402///
12403/// @param fqn the fully qualified name of the class type node to look
12404/// up.
12405///
12406/// @param tu the translation unit to perform lookup from.
12407///
12408/// @return the declaration of the class type IR node found, NULL
12409/// otherwise.
12411lookup_class_type(const string& fqn, const translation_unit& tu)
12412{
12413 const environment& env = tu.get_environment();
12414 interned_string s = env.intern(fqn);
12415 return lookup_class_type(s, tu);
12416}
12417
12418/// Lookup a class type from a translation unit.
12419///
12420/// This is done by looking the type up in the type map that is
12421/// maintained in the translation unit. So this is as fast as
12422/// possible.
12423///
12424/// @param type_name the name of the class type to look for.
12425///
12426/// @param tu the translation unit to look into.
12427///
12428/// @return the class type found or nil if no class type was found.
12431{
12432 return lookup_type_in_map<class_decl>(type_name,
12433 tu.get_types().class_types());
12434}
12435
12436/// Lookup a union type from a translation unit.
12437///
12438/// This is done by looking the type up in the type map that is
12439/// maintained in the translation unit. So this is as fast as
12440/// possible.
12441///
12442/// @param type_name the name of the union type to look for.
12443///
12444/// @param tu the translation unit to look into.
12445///
12446/// @return the union type found or nil if no union type was found.
12447union_decl_sptr
12449{
12450 return lookup_type_in_map<union_decl>(type_name,
12451 tu.get_types().union_types());
12452}
12453
12454/// Lookup a union type from a translation unit.
12455///
12456/// This is done by looking the type up in the type map that is
12457/// maintained in the translation unit. So this is as fast as
12458/// possible.
12459///
12460/// @param fqn the fully qualified name of the type to lookup.
12461///
12462/// @param tu the translation unit to look into.
12463///
12464/// @return the union type found or nil if no union type was found.
12465union_decl_sptr
12466lookup_union_type(const string& fqn, const translation_unit& tu)
12467{
12468 const environment& env = tu.get_environment();
12469 interned_string s = env.intern(fqn);
12470 return lookup_union_type(s, tu);
12471}
12472
12473/// Lookup a union type in a given corpus, from its location.
12474///
12475/// @param loc the location of the union type to look for.
12476///
12477/// @param corp the corpus to look it from.
12478///
12479/// @return the resulting union_decl.
12480union_decl_sptr
12482{
12485 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
12486
12487 return result;
12488}
12489
12490/// Lookup a union type in a given corpus, from its location.
12491///
12492/// @param loc the location of the union type to look for.
12493///
12494/// @param corp the corpus to look it from.
12495///
12496/// @return the resulting union_decl.
12497union_decl_sptr
12498lookup_union_type_per_location(const string& loc, const corpus& corp)
12499{
12500 const environment& env = corp.get_environment();
12501 return lookup_union_type_per_location(env.intern(loc), corp);
12502}
12503
12504/// Lookup an enum type from a translation unit.
12505///
12506/// This is done by looking the type up in the type map that is
12507/// maintained in the translation unit. So this is as fast as
12508/// possible.
12509///
12510/// @param type_name the name of the enum type to look for.
12511///
12512/// @param tu the translation unit to look into.
12513///
12514/// @return the enum type found or nil if no enum type was found.
12517{
12518 return lookup_type_in_map<enum_type_decl>(type_name,
12519 tu.get_types().enum_types());
12520}
12521
12522/// Lookup an enum type from a translation unit.
12523///
12524/// This is done by looking the type up in the type map that is
12525/// maintained in the translation unit. So this is as fast as
12526/// possible.
12527///
12528/// @param type_name the name of the enum type to look for.
12529///
12530/// @param tu the translation unit to look into.
12531///
12532/// @return the enum type found or nil if no enum type was found.
12534lookup_enum_type(const string& type_name, const translation_unit& tu)
12535{
12536 const environment& env = tu.get_environment();
12537 interned_string s = env.intern(type_name);
12538 return lookup_enum_type(s, tu);
12539}
12540
12541/// Lookup a typedef type from a translation unit.
12542///
12543/// This is done by looking the type up in the type map that is
12544/// maintained in the translation unit. So this is as fast as
12545/// possible.
12546///
12547/// @param type_name the name of the typedef type to look for.
12548///
12549/// @param tu the translation unit to look into.
12550///
12551/// @return the typedef type found or nil if no typedef type was
12552/// found.
12555 const translation_unit& tu)
12556{
12557 return lookup_type_in_map<typedef_decl>(type_name,
12558 tu.get_types().typedef_types());
12559}
12560
12561/// Lookup a typedef type from a translation unit.
12562///
12563/// This is done by looking the type up in the type map that is
12564/// maintained in the translation unit. So this is as fast as
12565/// possible.
12566///
12567/// @param type_name the name of the typedef type to look for.
12568///
12569/// @param tu the translation unit to look into.
12570///
12571/// @return the typedef type found or nil if no typedef type was
12572/// found.
12574lookup_typedef_type(const string& type_name, const translation_unit& tu)
12575{
12576 const environment& env = tu.get_environment();
12577 interned_string s = env.intern(type_name);
12578 return lookup_typedef_type(s, tu);
12579}
12580
12581/// Lookup a qualified type from a translation unit.
12582///
12583/// This is done by looking the type up in the type map that is
12584/// maintained in the translation unit. So this is as fast as
12585/// possible.
12586///
12587/// @param type_name the name of the qualified type to look for.
12588///
12589/// @param tu the translation unit to look into.
12590///
12591/// @return the qualified type found or nil if no qualified type was
12592/// found.
12593qualified_type_def_sptr
12595 const translation_unit& tu)
12596{
12597 const type_maps& m = tu.get_types();
12598 return lookup_type_in_map<qualified_type_def>(type_name,
12599 m.qualified_types());
12600}
12601
12602/// Lookup a qualified type from a translation unit.
12603///
12604/// This is done by looking the type up in the type map that is
12605/// maintained in the translation unit. So this is as fast as
12606/// possible.
12607///
12608/// @param underlying_type the underying type of the qualified type to
12609/// look up.
12610///
12611/// @param quals the CV-qualifiers of the qualified type to look for.
12612///
12613/// @param tu the translation unit to look into.
12614///
12615/// @return the qualified type found or nil if no qualified type was
12616/// found.
12617qualified_type_def_sptr
12618lookup_qualified_type(const type_base_sptr& underlying_type,
12620 const translation_unit& tu)
12621{
12622 interned_string type_name = get_name_of_qualified_type(underlying_type,
12623 quals);
12624 return lookup_qualified_type(type_name, tu);
12625}
12626
12627/// Lookup a pointer type from a translation unit.
12628///
12629/// This is done by looking the type up in the type map that is
12630/// maintained in the translation unit. So this is as fast as
12631/// possible.
12632///
12633/// @param type_name the name of the pointer type to look for.
12634///
12635/// @param tu the translation unit to look into.
12636///
12637/// @return the pointer type found or nil if no pointer type was
12638/// found.
12641 const translation_unit& tu)
12642{
12643 const type_maps& m = tu.get_types();
12644 return lookup_type_in_map<pointer_type_def>(type_name,
12645 m.pointer_types());
12646}
12647
12648/// Lookup a pointer type from a translation unit.
12649///
12650/// This is done by looking the type up in the type map that is
12651/// maintained in the translation unit. So this is as fast as
12652/// possible.
12653///
12654/// @param type_name the name of the pointer type to look for.
12655///
12656/// @param tu the translation unit to look into.
12657///
12658/// @return the pointer type found or nil if no pointer type was
12659/// found.
12661lookup_pointer_type(const string& type_name, const translation_unit& tu)
12662{
12663 const environment& env = tu.get_environment();
12664 interned_string s = env.intern(type_name);
12665 return lookup_pointer_type(s, tu);
12666}
12667
12668/// Lookup a pointer type from a translation unit.
12669///
12670/// This is done by looking the type up in the type map that is
12671/// maintained in the translation unit. So this is as fast as
12672/// possible.
12673///
12674/// @param pointed_to_type the pointed-to-type of the pointer to look for.
12675///
12676/// @param tu the translation unit to look into.
12677///
12678/// @return the pointer type found or nil if no pointer type was
12679/// found.
12681lookup_pointer_type(const type_base_sptr& pointed_to_type,
12682 const translation_unit& tu)
12683{
12684 type_base_sptr t = look_through_decl_only_type(pointed_to_type);
12686 return lookup_pointer_type(type_name, tu);
12687}
12688
12689/// Lookup a reference type from a translation unit.
12690///
12691/// This is done by looking the type up in the type map that is
12692/// maintained in the translation unit. So this is as fast as
12693/// possible.
12694///
12695/// @param type_name the name of the reference type to look for.
12696///
12697/// @param tu the translation unit to look into.
12698///
12699/// @return the reference type found or nil if no reference type was
12700/// found.
12703 const translation_unit& tu)
12704{
12705 const type_maps& m = tu.get_types();
12706 return lookup_type_in_map<reference_type_def>(type_name,
12707 m.reference_types());
12708}
12709
12710/// Lookup a reference type from a translation unit.
12711///
12712/// This is done by looking the type up in the type map that is
12713/// maintained in the translation unit. So this is as fast as
12714/// possible.
12715///
12716/// @param pointed_to_type the pointed-to-type of the reference to
12717/// look up.
12718///
12719/// @param tu the translation unit to look into.
12720///
12721/// @return the reference type found or nil if no reference type was
12722/// found.
12724lookup_reference_type(const type_base_sptr& pointed_to_type,
12725 bool lvalue_reference,
12726 const translation_unit& tu)
12727{
12728 interned_string type_name =
12730 lvalue_reference);
12731 return lookup_reference_type(type_name, tu);
12732}
12733
12734/// Lookup an array type from a translation unit.
12735///
12736/// This is done by looking the type up in the type map that is
12737/// maintained in the translation unit. So this is as fast as
12738/// possible.
12739///
12740/// @param type_name the name of the array type to look for.
12741///
12742/// @param tu the translation unit to look into.
12743///
12744/// @return the array type found or nil if no array type was found.
12747 const translation_unit& tu)
12748{
12749 const type_maps& m = tu.get_types();
12750 return lookup_type_in_map<array_type_def>(type_name,
12751 m.array_types());
12752}
12753
12754/// Lookup a function type from a translation unit.
12755///
12756/// This is done by looking the type up in the type map that is
12757/// maintained in the translation unit. So this is as fast as
12758/// possible.
12759///
12760/// @param type_name the name of the type to lookup.
12761///
12762/// @param tu the translation unit to look into.
12763///
12764/// @return the function type found, or NULL of none was found.
12767 const translation_unit& tu)
12768{
12769 const type_maps& m = tu.get_types();
12770 return lookup_type_in_map<function_type>(type_name,
12771 m.function_types());
12772}
12773
12774/// Lookup a function type from a translation unit.
12775///
12776/// This walks all the function types held by the translation unit and
12777/// compare their sub-type *names*. If the names match then return
12778/// the function type found in the translation unit.
12779///
12780/// @param t the function type to look for.
12781///
12782/// @param tu the translation unit to look into.
12783///
12784/// @return the function type found, or NULL of none was found.
12787 const translation_unit& tu)
12788{
12789 interned_string type_name = get_type_name(t);
12790 return lookup_function_type(type_name, tu);
12791}
12792
12793/// Lookup a function type from a translation unit.
12794///
12795/// This is done by looking the type up in the type map that is
12796/// maintained in the translation unit. So this is as fast as
12797/// possible.
12798///
12799/// @param t the function type to look for.
12800///
12801/// @param tu the translation unit to look into.
12802///
12803/// @return the function type found, or NULL of none was found.
12806 const translation_unit& tu)
12807{return lookup_function_type(*t, tu);}
12808
12809/// Lookup a type in a translation unit.
12810///
12811/// @param fqn the fully qualified name of the type to lookup.
12812///
12813/// @param tu the translation unit to consider.
12814///
12815/// @return the declaration of the type if found, NULL otherwise.
12816const type_base_sptr
12818 const translation_unit& tu)
12819{
12820 type_base_sptr result;
12821 ((result = lookup_typedef_type(fqn, tu))
12822 || (result = lookup_class_type(fqn, tu))
12823 || (result = lookup_union_type(fqn, tu))
12824 || (result = lookup_enum_type(fqn, tu))
12825 || (result = lookup_qualified_type(fqn, tu))
12826 || (result = lookup_pointer_type(fqn, tu))
12827 || (result = lookup_reference_type(fqn, tu))
12828 || (result = lookup_array_type(fqn, tu))
12829 || (result = lookup_function_type(fqn, tu))
12830 || (result = lookup_basic_type(fqn, tu)));
12831
12832 return result;
12833}
12834
12835/// Lookup a type in a translation unit, starting from the global
12836/// namespace.
12837///
12838/// @param fqn the fully qualified name of the type to lookup.
12839///
12840/// @param tu the translation unit to consider.
12841///
12842/// @return the declaration of the type if found, NULL otherwise.
12843type_base_sptr
12844lookup_type(const string& fqn, const translation_unit& tu)
12845{
12846 const environment&env = tu.get_environment();
12847 interned_string ifqn = env.intern(fqn);
12848 return lookup_type(ifqn, tu);
12849}
12850
12851/// Lookup a type from a translation unit.
12852///
12853/// @param fqn the components of the fully qualified name of the node
12854/// to look up.
12855///
12856/// @param tu the translation unit to perform lookup from.
12857///
12858/// @return the declaration of the IR node found, NULL otherwise.
12859const type_base_sptr
12860lookup_type(const type_base_sptr type,
12861 const translation_unit& tu)
12862{
12863 interned_string type_name = get_type_name(type);
12864 return lookup_type(type_name, tu);
12865}
12866
12867/// Lookup a type in a scope.
12868///
12869/// This is really slow as it walks the member types of the scope in
12870/// sequence to find the type with a given name.
12871///
12872/// If possible, users should prefer looking up types from the
12873/// enclosing translation unit or even ABI corpus because both the
12874/// translation unit and the corpus have a map of type, indexed by
12875/// their name. Looking up a type from those maps is thus much
12876/// faster.
12877///
12878/// @param fqn the fully qualified name of the type to lookup.
12879///
12880/// @param skope the scope to look into.
12881///
12882/// @return the declaration of the type if found, NULL otherwise.
12883const type_base_sptr
12884lookup_type_in_scope(const string& fqn,
12885 const scope_decl_sptr& skope)
12886{
12887 list<string> comps;
12888 fqn_to_components(fqn, comps);
12889 return lookup_type_in_scope(comps, skope);
12890}
12891
12892/// Lookup a @ref var_decl in a scope.
12893///
12894/// @param fqn the fuly qualified name of the @var_decl to lookup.
12895///
12896/// @param skope the scope to look into.
12897///
12898/// @return the declaration of the @ref var_decl if found, NULL
12899/// otherwise.
12900const decl_base_sptr
12902 const scope_decl_sptr& skope)
12903{
12904 list<string> comps;
12905 fqn_to_components(fqn, comps);
12906 return lookup_var_decl_in_scope(comps, skope);
12907}
12908
12909/// A generic function (template) to get the name of a node, whatever
12910/// node it is. This has to be specialized for the kind of node we
12911/// want.
12912///
12913/// Note that a node is a member of a scope.
12914///
12915/// @tparam NodeKind the kind of node to consider.
12916///
12917/// @param node the node to get the name from.
12918///
12919/// @return the name of the node.
12920template<typename NodeKind>
12921static const interned_string&
12922get_node_name(shared_ptr<NodeKind> node);
12923
12924/// Gets the name of a class_decl node.
12925///
12926/// @param node the decl_base node to get the name from.
12927///
12928/// @return the name of the node.
12929template<>
12930const interned_string&
12932{return node->get_name();}
12933
12934/// Gets the name of a type_base node.
12935///
12936/// @param node the type_base node to get the name from.
12937///
12938/// @return the name of the node.
12939template<>
12940const interned_string&
12941get_node_name(type_base_sptr node)
12942{return get_type_declaration(node)->get_name();}
12943
12944/// Gets the name of a var_decl node.
12945///
12946/// @param node the var_decl node to get the name from.
12947///
12948/// @return the name of the node.
12949template<>
12950const interned_string&
12952{return node->get_name();}
12953
12954/// Generic function to get the declaration of a given node, whatever
12955/// it is. There has to be specializations for the kind of the nodes
12956/// we want to support.
12957///
12958/// @tparam NodeKind the type of the node we are looking at.
12959///
12960/// @return the declaration.
12961template<typename NodeKind>
12962static decl_base_sptr
12963convert_node_to_decl(shared_ptr<NodeKind> node);
12964
12965/// Lookup a node in a given scope.
12966///
12967/// @tparam the type of the node to lookup.
12968///
12969/// @param fqn the components of the fully qualified name of the node
12970/// to lookup.
12971///
12972/// @param skope the scope to look into.
12973///
12974/// @return the declaration of the looked up node, or NULL if it
12975/// wasn't found.
12976template<typename NodeKind>
12977static const type_or_decl_base_sptr
12978lookup_node_in_scope(const list<string>& fqn,
12979 const scope_decl_sptr& skope)
12980{
12981 type_or_decl_base_sptr resulting_decl;
12982 shared_ptr<NodeKind> node;
12983 bool it_is_last = false;
12984 scope_decl_sptr cur_scope = skope, new_scope, scope;
12985
12986 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
12987 {
12988 new_scope.reset();
12989 it_is_last = iterator_is_last(fqn, c);
12990 for (scope_decl::declarations::const_iterator m =
12991 cur_scope->get_member_decls().begin();
12992 m != cur_scope->get_member_decls().end();
12993 ++m)
12994 {
12995 if (!it_is_last)
12996 {
12997 // looking for a scope
12998 scope = dynamic_pointer_cast<scope_decl>(*m);
12999 if (scope && scope->get_name() == *c)
13000 {
13001 new_scope = scope;
13002 break;
13003 }
13004 }
13005 else
13006 {
13007 //looking for a final type.
13008 node = dynamic_pointer_cast<NodeKind>(*m);
13009 if (node && get_node_name(node) == *c)
13010 {
13011 if (class_decl_sptr cl =
13012 dynamic_pointer_cast<class_decl>(node))
13013 if (cl->get_is_declaration_only()
13014 && !cl->get_definition_of_declaration())
13015 continue;
13016 resulting_decl = node;
13017 break;
13018 }
13019 }
13020 }
13021 if (!new_scope && !resulting_decl)
13022 return decl_base_sptr();
13023 cur_scope = new_scope;
13024 }
13025 ABG_ASSERT(resulting_decl);
13026 return resulting_decl;
13027}
13028
13029/// lookup a type in a scope.
13030///
13031///
13032/// This is really slow as it walks the member types of the scope in
13033/// sequence to find the type with a given name.
13034///
13035/// If possible, users should prefer looking up types from the
13036/// enclosing translation unit or even ABI corpus because both the
13037/// translation unit and the corpus have a map of type, indexed by
13038/// their name. Looking up a type from those maps is thus much
13039/// faster.
13040///
13041/// @param comps the components of the fully qualified name of the
13042/// type to lookup.
13043///
13044/// @param skope the scope to look into.
13045///
13046/// @return the declaration of the type found.
13047const type_base_sptr
13048lookup_type_in_scope(const list<string>& comps,
13049 const scope_decl_sptr& scope)
13050{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
13051
13052/// lookup a type in a scope.
13053///
13054/// This is really slow as it walks the member types of the scope in
13055/// sequence to find the type with a given name.
13056///
13057/// If possible, users should prefer looking up types from the
13058/// enclosing translation unit or even ABI corpus because both the
13059/// translation unit and the corpus have a map of type, indexed by
13060/// their name. Looking up a type from those maps is thus much
13061/// faster.
13062///
13063/// @param type the type to look for.
13064///
13065/// @param access_path a vector of scopes the path of scopes to follow
13066/// before reaching the scope into which to look for @p type. Note
13067/// that the deepest scope (the one immediately containing @p type) is
13068/// at index 0 of this vector, and the top-most scope is the last
13069/// element of the vector.
13070///
13071/// @param scope the top-most scope into which to look for @p type.
13072///
13073/// @return the scope found in @p scope, or NULL if it wasn't found.
13074static const type_base_sptr
13076 const vector<scope_decl*>& access_path,
13077 const scope_decl* scope)
13078{
13079 vector<scope_decl*> a = access_path;
13080 type_base_sptr result;
13081
13082 scope_decl* first_scope = 0;
13083 if (!a.empty())
13084 {
13085 first_scope = a.back();
13086 ABG_ASSERT(first_scope->get_name() == scope->get_name());
13087 a.pop_back();
13088 }
13089
13090 if (a.empty())
13091 {
13092 interned_string n = get_type_name(type, false);
13093 for (scope_decl::declarations::const_iterator i =
13094 scope->get_member_decls().begin();
13095 i != scope->get_member_decls().end();
13096 ++i)
13097 if (is_type(*i) && (*i)->get_name() == n)
13098 {
13099 result = is_type(*i);
13100 break;
13101 }
13102 }
13103 else
13104 {
13105 first_scope = a.back();
13106 interned_string scope_name, cur_scope_name = first_scope->get_name();
13107 for (scope_decl::scopes::const_iterator i =
13108 scope->get_member_scopes().begin();
13109 i != scope->get_member_scopes().end();
13110 ++i)
13111 {
13112 scope_name = (*i)->get_name();
13113 if (scope_name == cur_scope_name)
13114 {
13115 result = lookup_type_in_scope(type, a, (*i).get());
13116 break;
13117 }
13118 }
13119 }
13120 return result;
13121}
13122
13123/// lookup a type in a scope.
13124///
13125/// This is really slow as it walks the member types of the scope in
13126/// sequence to find the type with a given name.
13127///
13128/// If possible, users should prefer looking up types from the
13129/// enclosing translation unit or even ABI corpus because both the
13130/// translation unit and the corpus have a map of type, indexed by
13131/// their name. Looking up a type from those maps is thus much
13132/// faster.
13133///
13134/// @param type the type to look for.
13135///
13136/// @param scope the top-most scope into which to look for @p type.
13137///
13138/// @return the scope found in @p scope, or NULL if it wasn't found.
13139static const type_base_sptr
13140lookup_type_in_scope(const type_base_sptr type,
13141 const scope_decl* scope)
13142{
13143 if (!type || is_function_type(type))
13144 return type_base_sptr();
13145
13146 decl_base_sptr type_decl = get_type_declaration(type);
13147 ABG_ASSERT(type_decl);
13148 vector<scope_decl*> access_path;
13149 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
13150 {
13151 access_path.push_back(s);
13152 if (is_global_scope(s))
13153 break;
13154 }
13155 return lookup_type_in_scope(*type, access_path, scope);
13156}
13157
13158/// Lookup a type from a translation unit by walking the scopes of the
13159/// translation unit in sequence and looking into them.
13160///
13161/// This is really slow as it walks the member types of the scopes in
13162/// sequence to find the type with a given name.
13163///
13164/// If possible, users should prefer looking up types from the
13165/// translation unit or even ABI corpus in a more direct way, by using
13166/// the lookup_type() functins.
13167///
13168///
13169/// This is because both the translation unit and the corpus have a
13170/// map of types, indexed by their name. Looking up a type from those
13171/// maps is thus much faster. @param fqn the components of the fully
13172/// qualified name of the node to look up.
13173///
13174/// @param tu the translation unit to perform lookup from.
13175///
13176/// @return the declaration of the IR node found, NULL otherwise.
13177const type_base_sptr
13178lookup_type_through_scopes(const type_base_sptr type,
13179 const translation_unit& tu)
13180{
13181 if (function_type_sptr fn_type = is_function_type(type))
13182 return lookup_function_type(fn_type, tu);
13183 return lookup_type_in_scope(type, tu.get_global_scope().get());
13184}
13185
13186/// lookup a var_decl in a scope.
13187///
13188/// @param comps the components of the fully qualified name of the
13189/// var_decl to lookup.
13190///
13191/// @param skope the scope to look into.
13192const decl_base_sptr
13193lookup_var_decl_in_scope(const std::list<string>& comps,
13194 const scope_decl_sptr& skope)
13195{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
13196
13197/// Lookup an IR node from a translation unit.
13198///
13199/// @tparam NodeKind the type of the IR node to lookup from the
13200/// translation unit.
13201///
13202/// @param fqn the components of the fully qualified name of the node
13203/// to look up.
13204///
13205/// @param tu the translation unit to perform lookup from.
13206///
13207/// @return the declaration of the IR node found, NULL otherwise.
13208template<typename NodeKind>
13209static const type_or_decl_base_sptr
13210lookup_node_in_translation_unit(const list<string>& fqn,
13211 const translation_unit& tu)
13212{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
13213
13214/// Lookup a type from a translation unit by walking its scopes in
13215/// sequence and by looking into them.
13216///
13217/// This is much slower than using the lookup_type() function.
13218///
13219/// @param fqn the components of the fully qualified name of the node
13220/// to look up.
13221///
13222/// @param tu the translation unit to perform lookup from.
13223///
13224/// @return the declaration of the IR node found, NULL otherwise.
13225type_base_sptr
13226lookup_type_through_scopes(const list<string>& fqn,
13227 const translation_unit& tu)
13228{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
13229
13230
13231/// Lookup a class type from a translation unit by walking its scopes
13232/// in sequence and by looking into them.
13233///
13234/// This is much slower than using the lookup_class_type() function
13235/// because it walks all the scopes of the translation unit in
13236/// sequence and lookup the types to find one that has a given name.
13237///
13238/// @param fqn the components of the fully qualified name of the class
13239/// type node to look up.
13240///
13241/// @param tu the translation unit to perform lookup from.
13242///
13243/// @return the declaration of the class type IR node found, NULL
13244/// otherwise.
13246lookup_class_type_through_scopes(const list<string>& fqn,
13247 const translation_unit& tu)
13248{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
13249
13250/// Lookup a basic type from all the translation units of a given
13251/// corpus.
13252///
13253/// @param fqn the components of the fully qualified name of the basic
13254/// type node to look up.
13255///
13256/// @param tu the translation unit to perform lookup from.
13257///
13258/// @return the declaration of the basic type IR node found, NULL
13259/// otherwise.
13260static type_decl_sptr
13261lookup_basic_type_through_translation_units(const interned_string& type_name,
13262 const corpus& abi_corpus)
13263{
13264 type_decl_sptr result;
13265
13266 for (translation_units::const_iterator tu =
13267 abi_corpus.get_translation_units().begin();
13268 tu != abi_corpus.get_translation_units().end();
13269 ++tu)
13270 if ((result = lookup_basic_type(type_name, **tu)))
13271 break;
13272
13273 return result;
13274}
13275
13276/// Lookup a union type from all the translation units of a given
13277/// corpus.
13278///
13279/// @param fqn the components of the fully qualified name of the union
13280/// type node to look up.
13281///
13282/// @param tu the translation unit to perform lookup from.
13283///
13284/// @return the declaration of the union type IR node found, NULL
13285/// otherwise.
13286static union_decl_sptr
13287lookup_union_type_through_translation_units(const interned_string& type_name,
13288 const corpus & abi_corpus)
13289{
13290 union_decl_sptr result;
13291
13292 for (translation_units::const_iterator tu =
13293 abi_corpus.get_translation_units().begin();
13294 tu != abi_corpus.get_translation_units().end();
13295 ++tu)
13296 if ((result = lookup_union_type(type_name, **tu)))
13297 break;
13298
13299 return result;
13300}
13301
13302/// Lookup an enum type from all the translation units of a given
13303/// corpus.
13304///
13305/// @param fqn the components of the fully qualified name of the enum
13306/// type node to look up.
13307///
13308/// @param tu the translation unit to perform lookup from.
13309///
13310/// @return the declaration of the enum type IR node found, NULL
13311/// otherwise.
13313lookup_enum_type_through_translation_units(const interned_string& type_name,
13314 const corpus & abi_corpus)
13315{
13316 enum_type_decl_sptr result;
13317
13318 for (translation_units::const_iterator tu =
13319 abi_corpus.get_translation_units().begin();
13320 tu != abi_corpus.get_translation_units().end();
13321 ++tu)
13322 if ((result = lookup_enum_type(type_name, **tu)))
13323 break;
13324
13325 return result;
13326}
13327
13328/// Lookup a typedef type definition in all the translation units of a
13329/// given ABI corpus.
13330///
13331/// @param @param qn the fully qualified name of the typedef type to lookup.
13332///
13333/// @param abi_corpus the ABI corpus which to look the type up in.
13334///
13335/// @return the type definition if any was found, or a NULL pointer.
13336static typedef_decl_sptr
13337lookup_typedef_type_through_translation_units(const interned_string& type_name,
13338 const corpus & abi_corpus)
13339{
13340 typedef_decl_sptr result;
13341
13342 for (translation_units::const_iterator tu =
13343 abi_corpus.get_translation_units().begin();
13344 tu != abi_corpus.get_translation_units().end();
13345 ++tu)
13346 if ((result = lookup_typedef_type(type_name, **tu)))
13347 break;
13348
13349 return result;
13350}
13351
13352/// Lookup a qualified type definition in all the translation units of a
13353/// given ABI corpus.
13354///
13355/// @param @param qn the fully qualified name of the qualified type to
13356/// lookup.
13357///
13358/// @param abi_corpus the ABI corpus which to look the type up in.
13359///
13360/// @return the type definition if any was found, or a NULL pointer.
13361static qualified_type_def_sptr
13362lookup_qualified_type_through_translation_units(const interned_string& t_name,
13363 const corpus & abi_corpus)
13364{
13365 qualified_type_def_sptr result;
13366
13367 for (translation_units::const_iterator tu =
13368 abi_corpus.get_translation_units().begin();
13369 tu != abi_corpus.get_translation_units().end();
13370 ++tu)
13371 if ((result = lookup_qualified_type(t_name, **tu)))
13372 break;
13373
13374 return result;
13375}
13376
13377/// Lookup a pointer type definition in all the translation units of a
13378/// given ABI corpus.
13379///
13380/// @param @param qn the fully qualified name of the pointer type to
13381/// lookup.
13382///
13383/// @param abi_corpus the ABI corpus which to look the type up in.
13384///
13385/// @return the type definition if any was found, or a NULL pointer.
13387lookup_pointer_type_through_translation_units(const interned_string& type_name,
13388 const corpus & abi_corpus)
13389{
13390 pointer_type_def_sptr result;
13391
13392 for (translation_units::const_iterator tu =
13393 abi_corpus.get_translation_units().begin();
13394 tu != abi_corpus.get_translation_units().end();
13395 ++tu)
13396 if ((result = lookup_pointer_type(type_name, **tu)))
13397 break;
13398
13399 return result;
13400}
13401
13402/// Lookup a reference type definition in all the translation units of a
13403/// given ABI corpus.
13404///
13405/// @param @param qn the fully qualified name of the reference type to
13406/// lookup.
13407///
13408/// @param abi_corpus the ABI corpus which to look the type up in.
13409///
13410/// @return the type definition if any was found, or a NULL pointer.
13412lookup_reference_type_through_translation_units(const interned_string& t_name,
13413 const corpus & abi_corpus)
13414{
13416
13417 for (translation_units::const_iterator tu =
13418 abi_corpus.get_translation_units().begin();
13419 tu != abi_corpus.get_translation_units().end();
13420 ++tu)
13421 if ((result = lookup_reference_type(t_name, **tu)))
13422 break;
13423
13424 return result;
13425}
13426
13427/// Lookup a array type definition in all the translation units of a
13428/// given ABI corpus.
13429///
13430/// @param @param qn the fully qualified name of the array type to
13431/// lookup.
13432///
13433/// @param abi_corpus the ABI corpus which to look the type up in.
13434///
13435/// @return the type definition if any was found, or a NULL pointer.
13437lookup_array_type_through_translation_units(const interned_string& type_name,
13438 const corpus & abi_corpus)
13439{
13440 array_type_def_sptr result;
13441
13442 for (translation_units::const_iterator tu =
13443 abi_corpus.get_translation_units().begin();
13444 tu != abi_corpus.get_translation_units().end();
13445 ++tu)
13446 if ((result = lookup_array_type(type_name, **tu)))
13447 break;
13448
13449 return result;
13450}
13451
13452/// Lookup a function type definition in all the translation units of
13453/// a given ABI corpus.
13454///
13455/// @param @param qn the fully qualified name of the function type to
13456/// lookup.
13457///
13458/// @param abi_corpus the ABI corpus which to look the type up in.
13459///
13460/// @return the type definition if any was found, or a NULL pointer.
13461static function_type_sptr
13462lookup_function_type_through_translation_units(const interned_string& type_name,
13463 const corpus & abi_corpus)
13464{
13465 function_type_sptr result;
13466
13467 for (translation_units::const_iterator tu =
13468 abi_corpus.get_translation_units().begin();
13469 tu != abi_corpus.get_translation_units().end();
13470 ++tu)
13471 if ((result = lookup_function_type(type_name, **tu)))
13472 break;
13473
13474 return result;
13475}
13476
13477/// Lookup a type definition in all the translation units of a given
13478/// ABI corpus.
13479///
13480/// @param @param qn the fully qualified name of the type to lookup.
13481///
13482/// @param abi_corpus the ABI corpus which to look the type up in.
13483///
13484/// @return the type definition if any was found, or a NULL pointer.
13485type_base_sptr
13487 const corpus& abi_corpus)
13488{
13489 type_base_sptr result;
13490
13491 for (translation_units::const_iterator tu =
13492 abi_corpus.get_translation_units().begin();
13493 tu != abi_corpus.get_translation_units().end();
13494 ++tu)
13495 if ((result = lookup_type(qn, **tu)))
13496 break;
13497
13498 return result;
13499}
13500
13501/// Lookup a type from a given translation unit present in a give corpus.
13502///
13503/// @param type_name the name of the type to look for.
13504///
13505/// @parm tu_path the path of the translation unit to consider.
13506///
13507/// @param corp the corpus to consider.
13508///
13509/// @return the resulting type, if any.
13510type_base_sptr
13512 const string& tu_path,
13513 const corpus& corp)
13514{
13515 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
13516 if (i == corp.priv_->path_tu_map.end())
13517 return type_base_sptr();
13518
13519 translation_unit_sptr tu = i->second;
13520 ABG_ASSERT(tu);
13521
13522 type_base_sptr t = lookup_type(type_name, *tu);
13523 return t;
13524}
13525
13526/// Look into an ABI corpus for a function type.
13527///
13528/// @param fn_type the function type to be looked for in the ABI
13529/// corpus.
13530///
13531/// @param corpus the ABI corpus into which to look for the function
13532/// type.
13533///
13534/// @return the function type found in the corpus.
13537 const corpus& corpus)
13538{
13539 ABG_ASSERT(fn_t);
13540
13541 function_type_sptr result;
13542
13543 if ((result = lookup_function_type(fn_t, corpus)))
13544 return result;
13545
13546 for (translation_units::const_iterator i =
13547 corpus.get_translation_units().begin();
13548 i != corpus.get_translation_units().end();
13549 ++i)
13551 **i)))
13552 return result;
13553
13554 return result;
13555}
13556
13557/// Look into a given corpus to find a type which has the same
13558/// qualified name as a giventype.
13559///
13560/// If the per-corpus type map is non-empty (because the corpus allows
13561/// the One Definition Rule) then the type islooked up in that
13562/// per-corpus type map. Otherwise, the type is looked-up in each
13563/// translation unit.
13564///
13565/// @param t the type which has the same qualified name as the type we
13566/// are looking for.
13567///
13568/// @param corp the ABI corpus to look into for the type.
13570lookup_basic_type(const type_decl& t, const corpus& corp)
13571{return lookup_basic_type(t.get_name(), corp);}
13572
13573/// Look into a given corpus to find a basic type which has a given
13574/// qualified name.
13575///
13576/// If the per-corpus type map is non-empty (because the corpus allows
13577/// the One Definition Rule) then the type islooked up in that
13578/// per-corpus type map. Otherwise, the type is looked-up in each
13579/// translation unit.
13580///
13581/// @param qualified_name the qualified name of the basic type to look
13582/// for.
13583///
13584/// @param corp the corpus to look into.
13586lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
13587{
13589 type_decl_sptr result;
13590
13591 if (!m.empty())
13592 result = lookup_type_in_map<type_decl>(qualified_name, m);
13593 else
13594 result = lookup_basic_type_through_translation_units(qualified_name, corp);
13595
13596 return result;
13597}
13598
13599/// Lookup a @ref type_decl type from a given corpus, by its location.
13600///
13601/// @param loc the location to consider.
13602///
13603/// @param corp the corpus to consider.
13604///
13605/// @return the resulting basic type, if any.
13608 const corpus &corp)
13609{
13612 type_decl_sptr result;
13613
13614 result = lookup_type_in_map<type_decl>(loc, m);
13615
13616 return result;
13617}
13618
13619/// Lookup a @ref type_decl type from a given corpus, by its location.
13620///
13621/// @param loc the location to consider.
13622///
13623/// @param corp the corpus to consider.
13624///
13625/// @return the resulting basic type, if any.
13627lookup_basic_type_per_location(const string &loc, const corpus &corp)
13628{
13629 const environment& env = corp.get_environment();
13630 return lookup_basic_type_per_location(env.intern(loc), corp);
13631}
13632
13633/// Look into a given corpus to find a basic type which has a given
13634/// qualified name.
13635///
13636/// If the per-corpus type map is non-empty (because the corpus allows
13637/// the One Definition Rule) then the type islooked up in that
13638/// per-corpus type map. Otherwise, the type is looked-up in each
13639/// translation unit.
13640///
13641/// @param qualified_name the qualified name of the basic type to look
13642/// for.
13643///
13644/// @param corp the corpus to look into.
13646lookup_basic_type(const string& qualified_name, const corpus& corp)
13647{
13648 return lookup_basic_type(corp.get_environment().intern(qualified_name),
13649 corp);
13650}
13651
13652/// Look into a given corpus to find a class type which has the same
13653/// qualified name as a given type.
13654///
13655/// If the per-corpus type map is non-empty (because the corpus allows
13656/// the One Definition Rule) then the type islooked up in that
13657/// per-corpus type map. Otherwise, the type is looked-up in each
13658/// translation unit.
13659///
13660/// @param t the class decl type which has the same qualified name as
13661/// the type we are looking for.
13662///
13663/// @param corp the corpus to look into.
13666{
13668 return lookup_class_type(s, corp);
13669}
13670
13671/// Look into a given corpus to find a class type which has a given
13672/// qualified name.
13673///
13674/// If the per-corpus type map is non-empty (because the corpus allows
13675/// the One Definition Rule) then the type islooked up in that
13676/// per-corpus type map. Otherwise, the type is looked-up in each
13677/// translation unit.
13678///
13679/// @param qualified_name the qualified name of the type to look for.
13680///
13681/// @param corp the corpus to look into.
13683lookup_class_type(const string& qualified_name, const corpus& corp)
13684{
13685 interned_string s = corp.get_environment().intern(qualified_name);
13686 return lookup_class_type(s, corp);
13687}
13688
13689/// Look into a given corpus to find a class type which has a given
13690/// qualified name.
13691///
13692/// If the per-corpus type map is non-empty (because the corpus allows
13693/// the One Definition Rule) then the type islooked up in that
13694/// per-corpus type map. Otherwise, the type is looked-up in each
13695/// translation unit.
13696///
13697/// @param qualified_name the qualified name of the type to look for.
13698///
13699/// @param corp the corpus to look into.
13701lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13702{
13704
13705 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13706
13707 return result;
13708}
13709
13710/// Look into a given corpus to find the class type*s* that have a
13711/// given qualified name.
13712///
13713/// @param qualified_name the qualified name of the type to look for.
13714///
13715/// @param corp the corpus to look into.
13716///
13717/// @return the vector of class types named @p qualified_name.
13719lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13720{
13722
13723 return lookup_types_in_map(qualified_name, m);
13724}
13725
13726/// Look into a given corpus to find the class type*s* that have a
13727/// given qualified name and that are declaration-only.
13728///
13729/// @param qualified_name the qualified name of the type to look for.
13730///
13731/// @param corp the corpus to look into.
13732///
13733/// @param result the vector of decl-only class types named @p
13734/// qualified_name. This is populated iff the function returns true.
13735///
13736/// @return true iff @p result was populated with the decl-only
13737/// classes named @p qualified_name.
13738bool
13740 const corpus& corp,
13741 type_base_wptrs_type& result)
13742{
13744
13745 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13746 if (!v)
13747 return false;
13748
13749 for (auto type : *v)
13750 {
13751 type_base_sptr t(type);
13753 if (c->get_is_declaration_only()
13754 && !c->get_definition_of_declaration())
13755 result.push_back(type);
13756 }
13757
13758 return !result.empty();
13759}
13760
13761/// Look into a given corpus to find the union type*s* that have a
13762/// given qualified name.
13763///
13764/// @param qualified_name the qualified name of the type to look for.
13765///
13766/// @param corp the corpus to look into.
13767///
13768/// @return the vector of union types named @p qualified_name.
13770lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13771{
13773
13774 return lookup_types_in_map(qualified_name, m);
13775}
13776
13777/// Look into a given corpus to find the class type*s* that have a
13778/// given qualified name.
13779///
13780/// @param qualified_name the qualified name of the type to look for.
13781///
13782/// @param corp the corpus to look into.
13783///
13784/// @return the vector of class types which name is @p qualified_name.
13786lookup_class_types(const string& qualified_name, const corpus& corp)
13787{
13788 interned_string s = corp.get_environment().intern(qualified_name);
13789 return lookup_class_types(s, corp);
13790}
13791
13792/// Look into a given corpus to find the union types that have a given
13793/// qualified name.
13794///
13795/// @param qualified_name the qualified name of the type to look for.
13796///
13797/// @param corp the corpus to look into.
13798///
13799/// @return the vector of union types which name is @p qualified_name.
13801lookup_union_types(const string& qualified_name, const corpus& corp)
13802{
13803 interned_string s = corp.get_environment().intern(qualified_name);
13804 return lookup_union_types(s, corp);
13805}
13806
13807/// Look up a @ref class_decl from a given corpus by its location.
13808///
13809/// @param loc the location to consider.
13810///
13811/// @param corp the corpus to consider.
13812///
13813/// @return the resulting class decl, if any.
13816 const corpus& corp)
13817{
13820 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13821
13822 return result;
13823}
13824
13825/// Look up a @ref class_decl from a given corpus by its location.
13826///
13827/// @param loc the location to consider.
13828///
13829/// @param corp the corpus to consider.
13830///
13831/// @return the resulting class decl, if any.
13833lookup_class_type_per_location(const string &loc, const corpus &corp)
13834{
13835 const environment& env = corp.get_environment();
13836 return lookup_class_type_per_location(env.intern(loc), corp);
13837}
13838
13839/// Look into a given corpus to find a union type which has a given
13840/// qualified name.
13841///
13842/// If the per-corpus type map is non-empty (because the corpus allows
13843/// the One Definition Rule) then the type islooked up in that
13844/// per-corpus type map. Otherwise, the type is looked-up in each
13845/// translation unit.
13846///
13847/// @param qualified_name the qualified name of the type to look for.
13848///
13849/// @param corp the corpus to look into.
13850union_decl_sptr
13851lookup_union_type(const interned_string& type_name, const corpus& corp)
13852{
13854
13855 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13856 if (!result)
13857 result = lookup_union_type_through_translation_units(type_name, corp);
13858
13859 return result;
13860}
13861
13862/// Look into a given corpus to find a union type which has a given
13863/// qualified name.
13864///
13865/// If the per-corpus type map is non-empty (because the corpus allows
13866/// the One Definition Rule) then the type islooked up in that
13867/// per-corpus type map. Otherwise, the type is looked-up in each
13868/// translation unit.
13869///
13870/// @param qualified_name the qualified name of the type to look for.
13871///
13872/// @param corp the corpus to look into.
13873union_decl_sptr
13874lookup_union_type(const string& type_name, const corpus& corp)
13875{
13876 interned_string s = corp.get_environment().intern(type_name);
13877 return lookup_union_type(s, corp);
13878}
13879
13880/// Look into a given corpus to find an enum type which has the same
13881/// qualified name as a given enum type.
13882///
13883/// If the per-corpus type map is non-empty (because the corpus allows
13884/// the One Definition Rule) then the type islooked up in that
13885/// per-corpus type map. Otherwise, the type is looked-up in each
13886/// translation unit.
13887///
13888/// @param t the enum type which has the same qualified name as the
13889/// type we are looking for.
13890///
13891/// @param corp the corpus to look into.
13894{
13896 return lookup_enum_type(s, corp);
13897}
13898
13899/// Look into a given corpus to find an enum type which has a given
13900/// qualified name.
13901///
13902/// If the per-corpus type map is non-empty (because the corpus allows
13903/// the One Definition Rule) then the type islooked up in that
13904/// per-corpus type map. Otherwise, the type is looked-up in each
13905/// translation unit.
13906///
13907/// @param qualified_name the qualified name of the enum type to look
13908/// for.
13909///
13910/// @param corp the corpus to look into.
13912lookup_enum_type(const string& qualified_name, const corpus& corp)
13913{
13914 interned_string s = corp.get_environment().intern(qualified_name);
13915 return lookup_enum_type(s, corp);
13916}
13917
13918/// Look into a given corpus to find an enum type which has a given
13919/// qualified name.
13920///
13921/// If the per-corpus type map is non-empty (because the corpus allows
13922/// the One Definition Rule) then the type islooked up in that
13923/// per-corpus type map. Otherwise, the type is looked-up in each
13924/// translation unit.
13925///
13926/// @param qualified_name the qualified name of the enum type to look
13927/// for.
13928///
13929/// @param corp the corpus to look into.
13931lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
13932{
13934
13935 enum_type_decl_sptr result =
13936 lookup_type_in_map<enum_type_decl>(qualified_name, m);
13937 if (!result)
13938 result = lookup_enum_type_through_translation_units(qualified_name, corp);
13939
13940 return result;
13941}
13942
13943/// Look into a given corpus to find the enum type*s* that have a
13944/// given qualified name.
13945///
13946/// @param qualified_name the qualified name of the type to look for.
13947///
13948/// @param corp the corpus to look into.
13949///
13950/// @return the vector of enum types that which name is @p qualified_name.
13952lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
13953{
13955
13956 return lookup_types_in_map(qualified_name, m);
13957}
13958
13959/// Look into a given corpus to find the enum type*s* that have a
13960/// given qualified name.
13961///
13962/// @param qualified_name the qualified name of the type to look for.
13963///
13964/// @param corp the corpus to look into.
13965///
13966/// @return the vector of enum types that which name is @p qualified_name.
13968lookup_enum_types(const string& qualified_name, const corpus& corp)
13969{
13970 interned_string s = corp.get_environment().intern(qualified_name);
13971 return lookup_enum_types(s, corp);
13972}
13973
13974/// Look up an @ref enum_type_decl from a given corpus, by its location.
13975///
13976/// @param loc the location to consider.
13977///
13978/// @param corp the corpus to look the type from.
13979///
13980/// @return the resulting enum type, if any.
13983{
13986 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
13987
13988 return result;
13989}
13990
13991/// Look up an @ref enum_type_decl from a given corpus, by its location.
13992///
13993/// @param loc the location to consider.
13994///
13995/// @param corp the corpus to look the type from.
13996///
13997/// @return the resulting enum type, if any.
13999lookup_enum_type_per_location(const string &loc, const corpus &corp)
14000{
14001 const environment& env = corp.get_environment();
14002 return lookup_enum_type_per_location(env.intern(loc), corp);
14003}
14004
14005/// Look into a given corpus to find a typedef type which has the
14006/// same qualified name as a given typedef type.
14007///
14008/// If the per-corpus type map is non-empty (because the corpus allows
14009/// the One Definition Rule) then the type islooked up in that
14010/// per-corpus type map. Otherwise, the type is looked-up in each
14011/// translation unit.
14012///
14013/// @param t the typedef type which has the same qualified name as the
14014/// typedef type we are looking for.
14015///
14016/// @param corp the corpus to look into.
14019{
14021 return lookup_typedef_type(s, corp);
14022}
14023
14024/// Look into a given corpus to find a typedef type which has the
14025/// same qualified name as a given typedef type.
14026///
14027/// If the per-corpus type map is non-empty (because the corpus allows
14028/// the One Definition Rule) then the type islooked up in that
14029/// per-corpus type map. Otherwise, the type is looked-up in each
14030/// translation unit.
14031///
14032/// @param t the typedef type which has the same qualified name as the
14033/// typedef type we are looking for.
14034///
14035/// @param corp the corpus to look into.
14037lookup_typedef_type(const string& qualified_name, const corpus& corp)
14038{
14039 interned_string s = corp.get_environment().intern(qualified_name);
14040 return lookup_typedef_type(s, corp);
14041}
14042
14043/// Look into a given corpus to find a typedef type which has a
14044/// given qualified name.
14045///
14046/// If the per-corpus type map is non-empty (because the corpus allows
14047/// the One Definition Rule) then the type islooked up in that
14048/// per-corpus type map. Otherwise, the type is looked-up in each
14049/// translation unit.
14050///
14051/// @param qualified_name the qualified name of the typedef type to
14052/// look for.
14053///
14054/// @param corp the corpus to look into.
14056lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
14057{
14059
14060 typedef_decl_sptr result =
14061 lookup_type_in_map<typedef_decl>(qualified_name, m);
14062 if (!result)
14063 result = lookup_typedef_type_through_translation_units(qualified_name,
14064 corp);
14065
14066 return result;
14067}
14068
14069/// Lookup a @ref typedef_decl from a corpus, by its location.
14070///
14071/// @param loc the location to consider.
14072///
14073/// @param corp the corpus to consider.
14074///
14075/// @return the typedef_decl found, if any.
14078{
14081 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
14082
14083 return result;
14084}
14085
14086/// Lookup a @ref typedef_decl from a corpus, by its location.
14087///
14088/// @param loc the location to consider.
14089///
14090/// @param corp the corpus to consider.
14091///
14092/// @return the typedef_decl found, if any.
14094lookup_typedef_type_per_location(const string &loc, const corpus &corp)
14095{
14096 const environment& env = corp.get_environment();
14097 return lookup_typedef_type_per_location(env.intern(loc), corp);
14098}
14099
14100/// Look into a corpus to find a class, union or typedef type which
14101/// has a given qualified name.
14102///
14103/// If the per-corpus type map is non-empty (because the corpus allows
14104/// the One Definition Rule) then the type islooked up in that
14105/// per-corpus type map. Otherwise, the type is looked-up in each
14106/// translation unit.
14107///
14108/// @param qualified_name the name of the type to find.
14109///
14110/// @param corp the corpus to look into.
14111///
14112/// @return the typedef or class type found.
14113type_base_sptr
14114lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
14115{
14116 type_base_sptr result = lookup_class_type(qualified_name, corp);
14117 if (!result)
14118 result = lookup_union_type(qualified_name, corp);
14119
14120 if (!result)
14121 result = lookup_typedef_type(qualified_name, corp);
14122 return result;
14123}
14124
14125/// Look into a corpus to find a class, typedef or enum type which has
14126/// a given qualified name.
14127///
14128/// If the per-corpus type map is non-empty (because the corpus allows
14129/// the One Definition Rule) then the type islooked up in that
14130/// per-corpus type map. Otherwise, the type is looked-up in each
14131/// translation unit.
14132///
14133/// @param qualified_name the qualified name of the type to look for.
14134///
14135/// @param corp the corpus to look into.
14136///
14137/// @return the typedef, class or enum type found.
14138type_base_sptr
14139lookup_class_typedef_or_enum_type(const string& qualified_name,
14140 const corpus& corp)
14141{
14142 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
14143 if (!result)
14144 result = lookup_enum_type(qualified_name, corp);
14145
14146 return result;
14147}
14148
14149/// Look into a given corpus to find a qualified type which has the
14150/// same qualified name as a given type.
14151///
14152/// @param t the type which has the same qualified name as the
14153/// qualified type we are looking for.
14154///
14155/// @param corp the corpus to look into.
14156///
14157/// @return the qualified type found.
14158qualified_type_def_sptr
14160{
14162 return lookup_qualified_type(s, corp);
14163}
14164
14165/// Look into a given corpus to find a qualified type which has a
14166/// given qualified name.
14167///
14168/// @param qualified_name the qualified name of the type to look for.
14169///
14170/// @param corp the corpus to look into.
14171///
14172/// @return the type found.
14173qualified_type_def_sptr
14174lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
14175{
14177 corp.get_types().qualified_types();
14178
14179 qualified_type_def_sptr result =
14180 lookup_type_in_map<qualified_type_def>(qualified_name, m);
14181
14182 if (!result)
14183 result = lookup_qualified_type_through_translation_units(qualified_name,
14184 corp);
14185
14186 return result;
14187}
14188
14189/// Look into a given corpus to find a pointer type which has the same
14190/// qualified name as a given pointer type.
14191///
14192/// @param t the pointer type which has the same qualified name as the
14193/// type we are looking for.
14194///
14195/// @param corp the corpus to look into.
14196///
14197/// @return the pointer type found.
14200{
14202 return lookup_pointer_type(s, corp);
14203}
14204
14205/// Look into a given corpus to find a pointer type which has a given
14206/// qualified name.
14207///
14208/// If the per-corpus type map is non-empty (because the corpus allows
14209/// the One Definition Rule) then the type islooked up in that
14210/// per-corpus type map. Otherwise, the type is looked-up in each
14211/// translation unit.
14212///
14213/// @param qualified_name the qualified name of the pointer type to
14214/// look for.
14215///
14216/// @param corp the corpus to look into.
14217///
14218/// @return the pointer type found.
14220lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
14221{
14223
14224 pointer_type_def_sptr result =
14225 lookup_type_in_map<pointer_type_def>(qualified_name, m);
14226 if (!result)
14227 result = lookup_pointer_type_through_translation_units(qualified_name,
14228 corp);
14229
14230 return result;
14231}
14232
14233/// Look into a given corpus to find a reference type which has the
14234/// same qualified name as a given reference type.
14235///
14236/// If the per-corpus type map is non-empty (because the corpus allows
14237/// the One Definition Rule) then the type islooked up in that
14238/// per-corpus type map. Otherwise, the type is looked-up in each
14239/// translation unit.
14240///
14241/// @param t the reference type which has the same qualified name as
14242/// the reference type we are looking for.
14243///
14244/// @param corp the corpus to look into.
14245///
14246/// @return the reference type found.
14249{
14251 return lookup_reference_type(s, corp);
14252}
14253
14254/// Look into a given corpus to find a reference type which has a
14255/// given qualified name.
14256///
14257/// If the per-corpus type map is non-empty (because the corpus allows
14258/// the One Definition Rule) then the type islooked up in that
14259/// per-corpus type map. Otherwise, the type is looked-up in each
14260/// translation unit.
14261///
14262/// @param qualified_name the qualified name of the reference type to
14263/// look for.
14264///
14265/// @param corp the corpus to look into.
14266///
14267/// @return the reference type found.
14269lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
14270{
14272 corp.get_types().reference_types();
14273
14275 lookup_type_in_map<reference_type_def>(qualified_name, m);
14276 if (!result)
14277 result = lookup_reference_type_through_translation_units(qualified_name,
14278 corp);
14279
14280 return result;
14281}
14282
14283/// Look into a given corpus to find an array type which has a given
14284/// qualified name.
14285///
14286/// If the per-corpus type map is non-empty (because the corpus allows
14287/// the One Definition Rule) then the type islooked up in that
14288/// per-corpus type map. Otherwise, the type is looked-up in each
14289/// translation unit.
14290///
14291/// @param qualified_name the qualified name of the array type to look
14292/// for.
14293///
14294/// @param corp the corpus to look into.
14295///
14296/// @return the array type found.
14299{
14301 return lookup_array_type(s, corp);
14302}
14303
14304/// Look into a given corpus to find an array type which has the same
14305/// qualified name as a given array type.
14306///
14307/// If the per-corpus type map is non-empty (because the corpus allows
14308/// the One Definition Rule) then the type islooked up in that
14309/// per-corpus type map. Otherwise, the type is looked-up in each
14310/// translation unit.
14311///
14312/// @param t the type which has the same qualified name as the type we
14313/// are looking for.
14314///
14315/// @param corp the corpus to look into.
14316///
14317/// @return the type found.
14319lookup_array_type(const interned_string& qualified_name, const corpus& corp)
14320{
14322
14323 array_type_def_sptr result =
14324 lookup_type_in_map<array_type_def>(qualified_name, m);
14325 if (!result)
14326 result = lookup_array_type_through_translation_units(qualified_name, corp);
14327
14328 return result;
14329}
14330
14331/// Look into a given corpus to find a function type which has the same
14332/// qualified name as a given function type.
14333///
14334/// If the per-corpus type map is non-empty (because the corpus allows
14335/// the One Definition Rule) then the type islooked up in that
14336/// per-corpus type map. Otherwise, the type is looked-up in each
14337/// translation unit.
14338///
14339/// @param t the function type which has the same qualified name as
14340/// the function type we are looking for.
14341///
14342/// @param corp the corpus to look into.
14343///
14344/// @return the function type found.
14347{
14348 interned_string type_name = get_type_name(t);
14349 return lookup_function_type(type_name, corp);
14350}
14351
14352/// Look into a given corpus to find a function type which has the same
14353/// qualified name as a given function type.
14354///
14355/// If the per-corpus type map is non-empty (because the corpus allows
14356/// the One Definition Rule) then the type islooked up in that
14357/// per-corpus type map. Otherwise, the type is looked-up in each
14358/// translation unit.
14359///
14360/// @param t the function type which has the same qualified name as
14361/// the function type we are looking for.
14362///
14363/// @param corp the corpus to look into.
14364///
14365/// @return the function type found.
14368 const corpus& corpus)
14369{
14370 if (fn_t)
14371 return lookup_function_type(*fn_t, corpus);
14372 return function_type_sptr();
14373}
14374
14375/// Look into a given corpus to find a function type which has a given
14376/// qualified name.
14377///
14378/// If the per-corpus type map is non-empty (because the corpus allows
14379/// the One Definition Rule) then the type islooked up in that
14380/// per-corpus type map. Otherwise, the type is looked-up in each
14381/// translation unit.
14382///
14383/// @param qualified_name the qualified name of the function type to
14384/// look for.
14385///
14386/// @param corp the corpus to look into.
14387///
14388/// @return the function type found.
14390lookup_function_type(const interned_string& qualified_name, const corpus& corp)
14391{
14393
14394 function_type_sptr result =
14395 lookup_type_in_map<function_type>(qualified_name, m);
14396 if (!result)
14397 result = lookup_function_type_through_translation_units(qualified_name,
14398 corp);
14399
14400 return result;
14401}
14402
14403/// Look into a given corpus to find a type which has a given
14404/// qualified name.
14405///
14406/// If the per-corpus type map is non-empty (because the corpus allows
14407/// the One Definition Rule) then the type islooked up in that
14408/// per-corpus type map. Otherwise, the type is looked-up in each
14409/// translation unit.
14410///
14411/// @param qualified_name the qualified name of the function type to
14412/// look for.
14413///
14414/// @param corp the corpus to look into.
14415///
14416/// @return the function type found.
14417type_base_sptr
14418lookup_type(const interned_string& n, const corpus& corp)
14419{
14420 type_base_sptr result;
14421
14422 ((result = lookup_basic_type(n, corp))
14423 || (result = lookup_class_type(n, corp))
14424 || (result = lookup_union_type(n, corp))
14425 || (result = lookup_enum_type(n, corp))
14426 || (result = lookup_typedef_type(n, corp))
14427 || (result = lookup_qualified_type(n, corp))
14428 || (result = lookup_pointer_type(n, corp))
14429 || (result = lookup_reference_type(n, corp))
14430 || (result = lookup_array_type(n, corp))
14431 || (result= lookup_function_type(n, corp)));
14432
14433 return result;
14434}
14435
14436/// Lookup a type from a corpus, by its location.
14437///
14438/// @param loc the location to consider.
14439///
14440/// @param corp the corpus to look the type from.
14441///
14442/// @return the resulting type, if any found.
14443type_base_sptr
14445{
14446 // TODO: finish this.
14447
14448 //TODO: when we fully support types indexed by their location, this
14449 //function should return a vector of types because at each location,
14450 //there can be several types that are defined (yay, C and C++,
14451 //*sigh*).
14452
14453 type_base_sptr result;
14454 ((result = lookup_basic_type_per_location(loc, corp))
14455 || (result = lookup_class_type_per_location(loc, corp))
14456 || (result = lookup_union_type_per_location(loc, corp))
14457 || (result = lookup_enum_type_per_location(loc, corp))
14458 || (result = lookup_typedef_type_per_location(loc, corp)));
14459
14460 return result;
14461}
14462
14463/// Look into a given corpus to find a type
14464///
14465/// If the per-corpus type map is non-empty (because the corpus allows
14466/// the One Definition Rule) then the type islooked up in that
14467/// per-corpus type map. Otherwise, the type is looked-up in each
14468/// translation unit.
14469///
14470/// @param qualified_name the qualified name of the function type to
14471/// look for.
14472///
14473/// @param corp the corpus to look into.
14474///
14475/// @return the function type found.
14476type_base_sptr
14477lookup_type(const type_base&t, const corpus& corp)
14478{
14480 return lookup_type(n, corp);
14481}
14482
14483/// Look into a given corpus to find a type
14484///
14485/// If the per-corpus type map is non-empty (because the corpus allows
14486/// the One Definition Rule) then the type islooked up in that
14487/// per-corpus type map. Otherwise, the type is looked-up in each
14488/// translation unit.
14489///
14490/// @param qualified_name the qualified name of the function type to
14491/// look for.
14492///
14493/// @param corp the corpus to look into.
14494///
14495/// @return the function type found.
14496type_base_sptr
14497lookup_type(const type_base_sptr&t, const corpus& corp)
14498{
14499 if (t)
14500 return lookup_type(*t, corp);
14501 return type_base_sptr();
14502}
14503
14504/// Update the map that associates a fully qualified name of a given
14505/// type to that type.
14506///
14507///
14508/// @param type the type we are considering.
14509///
14510/// @param types_map the map to update. It's a map that assciates a
14511/// fully qualified name of a type to the type itself.
14512///
14513/// @param use_type_name_as_key if true, use the name of the type as
14514/// the key to look it up later. If false, then use the location of
14515/// the type as a key to look it up later.
14516///
14517/// @return true iff the type was added to the map.
14518template<typename TypeKind>
14519bool
14520maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
14522 bool use_type_name_as_key = true)
14523{
14525
14526 if (use_type_name_as_key)
14527 s = get_type_name(type);
14528 else if (location l = type->get_location())
14529 {
14530 string str = l.expand();
14531 s = type->get_environment().intern(str);
14532 }
14533
14534 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14535 bool result = false;
14536
14537 if (i == types_map.end())
14538 {
14539 types_map[s].push_back(type);
14540 result = true;
14541 }
14542 else
14543 i->second.push_back(type);
14544
14545 return result;
14546}
14547
14548/// This is the specialization for type @ref class_decl of the
14549/// function template:
14550///
14551/// maybe_update_types_lookup_map<T>(scope_decl*,
14552/// const shared_ptr<T>&,
14553/// istring_type_base_wptrs_map_type&)
14554///
14555/// @param class_type the type to consider.
14556///
14557/// @param types_map the type map to update.
14558///
14559/// @return true iff the type was added to the map.
14560template<>
14561bool
14564 bool use_type_name_as_key)
14565{
14566 class_decl_sptr type = class_type;
14567
14568 bool update_qname_map = true;
14569 if (type->get_is_declaration_only())
14570 {
14571 // Let's try to look through decl-only classes to get their
14572 // definition. But if the class doesn't have a definition then
14573 // we'll keep it.
14574 if (class_decl_sptr def =
14575 is_class_type(class_type->get_definition_of_declaration()))
14576 type = def;
14577 }
14578
14579 if (!update_qname_map)
14580 return false;
14581
14583 if (use_type_name_as_key)
14584 {
14585 string qname = type->get_qualified_name();
14586 s = type->get_environment().intern(qname);
14587 }
14588 else if (location l = type->get_location())
14589 {
14590 string str = l.expand();
14591 s = type->get_environment().intern(str);
14592 }
14593
14594 bool result = false;
14595 istring_type_base_wptrs_map_type::iterator i = map.find(s);
14596 if (i == map.end())
14597 {
14598 map[s].push_back(type);
14599 result = true;
14600 }
14601 else
14602 i->second.push_back(type);
14603
14604 return result;
14605}
14606
14607/// This is the specialization for type @ref function_type of the
14608/// function template:
14609///
14610/// maybe_update_types_lookup_map<T>(scope_decl*,
14611/// const shared_ptr<T>&,
14612/// istring_type_base_wptrs_map_type&)
14613///
14614/// @param scope the scope of the type to consider.
14615///
14616/// @param class_type the type to consider.
14617///
14618/// @param types_map the type map to update.
14619///
14620/// @return true iff the type was added to the map.
14621template<>
14622bool
14624(const function_type_sptr& type,
14626 bool /*use_type_name_as_key*/)
14627{
14628 bool result = false;
14630 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14631 if (i == types_map.end())
14632 {
14633 types_map[s].push_back(type);
14634 result = true;
14635 }
14636 else
14637 i->second.push_back(type);
14638
14639 return result;
14640}
14641
14642/// Update the map that associates the fully qualified name of a basic
14643/// type with the type itself.
14644///
14645/// The per-translation unit type map is updated if no type with this
14646/// name was already existing in that map.
14647///
14648/// If no type with this name did already exist in the per-corpus type
14649/// map, then that per-corpus type map is updated. Otherwise, that
14650/// type is erased from that per-corpus map.
14651///
14652/// @param basic_type the basic type to consider.
14653void
14655{
14656 if (translation_unit *tu = basic_type->get_translation_unit())
14657 maybe_update_types_lookup_map<type_decl>
14658 (basic_type, tu->get_types().basic_types());
14659
14660 if (corpus *type_corpus = basic_type->get_corpus())
14661 {
14662 maybe_update_types_lookup_map<type_decl>
14663 (basic_type,
14664 type_corpus->priv_->get_types().basic_types());
14665
14666 maybe_update_types_lookup_map<type_decl>
14667 (basic_type,
14668 type_corpus->get_type_per_loc_map().basic_types(),
14669 /*use_type_name_as_key*/false);
14670
14671 if (corpus *group = type_corpus->get_group())
14672 {
14673 maybe_update_types_lookup_map<type_decl>
14674 (basic_type,
14675 group->priv_->get_types().basic_types());
14676
14677 maybe_update_types_lookup_map<type_decl>
14678 (basic_type,
14679 group->get_type_per_loc_map().basic_types(),
14680 /*use_type_name_as_key*/false);
14681 }
14682 }
14683
14684}
14685
14686/// Update the map that associates the fully qualified name of a class
14687/// type with the type itself.
14688///
14689/// The per-translation unit type map is updated if no type with this
14690/// name was already existing in that map.
14691///
14692/// If no type with this name did already exist in the per-corpus type
14693/// map, then that per-corpus type map is updated. Otherwise, that
14694/// type is erased from that per-corpus map.
14695///
14696/// @param class_type the class type to consider.
14697void
14699{
14700 if (translation_unit *tu = class_type->get_translation_unit())
14702 (class_type, tu->get_types().class_types());
14703
14704 if (corpus *type_corpus = class_type->get_corpus())
14705 {
14707 (class_type,
14708 type_corpus->priv_->get_types().class_types());
14709
14711 (class_type,
14712 type_corpus->get_type_per_loc_map().class_types(),
14713 /*use_type_name_as_key*/false);
14714
14715 if (corpus *group = type_corpus->get_group())
14716 {
14718 (class_type,
14719 group->priv_->get_types().class_types());
14720
14722 (class_type,
14723 group->get_type_per_loc_map().class_types(),
14724 /*use_type_name_as_key*/false);
14725 }
14726 }
14727}
14728
14729/// Update the map that associates the fully qualified name of a union
14730/// type with the type itself.
14731///
14732/// The per-translation unit type map is updated if no type with this
14733/// name was already existing in that map.
14734///
14735/// If no type with this name did already exist in the per-corpus type
14736/// map, then that per-corpus type map is updated. Otherwise, that
14737/// type is erased from that per-corpus map.
14738///
14739/// @param union_type the union type to consider.
14740void
14741maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14742{
14743 if (translation_unit *tu = union_type->get_translation_unit())
14744 maybe_update_types_lookup_map<union_decl>
14745 (union_type, tu->get_types().union_types());
14746
14747 if (corpus *type_corpus = union_type->get_corpus())
14748 {
14749 maybe_update_types_lookup_map<union_decl>
14750 (union_type,
14751 type_corpus->priv_->get_types().union_types());
14752
14753 maybe_update_types_lookup_map<union_decl>
14754 (union_type,
14755 type_corpus->get_type_per_loc_map().union_types(),
14756 /*use_type_name_as_key*/false);
14757
14758 if (corpus *group = type_corpus->get_group())
14759 {
14760 maybe_update_types_lookup_map<union_decl>
14761 (union_type,
14762 group->priv_->get_types().union_types());
14763
14764 maybe_update_types_lookup_map<union_decl>
14765 (union_type,
14766 group->get_type_per_loc_map().union_types(),
14767 /*use_type_name_as_key*/false);
14768 }
14769 }
14770}
14771
14772/// Update the map that associates the fully qualified name of an enum
14773/// type with the type itself.
14774///
14775/// The per-translation unit type map is updated if no type with this
14776/// name was already existing in that map.
14777///
14778/// If no type with this name did already exist in the per-corpus type
14779/// map, then that per-corpus type map is updated. Otherwise, that
14780/// type is erased from that per-corpus map.
14781///
14782/// @param enum_type the type to consider.
14783void
14785{
14786 if (translation_unit *tu = enum_type->get_translation_unit())
14787 maybe_update_types_lookup_map<enum_type_decl>
14788 (enum_type, tu->get_types().enum_types());
14789
14790 if (corpus *type_corpus = enum_type->get_corpus())
14791 {
14792 maybe_update_types_lookup_map<enum_type_decl>
14793 (enum_type,
14794 type_corpus->priv_->get_types().enum_types());
14795
14796 maybe_update_types_lookup_map<enum_type_decl>
14797 (enum_type,
14798 type_corpus->get_type_per_loc_map().enum_types(),
14799 /*use_type_name_as_key*/false);
14800
14801 if (corpus *group = type_corpus->get_group())
14802 {
14803 maybe_update_types_lookup_map<enum_type_decl>
14804 (enum_type,
14805 group->priv_->get_types().enum_types());
14806
14807 maybe_update_types_lookup_map<enum_type_decl>
14808 (enum_type,
14809 group->get_type_per_loc_map().enum_types(),
14810 /*use_type_name_as_key*/false);
14811 }
14812 }
14813
14814}
14815
14816/// Update the map that associates the fully qualified name of a
14817/// typedef type with the type itself.
14818///
14819/// The per-translation unit type map is updated if no type with this
14820/// name was already existing in that map.
14821///
14822/// If no type with this name did already exist in the per-corpus type
14823/// map, then that per-corpus type map is updated. Otherwise, that
14824/// type is erased from that per-corpus map.
14825///
14826/// @param typedef_type the type to consider.
14827void
14829{
14830 if (translation_unit *tu = typedef_type->get_translation_unit())
14831 maybe_update_types_lookup_map<typedef_decl>
14832 (typedef_type, tu->get_types().typedef_types());
14833
14834 if (corpus *type_corpus = typedef_type->get_corpus())
14835 {
14836 maybe_update_types_lookup_map<typedef_decl>
14837 (typedef_type,
14838 type_corpus->priv_->get_types().typedef_types());
14839
14840 maybe_update_types_lookup_map<typedef_decl>
14841 (typedef_type,
14842 type_corpus->get_type_per_loc_map().typedef_types(),
14843 /*use_type_name_as_key*/false);
14844
14845 if (corpus *group = type_corpus->get_group())
14846 {
14847 maybe_update_types_lookup_map<typedef_decl>
14848 (typedef_type,
14849 group->priv_->get_types().typedef_types());
14850
14851 maybe_update_types_lookup_map<typedef_decl>
14852 (typedef_type,
14853 group->get_type_per_loc_map().typedef_types(),
14854 /*use_type_name_as_key*/false);
14855 }
14856 }
14857}
14858
14859/// Update the map that associates the fully qualified name of a
14860/// qualified type with the type itself.
14861///
14862/// The per-translation unit type map is updated if no type with this
14863/// name was already existing in that map.
14864///
14865/// If no type with this name did already exist in the per-corpus type
14866/// map, then that per-corpus type map is updated. Otherwise, that
14867/// type is erased from that per-corpus map.
14868///
14869/// @param qualified_type the type to consider.
14870void
14871maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14872{
14873 if (translation_unit *tu = qualified_type->get_translation_unit())
14874 maybe_update_types_lookup_map<qualified_type_def>
14875 (qualified_type, tu->get_types().qualified_types());
14876
14877 if (corpus *type_corpus = qualified_type->get_corpus())
14878 {
14879 maybe_update_types_lookup_map<qualified_type_def>
14880 (qualified_type,
14881 type_corpus->priv_->get_types().qualified_types());
14882
14883 if (corpus *group = type_corpus->get_group())
14884 {
14885 maybe_update_types_lookup_map<qualified_type_def>
14886 (qualified_type,
14887 group->priv_->get_types().qualified_types());
14888 }
14889 }
14890}
14891
14892/// Update the map that associates the fully qualified name of a
14893/// pointer type with the type itself.
14894///
14895/// The per-translation unit type map is updated if no type with this
14896/// name was already existing in that map.
14897///
14898/// If no type with this name did already exist in the per-corpus type
14899/// map, then that per-corpus type map is updated. Otherwise, that
14900/// type is erased from that per-corpus map.
14901///
14902/// @param pointer_type the type to consider.
14903void
14905{
14906 if (translation_unit *tu = pointer_type->get_translation_unit())
14907 maybe_update_types_lookup_map<pointer_type_def>
14908 (pointer_type, tu->get_types().pointer_types());
14909
14910 if (corpus *type_corpus = pointer_type->get_corpus())
14911 {
14912 maybe_update_types_lookup_map<pointer_type_def>
14913 (pointer_type,
14914 type_corpus->priv_->get_types().pointer_types());
14915
14916 if (corpus *group = type_corpus->get_group())
14917 {
14918 maybe_update_types_lookup_map<pointer_type_def>
14919 (pointer_type,
14920 group->priv_->get_types().pointer_types());
14921 }
14922 }
14923}
14924
14925/// Update the map that associates the fully qualified name of a
14926/// pointer-to-member type with the type itself.
14927///
14928/// The per-translation unit type map is updated if no type with this
14929/// name was already existing in that map.
14930///
14931/// If no type with this name did already exist in the per-corpus type
14932/// map, then that per-corpus type map is updated. Otherwise, that
14933/// type is erased from that per-corpus map.
14934///
14935/// @param ptr_to_mbr_type the type to consider.
14936void
14938{
14939 if (translation_unit *tu = ptr_to_member->get_translation_unit())
14940 maybe_update_types_lookup_map<ptr_to_mbr_type>
14941 (ptr_to_member, tu->get_types().ptr_to_mbr_types());
14942
14943 if (corpus *type_corpus = ptr_to_member->get_corpus())
14944 {
14945 maybe_update_types_lookup_map<ptr_to_mbr_type>
14946 (ptr_to_member,
14947 type_corpus->priv_->get_types().ptr_to_mbr_types());
14948
14949 if (corpus *group = type_corpus->get_group())
14950 {
14951 maybe_update_types_lookup_map<ptr_to_mbr_type>
14952 (ptr_to_member,
14953 group->priv_->get_types().ptr_to_mbr_types());
14954 }
14955 }
14956}
14957
14958/// Update the map that associates the fully qualified name of a
14959/// reference type with the type itself.
14960///
14961/// The per-translation unit type map is updated if no type with this
14962/// name was already existing in that map.
14963///
14964/// If no type with this name did already exist in the per-corpus type
14965/// map, then that per-corpus type map is updated. Otherwise, that
14966/// type is erased from that per-corpus map.
14967///
14968/// @param reference_type the type to consider.
14969void
14971{
14972 if (translation_unit *tu = reference_type->get_translation_unit())
14973 maybe_update_types_lookup_map<reference_type_def>
14974 (reference_type, tu->get_types().reference_types());
14975
14976 if (corpus *type_corpus = reference_type->get_corpus())
14977 {
14978 maybe_update_types_lookup_map<reference_type_def>
14979 (reference_type,
14980 type_corpus->priv_->get_types().reference_types());
14981
14982 if (corpus *group = type_corpus->get_group())
14983 {
14984 maybe_update_types_lookup_map<reference_type_def>
14985 (reference_type,
14986 group->priv_->get_types().reference_types());
14987 }
14988 }
14989}
14990
14991/// Update the map that associates the fully qualified name of a type
14992/// with the type itself.
14993///
14994/// The per-translation unit type map is updated if no type with this
14995/// name was already existing in that map.
14996///
14997/// If no type with this name did already exist in the per-corpus type
14998/// map, then that per-corpus type map is updated. Otherwise, that
14999/// type is erased from that per-corpus map.
15000///
15001/// @param array_type the type to consider.
15002void
15004{
15005 if (translation_unit *tu = array_type->get_translation_unit())
15006 maybe_update_types_lookup_map<array_type_def>
15007 (array_type, tu->get_types().array_types());
15008
15009 if (corpus *type_corpus = array_type->get_corpus())
15010 {
15011 maybe_update_types_lookup_map<array_type_def>
15012 (array_type,
15013 type_corpus->priv_->get_types().array_types());
15014
15015 maybe_update_types_lookup_map<array_type_def>
15016 (array_type,
15017 type_corpus->get_type_per_loc_map().array_types(),
15018 /*use_type_name_as_key*/false);
15019
15020 if (corpus *group = type_corpus->get_group())
15021 {
15022 maybe_update_types_lookup_map<array_type_def>
15023 (array_type,
15024 group->priv_->get_types().array_types());
15025
15026 maybe_update_types_lookup_map<array_type_def>
15027 (array_type,
15028 group->get_type_per_loc_map().array_types(),
15029 /*use_type_name_as_key*/false);
15030 }
15031 }
15032}
15033
15034/// Update the map that associates the fully qualified name of a type
15035/// with the type itself.
15036///
15037/// The per-translation unit type map is updated if no type with this
15038/// name was already existing in that map.
15039///
15040/// If no type with this name did already exist in the per-corpus type
15041/// map, then that per-corpus type map is updated. Otherwise, that
15042/// type is erased from that per-corpus map.
15043///
15044/// @param subrange_type the type to consider.
15045void
15047(const array_type_def::subrange_sptr& subrange_type)
15048{
15049 if (translation_unit *tu = subrange_type->get_translation_unit())
15050 maybe_update_types_lookup_map<array_type_def::subrange_type>
15051 (subrange_type, tu->get_types().subrange_types());
15052
15053 if (corpus *type_corpus = subrange_type->get_corpus())
15054 {
15055 maybe_update_types_lookup_map<array_type_def::subrange_type>
15056 (subrange_type,
15057 type_corpus->priv_->get_types().subrange_types());
15058
15059 maybe_update_types_lookup_map<array_type_def::subrange_type>
15060 (subrange_type,
15061 type_corpus->get_type_per_loc_map().subrange_types(),
15062 /*use_type_name_as_key*/false);
15063
15064 if (corpus *group = subrange_type->get_corpus())
15065 {
15066 maybe_update_types_lookup_map<array_type_def::subrange_type>
15067 (subrange_type,
15068 group->priv_->get_types().subrange_types());
15069
15070 maybe_update_types_lookup_map<array_type_def::subrange_type>
15071 (subrange_type,
15072 group->get_type_per_loc_map().subrange_types(),
15073 /*use_type_name_as_key*/false);
15074 }
15075 }
15076}
15077
15078/// Update the map that associates the fully qualified name of a
15079/// function type with the type itself.
15080///
15081/// The per-translation unit type map is updated if no type with this
15082/// name was already existing in that map.
15083///
15084/// If no type with this name did already exist in the per-corpus type
15085/// map, then that per-corpus type map is updated. Otherwise, that
15086/// type is erased from that per-corpus map.
15087///
15088/// @param scope the scope of the function type.
15089/// @param fn_type the type to consider.
15090void
15092{
15093 if (translation_unit *tu = fn_type->get_translation_unit())
15095 (fn_type, tu->get_types().function_types());
15096
15097 if (corpus *type_corpus = fn_type->get_corpus())
15098 {
15100 (fn_type,
15101 type_corpus->priv_->get_types().function_types());
15102
15103 if (corpus *group = fn_type->get_corpus())
15104 {
15106 (fn_type,
15107 group->priv_->get_types().function_types());
15108 }
15109 }
15110}
15111
15112/// Update the map that associates the fully qualified name of a type
15113/// declaration with the type itself.
15114///
15115/// The per-translation unit type map is updated if no type with this
15116/// name was already existing in that map.
15117///
15118/// If no type with this name did already exist in the per-corpus type
15119/// map, then that per-corpus type map is updated. Otherwise, that
15120/// type is erased from that per-corpus map.
15121///
15122/// @param decl the declaration of the type to consider.
15123void
15124maybe_update_types_lookup_map(const decl_base_sptr& decl)
15125{
15126 if (!is_type(decl))
15127 return;
15128
15129 if (type_decl_sptr basic_type = is_type_decl(decl))
15131 else if (class_decl_sptr class_type = is_class_type(decl))
15133 else if (union_decl_sptr union_type = is_union_type(decl))
15135 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
15137 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
15138 maybe_update_types_lookup_map(typedef_type);
15139 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
15140 maybe_update_types_lookup_map(qualified_type);
15141 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
15142 maybe_update_types_lookup_map(pointer_type);
15143 else if (ptr_to_mbr_type_sptr ptr_to_member = is_ptr_to_mbr_type(decl))
15144 maybe_update_types_lookup_map(ptr_to_member);
15145 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
15146 maybe_update_types_lookup_map(reference_type);
15147 else if (array_type_def_sptr array_type = is_array_type(decl))
15149 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
15150 maybe_update_types_lookup_map(subrange_type);
15151 else if (function_type_sptr fn_type = is_function_type(decl))
15153 else
15155}
15156
15157/// Update the map that associates the fully qualified name of a type
15158/// with the type itself.
15159///
15160/// The per-translation unit type map is updated if no type with this
15161/// name was already existing in that map.
15162///
15163/// If no type with this name did already exist in the per-corpus type
15164/// map, then that per-corpus type map is updated. Otherwise, that
15165/// type is erased from that per-corpus map.
15166///
15167/// @param type the type to consider.
15168void
15169maybe_update_types_lookup_map(const type_base_sptr& type)
15170{
15171 if (decl_base_sptr decl = get_type_declaration(type))
15173 else if (function_type_sptr fn_type = is_function_type(type))
15175 else
15177}
15178
15179//--------------------------------
15180// </type and decls lookup stuff>
15181// ------------------------------
15182
15183/// In a translation unit, lookup a given type or synthesize it if
15184/// it's a qualified type.
15185///
15186/// So this function first looks the type up in the translation unit.
15187/// If it's found, then OK, it's returned. Otherwise, if it's a
15188/// qualified, reference or pointer or function type (a composite
15189/// type), lookup the underlying type, synthesize the type we want
15190/// from it and return it.
15191///
15192/// If the underlying types is not not found, then give up and return
15193/// nil.
15194///
15195/// @return the type that was found or the synthesized type.
15196type_base_sptr
15197synthesize_type_from_translation_unit(const type_base_sptr& type,
15198 translation_unit& tu)
15199{
15200 type_base_sptr result;
15201
15202 result = lookup_type(type, tu);
15203
15204 if (!result)
15205 {
15206 if (qualified_type_def_sptr qual = is_qualified_type(type))
15207 {
15208 type_base_sptr underlying_type =
15209 synthesize_type_from_translation_unit(qual->get_underlying_type(),
15210 tu);
15211 if (underlying_type)
15212 {
15213 result.reset(new qualified_type_def(underlying_type,
15214 qual->get_cv_quals(),
15215 qual->get_location()));
15216 }
15217 }
15218 else if (pointer_type_def_sptr p = is_pointer_type(type))
15219 {
15220 type_base_sptr pointed_to_type =
15221 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
15222 tu);
15223 if (pointed_to_type)
15224 {
15225 result.reset(new pointer_type_def(pointed_to_type,
15226 p->get_size_in_bits(),
15227 p->get_alignment_in_bits(),
15228 p->get_location()));
15229 }
15230 }
15231 else if (reference_type_def_sptr r = is_reference_type(type))
15232 {
15233 type_base_sptr pointed_to_type =
15234 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
15235 if (pointed_to_type)
15236 {
15237 result.reset(new reference_type_def(pointed_to_type,
15238 r->is_lvalue(),
15239 r->get_size_in_bits(),
15240 r->get_alignment_in_bits(),
15241 r->get_location()));
15242 }
15243 }
15244 else if (function_type_sptr f = is_function_type(type))
15246
15247 if (result)
15248 {
15250 canonicalize(result);
15251 }
15252 }
15253
15254 if (result)
15255 tu.priv_->synthesized_types_.push_back(result);
15256
15257 return result;
15258}
15259
15260/// In a translation unit, lookup the sub-types that make up a given
15261/// function type and if the sub-types are all found, synthesize and
15262/// return a function_type with them.
15263///
15264/// This function is like lookup_function_type_in_translation_unit()
15265/// execept that it constructs the function type from the sub-types
15266/// found in the translation, rather than just looking for the
15267/// function types held by the translation unit. This can be useful
15268/// if the translation unit doesnt hold the function type we are
15269/// looking for (i.e, lookup_function_type_in_translation_unit()
15270/// returned NULL) but we still want to see if the sub-types of the
15271/// function types are present in the translation unit.
15272///
15273/// @param fn_type the function type to consider.
15274///
15275/// @param tu the translation unit to look into.
15276///
15277/// @return the resulting synthesized function type if all its
15278/// sub-types have been found, NULL otherwise.
15281 translation_unit& tu)
15282{
15284
15285 const environment& env = tu.get_environment();
15286
15287 type_base_sptr return_type = fn_type.get_return_type();
15288 type_base_sptr result_return_type;
15289 if (!return_type || env.is_void_type(return_type))
15290 result_return_type = env.get_void_type();
15291 else
15292 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
15293 if (!result_return_type)
15294 return nil;
15295
15297 type_base_sptr parm_type;
15299 for (function_type::parameters::const_iterator i =
15300 fn_type.get_parameters().begin();
15301 i != fn_type.get_parameters().end();
15302 ++i)
15303 {
15304 type_base_sptr t = (*i)->get_type();
15305 parm_type = synthesize_type_from_translation_unit(t, tu);
15306 if (!parm_type)
15307 return nil;
15308 parm.reset(new function_decl::parameter(parm_type,
15309 (*i)->get_index(),
15310 (*i)->get_name(),
15311 (*i)->get_location(),
15312 (*i)->get_variadic_marker(),
15313 (*i)->get_is_artificial()));
15314 parms.push_back(parm);
15315 }
15316
15317 class_or_union_sptr class_type;
15318 const method_type* method = is_method_type(&fn_type);
15319 if (method)
15320 {
15321 class_type = is_class_or_union_type
15323 ABG_ASSERT(class_type);
15324 }
15325
15326 function_type_sptr result_fn_type;
15327
15328 if (class_type)
15329 result_fn_type.reset(new method_type(result_return_type,
15330 class_type,
15331 parms,
15332 method->get_is_const(),
15333 fn_type.get_size_in_bits(),
15334 fn_type.get_alignment_in_bits()));
15335 else
15336 result_fn_type.reset(new function_type(result_return_type,
15337 parms,
15338 fn_type.get_size_in_bits(),
15339 fn_type.get_alignment_in_bits()));
15340
15341 tu.priv_->synthesized_types_.push_back(result_fn_type);
15342 tu.bind_function_type_life_time(result_fn_type);
15343
15344 canonicalize(result_fn_type);
15345 return result_fn_type;
15346}
15347
15348/// Demangle a C++ mangled name and return the resulting string
15349///
15350/// @param mangled_name the C++ mangled name to demangle.
15351///
15352/// @return the resulting mangled name.
15353string
15354demangle_cplus_mangled_name(const string& mangled_name)
15355{
15356 if (mangled_name.empty())
15357 return "";
15358
15359 size_t l = 0;
15360 int status = 0;
15361 char * str = abi::__cxa_demangle(mangled_name.c_str(),
15362 NULL, &l, &status);
15363 string demangled_name = mangled_name;
15364 if (str)
15365 {
15366 ABG_ASSERT(status == 0);
15367 demangled_name = str;
15368 free(str);
15369 str = 0;
15370 }
15371 return demangled_name;
15372}
15373
15374/// Return either the type given in parameter if it's non-null, or the
15375/// void type.
15376///
15377/// @param t the type to consider.
15378///
15379/// @param env the environment to use. If NULL, just abort the
15380/// process.
15381///
15382/// @return either @p t if it is non-null, or the void type.
15383type_base_sptr
15384type_or_void(const type_base_sptr t, const environment& env)
15385{
15386 type_base_sptr r;
15387
15388 if (t)
15389 r = t;
15390 else
15391 r = type_base_sptr(env.get_void_type());
15392
15393 return r;
15394}
15395
15396global_scope::~global_scope()
15397{
15398}
15399
15400/// Test if two types are eligible to the "Linux Kernel Fast Type
15401/// Comparison Optimization", a.k.a LKFTCO.
15402///
15403/// Two types T1 and T2 (who are presumably of the same name and kind)
15404/// are eligible to the LKFTCO if they fulfill the following criteria/
15405///
15406/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
15407/// either class, union or enums.
15408///
15409/// 2/ They are defined in the same translation unit.
15410///
15411/// @param t1 the first type to consider.
15412///
15413/// @param t2 the second type to consider.
15414///
15415/// @return true iff t1 and t2 are eligible to the LKFTCO.
15416static bool
15417types_defined_same_linux_kernel_corpus_public(const type_base& t1,
15418 const type_base& t2)
15419{
15420 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
15421 string t1_file_path, t2_file_path;
15422
15423 /// If the t1 (and t2) are classes/unions/enums from the same linux
15424 /// kernel corpus, let's move on. Otherwise bail out.
15425 if (!(t1_corpus && t2_corpus
15426 && t1_corpus == t2_corpus
15427 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
15428 && (is_class_or_union_type(&t1)
15429 || is_enum_type(&t1))))
15430 return false;
15431
15432 class_or_union *c1 = 0, *c2 = 0;
15433 c1 = is_class_or_union_type(&t1);
15434 c2 = is_class_or_union_type(&t2);
15435
15436 // Two anonymous class types with no naming typedefs cannot be
15437 // eligible to this optimization.
15438 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
15439 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
15440 return false;
15441
15442 // Two anonymous classes with naming typedefs should have the same
15443 // typedef name.
15444 if (c1
15445 && c2
15446 && c1->get_is_anonymous() && c1->get_naming_typedef()
15447 && c2->get_is_anonymous() && c2->get_naming_typedef())
15448 if (c1->get_naming_typedef()->get_name()
15449 != c2->get_naming_typedef()->get_name())
15450 return false;
15451
15452 // Two anonymous enum types cannot be eligible to this optimization.
15453 if (const enum_type_decl *e1 = is_enum_type(&t1))
15454 if (const enum_type_decl *e2 = is_enum_type(&t2))
15455 if (e1->get_is_anonymous() || e2->get_is_anonymous())
15456 return false;
15457
15458 // Look through declaration-only types. That is, get the associated
15459 // definition type.
15462
15463 if (c1 && c2)
15464 {
15465 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
15466 {
15467 if (c1->get_environment().decl_only_class_equals_definition())
15468 // At least one of classes/union is declaration-only.
15469 // Because we are in a context in which a declaration-only
15470 // class/union is equal to all definitions of that
15471 // class/union, we can assume that the two types are
15472 // equal.
15473 return true;
15474 }
15475 }
15476
15477 if (t1.get_size_in_bits() != t2.get_size_in_bits())
15478 return false;
15479
15480 // Look at the file names of the locations of t1 and t2. If they
15481 // are equal, then t1 and t2 are defined in the same file.
15482 {
15483 location l;
15484
15485 if (c1)
15486 l = c1->get_location();
15487 else
15488 l = dynamic_cast<const decl_base&>(t1).get_location();
15489
15490 unsigned line = 0, col = 0;
15491 if (l)
15492 l.expand(t1_file_path, line, col);
15493 if (c2)
15494 l = c2->get_location();
15495 else
15496 l = dynamic_cast<const decl_base&>(t2).get_location();
15497 if (l)
15498 l.expand(t2_file_path, line, col);
15499 }
15500
15501 if (t1_file_path.empty() || t2_file_path.empty())
15502 return false;
15503
15504 if (t1_file_path == t2_file_path)
15505 return true;
15506
15507 return false;
15508}
15509
15510
15511/// Compare a type T against a canonical type.
15512///
15513/// This function is called during the canonicalization process of the
15514/// type T. T is called the "candidate type" because it's in the
15515/// process of being canonicalized. Meaning, it's going to be
15516/// compared to a canonical type C. If T equals C, then the canonical
15517/// type of T is C.
15518///
15519/// The purpose of this function is to allow the debugging of the
15520/// canonicalization of T, if that debugging is activated by
15521/// configuring the libabigail package with
15522/// --enable-debug-type-canonicalization and by running "abidw
15523/// --debug-tc". In that case, T is going to be compared to C twice:
15524/// once with canonical equality and once with structural equality.
15525/// The two comparisons must be equal. Otherwise, the
15526/// canonicalization process is said to be faulty and this function
15527/// aborts.
15528///
15529/// This is a sub-routine of type_base::get_canonical_type_for.
15530///
15531/// @param canonical_type the canonical type to compare the candidate
15532/// type against.
15533///
15534/// @param candidate_type the candidate type to compare against the
15535/// canonical type.
15536///
15537/// @return true iff @p canonical_type equals @p candidate_type.
15538///
15539static bool
15540compare_types_during_canonicalization(const type_base& canonical_type,
15541 const type_base& candidate_type)
15542{
15543#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
15544 const environment& env = canonical_type.get_environment();
15545 if (env.debug_type_canonicalization_is_on())
15546 {
15547 bool canonical_equality = false, structural_equality = false;
15548 env.priv_->allow_type_comparison_results_caching(false);
15549 env.priv_->use_canonical_type_comparison_ = false;
15550 structural_equality = canonical_type == candidate_type;
15551 env.priv_->use_canonical_type_comparison_ = true;
15552 canonical_equality = canonical_type == candidate_type;
15553 env.priv_->allow_type_comparison_results_caching(true);
15554 if (canonical_equality != structural_equality)
15555 {
15556 std::cerr << "structural & canonical equality different for type: "
15557 << canonical_type.get_pretty_representation(true, true)
15558 << std::endl;
15560 }
15561 return structural_equality;
15562 }
15563#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
15564 return canonical_type == candidate_type;
15565}
15566
15567/// Compare a canonical type against a candidate canonical type.
15568///
15569/// This is ultimately a sub-routine of the
15570/// type_base::get_canonical_type_for().
15571///
15572/// The goal of this function is to ease debugging because it can be
15573/// called from within type_base::get_canonical_type_for() from the
15574/// prompt of the debugger (with some breakpoint appropriately set) to
15575/// debug the comparison that happens during type canonicalization,
15576/// between a candidate type being canonicalized, and an existing
15577/// canonical type that is registered in the system, in as returned by
15578/// environment::get_canonical_types()
15579///
15580/// @param canonical_type the canonical type to consider.
15581///
15582/// @param candidate_type the candidate type that is being
15583/// canonicalized, and thus compared to @p canonical_type.
15584///
15585/// @return true iff @p canonical_type compares equal to @p
15586/// candidate_type.
15587static bool
15588compare_canonical_type_against_candidate(const type_base& canonical_type,
15589 const type_base& candidate_type)
15590{
15591 environment& env = const_cast<environment&>(canonical_type.get_environment());
15592
15593 // Before the "*it == it" comparison below is done, let's
15594 // perform on-the-fly-canonicalization. For C types, let's
15595 // consider that an unresolved struct declaration 'struct S'
15596 // is different from a definition 'struct S'. This is
15597 // because normally, at this point all the declarations of
15598 // struct S that are compatible with the definition of
15599 // struct S have already been resolved to that definition,
15600 // during the DWARF parsing. The remaining unresolved
15601 // declaration are thus considered different. With this
15602 // setup we can properly handle cases of two *different*
15603 // struct S being defined in the same binary (in different
15604 // translation units), and a third struct S being only
15605 // declared as an opaque type in a third translation unit of
15606 // its own, with no definition in there. In that case, the
15607 // declaration-only struct S should be left alone and not
15608 // resolved to any of the two definitions of struct S.
15609 bool saved_decl_only_class_equals_definition =
15610 env.decl_only_class_equals_definition();
15611
15612 // Compare types by considering that decl-only classes don't
15613 // equal their definition.
15614 env.decl_only_class_equals_definition(false);
15615 env.priv_->allow_type_comparison_results_caching(true);
15616 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
15617 candidate_type)
15618 || compare_types_during_canonicalization(canonical_type,
15619 candidate_type));
15620 // Restore the state of the on-the-fly-canonicalization and
15621 // the decl-only-class-being-equal-to-a-matching-definition
15622 // flags.
15623 env.priv_->clear_type_comparison_results_cache();
15624 env.priv_->allow_type_comparison_results_caching(false);
15625 env.decl_only_class_equals_definition
15626 (saved_decl_only_class_equals_definition);
15627 return equal;
15628}
15629
15630/// Compare a canonical type against a candidate canonical type.
15631///
15632/// This is ultimately a sub-routine of the
15633/// type_base::get_canonical_type_for().
15634///
15635/// The goal of this function is to ease debugging because it can be
15636/// called from within type_base::get_canonical_type_for() from the
15637/// prompt of the debugger (with some breakpoint appropriately set) to
15638/// debug the comparison that happens during type canonicalization,
15639/// between a candidate type being canonicalized, and an existing
15640/// canonical type that is registered in the system, in as returned by
15641/// environment::get_canonical_types()
15642///
15643/// @param canonical_type the canonical type to consider.
15644///
15645/// @param candidate_type the candidate type that is being
15646/// canonicalized, and thus compared to @p canonical_type.
15647///
15648/// @return true iff @p canonical_type compares equal to @p
15649/// candidate_type.
15650static bool
15651compare_canonical_type_against_candidate(const type_base* canonical_type,
15652 const type_base* candidate_type)
15653{
15654 return compare_canonical_type_against_candidate(*canonical_type,
15655 *candidate_type);
15656}
15657
15658/// Compare a canonical type against a candidate canonical type.
15659///
15660/// This is ultimately a sub-routine of the
15661/// type_base::get_canonical_type_for().
15662///
15663/// The goal of this function is to ease debugging because it can be
15664/// called from within type_base::get_canonical_type_for() from the
15665/// prompt of the debugger (with some breakpoint appropriately set) to
15666/// debug the comparison that happens during type canonicalization,
15667/// between a candidate type being canonicalized, and an existing
15668/// canonical type that is registered in the system, in as returned by
15669/// environment::get_canonical_types()
15670///
15671/// @param canonical_type the canonical type to consider.
15672///
15673/// @param candidate_type the candidate type that is being
15674/// canonicalized, and thus compared to @p canonical_type.
15675///
15676/// @return true iff @p canonical_type compares equal to @p
15677/// candidate_type.
15678static bool
15679compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15680 const type_base_sptr& candidate_type)
15681{
15682 return compare_canonical_type_against_candidate(canonical_type.get(),
15683 candidate_type.get());
15684}
15685
15686/// Test if a candidate for type canonicalization coming from ABIXML
15687/// matches a canonical type by first looking at their hash values.
15688///
15689/// If the two hash values are equal then the candidate is
15690/// structurally compared to the canonical type. If the two hashes
15691/// are different then the two types are considered different and the
15692/// function returns nullptr.
15693///
15694/// If the candidate doesn't come from ABIXML then the function
15695/// returns nullptr.
15696///
15697/// @param cncls the vector of canonical types to consider.
15698///
15699/// @param type the candidate to consider for canonicalization.
15700///
15701/// @return the canonical type from @p cncls that matches the
15702/// candidate @p type.
15703static type_base_sptr
15704candidate_matches_a_canonical_type_hash(const vector<type_base_sptr>& cncls,
15705 type_base& type)
15706{
15707 if (type.get_corpus()
15708 && type.get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
15709 && peek_hash_value(type))
15710 {
15711 // The candidate type comes from ABIXML and does have a stashed
15712 // hash value coming from the ABIXML.
15713
15714 // Let's see if we find a potential canonical type whose hash
15715 // matches the stashed hash and whose canonical type index
15716 // matches it too.
15717 for (const auto& c : cncls)
15718 if (peek_hash_value(type) == peek_hash_value(*c))
15720 // We found a potential canonical type which hash matches the
15721 // stashed hash of the candidate type. Let's compare them to
15722 // see if they match.
15723 if (compare_canonical_type_against_candidate(*c, type))
15724 return c;
15725
15726 // Let's do the same things, but just consideing hash values.
15727 for (const auto& c : cncls)
15728 if (peek_hash_value(type) == peek_hash_value(*c))
15729 // We found a potential canonical type which hash matches the
15730 // stashed hash of the candidate type. Let's compare them to
15731 // see if they match.
15732 if (compare_canonical_type_against_candidate(*c, type))
15733 return c;
15734 }
15735
15736 return nullptr;
15737}
15738
15739/// Test if we should attempt to compute a hash value for a given
15740/// type.
15741///
15742/// For now this function returns true only for types originating from
15743/// ELF. For types originating from ABIXML, for instance, the
15744/// function return false, meaning that types originating from ABIXML
15745/// should NOT be hashed.
15746///
15747/// @param t the type to consider.
15748///
15749/// @return true iff @p type should be considered for hashing.
15750bool
15752{
15753 if (t.get_corpus()
15754 && (t.get_corpus()->get_origin() & corpus::ELF_ORIGIN))
15755 return true;
15756 return false;
15757}
15758
15759/// Compute the canonical type for a given instance of @ref type_base.
15760///
15761/// Consider two types T and T'. The canonical type of T, denoted
15762/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
15763/// otherwise, to compare two types, one just needs to compare their
15764/// canonical types using pointer equality. That makes type
15765/// comparison faster than the structural comparison performed by the
15766/// abigail::ir::equals() overloads.
15767///
15768/// If there is not yet any canonical type for @p t, then @p t is its
15769/// own canonical type. Otherwise, this function returns the
15770/// canonical type of @p t which is the canonical type that has the
15771/// same hash value as @p t and that structurally equals @p t. Note
15772/// that after invoking this function, the life time of the returned
15773/// canonical time is then equals to the life time of the current
15774/// process.
15775///
15776/// @param t a smart pointer to instance of @ref type_base we want to
15777/// compute a canonical type for.
15778///
15779/// @return the canonical type for the current instance of @ref
15780/// type_base.
15781type_base_sptr
15782type_base::get_canonical_type_for(type_base_sptr t)
15783{
15784 if (!t)
15785 return t;
15786
15787 environment& env = const_cast<environment&>(t->get_environment());
15788
15790 // This type should not be canonicalized!
15791 return type_base_sptr();
15792
15793 if (is_decl(t))
15795
15796 // Look through decl-only types (classes, unions and enums)
15797 bool decl_only_class_equals_definition =
15799
15800 class_or_union_sptr class_or_union = is_class_or_union_type(t);
15801
15802 // In the context of types from C++ or languages where we assume the
15803 // "One Definition Rule", we assume that a declaration-only
15804 // non-anonymous class equals all fully defined classes of the same
15805 // name.
15806 //
15807 // Otherwise, all classes, including declaration-only classes are
15808 // canonicalized and only canonical comparison is going to be used
15809 // in the system.
15810 if (decl_only_class_equals_definition)
15811 if (class_or_union)
15813 return type_base_sptr();
15814
15815 class_decl_sptr is_class = is_class_type(t);
15816 if (t->get_canonical_type())
15817 return t->get_canonical_type();
15818
15819 // For classes and union, ensure that an anonymous class doesn't
15820 // have a linkage name. If it does in the future, then me must be
15821 // mindful that the linkage name respects the type identity
15822 // constraints which states that "if two linkage names are different
15823 // then the two types are different".
15827
15828 // We want the pretty representation of the type, but for an
15829 // internal use, not for a user-facing purpose.
15830 //
15831 // If two classe types Foo are declared, one as a class and the
15832 // other as a struct, but are otherwise equivalent, we want their
15833 // pretty representation to be the same. Hence the 'internal'
15834 // argument of ir::get_pretty_representation() is set to true here.
15835 // So in this case, the pretty representation of Foo is going to be
15836 // "class Foo", regardless of its struct-ness. This also applies to
15837 // composite types which would have "class Foo" as a sub-type.
15838 string repr = t->get_cached_pretty_representation(/*internal=*/true);
15839
15840 // If 't' already has a canonical type 'inside' its corpus
15841 // (t_corpus), then this variable is going to contain that canonical
15842 // type.
15843 type_base_sptr canonical_type_present_in_corpus;
15846
15847 type_base_sptr result;
15848 environment::canonical_types_map_type::iterator i = types.find(repr);
15849
15850 if (i == types.end())
15851 {
15852 vector<type_base_sptr> v;
15853 v.push_back(t);
15854 types[repr] = v;
15855 result = t;
15856 }
15857 else
15858 {
15859 vector<type_base_sptr> &v = i->second;
15860 // Look at the canonical types and if the current candidate type
15861 // coming from abixml has the same hash as one of the canonical
15862 // types, then compare the current candidate with the one with a
15863 // matching hash.
15864 result = candidate_matches_a_canonical_type_hash(v, *t);
15865
15866 // Let's compare 't' structurally (i.e, compare its sub-types
15867 // recursively) against the canonical types of the system. If it
15868 // equals a given canonical type C, then it means C is the
15869 // canonical type of 't'. Otherwise, if 't' is different from
15870 // all the canonical types of the system, then it means 't' is a
15871 // canonical type itself.
15872 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15873 !result && it != v.rend();
15874 ++it)
15875 {
15876 bool equal = compare_canonical_type_against_candidate(*it, t);
15877 if (equal)
15878 {
15879 result = *it;
15880 break;
15881 }
15882 }
15883#ifdef WITH_DEBUG_SELF_COMPARISON
15884 if (env.self_comparison_debug_is_on())
15885 {
15886 // So we are debugging the canonicalization process,
15887 // possibly via the use of 'abidw --debug-abidiff <binary>'.
15888 corpus_sptr corp1, corp2;
15889 env.get_self_comparison_debug_inputs(corp1, corp2);
15890 if (corp1 && corp2 && type_originates_from_corpus(t, corp2)
15891 && corp1->get_origin() != corp2->get_origin()
15892 && corp2->get_origin() & corpus::NATIVE_XML_ORIGIN)
15893 {
15894 // If 't' comes from the second corpus, then it *must*
15895 // be equal to its matching canonical type coming from
15896 // the first corpus because the second corpus is the
15897 // abixml representation of the first corpus. In other
15898 // words, all types coming from the second corpus must
15899 // have canonical types coming from the first corpus.
15900 if (result)
15901 {
15902 if (!env.priv_->
15903 check_canonical_type_from_abixml_during_self_comp(t,
15904 result))
15905 {
15906 // The canonical type of the type re-read from abixml
15907 // type doesn't match the canonical type that was
15908 // initially serialized down.
15909 uintptr_t should_have_canonical_type = 0;
15910 string type_id = env.get_type_id_from_type(t.get());
15911 if (type_id.empty())
15912 type_id = "type-id-<not-found>";
15913 else
15914 should_have_canonical_type =
15915 env.get_canonical_type_from_type_id(type_id.c_str());
15916 std::cerr << "error: wrong canonical type for '"
15917 << repr
15918 << "' / type: @"
15919 << std::hex
15920 << t.get()
15921 << "/ canon: @"
15922 << result.get()
15923 << ", type-id: '"
15924 << type_id
15925 << "'. Should have had canonical type: "
15926 << std::hex
15927 << should_have_canonical_type
15928 << std::dec
15929 << std::endl;
15930 }
15931 }
15932 else //!result
15933 {
15934 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
15935 string type_id = env.get_type_id_from_pointer(ptr_val);
15936 if (type_id.empty())
15937 type_id = "type-id-<not-found>";
15938 // We are in the case where 't' is different from all
15939 // the canonical types of the same name that come from
15940 // the first corpus.
15941 //
15942 // If 't' indeed comes from the second corpus then this
15943 // clearly is a canonicalization failure.
15944 //
15945 // There was a problem either during the serialization
15946 // of 't' into abixml, or during the de-serialization
15947 // from abixml into abigail::ir. Further debugging is
15948 // needed to determine what that root cause problem is.
15949 //
15950 // Note that the first canonicalization problem of this
15951 // kind must be fixed before looking at the subsequent
15952 // ones, because the later might well just be
15953 // consequences of the former.
15954 std::cerr << "error: wrong induced canonical type for '"
15955 << repr
15956 << "' from second corpus"
15957 << ", ptr: " << std::hex << t.get()
15958 << " type-id: " << type_id
15959 << " /hash="
15960 << *t->hash_value()
15961 << std::dec
15962 << std::endl;
15963 }
15964 }
15965 if (result)
15966 {
15967 if (!is_type_decl(t))
15968 if (hash_t t_hash = peek_hash_value(*t))
15969 if (hash_t result_hash = peek_hash_value(*result))
15970 if (t_hash != result_hash)
15971 {
15972 std::cerr << "error: type hash mismatch"
15973 << " between type: '"
15974 << repr
15975 << "' @ "
15976 << std::hex
15977 << t.get()
15978 << "/hash="
15979 << *t->hash_value()
15980 << " and its computed canonical type @"
15981 << std::hex
15982 << result.get()
15983 << "/hash="
15984 << std::hex
15985 << *result->hash_value()
15986 << std::dec
15987 << std::endl;
15988 }
15989 }
15990 }
15991#endif //WITH_DEBUG_SELF_COMPARISON
15992
15993 if (!result)
15994 {
15995 v.push_back(t);
15996 result = t;
15997 // we need to generate a canonical type index to sort these
15998 // types that have the same representation and potentially
15999 // same hash value but are canonically different.
16000 t->priv_->canonical_type_index = v.size();
16001 }
16002 }
16003
16004 return result;
16005}
16006
16007/// This method is invoked automatically right after the current
16008/// instance of @ref class_decl has been canonicalized.
16009void
16011{}
16012
16013/// This is a subroutine of the canonicalize() function.
16014///
16015/// When the canonical type C of type T has just been computed, there
16016/// can be cases where T has member functions that C doesn't have.
16017///
16018/// This is possible because non virtual member functions are not
16019/// taken in account when comparing two types.
16020///
16021/// In that case, this function updates C so that it contains the
16022/// member functions.
16023///
16024/// There can also be cases where C has a method M which is not linked
16025/// to any underlying symbol, whereas in T, M is to link to an
16026/// underlying symbol. In that case, this function updates M in C so
16027/// that it's linked to the same underlying symbol as for M in T.
16028static void
16029maybe_adjust_canonical_type(const type_base_sptr& canonical,
16030 const type_base_sptr& type)
16031{
16032 if (type->get_naked_canonical_type())
16033 return;
16034
16035 class_decl_sptr canonical_class = is_class_type(canonical);
16036
16037 if (class_decl_sptr cl = is_class_type(type))
16038 {
16040 if (canonical_class
16041 && canonical_class.get() != cl.get())
16042 {
16043 // Set symbols of member functions that might be missing
16044 // theirs.
16045 for (class_decl::member_functions::const_iterator i =
16046 cl->get_member_functions().begin();
16047 i != cl->get_member_functions().end();
16048 ++i)
16049 if ((*i)->get_symbol())
16050 {
16051 if (method_decl *m = canonical_class->
16052 find_member_function((*i)->get_linkage_name()))
16053 {
16054 elf_symbol_sptr s1 = (*i)->get_symbol();
16055 if (s1 && !m->get_symbol())
16056 // Method 'm' in the canonical type is not
16057 // linked to the underlying symbol of '*i'.
16058 // Let's link it now. have th
16059 m->set_symbol(s1);
16060 }
16061 else
16062 if (canonical_class->get_corpus()
16063 && cl->get_corpus()
16064 && (cl->get_corpus() == canonical_class->get_corpus()))
16065 // There is a member function defined and publicly
16066 // exported in the other class and the canonical
16067 // class doesn't have that member function. This
16068 // should not have happened! For instance, the
16069 // DWARF reader does merge the member functions of
16070 // classes having the same name so that all of them
16071 // end-up having the same member functions. What's
16072 // going on here?
16074 }
16075
16076 // Set symbols of static data members that might be missing
16077 // theirs.
16078 for (const auto& data_member : cl->get_data_members())
16079 {
16080 if (!get_member_is_static(data_member))
16081 continue;
16082 elf_symbol_sptr sym = data_member->get_symbol();
16083 if (!sym)
16084 continue;
16085 const auto& canonical_data_member =
16086 canonical_class->find_data_member(data_member->get_name());
16087 if (!canonical_data_member)
16088 // Hmmh, maybe we
16089 // should consider
16090 // static data members
16091 // when comparing two
16092 // classes for the
16093 // purpose of type
16094 // canonicalization?
16095 continue;
16096 if (!canonical_data_member->get_symbol())
16097 canonical_data_member->set_symbol(sym);
16098 }
16099 }
16100 }
16101
16102 // Make sure the virtual member functions with exported symbols are
16103 // all added to the set of exported functions of the corpus.
16104
16105 // If we are looking at a non-canonicalized class (for instance, a
16106 // decl-only class that has virtual member functions), let's pretend
16107 // it does have a canonical class so that we can perform the
16108 // necessary virtual member function adjustments
16109 if (class_decl_sptr cl = is_class_type(type))
16111 {
16112 ABG_ASSERT(!canonical_class);
16113 canonical_class = cl;
16114 }
16115
16116 if (canonical_class)
16117 {
16118 if (auto abi_corpus = canonical_class->get_corpus())
16119 {
16120 for (auto& fn : canonical_class->get_member_functions())
16121 {
16122 if (elf_symbol_sptr sym = fn->get_symbol())
16123 {
16124 if (sym->is_defined() && sym->is_public())
16125 {
16126 fn->set_is_in_public_symbol_table(true);
16127 auto b = abi_corpus->get_exported_decls_builder();
16128 b->maybe_add_fn_to_exported_fns(fn.get());
16129 }
16130 else if (!sym->is_defined())
16131 abi_corpus->get_undefined_functions().insert(fn.get());
16132 }
16133 }
16134 }
16135 }
16136
16137 // If an artificial function type equals a non-artfificial one in
16138 // the system, then the canonical type of both should be deemed
16139 // non-artificial. This is important because only non-artificial
16140 // canonical function types are emitted out into abixml, so if don't
16141 // do this we risk missing to emit some function types.
16142 if (is_function_type(type))
16143 if (type->get_is_artificial() != canonical->get_is_artificial())
16144 canonical->set_is_artificial(false);
16145}
16146
16147/// Compute the canonical type of a given type.
16148///
16149/// It means that after invoking this function, comparing the intance
16150/// instance @ref type_base and another one (on which
16151/// type_base::enable_canonical_equality() would have been invoked as
16152/// well) is performed by just comparing the pointer values of the
16153/// canonical types of both types. That equality comparison is
16154/// supposedly faster than structural comparison of the types.
16155///
16156/// @param t a smart pointer to the instance of @ref type_base for
16157/// which to compute the canonical type. After this call,
16158/// t->get_canonical_type() will return the newly computed canonical
16159/// type.
16160///
16161/// @param do_log if true then logs are emitted about canonicalization
16162/// progress.
16163///
16164/// @param show_stats if true and if @p do_log is true as well, then
16165/// more detailed logs are emitted about canonicalization.
16166///
16167/// @return the canonical type computed for @p t.
16168type_base_sptr
16169canonicalize(type_base_sptr t, bool do_log, bool show_stats)
16170{
16171 if (!t)
16172 return t;
16173
16174 if (t->get_canonical_type())
16175 return t->get_canonical_type();
16176
16177 if (do_log && show_stats)
16178 std::cerr << "Canonicalization of type '"
16179 << t->get_pretty_representation(true, true)
16180 << "/@#" << std::hex << t.get() << ": ";
16181
16183
16184 if (do_log && show_stats)
16185 tmr.start();
16186 type_base_sptr canonical = type_base::get_canonical_type_for(t);
16187
16188 if (do_log && show_stats)
16189 tmr.stop();
16190
16191 if (do_log && show_stats)
16192 std::cerr << tmr << "\n";
16193
16194 maybe_adjust_canonical_type(canonical, t);
16195
16196 t->priv_->canonical_type = canonical;
16197 t->priv_->naked_canonical_type = canonical.get();
16198
16199 if (canonical)
16200 if (!t->priv_->canonical_type_index)
16201 t->priv_->canonical_type_index = canonical->priv_->canonical_type_index;
16202
16203 if (class_decl_sptr cl = is_class_type(t))
16204 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
16205 if ((canonical = d->get_canonical_type()))
16206 {
16207 d->priv_->canonical_type = canonical;
16208 d->priv_->naked_canonical_type = canonical.get();
16209 }
16210
16211 if (canonical)
16212 {
16213 if (decl_base_sptr d = is_decl_slow(canonical))
16214 {
16215 scope_decl *scope = d->get_scope();
16216 // Add the canonical type to the set of canonical types
16217 // belonging to its scope.
16218 if (scope)
16219 {
16220 if (is_type(scope))
16221 // The scope in question is itself a type (e.g, a class
16222 // or union). Let's call that type ST. We want to add
16223 // 'canonical' to the set of canonical types belonging
16224 // to ST.
16225 if (type_base_sptr c = is_type(scope)->get_canonical_type())
16226 // We want to add 'canonical' to the set of
16227 // canonical types belonging to the canonical type
16228 // of ST. That way, just looking at the canonical
16229 // type of ST is enough to get the types that belong
16230 // to the scope of the class of equivalence of ST.
16231 scope = is_scope_decl(is_decl(c)).get();
16232 scope->get_canonical_types().insert(canonical);
16233 }
16234 // else, if the type doesn't have a scope, it's not meant to be
16235 // emitted. This can be the case for the result of the
16236 // function strip_typedef, for instance.
16237 }
16238 }
16239
16240 t->on_canonical_type_set();
16241 return canonical;
16242}
16243
16244/// Set the definition of this declaration-only @ref decl_base.
16245///
16246/// @param d the new definition to set.
16247void
16249{
16251 priv_->definition_of_declaration_ = d;
16252 if (type_base *t = is_type(this))
16253 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
16254 t->priv_->canonical_type = canonical_type;
16255
16256 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
16257}
16258
16259/// The constructor of @ref type_base.
16260///
16261/// @param s the size of the type, in bits.
16262///
16263/// @param a the alignment of the type, in bits.
16264type_base::type_base(const environment& e, size_t s, size_t a)
16265 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
16266 priv_(new priv(s, a))
16267{}
16268
16269/// Return the hash value of the current IR node.
16270///
16271/// Note that upon the first invocation, this member functions
16272/// computes the hash value and returns it. Subsequent invocations
16273/// just return the hash value that was previously calculated.
16274///
16275/// @return the hash value of the current IR node.
16276hash_t
16278{
16279 type_base::hash do_hash;
16280 return do_hash(this);
16281}
16282
16283/// Getter of the canonical type of the current instance of @ref
16284/// type_base.
16285///
16286/// @return a smart pointer to the canonical type of the current
16287/// intance of @ref type_base, or an empty smart pointer if the
16288/// current instance of @ref type_base doesn't have any canonical
16289/// type.
16290type_base_sptr
16292{return priv_->canonical_type.lock();}
16293
16294/// Getter of the canonical type pointer.
16295///
16296/// Note that this function doesn't return a smart pointer, but rather
16297/// the underlying pointer managed by the smart pointer. So it's as
16298/// fast as possible. This getter is to be used in code paths that
16299/// are proven to be performance hot spots; especially, when comparing
16300/// sensitive types like class, function, pointers and reference
16301/// types. Those are compared extremely frequently and thus, their
16302/// accessing the canonical type must be fast.
16303///
16304/// @return the canonical type pointer, not managed by a smart
16305/// pointer.
16306type_base*
16308{return priv_->naked_canonical_type;}
16309
16310/// Get the pretty representation of the current type.
16311///
16312/// The pretty representation is retrieved from a cache. If the cache
16313/// is empty, this function computes the pretty representation, put it
16314/// in the cache and returns it.
16315///
16316/// Please note that if this function is called too early in the life
16317/// cycle of the type (before the type is fully constructed), then the
16318/// pretty representation that is cached is going to represent a
16319/// non-complete (and thus wrong) representation of the type. Thus
16320/// this function must be called only once the type is fully
16321/// constructed.
16322///
16323/// @param internal if true, then the pretty representation is to be
16324/// used for purpuses that are internal to the libabigail library
16325/// itself. If you don't know what this means, then you probably
16326/// should set this parameter to "false".
16327///
16328/// @return a reference to a cached @ref interned_string holding the
16329/// pretty representation of the current type.
16330const interned_string&
16332{
16333 if (internal)
16334 {
16335 if (priv_->internal_cached_repr_.empty())
16336 {
16337 string r = ir::get_pretty_representation(this, internal);
16338 priv_->internal_cached_repr_ = get_environment().intern(r);
16339 }
16340 return priv_->internal_cached_repr_;
16341 }
16342
16343 if (priv_->cached_repr_.empty())
16344 {
16345 string r = ir::get_pretty_representation(this, internal);
16346 priv_->cached_repr_ = get_environment().intern(r);
16347 }
16348
16349 return priv_->cached_repr_;
16350}
16351
16352/// Compares two instances of @ref type_base.
16353///
16354/// If the two intances are different, set a bitfield to give some
16355/// insight about the kind of differences there are.
16356///
16357/// @param l the first artifact of the comparison.
16358///
16359/// @param r the second artifact of the comparison.
16360///
16361/// @param k a pointer to a bitfield that gives information about the
16362/// kind of changes there are between @p l and @p r. This one is set
16363/// iff @p is non-null and if the function returns false.
16364///
16365/// Please note that setting k to a non-null value does have a
16366/// negative performance impact because even if @p l and @p r are not
16367/// equal, the function keeps up the comparison in order to determine
16368/// the different kinds of ways in which they are different.
16369///
16370/// @return true if @p l equals @p r, false otherwise.
16371bool
16372equals(const type_base& l, const type_base& r, change_kind* k)
16373{
16374 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
16376 if (!result)
16377 if (k)
16379 ABG_RETURN(result);
16380}
16381
16382/// Return true iff both type declarations are equal.
16383///
16384/// Note that this doesn't test if the scopes of both types are equal.
16385bool
16387{return equals(*this, other, 0);}
16388
16389/// Inequality operator.
16390///
16391///@param other the instance of @ref type_base to compare the current
16392/// instance against.
16393///
16394/// @return true iff the current instance is different from @p other.
16395bool
16397{return !operator==(other);}
16398
16399/// Setter for the size of the type.
16400///
16401/// @param s the new size -- in bits.
16402void
16404{priv_->size_in_bits = s;}
16405
16406/// Getter for the size of the type.
16407///
16408/// @return the size in bits of the type.
16409size_t
16411{return priv_->size_in_bits;}
16412
16413/// Setter for the alignment of the type.
16414///
16415/// @param a the new alignment -- in bits.
16416void
16418{priv_->alignment_in_bits = a;}
16419
16420/// Getter for the alignment of the type.
16421///
16422/// @return the alignment of the type in bits.
16423size_t
16425{return priv_->alignment_in_bits;}
16426
16427/// Default implementation of traversal for types. This function does
16428/// nothing. It must be implemented by every single new type that is
16429/// written.
16430///
16431/// Please look at e.g, class_decl::traverse() for an example of how
16432/// to implement this.
16433///
16434/// @param v the visitor used to visit the type.
16435bool
16437{
16438 if (v.type_node_has_been_visited(this))
16439 return true;
16440
16441 v.visit_begin(this);
16442 bool result = v.visit_end(this);
16444
16445 return result;
16446}
16447
16448type_base::~type_base()
16449{delete priv_;}
16450
16451// </type_base definitions>
16452
16453// <real_type definitions>
16454
16455/// Bitwise OR operator for real_type::modifiers_type.
16456///
16457/// @param l the left-hand side operand.
16458///
16459/// @param r the right-hand side operand.
16460///
16461/// @return the result of the bitwise OR.
16464{
16465 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16466 |
16467 static_cast<unsigned>(r));
16468}
16469
16470/// Bitwise AND operator for real_type::modifiers_type.
16471///
16472/// @param l the left-hand side operand.
16473///
16474/// @param r the right-hand side operand.
16475///
16476/// @return the result of the bitwise AND.
16479{
16480 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16481 &
16482 static_cast<unsigned>(r));
16483}
16484
16485/// Bitwise one's complement operator for real_type::modifiers_type.
16486///
16487/// @param l the left-hand side operand.
16488///
16489/// @param r the right-hand side operand.
16490///
16491/// @return the result of the bitwise one's complement operator.
16494{
16495 return static_cast<real_type::modifiers_type>(~static_cast<unsigned>(l));
16496}
16497
16498/// Bitwise |= operator for real_type::modifiers_type.
16499///
16500/// @param l the left-hand side operand.
16501///
16502/// @param r the right-hand side operand.
16503///
16504/// @return the result of the bitwise |=.
16507{
16508 l = l | r;
16509 return l;
16510}
16511
16512/// Bitwise &= operator for real_type::modifiers_type.
16513///
16514/// @param l the left-hand side operand.
16515///
16516/// @param r the right-hand side operand.
16517///
16518/// @return the result of the bitwise &=.
16521{
16522 l = l & r;
16523 return l;
16524}
16525
16526/// Parse a word containing one real type modifier.
16527///
16528/// A word is considered to be a string of characters that doesn't
16529/// contain any white space.
16530///
16531/// @param word the word to parse. It is considered to be a string of
16532/// characters that doesn't contain any white space.
16533///
16534/// @param modifiers out parameter. It's set by this function to the
16535/// parsed modifier iff the function returned true.
16536///
16537/// @return true iff @word was successfully parsed.
16538static bool
16539parse_real_type_modifier(const string& word,
16540 real_type::modifiers_type &modifiers)
16541{
16542 if (word == "signed")
16543 modifiers |= real_type::SIGNED_MODIFIER;
16544 else if (word == "unsigned")
16545 modifiers |= real_type::UNSIGNED_MODIFIER;
16546 else if (word == "short")
16547 modifiers |= real_type::SHORT_MODIFIER;
16548 else if (word == "long")
16549 modifiers |= real_type::LONG_MODIFIER;
16550 else if (word == "long long")
16551 modifiers |= real_type::LONG_LONG_MODIFIER;
16552 else
16553 return false;
16554
16555 return true;
16556}
16557
16558/// Parse a base type of a real type from a string.
16559///
16560/// @param type_name the type name to parse.
16561///
16562/// @param base out parameter. This is set to the resulting base type
16563/// parsed, iff the function returned true.
16564///
16565/// @return true iff the function could successfully parse the base
16566/// type.
16567static bool
16568parse_base_real_type(const string& type_name,
16570{
16571 if (type_name == "int")
16573 else if (type_name == "char")
16575 else if (type_name == "bool" || type_name == "_Bool")
16577 else if (type_name == "double")
16579 else if (type_name =="float")
16581 else if (type_name == "char16_t")
16583 else if (type_name == "char32_t")
16585 else if (type_name == "wchar_t")
16587 else if (type_name == "__ARRAY_SIZE_TYPE__")
16589 else if (type_name == "sizetype")
16590 base = real_type::SIZE_BASE_TYPE;
16591 else if (type_name == "ssizetype")
16592 base = real_type::SSIZE_BASE_TYPE;
16593 else if (type_name == "bitsizetype")
16594 base = real_type::BIT_SIZE_BASE_TYPE;
16595 else if (type_name == "sbitsizetype")
16596 base = real_type::SBIT_SIZE_BASE_TYPE;
16597 else
16598 return false;
16599
16600 return true;
16601}
16602
16603/// Parse a real type from a string.
16604///
16605/// @param type_name the string containing the real type to parse.
16606///
16607/// @param base out parameter. Is set by this function to the base
16608/// type of the real type, iff the function returned true.
16609///
16610/// @param modifiers out parameter If set by this function to the
16611/// modifier of the real type, iff the function returned true.
16612///
16613/// @return true iff the function could parse a real type from @p
16614/// type_name.
16615static bool
16616parse_real_type(const string& type_name,
16618 real_type::modifiers_type& modifiers)
16619{
16620 string input = type_name;
16621 string::size_type len = input.length();
16622 string::size_type cur_pos = 0, prev_pos = 0;
16623 string cur_word, prev_word;
16624 bool ok = false;
16625
16626 while (cur_pos < len)
16627 {
16628 if (cur_pos < len && isspace(input[cur_pos]))
16629 do
16630 ++cur_pos;
16631 while (cur_pos < len && isspace(input[cur_pos]));
16632
16633 prev_pos = cur_pos;
16634 cur_pos = input.find(' ', prev_pos);
16635 prev_word = cur_word;
16636 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16637
16638 if (cur_pos < len
16639 && cur_word == "long"
16640 && prev_word != "long")
16641 {
16642 if (cur_pos < len && isspace(input[cur_pos]))
16643 do
16644 ++cur_pos;
16645 while (cur_pos < len && isspace(input[cur_pos]));
16646 prev_pos = cur_pos;
16647
16648 cur_pos = input.find(' ', prev_pos);
16649 string saved_prev_word = prev_word;
16650 prev_word = cur_word;
16651 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16652 if (cur_word == "long")
16653 cur_word = "long long";
16654 else
16655 {
16656 cur_pos = prev_pos;
16657 cur_word = prev_word;
16658 prev_word = saved_prev_word;
16659 }
16660 }
16661
16662 if (!parse_real_type_modifier(cur_word, modifiers))
16663 {
16664 if (!parse_base_real_type(cur_word, base))
16665 return false;
16666 else
16667 ok = true;
16668 }
16669 else
16670 ok = true;
16671 }
16672
16673 return ok;
16674}
16675
16676/// Parse a real type from a string.
16677///
16678/// @param str the string containing the real type to parse.
16679///
16680///@param type the resulting @ref real_type. Is set to the result
16681///of the parse, iff the function returns true.
16682///
16683/// @return true iff the function could parse a real type from @p
16684/// str.
16685bool
16686parse_real_type(const string& str, real_type& type)
16687{
16689 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16690
16691 if (!parse_real_type(str, base_type, modifiers))
16692 return false;
16693
16694 // So this is a real type.
16695 real_type int_type(base_type, modifiers);
16696 type = int_type;
16697 return true;
16698}
16699
16700/// Default constructor of the @ref real_type.
16702 : base_(INT_BASE_TYPE),
16703 modifiers_(NO_MODIFIER)
16704{}
16705
16706/// Constructor of the @ref real_type.
16707///
16708/// @param b the base type of the real type.
16709///
16710/// @param m the modifiers of the real type.
16712 : base_(b), modifiers_(m)
16713{}
16714
16715/// Constructor of the @ref real_type.
16716///
16717/// @param the name of the real type to parse to initialize the
16718/// current instance of @ref real_type.
16719real_type::real_type(const string& type_name)
16720 : base_(INT_BASE_TYPE),
16721 modifiers_(NO_MODIFIER)
16722{
16723 bool could_parse = parse_real_type(type_name, base_, modifiers_);
16724 ABG_ASSERT(could_parse);
16725}
16726
16727/// Getter of the base type of the @ref real_type.
16728///
16729/// @return the base type of the @ref real_type.
16732{return base_;}
16733
16734/// Getter of the modifiers bitmap of the @ref real_type.
16735///
16736/// @return the modifiers bitmap of the @ref real_type.
16739{return modifiers_;}
16740
16741/// Setter of the modifiers bitmap of the @ref real_type.
16742///
16743/// @param m the new modifiers.
16744void
16746{modifiers_ = m;}
16747
16748/// Equality operator for the @ref real_type.
16749///
16750/// @param other the other real type to compare against.
16751///
16752/// @return true iff @p other equals the current instance of @ref
16753/// real_type.
16754bool
16756{return base_ == other.base_ && modifiers_ == other.modifiers_;}
16757
16758/// Return the string representation of the current instance of @ref
16759/// real_type.
16760///
16761/// @param internal if true the string representation is to be used
16762/// for internal purposes. In general, it means it's for type
16763/// canonicalization purposes.
16764///
16765/// @return the string representation of the current instance of @ref
16766/// real_type.
16767string
16768real_type::to_string(bool internal) const
16769{
16770 string result;
16771
16772 // Look at modifiers ...
16773 if (modifiers_ & SIGNED_MODIFIER)
16774 result += "signed ";
16775 if (modifiers_ & UNSIGNED_MODIFIER)
16776 result += "unsigned ";
16777 if (!internal)
16778 {
16779 // For canonicalization purposes, we won't emit the "short, long, or
16780 // long long" modifiers. This is because on some platforms, "long
16781 // int" and "long long int" might have the same size. In those
16782 // cases, we want the two types to be equivalent if they have the
16783 // same size. If they don't have the same internal string
16784 // representation, they'd automatically have different canonical
16785 // types and thus be canonically different.
16786 if (modifiers_ & SHORT_MODIFIER)
16787 result += "short ";
16788 if (modifiers_ & LONG_MODIFIER)
16789 result += "long ";
16790 if (modifiers_ & LONG_LONG_MODIFIER)
16791 result += "long long ";
16792 }
16793
16794 // ... and look at base types.
16795 if (base_ == INT_BASE_TYPE)
16796 result += "int";
16797 else if (base_ == CHAR_BASE_TYPE)
16798 result += "char";
16799 else if (base_ == BOOL_BASE_TYPE)
16800 result += "bool";
16801 else if (base_ == DOUBLE_BASE_TYPE)
16802 result += "double";
16803 else if (base_ == FLOAT_BASE_TYPE)
16804 result += "float";
16805 else if (base_ == CHAR16_T_BASE_TYPE)
16806 result += "char16_t";
16807 else if (base_ == CHAR32_T_BASE_TYPE)
16808 result += "char32_t";
16809 else if (base_ == WCHAR_T_BASE_TYPE)
16810 result += "wchar_t";
16811 else if (base_ == ARRAY_SIZE_BASE_TYPE)
16812 result += "__ARRAY_SIZE_TYPE__";
16813 else if (base_ == SIZE_BASE_TYPE)
16814 result += "sizetype";
16815 else if (base_ == SSIZE_BASE_TYPE)
16816 result += "ssizetype";
16817 else if (base_ == BIT_SIZE_BASE_TYPE)
16818 result += "bitsizetype";
16819 else if (base_ == SBIT_SIZE_BASE_TYPE)
16820 result += "sbitsizetype";
16821 return result;
16822}
16823
16824/// Convert the current instance of @ref real_type into its string
16825/// representation.
16826///
16827/// @return the string representation of the current instance of @ref
16828/// real_type.
16829real_type::operator string() const
16830{return to_string();}
16831
16832// </real_type definitions>
16833
16834//<type_decl definitions>
16835
16836/// Constructor.
16837///
16838/// @param env the environment we are operating from.
16839///
16840/// @param name the name of the type declaration.
16841///
16842/// @param size_in_bits the size of the current type_decl, in bits.
16843///
16844/// @param alignment_in_bits the alignment of the current typ, in
16845/// bits.
16846///
16847/// @param locus the source location of the current type declaration.
16848///
16849/// @param linkage_name the linkage_name of the current type declaration.
16850///
16851/// @param vis the visibility of the type declaration.
16852type_decl::type_decl(const environment& env,
16853 const string& name,
16854 size_t size_in_bits,
16855 size_t alignment_in_bits,
16856 const location& locus,
16857 const string& linkage_name,
16858 visibility vis)
16859
16860 : type_or_decl_base(env,
16861 BASIC_TYPE
16862 | ABSTRACT_TYPE_BASE
16863 | ABSTRACT_DECL_BASE),
16864 decl_base(env, name, locus, linkage_name, vis),
16865 type_base(env, size_in_bits, alignment_in_bits)
16866{
16868
16870 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16871 real_type int_type(base_type, modifiers);
16872 if (parse_real_type(name, int_type))
16873 {
16874 // Convert the real_type into its canonical string
16875 // representation.
16876 string real_type_name = int_type;
16877
16878 // Set the name of this type_decl to the canonical string
16879 // representation above
16880 set_name(real_type_name);
16882
16883 if (!get_linkage_name().empty())
16884 set_linkage_name(real_type_name);
16885 }
16886}
16887
16888/// Return the hash value of the current IR node.
16889///
16890/// Note that upon the first invocation, this member functions
16891/// computes the hash value and returns it. Subsequent invocations
16892/// just return the hash value that was previously calculated.
16893///
16894/// @return the hash value of the current IR node.
16895hash_t
16897{
16899 return h;
16900}
16901
16902/// Compares two instances of @ref type_decl.
16903///
16904/// If the two intances are different, set a bitfield to give some
16905/// insight about the kind of differences there are.
16906///
16907/// @param l the first artifact of the comparison.
16908///
16909/// @param r the second artifact of the comparison.
16910///
16911/// @param k a pointer to a bitfield that gives information about the
16912/// kind of changes there are between @p l and @p r. This one is set
16913/// iff @p k is non-null and the function returns false.
16914///
16915/// Please note that setting k to a non-null value does have a
16916/// negative performance impact because even if @p l and @p r are not
16917/// equal, the function keeps up the comparison in order to determine
16918/// the different kinds of ways in which they are different.
16919///
16920/// @return true if @p l equals @p r, false otherwise.
16921bool
16922equals(const type_decl& l, const type_decl& r, change_kind* k)
16923{
16924 bool result = false;
16925
16926 // Consider the types as decls to compare their decls-related
16927 // properties.
16928 result = equals(static_cast<const decl_base&>(l),
16929 static_cast<const decl_base&>(r),
16930 k);
16931 if (!k && !result)
16933
16934 // Now consider the types a "types' to compare their size-related
16935 // properties.
16936 result &= equals(static_cast<const type_base&>(l),
16937 static_cast<const type_base&>(r),
16938 k);
16939 ABG_RETURN(result);
16940}
16941
16942/// Return true if both types equals.
16943///
16944/// This operator re-uses the overload that takes a decl_base.
16945///
16946/// Note that this does not check the scopes of any of the types.
16947///
16948/// @param o the other type_decl to check agains.
16949bool
16951{
16952 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16953 if (!other)
16954 return false;
16955 return *this == *other;
16956}
16957
16958/// Return true if both types equals.
16959///
16960/// Note that this does not check the scopes of any of the types.
16961///
16962/// @param o the other type_decl to check against.
16963bool
16965{
16966 const type_decl* other = dynamic_cast<const type_decl*>(&o);
16967 if (!other)
16968 return false;
16969 return try_canonical_compare(this, other);
16970}
16971
16972/// Return true if both types equals.
16973///
16974/// Note that this does not check the scopes of any of the types.
16975///
16976/// @param o the other type_decl to check against.
16977///
16978/// @return true iff the current isntance equals @p o
16979bool
16981{
16982 const decl_base& other = o;
16983 return *this == other;
16984}
16985
16986/// Return true if both types equals.
16987///
16988/// Note that this does not check the scopes of any of the types.
16989///
16990/// @param o the other type_decl to check against.
16991///
16992/// @return true iff the current isntance equals @p o
16993bool
16995{return !operator==(o);}
16996
16997/// Return true if both types equals.
16998///
16999/// Note that this does not check the scopes of any of the types.
17000///
17001/// @param o the other type_decl to check against.
17002///
17003/// @return true iff the current isntance equals @p o
17004bool
17006{return !operator==(o);}
17007
17008/// Inequality operator.
17009///
17010/// @param o the other type to compare against.
17011///
17012/// @return true iff the current instance is different from @p o.
17013bool
17015{return !operator==(o);}
17016
17017/// Equality operator for @ref type_decl_sptr.
17018///
17019/// @param l the first operand to compare.
17020///
17021/// @param r the second operand to compare.
17022///
17023/// @return true iff @p l equals @p r.
17024bool
17026{
17027 if (!!l != !!r)
17028 return false;
17029 if (l.get() == r.get())
17030 return true;
17031 return *l == *r;
17032}
17033
17034/// Inequality operator for @ref type_decl_sptr.
17035///
17036/// @param l the first operand to compare.
17037///
17038/// @param r the second operand to compare.
17039///
17040/// @return true iff @p l is different from @p r.
17041bool
17043{return !operator==(l, r);}
17044
17045/// Implementation for the virtual qualified name builder for @ref
17046/// type_decl.
17047///
17048/// @param qualified_name the output parameter to hold the resulting
17049/// qualified name.
17050///
17051/// @param internal set to true if the call is intended for an
17052/// internal use (for technical use inside the library itself), false
17053/// otherwise. If you don't know what this is for, then set it to
17054/// false.
17055void
17057 bool internal) const
17058{qualified_name = get_qualified_name(internal);}
17059
17060/// Implementation for the virtual qualified name builder for @ref
17061/// type_decl.
17062///
17063/// @param qualified_name the output parameter to hold the resulting
17064/// qualified name.
17065///
17066/// @param internal set to true if the call is intended for an
17067/// internal use (for technical use inside the library itself), false
17068/// otherwise. If you don't know what this is for, then set it to
17069/// false.
17070const interned_string&
17072{
17073 const environment& env = get_environment();
17074
17075
17076 if (internal)
17077 if (is_real_type(this))
17078 {
17080 {
17081 if (decl_base::priv_->internal_qualified_name_.empty())
17082 decl_base::priv_->internal_qualified_name_ =
17083 env.intern(get_internal_real_type_name(this));
17084 return decl_base::priv_->internal_qualified_name_;
17085 }
17086 else
17087 {
17088 decl_base::priv_->temporary_internal_qualified_name_ =
17089 env.intern(get_internal_real_type_name(this));
17090 return decl_base::priv_->temporary_internal_qualified_name_;
17091 }
17092 }
17093
17094 return decl_base::get_qualified_name(/*internal=*/false);
17095}
17096
17097/// Get the pretty representation of the current instance of @ref
17098/// type_decl.
17099///
17100/// @param internal set to true if the call is intended to get a
17101/// representation of the decl (or type) for the purpose of canonical
17102/// type comparison. This is mainly used in the function
17103/// type_base::get_canonical_type_for().
17104///
17105/// In other words if the argument for this parameter is true then the
17106/// call is meant for internal use (for technical use inside the
17107/// library itself), false otherwise. If you don't know what this is
17108/// for, then set it to false.
17109///
17110/// @param qualified_name if true, names emitted in the pretty
17111/// representation are fully qualified.
17112///
17113/// @return the pretty representatin of the @ref type_decl.
17114string
17116 bool qualified_name) const
17117{
17118 if (internal)
17119 if (is_real_type(this))
17120 return get_internal_real_type_name(this);
17121
17122 if (qualified_name)
17123 return get_qualified_name(internal);
17124 return get_name();
17125}
17126
17127/// This implements the ir_traversable_base::traverse pure virtual
17128/// function.
17129///
17130/// @param v the visitor used on the current instance.
17131///
17132/// @return true if the entire IR node tree got traversed, false
17133/// otherwise.
17134bool
17136{
17137 if (v.type_node_has_been_visited(this))
17138 return true;
17139
17140 v.visit_begin(this);
17141 bool result = v.visit_end(this);
17143
17144 return result;
17145}
17146
17147type_decl::~type_decl()
17148{}
17149//</type_decl definitions>
17150
17151// <scope_type_decl definitions>
17152
17153/// Constructor.
17154///
17155/// @param env the environment we are operating from.
17156///
17157/// @param name the name of the type.
17158///
17159/// @param size_in_bits the size of the type, in bits.
17160///
17161/// @param alignment_in_bits the alignment of the type, in bits.
17162///
17163/// @param locus the source location where the type is defined.
17164///
17165/// @param vis the visibility of the type.
17166scope_type_decl::scope_type_decl(const environment& env,
17167 const string& name,
17168 size_t size_in_bits,
17169 size_t alignment_in_bits,
17170 const location& locus,
17171 visibility vis)
17172 : type_or_decl_base(env,
17173 ABSTRACT_SCOPE_TYPE_DECL
17174 | ABSTRACT_TYPE_BASE
17175 | ABSTRACT_DECL_BASE),
17176 decl_base(env, name, locus, "", vis),
17177 type_base(env, size_in_bits, alignment_in_bits),
17178 scope_decl(env, name, locus)
17179{}
17180
17181/// Compares two instances of @ref scope_type_decl.
17182///
17183/// If the two intances are different, set a bitfield to give some
17184/// insight about the kind of differences there are.
17185///
17186/// @param l the first artifact of the comparison.
17187///
17188/// @param r the second artifact of the comparison.
17189///
17190/// @param k a pointer to a bitfield that gives information about the
17191/// kind of changes there are between @p l and @p r. This one is set
17192/// iff @p k is non-null and the function returns false.
17193///
17194/// Please note that setting k to a non-null value does have a
17195/// negative performance impact because even if @p l and @p r are not
17196/// equal, the function keeps up the comparison in order to determine
17197/// the different kinds of ways in which they are different.
17198///
17199/// @return true if @p l equals @p r, false otherwise.
17200bool
17202{
17203 bool result = equals(static_cast<const scope_decl&>(l),
17204 static_cast<const scope_decl&>(r),
17205 k);
17206
17207 if (!k && !result)
17209
17210 result &= equals(static_cast<const type_base&>(l),
17211 static_cast<const type_base&>(r),
17212 k);
17213
17214 ABG_RETURN(result);
17215}
17216
17217/// Equality operator between two scope_type_decl.
17218///
17219/// Note that this function does not consider the scope of the scope
17220/// types themselves.
17221///
17222/// @return true iff both scope types are equal.
17223bool
17225{
17226 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
17227 if (!other)
17228 return false;
17229 return try_canonical_compare(this, other);
17230}
17231
17232/// Equality operator between two scope_type_decl.
17233///
17234/// This re-uses the equality operator that takes a decl_base.
17235///
17236/// @param o the other scope_type_decl to compare against.
17237///
17238/// @return true iff both scope types are equal.
17239bool
17241{
17242 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17243 if (!other)
17244 return false;
17245
17246 return *this == *other;
17247}
17248
17249/// Traverses an instance of @ref scope_type_decl, visiting all the
17250/// sub-types and decls that it might contain.
17251///
17252/// @param v the visitor that is used to visit every IR sub-node of
17253/// the current node.
17254///
17255/// @return true if either
17256/// - all the children nodes of the current IR node were traversed
17257/// and the calling code should keep going with the traversing.
17258/// - or the current IR node is already being traversed.
17259/// Otherwise, returning false means that the calling code should not
17260/// keep traversing the tree.
17261bool
17263{
17264 if (visiting())
17265 return true;
17266
17267 if (v.type_node_has_been_visited(this))
17268 return true;
17269
17270 if (v.visit_begin(this))
17271 {
17272 visiting(true);
17273 for (scope_decl::declarations::const_iterator i =
17274 get_member_decls().begin();
17275 i != get_member_decls ().end();
17276 ++i)
17277 if (!(*i)->traverse(v))
17278 break;
17279 visiting(false);
17280 }
17281
17282 bool result = v.visit_end(this);
17284
17285 return result;
17286}
17287
17288scope_type_decl::~scope_type_decl()
17289{}
17290// </scope_type_decl definitions>
17291
17292// <namespace_decl>
17293
17294/// Constructor.
17295///
17296/// @param the environment we are operatin from.
17297///
17298/// @param name the name of the namespace.
17299///
17300/// @param locus the source location where the namespace is defined.
17301///
17302/// @param vis the visibility of the namespace.
17304 const string& name,
17305 const location& locus,
17306 visibility vis)
17307 // We need to call the constructor of decl_base directly here
17308 // because it is virtually inherited by scope_decl. Note that we
17309 // just implicitely call the default constructor for scope_decl
17310 // here, as what we really want is to initialize the decl_base
17311 // subobject. Wow, virtual inheritance is useful, but setting it
17312 // up is ugly.
17313 : type_or_decl_base(env,
17314 NAMESPACE_DECL
17315 | ABSTRACT_DECL_BASE
17316 | ABSTRACT_SCOPE_DECL),
17317 decl_base(env, name, locus, "", vis),
17318 scope_decl(env, name, locus)
17319{
17321}
17322
17323/// Build and return a copy of the pretty representation of the
17324/// namespace.
17325///
17326/// @param internal set to true if the call is intended to get a
17327/// representation of the decl (or type) for the purpose of canonical
17328/// type comparison. This is mainly used in the function
17329/// type_base::get_canonical_type_for().
17330///
17331/// In other words if the argument for this parameter is true then the
17332/// call is meant for internal use (for technical use inside the
17333/// library itself), false otherwise. If you don't know what this is
17334/// for, then set it to false.
17335///
17336/// @param qualified_name if true, names emitted in the pretty
17337/// representation are fully qualified.
17338///
17339/// @return a copy of the pretty representation of the namespace.
17340string
17342 bool qualified_name) const
17343{
17344 string r =
17345 "namespace " + scope_decl::get_pretty_representation(internal,
17346 qualified_name);
17347 return r;
17348}
17349
17350/// Return true iff both namespaces and their members are equal.
17351///
17352/// Note that this function does not check if the scope of these
17353/// namespaces are equal.
17354bool
17356{
17357 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
17358 if (!other)
17359 return false;
17360 return scope_decl::operator==(*other);
17361}
17362
17363/// Test if the current namespace_decl is empty or contains empty
17364/// namespaces itself.
17365///
17366/// @return true iff the current namespace_decl is empty or contains
17367/// empty itself.
17368bool
17370{
17371 if (is_empty())
17372 return true;
17373
17374 for (declarations::const_iterator i = get_member_decls().begin();
17375 i != get_member_decls().end();
17376 ++i)
17377 {
17378 if (!is_namespace(*i))
17379 return false;
17380
17382 ABG_ASSERT(ns);
17383
17384 if (!ns->is_empty_or_has_empty_sub_namespaces())
17385 return false;
17386 }
17387
17388 return true;
17389}
17390
17391/// This implements the ir_traversable_base::traverse pure virtual
17392/// function.
17393///
17394/// @param v the visitor used on the current instance and on its
17395/// member nodes.
17396///
17397/// @return true if the entire IR node tree got traversed, false
17398/// otherwise.
17399bool
17401{
17402 if (visiting())
17403 return true;
17404
17405 if (v.visit_begin(this))
17406 {
17407 visiting(true);
17408 scope_decl::declarations::const_iterator i;
17409 for (i = get_member_decls().begin();
17410 i != get_member_decls ().end();
17411 ++i)
17412 {
17414 dynamic_pointer_cast<ir_traversable_base>(*i);
17415 if (t)
17416 if (!t->traverse (v))
17417 break;
17418 }
17419 visiting(false);
17420 }
17421 return v.visit_end(this);
17422}
17423
17424namespace_decl::~namespace_decl()
17425{
17426}
17427
17428// </namespace_decl>
17429
17430// <qualified_type_def>
17431
17432/// Type of the private data of qualified_type_def.
17433class qualified_type_def::priv
17434{
17435 friend class qualified_type_def;
17436
17437 qualified_type_def::CV cv_quals_;
17438 // Before the type is canonicalized, this is used as a temporary
17439 // internal name.
17440 interned_string temporary_internal_name_;
17441 // Once the type is canonicalized, this is used as the internal
17442 // name.
17443 interned_string internal_name_;
17444 weak_ptr<type_base> underlying_type_;
17445
17446 priv()
17447 : cv_quals_(CV_NONE)
17448 {}
17449
17450 priv(qualified_type_def::CV quals,
17451 type_base_sptr t)
17452 : cv_quals_(quals),
17453 underlying_type_(t)
17454 {}
17455
17456 priv(qualified_type_def::CV quals)
17457 : cv_quals_(quals)
17458 {}
17459};// end class qualified_type_def::priv
17460
17461/// Build the name of the current instance of qualified type.
17462///
17463/// @param fully_qualified if true, build a fully qualified name.
17464///
17465/// @param internal set to true if the call is intended for an
17466/// internal use (for technical use inside the library itself), false
17467/// otherwise. If you don't know what this is for, then set it to
17468/// false.
17469///
17470/// @return a copy of the newly-built name.
17471string
17472qualified_type_def::build_name(bool fully_qualified, bool internal) const
17473{
17474 type_base_sptr t = get_underlying_type();
17475 if (!t)
17476 // The qualified type might temporarily have no underlying type,
17477 // especially during the construction of the type, while the
17478 // underlying type is not yet constructed. In that case, let's do
17479 // like if the underlying type is the 'void' type.
17481
17483 fully_qualified,
17484 internal);
17485}
17486
17487/// This function is automatically invoked whenever an instance of
17488/// this type is canonicalized.
17489///
17490/// It's an overload of the virtual type_base::on_canonical_type_set.
17491///
17492/// We put here what is thus meant to be executed only at the point of
17493/// type canonicalization.
17494void
17497
17498/// Constructor of the qualified_type_def
17499///
17500/// @param type the underlying type
17501///
17502/// @param quals a bitfield representing the const/volatile qualifiers
17503///
17504/// @param locus the location of the qualified type definition
17505qualified_type_def::qualified_type_def(type_base_sptr type,
17506 CV quals,
17507 const location& locus)
17508 : type_or_decl_base(type->get_environment(),
17509 QUALIFIED_TYPE
17510 | ABSTRACT_TYPE_BASE
17511 | ABSTRACT_DECL_BASE),
17512 type_base(type->get_environment(), type->get_size_in_bits(),
17513 type->get_alignment_in_bits()),
17514 decl_base(type->get_environment(), "", locus, "",
17515 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
17516 priv_(new priv(quals, type))
17517{
17519 interned_string name = type->get_environment().intern(build_name(false));
17520 set_name(name);
17521}
17522
17523/// Constructor of the qualified_type_def
17524///
17525/// @param env the environment of the type.
17526///
17527/// @param quals a bitfield representing the const/volatile qualifiers
17528///
17529/// @param locus the location of the qualified type definition
17530qualified_type_def::qualified_type_def(const environment& env,
17531 CV quals,
17532 const location& locus)
17533 : type_or_decl_base(env,
17534 QUALIFIED_TYPE
17535 | ABSTRACT_TYPE_BASE
17536 | ABSTRACT_DECL_BASE),
17537 type_base(env, /*size_in_bits=*/0,
17538 /*alignment_in_bits=*/0),
17539 decl_base(env, "", locus, ""),
17540 priv_(new priv(quals))
17541{
17543 // We don't yet have an underlying type. So for naming purpose,
17544 // let's temporarily pretend the underlying type is 'void'.
17545 interned_string name = env.intern("void");
17546 set_name(name);
17547}
17548
17549/// Return the hash value of the current IR node.
17550///
17551/// Note that upon the first invocation, this member functions
17552/// computes the hash value and returns it. Subsequent invocations
17553/// just return the hash value that was previously calculated.
17554///
17555/// @return the hash value of the current IR node.
17556hash_t
17558{
17560 return h;
17561}
17562
17563/// Get the size of the qualified type def.
17564///
17565/// This is an overload for type_base::get_size_in_bits().
17566///
17567/// @return the size of the qualified type.
17568size_t
17570{
17571 size_t s = 0;
17572 if (type_base_sptr ut = get_underlying_type())
17573 {
17574 // We do have the underlying type properly set, so let's make
17575 // the size of the qualified type match the size of its
17576 // underlying type.
17577 s = ut->get_size_in_bits();
17578 if (s != type_base::get_size_in_bits())
17579 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
17580 }
17582}
17583
17584/// Compares two instances of @ref qualified_type_def.
17585///
17586/// If the two intances are different, set a bitfield to give some
17587/// insight about the kind of differences there are.
17588///
17589/// @param l the first artifact of the comparison.
17590///
17591/// @param r the second artifact of the comparison.
17592///
17593/// @param k a pointer to a bitfield that gives information about the
17594/// kind of changes there are between @p l and @p r. This one is set
17595/// iff @p k is non-null and the function returns false.
17596///
17597/// Please note that setting k to a non-null value does have a
17598/// negative performance impact because even if @p l and @p r are not
17599/// equal, the function keeps up the comparison in order to determine
17600/// the different kinds of ways in which they are different.
17601///
17602/// @return true if @p l equals @p r, false otherwise.
17603bool
17605{
17606 bool result = true;
17607 if (l.get_cv_quals() != r.get_cv_quals())
17608 {
17609 result = false;
17610 if (k)
17612 else
17614 }
17615
17617 {
17618 result = false;
17619 if (k)
17620 {
17622 r.get_underlying_type().get()))
17623 // Underlying type changes in which the structure of the
17624 // type changed are considered local changes to the
17625 // qualified type.
17627 else
17628 *k |= SUBTYPE_CHANGE_KIND;
17629 }
17630 else
17631 // okay strictly speaking this is not necessary, but I am
17632 // putting it here to maintenance; that is, so that adding
17633 // subsequent clauses needed to compare two qualified types
17634 // later still works.
17636 }
17637
17638 ABG_RETURN(result);
17639}
17640
17641/// Equality operator for qualified types.
17642///
17643/// Note that this function does not check for equality of the scopes.
17644///
17645///@param o the other qualified type to compare against.
17646///
17647/// @return true iff both qualified types are equal.
17648bool
17650{
17651 const qualified_type_def* other =
17652 dynamic_cast<const qualified_type_def*>(&o);
17653 if (!other)
17654 return false;
17655 return try_canonical_compare(this, other);
17656}
17657
17658/// Equality operator for qualified types.
17659///
17660/// Note that this function does not check for equality of the scopes.
17661/// Also, this re-uses the equality operator above that takes a
17662/// decl_base.
17663///
17664///@param o the other qualified type to compare against.
17665///
17666/// @return true iff both qualified types are equal.
17667bool
17669{
17670 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17671 if (!other)
17672 return false;
17673 return *this == *other;
17674}
17675
17676/// Equality operator for qualified types.
17677///
17678/// Note that this function does not check for equality of the scopes.
17679/// Also, this re-uses the equality operator above that takes a
17680/// decl_base.
17681///
17682///@param o the other qualified type to compare against.
17683///
17684/// @return true iff both qualified types are equal.
17685bool
17687{
17688 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17689 if (!other)
17690 return false;
17691 return *this == *other;
17692}
17693
17694/// Implementation for the virtual qualified name builder for @ref
17695/// qualified_type_def.
17696///
17697/// @param qualified_name the output parameter to hold the resulting
17698/// qualified name.
17699///
17700/// @param internal set to true if the call is intended for an
17701/// internal use (for technical use inside the library itself), false
17702/// otherwise. If you don't know what this is for, then set it to
17703/// false.
17704void
17706 bool internal) const
17707{qualified_name = get_qualified_name(internal);}
17708
17709/// Implementation of the virtual qualified name builder/getter.
17710///
17711/// @param internal set to true if the call is intended for an
17712/// internal use (for technical use inside the library itself), false
17713/// otherwise. If you don't know what this is for, then set it to
17714/// false.
17715///
17716/// @return the resulting qualified name.
17717const interned_string&
17719{
17720 const environment& env = get_environment();
17721
17722
17723 if (!get_canonical_type())
17724 {
17725 // The type hasn't been canonicalized yet. We want to return a
17726 // temporary name that is not cached because the structure of
17727 // this type (and so its name) can change until its
17728 // canonicalized.
17729 if (internal)
17730 {
17731 // We are asked to return a temporary *internal* name.
17732 // Lets compute it and return a reference to where it's
17733 // stored.
17734 if (priv_->temporary_internal_name_.empty())
17735 priv_->temporary_internal_name_ =
17736 env.intern(build_name(true, /*internal=*/true));
17737 return priv_->temporary_internal_name_;
17738 }
17739 else
17740 {
17741 // We are asked to return a temporary non-internal name.
17743 (env.intern(build_name(true, /*internal=*/false)));
17745 }
17746 }
17747 else
17748 {
17749 // The type has already been canonicalized. We want to return
17750 // the definitive name and cache it.
17751 if (internal)
17752 {
17753 if (priv_->internal_name_.empty())
17754 priv_->internal_name_ =
17755 env.intern(build_name(/*qualified=*/true,
17756 /*internal=*/true));
17757 return priv_->internal_name_;
17758 }
17759 else
17760 {
17761 if (peek_qualified_name().empty())
17763 (env.intern(build_name(/*qualified=*/true,
17764 /*internal=*/false)));
17765 return peek_qualified_name();
17766 }
17767 }
17768}
17769
17770/// This implements the ir_traversable_base::traverse pure virtual
17771/// function.
17772///
17773/// @param v the visitor used on the current instance.
17774///
17775/// @return true if the entire IR node tree got traversed, false
17776/// otherwise.
17777bool
17779{
17780 if (v.type_node_has_been_visited(this))
17781 return true;
17782
17783 if (visiting())
17784 return true;
17785
17786 if (v.visit_begin(this))
17787 {
17788 visiting(true);
17789 if (type_base_sptr t = get_underlying_type())
17790 t->traverse(v);
17791 visiting(false);
17792 }
17793 bool result = v.visit_end(this);
17795 return result;
17796}
17797
17798qualified_type_def::~qualified_type_def()
17799{
17800}
17801
17802/// Getter of the const/volatile qualifier bit field
17805{return priv_->cv_quals_;}
17806
17807/// Setter of the const/value qualifiers bit field
17808void
17810{priv_->cv_quals_ = cv_quals;}
17811
17812/// Compute and return the string prefix or suffix representing the
17813/// qualifiers hold by the current instance of @ref
17814/// qualified_type_def.
17815///
17816/// @return the newly-built cv string.
17817string
17819{return get_string_representation_of_cv_quals(priv_->cv_quals_);}
17820
17821/// Getter of the underlying type
17822type_base_sptr
17824{return priv_->underlying_type_.lock();}
17825
17826/// Setter of the underlying type.
17827///
17828/// @param t the new underlying type.
17829void
17831{
17832 ABG_ASSERT(t);
17833 priv_->underlying_type_ = t;
17834 // Now we need to update other properties that depend on the new underlying type.
17835 set_size_in_bits(t->get_size_in_bits());
17836 set_alignment_in_bits(t->get_alignment_in_bits());
17838 set_name(name);
17839 if (scope_decl* s = get_scope())
17840 {
17841 // Now that the name has been updated, we need to update the
17842 // lookup maps accordingly.
17843 scope_decl::declarations::iterator i;
17844 if (s->find_iterator_for_member(this, i))
17846 else
17848 }
17849}
17850
17851/// Non-member equality operator for @ref qualified_type_def
17852///
17853/// @param l the left-hand side of the equality operator
17854///
17855/// @param r the right-hand side of the equality operator
17856///
17857/// @return true iff @p l and @p r equals.
17858bool
17859operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17860{
17861 if (l.get() == r.get())
17862 return true;
17863 if (!!l != !!r)
17864 return false;
17865
17866 return *l == *r;
17867}
17868
17869/// Non-member inequality operator for @ref qualified_type_def
17870///
17871/// @param l the left-hand side of the equality operator
17872///
17873/// @param r the right-hand side of the equality operator
17874///
17875/// @return true iff @p l and @p r equals.
17876bool
17877operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17878{return ! operator==(l, r);}
17879
17880/// Overloaded bitwise OR operator for cv qualifiers.
17883{
17884 return static_cast<qualified_type_def::CV>
17885 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
17886}
17887
17888/// Overloaded bitwise |= operator for cv qualifiers.
17891{
17892 l = l | r;
17893 return l;
17894}
17895
17896/// Overloaded bitwise &= operator for cv qualifiers.
17899{
17900 l = l & r;
17901 return l;
17902}
17903
17904/// Overloaded bitwise AND operator for CV qualifiers.
17907{
17908 return static_cast<qualified_type_def::CV>
17909 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
17910}
17911
17912/// Overloaded bitwise inverting operator for CV qualifiers.
17915{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
17916
17917/// Streaming operator for qualified_type_decl::CV
17918///
17919/// @param o the output stream to serialize the cv qualifier to.
17920///
17921/// @param cv the cv qualifier to serialize.
17922///
17923/// @return the output stream used.
17924std::ostream&
17925operator<<(std::ostream& o, qualified_type_def::CV cv)
17926{
17927 string str;
17928
17929 switch (cv)
17930 {
17931 case qualified_type_def::CV_NONE:
17932 str = "none";
17933 break;
17934 case qualified_type_def::CV_CONST:
17935 str = "const";
17936 break;
17937 case qualified_type_def::CV_VOLATILE:
17938 str = "volatile";
17939 break;
17940 case qualified_type_def::CV_RESTRICT:
17941 str = "restrict";
17942 break;
17943 }
17944
17945 o << str;
17946 return o;
17947}
17948
17949// </qualified_type_def>
17950
17951//<pointer_type_def definitions>
17952
17953/// Private data structure of the @ref pointer_type_def.
17954struct pointer_type_def::priv
17955{
17956 type_base_wptr pointed_to_type_;
17957 type_base* naked_pointed_to_type_;
17958 interned_string internal_qualified_name_;
17959 interned_string temp_internal_qualified_name_;
17960
17961 priv(const type_base_sptr& t)
17962 : pointed_to_type_(type_or_void(t, t->get_environment())),
17963 naked_pointed_to_type_(t.get())
17964 {}
17965
17966 priv()
17967 : naked_pointed_to_type_()
17968 {}
17969}; //end struct pointer_type_def
17970
17971/// This function is automatically invoked whenever an instance of
17972/// this type is canonicalized.
17973///
17974/// It's an overload of the virtual type_base::on_canonical_type_set.
17975///
17976/// We put here what is thus meant to be executed only at the point of
17977/// type canonicalization.
17978void
17981
17982
17983///Constructor of @ref pointer_type_def.
17984///
17985/// @param pointed_to the pointed-to type.
17986///
17987/// @param size_in_bits the size of the type, in bits.
17988///
17989/// @param align_in_bits the alignment of the type, in bits.
17990///
17991/// @param locus the source location where the type was defined.
17992pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
17993 size_t size_in_bits,
17994 size_t align_in_bits,
17995 const location& locus)
17996 : type_or_decl_base(pointed_to->get_environment(),
17997 POINTER_TYPE
17998 | ABSTRACT_TYPE_BASE
17999 | ABSTRACT_DECL_BASE),
18000 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18001 decl_base(pointed_to->get_environment(), "", locus, ""),
18002 priv_(new priv(pointed_to))
18003{
18005 try
18006 {
18007 ABG_ASSERT(pointed_to);
18008 const environment& env = pointed_to->get_environment();
18009 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18010 string name = (pto ? pto->get_name() : string("void")) + "*";
18011 set_name(env.intern(name));
18012 if (pto)
18013 set_visibility(pto->get_visibility());
18014 }
18015 catch (...)
18016 {}
18017}
18018
18019///Constructor of @ref pointer_type_def.
18020///
18021/// @param env the environment of the type.
18022///
18023/// @param size_in_bits the size of the type, in bits.
18024///
18025/// @param align_in_bits the alignment of the type, in bits.
18026///
18027/// @param locus the source location where the type was defined.
18028pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
18029 size_t alignment_in_bits,
18030 const location& locus)
18031 : type_or_decl_base(env,
18032 POINTER_TYPE
18033 | ABSTRACT_TYPE_BASE
18034 | ABSTRACT_DECL_BASE),
18035 type_base(env, size_in_bits, alignment_in_bits),
18036 decl_base(env, "", locus, ""),
18037 priv_(new priv())
18038{
18040 string name = string("void") + "*";
18041 set_name(env.intern(name));
18042}
18043
18044/// Return the hash value of the current IR node.
18045///
18046/// Note that upon the first invocation, this member functions
18047/// computes the hash value and returns it. Subsequent invocations
18048/// just return the hash value that was previously calculated.
18049///
18050/// @return the hash value of the current IR node.
18051hash_t
18053{
18055 return h;
18056}
18057
18058/// Set the pointed-to type of the pointer.
18059///
18060/// @param t the new pointed-to type.
18061void
18063{
18064 ABG_ASSERT(t);
18065 priv_->pointed_to_type_ = t;
18066 priv_->naked_pointed_to_type_ = t.get();
18067
18068 try
18069 {
18070 const environment& env = t->get_environment();
18071 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
18072 string name = (pto ? pto->get_name() : string("void")) + "*";
18073 set_name(env.intern(name));
18074 if (pto)
18075 set_visibility(pto->get_visibility());
18076 }
18077 catch (...)
18078 {}
18079}
18080
18081/// Compares two instances of @ref pointer_type_def.
18082///
18083/// If the two intances are different, set a bitfield to give some
18084/// insight about the kind of differences there are.
18085///
18086/// @param l the first artifact of the comparison.
18087///
18088/// @param r the second artifact of the comparison.
18089///
18090/// @param k a pointer to a bitfield that gives information about the
18091/// kind of changes there are between @p l and @p r. This one is set
18092/// iff @p k is non-null and the function returns false.
18093///
18094/// Please note that setting k to a non-null value does have a
18095/// negative performance impact because even if @p l and @p r are not
18096/// equal, the function keeps up the comparison in order to determine
18097/// the different kinds of ways in which they are different.
18098///
18099/// @return true if @p l equals @p r, false otherwise.
18100bool
18102{
18103 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18104 bool result = p1 == p2;
18105 if (!result)
18106 if (k)
18107 {
18108 if (!types_have_similar_structure(&l, &r))
18109 // pointed-to type changes in which the structure of the
18110 // type changed are considered local changes to the pointer
18111 // type.
18113 *k |= SUBTYPE_CHANGE_KIND;
18114 }
18115
18116 ABG_RETURN(result);
18117}
18118
18119/// Return true iff both instances of pointer_type_def are equal.
18120///
18121/// Note that this function does not check for the scopes of the this
18122/// types.
18123bool
18125{
18126 const pointer_type_def* other = is_pointer_type(&o);
18127 if (!other)
18128 return false;
18129 return try_canonical_compare(this, other);
18130}
18131
18132/// Return true iff both instances of pointer_type_def are equal.
18133///
18134/// Note that this function does not check for the scopes of the
18135/// types.
18136///
18137/// @param other the other type to compare against.
18138///
18139/// @return true iff @p other equals the current instance.
18140bool
18142{
18143 const decl_base* o = is_decl(&other);
18144 if (!o)
18145 return false;
18146 return *this == *o;
18147}
18148
18149/// Return true iff both instances of pointer_type_def are equal.
18150///
18151/// Note that this function does not check for the scopes of the
18152/// types.
18153///
18154/// @param other the other type to compare against.
18155///
18156/// @return true iff @p other equals the current instance.
18157bool
18159{
18160 const decl_base& o = other;
18161 return *this == o;
18162}
18163
18164/// Getter of the pointed-to type.
18165///
18166/// @return the pointed-to type.
18167const type_base_sptr
18169{return priv_->pointed_to_type_.lock();}
18170
18171/// Getter of a naked pointer to the pointed-to type.
18172///
18173/// @return a naked pointed to the pointed-to type.
18174type_base*
18176{return priv_->naked_pointed_to_type_;}
18177
18178/// Build and return the qualified name of the current instance of
18179/// @ref pointer_type_def.
18180///
18181/// @param qn output parameter. The resulting qualified name.
18182///
18183/// @param internal set to true if the call is intended for an
18184/// internal use (for technical use inside the library itself), false
18185/// otherwise. If you don't know what this is for, then set it to
18186/// false.
18187void
18189{qn = get_qualified_name(internal);}
18190
18191/// Build, cache and return the qualified name of the current instance
18192/// of @ref pointer_type_def. Subsequent invocations of this function
18193/// return the cached value.
18194///
18195/// Note that this function should work even if the underlying type is
18196/// momentarily empty.
18197///
18198/// @param internal set to true if the call is intended for an
18199/// internal use (for technical use inside the library itself), false
18200/// otherwise. If you don't know what this is for, then set it to
18201/// false.
18202///
18203/// @return the resulting qualified name.
18204const interned_string&
18206{
18207 type_base* pointed_to_type = get_naked_pointed_to_type();
18208 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18209
18210 if (internal)
18211 {
18212 if (get_canonical_type())
18213 {
18214 if (priv_->internal_qualified_name_.empty())
18215 if (pointed_to_type)
18216 priv_->internal_qualified_name_ =
18217 pointer_declaration_name(this,
18218 /*variable_name=*/"",
18219 /*qualified_name=*/
18220 is_typedef(pointed_to_type)
18221 ? false
18222 : true,
18223 /*internal=*/true);
18224 return priv_->internal_qualified_name_;
18225 }
18226 else
18227 {
18228 // As the type hasn't yet been canonicalized, its structure
18229 // (and so its name) can change. So let's invalidate the
18230 // cache where we store its name at each invocation of this
18231 // function.
18232 if (pointed_to_type)
18233 if (priv_->temp_internal_qualified_name_.empty())
18234 priv_->temp_internal_qualified_name_ =
18235 pointer_declaration_name(this,
18236 /*variable_name=*/"",
18237 /*qualified_name=*/
18238 is_typedef(pointed_to_type)
18239 ? false
18240 : true,
18241 /*internal=*/true);
18242 return priv_->temp_internal_qualified_name_;
18243 }
18244 }
18245 else
18246 {
18248 {
18249 if (decl_base::peek_qualified_name().empty())
18251 (pointer_declaration_name(this,
18252 /*variable_name=*/"",
18253 /*qualified_name=*/true,
18254 /*internal=*/false));
18256 }
18257 else
18258 {
18259 // As the type hasn't yet been canonicalized, its structure
18260 // (and so its name) can change. So let's invalidate the
18261 // cache where we store its name at each invocation of this
18262 // function.
18263 if (pointed_to_type)
18265 (pointer_declaration_name(this,
18266 /*variable_name=*/"",
18267 /*qualified_name=*/true,
18268 /*internal=*/false));
18270 }
18271 }
18272}
18273
18274/// This implements the ir_traversable_base::traverse pure virtual
18275/// function.
18276///
18277/// @param v the visitor used on the current instance.
18278///
18279/// @return true if the entire IR node tree got traversed, false
18280/// otherwise.
18281bool
18283{
18284 if (v.type_node_has_been_visited(this))
18285 return true;
18286
18287 if (visiting())
18288 return true;
18289
18290 if (v.visit_begin(this))
18291 {
18292 visiting(true);
18293 if (type_base_sptr t = get_pointed_to_type())
18294 t->traverse(v);
18295 visiting(false);
18296 }
18297
18298 bool result = v.visit_end(this);
18300 return result;
18301}
18302
18303pointer_type_def::~pointer_type_def()
18304{}
18305
18306/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
18307/// equality; that is, make it compare the pointed to objects too.
18308///
18309/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18310/// of the equality.
18311///
18312/// @param r the shared_ptr of @ref pointer_type_def on
18313/// right-hand-side of the equality.
18314///
18315/// @return true if the @ref pointer_type_def pointed to by the
18316/// shared_ptrs are equal, false otherwise.
18317bool
18319{
18320 if (l.get() == r.get())
18321 return true;
18322 if (!!l != !!r)
18323 return false;
18324
18325 return *l == *r;
18326}
18327
18328/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
18329/// equality; that is, make it compare the pointed to objects too.
18330///
18331/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18332/// of the equality.
18333///
18334/// @param r the shared_ptr of @ref pointer_type_def on
18335/// right-hand-side of the equality.
18336///
18337/// @return true iff the @ref pointer_type_def pointed to by the
18338/// shared_ptrs are different.
18339bool
18341{return !operator==(l, r);}
18342
18343// </pointer_type_def definitions>
18344
18345// <reference_type_def definitions>
18346
18347/// Private data structure of the @ref reference_type_def type.
18348struct reference_type_def::priv
18349{
18350
18351 type_base_wptr pointed_to_type_;
18352 bool is_lvalue_;
18353 interned_string internal_qualified_name_;
18354 interned_string temp_internal_qualified_name_;
18355
18356 priv(const type_base_sptr& t, bool is_lvalue)
18357 : pointed_to_type_(type_or_void(t, t->get_environment())),
18358 is_lvalue_(is_lvalue)
18359 {}
18360
18361 priv(bool is_lvalue)
18362 : is_lvalue_(is_lvalue)
18363 {}
18364
18365 priv() = delete;
18366};
18367
18368/// This function is automatically invoked whenever an instance of
18369/// this type is canonicalized.
18370///
18371/// It's an overload of the virtual type_base::on_canonical_type_set.
18372///
18373/// We put here what is thus meant to be executed only at the point of
18374/// type canonicalization.
18375void
18378
18379/// Constructor of the reference_type_def type.
18380///
18381/// @param pointed_to the pointed to type.
18382///
18383/// @param lvalue wether the reference is an lvalue reference. If
18384/// false, the reference is an rvalue one.
18385///
18386/// @param size_in_bits the size of the type, in bits.
18387///
18388/// @param align_in_bits the alignment of the type, in bits.
18389///
18390/// @param locus the source location of the type.
18391reference_type_def::reference_type_def(const type_base_sptr pointed_to,
18392 bool lvalue,
18393 size_t size_in_bits,
18394 size_t align_in_bits,
18395 const location& locus)
18396 : type_or_decl_base(pointed_to->get_environment(),
18397 REFERENCE_TYPE
18398 | ABSTRACT_TYPE_BASE
18399 | ABSTRACT_DECL_BASE),
18400 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18401 decl_base(pointed_to->get_environment(), "", locus, ""),
18402 priv_(new priv(pointed_to, lvalue))
18403{
18405
18406 try
18407 {
18408 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18409 string name;
18410 if (pto)
18411 {
18412 set_visibility(pto->get_visibility());
18413 name = string(pto->get_name()) + "&";
18414 }
18415 else
18416 name = string(get_type_name(is_function_type(pointed_to),
18417 /*qualified_name=*/true)) + "&";
18418
18419 if (!is_lvalue())
18420 name += "&";
18421 const environment& env = pointed_to->get_environment();
18422 set_name(env.intern(name));
18423 }
18424 catch (...)
18425 {}
18426}
18427
18428/// Constructor of the reference_type_def type.
18429///
18430/// This one creates a type that has no pointed-to type, temporarily.
18431/// This is useful for cases where the underlying type is not yet
18432/// available. It can be set later using
18433/// reference_type_def::set_pointed_to_type().
18434///
18435/// @param env the environment of the type.
18436///
18437/// @param lvalue wether the reference is an lvalue reference. If
18438/// false, the reference is an rvalue one.
18439///
18440/// @param size_in_bits the size of the type, in bits.
18441///
18442/// @param align_in_bits the alignment of the type, in bits.
18443///
18444/// @param locus the source location of the type.
18445reference_type_def::reference_type_def(const environment& env, bool lvalue,
18446 size_t size_in_bits,
18447 size_t alignment_in_bits,
18448 const location& locus)
18449 : type_or_decl_base(env,
18450 REFERENCE_TYPE
18451 | ABSTRACT_TYPE_BASE
18452 | ABSTRACT_DECL_BASE),
18453 type_base(env, size_in_bits, alignment_in_bits),
18454 decl_base(env, "", locus, ""),
18455 priv_(new priv(lvalue))
18456{
18458 string name = "void&";
18459 if (!is_lvalue())
18460 name += "&";
18461
18462 set_name(env.intern(name));
18463 priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
18464}
18465
18466/// Return the hash value of the current IR node.
18467///
18468/// Note that upon the first invocation, this member functions
18469/// computes the hash value and returns it. Subsequent invocations
18470/// just return the hash value that was previously calculated.
18471///
18472/// @return the hash value of the current IR node.
18473hash_t
18475{
18477 return h;
18478}
18479
18480/// Setter of the pointed_to type of the current reference type.
18481///
18482/// @param pointed_to the new pointed to type.
18483void
18484reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
18485{
18486 ABG_ASSERT(pointed_to_type);
18487 priv_->pointed_to_type_ = pointed_to_type;
18488
18489 decl_base_sptr pto;
18490 try
18491 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
18492 catch (...)
18493 {}
18494
18495 if (pto)
18496 {
18497 set_visibility(pto->get_visibility());
18498 string name = string(pto->get_name()) + "&";
18499 if (!is_lvalue())
18500 name += "&";
18501 const environment& env = pto->get_environment();
18502 set_name(env.intern(name));
18503 }
18504}
18505
18506/// Compares two instances of @ref reference_type_def.
18507///
18508/// If the two intances are different, set a bitfield to give some
18509/// insight about the kind of differences there are.
18510///
18511/// @param l the first artifact of the comparison.
18512///
18513/// @param r the second artifact of the comparison.
18514///
18515/// @param k a pointer to a bitfield that gives information about the
18516/// kind of changes there are between @p l and @p r. This one is set
18517/// iff @p k is non-null and the function returns false.
18518///
18519/// Please note that setting k to a non-null value does have a
18520/// negative performance impact because even if @p l and @p r are not
18521/// equal, the function keeps up the comparison in order to determine
18522/// the different kinds of ways in which they are different.
18523///
18524/// @return true if @p l equals @p r, false otherwise.
18525bool
18527{
18528 if (l.is_lvalue() != r.is_lvalue())
18529 {
18530 if (k)
18533 }
18534 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18535 bool result = p1 == p2;
18536 if (!result)
18537 if (k)
18538 {
18539 if (!types_have_similar_structure(&l, &r))
18541 *k |= SUBTYPE_CHANGE_KIND;
18542 }
18543 ABG_RETURN(result);
18544}
18545
18546/// Equality operator of the @ref reference_type_def type.
18547///
18548/// @param o the other instance of @ref reference_type_def to compare
18549/// against.
18550///
18551/// @return true iff the two instances are equal.
18552bool
18554{
18555 const reference_type_def* other =
18556 dynamic_cast<const reference_type_def*>(&o);
18557 if (!other)
18558 return false;
18559 return try_canonical_compare(this, other);
18560}
18561
18562/// Equality operator of the @ref reference_type_def type.
18563///
18564/// @param o the other instance of @ref reference_type_def to compare
18565/// against.
18566///
18567/// @return true iff the two instances are equal.
18568bool
18570{
18571 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18572 if (!other)
18573 return false;
18574 return *this == *other;
18575}
18576
18577/// Equality operator of the @ref reference_type_def type.
18578///
18579/// @param o the other instance of @ref reference_type_def to compare
18580/// against.
18581///
18582/// @return true iff the two instances are equal.
18583bool
18585{
18586 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18587 if (!other)
18588 return false;
18589 return *this == *other;
18590}
18591
18592type_base_sptr
18593reference_type_def::get_pointed_to_type() const
18594{return priv_->pointed_to_type_.lock();}
18595
18596bool
18597reference_type_def::is_lvalue() const
18598{return priv_->is_lvalue_;}
18599
18600/// Build and return the qualified name of the current instance of the
18601/// @ref reference_type_def.
18602///
18603/// @param qn output parameter. Is set to the newly-built qualified
18604/// name of the current instance of @ref reference_type_def.
18605///
18606/// @param internal set to true if the call is intended for an
18607/// internal use (for technical use inside the library itself), false
18608/// otherwise. If you don't know what this is for, then set it to
18609/// false.
18610void
18612{qn = get_qualified_name(internal);}
18613
18614/// Build, cache and return the qualified name of the current instance
18615/// of the @ref reference_type_def. Subsequent invocations of this
18616/// function return the cached value.
18617///
18618/// @param internal set to true if the call is intended for an
18619/// internal use (for technical use inside the library itself), false
18620/// otherwise. If you don't know what this is for, then set it to
18621/// false.
18622///
18623/// @return the newly-built qualified name of the current instance of
18624/// @ref reference_type_def.
18625const interned_string&
18627{
18628 type_base_sptr pointed_to_type = get_pointed_to_type();
18629 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18630
18631 if (internal)
18632 {
18633 if (get_canonical_type())
18634 {
18635 if (priv_->internal_qualified_name_.empty())
18636 if (pointed_to_type)
18637 priv_->internal_qualified_name_ =
18638 get_name_of_reference_to_type(*pointed_to_type,
18639 is_lvalue(),
18640 /*qualified_name=*/
18641 is_typedef(pointed_to_type)
18642 ? false
18643 : true,
18644 /*internal=*/true);
18645 return priv_->internal_qualified_name_;
18646 }
18647 else
18648 {
18649 // As the type hasn't yet been canonicalized, its structure
18650 // (and so its name) can change. So let's invalidate the
18651 // cache where we store its name at each invocation of this
18652 // function.
18653 if (pointed_to_type)
18654 if (priv_->temp_internal_qualified_name_.empty())
18655 priv_->temp_internal_qualified_name_ =
18656 get_name_of_reference_to_type(*pointed_to_type,
18657 is_lvalue(),
18658 /*qualified_name=*/
18659 is_typedef(pointed_to_type)
18660 ? false
18661 : true,
18662 /*internal=*/true);
18663 return priv_->temp_internal_qualified_name_;
18664 }
18665 }
18666 else
18667 {
18669 {
18671 (get_name_of_reference_to_type(*pointed_to_type,
18672 is_lvalue(),
18673 /*qualified_name=*/true,
18674 /*internal=*/false));
18676 }
18677 else
18678 {
18679 // As the type hasn't yet been canonicalized, its structure
18680 // (and so its name) can change. So let's invalidate the
18681 // cache where we store its name at each invocation of this
18682 // function.
18683 if (pointed_to_type)
18685 (get_name_of_reference_to_type(*pointed_to_type,
18686 is_lvalue(),
18687 /*qualified_name=*/true,
18688 /*internal=*/false));
18690 }
18691 }
18692}
18693
18694/// Get the pretty representation of the current instance of @ref
18695/// reference_type_def.
18696///
18697/// @param internal set to true if the call is intended to get a
18698/// representation of the decl (or type) for the purpose of canonical
18699/// type comparison. This is mainly used in the function
18700/// type_base::get_canonical_type_for().
18701///
18702/// In other words if the argument for this parameter is true then the
18703/// call is meant for internal use (for technical use inside the
18704/// library itself), false otherwise. If you don't know what this is
18705/// for, then set it to false.
18706///
18707/// @param qualified_name if true, names emitted in the pretty
18708/// representation are fully qualified.
18709///
18710/// @return the pretty representatin of the @ref reference_type_def.
18711string
18713 bool qualified_name) const
18714{
18715 string result =
18717 (get_pointed_to_type()),
18718 is_lvalue(),
18719 qualified_name,
18720 internal);
18721
18722 return result;
18723}
18724
18725/// This implements the ir_traversable_base::traverse pure virtual
18726/// function.
18727///
18728/// @param v the visitor used on the current instance.
18729///
18730/// @return true if the entire IR node tree got traversed, false
18731/// otherwise.
18732bool
18734{
18735 if (v.type_node_has_been_visited(this))
18736 return true;
18737
18738 if (visiting())
18739 return true;
18740
18741 if (v.visit_begin(this))
18742 {
18743 visiting(true);
18744 if (type_base_sptr t = get_pointed_to_type())
18745 t->traverse(v);
18746 visiting(false);
18747 }
18748
18749 bool result = v.visit_end(this);
18751 return result;
18752}
18753
18754reference_type_def::~reference_type_def()
18755{}
18756
18757/// Turn equality of shared_ptr of @ref reference_type_def into a deep
18758/// equality; that is, make it compare the pointed to objects too.
18759///
18760/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18761/// of the equality.
18762///
18763/// @param r the shared_ptr of @ref reference_type_def on
18764/// right-hand-side of the equality.
18765///
18766/// @return true if the @ref reference_type_def pointed to by the
18767/// shared_ptrs are equal, false otherwise.
18768bool
18770{
18771 if (l.get() == r.get())
18772 return true;
18773 if (!!l != !!r)
18774 return false;
18775
18776 return *l == *r;
18777}
18778
18779/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
18780/// equality; that is, make it compare the pointed to objects too.
18781///
18782/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18783/// of the equality.
18784///
18785/// @param r the shared_ptr of @ref reference_type_def on
18786/// right-hand-side of the equality.
18787///
18788/// @return true iff the @ref reference_type_def pointed to by the
18789/// shared_ptrs are different.
18790bool
18792{return !operator==(l, r);}
18793
18794// </reference_type_def definitions>
18795
18796// <ptr_to_mbr_type definitions>
18797
18798/// The private data type of @ref ptr_to_mbr_type.
18799struct ptr_to_mbr_type::priv
18800{
18801 // The type of the data member this pointer-to-member-type
18802 // designates.
18803 type_base_sptr dm_type_;
18804 // The class (or typedef to potentially qualified class) containing
18805 // the data member this pointer-to-member-type designates.
18806 type_base_sptr containing_type_;
18807 interned_string internal_qualified_name_;
18808 interned_string temp_internal_qualified_name_;
18809
18810 priv()
18811 {}
18812
18813 priv(const type_base_sptr& dm_type, const type_base_sptr& containing_type)
18814 : dm_type_(dm_type),
18815 containing_type_(containing_type)
18816 {}
18817};// end struct ptr_to_mbr_type::priv
18818
18819/// A constructor for a @ref ptr_to_mbr_type type.
18820///
18821/// @param env the environment to construct the @ref ptr_to_mbr_type in.
18822///
18823/// @param member_type the member type of the of the @ref
18824/// ptr_to_mbr_type to construct.
18825///
18826/// @param containing_type the containing type of the @ref
18827/// ptr_to_mbr_type to construct.
18828///
18829/// @param size_in_bits the size (in bits) of the resulting type.
18830///
18831/// @param alignment_in_bits the alignment (in bits) of the resulting
18832/// type.
18833///
18834/// @param locus the source location of the definition of the
18835/// resulting type.
18836ptr_to_mbr_type::ptr_to_mbr_type(const environment& env,
18837 const type_base_sptr& member_type,
18838 const type_base_sptr& containing_type,
18839 size_t size_in_bits,
18840 size_t alignment_in_bits,
18841 const location& locus)
18842 : type_or_decl_base(env,
18843 POINTER_TO_MEMBER_TYPE
18844 | ABSTRACT_TYPE_BASE
18845 | ABSTRACT_DECL_BASE),
18846 type_base(env, size_in_bits, alignment_in_bits),
18847 decl_base(env, "", locus, ""),
18848 priv_(new priv(member_type, containing_type))
18849{
18851 ABG_ASSERT(member_type);
18852 ABG_ASSERT(containing_type);
18853 set_is_anonymous(false);
18854}
18855
18856/// Getter of the name of the current ptr-to-mbr-type.
18857///
18858/// This just returns the qualified name.
18859///
18860/// @return the (qualified) name of the the type.
18861const interned_string&
18863{
18864 return get_qualified_name(/*internal=*/false);
18865}
18866
18867/// Return the hash value of the current IR node.
18868///
18869/// Note that upon the first invocation, this member functions
18870/// computes the hash value and returns it. Subsequent invocations
18871/// just return the hash value that was previously calculated.
18872///
18873/// @return the hash value of the current IR node.
18874hash_t
18876{
18878 return h;
18879}
18880
18881/// Getter of the member type of the current @ref ptr_to_mbr_type.
18882///
18883/// @return the type of the member referred to by the current
18884/// @ptr_to_mbr_type.
18885const type_base_sptr&
18887{return priv_->dm_type_;}
18888
18889/// Getter of the type containing the member pointed-to by the current
18890/// @ref ptr_to_mbr_type.
18891///
18892/// @return the type containing the member pointed-to by the current
18893/// @ref ptr_to_mbr_type.
18894const type_base_sptr&
18896{return priv_->containing_type_;}
18897
18898/// Equality operator for the current @ref ptr_to_mbr_type.
18899///
18900///@param o the other instance of @ref ptr_to_mbr_type to compare the
18901///current instance to.
18902///
18903/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18904bool
18906{
18907 const ptr_to_mbr_type* other =
18908 dynamic_cast<const ptr_to_mbr_type*>(&o);
18909 if (!other)
18910 return false;
18911 return try_canonical_compare(this, other);
18912}
18913
18914/// Equality operator for the current @ref ptr_to_mbr_type.
18915///
18916///@param o the other instance of @ref ptr_to_mbr_type to compare the
18917///current instance to.
18918///
18919/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18920bool
18922{
18923 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18924 if (!other)
18925 return false;
18926 return *this == *other;
18927}
18928
18929/// Equality operator for the current @ref ptr_to_mbr_type.
18930///
18931///@param o the other instance of @ref ptr_to_mbr_type to compare the
18932///current instance to.
18933///
18934/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18935bool
18937{
18938 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18939 if (!other)
18940 return false;
18941 return *this == *other;
18942}
18943
18944/// Get the qualified name for the current @ref ptr_to_mbr_type.
18945///
18946/// @param qualified_name out parameter. This is set to the name of
18947/// the current @ref ptr_to_mbr_type.
18948///
18949/// @param internal if this is true, then the qualified name is for
18950/// the purpose of type canoicalization.
18951void
18953 bool internal) const
18954{qualified_name = get_qualified_name(internal);}
18955
18956/// Get the qualified name for the current @ref ptr_to_mbr_type.
18957///
18958/// @param internal if this is true, then the qualified name is for
18959/// the purpose of type canoicalization.
18960///
18961/// @return the qualified name for the current @ref ptr_to_mbr_type.
18962const interned_string&
18964{
18965 type_base_sptr member_type = get_member_type();
18966 type_base_sptr containing_type = get_containing_type();
18967
18968 if (internal)
18969 {
18970 if (get_canonical_type())
18971 {
18972 if (priv_->internal_qualified_name_.empty())
18973 priv_->internal_qualified_name_ =
18974 ptr_to_mbr_declaration_name(this, "",
18975 /*qualified=*/true,
18976 internal);
18977 return priv_->internal_qualified_name_;
18978 }
18979 else
18980 {
18981 priv_->temp_internal_qualified_name_ =
18982 ptr_to_mbr_declaration_name(this, "", /*qualified=*/true, internal);
18983 return priv_->temp_internal_qualified_name_;
18984 }
18985 }
18986 else
18987 {
18989 (ptr_to_mbr_declaration_name(this, "", /*qualified=*/true,
18990 /*internal=*/false));
18992 }
18993}
18994
18995/// This implements the ir_traversable_base::traverse pure virtual
18996/// function for @ref ptr_to_mbr_type.
18997///
18998/// @param v the visitor used on the current instance.
18999///
19000/// @return true if the entire IR node tree got traversed, false
19001/// otherwise.
19002bool
19004{
19005 if (v.type_node_has_been_visited(this))
19006 return true;
19007
19008 if (visiting())
19009 return true;
19010
19011 if (v.visit_begin(this))
19012 {
19013 visiting(true);
19014 if (type_base_sptr t = get_member_type())
19015 t->traverse(v);
19016
19017 if (type_base_sptr t = get_containing_type())
19018 t->traverse(v);
19019 visiting(false);
19020 }
19021
19022 bool result = v.visit_end(this);
19024 return result;
19025}
19026
19027/// Desctructor for @ref ptr_to_mbr_type.
19029{}
19030
19031
19032/// Compares two instances of @ref ptr_to_mbr_type.
19033///
19034/// If the two intances are different, set a bitfield to give some
19035/// insight about the kind of differences there are.
19036///
19037/// @param l the first artifact of the comparison.
19038///
19039/// @param r the second artifact of the comparison.
19040///
19041/// @param k a pointer to a bitfield that gives information about the
19042/// kind of changes there are between @p l and @p r. This one is set
19043/// iff @p k is non-null and the function returns false.
19044///
19045/// Please note that setting k to a non-null value does have a
19046/// negative performance impact because even if @p l and @p r are not
19047/// equal, the function keeps up the comparison in order to determine
19048/// the different kinds of ways in which they are different.
19049///
19050/// @return true if @p l equals @p r, false otherwise.
19051bool
19053{
19054 bool result = true;
19055
19056 if (!(l.decl_base::operator==(r)))
19057 {
19058 result = false;
19059 if (k)
19061 else
19062 result = false;
19063 }
19064
19065 if (l.get_member_type() != r.get_member_type())
19066 {
19067 if (k)
19068 {
19069 if (!types_have_similar_structure(&l, &r))
19071 *k |= SUBTYPE_CHANGE_KIND;
19072 }
19073 result = false;
19074 }
19075
19077 {
19078 if (k)
19079 {
19080 if (!types_have_similar_structure(&l, &r))
19082 *k |= SUBTYPE_CHANGE_KIND;
19083 }
19084 result = false;
19085 }
19086
19087 ABG_RETURN(result);
19088}
19089
19090// </ptr_to_mbr_type definitions>
19091
19092// <array_type_def definitions>
19093
19094// <array_type_def::subrange_type>
19095array_type_def::subrange_type::~subrange_type() = default;
19096
19097// <array_type_def::subrante_type::bound_value>
19098
19099/// Default constructor of the @ref
19100/// array_type_def::subrange_type::bound_value class.
19101///
19102/// Constructs an unsigned bound_value of value zero.
19104 : s_(UNSIGNED_SIGNEDNESS)
19105{
19106 v_.unsigned_ = 0;
19107}
19108
19109/// Initialize an unsigned bound_value with a given value.
19110///
19111/// @param v the initial bound value.
19113 : s_(UNSIGNED_SIGNEDNESS)
19114{
19115 v_.unsigned_ = v;
19116}
19117
19118/// Initialize a signed bound_value with a given value.
19119///
19120/// @param v the initial bound value.
19122 : s_(SIGNED_SIGNEDNESS)
19123{
19124 v_.signed_ = v;
19125}
19126
19127/// Getter of the signedness (unsigned VS signed) of the bound value.
19128///
19129/// @return the signedness of the bound value.
19130enum array_type_def::subrange_type::bound_value::signedness
19132{return s_;}
19133
19134/// Setter of the signedness (unsigned VS signed) of the bound value.
19135///
19136/// @param s the new signedness of the bound value.
19137void
19139{ s_ = s;}
19140
19141/// Getter of the bound value as a signed value.
19142///
19143/// @return the bound value as signed.
19144int64_t
19146{return v_.signed_;
19147}
19148
19149/// Getter of the bound value as an unsigned value.
19150///
19151/// @return the bound value as unsigned.
19152uint64_t
19154{return v_.unsigned_;}
19155
19156/// Setter of the bound value as unsigned.
19157///
19158/// @param v the new unsigned value.
19159void
19161{
19162 s_ = UNSIGNED_SIGNEDNESS;
19163 v_.unsigned_ = v;
19164}
19165
19166/// Setter of the bound value as signed.
19167///
19168/// @param v the new signed value.
19169void
19171{
19172 s_ = SIGNED_SIGNEDNESS;
19173 v_.signed_ = v;
19174}
19175
19176/// Equality operator of the bound value.
19177///
19178/// @param v the other bound value to compare with.
19179///
19180/// @return true iff the current bound value equals @p v.
19181bool
19183{
19184 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
19185}
19186
19187// </array_type_def::subrante_type::bound_value>
19188
19189struct array_type_def::subrange_type::priv
19190{
19191 bound_value lower_bound_;
19192 bound_value upper_bound_;
19193 type_base_wptr underlying_type_;
19195 bool infinite_;
19196
19197 priv(bound_value ub,
19198 translation_unit::language l = translation_unit::LANG_C11)
19199 : upper_bound_(ub), language_(l), infinite_(false)
19200 {}
19201
19202 priv(bound_value lb, bound_value ub,
19203 translation_unit::language l = translation_unit::LANG_C11)
19204 : lower_bound_(lb), upper_bound_(ub),
19205 language_(l), infinite_(false)
19206 {}
19207
19208 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
19209 translation_unit::language l = translation_unit::LANG_C11)
19210 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
19211 language_(l), infinite_(false)
19212 {}
19213};
19214
19215/// Constructor of an array_type_def::subrange_type type.
19216///
19217/// @param env the environment this type was created from.
19218///
19219/// @param name the name of the subrange type.
19220///
19221/// @param lower_bound the lower bound of the array. This is
19222/// generally zero (at least for C and C++).
19223///
19224/// @param upper_bound the upper bound of the array.
19225///
19226/// @param underlying_type the underlying type of the subrange type.
19227///
19228/// @param loc the source location where the type is defined.
19229array_type_def::subrange_type::subrange_type(const environment& env,
19230 const string& name,
19231 bound_value lower_bound,
19232 bound_value upper_bound,
19233 const type_base_sptr& utype,
19234 const location& loc,
19236 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19237 type_base(env,
19238 utype
19239 ? utype->get_size_in_bits()
19240 : 0,
19241 0),
19242 decl_base(env, name, loc, ""),
19243 priv_(new priv(lower_bound, upper_bound, utype, l))
19244{
19246}
19247
19248/// Constructor of the array_type_def::subrange_type type.
19249///
19250/// @param env the environment this type is being created in.
19251///
19252/// @param name the name of the subrange type.
19253///
19254/// @param lower_bound the lower bound of the array. This is
19255/// generally zero (at least for C and C++).
19256///
19257/// @param upper_bound the upper bound of the array.
19258///
19259/// @param loc the source location where the type is defined.
19260///
19261/// @param l the language that generated this subrange.
19262array_type_def::subrange_type::subrange_type(const environment& env,
19263 const string& name,
19264 bound_value lower_bound,
19265 bound_value upper_bound,
19266 const location& loc,
19268 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19269 type_base(env, /*size-in-bits=*/0, /*alignment=*/0),
19270 decl_base(env, name, loc, ""),
19271 priv_(new priv(lower_bound, upper_bound, l))
19272{
19274}
19275
19276/// Constructor of the array_type_def::subrange_type type.
19277///
19278/// @param env the environment this type is being created from.
19279///
19280/// @param name of the name of type.
19281///
19282/// @param upper_bound the upper bound of the array. The lower bound
19283/// is considered to be zero.
19284///
19285/// @param loc the source location of the type.
19286///
19287/// @param the language that generated this type.
19288array_type_def::subrange_type::subrange_type(const environment& env,
19289 const string& name,
19290 bound_value upper_bound,
19291 const location& loc,
19293 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19294 type_base(env, upper_bound.get_unsigned_value(), 0),
19295 decl_base(env, name, loc, ""),
19296 priv_(new priv(upper_bound, l))
19297{
19299}
19300
19301/// Return the hash value of the current IR node.
19302///
19303/// Note that upon the first invocation, this member functions
19304/// computes the hash value and returns it. Subsequent invocations
19305/// just return the hash value that was previously calculated.
19306///
19307/// @return the hash value of the current IR node.
19308hash_t
19310{
19312 return h;
19313}
19314
19315/// Getter of the underlying type of the subrange, that is, the type
19316/// that defines the range.
19317///
19318/// @return the underlying type.
19319type_base_sptr
19321{return priv_->underlying_type_.lock();}
19322
19323/// Setter of the underlying type of the subrange, that is, the type
19324/// that defines the range.
19325///
19326/// @param u the new underlying type.
19327void
19329{
19330 ABG_ASSERT(priv_->underlying_type_.expired());
19331 priv_->underlying_type_ = u;
19332 if (u)
19333 set_size_in_bits(u->get_size_in_bits());
19334}
19335
19336/// Getter of the upper bound of the subrange type.
19337///
19338/// @return the upper bound of the subrange type.
19339int64_t
19341{return priv_->upper_bound_.get_signed_value();}
19342
19343/// Getter of the lower bound of the subrange type.
19344///
19345/// @return the lower bound of the subrange type.
19346int64_t
19348{return priv_->lower_bound_.get_signed_value();}
19349
19350/// Setter of the upper bound of the subrange type.
19351///
19352/// @param ub the new value of the upper bound.
19353void
19355{priv_->upper_bound_ = ub;}
19356
19357/// Setter of the lower bound.
19358///
19359/// @param lb the new value of the lower bound.
19360void
19362{priv_->lower_bound_ = lb;}
19363
19364/// Getter of the length of the subrange type.
19365///
19366/// Note that a length of zero means the array has an infinite (or
19367/// rather a non-known) size.
19368///
19369/// @return the length of the subrange type.
19370uint64_t
19372{
19373 if (is_non_finite())
19374 return 0;
19375
19376 // A subrange can have an upper bound that is lower than its lower
19377 // bound. This is possible in Ada for instance. In that case, the
19378 // length of the subrange is considered to be zero.
19379 if (get_upper_bound() >= get_lower_bound())
19380 return get_upper_bound() - get_lower_bound() + 1;
19381 return 0;
19382}
19383
19384/// Test if the length of the subrange type is infinite.
19385///
19386/// @return true iff the length of the subrange type is infinite.
19387bool
19389{return priv_->infinite_;}
19390
19391/// Set the infinite-ness status of the subrange type.
19392///
19393/// @param f true iff the length of the subrange type should be set to
19394/// being infinite.
19395void
19397{priv_->infinite_ = f;}
19398
19399/// Getter of the language that generated this type.
19400///
19401/// @return the language of this type.
19404{return priv_->language_;}
19405
19406/// Return a string representation of the sub range.
19407///
19408/// @return the string representation of the sub range.
19409string
19411{
19412 std::ostringstream o;
19413
19415 {
19416 type_base_sptr underlying_type = get_underlying_type();
19417 if (underlying_type)
19418 o << ir::get_pretty_representation(underlying_type, false) << " ";
19419 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
19420 }
19421 else if (is_non_finite())
19422 o << "[]";
19423 else
19424 o << "[" << get_length() << "]";
19425
19426 return o.str();
19427}
19428
19429/// Return a string representation of a vector of subranges
19430///
19431/// @return the string representation of a vector of sub ranges.
19432string
19434{
19435 if (v.empty())
19436 return "[]";
19437
19438 string r;
19439 for (vector<subrange_sptr>::const_iterator i = v.begin();
19440 i != v.end();
19441 ++i)
19442 r += (*i)->as_string();
19443
19444 return r;
19445}
19446
19447/// Compares two isntances of @ref array_type_def::subrange_type.
19448///
19449/// If the two intances are different, set a bitfield to give some
19450/// insight about the kind of differences there are.
19451///
19452/// @param l the first artifact of the comparison.
19453///
19454/// @param r the second artifact of the comparison.
19455///
19456/// @param k a pointer to a bitfield that gives information about the
19457/// kind of changes there are between @p l and @p r. This one is set
19458/// iff @p k is non-null and the function returns false.
19459///
19460/// Please note that setting k to a non-null value does have a
19461/// negative performance impact because even if @p l and @p r are not
19462/// equal, the function keeps up the comparison in order to determine
19463/// the different kinds of ways in which they are different.
19464///
19465/// @return true if @p l equals @p r, false otherwise.
19466bool
19469 change_kind* k)
19470{
19471 bool result = true;
19472
19473 if (l.get_lower_bound() != r.get_lower_bound()
19474 || l.get_upper_bound() != r.get_upper_bound()
19475 || l.get_name() != r.get_name())
19476 {
19477 result = false;
19478 if (k)
19480 else
19481 ABG_RETURN(result);
19482 }
19483
19484 if (l.get_underlying_type()
19485 && r.get_underlying_type()
19486 && (*l.get_underlying_type() != *r.get_underlying_type()))
19487 {
19488 result = false;
19489 if (k)
19490 *k |= SUBTYPE_CHANGE_KIND;
19491 else
19492 ABG_RETURN(result);
19493 }
19494
19495 ABG_RETURN(result);
19496}
19497
19498/// Equality operator.
19499///
19500/// @param o the other subrange to test against.
19501///
19502/// @return true iff @p o equals the current instance of
19503/// array_type_def::subrange_type.
19504bool
19506{
19507 const subrange_type* other =
19508 dynamic_cast<const subrange_type*>(&o);
19509 if (!other)
19510 return false;
19511 return try_canonical_compare(this, other);
19512}
19513
19514/// Equality operator.
19515///
19516/// @param o the other subrange to test against.
19517///
19518/// @return true iff @p o equals the current instance of
19519/// array_type_def::subrange_type.
19520bool
19522{
19523 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19524 if (!other)
19525 return false;
19526 return *this == *other;
19527}
19528
19529/// Equality operator.
19530///
19531/// @param o the other subrange to test against.
19532///
19533/// @return true iff @p o equals the current instance of
19534/// array_type_def::subrange_type.
19535bool
19537{
19538 const type_base &t = o;
19539 return operator==(t);
19540}
19541
19542/// Equality operator.
19543///
19544/// @param o the other subrange to test against.
19545///
19546/// @return true iff @p o equals the current instance of
19547/// array_type_def::subrange_type.
19548bool
19550{return !operator==(o);}
19551
19552/// Equality operator.
19553///
19554/// @param o the other subrange to test against.
19555///
19556/// @return true iff @p o equals the current instance of
19557/// array_type_def::subrange_type.
19558bool
19560{return !operator==(o);}
19561
19562/// Inequality operator.
19563///
19564/// @param o the other subrange to test against.
19565///
19566/// @return true iff @p o is different from the current instance of
19567/// array_type_def::subrange_type.
19568bool
19570{return !operator==(o);}
19571
19572/// Build a pretty representation for an
19573/// array_type_def::subrange_type.
19574///
19575/// @param internal set to true if the call is intended to get a
19576/// representation of the decl (or type) for the purpose of canonical
19577/// type comparison. This is mainly used in the function
19578/// type_base::get_canonical_type_for().
19579///
19580/// In other words if the argument for this parameter is true then the
19581/// call is meant for internal use (for technical use inside the
19582/// library itself), false otherwise. If you don't know what this is
19583/// for, then set it to false.
19584///
19585/// @return a copy of the pretty representation of the current
19586/// instance of typedef_decl.
19587string
19589{
19590 string name = get_name();
19591 string repr;
19592
19593 if (name.empty())
19594 repr += "<anonymous range>";
19595 else
19596 repr += "<range " + get_name() + ">";
19597 repr += as_string();
19598
19599 return repr;
19600}
19601
19602/// This implements the ir_traversable_base::traverse pure virtual
19603/// function.
19604///
19605/// @param v the visitor used on the current instance.
19606///
19607/// @return true if the entire IR node tree got traversed, false
19608/// otherwise.
19609bool
19611{
19612 if (v.type_node_has_been_visited(this))
19613 return true;
19614
19615 if (v.visit_begin(this))
19616 {
19617 visiting(true);
19618 if (type_base_sptr u = get_underlying_type())
19619 u->traverse(v);
19620 visiting(false);
19621 }
19622
19623 bool result = v.visit_end(this);
19625 return result;
19626}
19627
19628// </array_type_def::subrange_type>
19629
19630struct array_type_def::priv
19631{
19632 type_base_wptr element_type_;
19633 subranges_type subranges_;
19634 interned_string temp_internal_qualified_name_;
19635 interned_string internal_qualified_name_;
19636
19637 priv(type_base_sptr t)
19638 : element_type_(t)
19639 {}
19640
19641 priv(type_base_sptr t, subranges_type subs)
19642 : element_type_(t), subranges_(subs)
19643 {}
19644
19645 priv()
19646 {}
19647};
19648
19649/// Constructor for the type array_type_def
19650///
19651/// Note how the constructor expects a vector of subrange
19652/// objects. Parsing of the array information always entails
19653/// parsing the subrange info as well, thus the class subrange_type
19654/// is defined inside class array_type_def and also parsed
19655/// simultaneously.
19656///
19657/// @param e_type the type of the elements contained in the array
19658///
19659/// @param subs a vector of the array's subranges(dimensions)
19660///
19661/// @param locus the source location of the array type definition.
19662array_type_def::array_type_def(const type_base_sptr e_type,
19663 const std::vector<subrange_sptr>& subs,
19664 const location& locus)
19666 ARRAY_TYPE
19667 | ABSTRACT_TYPE_BASE
19668 | ABSTRACT_DECL_BASE),
19669 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
19670 decl_base(e_type->get_environment(), locus),
19671 priv_(new priv(e_type))
19672{
19674 append_subranges(subs);
19675}
19676
19677/// Constructor for the type array_type_def
19678///
19679/// This constructor builds a temporary array that has no element type
19680/// associated. Later when the element type is available, it be set
19681/// with the array_type_def::set_element_type() member function.
19682///
19683/// Note how the constructor expects a vector of subrange
19684/// objects. Parsing of the array information always entails
19685/// parsing the subrange info as well, thus the class subrange_type
19686/// is defined inside class array_type_def and also parsed
19687/// simultaneously.
19688///
19689/// @param env the environment of the array type.
19690///
19691/// @param subs a vector of the array's subranges(dimensions)
19692///
19693/// @param locus the source location of the array type definition.
19694array_type_def::array_type_def(const environment& env,
19695 const std::vector<subrange_sptr>& subs,
19696 const location& locus)
19697 : type_or_decl_base(env,
19698 ARRAY_TYPE
19699 | ABSTRACT_TYPE_BASE
19700 | ABSTRACT_DECL_BASE),
19701 type_base(env, 0, 0),
19702 decl_base(env, locus),
19703 priv_(new priv)
19704{
19706 append_subranges(subs);
19707}
19708
19709/// Return the hash value of the current IR node.
19710///
19711/// Note that upon the first invocation, this member functions
19712/// computes the hash value and returns it. Subsequent invocations
19713/// just return the hash value that was previously calculated.
19714///
19715/// @return the hash value of the current IR node.
19716hash_t
19718{
19720 return h;
19721}
19722
19723/// Update the size of the array.
19724///
19725/// This function computes the size of the array and sets it using
19726/// type_base::set_size_in_bits().
19727void
19728array_type_def::update_size()
19729{
19730 type_base_sptr e = priv_->element_type_.lock();
19731 if (e)
19732 {
19733 size_t s = e->get_size_in_bits();
19734 if (s)
19735 {
19736 for (const auto &sub : get_subranges())
19737 s *= sub->get_length();
19739 }
19740 set_alignment_in_bits(e->get_alignment_in_bits());
19741 }
19742}
19743
19744string
19745array_type_def::get_subrange_representation() const
19746{
19748 return r;
19749}
19750
19751/// Get the pretty representation of the current instance of @ref
19752/// array_type_def.
19753///
19754/// @param internal set to true if the call is intended to get a
19755/// representation of the decl (or type) for the purpose of canonical
19756/// type comparison. This is mainly used in the function
19757/// type_base::get_canonical_type_for().
19758///
19759/// In other words if the argument for this parameter is true then the
19760/// call is meant for internal use (for technical use inside the
19761/// library itself), false otherwise. If you don't know what this is
19762/// for, then set it to false.
19763/// @param internal set to true if the call is intended for an
19764/// internal use (for technical use inside the library itself), false
19765/// otherwise. If you don't know what this is for, then set it to
19766/// false.
19767///
19768/// @return the pretty representation of the ABI artifact.
19769string
19771 bool qualified_name) const
19772{
19773 return array_declaration_name(this, /*variable_name=*/"",
19774 qualified_name, internal);
19775}
19776
19777/// Compares two instances of @ref array_type_def.
19778///
19779/// If the two intances are different, set a bitfield to give some
19780/// insight about the kind of differences there are.
19781///
19782/// @param l the first artifact of the comparison.
19783///
19784/// @param r the second artifact of the comparison.
19785///
19786/// @param k a pointer to a bitfield that gives information about the
19787/// kind of changes there are between @p l and @p r. This one is set
19788/// iff @p k is non-null and the function returns false.
19789///
19790/// Please note that setting k to a non-null value does have a
19791/// negative performance impact because even if @p l and @p r are not
19792/// equal, the function keeps up the comparison in order to determine
19793/// the different kinds of ways in which they are different.
19794///
19795/// @return true if @p l equals @p r, false otherwise.
19796bool
19798{
19799 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
19800 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
19801
19802 bool result = true;
19803 if (this_subs.size() != other_subs.size())
19804 {
19805 result = false;
19806 if (k)
19808 else
19810 }
19811
19812 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19813 for (i = this_subs.begin(), j = other_subs.begin();
19814 i != this_subs.end() && j != other_subs.end();
19815 ++i, ++j)
19816 if (**i != **j)
19817 {
19818 result = false;
19819 if (k)
19820 {
19822 break;
19823 }
19824 else
19826 }
19827
19828 // Compare the element types modulo the typedefs they might have
19829 if (l.get_element_type() != r.get_element_type())
19830 {
19831 result = false;
19832 if (k)
19833 *k |= SUBTYPE_CHANGE_KIND;
19834 else
19836 }
19837
19838 ABG_RETURN(result);
19839}
19840
19841/// Test if two array types are equals modulo CV qualifiers.
19842///
19843/// @param l the first array of the comparison.
19844///
19845/// @param r the second array of the comparison.
19846///
19847/// @return true iff @p l equals @p r or, if they are different, the
19848/// difference between the too is just a matter of CV qualifiers.
19849bool
19851{
19852 if (l == r)
19853 return true;
19854
19855 if (!l || !r)
19857
19860
19861 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
19862 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
19863
19864 if (this_subs.size() != other_subs.size())
19866
19867 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19868 for (i = this_subs.begin(), j = other_subs.begin();
19869 i != this_subs.end() && j != other_subs.end();
19870 ++i, ++j)
19871 if (**i != **j)
19873
19874 type_base *first_element_type =
19876 type_base *second_element_type =
19878
19879 if (*first_element_type != *second_element_type)
19881
19882 return true;
19883}
19884
19885/// Test if two array types are equals modulo CV qualifiers.
19886///
19887/// @param l the first array of the comparison.
19888///
19889/// @param r the second array of the comparison.
19890///
19891/// @return true iff @p l equals @p r or, if they are different, the
19892/// difference between the too is just a matter of CV qualifiers.
19893bool
19895 const array_type_def_sptr& r)
19896{return equals_modulo_cv_qualifier(l.get(), r.get());}
19897
19898/// Test if two pointer types are equals modulo CV qualifiers.
19899///
19900/// @param l the first pointer of the comparison.
19901///
19902/// @param r the second pointer of the comparison.
19903///
19904/// @return true iff @p l equals @p r or, if they are different, the
19905/// difference between the too is just a matter of CV qualifiers.
19906bool
19908{
19909 if (l == r)
19910 return true;
19911
19912 if (!l || !r)
19914
19915 type_base_sptr l_ptt = l->get_pointed_to_type(),
19916 r_ptt = r->get_pointed_to_type();
19917
19918 do
19919 {
19920 l_ptt = peel_qualified_or_typedef_type(l_ptt);
19921 r_ptt = peel_qualified_or_typedef_type(r_ptt);
19922
19923 l_ptt = is_pointer_type(l_ptt)
19925 : l_ptt;
19926
19927 r_ptt = is_pointer_type(r_ptt)
19929 : r_ptt;
19930 } while (is_pointer_type(l_ptt) && is_pointer_type(r_ptt));
19931
19932 l_ptt = peel_qualified_or_typedef_type(l_ptt);
19933 r_ptt = peel_qualified_or_typedef_type(r_ptt);
19934
19935 return *l_ptt == *r_ptt;
19936}
19937
19938/// Test if two pointer types are equals modulo CV qualifiers.
19939///
19940/// @param l the first pointer of the comparison.
19941///
19942/// @param r the second pointer of the comparison.
19943///
19944/// @return true iff @p l equals @p r or, if they are different, the
19945/// difference between the too is just a matter of CV qualifiers.
19946bool
19948 const pointer_type_def_sptr& r)
19949{return equals_modulo_cv_qualifier(l.get(), r.get());}
19950
19951/// Get the language of the array.
19952///
19953/// @return the language of the array.
19956{
19957 const std::vector<subrange_sptr>& subranges =
19958 get_subranges();
19959
19960 if (subranges.empty())
19961 return translation_unit::LANG_C11;
19962 return subranges.front()->get_language();
19963}
19964
19965bool
19967{
19968 const array_type_def* other =
19969 dynamic_cast<const array_type_def*>(&o);
19970 if (!other)
19971 return false;
19972 return try_canonical_compare(this, other);
19973}
19974
19975bool
19977{
19978 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19979 if (!other)
19980 return false;
19981 return *this == *other;
19982}
19983
19984/// Getter of the type of an array element.
19985///
19986/// @return the type of an array element.
19987const type_base_sptr
19989{return priv_->element_type_.lock();}
19990
19991/// Setter of the type of array element.
19992///
19993/// Beware that after using this function, one might want to
19994/// re-compute the canonical type of the array, if one has already
19995/// been computed.
19996///
19997/// The intended use of this method is to permit in-place adjustment
19998/// of the element type's qualifiers. In particular, the size of the
19999/// element type should not be changed.
20000///
20001/// @param element_type the new element type to set.
20002void
20003array_type_def::set_element_type(const type_base_sptr& element_type)
20004{
20005 priv_->element_type_ = element_type;
20006 update_size();
20008}
20009
20010/// Append subranges from the vector @param subs to the current
20011/// vector of subranges.
20012void
20013array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
20014{
20015
20016 for (const auto &sub : subs)
20017 priv_->subranges_.push_back(sub);
20018
20019 update_size();
20021}
20022
20023/// @return true if one of the sub-ranges of the array is infinite, or
20024/// if the array has no sub-range at all, also meaning that the size
20025/// of the array is infinite.
20026bool
20028{
20029 if (priv_->subranges_.empty())
20030 return true;
20031
20032 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
20033 priv_->subranges_.begin();
20034 i != priv_->subranges_.end();
20035 ++i)
20036 if ((*i)->is_non_finite())
20037 return true;
20038
20039 return false;
20040}
20041
20042int
20043array_type_def::get_dimension_count() const
20044{return priv_->subranges_.size();}
20045
20046/// Build and return the qualified name of the current instance of the
20047/// @ref array_type_def.
20048///
20049/// @param qn output parameter. Is set to the newly-built qualified
20050/// name of the current instance of @ref array_type_def.
20051///
20052/// @param internal set to true if the call is intended for an
20053/// internal use (for technical use inside the library itself), false
20054/// otherwise. If you don't know what this is for, then set it to
20055/// false.
20056void
20058{qn = get_qualified_name(internal);}
20059
20060/// Compute the qualified name of the array.
20061///
20062/// @param internal set to true if the call is intended for an
20063/// internal use (for technical use inside the library itself), false
20064/// otherwise. If you don't know what this is for, then set it to
20065/// false.
20066///
20067/// @return the resulting qualified name.
20068const interned_string&
20070{
20071 if (internal)
20072 {
20073 if (get_canonical_type())
20074 {
20075 if (priv_->internal_qualified_name_.empty())
20076 priv_->internal_qualified_name_ =
20077 array_declaration_name(this, /*variable_name=*/"",
20078 /*qualified=*/false,
20079 /*internal=*/true);
20080 return priv_->internal_qualified_name_;
20081 }
20082 else
20083 {
20084 priv_->temp_internal_qualified_name_ =
20085 array_declaration_name(this, /*variable_name=*/"",
20086 /*qualified*/false, /*internal*/true);
20087 return priv_->temp_internal_qualified_name_;
20088 }
20089 }
20090 else
20091 {
20092 if (get_canonical_type())
20093 {
20094 if (decl_base::peek_qualified_name().empty())
20095 set_qualified_name(array_declaration_name(this,
20096 /*variable_name=*/"",
20097 /*qualified=*/false,
20098 /*internal=*/false));
20100 }
20101 else
20102 {
20104 (array_declaration_name(this, /*variable_name=*/"",
20105 /*qualified=*/false,
20106 /*internal=*/false));
20108 }
20109 }
20110}
20111
20112/// This implements the ir_traversable_base::traverse pure virtual
20113/// function.
20114///
20115/// @param v the visitor used on the current instance.
20116///
20117/// @return true if the entire IR node tree got traversed, false
20118/// otherwise.
20119bool
20121{
20122 if (v.type_node_has_been_visited(this))
20123 return true;
20124
20125 if (visiting())
20126 return true;
20127
20128 if (v.visit_begin(this))
20129 {
20130 visiting(true);
20131 if (type_base_sptr t = get_element_type())
20132 t->traverse(v);
20133 visiting(false);
20134 }
20135
20136 bool result = v.visit_end(this);
20138 return result;
20139}
20140
20141const location&
20142array_type_def::get_location() const
20143{return decl_base::get_location();}
20144
20145/// Get the array's subranges
20146const std::vector<array_type_def::subrange_sptr>&
20148{return priv_->subranges_;}
20149
20150array_type_def::~array_type_def()
20151{}
20152
20153// </array_type_def definitions>
20154
20155// <enum_type_decl definitions>
20156
20157class enum_type_decl::priv
20158{
20159 type_base_sptr underlying_type_;
20160 enumerators enumerators_;
20161 mutable enumerators sorted_enumerators_;
20162
20163 friend class enum_type_decl;
20164
20165 priv();
20166
20167public:
20168 priv(type_base_sptr underlying_type,
20170 : underlying_type_(underlying_type),
20171 enumerators_(enumerators)
20172 {}
20173}; // end class enum_type_decl::priv
20174
20175/// Constructor.
20176///
20177/// @param name the name of the type declaration.
20178///
20179/// @param locus the source location where the type was defined.
20180///
20181/// @param underlying_type the underlying type of the enum.
20182///
20183/// @param enums the enumerators of this enum type.
20184///
20185/// @param linkage_name the linkage name of the enum.
20186///
20187/// @param vis the visibility of the enum type.
20188enum_type_decl::enum_type_decl(const string& name,
20189 const location& locus,
20190 type_base_sptr underlying_type,
20191 enumerators& enums,
20192 const string& linkage_name,
20193 visibility vis)
20194 : type_or_decl_base(underlying_type->get_environment(),
20195 ENUM_TYPE
20196 | ABSTRACT_TYPE_BASE
20197 | ABSTRACT_DECL_BASE),
20198 type_base(underlying_type->get_environment(),
20199 underlying_type->get_size_in_bits(),
20200 underlying_type->get_alignment_in_bits()),
20201 decl_base(underlying_type->get_environment(),
20202 name, locus, linkage_name, vis),
20203 priv_(new priv(underlying_type, enums))
20204{
20206 for (enumerators::iterator e = get_enumerators().begin();
20207 e != get_enumerators().end();
20208 ++e)
20209 e->set_enum_type(this);
20210}
20211
20212/// Return the hash value of the current IR node.
20213///
20214/// Note that upon the first invocation, this member functions
20215/// computes the hash value and returns it. Subsequent invocations
20216/// just return the hash value that was previously calculated.
20217///
20218/// @return the hash value of the current IR node.
20219hash_t
20221{
20223 return h;
20224}
20225
20226/// Return the underlying type of the enum.
20227type_base_sptr
20229{return priv_->underlying_type_;}
20230
20231/// @return the list of enumerators of the enum.
20234{return priv_->enumerators_;}
20235
20236/// @return the list of enumerators of the enum.
20239{return priv_->enumerators_;}
20240
20241/// Get the lexicographically sorted vector of enumerators.
20242///
20243/// @return the lexicographically sorted vector of enumerators.
20246{
20247 if (priv_->sorted_enumerators_.empty())
20248 {
20249 for (auto e = get_enumerators().rbegin();
20250 e != get_enumerators().rend();
20251 ++e)
20252 priv_->sorted_enumerators_.push_back(*e);
20253
20254 std::sort(priv_->sorted_enumerators_.begin(),
20255 priv_->sorted_enumerators_.end(),
20256 [](const enum_type_decl::enumerator& l,
20258 {
20259 if (l.get_name() == r.get_name())
20260 return l.get_value() < r.get_value();
20261 return (l.get_name() < r.get_name());
20262 });
20263 }
20264
20265 return priv_->sorted_enumerators_;
20266}
20267
20268/// Find an enumerator by its value.
20269///
20270/// @param value the enumerator value to look for.
20271///
20272/// @param result output parameter. This is set to the enumerator
20273/// which value is @p value, if found. This is set iff the function
20274/// returns true.
20275///
20276/// @return true iff an enumerator with value @p value was found and
20277/// returned by argument via @p result.
20278bool
20281{
20282 for (auto& e : get_enumerators())
20283 if (e.get_value() == value)
20284 {
20285 result = e;
20286 return true;
20287 }
20288
20289 return false;
20290}
20291
20292/// Find an enumerator by its name
20293///
20294/// @param name the enumerator name to look for.
20295///
20296/// @param result output parameter. This is set to the enumerator
20297/// which name is @p name, if found. This is set iff the function
20298/// returns true.
20299///
20300/// @return true iff an enumerator with name @p name was found and
20301/// returned by argument via @p result.
20302bool
20305{
20306 for (auto& e : get_enumerators())
20307 if (e.get_name() == name)
20308 {
20309 result = e;
20310 return true;
20311 }
20312
20313 return false;
20314}
20315
20316/// Get the pretty representation of the current instance of @ref
20317/// enum_type_decl.
20318///
20319/// @param internal set to true if the call is intended to get a
20320/// representation of the decl (or type) for the purpose of canonical
20321/// type comparison. This is mainly used in the function
20322/// type_base::get_canonical_type_for().
20323///
20324/// In other words if the argument for this parameter is true then the
20325/// call is meant for internal use (for technical use inside the
20326/// library itself), false otherwise. If you don't know what this is
20327/// for, then set it to false.
20328///
20329/// @param qualified_name if true, names emitted in the pretty
20330/// representation are fully qualified.
20331///
20332/// @return the pretty representation of the enum type.
20333string
20335 bool qualified_name) const
20336{
20337 string r = "enum ";
20338
20339 if (internal && get_is_anonymous())
20340 r += get_type_name(this, qualified_name, /*internal=*/true);
20341 else if (get_is_anonymous())
20342 r += get_enum_flat_representation(*this, "",
20343 /*one_line=*/true,
20344 qualified_name);
20345 else
20347 qualified_name);
20348 return r;
20349}
20350
20351/// This implements the ir_traversable_base::traverse pure virtual
20352/// function.
20353///
20354/// @param v the visitor used on the current instance.
20355///
20356/// @return true if the entire IR node tree got traversed, false
20357/// otherwise.
20358bool
20360{
20361 if (v.type_node_has_been_visited(this))
20362 return true;
20363
20364 if (visiting())
20365 return true;
20366
20367 if (v.visit_begin(this))
20368 {
20369 visiting(true);
20370 if (type_base_sptr t = get_underlying_type())
20371 t->traverse(v);
20372 visiting(false);
20373 }
20374
20375 bool result = v.visit_end(this);
20377 return result;
20378}
20379
20380/// Destructor for the enum type declaration.
20382{}
20383
20384/// Test if two enums differ, but not by a name change.
20385///
20386/// @param l the first enum to consider.
20387///
20388/// @param r the second enum to consider.
20389///
20390/// @return true iff @p l differs from @p r by anything but a name
20391/// change.
20392bool
20394 const enum_type_decl& r,
20395 change_kind* k)
20396{
20397 bool result = false;
20399 {
20400 result = true;
20401 if (k)
20402 *k |= SUBTYPE_CHANGE_KIND;
20403 else
20404 return true;
20405 }
20406
20407 enum_type_decl::enumerators::const_iterator i, j;
20408 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
20409 i != l.get_enumerators().end() && j != r.get_enumerators().end();
20410 ++i, ++j)
20411 if (*i != *j)
20412 {
20413 result = true;
20414 if (k)
20415 {
20417 break;
20418 }
20419 else
20420 return true;
20421 }
20422
20423 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
20424 {
20425 result = true;
20426 if (k)
20428 else
20429 return true;
20430 }
20431
20432 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
20435 string n_l = l.get_name();
20436 string n_r = r.get_name();
20437 local_r.set_qualified_name(qn_l);
20438 local_r.set_name(n_l);
20439
20440 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
20441 {
20442 result = true;
20443 if (k)
20444 {
20445 if (!l.decl_base::operator==(r))
20447 if (!l.type_base::operator==(r))
20449 }
20450 else
20451 {
20452 local_r.set_name(n_r);
20453 local_r.set_qualified_name(qn_r);
20454 return true;
20455 }
20456 }
20457 local_r.set_qualified_name(qn_r);
20458 local_r.set_name(n_r);
20459
20460 return result;
20461}
20462
20463/// Test if a given enumerator is found present in an enum.
20464///
20465/// This is a subroutine of the equals function for enums.
20466///
20467/// @param enr the enumerator to consider.
20468///
20469/// @param enom the enum to consider.
20470///
20471/// @return true iff the enumerator @p enr is present in the enum @p
20472/// enom.
20473bool
20475 const enum_type_decl &enom)
20476{
20477 for (const auto &e : enom.get_enumerators())
20478 if (e == enr)
20479 return true;
20480 return false;
20481}
20482
20483/// Check if two enumerators values are equal.
20484///
20485/// This function doesn't check if the names of the enumerators are
20486/// equal or not.
20487///
20488/// @param enr the first enumerator to consider.
20489///
20490/// @param enl the second enumerator to consider.
20491///
20492/// @return true iff @p enr has the same value as @p enl.
20493static bool
20494enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
20495 const enum_type_decl::enumerator &enl)
20496{return enr.get_value() == enl.get_value();}
20497
20498/// Detect if a given enumerator value is present in an enum.
20499///
20500/// This function looks inside the enumerators of a given enum and
20501/// detect if the enum contains at least one enumerator or a given
20502/// value. The function also detects if the enumerator value we are
20503/// looking at is present in the enum with a different name. An
20504/// enumerator with the same value but with a different name is named
20505/// a "redundant enumerator". The function returns the set of
20506/// enumerators that are redundant with the value we are looking at.
20507///
20508/// @param enr the enumerator to consider.
20509///
20510/// @param enom the enum to consider.
20511///
20512/// @param redundant_enrs if the function returns true, then this
20513/// vector is filled with enumerators that are redundant with the
20514/// value of @p enr.
20515///
20516/// @return true iff the function detects that @p enom contains
20517/// enumerators with the same value as @p enr.
20518static bool
20519is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
20520 const enum_type_decl &enom,
20521 vector<enum_type_decl::enumerator>& redundant_enrs)
20522{
20523 bool found = false;
20524 for (const auto &e : enom.get_enumerators())
20525 if (enumerators_values_are_equal(e, enr))
20526 {
20527 found = true;
20528 if (e != enr)
20529 redundant_enrs.push_back(e);
20530 }
20531
20532 return found;
20533}
20534
20535/// Check if an enumerator value is redundant in a given enum.
20536///
20537/// Given an enumerator value, this function detects if an enum
20538/// contains at least one enumerator with the the same value but with
20539/// a different name.
20540///
20541/// @param enr the enumerator to consider.
20542///
20543/// @param enom the enum to consider.
20544///
20545/// @return true iff @p enr is a redundant enumerator in enom.
20546static bool
20547is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
20548 const enum_type_decl &enom)
20549{
20550 vector<enum_type_decl::enumerator> redundant_enrs;
20551 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
20552 {
20553 if (!redundant_enrs.empty())
20554 return true;
20555 }
20556 return false;
20557}
20558
20559/// Compares two instances of @ref enum_type_decl.
20560///
20561/// If the two intances are different, set a bitfield to give some
20562/// insight about the kind of differences there are.
20563///
20564/// @param l the first artifact of the comparison.
20565///
20566/// @param r the second artifact of the comparison.
20567///
20568/// @param k a pointer to a bitfield that gives information about the
20569/// kind of changes there are between @p l and @p r. This one is set
20570/// iff @p k is non-null and the function returns false.
20571///
20572/// Please note that setting k to a non-null value does have a
20573/// negative performance impact because even if @p l and @p r are not
20574/// equal, the function keeps up the comparison in order to determine
20575/// the different kinds of ways in which they are different.
20576///
20577/// @return true if @p l equals @p r, false otherwise.
20578bool
20580{
20581 bool result = true;
20582
20583 //
20584 // Look through decl-only-enum.
20585 //
20586
20587 const enum_type_decl *def1 =
20590 : &l;
20591
20592 const enum_type_decl *def2 =
20595 : &r;
20596
20597 if (!!def1 != !!def2)
20598 {
20599 // One enum is decl-only while the other is not.
20600 // So the two enums are different.
20601 result = false;
20602 if (k)
20603 *k |= SUBTYPE_CHANGE_KIND;
20604 else
20606 }
20607
20608 //
20609 // At this point, both enums have the same state of decl-only-ness.
20610 // So we can compare oranges to oranges.
20611 //
20612
20613 if (!def1)
20614 def1 = &l;
20615 if (!def2)
20616 def2 = &r;
20617
20618 if (def1->get_underlying_type() != def2->get_underlying_type())
20619 {
20620 result = false;
20621 if (k)
20622 *k |= SUBTYPE_CHANGE_KIND;
20623 else
20625 }
20626
20627 if (!(def1->decl_base::operator==(*def2)
20628 && def1->type_base::operator==(*def2)))
20629 {
20630 result = false;
20631 if (k)
20632 {
20633 if (!def1->decl_base::operator==(*def2))
20635 if (!def1->type_base::operator==(*def2))
20637 }
20638 else
20640 }
20641
20642 // Now compare the enumerators.
20643
20644 // First in a naive (but potentially fast) way in case both enums
20645 // are equal in a naive manner.
20646
20647 if (def1->get_enumerators().size() == def2->get_enumerators().size())
20648 {
20649 bool equals = true;
20650 for (auto e1 = def1->get_enumerators().begin(),
20651 e2 = def2->get_enumerators().begin();
20652 (e1 != def1->get_enumerators().end()
20653 && e2 != def2->get_enumerators().end());
20654 ++e1, ++e2)
20655 {
20656 if (*e1 != *e2)
20657 {
20658 equals = false;
20659 break;
20660 }
20661 }
20662 if (equals)
20663 ABG_RETURN(result);
20664 }
20665
20666 // If the two enums where not naively equals, let's try a more
20667 // clever (and slow) way.
20668
20669 // Note that the order of declaration
20670 // of enumerators should not matter in the comparison.
20671 //
20672 // Also if an enumerator value is redundant, that shouldn't impact
20673 // the comparison.
20674 //
20675 // In that case, note that the two enums below are considered equal:
20676 //
20677 // enum foo
20678 // {
20679 // e0 = 0;
20680 // e1 = 1;
20681 // e2 = 2;
20682 // };
20683 //
20684 // enum foo
20685 // {
20686 // e0 = 0;
20687 // e1 = 1;
20688 // e2 = 2;
20689 // e_added = 1; // <-- this value is redundant with the value
20690 // // of the enumerator e1.
20691 // };
20692 //
20693 // Note however that in the case below, the enums are different.
20694 //
20695 // enum foo
20696 // {
20697 // e0 = 0;
20698 // e1 = 1;
20699 // };
20700 //
20701 // enum foo
20702 // {
20703 // e0 = 0;
20704 // e2 = 1; // <-- this enum value is present in the first version
20705 // // of foo, but is not redundant with any enumerator
20706 // // in the second version of of enum foo.
20707 // };
20708 //
20709 // These two enums are considered equal.
20710
20711 for(const auto &e : def1->get_enumerators())
20712 if (!is_enumerator_present_in_enum(e, *def2)
20713 && (!is_enumerator_value_redundant(e, *def2)
20714 || !is_enumerator_value_redundant(e, *def1)))
20715 {
20716 result = false;
20717 if (k)
20718 {
20720 break;
20721 }
20722 else
20724 }
20725
20726 for(const auto &e : def2->get_enumerators())
20727 if (!is_enumerator_present_in_enum(e, *def1)
20728 && (!is_enumerator_value_redundant(e, *def1)
20729 || !is_enumerator_value_redundant(e, *def2)))
20730 {
20731 result = false;
20732 if (k)
20733 {
20735 break;
20736 }
20737 else
20739 }
20740
20741 ABG_RETURN(result);
20742}
20743
20744/// Equality operator.
20745///
20746/// @param o the other enum to test against.
20747///
20748/// @return true iff @p o equals the current instance of enum type
20749/// decl.
20750bool
20752{
20753 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
20754 if (!op)
20755 return false;
20756 return try_canonical_compare(this, op);
20757}
20758
20759/// Equality operator.
20760///
20761/// @param o the other enum to test against.
20762///
20763/// @return true iff @p o is equals the current instance of enum type
20764/// decl.
20765bool
20767{
20768 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20769 if (!other)
20770 return false;
20771 return *this == *other;
20772}
20773
20774/// Equality operator for @ref enum_type_decl_sptr.
20775///
20776/// @param l the first operand to compare.
20777///
20778/// @param r the second operand to compare.
20779///
20780/// @return true iff @p l equals @p r.
20781bool
20783{
20784 if (!!l != !!r)
20785 return false;
20786 if (l.get() == r.get())
20787 return true;
20788 decl_base_sptr o = r;
20789 return *l == *o;
20790}
20791
20792/// Inequality operator for @ref enum_type_decl_sptr.
20793///
20794/// @param l the first operand to compare.
20795///
20796/// @param r the second operand to compare.
20797///
20798/// @return true iff @p l equals @p r.
20799bool
20801{return !operator==(l, r);}
20802
20803/// The type of the private data of an @ref
20804/// enum_type_decl::enumerator.
20805class enum_type_decl::enumerator::priv
20806{
20807 string name_;
20808 int64_t value_;
20809 string qualified_name_;
20810 enum_type_decl* enum_type_;
20811
20812 friend class enum_type_decl::enumerator;
20813
20814public:
20815
20816 priv()
20817 : enum_type_()
20818 {}
20819
20820 priv(const string& name,
20821 int64_t value,
20822 enum_type_decl* e = 0)
20823 : name_(name),
20824 value_(value),
20825 enum_type_(e)
20826 {}
20827}; // end class enum_type_def::enumerator::priv
20828
20829/// Default constructor of the @ref enum_type_decl::enumerator type.
20831 : priv_(new priv)
20832{}
20833
20834enum_type_decl::enumerator::~enumerator() = default;
20835
20836/// Constructor of the @ref enum_type_decl::enumerator type.
20837///
20838/// @param env the environment we are operating from.
20839///
20840/// @param name the name of the enumerator.
20841///
20842/// @param value the value of the enumerator.
20844 int64_t value)
20845 : priv_(new priv(name, value))
20846{}
20847
20848/// Copy constructor of the @ref enum_type_decl::enumerator type.
20849///
20850/// @param other enumerator to copy.
20852 : priv_(new priv(other.get_name(),
20853 other.get_value(),
20854 other.get_enum_type()))
20855{}
20856
20857/// Assignment operator of the @ref enum_type_decl::enumerator type.
20858///
20859/// @param o
20862{
20863 priv_->name_ = o.get_name();
20864 priv_->value_ = o.get_value();
20865 priv_->enum_type_ = o.get_enum_type();
20866 return *this;
20867}
20868
20869/// Equality operator
20870///
20871/// @param other the enumerator to compare to the current
20872/// instance of enum_type_decl::enumerator.
20873///
20874/// @return true if @p other equals the current instance of
20875/// enum_type_decl::enumerator.
20876bool
20878{
20879 bool names_equal = true;
20880 names_equal = (get_name() == other.get_name());
20881 return names_equal && (get_value() == other.get_value());
20882}
20883
20884/// Inequality operator.
20885///
20886/// @param other the other instance to compare against.
20887///
20888/// @return true iff @p other is different from the current instance.
20889bool
20891{return !operator==(other);}
20892
20893/// Getter for the name of the current instance of
20894/// enum_type_decl::enumerator.
20895///
20896/// @return a reference to the name of the current instance of
20897/// enum_type_decl::enumerator.
20898const string&
20900{return priv_->name_;}
20901
20902/// Getter for the qualified name of the current instance of
20903/// enum_type_decl::enumerator. The first invocation of the method
20904/// builds the qualified name, caches it and return a reference to the
20905/// cached qualified name. Subsequent invocations just return the
20906/// cached value.
20907///
20908/// @param internal set to true if the call is intended for an
20909/// internal use (for technical use inside the library itself), false
20910/// otherwise. If you don't know what this is for, then set it to
20911/// false.
20912///
20913/// @return the qualified name of the current instance of
20914/// enum_type_decl::enumerator.
20915const string&
20917{
20918 if (priv_->qualified_name_.empty())
20919 {
20920 priv_->qualified_name_ =
20921 get_enum_type()->get_qualified_name(internal)
20922 + "::"
20923 + get_name();
20924 }
20925 return priv_->qualified_name_;
20926}
20927
20928/// Setter for the name of @ref enum_type_decl::enumerator.
20929///
20930/// @param n the new name.
20931void
20933{priv_->name_ = n;}
20934
20935/// Getter for the value of @ref enum_type_decl::enumerator.
20936///
20937/// @return the value of the current instance of
20938/// enum_type_decl::enumerator.
20939int64_t
20941{return priv_->value_;}
20942
20943/// Setter for the value of @ref enum_type_decl::enumerator.
20944///
20945/// @param v the new value of the enum_type_decl::enumerator.
20946void
20948{priv_->value_= v;}
20949
20950/// Getter for the enum type that this enumerator is for.
20951///
20952/// @return the enum type that this enumerator is for.
20955{return priv_->enum_type_;}
20956
20957/// Setter for the enum type that this enumerator is for.
20958///
20959/// @param e the new enum type.
20960void
20962{priv_->enum_type_ = e;}
20963// </enum_type_decl definitions>
20964
20965// <typedef_decl definitions>
20966
20967/// Private data structure of the @ref typedef_decl.
20968struct typedef_decl::priv
20969{
20970 type_base_wptr underlying_type_;
20971
20972 priv(const type_base_sptr& t)
20973 : underlying_type_(t)
20974 {}
20975}; // end struct typedef_decl::priv
20976
20977/// Constructor of the typedef_decl type.
20978///
20979/// @param name the name of the typedef.
20980///
20981/// @param underlying_type the underlying type of the typedef.
20982///
20983/// @param locus the source location of the typedef declaration.
20984///
20985/// @param linkage_name the mangled name of the typedef.
20986///
20987/// @param vis the visibility of the typedef type.
20988typedef_decl::typedef_decl(const string& name,
20989 const type_base_sptr underlying_type,
20990 const location& locus,
20991 const string& linkage_name,
20992 visibility vis)
20993 : type_or_decl_base(underlying_type->get_environment(),
20994 TYPEDEF_TYPE
20995 | ABSTRACT_TYPE_BASE
20996 | ABSTRACT_DECL_BASE),
20997 type_base(underlying_type->get_environment(),
20998 underlying_type->get_size_in_bits(),
20999 underlying_type->get_alignment_in_bits()),
21000 decl_base(underlying_type->get_environment(),
21001 name, locus, linkage_name, vis),
21002 priv_(new priv(underlying_type))
21003{
21005}
21006
21007/// Constructor of the typedef_decl type.
21008///
21009/// @param name the name of the typedef.
21010///
21011/// @param env the environment of the current typedef.
21012///
21013/// @param locus the source location of the typedef declaration.
21014///
21015/// @param mangled_name the mangled name of the typedef.
21016///
21017/// @param vis the visibility of the typedef type.
21018typedef_decl::typedef_decl(const string& name,
21019 const environment& env,
21020 const location& locus,
21021 const string& mangled_name,
21022 visibility vis)
21023 : type_or_decl_base(env,
21024 TYPEDEF_TYPE
21025 | ABSTRACT_TYPE_BASE
21026 | ABSTRACT_DECL_BASE),
21027 type_base(env, /*size_in_bits=*/0,
21028 /*alignment_in_bits=*/0),
21029 decl_base(env, name, locus, mangled_name, vis),
21030 priv_(new priv(nullptr))
21031{
21033}
21034
21035/// Return the hash value of the current IR node.
21036///
21037/// Note that upon the first invocation, this member functions
21038/// computes the hash value and returns it. Subsequent invocations
21039/// just return the hash value that was previously calculated.
21040///
21041/// @return the hash value of the current IR node.
21042hash_t
21044{
21046 return h;
21047}
21048
21049/// Return the size of the typedef.
21050///
21051/// This function looks at the size of the underlying type and ensures
21052/// that it's the same as the size of the typedef.
21053///
21054/// @return the size of the typedef.
21055size_t
21057{
21058 if (!get_underlying_type())
21059 return 0;
21060 size_t s = get_underlying_type()->get_size_in_bits();
21061 if (s != type_base::get_size_in_bits())
21062 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
21064}
21065
21066/// Return the alignment of the typedef.
21067///
21068/// This function looks at the alignment of the underlying type and
21069/// ensures that it's the same as the alignment of the typedef.
21070///
21071/// @return the size of the typedef.
21072size_t
21074{
21075 if (!get_underlying_type())
21076 return 0;
21077 size_t s = get_underlying_type()->get_alignment_in_bits();
21079 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
21081}
21082
21083/// Compares two instances of @ref typedef_decl.
21084///
21085/// If the two intances are different, set a bitfield to give some
21086/// insight about the kind of differences there are.
21087///
21088/// @param l the first artifact of the comparison.
21089///
21090/// @param r the second artifact of the comparison.
21091///
21092/// @param k a pointer to a bitfield that gives information about the
21093/// kind of changes there are between @p l and @p r. This one is set
21094/// iff @p k is non-null and the function returns false.
21095///
21096/// Please note that setting k to a non-null value does have a
21097/// negative performance impact because even if @p l and @p r are not
21098/// equal, the function keeps up the comparison in order to determine
21099/// the different kinds of ways in which they are different.
21100///
21101/// @return true if @p l equals @p r, false otherwise.
21102bool
21104{
21105 bool result = true;
21106
21107 // No need to go further if the types have different names or
21108 // different size / alignment.
21109 if (!(l.decl_base::operator==(r)))
21110 {
21111 result = false;
21112 if (k)
21114 else
21116 }
21117
21119 {
21120 // Changes to the underlying type of a typedef are considered
21121 // local, a bit like for pointers.
21122 result = false;
21123 if (k)
21125 else
21127 }
21128
21129 ABG_RETURN(result);
21130}
21131
21132/// Equality operator
21133///
21134/// @param o the other typedef_decl to test against.
21135bool
21137{
21138 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
21139 if (!other)
21140 return false;
21141 return try_canonical_compare(this, other);
21142}
21143
21144/// Equality operator
21145///
21146/// @param o the other typedef_decl to test against.
21147///
21148/// @return true if the current instance of @ref typedef_decl equals
21149/// @p o.
21150bool
21152{
21153 const decl_base* other = dynamic_cast<const decl_base*>(&o);
21154 if (!other)
21155 return false;
21156 return *this == *other;
21157}
21158
21159/// Build a pretty representation for a typedef_decl.
21160///
21161/// @param internal set to true if the call is intended to get a
21162/// representation of the decl (or type) for the purpose of canonical
21163/// type comparison. This is mainly used in the function
21164/// type_base::get_canonical_type_for().
21165///
21166/// In other words if the argument for this parameter is true then the
21167/// call is meant for internal use (for technical use inside the
21168/// library itself), false otherwise. If you don't know what this is
21169/// for, then set it to false.
21170
21171/// @param qualified_name if true, names emitted in the pretty
21172/// representation are fully qualified.
21173///
21174/// @return a copy of the pretty representation of the current
21175/// instance of typedef_decl.
21176string
21178 bool qualified_name) const
21179{
21180
21181 string result = "typedef ";
21182 if (qualified_name)
21183 result += get_qualified_name(internal);
21184 else
21185 result += get_name();
21186
21187 return result;
21188}
21189
21190/// Getter of the underlying type of the typedef.
21191///
21192/// @return the underlying_type.
21193type_base_sptr
21195{return priv_->underlying_type_.lock();}
21196
21197/// Setter ofthe underlying type of the typedef.
21198///
21199/// @param t the new underlying type of the typedef.
21200void
21202{
21203 priv_->underlying_type_ = t;
21204 set_size_in_bits(t->get_size_in_bits());
21205 set_alignment_in_bits(t->get_alignment_in_bits());
21206}
21207
21208/// Implementation of the virtual "get_qualified_name" method.
21209///
21210/// @param qualified_name the resuling qualified name of the typedef type.
21211///
21212/// @param internal if true, then it means the qualified name is for
21213/// "internal" purposes, meaning mainly for type canonicalization
21214/// purposes.
21215void
21217 bool internal) const
21218{qualified_name = get_qualified_name(internal);}
21219
21220/// Implementation of the virtual "get_qualified_name" method.
21221///
21222/// @param internal if true, then it means the qualified name is for
21223/// "internal" purposes, meaning mainly for type canonicalization
21224/// purposes.
21225///
21226/// @return the qualified name.
21227const interned_string&
21229{
21230 // Note that the qualified name has been already set by
21231 // qualified_name_setter::do_update, which is invoked by
21232 // update_qualified_name. The latter is itself invoked whenever the
21233 // typedef is added to its scope, in scope_decl::add_member_decl.
21234 if (internal)
21235 return decl_base::priv_->internal_qualified_name_;
21236 else
21237 return decl_base::priv_->qualified_name_;
21238}
21239
21240/// This implements the ir_traversable_base::traverse pure virtual
21241/// function.
21242///
21243/// @param v the visitor used on the current instance.
21244///
21245/// @return true if the entire IR node tree got traversed, false
21246/// otherwise.
21247bool
21249{
21250 if (v.type_node_has_been_visited(this))
21251 return true;
21252
21253 if (visiting())
21254 return true;
21255
21256 if (v.visit_begin(this))
21257 {
21258 visiting(true);
21259 if (type_base_sptr t = get_underlying_type())
21260 t->traverse(v);
21261 visiting(false);
21262 }
21263
21264 bool result = v.visit_end(this);
21266 return result;
21267}
21268
21269typedef_decl::~typedef_decl()
21270{}
21271// </typedef_decl definitions>
21272
21273// <var_decl definitions>
21274
21275struct var_decl::priv
21276{
21277 type_base_wptr type_;
21278 type_base* naked_type_;
21279 decl_base::binding binding_;
21280 elf_symbol_sptr symbol_;
21281 interned_string id_;
21282
21283 priv()
21284 : naked_type_(),
21285 binding_(decl_base::BINDING_GLOBAL)
21286 {}
21287
21288 priv(type_base_sptr t,
21290 : type_(t),
21291 naked_type_(t.get()),
21292 binding_(b)
21293 {}
21294
21295 /// Setter of the type of the variable.
21296 ///
21297 /// @param t the new variable type.
21298 void
21299 set_type(type_base_sptr t)
21300 {
21301 type_ = t;
21302 naked_type_ = t.get();
21303 }
21304}; // end struct var_decl::priv
21305
21306/// Constructor of the @ref var_decl type.
21307///
21308/// @param name the name of the variable declaration
21309///
21310/// @param type the type of the variable declaration
21311///
21312/// @param locus the source location where the variable was defined.
21313///
21314/// @param linkage_name the linkage name of the variable.
21315///
21316/// @param vis the visibility of of the variable.
21317///
21318/// @param bind the binding kind of the variable.
21319var_decl::var_decl(const string& name,
21320 type_base_sptr type,
21321 const location& locus,
21322 const string& linkage_name,
21323 visibility vis,
21324 binding bind)
21325 : type_or_decl_base(type->get_environment(),
21326 VAR_DECL | ABSTRACT_DECL_BASE),
21327 decl_base(type->get_environment(), name, locus, linkage_name, vis),
21328 priv_(new priv(type, bind))
21329{
21331}
21332
21333/// Getter of the type of the variable.
21334///
21335/// @return the type of the variable.
21336const type_base_sptr
21338{return priv_->type_.lock();}
21339
21340/// Setter of the type of the variable.
21341///
21342/// @param the new type of the variable.
21343void
21344var_decl::set_type(type_base_sptr& t)
21345{priv_->set_type(t);}
21346
21347/// Getter of the type of the variable.
21348///
21349/// This getter returns a bare pointer, as opposed to a smart pointer.
21350/// It's to be used on performance sensitive code paths identified by
21351/// careful profiling.
21352///
21353/// @return the type of the variable, as a bare pointer.
21354const type_base*
21356{return priv_->naked_type_;}
21357
21358/// Getter of the binding of the variable.
21359///
21360/// @return the biding of the variable.
21363{return priv_->binding_;}
21364
21365/// Setter of the binding of the variable.
21366///
21367/// @param b the new binding value.
21368void
21370{priv_->binding_ = b;}
21371
21372/// Sets the underlying ELF symbol for the current variable.
21373///
21374/// And underlyin$g ELF symbol for the current variable might exist
21375/// only if the corpus that this variable originates from was
21376/// constructed from an ELF binary file.
21377///
21378/// Note that comparing two variables that have underlying ELF symbols
21379/// involves comparing their underlying elf symbols. The decl name
21380/// for the variable thus becomes irrelevant in the comparison.
21381///
21382/// @param sym the new ELF symbol for this variable decl.
21383void
21385{
21386 priv_->symbol_ = sym;
21387 // The variable id cache that depends on the symbol must be
21388 // invalidated because the symbol changed.
21389 priv_->id_ = get_environment().intern("");
21390}
21391
21392/// Gets the the underlying ELF symbol for the current variable,
21393/// that was set using var_decl::set_symbol(). Please read the
21394/// documentation for that member function for more information about
21395/// "underlying ELF symbols".
21396///
21397/// @return sym the underlying ELF symbol for this variable decl, if
21398/// one exists.
21399const elf_symbol_sptr&
21401{return priv_->symbol_;}
21402
21403/// Create a new var_decl that is a clone of the current one.
21404///
21405/// @return the cloned var_decl.
21408{
21410 get_type(),
21411 get_location(),
21414 get_binding()));
21415
21416 v->set_symbol(get_symbol());
21417
21418 if (is_member_decl(*this))
21419 {
21423 get_member_is_static(*this),
21424 get_data_member_offset(*this));
21425 }
21426 else
21428
21429 return v;
21430}
21431/// Setter of the scope of the current var_decl.
21432///
21433/// Note that the decl won't hold a reference on the scope. It's
21434/// rather the scope that holds a reference on its members.
21435///
21436/// @param scope the new scope.
21437void
21438var_decl::set_scope(scope_decl* scope)
21439{
21440 if (!get_context_rel())
21441 set_context_rel(new dm_context_rel(scope));
21442 else
21443 get_context_rel()->set_scope(scope);
21444}
21445
21446/// Compares two instances of @ref var_decl without taking their type
21447/// into account.
21448///
21449/// If the two intances are different modulo their type, set a
21450/// bitfield to give some insight about the kind of differences there
21451/// are.
21452///
21453/// @param l the first artifact of the comparison.
21454///
21455/// @param r the second artifact of the comparison.
21456///
21457/// @param k a pointer to a bitfield that gives information about the
21458/// kind of changes there are between @p l and @p r. This one is set
21459/// iff @p k is non-null and the function returns false.
21460///
21461/// Please note that setting k to a non-null value does have a
21462/// negative performance impact because even if @p l and @p r are not
21463/// equal, the function keeps up the comparison in order to determine
21464/// the different kinds of ways in which they are different.
21465///
21466/// @return true if @p l equals @p r, false otherwise.
21467bool
21469{
21470 bool result = true;
21471
21472 // If there are underlying elf symbols for these variables,
21473 // compare them. And then compare the other parts.
21474 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
21475 if (!!s0 != !!s1)
21476 {
21477 result = false;
21478 if (k)
21480 else
21482 }
21483 else if (s0 && !textually_equals(*s0, *s1, k))
21484 {
21485 result = false;
21486 if (!k)
21488 }
21489 bool symbols_are_equal = (s0 && s1 && result);
21490
21491 if (symbols_are_equal)
21492 {
21493 // The variables have underlying elf symbols that are equal, so
21494 // now, let's compare the decl_base part of the variables w/o
21495 // considering their decl names.
21496 const environment& env = l.get_environment();
21497 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
21498 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
21499 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
21500 bool decl_bases_different = !l.decl_base::operator==(r);
21501 const_cast<var_decl&>(l).set_qualified_name(n1);
21502 const_cast<var_decl&>(r).set_qualified_name(n2);
21503
21504 if (decl_bases_different)
21505 {
21506 result = false;
21507 if (k)
21509 else
21511 }
21512 }
21513 else
21514 if (!l.decl_base::operator==(r))
21515 {
21516 result = false;
21517 if (k)
21519 else
21521 }
21522
21523 const dm_context_rel* c0 =
21524 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
21525 const dm_context_rel* c1 =
21526 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
21527 ABG_ASSERT(c0 && c1);
21528
21529 if (*c0 != *c1)
21530 {
21531 result = false;
21532 if (k)
21534 else
21536 }
21537
21538 ABG_RETURN(result);
21539}
21540
21541/// Compares two instances of @ref var_decl.
21542///
21543/// If the two intances are different, set a bitfield to give some
21544/// insight about the kind of differences there are.
21545///
21546/// @param l the first artifact of the comparison.
21547///
21548/// @param r the second artifact of the comparison.
21549///
21550/// @param k a pointer to a bitfield that gives information about the
21551/// kind of changes there are between @p l and @p r. This one is set
21552/// iff @p k is non-null and the function returns false.
21553///
21554/// Please note that setting k to a non-null value does have a
21555/// negative performance impact because even if @p l and @p r are not
21556/// equal, the function keeps up the comparison in order to determine
21557/// the different kinds of ways in which they are different.
21558///
21559/// @return true if @p l equals @p r, false otherwise.
21560bool
21561equals(const var_decl& l, const var_decl& r, change_kind* k)
21562{
21563 bool result = true;
21564
21565 // First test types of variables. This should be fast because in
21566 // the general case, most types should be canonicalized.
21567 if (*l.get_naked_type() != *r.get_naked_type())
21568 {
21569 result = false;
21570 if (k)
21571 {
21573 r.get_naked_type()))
21574 *k |= (LOCAL_TYPE_CHANGE_KIND);
21575 else
21576 *k |= SUBTYPE_CHANGE_KIND;
21577 }
21578 else
21580 }
21581
21582 result &= var_equals_modulo_types(l, r, k);
21583
21584 ABG_RETURN(result);
21585}
21586
21587/// Comparison operator of @ref var_decl.
21588///
21589/// @param o the instance of @ref var_decl to compare against.
21590///
21591/// @return true iff the current instance of @ref var_decl equals @p o.
21592bool
21594{
21595 const var_decl* other = dynamic_cast<const var_decl*>(&o);
21596 if (!other)
21597 return false;
21598
21599 return equals(*this, *other, 0);
21600}
21601
21602/// Return an ID that tries to uniquely identify the variable inside a
21603/// program or a library.
21604///
21605/// So if the variable has an underlying elf symbol, the ID is the
21606/// concatenation of the symbol name and its version. Otherwise, the
21607/// ID is the linkage name if its non-null. Otherwise, it's the
21608/// pretty representation of the variable.
21609///
21610/// @return the ID.
21613{
21614 if (priv_->id_.empty())
21615 {
21616 string repr = get_name();
21617 string sym_str;
21618 if (elf_symbol_sptr s = get_symbol())
21619 sym_str = s->get_id_string();
21620 else if (!get_linkage_name().empty())
21621 sym_str = get_linkage_name();
21622
21623 const environment& env = get_type()->get_environment();
21624 priv_->id_ = env.intern(repr);
21625 if (!sym_str.empty())
21626 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
21627 }
21628 return priv_->id_;
21629}
21630
21631/// Get the qualified name of a given variable or data member.
21632///
21633///
21634/// Note that if the current instance of @ref var_decl is an anonymous
21635/// data member, then the qualified name is actually the flat
21636/// representation (the definition) of the type of the anonymous data
21637/// member. We chose the flat representation because otherwise, the
21638/// name of an *anonymous* data member is empty, by construction, e.g:
21639///
21640/// struct foo {
21641/// int a;
21642/// union {
21643/// char b;
21644/// char c;
21645/// }; // <---- this data member is anonymous.
21646/// int d;
21647/// }
21648///
21649/// The string returned for the anonymous member here is going to be:
21650///
21651/// "union {char b; char c}"
21652///
21653/// @param internal if true then this is for a purpose to the library,
21654/// otherwise, it's for being displayed to users.
21655///
21656/// @return the resulting qualified name.
21657const interned_string&
21659{
21660 if (is_anonymous_data_member(this)
21661 && decl_base::get_qualified_name().empty())
21662 {
21663 // Display the anonymous data member in a way that makes sense.
21664 string r = get_pretty_representation(internal);
21666 }
21667
21668 return decl_base::get_qualified_name(internal);
21669}
21670
21671/// Build and return the pretty representation of this variable.
21672///
21673/// @param internal set to true if the call is intended to get a
21674/// representation of the decl (or type) for the purpose of canonical
21675/// type comparison. This is mainly used in the function
21676/// type_base::get_canonical_type_for().
21677///
21678/// In other words if the argument for this parameter is true then the
21679/// call is meant for internal use (for technical use inside the
21680/// library itself), false otherwise. If you don't know what this is
21681/// for, then set it to false.
21682///
21683/// @param qualified_name if true, names emitted in the pretty
21684/// representation are fully qualified.
21685///
21686/// @return a copy of the pretty representation of this variable.
21687string
21688var_decl::get_pretty_representation(bool internal, bool qualified_name) const
21689{
21690 string result;
21691
21692 if (is_member_decl(this) && get_member_is_static(this))
21693 result = "static ";
21694
21695 // Detect if the current instance of var_decl is a member of
21696 // an anonymous class or union.
21697 bool member_of_anonymous_class = false;
21698 if (class_or_union* scope = is_at_class_scope(this))
21699 if (scope->get_is_anonymous())
21700 member_of_anonymous_class = true;
21701
21702 type_base_sptr type = get_type();
21703 if (is_array_type(type, /*look_through_qualifiers=*/true)
21704 || is_pointer_type(type, /*look_through_qualifiers=*/true)
21705 || is_reference_type(type, /*look_through_qualifiers=*/true)
21706 || is_ptr_to_mbr_type(type, /*look_through_qualifiers=*/true))
21707 {
21708 string name;
21709 if (member_of_anonymous_class || !qualified_name)
21710 name = get_name();
21711 else
21712 name = get_qualified_name(internal);
21713
21714 if (qualified_type_def_sptr q = is_qualified_type(type))
21715 {
21716 string quals_repr =
21717 get_string_representation_of_cv_quals(q->get_cv_quals());
21718 if (!quals_repr.empty())
21719 name = quals_repr + " " + name;
21720 type = peel_qualified_type(type);
21721 }
21722
21723 name = string(" ") + name;
21724 if (array_type_def_sptr t = is_array_type(type))
21725 result += array_declaration_name(t, name, qualified_name, internal);
21726 else if (pointer_type_def_sptr t = is_pointer_type(type))
21727 result += pointer_declaration_name(t, name, qualified_name, internal);
21728 else if (reference_type_def_sptr t = is_reference_type(type))
21729 result += pointer_declaration_name(t, name, qualified_name, internal);
21730 else if (ptr_to_mbr_type_sptr t = is_ptr_to_mbr_type(type))
21731 result += ptr_to_mbr_declaration_name(t, name,
21732 qualified_name,
21733 internal);
21734 }
21735 else
21736 {
21737 if (/*The current var_decl is to be used as an anonymous data
21738 member. */
21739 get_name().empty())
21740 {
21741 // Display the anonymous data member in a way that
21742 // makes sense.
21743 result +=
21746 "", /*one_line=*/true, internal);
21747 }
21748 else if (data_member_has_anonymous_type(this))
21749 {
21752 "", /*one_line=*/true, internal);
21753 result += " ";
21754 if (!internal
21755 && (member_of_anonymous_class || !qualified_name))
21756 // It doesn't make sense to name the member of an
21757 // anonymous class or union like:
21758 // "__anonymous__::data_member_name". So let's just use
21759 // its non-qualified name.
21760 result += get_name();
21761 else
21762 result += get_qualified_name(internal);
21763 }
21764 else
21765 {
21766 result +=
21768 + " ";
21769
21770 if (!internal
21771 && (member_of_anonymous_class || !qualified_name))
21772 // It doesn't make sense to name the member of an
21773 // anonymous class or union like:
21774 // "__anonymous__::data_member_name". So let's just use
21775 // its non-qualified name.
21776 result += get_name();
21777 else
21778 result += get_qualified_name(internal);
21779 }
21780 }
21781 return result;
21782}
21783
21784/// Get a name that is valid even for an anonymous data member.
21785///
21786/// If the current @ref var_decl is an anonymous data member, then
21787/// return its pretty representation. As of now, that pretty
21788/// representation is actually its flat representation as returned by
21789/// get_class_or_union_flat_representation().
21790///
21791/// Otherwise, just return the name of the current @ref var_decl.
21792///
21793/// @param qualified if true, return the qualified name. This doesn't
21794/// have an effet if the current @ref var_decl represents an anonymous
21795/// data member.
21796string
21798{
21799 string name;
21800 if (is_anonymous_data_member(this))
21801 // This function is used in the comparison engine to determine
21802 // which anonymous data member was deleted. So it's not involved
21803 // in type comparison or canonicalization. We don't want to use
21804 // the 'internal' version of the pretty presentation.
21805 name = get_pretty_representation(/*internal=*/false, qualified);
21806 else
21807 name = get_name();
21808
21809 return name;
21810}
21811
21812/// This implements the ir_traversable_base::traverse pure virtual
21813/// function.
21814///
21815/// @param v the visitor used on the current instance.
21816///
21817/// @return true if the entire IR node tree got traversed, false
21818/// otherwise.
21819bool
21821{
21822 if (visiting())
21823 return true;
21824
21825 if (v.visit_begin(this))
21826 {
21827 visiting(true);
21828 if (type_base_sptr t = get_type())
21829 t->traverse(v);
21830 visiting(false);
21831 }
21832 return v.visit_end(this);
21833}
21834
21835var_decl::~var_decl()
21836{}
21837
21838// </var_decl definitions>
21839
21840/// This function is automatically invoked whenever an instance of
21841/// this type is canonicalized.
21842///
21843/// It's an overload of the virtual type_base::on_canonical_type_set.
21844///
21845/// We put here what is thus meant to be executed only at the point of
21846/// type canonicalization.
21847void
21849{
21850 priv_->cached_name_.clear();
21851 priv_->internal_cached_name_.clear();
21852}
21853
21854/// The most straightforward constructor for the function_type class.
21855///
21856/// @param return_type the return type of the function type.
21857///
21858/// @param parms the list of parameters of the function type.
21859/// Stricto sensu, we just need a list of types; we are using a list
21860/// of parameters (where each parameter also carries the name of the
21861/// parameter and its source location) to try and provide better
21862/// diagnostics whenever it makes sense. If it appears that this
21863/// wasts too many resources, we can fall back to taking just a
21864/// vector of types here.
21865///
21866/// @param size_in_bits the size of this type, in bits.
21867///
21868/// @param alignment_in_bits the alignment of this type, in bits.
21869///
21870/// @param size_in_bits the size of this type.
21871function_type::function_type(type_base_sptr return_type,
21872 const parameters& parms,
21873 size_t size_in_bits,
21874 size_t alignment_in_bits)
21875 : type_or_decl_base(return_type->get_environment(),
21876 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21877 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21878 priv_(new priv(parms, return_type))
21879{
21881
21882 for (parameters::size_type i = 0, j = 1;
21883 i < priv_->parms_.size();
21884 ++i, ++j)
21885 {
21886 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21887 // If the first parameter is artificial, then it certainly
21888 // means that this is a member function, and the first
21889 // parameter is the implicit this pointer. In that case, set
21890 // the index of that implicit parameter to zero. Otherwise,
21891 // the index of the first parameter starts at one.
21892 j = 0;
21893 priv_->parms_[i]->set_index(j);
21894 }
21895}
21896
21897/// A constructor for a function_type that takes no parameters.
21898///
21899/// @param return_type the return type of this function_type.
21900///
21901/// @param size_in_bits the size of this type, in bits.
21902///
21903/// @param alignment_in_bits the alignment of this type, in bits.
21904function_type::function_type(type_base_sptr return_type,
21905 size_t size_in_bits, size_t alignment_in_bits)
21906 : type_or_decl_base(return_type->get_environment(),
21907 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21908 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21909 priv_(new priv(return_type))
21910{
21912}
21913
21914/// A constructor for a function_type that takes no parameter and
21915/// that has no return_type yet. These missing parts can (and must)
21916/// be added later.
21917///
21918/// @param env the environment we are operating from.
21919///
21920/// @param size_in_bits the size of this type, in bits.
21921///
21922/// @param alignment_in_bits the alignment of this type, in bits.
21923function_type::function_type(const environment& env,
21924 size_t size_in_bits,
21925 size_t alignment_in_bits)
21926 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21927 type_base(env, size_in_bits, alignment_in_bits),
21928 priv_(new priv)
21929{
21931}
21932
21933/// Return the hash value of the current IR node.
21934///
21935/// Note that upon the first invocation, this member functions
21936/// computes the hash value and returns it. Subsequent invocations
21937/// just return the hash value that was previously calculated.
21938///
21939/// @return the hash value of the current IR node.
21940hash_t
21942{
21944 return h;
21945}
21946
21947/// Getter for the return type of the current instance of @ref
21948/// function_type.
21949///
21950/// @return the return type.
21951type_base_sptr
21953{return priv_->return_type_.lock();}
21954
21955/// Setter of the return type of the current instance of @ref
21956/// function_type.
21957///
21958/// @param t the new return type to set.
21959void
21961{priv_->return_type_ = t;}
21962
21963/// Getter for the set of parameters of the current intance of @ref
21964/// function_type.
21965///
21966/// @return the parameters of the current instance of @ref
21967/// function_type.
21970{return priv_->parms_;}
21971
21972/// Get the Ith parameter of the vector of parameters of the current
21973/// instance of @ref function_type.
21974///
21975/// Note that the first parameter is at index 0. That parameter is
21976/// the first parameter that comes after the possible implicit "this"
21977/// parameter, when the current instance @ref function_type is for a
21978/// member function. Otherwise, if the current instance of @ref
21979/// function_type is for a non-member function, the parameter at index
21980/// 0 is the first parameter of the function.
21981///
21982///
21983/// @param i the index of the parameter to return. If i is greater
21984/// than the index of the last parameter, then this function returns
21985/// an empty parameter (smart) pointer.
21986///
21987/// @return the @p i th parameter that is not implicit.
21990{
21991 parameter_sptr result;
21992 if (dynamic_cast<const method_type*>(this))
21993 {
21994 if (i + 1 < get_parameters().size())
21995 result = get_parameters()[i + 1];
21996 }
21997 else
21998 {
21999 if (i < get_parameters().size())
22000 result = get_parameters()[i];
22001 }
22002 return result;
22003}
22004
22005/// Setter for the parameters of the current instance of @ref
22006/// function_type.
22007///
22008/// @param p the new vector of parameters to set.
22009void
22011{
22012 priv_->parms_ = p;
22013 for (parameters::size_type i = 0, j = 1;
22014 i < priv_->parms_.size();
22015 ++i, ++j)
22016 {
22017 if (i == 0 && priv_->parms_[i]->get_is_artificial())
22018 // If the first parameter is artificial, then it certainly
22019 // means that this is a member function, and the first
22020 // parameter is the implicit this pointer. In that case, set
22021 // the index of that implicit parameter to zero. Otherwise,
22022 // the index of the first parameter starts at one.
22023 j = 0;
22024 priv_->parms_[i]->set_index(j);
22025 }
22026}
22027
22028/// Append a new parameter to the vector of parameters of the current
22029/// instance of @ref function_type.
22030///
22031/// @param parm the parameter to append.
22032void
22034{
22035 parm->set_index(priv_->parms_.size());
22036 priv_->parms_.push_back(parm);
22037}
22038
22039/// Test if the current instance of @ref function_type is for a
22040/// variadic function.
22041///
22042/// A variadic function is a function that takes a variable number of
22043/// arguments.
22044///
22045/// @return true iff the current instance of @ref function_type is for
22046/// a variadic function.
22047bool
22049{
22050 return (!priv_->parms_.empty()
22051 && priv_->parms_.back()->get_variadic_marker());
22052}
22053
22054/// Compare two function types.
22055///
22056/// In case these function types are actually method types, this
22057/// function avoids comparing two parameters (of the function types)
22058/// if the types of the parameters are actually the types of the
22059/// classes of the method types. This prevents infinite recursion
22060/// during the comparison of two classes that are structurally
22061/// identical.
22062///
22063/// This is a subroutine of the equality operator of function_type.
22064///
22065/// @param lhs the first function type to consider
22066///
22067/// @param rhs the second function type to consider
22068///
22069/// @param k a pointer to a bitfield set by the function to give
22070/// information about the kind of changes carried by @p lhs and @p
22071/// rhs. It is set iff @p k is non-null and the function returns
22072/// false.
22073///
22074/// Please note that setting k to a non-null value does have a
22075/// negative performance impact because even if @p l and @p r are not
22076/// equal, the function keeps up the comparison in order to determine
22077/// the different kinds of ways in which they are different.
22078///
22079///@return true if lhs == rhs, false otherwise.
22080bool
22082{
22083#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
22084
22086
22087 {
22088 // First of all, let's see if these two function types haven't
22089 // already been compared. If so, and if the result of the
22090 // comparison has been cached, let's just re-use it, rather than
22091 // comparing them all over again.
22092 bool cached_result = false;
22093 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
22094 cached_result))
22095 ABG_RETURN(cached_result);
22096 }
22097
22099
22100 bool result = true;
22101
22102 if (!l.type_base::operator==(r))
22103 {
22104 result = false;
22105 if (k)
22107 else
22108 RETURN(result);
22109 }
22110
22111 class_or_union* l_class = 0, *r_class = 0;
22112 if (const method_type* m = dynamic_cast<const method_type*>(&l))
22113 l_class = m->get_class_type().get();
22114
22115 if (const method_type* m = dynamic_cast<const method_type*>(&r))
22116 r_class = m->get_class_type().get();
22117
22118 // Compare the names of the class of the method
22119
22120 if (!!l_class != !!r_class)
22121 {
22122 result = false;
22123 if (k)
22125 else
22126 RETURN(result);
22127 }
22128 else if (l_class
22129 && (l_class->get_qualified_name()
22130 != r_class->get_qualified_name()))
22131 {
22132 result = false;
22133 if (k)
22135 else
22136 RETURN(result);
22137 }
22138
22139 // Then compare the return type; Beware if it's t's a class type
22140 // that is the same as the method class name; we can recurse for
22141 // ever in that case.
22142
22143 decl_base* l_return_type_decl =
22145 decl_base* r_return_type_decl =
22147 bool compare_result_types = true;
22148 string l_rt_name = l_return_type_decl
22149 ? l_return_type_decl->get_qualified_name()
22150 : string();
22151 string r_rt_name = r_return_type_decl
22152 ? r_return_type_decl->get_qualified_name()
22153 : string();
22154
22155 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
22156 ||
22157 (r_class && (r_class->get_qualified_name() == r_rt_name)))
22158 compare_result_types = false;
22159
22160 if (compare_result_types)
22161 {
22162 // Let's not consider typedefs when comparing return types to
22163 // avoid spurious changes.
22164 //
22165 // TODO: We should also do this for parameter types, or rather,
22166 // we should teach the equality operators in the IR, at some
22167 // point, to peel typedefs off.
22168 if (l.get_return_type() != r.get_return_type())
22169 {
22170 result = false;
22171 if (k)
22172 {
22174 r.get_return_type()))
22176 else
22177 *k |= SUBTYPE_CHANGE_KIND;
22178 }
22179 else
22180 RETURN(result);
22181 }
22182 }
22183 else
22184 if (l_rt_name != r_rt_name)
22185 {
22186 result = false;
22187 if (k)
22188 *k |= SUBTYPE_CHANGE_KIND;
22189 else
22190 RETURN(result);
22191 }
22192
22193 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
22194 for (i = l.get_first_parm(), j = r.get_first_parm();
22195 i != l.get_parameters().end() && j != r.get_parameters().end();
22196 ++i, ++j)
22197 {
22198 if (**i != **j)
22199 {
22200 result = false;
22201 if (k)
22202 {
22203 if (!types_have_similar_structure((*i)->get_type(),
22204 (*j)->get_type()))
22206 else
22207 *k |= SUBTYPE_CHANGE_KIND;
22208 }
22209 else
22210 RETURN(result);
22211 }
22212 }
22213
22214 if ((i != l.get_parameters().end()
22215 || j != r.get_parameters().end()))
22216 {
22217 result = false;
22218 if (k)
22220 else
22221 RETURN(result);
22222 }
22223
22224 RETURN(result);
22225#undef RETURN
22226}
22227
22228/// Get the first parameter of the function.
22229///
22230/// If the function is a non-static member function, the parameter
22231/// returned is the first one following the implicit 'this' parameter.
22232///
22233/// @return the first non implicit parameter of the function.
22234function_type::parameters::const_iterator
22236{
22237 if (get_parameters().empty())
22238 return get_parameters().end();
22239
22240 bool is_method = dynamic_cast<const method_type*>(this);
22241
22242 parameters::const_iterator i = get_parameters().begin();
22243
22244 if (is_method && (*i)->get_is_artificial())
22245 ++i;
22246
22247 return i;
22248}
22249
22250/// Get the first parameter of the function.
22251///
22252/// Note that if the function is a non-static member function, the
22253/// parameter returned is the implicit 'this' parameter.
22254///
22255/// @return the first parameter of the function.
22256function_type::parameters::const_iterator
22258{return get_parameters().begin();}
22259
22260/// Get the name of the current @ref function_type.
22261///
22262/// The name is retrieved from a cache. If the cache is empty, this
22263/// function computes the name of the type, stores it in the cache and
22264/// returns it. Subsequent invocation of the function are going to
22265/// just hit the cache.
22266///
22267/// Note that if the type is *NOT* canonicalized then function type
22268/// name is never cached.
22269///
22270/// @param internal if true then it means the function type name is
22271/// going to be used for purposes that are internal to libabigail
22272/// itself. If you don't know what this is then you probably should
22273/// set this parameter to 'false'.
22274///
22275/// @return the name of the function type.
22276const interned_string&
22278{
22279 if (internal)
22280 {
22282 {
22283 if (priv_->internal_cached_name_.empty())
22284 priv_->internal_cached_name_ =
22285 get_function_type_name(this, /*internal=*/true);
22286 return priv_->internal_cached_name_;
22287 }
22288 else
22289 {
22290 priv_->temp_internal_cached_name_ =
22291 get_function_type_name(this, /*internal=*/true);
22292 return priv_->temp_internal_cached_name_;
22293 }
22294 }
22295 else
22296 {
22298 {
22299 if (priv_->cached_name_.empty())
22300 priv_->cached_name_ =
22301 get_function_type_name(this, /*internal=*/false);
22302 return priv_->cached_name_;
22303 }
22304 else
22305 {
22306 priv_->cached_name_ =
22307 get_function_type_name(this, /*internal=*/false);
22308 return priv_->cached_name_;
22309 }
22310 }
22311}
22312
22313/// Equality operator for function_type.
22314///
22315/// @param o the other function_type to compare against.
22316///
22317/// @return true iff the two function_type are equal.
22318bool
22320{
22321 const function_type* o = dynamic_cast<const function_type*>(&other);
22322 if (!o)
22323 return false;
22324 return try_canonical_compare(this, o);
22325}
22326
22327/// Return a copy of the pretty representation of the current @ref
22328/// function_type.
22329///
22330/// @param internal set to true if the call is intended to get a
22331/// representation of the decl (or type) for the purpose of canonical
22332/// type comparison. This is mainly used in the function
22333/// type_base::get_canonical_type_for().
22334///
22335/// In other words if the argument for this parameter is true then the
22336/// call is meant for internal use (for technical use inside the
22337/// library itself), false otherwise. If you don't know what this is
22338/// for, then set it to false.
22339///
22340/// @return a copy of the pretty representation of the current @ref
22341/// function_type.
22342string
22344 bool /*qualified_name*/) const
22345{return ir::get_pretty_representation(this, internal);}
22346
22347/// Traverses an instance of @ref function_type, visiting all the
22348/// sub-types and decls that it might contain.
22349///
22350/// @param v the visitor that is used to visit every IR sub-node of
22351/// the current node.
22352///
22353/// @return true if either
22354/// - all the children nodes of the current IR node were traversed
22355/// and the calling code should keep going with the traversing.
22356/// - or the current IR node is already being traversed.
22357/// Otherwise, returning false means that the calling code should not
22358/// keep traversing the tree.
22359bool
22361{
22362 // TODO: should we allow the walker to avoid visiting function type
22363 // twice? I think that if we do, then ir_node_visitor needs an
22364 // option to specifically disallow this feature for function types.
22365
22366 if (visiting())
22367 return true;
22368
22369 if (v.visit_begin(this))
22370 {
22371 visiting(true);
22372 bool keep_going = true;
22373
22374 if (type_base_sptr t = get_return_type())
22375 {
22376 if (!t->traverse(v))
22377 keep_going = false;
22378 }
22379
22380 if (keep_going)
22381 for (parameters::const_iterator i = get_parameters().begin();
22382 i != get_parameters().end();
22383 ++i)
22384 if (type_base_sptr parm_type = (*i)->get_type())
22385 if (!parm_type->traverse(v))
22386 break;
22387
22388 visiting(false);
22389 }
22390 return v.visit_end(this);
22391}
22392
22393function_type::~function_type()
22394{}
22395// </function_type>
22396
22397// <method_type>
22398
22399struct method_type::priv
22400{
22401 class_or_union_wptr class_type_;
22402 bool is_const;
22403
22404 priv()
22405 : is_const()
22406 {}
22407}; // end struct method_type::priv
22408
22409/// Constructor for instances of method_type.
22410///
22411/// Instances of method_decl must be of type method_type.
22412///
22413/// @param return_type the type of the return value of the method.
22414///
22415/// @param class_type the base type of the method type. That is, the
22416/// type of the class the method belongs to.
22417///
22418/// @param p the vector of the parameters of the method.
22419///
22420/// @param is_const whether this method type is for a const method.
22421/// Note that const-ness is a property of the method *type* and of the
22422/// relationship between a method *declaration* and its scope.
22423///
22424/// @param size_in_bits the size of an instance of method_type,
22425/// expressed in bits.
22426///
22427/// @param alignment_in_bits the alignment of an instance of
22428/// method_type, expressed in bits.
22429method_type::method_type (type_base_sptr return_type,
22430 class_or_union_sptr class_type,
22431 const std::vector<function_decl::parameter_sptr>& p,
22432 bool is_const,
22433 size_t size_in_bits,
22434 size_t alignment_in_bits)
22435 : type_or_decl_base(class_type->get_environment(),
22436 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22437 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22438 function_type(return_type, p, size_in_bits, alignment_in_bits),
22439 priv_(new priv)
22440{
22442 set_class_type(class_type);
22443 set_is_const(is_const);
22444}
22445
22446/// Constructor of instances of method_type.
22447///
22448///Instances of method_decl must be of type method_type.
22449///
22450/// @param return_type the type of the return value of the method.
22451///
22452/// @param class_type the type of the class the method belongs to.
22453/// The actual (dynamic) type of class_type must be a pointer
22454/// class_type. We are setting it to pointer to type_base here to
22455/// help client code that is compiled without rtti and thus cannot
22456/// perform dynamic casts.
22457///
22458/// @param p the vector of the parameters of the method type.
22459///
22460/// @param is_const whether this method type is for a const method.
22461/// Note that const-ness is a property of the method *type* and of the
22462/// relationship between a method *declaration* and its scope.
22463///
22464/// @param size_in_bits the size of an instance of method_type,
22465/// expressed in bits.
22466///
22467/// @param alignment_in_bits the alignment of an instance of
22468/// method_type, expressed in bits.
22469method_type::method_type(type_base_sptr return_type,
22470 type_base_sptr class_type,
22471 const std::vector<function_decl::parameter_sptr>& p,
22472 bool is_const,
22473 size_t size_in_bits,
22474 size_t alignment_in_bits)
22475 : type_or_decl_base(class_type->get_environment(),
22476 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22477 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22478 function_type(return_type, p, size_in_bits, alignment_in_bits),
22479 priv_(new priv)
22480{
22482 set_class_type(is_class_type(class_type));
22483 set_is_const(is_const);
22484}
22485
22486/// Constructor of the qualified_type_def
22487///
22488/// @param env the environment we are operating from.
22489///
22490/// @param size_in_bits the size of the type, expressed in bits.
22491///
22492/// @param alignment_in_bits the alignment of the type, expressed in bits
22493method_type::method_type(const environment& env,
22494 size_t size_in_bits,
22495 size_t alignment_in_bits)
22496 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22497 type_base(env, size_in_bits, alignment_in_bits),
22498 function_type(env, size_in_bits, alignment_in_bits),
22499 priv_(new priv)
22500{
22502}
22503
22504/// Constructor of instances of method_type.
22505///
22506/// When constructed with this constructor, and instane of method_type
22507/// must set a return type using method_type::set_return_type
22508///
22509/// @param class_typ the base type of the method type. That is, the
22510/// type of the class (or union) the method belongs to.
22511///
22512/// @param size_in_bits the size of an instance of method_type,
22513/// expressed in bits.
22514///
22515/// @param alignment_in_bits the alignment of an instance of
22516/// method_type, expressed in bits.
22517method_type::method_type(class_or_union_sptr class_type,
22518 bool is_const,
22519 size_t size_in_bits,
22520 size_t alignment_in_bits)
22521 : type_or_decl_base(class_type->get_environment(),
22522 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22523 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22524 function_type(class_type->get_environment(),
22525 size_in_bits,
22526 alignment_in_bits),
22527 priv_(new priv)
22528{
22530 set_class_type(class_type);
22531 set_is_const(is_const);
22532}
22533
22534/// Return the hash value of the current IR node.
22535///
22536/// Note that upon the first invocation, this member functions
22537/// computes the hash value and returns it. Subsequent invocations
22538/// just return the hash value that was previously calculated.
22539///
22540/// @return the hash value of the current IR node.
22541hash_t
22543{
22545 return h;
22546}
22547
22548/// Get the class type this method belongs to.
22549///
22550/// @return the class type.
22551class_or_union_sptr
22553{return class_or_union_sptr(priv_->class_type_);}
22554
22555/// Sets the class type of the current instance of method_type.
22556///
22557/// The class type is the type of the class the method belongs to.
22558///
22559/// @param t the new class type to set.
22560void
22561method_type::set_class_type(const class_or_union_sptr& t)
22562{
22563 if (!t)
22564 return;
22565
22566 priv_->class_type_ = t;
22567}
22568
22569/// Return a copy of the pretty representation of the current @ref
22570/// method_type.
22571///
22572/// @param internal set to true if the call is intended to get a
22573/// representation of the decl (or type) for the purpose of canonical
22574/// type comparison. This is mainly used in the function
22575/// type_base::get_canonical_type_for().
22576///
22577/// In other words if the argument for this parameter is true then the
22578/// call is meant for internal use (for technical use inside the
22579/// library itself), false otherwise. If you don't know what this is
22580/// for, then set it to false.
22581///
22582/// @return a copy of the pretty representation of the current @ref
22583/// method_type.
22584string
22586 bool /*qualified_name*/) const
22587{return ir::get_pretty_representation(*this, internal);}
22588
22589/// Setter of the "is-const" property of @ref method_type.
22590///
22591/// @param the new value of the "is-const" property.
22592void
22594{priv_->is_const = f;}
22595
22596/// Getter of the "is-const" property of @ref method_type.
22597///
22598/// @return true iff the "is-const" property was set.
22599bool
22601{return priv_->is_const;}
22602
22603/// Test if the current method type is for a static method or not.
22604///
22605/// @return true iff the current method_type denotes a the type of a
22606/// static method.
22607bool
22609{
22610 // Let's see if the first parameter is artificial and is a pointer
22611 // to an instance of the same class type as the current class.
22613 if (!get_parameters().empty())
22614 first_parm = get_parameters()[0];
22615 if (!first_parm)
22616 return true;
22617 if (!first_parm->get_is_artificial())
22618 return true;
22619
22620 type_base_sptr this_ptr_type = first_parm->get_type();
22621 // Sometimes, the type of the "this" pointer is "const class_type*
22622 // const". Meaning that the "this pointer" itself is const
22623 // qualified. So let's get the underlying non-qualified pointer.
22624 this_ptr_type = peel_qualified_type(this_ptr_type);
22625 if (!is_pointer_type(this_ptr_type))
22626 return true;
22627
22628 type_base_sptr candidate_class_type =
22629 is_pointer_type(this_ptr_type)->get_pointed_to_type();
22630 candidate_class_type = peel_qualified_type(candidate_class_type);
22631 if (is_class_type(candidate_class_type)
22632 && get_type_name(candidate_class_type) == get_type_name(get_class_type()))
22633 // At this point, we are sure we are looking at a *non-static*
22634 // method.
22635 return false;
22636
22637 return true;
22638}
22639
22640/// The destructor of method_type
22642{}
22643
22644// </method_type>
22645
22646// <function_decl definitions>
22647
22648struct function_decl::priv
22649{
22650 bool declared_inline_;
22651 decl_base::binding binding_;
22652 function_type_wptr type_;
22653 function_type* naked_type_;
22654 elf_symbol_sptr symbol_;
22655 interned_string id_;
22656
22657 priv()
22658 : declared_inline_(false),
22659 binding_(decl_base::BINDING_GLOBAL),
22660 naked_type_()
22661 {}
22662
22663 priv(function_type_sptr t,
22664 bool declared_inline,
22666 : declared_inline_(declared_inline),
22667 binding_(binding),
22668 type_(t),
22669 naked_type_(t.get())
22670 {}
22671
22672 priv(function_type_sptr t,
22673 bool declared_inline,
22676 : declared_inline_(declared_inline),
22677 binding_(binding),
22678 type_(t),
22679 naked_type_(t.get()),
22680 symbol_(s)
22681 {}
22682}; // end sruct function_decl::priv
22683
22684/// Constructor of the @ref function_decl.
22685///
22686/// @param name the name of the function.
22687///
22688/// @param function_type the type of the function.
22689///
22690/// @param declared_inline wether the function is declared inline.
22691///
22692/// @param locus the source location of the function.
22693///
22694/// @param mangled_name the linkage name of the function.
22695///
22696/// @param vis the visibility of the function.
22697///
22698/// @param bind the binding of the function.
22701 bool declared_inline,
22702 const location& locus,
22703 const string& mangled_name,
22704 visibility vis,
22705 binding bind)
22706 : type_or_decl_base(function_type->get_environment(),
22707 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22708 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
22709 priv_(new priv(function_type, declared_inline, bind))
22710{
22712}
22713
22714/// Constructor of the function_decl type.
22715///
22716/// This flavour of constructor is for when the pointer to the
22717/// instance of function_type that the client code has is presented as
22718/// a pointer to type_base. In that case, this constructor saves the
22719/// client code from doing a dynamic_cast to get the function_type
22720/// pointer.
22721///
22722/// @param name the name of the function declaration.
22723///
22724/// @param fn_type the type of the function declaration. The dynamic
22725/// type of this parameter should be 'pointer to function_type'
22726///
22727/// @param declared_inline whether this function was declared inline
22728///
22729/// @param locus the source location of the function declaration.
22730///
22731/// @param linkage_name the mangled name of the function declaration.
22732///
22733/// @param vis the visibility of the function declaration.
22734///
22735/// @param bind the kind of the binding of the function
22736/// declaration.
22738 type_base_sptr fn_type,
22739 bool declared_inline,
22740 const location& locus,
22741 const string& linkage_name,
22742 visibility vis,
22743 binding bind)
22744 : type_or_decl_base(fn_type->get_environment(),
22745 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22746 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
22747 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
22748 declared_inline,
22749 bind))
22750{
22752}
22753
22754/// Get the pretty representation of the current instance of @ref function_decl.
22755///
22756/// @param internal set to true if the call is intended to get a
22757/// representation of the decl (or type) for the purpose of canonical
22758/// type comparison. This is mainly used in the function
22759/// type_base::get_canonical_type_for().
22760///
22761/// In other words if the argument for this parameter is true then the
22762/// call is meant for internal use (for technical use inside the
22763/// library itself), false otherwise. If you don't know what this is
22764/// for, then set it to false.
22765///
22766/// @return the pretty representation for a function.
22767string
22769 bool qualified_name) const
22770{
22771 const method_decl* mem_fn =
22772 dynamic_cast<const method_decl*>(this);
22773
22774 string fn_prefix = mem_fn ? "method ": "function ";
22775 string result;
22776
22777 if (mem_fn
22778 && is_member_function(mem_fn)
22780 fn_prefix += "virtual ";
22781
22782 decl_base_sptr return_type;
22783 if ((mem_fn
22784 && is_member_function(mem_fn)
22785 && (get_member_function_is_dtor(*mem_fn)
22786 || get_member_function_is_ctor(*mem_fn))))
22787 /*cdtors do not have return types. */;
22788 else
22789 return_type = mem_fn
22790 ? get_type_declaration(mem_fn->get_type()->get_return_type())
22792
22793 result = get_pretty_representation_of_declarator(internal);
22794 if (return_type)
22795 {
22796 if (is_npaf_type(is_type(return_type))
22797 || !(is_pointer_to_function_type(is_type(return_type))
22798 || is_pointer_to_array_type(is_type(return_type))))
22799 result = get_type_name(is_type(return_type).get(), qualified_name,
22800 internal) + " " + result;
22801 else if (pointer_type_def_sptr p =
22803 result = add_outer_pointer_to_fn_type_expr(p, result,
22804 /*qualified=*/true,
22805 internal);
22806 else if(pointer_type_def_sptr p =
22807 is_pointer_to_array_type(is_type(return_type)))
22808 result = add_outer_pointer_to_array_type_expr(p, result,
22809 qualified_name,
22810 internal);
22811 else
22813 }
22814
22815 return fn_prefix + result;
22816}
22817
22818/// Compute and return the pretty representation for the part of the
22819/// function declaration that starts at the declarator. That is, the
22820/// return type and the other specifiers of the beginning of the
22821/// function's declaration ar omitted.
22822///
22823/// @param internal set to true if the call is intended to get a
22824/// representation of the decl (or type) for the purpose of canonical
22825/// type comparison. This is mainly used in the function
22826/// type_base::get_canonical_type_for().
22827///
22828/// In other words if the argument for this parameter is true then the
22829/// call is meant for internal use (for technical use inside the
22830/// library itself), false otherwise. If you don't know what this is
22831/// for, then set it to false.
22832///
22833/// @return the pretty representation for the part of the function
22834/// declaration that starts at the declarator.
22835string
22837{
22838 const method_decl* mem_fn =
22839 dynamic_cast<const method_decl*>(this);
22840
22841 string result;
22842
22843 if (mem_fn)
22844 {
22845 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
22846 + "::" + mem_fn->get_name();
22847 }
22848 else
22849 result += get_qualified_name();
22850
22851 std::ostringstream fn_parms;
22852 stream_pretty_representation_of_fn_parms(*get_type(),
22853 fn_parms,
22854 /*qualified=*/true,
22855 internal);
22856 result += fn_parms.str();
22857
22858 if (mem_fn
22859 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
22860 || is_method_type(mem_fn->get_type())->get_is_const()))
22861 result += " const";
22862
22863 return result;
22864}
22865
22866/// Getter for the first non-implicit parameter of a function decl.
22867///
22868/// If the function is a non-static member function, the parameter
22869/// returned is the first one following the implicit 'this' parameter.
22870///
22871/// @return the first non implicit parm.
22872function_decl::parameters::const_iterator
22874{
22875 if (get_parameters().empty())
22876 return get_parameters().end();
22877
22878 bool is_method = dynamic_cast<const method_decl*>(this);
22879
22880 parameters::const_iterator i = get_parameters().begin();
22881 if (is_method)
22882 ++i;
22883
22884 return i;
22885}
22886
22887/// Return the type of the current instance of @ref function_decl.
22888///
22889/// It's either a function_type or method_type.
22890/// @return the type of the current instance of @ref function_decl.
22891const shared_ptr<function_type>
22893{return priv_->type_.lock();}
22894
22895/// Fast getter of the type of the current instance of @ref function_decl.
22896///
22897/// Note that this function returns the underlying pointer managed by
22898/// the smart pointer returned by function_decl::get_type(). It's
22899/// faster than function_decl::get_type(). This getter is to be used
22900/// in code paths that are proven to be performance hot spots;
22901/// especially (for instance) when comparing function types. Those
22902/// are compared extremely frequently when libabigail is used to
22903/// handle huge binaries with a lot of functions.
22904///
22905/// @return the type of the current instance of @ref function_decl.
22906const function_type*
22908{return priv_->naked_type_;}
22909
22910void
22911function_decl::set_type(const function_type_sptr& fn_type)
22912{
22913 priv_->type_ = fn_type;
22914 priv_->naked_type_ = fn_type.get();
22915}
22916
22917/// This sets the underlying ELF symbol for the current function decl.
22918///
22919/// And underlyin$g ELF symbol for the current function decl might
22920/// exist only if the corpus that this function decl originates from
22921/// was constructed from an ELF binary file.
22922///
22923/// Note that comparing two function decls that have underlying ELF
22924/// symbols involves comparing their underlying elf symbols. The decl
22925/// name for the function thus becomes irrelevant in the comparison.
22926///
22927/// @param sym the new ELF symbol for this function decl.
22928void
22930{
22931 priv_->symbol_ = sym;
22932 // The function id cache that depends on the symbol must be
22933 // invalidated because the symbol changed.
22934 priv_->id_ = get_environment().intern("");
22935}
22936
22937/// Gets the the underlying ELF symbol for the current variable,
22938/// that was set using function_decl::set_symbol(). Please read the
22939/// documentation for that member function for more information about
22940/// "underlying ELF symbols".
22941///
22942/// @return sym the underlying ELF symbol for this function decl, if
22943/// one exists.
22944const elf_symbol_sptr&
22946{return priv_->symbol_;}
22947
22948/// Test if the function was declared inline.
22949///
22950/// @return true iff the function was declared inline.
22951bool
22953{return priv_->declared_inline_;}
22954
22955/// Set the property of the function being declared inline.
22956///
22957/// @param value true iff the function was declared inline.
22958void
22960{priv_->declared_inline_ = value;}
22961
22963function_decl::get_binding() const
22964{return priv_->binding_;}
22965
22966/// @return the return type of the current instance of function_decl.
22967const shared_ptr<type_base>
22969{return get_type()->get_return_type();}
22970
22971/// @return the parameters of the function.
22972const std::vector<shared_ptr<function_decl::parameter> >&
22974{return get_type()->get_parameters();}
22975
22976/// Append a parameter to the type of this function.
22977///
22978/// @param parm the parameter to append.
22979void
22980function_decl::append_parameter(shared_ptr<parameter> parm)
22981{get_type()->append_parameter(parm);}
22982
22983/// Append a vector of parameters to the type of this function.
22984///
22985/// @param parms the vector of parameters to append.
22986void
22987function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
22988{
22989 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
22990 i != parms.end();
22991 ++i)
22992 get_type()->append_parameter(*i);
22993}
22994
22995/// Create a new instance of function_decl that is a clone of the
22996/// current one.
22997///
22998/// @return the new clone.
23001{
23003 if (is_member_function(*this))
23004 {
23005 method_decl_sptr
23006 m(new method_decl(get_name(),
23007 get_type(),
23009 get_location(),
23012 get_binding()));
23014 ABG_ASSERT(scope);
23018 get_member_is_static(*this),
23022 f = m;
23023 }
23024 else
23025 {
23026 f.reset(new function_decl(get_name(),
23027 get_type(),
23029 get_location(),
23032 get_binding()));
23034 }
23035 f->set_symbol(get_symbol());
23036
23037 return f;
23038}
23039
23040/// Compares two instances of @ref function_decl.
23041///
23042/// If the two intances are different, set a bitfield to give some
23043/// insight about the kind of differences there are.
23044///
23045/// @param l the first artifact of the comparison.
23046///
23047/// @param r the second artifact of the comparison.
23048///
23049/// @param k a pointer to a bitfield that gives information about the
23050/// kind of changes there are between @p l and @p r. This one is set
23051/// iff @p k is non-null and the function returns false.
23052///
23053/// Please note that setting k to a non-null value does have a
23054/// negative performance impact because even if @p l and @p r are not
23055/// equal, the function keeps up the comparison in order to determine
23056/// the different kinds of ways in which they are different.
23057///
23058/// @return true if @p l equals @p r, false otherwise.
23059bool
23061{
23062 bool result = true;
23063
23064 // Compare function types
23065 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
23066 if (t0 == t1 || *t0 == *t1)
23067 ; // the types are equal, let's move on to compare the other
23068 // properties of the functions.
23069 else
23070 {
23071 result = false;
23072 if (k)
23073 {
23074 if (!types_have_similar_structure(t0, t1))
23076 else
23077 *k |= SUBTYPE_CHANGE_KIND;
23078 }
23079 else
23081 }
23082
23083 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
23084 if (!!s0 != !!s1)
23085 {
23086 result = false;
23087 if (k)
23089 else
23091 }
23092 else if (s0 && s0 != s1)
23093 {
23094 if (!elf_symbols_alias(s0, s1))
23095 {
23096 result = false;
23097 if (k)
23099 else
23101 }
23102 }
23103 bool symbols_are_equal = (s0 && s1 && result);
23104
23105 if (symbols_are_equal)
23106 {
23107 // The functions have underlying elf symbols that are equal,
23108 // so now, let's compare the decl_base part of the functions
23109 // w/o considering their decl names.
23110 interned_string n1 = l.get_name(), n2 = r.get_name();
23112 const_cast<function_decl&>(l).set_name("");
23113 const_cast<function_decl&>(l).set_linkage_name("");
23114 const_cast<function_decl&>(r).set_name("");
23115 const_cast<function_decl&>(r).set_linkage_name("");
23116
23117 bool decl_bases_different = !l.decl_base::operator==(r);
23118
23119 const_cast<function_decl&>(l).set_name(n1);
23120 const_cast<function_decl&>(l).set_linkage_name(ln1);
23121 const_cast<function_decl&>(r).set_name(n2);
23122 const_cast<function_decl&>(r).set_linkage_name(ln2);
23123
23124 if (decl_bases_different)
23125 {
23126 result = false;
23127 if (k)
23129 else
23131 }
23132 }
23133 else
23134 if (!l.decl_base::operator==(r))
23135 {
23136 result = false;
23137 if (k)
23139 else
23141 }
23142
23143 // Compare the remaining properties. Note that we don't take into
23144 // account the fact that the function was declared inline or not as
23145 // that doesn't have any impact on the final ABI.
23146 if (l.get_binding() != r.get_binding())
23147 {
23148 result = false;
23149 if (k)
23151 else
23153 }
23154
23156 {
23157 result = false;
23158 if (k)
23160 else
23162 }
23163
23165 {
23178 {
23179 result = false;
23180 if (k)
23182 else
23184 }
23185 }
23186
23187 ABG_RETURN(result);
23188}
23189
23190/// Comparison operator for @ref function_decl.
23191///
23192/// @param other the other instance of @ref function_decl to compare
23193/// against.
23194///
23195/// @return true iff the current instance of @ref function_decl equals
23196/// @p other.
23197bool
23199{
23200 const function_decl* o = dynamic_cast<const function_decl*>(&other);
23201 if (!o)
23202 return false;
23203 return equals(*this, *o, 0);
23204}
23205
23206/// Return true iff the function takes a variable number of
23207/// parameters.
23208///
23209/// @return true if the function taks a variable number
23210/// of parameters.
23211bool
23213{
23214 return (!get_parameters().empty()
23215 && get_parameters().back()->get_variadic_marker());
23216}
23217
23218/// Return an ID that tries to uniquely identify the function inside a
23219/// program or a library.
23220///
23221/// So if the function has an underlying elf symbol, the ID is the
23222/// concatenation of the symbol name and its version. Otherwise, the
23223/// ID is the linkage name if its non-null. Otherwise, it's the
23224/// pretty representation of the function.
23225///
23226/// @return the ID.
23229{
23230 if (priv_->id_.empty())
23231 {
23232 const environment& env = get_type()->get_environment();
23233 if (elf_symbol_sptr s = get_symbol())
23234 {
23235 string virtual_member_suffix;
23236 if (is_member_function(this))
23237 {
23238 method_decl* m = is_method_decl(this);
23239 ABG_ASSERT(m);
23241 {
23243 (m->get_type()->get_class_type(),
23244 /*look_through_decl_only=*/true))
23245 virtual_member_suffix += "/o";
23246 }
23247 }
23248 if (s->has_aliases())
23249 // The symbol has several aliases, so let's use a scheme
23250 // that allows all aliased functions to have different
23251 // IDs.
23252 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
23253 else
23254 // Let's use the full symbol name with its version as ID.
23255 priv_->id_ = env.intern(s->get_id_string());
23256
23257 if (!virtual_member_suffix.empty())
23258 priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
23259 }
23260 else if (!get_linkage_name().empty())
23261 priv_->id_= env.intern(get_linkage_name());
23262 else
23263 priv_->id_ = env.intern(get_pretty_representation());
23264 }
23265 return priv_->id_;
23266}
23267
23268/// Test if two function declarations are aliases.
23269///
23270/// Two functions declarations are aliases if their symbols are
23271/// aliases, in the ELF sense.
23272///
23273/// @param f1 the first function to consider.
23274///
23275/// @param f2 the second function to consider.
23276///
23277/// @return true iff @p f1 is an alias of @p f2
23278bool
23280{
23281 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
23282
23283 if (!s1 || !s2)
23284 return false;
23285
23286 return elf_symbols_alias(s1, s2);
23287}
23288
23289/// This implements the ir_traversable_base::traverse pure virtual
23290/// function.
23291///
23292/// @param v the visitor used on the current instance.
23293///
23294/// @return true if the entire IR node tree got traversed, false
23295/// otherwise.
23296bool
23298{
23299 if (visiting())
23300 return true;
23301
23302 if (v.visit_begin(this))
23303 {
23304 visiting(true);
23305 if (type_base_sptr t = get_type())
23306 t->traverse(v);
23307 visiting(false);
23308 }
23309 return v.visit_end(this);
23310}
23311
23312/// Destructor of the @ref function_decl type.
23314{delete priv_;}
23315
23316/// A deep comparison operator for a shared pointer to @ref function_decl
23317///
23318/// This function compares to shared pointers to @ref function_decl by
23319/// looking at the pointed-to instances of @ref function_dec
23320/// comparing them too. If the two pointed-to objects are equal then
23321/// this function returns true.
23322///
23323/// @param l the left-hand side argument of the equality operator.
23324///
23325/// @param r the right-hand side argument of the equality operator.
23326///
23327/// @return true iff @p l equals @p r.
23328bool
23330{
23331 if (l.get() == r.get())
23332 return true;
23333 if (!!l != !!r)
23334 return false;
23335
23336 return *l == *r;
23337}
23338
23339/// A deep inequality operator for smart pointers to functions.
23340///
23341/// @param l the left-hand side argument of the inequality operator.
23342///
23343/// @pram r the right-hand side argument of the inequality operator.
23344///
23345/// @return true iff @p is not equal to @p r.
23346bool
23348{return !operator==(l, r);}
23349
23350// <function_decl definitions>
23351
23352// <function_decl::parameter definitions>
23353
23354struct function_decl::parameter::priv
23355{
23356 type_base_wptr type_;
23357 unsigned index_;
23358 bool variadic_marker_;
23359
23360 priv()
23361 : index_(),
23362 variadic_marker_()
23363 {}
23364
23365 priv(type_base_sptr type,
23366 unsigned index,
23367 bool variadic_marker)
23368 : type_(type),
23369 index_(index),
23370 variadic_marker_(variadic_marker)
23371 {}
23372};// end struct function_decl::parameter::priv
23373
23374function_decl::parameter::parameter(const type_base_sptr type,
23375 unsigned index,
23376 const string& name,
23377 const location& loc,
23378 bool is_variadic)
23379 : type_or_decl_base(type->get_environment(),
23380 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23381 decl_base(type->get_environment(), name, loc),
23382 priv_(new priv(type, index, is_variadic))
23383{
23384 runtime_type_instance(this);
23385}
23386
23387function_decl::parameter::parameter(const type_base_sptr type,
23388 unsigned index,
23389 const string& name,
23390 const location& loc,
23391 bool is_variadic,
23392 bool is_artificial)
23393 : type_or_decl_base(type->get_environment(),
23394 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23395 decl_base(type->get_environment(), name, loc),
23396 priv_(new priv(type, index, is_variadic))
23397{
23398 runtime_type_instance(this);
23399 set_is_artificial(is_artificial);
23400}
23401
23402function_decl::parameter::parameter(const type_base_sptr type,
23403 const string& name,
23404 const location& loc,
23405 bool is_variadic,
23406 bool is_artificial)
23407 : type_or_decl_base(type->get_environment(),
23408 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23409 decl_base(type->get_environment(), name, loc),
23410 priv_(new priv(type, 0, is_variadic))
23411{
23412 runtime_type_instance(this);
23413 set_is_artificial(is_artificial);
23414}
23415
23416function_decl::parameter::parameter(const type_base_sptr type,
23417 unsigned index,
23418 bool variad)
23419 : type_or_decl_base(type->get_environment(),
23420 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23421 decl_base(type->get_environment(), "", location()),
23422 priv_(new priv(type, index, variad))
23423{
23424 runtime_type_instance(this);
23425}
23426
23427function_decl::parameter::~parameter() = default;
23428
23429const type_base_sptr
23430function_decl::parameter::get_type()const
23431{return priv_->type_.lock();}
23432
23433/// @return a copy of the type name of the parameter.
23434interned_string
23436{
23437 const environment& env = get_environment();
23438
23439 type_base_sptr t = get_type();
23440 string str;
23441 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
23442 str = "...";
23443 else
23444 {
23445 ABG_ASSERT(t);
23447 }
23448 return env.intern(str);
23449}
23450
23451/// @return a copy of the pretty representation of the type of the
23452/// parameter.
23453const string
23455{
23456 type_base_sptr t = get_type();
23457 string str;
23458 if (get_variadic_marker()
23459 || get_environment().is_variadic_parameter_type(t))
23460 str = "...";
23461 else
23462 {
23463 ABG_ASSERT(t);
23465 }
23466 return str;
23467}
23468
23469/// Get a name uniquely identifying the parameter in the function.
23470///
23471///@return the unique parm name id.
23474{
23475 const environment& env = get_environment();
23476
23477
23478 std::ostringstream o;
23479 o << "parameter-" << get_index();
23480
23481 return env.intern(o.str());
23482}
23483
23484unsigned
23485function_decl::parameter::get_index() const
23486{return priv_->index_;}
23487
23488void
23489function_decl::parameter::set_index(unsigned i)
23490{priv_->index_ = i;}
23491
23492
23493bool
23494function_decl::parameter::get_variadic_marker() const
23495{return priv_->variadic_marker_;}
23496
23497/// Compares two instances of @ref function_decl::parameter.
23498///
23499/// If the two intances are different, set a bitfield to give some
23500/// insight about the kind of differences there are.
23501///
23502/// @param l the first artifact of the comparison.
23503///
23504/// @param r the second artifact of the comparison.
23505///
23506/// @param k a pointer to a bitfield that gives information about the
23507/// kind of changes there are between @p l and @p r. This one is set
23508/// iff @p k is non-null and the function returns false.
23509///
23510/// Please note that setting k to a non-null value does have a
23511/// negative performance impact because even if @p l and @p r are not
23512/// equal, the function keeps up the comparison in order to determine
23513/// the different kinds of ways in which they are different.
23514///
23515/// @return true if @p l equals @p r, false otherwise.
23516bool
23518 const function_decl::parameter& r,
23519 change_kind* k)
23520{
23521 bool result = true;
23522
23523 if ((l.get_variadic_marker() != r.get_variadic_marker())
23524 || (l.get_index() != r.get_index())
23525 || (!!l.get_type() != !!r.get_type()))
23526 {
23527 result = false;
23528 if (k)
23529 {
23530 if (l.get_index() != r.get_index())
23532 if (l.get_variadic_marker() != r.get_variadic_marker()
23533 || !!l.get_type() != !!r.get_type())
23535 }
23536 else
23538 }
23539
23540 type_base_sptr l_type = l.get_type();
23541 type_base_sptr r_type = r.get_type();
23542
23543 if (l_type != r_type)
23544 {
23545 result = false;
23546 if (k)
23547 {
23548 if (!types_have_similar_structure(l_type, r_type))
23550 else
23551 *k |= SUBTYPE_CHANGE_KIND;
23552 }
23553 else
23555 }
23556
23557 ABG_RETURN(result);
23558}
23559
23560bool
23561function_decl::parameter::operator==(const parameter& o) const
23562{return equals(*this, o, 0);}
23563
23564bool
23565function_decl::parameter::operator==(const decl_base& o) const
23566{
23567 const function_decl::parameter* p =
23568 dynamic_cast<const function_decl::parameter*>(&o);
23569 if (!p)
23570 return false;
23571 return function_decl::parameter::operator==(*p);
23572}
23573
23574/// Non-member equality operator for @ref function_decl::parameter.
23575///
23576/// @param l the left-hand side of the equality operator
23577///
23578/// @param r the right-hand side of the equality operator
23579///
23580/// @return true iff @p l and @p r equals.
23581bool
23584{
23585 if (!!l != !!r)
23586 return false;
23587 if (!l)
23588 return true;
23589 return *l == *r;
23590}
23591
23592/// Non-member inequality operator for @ref function_decl::parameter.
23593///
23594/// @param l the left-hand side of the equality operator
23595///
23596/// @param r the right-hand side of the equality operator
23597///
23598/// @return true iff @p l and @p r different.
23599bool
23602{return !operator==(l, r);}
23603
23604/// Traverse the diff sub-tree under the current instance
23605/// function_decl.
23606///
23607/// @param v the visitor to invoke on each diff node of the sub-tree.
23608///
23609/// @return true if the traversing has to keep going on, false
23610/// otherwise.
23611bool
23613{
23614 if (visiting())
23615 return true;
23616
23617 if (v.visit_begin(this))
23618 {
23619 visiting(true);
23620 if (type_base_sptr t = get_type())
23621 t->traverse(v);
23622 visiting(false);
23623 }
23624 return v.visit_end(this);
23625}
23626
23627/// Compute the qualified name of the parameter.
23628///
23629/// @param internal set to true if the call is intended for an
23630/// internal use (for technical use inside the library itself), false
23631/// otherwise. If you don't know what this is for, then set it to
23632/// false.
23633///
23634/// @param qn the resulting qualified name.
23635void
23637 bool /*internal*/) const
23638{qualified_name = get_name();}
23639
23640/// Compute and return a copy of the pretty representation of the
23641/// current function parameter.
23642///
23643/// @param internal set to true if the call is intended to get a
23644/// representation of the decl (or type) for the purpose of canonical
23645/// type comparison. This is mainly used in the function
23646/// type_base::get_canonical_type_for().
23647///
23648/// In other words if the argument for this parameter is true then the
23649/// call is meant for internal use (for technical use inside the
23650/// library itself), false otherwise. If you don't know what this is
23651/// for, then set it to false.
23652///
23653/// @return a copy of the textual representation of the current
23654/// function parameter.
23655string
23657 bool qualified_name) const
23658{
23659 const environment& env = get_environment();
23660
23661 string type_repr;
23662 type_base_sptr t = get_type();
23663 if (!t)
23664 type_repr = "void";
23665 else if (env.is_variadic_parameter_type(t))
23666 type_repr = "...";
23667 else
23668 type_repr = ir::get_type_name(t, qualified_name, internal);
23669
23670 string result = type_repr;
23671 string parm_name = get_name_id();
23672
23673 if (!parm_name.empty())
23674 result += " " + parm_name;
23675
23676 return result;
23677}
23678
23679// </function_decl::parameter definitions>
23680
23681// <class_or_union definitions>
23682
23683/// A Constructor for instances of @ref class_or_union
23684///
23685/// @param env the environment we are operating from.
23686///
23687/// @param name the identifier of the class.
23688///
23689/// @param size_in_bits the size of an instance of @ref
23690/// class_or_union, expressed in bits
23691///
23692/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23693/// expressed in bits.
23694///
23695/// @param locus the source location of declaration point this class.
23696///
23697/// @param vis the visibility of instances of @ref class_or_union.
23698///
23699/// @param mem_types the vector of member types of this instance of
23700/// @ref class_or_union.
23701///
23702/// @param data_members the vector of data members of this instance of
23703/// @ref class_or_union.
23704///
23705/// @param member_fns the vector of member functions of this instance
23706/// of @ref class_or_union.
23707class_or_union::class_or_union(const environment& env, const string& name,
23708 size_t size_in_bits, size_t align_in_bits,
23709 const location& locus, visibility vis,
23710 member_types& mem_types,
23712 member_functions& member_fns)
23713 : type_or_decl_base(env,
23714 ABSTRACT_TYPE_BASE
23715 | ABSTRACT_DECL_BASE
23716 | ABSTRACT_SCOPE_TYPE_DECL
23717 | ABSTRACT_SCOPE_DECL),
23718 decl_base(env, name, locus, name, vis),
23719 type_base(env, size_in_bits, align_in_bits),
23720 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23721 priv_(new priv(data_members, member_fns))
23722{
23723 for (member_types::iterator i = mem_types.begin();
23724 i != mem_types.end();
23725 ++i)
23728
23729 for (data_members::iterator i = data_members.begin();
23730 i != data_members.end();
23731 ++i)
23732 if (!has_scope(*i))
23733 add_decl_to_scope(*i, this);
23734
23735 for (member_functions::iterator i = member_fns.begin();
23736 i != member_fns.end();
23737 ++i)
23738 if (!has_scope(static_pointer_cast<decl_base>(*i)))
23739 add_decl_to_scope(*i, this);
23740}
23741
23742/// A constructor for instances of @ref class_or_union.
23743///
23744/// @param env the environment we are operating from.
23745///
23746/// @param name the name of the class.
23747///
23748/// @param size_in_bits the size of an instance of @ref
23749/// class_or_union, expressed in bits
23750///
23751/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23752/// expressed in bits.
23753///
23754/// @param locus the source location of declaration point this class.
23755///
23756/// @param vis the visibility of instances of @ref class_or_union.
23757class_or_union::class_or_union(const environment& env, const string& name,
23758 size_t size_in_bits, size_t align_in_bits,
23759 const location& locus, visibility vis)
23760 : type_or_decl_base(env,
23761 ABSTRACT_TYPE_BASE
23762 | ABSTRACT_DECL_BASE
23763 | ABSTRACT_SCOPE_TYPE_DECL
23764 | ABSTRACT_SCOPE_DECL),
23765 decl_base(env, name, locus, name, vis),
23766 type_base(env, size_in_bits, align_in_bits),
23767 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23768 priv_(new priv)
23769{}
23770
23771/// Constructor of the @ref class_or_union type.
23772///
23773/// @param env the @ref environment we are operating from.
23774///
23775/// @param name the name of the @ref class_or_union.
23776///
23777/// @param is_declaration_only a boolean saying whether the instance
23778/// represents a declaration only, or not.
23779class_or_union::class_or_union(const environment& env, const string& name,
23780 bool is_declaration_only)
23781 : type_or_decl_base(env,
23782 ABSTRACT_TYPE_BASE
23783 | ABSTRACT_DECL_BASE
23784 | ABSTRACT_SCOPE_TYPE_DECL
23785 | ABSTRACT_SCOPE_DECL),
23786 decl_base(env, name, location(), name),
23787 type_base(env, 0, 0),
23788 scope_type_decl(env, name, 0, 0, location()),
23789 priv_(new priv)
23790{
23791 set_is_declaration_only(is_declaration_only);
23792}
23793
23794/// Return the hash value of the current IR node.
23795///
23796/// Note that upon the first invocation, this member functions
23797/// computes the hash value and returns it. Subsequent invocations
23798/// just return the hash value that was previously calculated.
23799///
23800/// @return the hash value of the current IR node.
23801hash_t
23803{
23804 class_or_union::hash do_hash;
23805 hash_t h = do_hash(this);
23806 return h;
23807}
23808
23809/// This implements the ir_traversable_base::traverse pure virtual
23810/// function.
23811///
23812/// @param v the visitor used on the member nodes of the translation
23813/// unit during the traversal.
23814///
23815/// @return true if the entire IR node tree got traversed, false
23816/// otherwise.
23817bool
23819{
23820 if (v.type_node_has_been_visited(this))
23821 return true;
23822
23823 if (visiting())
23824 return true;
23825
23826 if (v.visit_begin(this))
23827 {
23828 visiting(true);
23829 bool stop = false;
23830
23831 if (!stop)
23832 for (data_members::const_iterator i = get_data_members().begin();
23833 i != get_data_members().end();
23834 ++i)
23835 if (!(*i)->traverse(v))
23836 {
23837 stop = true;
23838 break;
23839 }
23840
23841 if (!stop)
23842 for (member_functions::const_iterator i= get_member_functions().begin();
23843 i != get_member_functions().end();
23844 ++i)
23845 if (!(*i)->traverse(v))
23846 {
23847 stop = true;
23848 break;
23849 }
23850
23851 if (!stop)
23852 for (member_types::const_iterator i = get_member_types().begin();
23853 i != get_member_types().end();
23854 ++i)
23855 if (!(*i)->traverse(v))
23856 {
23857 stop = true;
23858 break;
23859 }
23860
23861 if (!stop)
23862 for (member_function_templates::const_iterator i =
23864 i != get_member_function_templates().end();
23865 ++i)
23866 if (!(*i)->traverse(v))
23867 {
23868 stop = true;
23869 break;
23870 }
23871
23872 if (!stop)
23873 for (member_class_templates::const_iterator i =
23875 i != get_member_class_templates().end();
23876 ++i)
23877 if (!(*i)->traverse(v))
23878 {
23879 stop = true;
23880 break;
23881 }
23882 visiting(false);
23883 }
23884
23885 bool result = v.visit_end(this);
23887 return result;
23888}
23889
23890/// Destrcutor of the @ref class_or_union type.
23892{delete priv_;}
23893
23894/// Add a member declaration to the current instance of class_or_union.
23895/// The member declaration can be either a member type, data member,
23896/// member function, or member template.
23897///
23898/// @param d the member declaration to add.
23899decl_base_sptr
23900class_or_union::add_member_decl(const decl_base_sptr& d)
23901{return insert_member_decl(d);}
23902
23903/// Remove a given decl from the current @ref class_or_union scope.
23904///
23905/// Note that only type declarations are supported by this method for
23906/// now. Support for the other kinds of declaration is left as an
23907/// exercise for the interested reader of the code.
23908///
23909/// @param decl the declaration to remove from this @ref
23910/// class_or_union scope.
23911void
23913{
23914 type_base_sptr t = is_type(decl);
23915
23916 // For now we want to support just removing types from classes. For
23917 // other kinds of IR node, we need more work.
23918 ABG_ASSERT(t);
23919
23921}
23922
23923/// Fixup the members of the type of an anonymous data member.
23924///
23925/// Walk all data members of (the type of) a given anonymous data
23926/// member and set a particular property of the relationship between
23927/// each data member and its containing type.
23928///
23929/// That property records the fact that the data member belongs to the
23930/// anonymous data member we consider.
23931///
23932/// In the future, if there are other properties of this relationship
23933/// to set in this manner, they ought to be added here.
23934///
23935/// @param anon_dm the anonymous data member to consider.
23936void
23938{
23939 class_or_union * anon_dm_type =
23941 if (!anon_dm_type)
23942 return;
23943
23944 for (class_or_union::data_members::const_iterator it =
23945 anon_dm_type->get_non_static_data_members().begin();
23946 it != anon_dm_type->get_non_static_data_members().end();
23947 ++it)
23948 {
23949 dm_context_rel *rel =
23950 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
23951 ABG_ASSERT(rel);
23952 rel->set_anonymous_data_member(anon_dm.get());
23953 }
23954}
23955
23956/// Getter of the alignment of the @ref class_or_union type.
23957///
23958/// If this @ref class_or_union is a declaration of a definition that
23959/// is elsewhere, then the size of the definition is returned.
23960///
23961/// @return the alignment of the @ref class_or_union type.
23962size_t
23964{
23968
23970}
23971
23972/// Setter of the alignment of the class type.
23973///
23974/// If this class is a declaration of a definition that is elsewhere,
23975/// then the new alignment is set to the definition.
23976///
23977/// @param s the new alignment.
23978void
23980{
23984 else
23986}
23987
23988/// Setter of the size of the @ref class_or_union type.
23989///
23990/// If this @ref class_or_union is a declaration of a definition that
23991/// is elsewhere, then the new size is set to the definition.
23992///
23993/// @param s the new size.
23994void
23996{
24000 else
24002}
24003
24004/// Getter of the size of the @ref class_or_union type.
24005///
24006/// If this @ref class_or_union is a declaration of a definition that
24007/// is elsewhere, then the size of the definition is returned.
24008///
24009/// @return the size of the @ref class_or_union type.
24010size_t
24012{
24016
24018}
24019
24020/// Get the number of anonymous member classes contained in this
24021/// class.
24022///
24023/// @return the number of anonymous member classes contained in this
24024/// class.
24025size_t
24027{
24028 int result = 0;
24029 for (member_types::const_iterator it = get_member_types().begin();
24030 it != get_member_types().end();
24031 ++it)
24032 if (class_decl_sptr t = is_class_type(*it))
24033 if (t->get_is_anonymous())
24034 ++result;
24035
24036 return result;
24037}
24038
24039/// Get the number of anonymous member unions contained in this class.
24040///
24041/// @return the number of anonymous member unions contained in this
24042/// class.
24043size_t
24045{
24046 int result = 0;
24047 for (member_types::const_iterator it = get_member_types().begin();
24048 it != get_member_types().end();
24049 ++it)
24050 if (union_decl_sptr t = is_union_type(*it))
24051 if (t->get_is_anonymous())
24052 ++result;
24053
24054 return result;
24055}
24056
24057/// Get the number of anonymous member enums contained in this class.
24058///
24059/// @return the number of anonymous member enums contained in this
24060/// class.
24061size_t
24063{
24064 int result = 0;
24065 for (member_types::const_iterator it = get_member_types().begin();
24066 it != get_member_types().end();
24067 ++it)
24068 if (enum_type_decl_sptr t = is_enum_type(*it))
24069 if (t->get_is_anonymous())
24070 ++result;
24071
24072 return result;
24073}
24074
24075/// Add a data member to the current instance of class_or_union.
24076///
24077/// @param v a var_decl to add as a data member. A proper
24078/// class_or_union::data_member is created from @p v and added to the
24079/// class_or_union. This var_decl should not have been already added
24080/// to a scope.
24081///
24082/// @param access the access specifier for the data member.
24083///
24084/// @param is_laid_out whether the data member was laid out. That is,
24085/// if its offset has been computed. In the pattern of a class
24086/// template for instance, this would be set to false.
24087///
24088/// @param is_static whether the data memer is static.
24089///
24090/// @param offset_in_bits if @p is_laid_out is true, this is the
24091/// offset of the data member, expressed (oh, surprise) in bits.
24092void
24094 bool is_laid_out, bool is_static,
24095 size_t offset_in_bits)
24096{
24097 ABG_ASSERT(!has_scope(v));
24098
24099 priv_->data_members_.push_back(v);
24101 set_data_member_is_laid_out(v, is_laid_out);
24102 set_data_member_offset(v, offset_in_bits);
24103 set_member_access_specifier(v, access);
24104 set_member_is_static(v, is_static);
24105
24106 // Add the variable to the set of static or non-static data members,
24107 // if it's not already in there.
24108 bool is_already_in = false;
24109 if (is_static)
24110 {
24111 for (const auto& s_dm: priv_->static_data_members_)
24112 {
24113 if (s_dm == v)
24114 {
24115 is_already_in = true;
24116 break;
24117 }
24118 }
24119 if (!is_already_in)
24120 priv_->static_data_members_.push_back(v);
24121 }
24122 else
24123 {
24124 // If this is a non-static variable, add it to the set of
24125 // non-static variables, if it's not already in there.
24126 for (data_members::const_iterator i =
24127 priv_->non_static_data_members_.begin();
24128 i != priv_->non_static_data_members_.end();
24129 ++i)
24130 if (*i == v)
24131 {
24132 is_already_in = true;
24133 break;
24134 }
24135 if (!is_already_in)
24136 priv_->non_static_data_members_.push_back(v);
24137 }
24138
24139 // If v is an anonymous data member, then fixup its data members.
24140 // For now, the only thing the fixup does is to make the data
24141 // members of the anonymous data member be aware of their containing
24142 // anonymous data member. That is helpful to compute the absolute
24143 // bit offset of each of the members of the anonymous data member.
24145}
24146
24147/// Get the data members of this @ref class_or_union.
24148///
24149/// @return a vector of the data members of this @ref class_or_union.
24152{return priv_->data_members_;}
24153
24154/// Find a data member of a given name in the current @ref class_or_union.
24155///
24156/// @param name the name of the data member to find in the current
24157/// @ref class_or_union.
24158///
24159/// @return a pointer to the @ref var_decl that represents the data
24160/// member to find inside the current @ref class_or_union.
24161const var_decl_sptr
24162class_or_union::find_data_member(const string& name) const
24163{
24164 for (data_members::const_iterator i = get_data_members().begin();
24165 i != get_data_members().end();
24166 ++i)
24167 if ((*i)->get_name() == name)
24168 return *i;
24169
24170 // We haven't found a data member with the name 'name'. Let's look
24171 // closer again, this time in our anonymous data members.
24172 for (data_members::const_iterator i = get_data_members().begin();
24173 i != get_data_members().end();
24174 ++i)
24176 {
24177 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
24178 ABG_ASSERT(type);
24179 if (var_decl_sptr data_member = type->find_data_member(name))
24180 return data_member;
24181 }
24182
24183 return var_decl_sptr();
24184}
24185
24186/// Find an anonymous data member in the class.
24187///
24188/// @param v the anonymous data member to find.
24189///
24190/// @return the anonymous data member found, or nil if none was found.
24191const var_decl_sptr
24193{
24194 if (!v->get_name().empty())
24195 return var_decl_sptr();
24196
24197 for (data_members::const_iterator it = get_non_static_data_members().begin();
24198 it != get_non_static_data_members().end();
24199 ++it)
24200 {
24201 if (is_anonymous_data_member(*it))
24202 if ((*it)->get_pretty_representation(/*internal=*/false, true)
24203 == v->get_pretty_representation(/*internal=*/false, true))
24204 return *it;
24205 }
24206
24207 return var_decl_sptr();
24208}
24209
24210/// Find a given data member.
24211///
24212/// This function takes a @ref var_decl as an argument. If it has a
24213/// non-empty name, then it tries to find a data member which has the
24214/// same name as the argument.
24215///
24216/// If it has an empty name, then the @ref var_decl is considered as
24217/// an anonymous data member. In that case, this function tries to
24218/// find an anonymous data member which type equals that of the @ref
24219/// var_decl argument.
24220///
24221/// @param v this carries either the name of the data member we need
24222/// to look for, or the type of the anonymous data member we are
24223/// looking for.
24224const var_decl_sptr
24226{
24227 if (!v)
24228 return var_decl_sptr();
24229
24230 if (v->get_name().empty())
24232
24233 return find_data_member(v->get_name());
24234}
24235
24236
24237/// Get the non-static data members of this @ref class_or_union.
24238///
24239/// @return a vector of the non-static data members of this @ref
24240/// class_or_union.
24243{return priv_->non_static_data_members_;}
24244
24245/// Get the static data memebers of this @ref class_or_union.
24246///
24247/// @return a vector of the static data members of this @ref
24248/// class_or_union.
24251{return priv_->static_data_members_;}
24252
24253/// Add a member function.
24254///
24255/// @param f the new member function to add.
24256///
24257/// @param a the access specifier to use for the new member function.
24258///
24259/// @param is_static whether the new member function is static.
24260///
24261/// @param is_ctor whether the new member function is a constructor.
24262///
24263/// @param is_dtor whether the new member function is a destructor.
24264///
24265/// @param is_const whether the new member function is const.
24266void
24269 bool is_static, bool is_ctor,
24270 bool is_dtor, bool is_const)
24271{
24272 ABG_ASSERT(!has_scope(f));
24273
24275
24276 set_member_function_is_ctor(f, is_ctor);
24277 set_member_function_is_dtor(f, is_dtor);
24279 set_member_is_static(f, is_static);
24280 set_member_function_is_const(f, is_const);
24281
24282 priv_->member_functions_.push_back(f);
24283
24284 // Update the map of linkage name -> member functions. It's useful,
24285 // so that class_or_union::find_member_function() can function.
24286 if (!f->get_linkage_name().empty())
24287 priv_->mem_fns_map_[f->get_linkage_name()] = f;
24288}
24289
24290/// Get the member functions of this @ref class_or_union.
24291///
24292/// @return a vector of the member functions of this @ref
24293/// class_or_union.
24296{return priv_->member_functions_;}
24297
24298/// Find a method, using its linkage name as a key.
24299///
24300/// @param linkage_name the linkage name of the method to find.
24301///
24302/// @return the method found, or nil if none was found.
24303const method_decl*
24304class_or_union::find_member_function(const string& linkage_name) const
24305{
24306 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
24307}
24308
24309/// Find a method, using its linkage name as a key.
24310///
24311/// @param linkage_name the linkage name of the method to find.
24312///
24313/// @return the method found, or nil if none was found.
24315class_or_union::find_member_function(const string& linkage_name)
24316{
24317 string_mem_fn_sptr_map_type::const_iterator i =
24318 priv_->mem_fns_map_.find(linkage_name);
24319 if (i == priv_->mem_fns_map_.end())
24320 return 0;
24321 return i->second.get();
24322}
24323
24324/// Find a method, using its linkage name as a key.
24325///
24326/// @param linkage_name the linkage name of the method to find.
24327///
24328/// @return the method found, or nil if none was found.
24329method_decl_sptr
24331{
24332 string_mem_fn_sptr_map_type::const_iterator i =
24333 priv_->mem_fns_map_.find(linkage_name);
24334 if (i == priv_->mem_fns_map_.end())
24335 return 0;
24336 return i->second;
24337}
24338
24339/// Find a method (member function) using its signature (pretty
24340/// representation) as a key.
24341///
24342/// @param s the signature of the method.
24343///
24344/// @return the method found, or nil if none was found.
24345const method_decl*
24347{
24348 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
24349}
24350
24351/// Find a method (member function) using its signature (pretty
24352/// representation) as a key.
24353///
24354/// @param s the signature of the method.
24355///
24356/// @return the method found, or nil if none was found.
24359{
24360 string_mem_fn_ptr_map_type::const_iterator i =
24361 priv_->signature_2_mem_fn_map_.find(s);
24362 if (i == priv_->signature_2_mem_fn_map_.end())
24363 return 0;
24364 return i->second;
24365}
24366
24367/// Get the member function templates of this class.
24368///
24369/// @return a vector of the member function templates of this class.
24370const member_function_templates&
24372{return priv_->member_function_templates_;}
24373
24374/// Get the member class templates of this class.
24375///
24376/// @return a vector of the member class templates of this class.
24377const member_class_templates&
24379{return priv_->member_class_templates_;}
24380
24381/// Append a member function template to the @ref class_or_union.
24382///
24383/// @param m the member function template to append.
24384void
24385class_or_union::add_member_function_template(member_function_template_sptr m)
24386{
24387 decl_base* c = m->as_function_tdecl()->get_scope();
24388 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24389 /// error message or something like a structured error.
24390 priv_->member_function_templates_.push_back(m);
24391 if (!c)
24392 scope_decl::add_member_decl(m->as_function_tdecl());
24393}
24394
24395/// Append a member class template to the @ref class_or_union.
24396///
24397/// @param m the member function template to append.
24398void
24400{
24401 decl_base* c = m->as_class_tdecl()->get_scope();
24402 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24403 /// error message or something like a structured error.
24404 m->set_scope(this);
24405 priv_->member_class_templates_.push_back(m);
24406 if (!c)
24407 scope_decl::add_member_decl(m->as_class_tdecl());
24408}
24409
24410///@return true iff the current instance has no member.
24411bool
24413{
24414 return (get_member_types().empty()
24415 && priv_->data_members_.empty()
24416 && priv_->member_functions_.empty()
24417 && priv_->member_function_templates_.empty()
24418 && priv_->member_class_templates_.empty());
24419}
24420
24421/// Insert a data member to this @ref class_or_union type.
24422///
24423/// @param d the data member to insert.
24424///
24425/// @return the decl @p that got inserted.
24426decl_base_sptr
24428{
24429 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
24430 {
24431 add_data_member(v, public_access,
24432 /*is_laid_out=*/false,
24433 /*is_static=*/true,
24434 /*offset_in_bits=*/0);
24435 d = v;
24436 }
24437 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24438 add_member_function(f, public_access,
24439 /*is_static=*/false,
24440 /*is_ctor=*/false,
24441 /*is_dtor=*/false,
24442 /*is_const=*/false);
24443 else if (member_function_template_sptr f =
24444 dynamic_pointer_cast<member_function_template>(d))
24446 else if (member_class_template_sptr c =
24447 dynamic_pointer_cast<member_class_template>(d))
24449 else
24451
24452 return d;
24453}
24454
24455/// Equality operator.
24456///
24457/// @param other the other @ref class_or_union to compare against.
24458///
24459/// @return true iff @p other equals the current @ref class_or_union.
24460bool
24462{
24463 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
24464 if (!op)
24465 return false;
24466
24467 // If this is a decl-only type (and thus with no canonical type),
24468 // use the canonical type of the definition, if any.
24469 const class_or_union *l = 0;
24471 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
24472 if (l == 0)
24473 l = this;
24474
24475 // Likewise for the other class.
24476 const class_or_union *r = 0;
24477 if (op->get_is_declaration_only())
24478 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
24479 if (r == 0)
24480 r = op;
24481
24482 return try_canonical_compare(l, r);
24483}
24484
24485/// Equality operator.
24486///
24487/// @param other the other @ref class_or_union to compare against.
24488///
24489/// @return true iff @p other equals the current @ref class_or_union.
24490bool
24492{
24493 const decl_base* o = dynamic_cast<const decl_base*>(&other);
24494 if (!o)
24495 return false;
24496 return *this == *o;
24497}
24498
24499/// Equality operator.
24500///
24501/// @param other the other @ref class_or_union to compare against.
24502///
24503/// @return true iff @p other equals the current @ref class_or_union.
24504bool
24506{
24507 const decl_base& o = other;
24509}
24510
24511/// Compares two instances of @ref class_or_union.
24512///
24513/// If the two intances are different, set a bitfield to give some
24514/// insight about the kind of differences there are.
24515///
24516/// @param l the first artifact of the comparison.
24517///
24518/// @param r the second artifact of the comparison.
24519///
24520/// @param k a pointer to a bitfield that gives information about the
24521/// kind of changes there are between @p l and @p r. This one is set
24522/// iff it's non-null and if the function returns false.
24523///
24524/// Please note that setting k to a non-null value does have a
24525/// negative performance impact because even if @p l and @p r are not
24526/// equal, the function keeps up the comparison in order to determine
24527/// the different kinds of ways in which they are different.
24528///
24529/// @return true if @p l equals @p r, false otherwise.
24530bool
24532{
24533 // if one of the classes is declaration-only, look through it to
24534 // get its definition.
24535 bool l_is_decl_only = l.get_is_declaration_only();
24536 bool r_is_decl_only = r.get_is_declaration_only();
24537 if (l_is_decl_only || r_is_decl_only)
24538 {
24539 const class_or_union* def1 = l_is_decl_only
24541 : &l;
24542
24543 const class_or_union* def2 = r_is_decl_only
24545 : &r;
24546
24547 if (!def1 || !def2)
24548 {
24549 if (!l.get_is_anonymous()
24550 && !r.get_is_anonymous()
24551 && l_is_decl_only && r_is_decl_only
24553 // The two decl-only classes differ from their size. A
24554 // true decl-only class should not have a size property to
24555 // begin with. This comes from a DWARF oddity and can
24556 // results in a false positive, so let's not consider that
24557 // change.
24558 return true;
24559
24563 {
24564 const interned_string& q1 = l.get_scoped_name();
24565 const interned_string& q2 = r.get_scoped_name();
24566 if (q1 == q2)
24567 // Not using RETURN(true) here, because that causes
24568 // performance issues. We don't need to do
24569 // l.priv_->unmark_as_being_compared({l,r}) here because
24570 // we haven't marked l or r as being compared yet, and
24571 // doing so has a peformance cost that shows up on
24572 // performance profiles for *big* libraries.
24573 return true;
24574 else
24575 {
24576 if (k)
24578 // Not using RETURN(true) here, because that causes
24579 // performance issues. We don't need to do
24580 // l.priv_->unmark_as_being_compared({l,r}) here because
24581 // we haven't marked l or r as being compared yet, and
24582 // doing so has a peformance cost that shows up on
24583 // performance profiles for *big* libraries.
24585 }
24586 }
24587 else // A decl-only class is considered different from a
24588 // class definition of the same name.
24589 {
24590 if (!!def1 != !!def2)
24591 {
24592 if (k)
24595 }
24596
24597 // both definitions are empty
24598 if (!(l.decl_base::operator==(r)
24599 && l.type_base::operator==(r)))
24600 {
24601 if (k)
24604 }
24605
24606 return true;
24607 }
24608 }
24609
24610 bool val = *def1 == *def2;
24611 if (!val)
24612 if (k)
24614 ABG_RETURN(val);
24615 }
24616
24617 // No need to go further if the classes have different names or
24618 // different size / alignment.
24619 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
24620 {
24621 if (k)
24624 }
24625
24626 if (types_defined_same_linux_kernel_corpus_public(l, r))
24627 return true;
24628
24629 //TODO: Maybe remove this (cycle detection and canonical type
24630 //propagation handling) from here and have it only in the equal
24631 //overload for class_decl and union_decl because this one ( the
24632 //equal overload for class_or_union) is just a sub-routine of these
24633 //two above.
24634#define RETURN(value) \
24635 return return_comparison_result(l, r, value);
24636
24638
24640
24641 bool result = true;
24642
24643 //compare data_members
24644 {
24645 if (l.get_non_static_data_members().size()
24646 != r.get_non_static_data_members().size())
24647 {
24648 result = false;
24649 if (k)
24651 else
24652 RETURN(result);
24653 }
24654
24655 for (class_or_union::data_members::const_iterator
24656 d0 = l.get_non_static_data_members().begin(),
24657 d1 = r.get_non_static_data_members().begin();
24658 (d0 != l.get_non_static_data_members().end()
24659 && d1 != r.get_non_static_data_members().end());
24660 ++d0, ++d1)
24661 if (**d0 != **d1)
24662 {
24663 result = false;
24664 if (k)
24665 {
24666 // Report any representation change as being local.
24667 if (!types_have_similar_structure((*d0)->get_type(),
24668 (*d1)->get_type())
24669 || (*d0)->get_type() == (*d1)->get_type())
24671 else
24672 *k |= SUBTYPE_CHANGE_KIND;
24673 }
24674 else
24675 RETURN(result);
24676 }
24677 }
24678
24679 // Do not compare member functions. DWARF does not necessarily
24680 // all the member functions, be they virtual or not, in all
24681 // translation units. So we cannot have a clear view of them, per
24682 // class
24683
24684 // compare member function templates
24685 {
24686 if (l.get_member_function_templates().size()
24687 != r.get_member_function_templates().size())
24688 {
24689 result = false;
24690 if (k)
24692 else
24693 RETURN(result);
24694 }
24695
24696 for (member_function_templates::const_iterator
24697 fn_tmpl_it0 = l.get_member_function_templates().begin(),
24698 fn_tmpl_it1 = r.get_member_function_templates().begin();
24699 fn_tmpl_it0 != l.get_member_function_templates().end()
24700 && fn_tmpl_it1 != r.get_member_function_templates().end();
24701 ++fn_tmpl_it0, ++fn_tmpl_it1)
24702 if (**fn_tmpl_it0 != **fn_tmpl_it1)
24703 {
24704 result = false;
24705 if (k)
24706 {
24708 break;
24709 }
24710 else
24711 RETURN(result);
24712 }
24713 }
24714
24715 // compare member class templates
24716 {
24717 if (l.get_member_class_templates().size()
24718 != r.get_member_class_templates().size())
24719 {
24720 result = false;
24721 if (k)
24723 else
24724 RETURN(result);
24725 }
24726
24727 for (member_class_templates::const_iterator
24728 cl_tmpl_it0 = l.get_member_class_templates().begin(),
24729 cl_tmpl_it1 = r.get_member_class_templates().begin();
24730 cl_tmpl_it0 != l.get_member_class_templates().end()
24731 && cl_tmpl_it1 != r.get_member_class_templates().end();
24732 ++cl_tmpl_it0, ++cl_tmpl_it1)
24733 if (**cl_tmpl_it0 != **cl_tmpl_it1)
24734 {
24735 result = false;
24736 if (k)
24737 {
24739 break;
24740 }
24741 else
24742 RETURN(result);
24743 }
24744 }
24745
24746 RETURN(result);
24747#undef RETURN
24748}
24749
24750
24751/// Copy a method of a @ref class_or_union into a new @ref
24752/// class_or_union.
24753///
24754/// @param t the @ref class_or_union into which the method is to be copied.
24755///
24756/// @param method the method to copy into @p t.
24757///
24758/// @return the resulting newly copied method.
24759method_decl_sptr
24760copy_member_function(const class_or_union_sptr& t,
24761 const method_decl_sptr& method)
24762{return copy_member_function(t, method.get());}
24763
24764
24765/// Copy a method of a @ref class_or_union into a new @ref
24766/// class_or_union.
24767///
24768/// @param t the @ref class_or_union into which the method is to be copied.
24769///
24770/// @param method the method to copy into @p t.
24771///
24772/// @return the resulting newly copied method.
24773method_decl_sptr
24774copy_member_function(const class_or_union_sptr& t, const method_decl* method)
24775{
24776 ABG_ASSERT(t);
24777 ABG_ASSERT(method);
24778
24779 method_type_sptr old_type = method->get_type();
24780 ABG_ASSERT(old_type);
24781 method_type_sptr new_type(new method_type(old_type->get_return_type(),
24782 t,
24783 old_type->get_parameters(),
24784 old_type->get_is_const(),
24785 old_type->get_size_in_bits(),
24786 old_type->get_alignment_in_bits()));
24787 t->get_translation_unit()->bind_function_type_life_time(new_type);
24788
24789 method_decl_sptr
24790 new_method(new method_decl(method->get_name(),
24791 new_type,
24792 method->is_declared_inline(),
24793 method->get_location(),
24794 method->get_linkage_name(),
24795 method->get_visibility(),
24796 method->get_binding()));
24797 new_method->set_symbol(method->get_symbol());
24798
24799 if (class_decl_sptr class_type = is_class_type(t))
24800 class_type->add_member_function(new_method,
24804 get_member_is_static(*method),
24808 else
24809 t->add_member_function(new_method,
24811 get_member_is_static(*method),
24815 return new_method;
24816}
24817
24818// </class_or_union definitions>
24819
24820// <class_decl definitions>
24821
24822static void
24823sort_virtual_member_functions(class_decl::member_functions& mem_fns);
24824
24825/// The private data for the class_decl type.
24826struct class_decl::priv
24827{
24828 base_specs bases_;
24829 unordered_map<string, base_spec_sptr> bases_map_;
24830 member_functions virtual_mem_fns_;
24831 virtual_mem_fn_map_type virtual_mem_fns_map_;
24832 bool is_struct_;
24833
24834 priv()
24835 : is_struct_(false)
24836 {}
24837
24838 priv(bool is_struct, class_decl::base_specs& bases)
24839 : bases_(bases),
24840 is_struct_(is_struct)
24841 {
24842 }
24843
24844 priv(bool is_struct)
24845 : is_struct_(is_struct)
24846 {}
24847};// end struct class_decl::priv
24848
24849/// A Constructor for instances of \ref class_decl
24850///
24851/// @param env the environment we are operating from.
24852///
24853/// @param name the identifier of the class.
24854///
24855/// @param size_in_bits the size of an instance of class_decl, expressed
24856/// in bits
24857///
24858/// @param align_in_bits the alignment of an instance of class_decl,
24859/// expressed in bits.
24860///
24861/// @param locus the source location of declaration point this class.
24862///
24863/// @param vis the visibility of instances of class_decl.
24864///
24865/// @param bases the vector of base classes for this instance of class_decl.
24866///
24867/// @param mbrs the vector of member types of this instance of
24868/// class_decl.
24869///
24870/// @param data_mbrs the vector of data members of this instance of
24871/// class_decl.
24872///
24873/// @param mbr_fns the vector of member functions of this instance of
24874/// class_decl.
24875class_decl::class_decl(const environment& env, const string& name,
24876 size_t size_in_bits, size_t align_in_bits,
24877 bool is_struct, const location& locus,
24878 visibility vis, base_specs& bases,
24879 member_types& mbr_types,
24880 data_members& data_mbrs,
24881 member_functions& mbr_fns)
24882 : type_or_decl_base(env,
24883 CLASS_TYPE
24884 | ABSTRACT_TYPE_BASE
24885 | ABSTRACT_DECL_BASE
24886 | ABSTRACT_SCOPE_TYPE_DECL
24887 | ABSTRACT_SCOPE_DECL),
24888 decl_base(env, name, locus, name, vis),
24889 type_base(env, size_in_bits, align_in_bits),
24890 class_or_union(env, name, size_in_bits, align_in_bits,
24891 locus, vis, mbr_types, data_mbrs, mbr_fns),
24892 priv_(new priv(is_struct, bases))
24893{
24895}
24896
24897/// A Constructor for instances of @ref class_decl
24898///
24899/// @param env the environment we are operating from.
24900///
24901/// @param name the identifier of the class.
24902///
24903/// @param size_in_bits the size of an instance of class_decl, expressed
24904/// in bits
24905///
24906/// @param align_in_bits the alignment of an instance of class_decl,
24907/// expressed in bits.
24908///
24909/// @param locus the source location of declaration point this class.
24910///
24911/// @param vis the visibility of instances of class_decl.
24912///
24913/// @param bases the vector of base classes for this instance of class_decl.
24914///
24915/// @param mbrs the vector of member types of this instance of
24916/// class_decl.
24917///
24918/// @param data_mbrs the vector of data members of this instance of
24919/// class_decl.
24920///
24921/// @param mbr_fns the vector of member functions of this instance of
24922/// class_decl.
24923///
24924/// @param is_anonymous whether the newly created instance is
24925/// anonymous.
24926class_decl::class_decl(const environment& env, const string& name,
24927 size_t size_in_bits, size_t align_in_bits,
24928 bool is_struct, const location& locus,
24929 visibility vis, base_specs& bases,
24930 member_types& mbr_types, data_members& data_mbrs,
24931 member_functions& mbr_fns, bool is_anonymous)
24932 : type_or_decl_base(env,
24933 CLASS_TYPE
24934 | ABSTRACT_TYPE_BASE
24935 | ABSTRACT_DECL_BASE
24936 | ABSTRACT_SCOPE_TYPE_DECL
24937 | ABSTRACT_SCOPE_DECL),
24938 decl_base(env, name, locus,
24939 // If the class is anonymous then by default it won't
24940 // have a linkage name. Also, the anonymous class does
24941 // have an internal-only unique name that is generally
24942 // not taken into account when comparing classes; such a
24943 // unique internal-only name, when used as a linkage
24944 // name might introduce spurious comparison false
24945 // negatives.
24946 /*linkage_name=*/is_anonymous ? string() : name,
24947 vis),
24948 type_base(env, size_in_bits, align_in_bits),
24949 class_or_union(env, name, size_in_bits, align_in_bits,
24950 locus, vis, mbr_types, data_mbrs, mbr_fns),
24951 priv_(new priv(is_struct, bases))
24952{
24954 set_is_anonymous(is_anonymous);
24955}
24956
24957/// A constructor for instances of class_decl.
24958///
24959/// @param env the environment we are operating from.
24960///
24961/// @param name the name of the class.
24962///
24963/// @param size_in_bits the size of an instance of class_decl, expressed
24964/// in bits
24965///
24966/// @param align_in_bits the alignment of an instance of class_decl,
24967/// expressed in bits.
24968///
24969/// @param locus the source location of declaration point this class.
24970///
24971/// @param vis the visibility of instances of class_decl.
24972class_decl::class_decl(const environment& env, const string& name,
24973 size_t size_in_bits, size_t align_in_bits,
24974 bool is_struct, const location& locus,
24975 visibility vis)
24976 : type_or_decl_base(env,
24977 CLASS_TYPE
24978 | ABSTRACT_TYPE_BASE
24979 | ABSTRACT_DECL_BASE
24980 | ABSTRACT_SCOPE_TYPE_DECL
24981 | ABSTRACT_SCOPE_DECL),
24982 decl_base(env, name, locus, name, vis),
24983 type_base(env, size_in_bits, align_in_bits),
24984 class_or_union(env, name, size_in_bits, align_in_bits,
24985 locus, vis),
24986 priv_(new priv(is_struct))
24987{
24989}
24990
24991/// A constructor for instances of @ref class_decl.
24992///
24993/// @param env the environment we are operating from.
24994///
24995/// @param name the name of the class.
24996///
24997/// @param size_in_bits the size of an instance of class_decl, expressed
24998/// in bits
24999///
25000/// @param align_in_bits the alignment of an instance of class_decl,
25001/// expressed in bits.
25002///
25003/// @param locus the source location of declaration point this class.
25004///
25005/// @param vis the visibility of instances of class_decl.
25006///
25007/// @param is_anonymous whether the newly created instance is
25008/// anonymous.
25009class_decl:: class_decl(const environment& env, const string& name,
25010 size_t size_in_bits, size_t align_in_bits,
25011 bool is_struct, const location& locus,
25012 visibility vis, bool is_anonymous)
25013 : type_or_decl_base(env,
25014 CLASS_TYPE
25015 | ABSTRACT_TYPE_BASE
25016 | ABSTRACT_DECL_BASE
25017 | ABSTRACT_SCOPE_TYPE_DECL
25018 | ABSTRACT_SCOPE_DECL),
25019 decl_base(env, name, locus,
25020 // If the class is anonymous then by default it won't
25021 // have a linkage name. Also, the anonymous class does
25022 // have an internal-only unique name that is generally
25023 // not taken into account when comparing classes; such a
25024 // unique internal-only name, when used as a linkage
25025 // name might introduce spurious comparison false
25026 // negatives.
25027 /*linkage_name=*/ is_anonymous ? string() : name,
25028 vis),
25029 type_base(env, size_in_bits, align_in_bits),
25030 class_or_union(env, name, size_in_bits, align_in_bits,
25031 locus, vis),
25032 priv_(new priv(is_struct))
25033{
25035 set_is_anonymous(is_anonymous);
25036}
25037
25038/// A constuctor for instances of class_decl that represent a
25039/// declaration without definition.
25040///
25041/// @param env the environment we are operating from.
25042///
25043/// @param name the name of the class.
25044///
25045/// @param is_declaration_only a boolean saying whether the instance
25046/// represents a declaration only, or not.
25047class_decl::class_decl(const environment& env, const string& name,
25048 bool is_struct, bool is_declaration_only)
25049 : type_or_decl_base(env,
25050 CLASS_TYPE
25051 | ABSTRACT_TYPE_BASE
25052 | ABSTRACT_DECL_BASE
25053 | ABSTRACT_SCOPE_TYPE_DECL
25054 | ABSTRACT_SCOPE_DECL),
25055 decl_base(env, name, location(), name),
25056 type_base(env, 0, 0),
25057 class_or_union(env, name, is_declaration_only),
25058 priv_(new priv(is_struct))
25059{
25061}
25062
25063/// This method is invoked automatically right after the current
25064/// instance of @ref class_decl has been canonicalized.
25065///
25066/// Currently, the only thing it does is to sort the virtual member
25067/// functions vector.
25068void
25070{
25072
25073 for (class_decl::virtual_mem_fn_map_type::iterator i =
25074 priv_->virtual_mem_fns_map_.begin();
25075 i != priv_->virtual_mem_fns_map_.end();
25076 ++i)
25077 sort_virtual_member_functions(i->second);
25078}
25079
25080/// Set the "is-struct" flag of the class.
25081///
25082/// @param f the new value of the flag.
25083void
25085{priv_->is_struct_ = f;}
25086
25087/// Test if the class is a struct.
25088///
25089/// @return true iff the class is a struct.
25090bool
25092{return priv_->is_struct_;}
25093
25094/// Add a base specifier to this class.
25095///
25096/// @param b the new base specifier.
25097void
25099{
25100 priv_->bases_.push_back(b);
25101 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
25102}
25103
25104/// Get the base specifiers for this class.
25105///
25106/// @return a vector of the base specifiers.
25109{return priv_->bases_;}
25110
25111/// Find a base class of a given qualified name for the current class.
25112///
25113/// @param qualified_name the qualified name of the base class to look for.
25114///
25115/// @return a pointer to the @ref class_decl that represents the base
25116/// class of name @p qualified_name, if found.
25118class_decl::find_base_class(const string& qualified_name) const
25119{
25120 unordered_map<string, base_spec_sptr>::iterator i =
25121 priv_->bases_map_.find(qualified_name);
25122
25123 if (i != priv_->bases_map_.end())
25124 return i->second->get_base_class();
25125
25126 return class_decl_sptr();
25127}
25128
25129/// Get the virtual member functions of this class.
25130///
25131/// @param return a vector of the virtual member functions of this
25132/// class.
25135{return priv_->virtual_mem_fns_;}
25136
25137/// Get the map that associates a virtual table offset to the virtual
25138/// member functions with that virtual table offset.
25139///
25140/// Usually, there should be a 1:1 mapping between a given vtable
25141/// offset and virtual member functions of that vtable offset. But
25142/// because of some implementation details, there can be several C++
25143/// destructor functions that are *generated* by compilers, for a
25144/// given destructor that is defined in the source code. If the
25145/// destructor is virtual then those generated functions have some
25146/// DWARF attributes in common with the constructor that the user
25147/// actually defined in its source code. Among those attributes are
25148/// the vtable offset of the destructor.
25149///
25150/// @return the map that associates a virtual table offset to the
25151/// virtual member functions with that virtual table offset.
25154{return priv_->virtual_mem_fns_map_;}
25155
25156/// Sort the virtual member functions by their virtual index.
25157void
25159{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
25160
25161/// Getter of the pretty representation of the current instance of
25162/// @ref class_decl.
25163///
25164/// @param internal set to true if the call is intended to get a
25165/// representation of the decl (or type) for the purpose of canonical
25166/// type comparison. This is mainly used in the function
25167/// type_base::get_canonical_type_for().
25168///
25169/// In other words if the argument for this parameter is true then the
25170/// call is meant for internal use (for technical use inside the
25171/// library itself), false otherwise. If you don't know what this is
25172/// for, then set it to false.
25173///
25174/// @param qualified_name if true, names emitted in the pretty
25175/// representation are fully qualified.
25176///
25177/// @return the pretty representaion for a class_decl.
25178string
25180 bool qualified_name) const
25181{
25182 string cl = "class ";
25183 if (!internal && is_struct())
25184 cl = "struct ";
25185
25186 // When computing the pretty representation for internal purposes,
25187 // if an anonymous class is named by a typedef, then consider that
25188 // it has a name, which is the typedef name.
25189 if (get_is_anonymous())
25190 {
25191 if (internal && !get_name().empty())
25192 return cl + get_type_name(this, qualified_name, /*internal=*/true);
25194 /*one_line=*/true,
25195 internal);
25196
25197 }
25198
25199 string result = cl;
25200 if (qualified_name)
25201 result += get_qualified_name(internal);
25202 else
25203 result += get_name();
25204
25205 return result;
25206}
25207
25208decl_base_sptr
25209class_decl::insert_member_decl(decl_base_sptr d)
25210{
25211 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
25212 add_member_function(f, public_access,
25213 /*is_virtual=*/false,
25214 /*vtable_offset=*/0,
25215 /*is_static=*/false,
25216 /*is_ctor=*/false,
25217 /*is_dtor=*/false,
25218 /*is_const=*/false);
25219 else
25221
25222 return d;
25223}
25224
25225/// The private data structure of class_decl::base_spec.
25226struct class_decl::base_spec::priv
25227{
25228 class_decl_wptr base_class_;
25229 long offset_in_bits_;
25230 bool is_virtual_;
25231
25232 priv(const class_decl_sptr& cl,
25233 long offset_in_bits,
25234 bool is_virtual)
25235 : base_class_(cl),
25236 offset_in_bits_(offset_in_bits),
25237 is_virtual_(is_virtual)
25238 {}
25239};
25240
25241/// Constructor for base_spec instances.
25242///
25243/// @param base the base class to consider
25244///
25245/// @param a the access specifier of the base class.
25246///
25247/// @param offset_in_bits if positive or null, represents the offset
25248/// of the base in the layout of its containing type.. If negative,
25249/// means that the current base is not laid out in its containing type.
25250///
25251/// @param is_virtual if true, means that the current base class is
25252/// virtual in it's containing type.
25253class_decl::base_spec::base_spec(const class_decl_sptr& base,
25255 long offset_in_bits,
25256 bool is_virtual)
25257 : type_or_decl_base(base->get_environment(),
25258 ABSTRACT_DECL_BASE),
25259 decl_base(base->get_environment(), base->get_name(), base->get_location(),
25260 base->get_linkage_name(), base->get_visibility()),
25261 member_base(a),
25262 priv_(new priv(base, offset_in_bits, is_virtual))
25263{
25265 set_qualified_name(base->get_qualified_name());
25266}
25267
25268/// Return the hash value of the current IR node.
25269///
25270/// Note that upon the first invocation, this member functions
25271/// computes the hash value and returns it. Subsequent invocations
25272/// just return the hash value that was previously calculated.
25273///
25274/// @return the hash value of the current IR node.
25275hash_t
25277{
25279 return h;
25280}
25281
25282/// Get the base class referred to by the current base class
25283/// specifier.
25284///
25285/// @return the base class.
25288{return priv_->base_class_.lock();}
25289
25290/// Getter of the "is-virtual" proprerty of the base class specifier.
25291///
25292/// @return true iff this specifies a virtual base class.
25293bool
25295{return priv_->is_virtual_;}
25296
25297/// Getter of the offset of the base.
25298///
25299/// @return the offset of the base.
25300long
25302{return priv_->offset_in_bits_;}
25303
25304/// Traverses an instance of @ref class_decl::base_spec, visiting all
25305/// the sub-types and decls that it might contain.
25306///
25307/// @param v the visitor that is used to visit every IR sub-node of
25308/// the current node.
25309///
25310/// @return true if either
25311/// - all the children nodes of the current IR node were traversed
25312/// and the calling code should keep going with the traversing.
25313/// - or the current IR node is already being traversed.
25314/// Otherwise, returning false means that the calling code should not
25315/// keep traversing the tree.
25316bool
25318{
25319 if (visiting())
25320 return true;
25321
25322 if (v.visit_begin(this))
25323 {
25324 visiting(true);
25325 get_base_class()->traverse(v);
25326 visiting(false);
25327 }
25328
25329 return v.visit_end(this);
25330}
25331
25332/// Constructor for base_spec instances.
25333///
25334/// Note that this constructor is for clients that don't support RTTI
25335/// and that have a base class of type_base, but of dynamic type
25336/// class_decl.
25337///
25338/// @param base the base class to consider. Must be a pointer to an
25339/// instance of class_decl
25340///
25341/// @param a the access specifier of the base class.
25342///
25343/// @param offset_in_bits if positive or null, represents the offset
25344/// of the base in the layout of its containing type.. If negative,
25345/// means that the current base is not laid out in its containing type.
25346///
25347/// @param is_virtual if true, means that the current base class is
25348/// virtual in it's containing type.
25349class_decl::base_spec::base_spec(const type_base_sptr& base,
25351 long offset_in_bits,
25352 bool is_virtual)
25354 ABSTRACT_DECL_BASE),
25359 member_base(a),
25360 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
25361 offset_in_bits,
25362 is_virtual))
25363{
25365}
25366
25367class_decl::base_spec::~base_spec() = default;
25368
25369/// Compares two instances of @ref class_decl::base_spec.
25370///
25371/// If the two intances are different, set a bitfield to give some
25372/// insight about the kind of differences there are.
25373///
25374/// @param l the first artifact of the comparison.
25375///
25376/// @param r the second artifact of the comparison.
25377///
25378/// @param k a pointer to a bitfield that gives information about the
25379/// kind of changes there are between @p l and @p r. This one is set
25380/// iff @p k is non-null and the function returns false.
25381///
25382/// Please note that setting k to a non-null value does have a
25383/// negative performance impact because even if @p l and @p r are not
25384/// equal, the function keeps up the comparison in order to determine
25385/// the different kinds of ways in which they are different.
25386///
25387/// @return true if @p l equals @p r, false otherwise.
25388bool
25390 const class_decl::base_spec& r,
25391 change_kind* k)
25392{
25393 if (!l.member_base::operator==(r))
25394 {
25395 if (k)
25398 }
25399
25401}
25402
25403/// Comparison operator for @ref class_decl::base_spec.
25404///
25405/// @param other the instance of @ref class_decl::base_spec to compare
25406/// against.
25407///
25408/// @return true if the current instance of @ref class_decl::base_spec
25409/// equals @p other.
25410bool
25412{
25413 const class_decl::base_spec* o =
25414 dynamic_cast<const class_decl::base_spec*>(&other);
25415
25416 if (!o)
25417 return false;
25418
25419 return equals(*this, *o, 0);
25420}
25421
25422/// Comparison operator for @ref class_decl::base_spec.
25423///
25424/// @param other the instance of @ref class_decl::base_spec to compare
25425/// against.
25426///
25427/// @return true if the current instance of @ref class_decl::base_spec
25428/// equals @p other.
25429bool
25431{
25432 const class_decl::base_spec* o =
25433 dynamic_cast<const class_decl::base_spec*>(&other);
25434 if (!o)
25435 return false;
25436
25437 return operator==(static_cast<const decl_base&>(*o));
25438}
25439
25440mem_fn_context_rel::~mem_fn_context_rel()
25441{
25442}
25443
25444/// A constructor for instances of method_decl.
25445///
25446/// @param name the name of the method.
25447///
25448/// @param type the type of the method.
25449///
25450/// @param declared_inline whether the method was
25451/// declared inline or not.
25452///
25453/// @param locus the source location of the method.
25454///
25455/// @param linkage_name the mangled name of the method.
25456///
25457/// @param vis the visibility of the method.
25458///
25459/// @param bind the binding of the method.
25460method_decl::method_decl(const string& name,
25461 method_type_sptr type,
25462 bool declared_inline,
25463 const location& locus,
25464 const string& linkage_name,
25465 visibility vis,
25466 binding bind)
25468 METHOD_DECL
25469 | ABSTRACT_DECL_BASE
25470 |FUNCTION_DECL),
25471 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25472 function_decl(name, static_pointer_cast<function_type>(type),
25473 declared_inline, locus, linkage_name, vis, bind)
25474{
25476 set_context_rel(new mem_fn_context_rel(0));
25477 set_member_function_is_const(*this, type->get_is_const());
25478}
25479
25480/// A constructor for instances of method_decl.
25481///
25482/// @param name the name of the method.
25483///
25484/// @param type the type of the method. Must be an instance of
25485/// method_type.
25486///
25487/// @param declared_inline whether the method was
25488/// declared inline or not.
25489///
25490/// @param locus the source location of the method.
25491///
25492/// @param linkage_name the mangled name of the method.
25493///
25494/// @param vis the visibility of the method.
25495///
25496/// @param bind the binding of the method.
25497method_decl::method_decl(const string& name,
25498 function_type_sptr type,
25499 bool declared_inline,
25500 const location& locus,
25501 const string& linkage_name,
25502 visibility vis,
25503 binding bind)
25504 : type_or_decl_base(type->get_environment(),
25505 METHOD_DECL
25506 | ABSTRACT_DECL_BASE
25507 | FUNCTION_DECL),
25508 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25509 function_decl(name, static_pointer_cast<function_type>
25510 (dynamic_pointer_cast<method_type>(type)),
25511 declared_inline, locus, linkage_name, vis, bind)
25512{
25514 set_context_rel(new mem_fn_context_rel(0));
25515}
25516
25517/// A constructor for instances of method_decl.
25518///
25519/// @param name the name of the method.
25520///
25521/// @param type the type of the method. Must be an instance of
25522/// method_type.
25523///
25524/// @param declared_inline whether the method was
25525/// declared inline or not.
25526///
25527/// @param locus the source location of the method.
25528///
25529/// @param linkage_name the mangled name of the method.
25530///
25531/// @param vis the visibility of the method.
25532///
25533/// @param bind the binding of the method.
25534method_decl::method_decl(const string& name,
25535 type_base_sptr type,
25536 bool declared_inline,
25537 const location& locus,
25538 const string& linkage_name,
25539 visibility vis,
25540 binding bind)
25541 : type_or_decl_base(type->get_environment(),
25542 METHOD_DECL
25543 | ABSTRACT_DECL_BASE
25544 | FUNCTION_DECL),
25545 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25546 function_decl(name, static_pointer_cast<function_type>
25547 (dynamic_pointer_cast<method_type>(type)),
25548 declared_inline, locus, linkage_name, vis, bind)
25549{
25551 set_context_rel(new mem_fn_context_rel(0));
25552}
25553
25554/// Set the linkage name of the method.
25555///
25556/// @param l the new linkage name of the method.
25557void
25559{
25560 string old_lname = get_linkage_name();
25562 // Update the linkage_name -> member function map of the containing
25563 // class declaration.
25564 if (!l.empty())
25565 {
25567 class_or_union_sptr cl = t->get_class_type();
25568 method_decl_sptr m(this, sptr_utils::noop_deleter());
25569 cl->priv_->mem_fns_map_[l] = m;
25570 if (!old_lname.empty() && l != old_lname)
25571 {
25572 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
25573 {
25574 ABG_ASSERT(m.get() == this);
25575 cl->priv_->mem_fns_map_.erase(old_lname);
25576 }
25577 }
25578 }
25579}
25580
25581method_decl::~method_decl()
25582{}
25583
25584const method_type_sptr
25586{
25587 method_type_sptr result;
25589 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
25590 return result;
25591}
25592
25593/// Set the containing class of a method_decl.
25594///
25595/// @param scope the new containing class_decl.
25596void
25597method_decl::set_scope(scope_decl* scope)
25598{
25599 if (!get_context_rel())
25600 set_context_rel(new mem_fn_context_rel(scope));
25601 else
25602 get_context_rel()->set_scope(scope);
25603}
25604
25605/// Equality operator for @ref method_decl_sptr.
25606///
25607/// This is a deep equality operator, as it compares the @ref
25608/// method_decl that is pointed-to by the smart pointer.
25609///
25610/// @param l the left-hand side argument of the equality operator.
25611///
25612/// @param r the righ-hand side argument of the equality operator.
25613///
25614/// @return true iff @p l equals @p r.
25615bool
25616operator==(const method_decl_sptr& l, const method_decl_sptr& r)
25617{
25618 if (l.get() == r.get())
25619 return true;
25620 if (!!l != !!r)
25621 return false;
25622
25623 return *l == *r;
25624}
25625
25626/// Inequality operator for @ref method_decl_sptr.
25627///
25628/// This is a deep equality operator, as it compares the @ref
25629/// method_decl that is pointed-to by the smart pointer.
25630///
25631/// @param l the left-hand side argument of the equality operator.
25632///
25633/// @param r the righ-hand side argument of the equality operator.
25634///
25635/// @return true iff @p l differs from @p r.
25636bool
25637operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
25638{return !operator==(l, r);}
25639
25640/// Test if a function_decl is actually a method_decl.
25641///
25642///@param d the @ref function_decl to consider.
25643///
25644/// @return the method_decl sub-object of @p d if inherits
25645/// a method_decl type.
25648{
25649 return dynamic_cast<method_decl*>
25650 (const_cast<type_or_decl_base*>(d));
25651}
25652
25653/// Test if a function_decl is actually a method_decl.
25654///
25655///@param d the @ref function_decl to consider.
25656///
25657/// @return the method_decl sub-object of @p d if inherits
25658/// a method_decl type.
25661{return is_method_decl(&d);}
25662
25663/// Test if a function_decl is actually a method_decl.
25664///
25665///@param d the @ref function_decl to consider.
25666///
25667/// @return the method_decl sub-object of @p d if inherits
25668/// a method_decl type.
25669method_decl_sptr
25671{return dynamic_pointer_cast<method_decl>(d);}
25672
25673/// A "less than" functor to sort a vector of instances of
25674/// method_decl that are virtual.
25675struct virtual_member_function_less_than
25676{
25677 /// The less than operator. First, it sorts the methods by their
25678 /// vtable index. If they have the same vtable index, it sorts them
25679 /// by the name of their ELF symbol. If they don't have elf
25680 /// symbols, it sorts them by considering their pretty
25681 /// representation.
25682 ///
25683 /// Note that this method expects virtual methods.
25684 ///
25685 /// @param f the first method to consider.
25686 ///
25687 /// @param s the second method to consider.
25688 ///
25689 /// @return true if method @p is less than method @s.
25690 bool
25691 operator()(const method_decl& f,
25692 const method_decl& s)
25693 {
25696
25697 ssize_t f_offset = get_member_function_vtable_offset(f);
25698 ssize_t s_offset = get_member_function_vtable_offset(s);
25699 if (f_offset != s_offset) return f_offset < s_offset;
25700
25701 string fn, sn;
25702 // Try the linkage names (important for destructors).
25703 fn = f.get_linkage_name();
25704 sn = s.get_linkage_name();
25705 if (fn != sn) return fn < sn;
25706
25707 // If the functions have symbols, then compare their symbol-id
25708 // string.
25709 elf_symbol_sptr f_sym = f.get_symbol();
25710 elf_symbol_sptr s_sym = s.get_symbol();
25711 if ((!f_sym) != (!s_sym)) return !f_sym;
25712 if (f_sym && s_sym)
25713 {
25714 fn = f_sym->get_id_string();
25715 sn = s_sym->get_id_string();
25716 if (fn != sn) return fn < sn;
25717 }
25718
25719 // None of the functions have symbols or linkage names that
25720 // distinguish them, so compare their pretty representation.
25723 if (fn != sn) return fn < sn;
25724
25725 /// If it's just the file paths that are different then sort them
25726 /// too.
25727 string fn_filepath, sn_filepath;
25728 unsigned line = 0, column = 0;
25729 location fn_loc = f.get_location(), sn_loc = s.get_location();
25730 if (fn_loc)
25731 fn_loc.expand(fn_filepath, line, column);
25732 if (sn_loc)
25733 sn_loc.expand(sn_filepath, line, column);
25734 return fn_filepath < sn_filepath;
25735 }
25736
25737 /// The less than operator. First, it sorts the methods by their
25738 /// vtable index. If they have the same vtable index, it sorts them
25739 /// by the name of their ELF symbol. If they don't have elf
25740 /// symbols, it sorts them by considering their pretty
25741 /// representation.
25742 ///
25743 /// Note that this method expects to take virtual methods.
25744 ///
25745 /// @param f the first method to consider.
25746 ///
25747 /// @param s the second method to consider.
25748 bool
25749 operator()(const method_decl_sptr f,
25750 const method_decl_sptr s)
25751 {return operator()(*f, *s);}
25752}; // end struct virtual_member_function_less_than
25753
25754/// Sort a vector of instances of virtual member functions.
25755///
25756/// @param mem_fns the vector of member functions to sort.
25757static void
25758sort_virtual_member_functions(class_decl::member_functions& mem_fns)
25759{
25760 virtual_member_function_less_than lt;
25761 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25762}
25763
25764/// Add a member function to the current instance of @ref class_or_union.
25765///
25766/// @param f a method_decl to add to the current class. This function
25767/// should not have been already added to a scope.
25768///
25769/// @param access the access specifier for the member function to add.
25770///
25771/// @param is_virtual if this is true then it means the function @p f
25772/// is a virtual function. That also means that the current instance
25773/// of @ref class_or_union is actually an instance of @ref class_decl.
25774///
25775/// @param vtable_offset the offset of the member function in the
25776/// virtual table. This parameter is taken into account only if @p
25777/// is_virtual is true.
25778///
25779/// @param is_static whether the member function is static.
25780///
25781/// @param is_ctor whether the member function is a constructor.
25782///
25783/// @param is_dtor whether the member function is a destructor.
25784///
25785/// @param is_const whether the member function is const.
25786void
25789 bool is_virtual,
25790 size_t vtable_offset,
25791 bool is_static, bool is_ctor,
25792 bool is_dtor, bool is_const)
25793{
25794 add_member_function(f, a, is_static, is_ctor,
25795 is_dtor, is_const);
25796
25797 if (class_decl* klass = is_class_type(this))
25798 {
25799 if (is_virtual)
25800 {
25801 set_member_function_virtuality(f, is_virtual, vtable_offset);
25802 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
25803 }
25804 }
25805}
25806
25807/// When a virtual member function has seen its virtualness set by
25808/// set_member_function_is_virtual(), this function ensures that the
25809/// member function is added to the specific vectors and maps of
25810/// virtual member function of its class.
25811///
25812/// @param method the method to fixup.
25813void
25814fixup_virtual_member_function(method_decl_sptr method)
25815{
25816 if (!method || !get_member_function_is_virtual(method))
25817 return;
25818
25819 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
25820
25821 class_decl::member_functions::const_iterator m;
25822 for (m = klass->priv_->virtual_mem_fns_.begin();
25823 m != klass->priv_->virtual_mem_fns_.end();
25824 ++m)
25825 if (m->get() == method.get()
25826 || (*m)->get_linkage_name() == method->get_linkage_name())
25827 break;
25828 if (m == klass->priv_->virtual_mem_fns_.end())
25829 klass->priv_->virtual_mem_fns_.push_back(method);
25830
25831 // Build or udpate the map that associates a vtable offset to the
25832 // number of virtual member functions that "point" to it.
25833 ssize_t voffset = get_member_function_vtable_offset(method);
25834 if (voffset == -1)
25835 return;
25836
25837 class_decl::virtual_mem_fn_map_type::iterator i =
25838 klass->priv_->virtual_mem_fns_map_.find(voffset);
25839 if (i == klass->priv_->virtual_mem_fns_map_.end())
25840 {
25841 class_decl::member_functions virtual_mem_fns_at_voffset;
25842 virtual_mem_fns_at_voffset.push_back(method);
25843 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
25844 }
25845 else
25846 {
25847 for (m = i->second.begin() ; m != i->second.end(); ++m)
25848 if (m->get() == method.get()
25849 || (*m)->get_linkage_name() == method->get_linkage_name())
25850 break;
25851 if (m == i->second.end())
25852 i->second.push_back(method);
25853 }
25854}
25855
25856/// Return true iff the class has no entity in its scope.
25857bool
25859{return priv_->bases_.empty() && has_no_member();}
25860
25861/// Test if the current instance of @ref class_decl has virtual member
25862/// functions.
25863///
25864/// @return true iff the current instance of @ref class_decl has
25865/// virtual member functions.
25866bool
25868{return !get_virtual_mem_fns().empty();}
25869
25870/// Test if the current instance of @ref class_decl has at least one
25871/// virtual base.
25872///
25873/// @return true iff the current instance of @ref class_decl has a
25874/// virtual member function.
25875bool
25877{
25878 for (base_specs::const_iterator b = get_base_specifiers().begin();
25879 b != get_base_specifiers().end();
25880 ++b)
25881 if ((*b)->get_is_virtual()
25882 || (*b)->get_base_class()->has_virtual_bases())
25883 return true;
25884
25885 return false;
25886}
25887
25888/// Test if the current instance has a vtable.
25889///
25890/// This is only valid for a C++ program.
25891///
25892/// Basically this function checks if the class has either virtual
25893/// functions, or virtual bases.
25894bool
25896{
25898 || has_virtual_bases())
25899 return true;
25900 return false;
25901}
25902
25903/// Get the highest vtable offset of all the virtual methods of the
25904/// class.
25905///
25906/// @return the highest vtable offset of all the virtual methods of
25907/// the class.
25908ssize_t
25910{
25911 ssize_t offset = -1;
25912 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
25913 get_virtual_mem_fns_map().begin();
25914 e != get_virtual_mem_fns_map().end();
25915 ++e)
25916 if (e->first > offset)
25917 offset = e->first;
25918
25919 return offset;
25920}
25921
25922/// Return the hash value of the current IR node.
25923///
25924/// Note that upon the first invocation, this member functions
25925/// computes the hash value and returns it. Subsequent invocations
25926/// just return the hash value that was previously calculated.
25927///
25928/// @return the hash value of the current IR node.
25929hash_t
25931{
25933 return h;
25934}
25935
25936/// Test if two methods are equal without taking their symbol or
25937/// linkage name into account.
25938///
25939/// @param f the first method.
25940///
25941/// @param s the second method.
25942///
25943/// @return true iff @p f equals @p s without taking their linkage
25944/// name or symbol into account.
25945static bool
25946methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
25947 const method_decl_sptr& s)
25948{
25949 method_decl_sptr first = f, second = s;
25950 elf_symbol_sptr saved_first_elf_symbol =
25951 first->get_symbol();
25952 elf_symbol_sptr saved_second_elf_symbol =
25953 second->get_symbol();
25954 interned_string saved_first_linkage_name =
25955 first->get_linkage_name();
25956 interned_string saved_second_linkage_name =
25957 second->get_linkage_name();
25958
25959 first->set_symbol(elf_symbol_sptr());
25960 first->set_linkage_name("");
25961 second->set_symbol(elf_symbol_sptr());
25962 second->set_linkage_name("");
25963
25964 bool equal = *first == *second;
25965
25966 first->set_symbol(saved_first_elf_symbol);
25967 first->set_linkage_name(saved_first_linkage_name);
25968 second->set_symbol(saved_second_elf_symbol);
25969 second->set_linkage_name(saved_second_linkage_name);
25970
25971 return equal;
25972}
25973
25974/// Test if a given method is equivalent to at least of other method
25975/// that is in a vector of methods.
25976///
25977/// Note that "equivalent" here means being equal without taking the
25978/// linkage name or the symbol of the methods into account.
25979///
25980/// This is a sub-routine of the 'equals' function that compares @ref
25981/// class_decl.
25982///
25983/// @param method the method to compare.
25984///
25985/// @param fns the vector of functions to compare @p method against.
25986///
25987/// @return true iff @p is equivalent to at least one method in @p
25988/// fns.
25989static bool
25990method_matches_at_least_one_in_vector(const method_decl_sptr& method,
25992{
25993 for (class_decl::member_functions::const_iterator i = fns.begin();
25994 i != fns.end();
25995 ++i)
25996 // Note that the comparison must be done in this order: method ==
25997 // *i This is to keep the consistency of the comparison. It's
25998 // important especially when doing type canonicalization. The
25999 // already canonicalize type is the left operand, and the type
26000 // being canonicalized is the right operand. This comes from the
26001 // code in type_base::get_canonical_type_for().
26002 if (methods_equal_modulo_elf_symbol(method, *i))
26003 return true;
26004
26005 return false;
26006}
26007
26008/// Compares two instances of @ref class_decl.
26009///
26010/// If the two intances are different, set a bitfield to give some
26011/// insight about the kind of differences there are.
26012///
26013/// @param l the first artifact of the comparison.
26014///
26015/// @param r the second artifact of the comparison.
26016///
26017/// @param k a pointer to a bitfield that gives information about the
26018/// kind of changes there are between @p l and @p r. This one is set
26019/// iff @p k is non-null and the function returns false.
26020///
26021/// Please note that setting k to a non-null value does have a
26022/// negative performance impact because even if @p l and @p r are not
26023/// equal, the function keeps up the comparison in order to determine
26024/// the different kinds of ways in which they are different.
26025///
26026/// @return true if @p l equals @p r, false otherwise.
26027bool
26029{
26030 {
26031 // First of all, let's see if these two types haven't already been
26032 // compared. If so, and if the result of the comparison has been
26033 // cached, let's just re-use it, rather than comparing them all
26034 // over again.
26035 bool result = false;
26036 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
26037 ABG_RETURN(result);
26038 }
26039
26040 // if one of the classes is declaration-only then we take a fast
26041 // path here.
26043 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
26044 static_cast<const class_or_union&>(r),
26045 k));
26046
26047 bool result = true;
26048 if (!equals(static_cast<const class_or_union&>(l),
26049 static_cast<const class_or_union&>(r),
26050 k))
26051 {
26052 result = false;
26053 if (!k)
26054 ABG_RETURN(result);
26055 }
26056
26058
26060
26061#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
26062
26063 // Compare bases.
26064 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
26065 {
26066 result = false;
26067 if (k)
26069 else
26070 RETURN(result);
26071 }
26072
26073 for (class_decl::base_specs::const_iterator
26074 b0 = l.get_base_specifiers().begin(),
26075 b1 = r.get_base_specifiers().begin();
26076 (b0 != l.get_base_specifiers().end()
26077 && b1 != r.get_base_specifiers().end());
26078 ++b0, ++b1)
26079 if (*b0 != *b1)
26080 {
26081 result = false;
26082 if (k)
26083 {
26084 if (!types_have_similar_structure((*b0)->get_base_class().get(),
26085 (*b1)->get_base_class().get()))
26087 else
26088 *k |= SUBTYPE_CHANGE_KIND;
26089 break;
26090 }
26091 RETURN(result);
26092 }
26093
26094 // Compare virtual member functions
26095
26096 // We look at the map that associates a given vtable offset to a
26097 // vector of virtual member functions that point to that offset.
26098 //
26099 // This is because there are cases where several functions can
26100 // point to the same virtual table offset.
26101 //
26102 // This is usually the case for virtual destructors. Even though
26103 // there can be only one virtual destructor declared in source
26104 // code, there are actually potentially up to three generated
26105 // functions for that destructor. Some of these generated
26106 // functions can be clones of other functions that are among those
26107 // generated ones. In any cases, they all have the same
26108 // properties, including the vtable offset property.
26109
26110 // So, there should be the same number of different vtable
26111 // offsets, the size of two maps must be equals.
26112 if (l.get_virtual_mem_fns_map().size()
26113 != r.get_virtual_mem_fns_map().size())
26114 {
26115 result = false;
26116 if (k)
26118 else
26119 RETURN(result);
26120 }
26121
26122 // Then, each virtual member function of a given vtable offset in
26123 // the first class type, must match an equivalent virtual member
26124 // function of a the same vtable offset in the second class type.
26125 //
26126 // By "match", I mean that the two virtual member function should
26127 // be equal if we don't take into account their symbol name or
26128 // their linkage name. This is because two destructor functions
26129 // clones (for instance) might have different linkage name, but
26130 // are still equivalent if their other properties are the same.
26131 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
26132 l.get_virtual_mem_fns_map().begin();
26133 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
26134 ++first_v_fn_entry)
26135 {
26136 unsigned voffset = first_v_fn_entry->first;
26137 const class_decl::member_functions& first_vfns =
26138 first_v_fn_entry->second;
26139
26140 const class_decl::virtual_mem_fn_map_type::const_iterator
26141 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
26142
26143 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
26144 {
26145 result = false;
26146 if (k)
26148 RETURN(result);
26149 }
26150
26151 const class_decl::member_functions& second_vfns =
26152 second_v_fn_entry->second;
26153
26154 bool matches = false;
26155 for (class_decl::member_functions::const_iterator i =
26156 first_vfns.begin();
26157 i != first_vfns.end();
26158 ++i)
26159 if (method_matches_at_least_one_in_vector(*i, second_vfns))
26160 {
26161 matches = true;
26162 break;
26163 }
26164
26165 if (!matches)
26166 {
26167 result = false;
26168 if (k)
26169 *k |= SUBTYPE_CHANGE_KIND;
26170 else
26171 RETURN(result);
26172 }
26173 }
26174
26175 RETURN(result);
26176#undef RETURN
26177}
26178
26179/// Copy a method of a class into a new class.
26180///
26181/// @param klass the class into which the method is to be copied.
26182///
26183/// @param method the method to copy into @p klass.
26184///
26185/// @return the resulting newly copied method.
26186method_decl_sptr
26187copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
26188{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26189
26190/// Copy a method of a class into a new class.
26191///
26192/// @param klass the class into which the method is to be copied.
26193///
26194/// @param method the method to copy into @p klass.
26195///
26196/// @return the resulting newly copied method.
26197method_decl_sptr
26199{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26200
26201/// Comparison operator for @ref class_decl.
26202///
26203/// @param other the instance of @ref class_decl to compare against.
26204///
26205/// @return true iff the current instance of @ref class_decl equals @p
26206/// other.
26207bool
26209{
26210 const class_decl* op = is_class_type(&other);
26211 if (!op)
26212 {
26213 if (class_or_union* cou = is_class_or_union_type(&other))
26214 return class_or_union::operator==(*cou);
26215 return false;
26216 }
26217
26218 // If this is a decl-only type (and thus with no canonical type),
26219 // use the canonical type of the definition, if any.
26220 const class_decl *l = 0;
26222 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
26223 if (l == 0)
26224 l = this;
26225
26226 ABG_ASSERT(l);
26227
26228 // Likewise for the other type.
26229 const class_decl *r = 0;
26230 if (op->get_is_declaration_only())
26231 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
26232 if (r == 0)
26233 r = op;
26234
26235 ABG_ASSERT(r);
26236
26237 return try_canonical_compare(l, r);
26238}
26239
26240/// Equality operator for class_decl.
26241///
26242/// Re-uses the equality operator that takes a decl_base.
26243///
26244/// @param other the other class_decl to compare against.
26245///
26246/// @return true iff the current instance equals the other one.
26247bool
26249{
26250 const decl_base* o = is_decl(&other);
26251 if (!o)
26252 return false;
26253 return *this == *o;
26254}
26255
26256/// Equality operator for class_decl.
26257///
26258/// Re-uses the equality operator that takes a decl_base.
26259///
26260/// @param other the other class_decl to compare against.
26261///
26262/// @return true iff the current instance equals the other one.
26263bool
26265{
26266 const decl_base& o = other;
26267 return *this == o;
26268}
26269
26270/// Comparison operator for @ref class_decl.
26271///
26272/// @param other the instance of @ref class_decl to compare against.
26273///
26274/// @return true iff the current instance of @ref class_decl equals @p
26275/// other.
26276bool
26278{
26279 const decl_base& o = other;
26280 return *this == o;
26281}
26282
26283/// Turn equality of shared_ptr of class_decl into a deep equality;
26284/// that is, make it compare the pointed to objects too.
26285///
26286/// @param l the shared_ptr of class_decl on left-hand-side of the
26287/// equality.
26288///
26289/// @param r the shared_ptr of class_decl on right-hand-side of the
26290/// equality.
26291///
26292/// @return true if the class_decl pointed to by the shared_ptrs are
26293/// equal, false otherwise.
26294bool
26296{
26297 if (l.get() == r.get())
26298 return true;
26299 if (!!l != !!r)
26300 return false;
26301
26302 return *l == *r;
26303}
26304
26305/// Turn inequality of shared_ptr of class_decl into a deep equality;
26306/// that is, make it compare the pointed to objects too.
26307///
26308/// @param l the shared_ptr of class_decl on left-hand-side of the
26309/// equality.
26310///
26311/// @param r the shared_ptr of class_decl on right-hand-side of the
26312/// equality.
26313///
26314/// @return true if the class_decl pointed to by the shared_ptrs are
26315/// different, false otherwise.
26316bool
26318{return !operator==(l, r);}
26319
26320/// Turn equality of shared_ptr of class_or_union into a deep
26321/// equality; that is, make it compare the pointed to objects too.
26322///
26323/// @param l the left-hand-side operand of the operator
26324///
26325/// @param r the right-hand-side operand of the operator.
26326///
26327/// @return true iff @p l equals @p r.
26328bool
26329operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
26330{
26331 if (l.get() == r.get())
26332 return true;
26333 if (!!l != !!r)
26334 return false;
26335
26336 return *l == *r;
26337}
26338
26339/// Turn inequality of shared_ptr of class_or_union into a deep
26340/// equality; that is, make it compare the pointed to objects too.
26341///
26342/// @param l the left-hand-side operand of the operator
26343///
26344/// @param r the right-hand-side operand of the operator.
26345///
26346/// @return true iff @p l is different from @p r.
26347bool
26348operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
26349{return !operator==(l, r);}
26350
26351/// This implements the ir_traversable_base::traverse pure virtual
26352/// function.
26353///
26354/// @param v the visitor used on the current instance and on its
26355/// members.
26356///
26357/// @return true if the entire IR node tree got traversed, false
26358/// otherwise.
26359bool
26361{
26362 if (v.type_node_has_been_visited(this))
26363 return true;
26364
26365 if (visiting())
26366 return true;
26367
26368 if (v.visit_begin(this))
26369 {
26370 visiting(true);
26371 bool stop = false;
26372
26373 for (base_specs::const_iterator i = get_base_specifiers().begin();
26374 i != get_base_specifiers().end();
26375 ++i)
26376 {
26377 if (!(*i)->traverse(v))
26378 {
26379 stop = true;
26380 break;
26381 }
26382 }
26383
26384 if (!stop)
26385 for (data_members::const_iterator i = get_data_members().begin();
26386 i != get_data_members().end();
26387 ++i)
26388 if (!(*i)->traverse(v))
26389 {
26390 stop = true;
26391 break;
26392 }
26393
26394 if (!stop)
26395 for (member_functions::const_iterator i= get_member_functions().begin();
26396 i != get_member_functions().end();
26397 ++i)
26398 if (!(*i)->traverse(v))
26399 {
26400 stop = true;
26401 break;
26402 }
26403
26404 if (!stop)
26405 for (member_types::const_iterator i = get_member_types().begin();
26406 i != get_member_types().end();
26407 ++i)
26408 if (!(*i)->traverse(v))
26409 {
26410 stop = true;
26411 break;
26412 }
26413
26414 if (!stop)
26415 for (member_function_templates::const_iterator i =
26417 i != get_member_function_templates().end();
26418 ++i)
26419 if (!(*i)->traverse(v))
26420 {
26421 stop = true;
26422 break;
26423 }
26424
26425 if (!stop)
26426 for (member_class_templates::const_iterator i =
26428 i != get_member_class_templates().end();
26429 ++i)
26430 if (!(*i)->traverse(v))
26431 {
26432 stop = true;
26433 break;
26434 }
26435 visiting(false);
26436 }
26437
26438 bool result = v.visit_end(this);
26440 return result;
26441}
26442
26443/// Destructor of the @ref class_decl type.
26445{delete priv_;}
26446
26447context_rel::~context_rel()
26448{}
26449
26450bool
26451member_base::operator==(const member_base& o) const
26452{
26454 && get_is_static() == o.get_is_static());
26455}
26456
26457/// Equality operator for smart pointers to @ref
26458/// class_decl::base_specs.
26459///
26460/// This compares the pointed-to objects.
26461///
26462/// @param l the first instance to consider.
26463///
26464/// @param r the second instance to consider.
26465///
26466/// @return true iff @p l equals @p r.
26467bool
26470{
26471 if (l.get() == r.get())
26472 return true;
26473 if (!!l != !!r)
26474 return false;
26475
26476 return *l == static_cast<const decl_base&>(*r);
26477}
26478
26479/// Inequality operator for smart pointers to @ref
26480/// class_decl::base_specs.
26481///
26482/// This compares the pointed-to objects.
26483///
26484/// @param l the first instance to consider.
26485///
26486/// @param r the second instance to consider.
26487///
26488/// @return true iff @p l is different from @p r.
26489bool
26492{return !operator==(l, r);}
26493
26494/// Test if an ABI artifact is a class base specifier.
26495///
26496/// @param tod the ABI artifact to consider.
26497///
26498/// @return a pointer to the @ref class_decl::base_spec sub-object of
26499/// @p tod iff it's a class base specifier.
26502{
26503 return dynamic_cast<class_decl::base_spec*>
26504 (const_cast<type_or_decl_base*>(tod));
26505}
26506
26507/// Test if an ABI artifact is a class base specifier.
26508///
26509/// @param tod the ABI artifact to consider.
26510///
26511/// @return a pointer to the @ref class_decl::base_spec sub-object of
26512/// @p tod iff it's a class base specifier.
26515{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
26516
26517bool
26518member_function_template::operator==(const member_base& other) const
26519{
26520 try
26521 {
26522 const member_function_template& o =
26523 dynamic_cast<const member_function_template&>(other);
26524
26525 if (!(is_constructor() == o.is_constructor()
26526 && is_const() == o.is_const()
26527 && member_base::operator==(o)))
26528 return false;
26529
26530 if (function_tdecl_sptr ftdecl = as_function_tdecl())
26531 {
26532 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
26533 if (other_ftdecl)
26534 return ftdecl->function_tdecl::operator==(*other_ftdecl);
26535 }
26536 }
26537 catch(...)
26538 {}
26539 return false;
26540}
26541
26542/// Equality operator for smart pointers to @ref
26543/// member_function_template. This is compares the
26544/// pointed-to instances.
26545///
26546/// @param l the first instance to consider.
26547///
26548/// @param r the second instance to consider.
26549///
26550/// @return true iff @p l equals @p r.
26551bool
26552operator==(const member_function_template_sptr& l,
26553 const member_function_template_sptr& r)
26554{
26555 if (l.get() == r.get())
26556 return true;
26557 if (!!l != !!r)
26558 return false;
26559
26560 return *l == *r;
26561}
26562
26563/// Inequality operator for smart pointers to @ref
26564/// member_function_template. This is compares the pointed-to
26565/// instances.
26566///
26567/// @param l the first instance to consider.
26568///
26569/// @param r the second instance to consider.
26570///
26571/// @return true iff @p l equals @p r.
26572bool
26573operator!=(const member_function_template_sptr& l,
26574 const member_function_template_sptr& r)
26575{return !operator==(l, r);}
26576
26577/// This implements the ir_traversable_base::traverse pure virtual
26578/// function.
26579///
26580/// @param v the visitor used on the current instance and on its
26581/// underlying function template.
26582///
26583/// @return true if the entire IR node tree got traversed, false
26584/// otherwise.
26585bool
26587{
26588 if (visiting())
26589 return true;
26590
26591 if (v.visit_begin(this))
26592 {
26593 visiting(true);
26594 if (function_tdecl_sptr f = as_function_tdecl())
26595 f->traverse(v);
26596 visiting(false);
26597 }
26598 return v.visit_end(this);
26599}
26600
26601/// Equality operator of the the @ref member_class_template class.
26602///
26603/// @param other the other @ref member_class_template to compare against.
26604///
26605/// @return true iff the current instance equals @p other.
26606bool
26608{
26609 try
26610 {
26611 const member_class_template& o =
26612 dynamic_cast<const member_class_template&>(other);
26613
26614 if (!member_base::operator==(o))
26615 return false;
26616
26617 return as_class_tdecl()->class_tdecl::operator==(o);
26618 }
26619 catch(...)
26620 {return false;}
26621}
26622
26623/// Equality operator of the the @ref member_class_template class.
26624///
26625/// @param other the other @ref member_class_template to compare against.
26626///
26627/// @return true iff the current instance equals @p other.
26628bool
26630{
26631 if (!decl_base::operator==(other))
26632 return false;
26633 return as_class_tdecl()->class_tdecl::operator==(other);
26634}
26635
26636/// Comparison operator for the @ref member_class_template
26637/// type.
26638///
26639/// @param other the other instance of @ref
26640/// member_class_template to compare against.
26641///
26642/// @return true iff the two instances are equal.
26643bool
26645{
26646 const decl_base* o = dynamic_cast<const decl_base*>(&other);
26647 return *this == *o;
26648}
26649
26650/// Comparison operator for the @ref member_class_template
26651/// type.
26652///
26653/// @param l the first argument of the operator.
26654///
26655/// @param r the second argument of the operator.
26656///
26657/// @return true iff the two instances are equal.
26658bool
26659operator==(const member_class_template_sptr& l,
26660 const member_class_template_sptr& r)
26661{
26662 if (l.get() == r.get())
26663 return true;
26664 if (!!l != !!r)
26665 return false;
26666
26667 return *l == *r;
26668}
26669
26670/// Inequality operator for the @ref member_class_template
26671/// type.
26672///
26673/// @param l the first argument of the operator.
26674///
26675/// @param r the second argument of the operator.
26676///
26677/// @return true iff the two instances are equal.
26678bool
26679operator!=(const member_class_template_sptr& l,
26680 const member_class_template_sptr& r)
26681{return !operator==(l, r);}
26682
26683/// This implements the ir_traversable_base::traverse pure virtual
26684/// function.
26685///
26686/// @param v the visitor used on the current instance and on the class
26687/// pattern of the template.
26688///
26689/// @return true if the entire IR node tree got traversed, false
26690/// otherwise.
26691bool
26693{
26694 if (visiting())
26695 return true;
26696
26697 if (v.visit_begin(this))
26698 {
26699 visiting(true);
26700 if (class_tdecl_sptr t = as_class_tdecl())
26701 t->traverse(v);
26702 visiting(false);
26703 }
26704 return v.visit_end(this);
26705}
26706
26707/// Streaming operator for class_decl::access_specifier.
26708///
26709/// @param o the output stream to serialize the access specifier to.
26710///
26711/// @param a the access specifier to serialize.
26712///
26713/// @return the output stream.
26714std::ostream&
26715operator<<(std::ostream& o, access_specifier a)
26716{
26717 string r;
26718
26719 switch (a)
26720 {
26721 case no_access:
26722 r = "none";
26723 break;
26724 case private_access:
26725 r = "private";
26726 break;
26727 case protected_access:
26728 r = "protected";
26729 break;
26730 case public_access:
26731 r= "public";
26732 break;
26733 };
26734 o << r;
26735 return o;
26736}
26737
26738/// Sets the static-ness property of a class member.
26739///
26740/// @param d the class member to set the static-ness property for.
26741/// Note that this must be a class member otherwise the function
26742/// aborts the current process.
26743///
26744/// @param s this must be true if the member is to be static, false
26745/// otherwise.
26746void
26748{
26750
26752 ABG_ASSERT(c);
26753
26754 c->set_is_static(s);
26755
26756 scope_decl* scope = d.get_scope();
26757
26758 if (class_or_union* cl = is_class_or_union_type(scope))
26759 {
26760 if (var_decl* v = is_var_decl(&d))
26761 {
26762 // First, find v in the set of data members.
26763 var_decl_sptr var;
26764 for (const auto& dm : cl->get_data_members())
26765 if (dm->get_name() == v->get_name())
26766 {
26767 var = dm;
26768 break;
26769 }
26770 if (!var)
26771 return;
26772
26773 if (s)
26774 {
26775 // remove from the non-static data members
26776 for (class_decl::data_members::iterator i =
26777 cl->priv_->non_static_data_members_.begin();
26778 i != cl->priv_->non_static_data_members_.end();
26779 ++i)
26780 {
26781 if ((*i)->get_name() == v->get_name())
26782 {
26783 cl->priv_->non_static_data_members_.erase(i);
26784 break;
26785 }
26786 }
26787
26788 // If it's not in the static data members, then add it
26789 // there.
26790 bool already_in_static_dms = false;
26791 for (const auto& s_dm : cl->priv_->static_data_members_)
26792 if (s_dm->get_name() == v->get_name())
26793 {
26794 already_in_static_dms = true;
26795 break;
26796 }
26797 if (!already_in_static_dms)
26798 cl->priv_->static_data_members_.push_back(var);
26799 }
26800 else // is non-static
26801 {
26802 // Remove from the static data members.
26803 for (class_or_union::data_members::iterator i =
26804 cl->priv_->static_data_members_.begin();
26805 i != cl->priv_->static_data_members_.end();
26806 ++i)
26807 if ((*i)->get_name() == v->get_name())
26808 {
26809 cl->priv_->static_data_members_.erase(i);
26810 break;
26811 }
26812
26813 // If it's not already in the non-static data members
26814 // then add it there.
26815 bool is_already_in_non_static_data_members = false;
26816 for (const auto& ns_dm : cl->priv_->non_static_data_members_)
26817 if (ns_dm->get_name() == v->get_name())
26818 {
26819 is_already_in_non_static_data_members = true;
26820 break;
26821 }
26822 if (!is_already_in_non_static_data_members)
26823 cl->priv_->non_static_data_members_.push_back(var);
26824 }
26825 }
26826 }
26827}
26828
26829/// Sets the static-ness property of a class member.
26830///
26831/// @param d the class member to set the static-ness property for.
26832/// Note that this must be a class member otherwise the function
26833/// aborts the current process.
26834///
26835/// @param s this must be true if the member is to be static, false
26836/// otherwise.
26837void
26838set_member_is_static(const decl_base_sptr& d, bool s)
26839{set_member_is_static(*d, s);}
26840
26841// </class_decl>
26842
26843// <union_decl>
26844
26845/// Constructor for the @ref union_decl type.
26846///
26847/// @param env the @ref environment we are operating from.
26848///
26849/// @param name the name of the union type.
26850///
26851/// @param size_in_bits the size of the union, in bits.
26852///
26853/// @param locus the location of the type.
26854///
26855/// @param vis the visibility of instances of @ref union_decl.
26856///
26857/// @param mbr_types the member types of the union.
26858///
26859/// @param data_mbrs the data members of the union.
26860///
26861/// @param member_fns the member functions of the union.
26862union_decl::union_decl(const environment& env, const string& name,
26863 size_t size_in_bits, const location& locus,
26864 visibility vis, member_types& mbr_types,
26865 data_members& data_mbrs, member_functions& member_fns)
26866 : type_or_decl_base(env,
26867 UNION_TYPE
26868 | ABSTRACT_TYPE_BASE
26869 | ABSTRACT_DECL_BASE),
26870 decl_base(env, name, locus, name, vis),
26871 type_base(env, size_in_bits, 0),
26872 class_or_union(env, name, size_in_bits, 0,
26873 locus, vis, mbr_types, data_mbrs, member_fns)
26874{
26876}
26877
26878/// Constructor for the @ref union_decl type.
26879///
26880/// @param env the @ref environment we are operating from.
26881///
26882/// @param name the name of the union type.
26883///
26884/// @param size_in_bits the size of the union, in bits.
26885///
26886/// @param locus the location of the type.
26887///
26888/// @param vis the visibility of instances of @ref union_decl.
26889///
26890/// @param mbr_types the member types of the union.
26891///
26892/// @param data_mbrs the data members of the union.
26893///
26894/// @param member_fns the member functions of the union.
26895///
26896/// @param is_anonymous whether the newly created instance is
26897/// anonymous.
26898union_decl::union_decl(const environment& env, const string& name,
26899 size_t size_in_bits, const location& locus,
26900 visibility vis, member_types& mbr_types,
26901 data_members& data_mbrs, member_functions& member_fns,
26902 bool is_anonymous)
26903 : type_or_decl_base(env,
26904 UNION_TYPE
26905 | ABSTRACT_TYPE_BASE
26906 | ABSTRACT_DECL_BASE),
26907 decl_base(env, name, locus,
26908 // If the class is anonymous then by default it won't
26909 // have a linkage name. Also, the anonymous class does
26910 // have an internal-only unique name that is generally
26911 // not taken into account when comparing classes; such a
26912 // unique internal-only name, when used as a linkage
26913 // name might introduce spurious comparison false
26914 // negatives.
26915 /*linkage_name=*/is_anonymous ? string() : name,
26916 vis),
26917 type_base(env, size_in_bits, 0),
26918 class_or_union(env, name, size_in_bits, 0,
26919 locus, vis, mbr_types, data_mbrs, member_fns)
26920{
26922 set_is_anonymous(is_anonymous);
26923}
26924
26925/// Constructor for the @ref union_decl type.
26926///
26927/// @param env the @ref environment we are operating from.
26928///
26929/// @param name the name of the union type.
26930///
26931/// @param size_in_bits the size of the union, in bits.
26932///
26933/// @param locus the location of the type.
26934///
26935/// @param vis the visibility of instances of @ref union_decl.
26936union_decl::union_decl(const environment& env, const string& name,
26937 size_t size_in_bits, const location& locus,
26938 visibility vis)
26939 : type_or_decl_base(env,
26940 UNION_TYPE
26941 | ABSTRACT_TYPE_BASE
26942 | ABSTRACT_DECL_BASE
26943 | ABSTRACT_SCOPE_TYPE_DECL
26944 | ABSTRACT_SCOPE_DECL),
26945 decl_base(env, name, locus, name, vis),
26946 type_base(env, size_in_bits, 0),
26947 class_or_union(env, name, size_in_bits,
26948 0, locus, vis)
26949{
26951}
26952
26953/// Constructor for the @ref union_decl type.
26954///
26955/// @param env the @ref environment we are operating from.
26956///
26957/// @param name the name of the union type.
26958///
26959/// @param size_in_bits the size of the union, in bits.
26960///
26961/// @param locus the location of the type.
26962///
26963/// @param vis the visibility of instances of @ref union_decl.
26964///
26965/// @param is_anonymous whether the newly created instance is
26966/// anonymous.
26967union_decl::union_decl(const environment& env, const string& name,
26968 size_t size_in_bits, const location& locus,
26969 visibility vis, bool is_anonymous)
26970 : type_or_decl_base(env,
26971 UNION_TYPE
26972 | ABSTRACT_TYPE_BASE
26973 | ABSTRACT_DECL_BASE
26974 | ABSTRACT_SCOPE_TYPE_DECL
26975 | ABSTRACT_SCOPE_DECL),
26976 decl_base(env, name, locus,
26977 // If the class is anonymous then by default it won't
26978 // have a linkage name. Also, the anonymous class does
26979 // have an internal-only unique name that is generally
26980 // not taken into account when comparing classes; such a
26981 // unique internal-only name, when used as a linkage
26982 // name might introduce spurious comparison false
26983 // negatives.
26984 /*linkage_name=*/is_anonymous ? string() : name,
26985 vis),
26986 type_base(env, size_in_bits, 0),
26987 class_or_union(env, name, size_in_bits,
26988 0, locus, vis)
26989{
26991 set_is_anonymous(is_anonymous);
26992}
26993
26994/// Constructor for the @ref union_decl type.
26995///
26996/// @param env the @ref environment we are operating from.
26997///
26998/// @param name the name of the union type.
26999///
27000/// @param is_declaration_only a boolean saying whether the instance
27001/// represents a declaration only, or not.
27002union_decl::union_decl(const environment& env,
27003 const string& name,
27004 bool is_declaration_only)
27005 : type_or_decl_base(env,
27006 UNION_TYPE
27007 | ABSTRACT_TYPE_BASE
27008 | ABSTRACT_DECL_BASE
27009 | ABSTRACT_SCOPE_TYPE_DECL
27010 | ABSTRACT_SCOPE_DECL),
27011 decl_base(env, name, location(), name),
27012 type_base(env, 0, 0),
27013 class_or_union(env, name, is_declaration_only)
27014{
27016}
27017
27018/// Return the hash value of the current IR node.
27019///
27020/// Note that upon the first invocation, this member functions
27021/// computes the hash value and returns it. Subsequent invocations
27022/// just return the hash value that was previously calculated.
27023///
27024/// @return the hash value of the current IR node.
27025hash_t
27027{
27029 return h;
27030}
27031
27032/// Getter of the pretty representation of the current instance of
27033/// @ref union_decl.
27034///
27035/// @param internal set to true if the call is intended to get a
27036/// representation of the decl (or type) for the purpose of canonical
27037/// type comparison. This is mainly used in the function
27038/// type_base::get_canonical_type_for().
27039///
27040/// In other words if the argument for this parameter is true then the
27041/// call is meant for internal use (for technical use inside the
27042/// library itself), false otherwise. If you don't know what this is
27043/// for, then set it to false.
27044///
27045/// @param qualified_name if true, names emitted in the pretty
27046/// representation are fully qualified.
27047///
27048/// @return the pretty representaion for a union_decl.
27049string
27051 bool qualified_name) const
27052{
27053 string repr;
27054 if (get_is_anonymous())
27055 {
27056 if (internal && !get_name().empty())
27057 repr = string("union ") +
27058 get_type_name(this, qualified_name, /*internal=*/true);
27059 else
27061 /*one_line=*/true,
27062 internal);
27063 }
27064 else
27065 {
27066 repr = "union ";
27067 if (qualified_name)
27068 repr += get_qualified_name(internal);
27069 else
27070 repr += get_name();
27071 }
27072
27073 return repr;
27074}
27075
27076/// Comparison operator for @ref union_decl.
27077///
27078/// @param other the instance of @ref union_decl to compare against.
27079///
27080/// @return true iff the current instance of @ref union_decl equals @p
27081/// other.
27082bool
27084{
27085 const union_decl* op = dynamic_cast<const union_decl*>(&other);
27086 if (!op)
27087 return false;
27088 return try_canonical_compare(this, op);
27089}
27090
27091/// Equality operator for union_decl.
27092///
27093/// Re-uses the equality operator that takes a decl_base.
27094///
27095/// @param other the other union_decl to compare against.
27096///
27097/// @return true iff the current instance equals the other one.
27098bool
27100{
27101 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27102 if (!o)
27103 return false;
27104 return *this == *o;
27105}
27106
27107/// Equality operator for union_decl.
27108///
27109/// Re-uses the equality operator that takes a decl_base.
27110///
27111/// @param other the other union_decl to compare against.
27112///
27113/// @return true iff the current instance equals the other one.
27114bool
27116{
27117 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27118 return *this == *o;
27119}
27120
27121/// Comparison operator for @ref union_decl.
27122///
27123/// @param other the instance of @ref union_decl to compare against.
27124///
27125/// @return true iff the current instance of @ref union_decl equals @p
27126/// other.
27127bool
27129{
27130 const decl_base& o = other;
27131 return *this == o;
27132}
27133
27134/// This implements the ir_traversable_base::traverse pure virtual
27135/// function.
27136///
27137/// @param v the visitor used on the current instance and on its
27138/// members.
27139///
27140/// @return true if the entire IR node tree got traversed, false
27141/// otherwise.
27142bool
27144{
27145 if (v.type_node_has_been_visited(this))
27146 return true;
27147
27148 if (visiting())
27149 return true;
27150
27151 if (v.visit_begin(this))
27152 {
27153 visiting(true);
27154 bool stop = false;
27155
27156 if (!stop)
27157 for (data_members::const_iterator i = get_data_members().begin();
27158 i != get_data_members().end();
27159 ++i)
27160 if (!(*i)->traverse(v))
27161 {
27162 stop = true;
27163 break;
27164 }
27165
27166 if (!stop)
27167 for (member_functions::const_iterator i= get_member_functions().begin();
27168 i != get_member_functions().end();
27169 ++i)
27170 if (!(*i)->traverse(v))
27171 {
27172 stop = true;
27173 break;
27174 }
27175
27176 if (!stop)
27177 for (member_types::const_iterator i = get_member_types().begin();
27178 i != get_member_types().end();
27179 ++i)
27180 if (!(*i)->traverse(v))
27181 {
27182 stop = true;
27183 break;
27184 }
27185
27186 if (!stop)
27187 for (member_function_templates::const_iterator i =
27189 i != get_member_function_templates().end();
27190 ++i)
27191 if (!(*i)->traverse(v))
27192 {
27193 stop = true;
27194 break;
27195 }
27196
27197 if (!stop)
27198 for (member_class_templates::const_iterator i =
27200 i != get_member_class_templates().end();
27201 ++i)
27202 if (!(*i)->traverse(v))
27203 {
27204 stop = true;
27205 break;
27206 }
27207 visiting(false);
27208 }
27209
27210 bool result = v.visit_end(this);
27212 return result;
27213}
27214
27215/// Destructor of the @ref union_decl type.
27217{}
27218
27219/// Compares two instances of @ref union_decl.
27220///
27221/// If the two intances are different, set a bitfield to give some
27222/// insight about the kind of differences there are.
27223///
27224/// @param l the first artifact of the comparison.
27225///
27226/// @param r the second artifact of the comparison.
27227///
27228/// @param k a pointer to a bitfield that gives information about the
27229/// kind of changes there are between @p l and @p r. This one is set
27230/// iff @p k is non-null and the function returns false.
27231///
27232/// Please note that setting k to a non-null value does have a
27233/// negative performance impact because even if @p l and @p r are not
27234/// equal, the function keeps up the comparison in order to determine
27235/// the different kinds of ways in which they are different.
27236///
27237/// @return true if @p l equals @p r, false otherwise.
27238bool
27240{
27241
27243
27244 {
27245 // First of all, let's see if these two types haven't already been
27246 // compared. If so, and if the result of the comparison has been
27247 // cached, let's just re-use it, rather than comparing them all
27248 // over again.
27249 bool result = false;
27250 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
27251 ABG_RETURN(result);
27252 }
27253
27254 bool result = equals(static_cast<const class_or_union&>(l),
27255 static_cast<const class_or_union&>(r),
27256 k);
27257
27259}
27260
27261/// Copy a method of a @ref union_decl into a new @ref
27262/// union_decl.
27263///
27264/// @param t the @ref union_decl into which the method is to be copied.
27265///
27266/// @param method the method to copy into @p t.
27267///
27268/// @return the resulting newly copied method.
27269method_decl_sptr
27270copy_member_function(const union_decl_sptr& union_type,
27271 const method_decl_sptr& f)
27272{return copy_member_function(union_type, f.get());}
27273
27274/// Copy a method of a @ref union_decl into a new @ref
27275/// union_decl.
27276///
27277/// @param t the @ref union_decl into which the method is to be copied.
27278///
27279/// @param method the method to copy into @p t.
27280///
27281/// @return the resulting newly copied method.
27282method_decl_sptr
27283copy_member_function(const union_decl_sptr& union_type,
27284 const method_decl* f)
27285{
27286 const class_or_union_sptr t = union_type;
27287 return copy_member_function(t, f);
27288}
27289
27290/// Turn equality of shared_ptr of union_decl into a deep equality;
27291/// that is, make it compare the pointed to objects too.
27292///
27293/// @param l the left-hand-side operand of the operator
27294///
27295/// @param r the right-hand-side operand of the operator.
27296///
27297/// @return true iff @p l equals @p r.
27298bool
27299operator==(const union_decl_sptr& l, const union_decl_sptr& r)
27300{
27301 if (l.get() == r.get())
27302 return true;
27303 if (!!l != !!r)
27304 return false;
27305
27306 return *l == *r;
27307}
27308
27309/// Turn inequality of shared_ptr of union_decl into a deep equality;
27310/// that is, make it compare the pointed to objects too.
27311///
27312/// @param l the left-hand-side operand of the operator
27313///
27314/// @param r the right-hand-side operand of the operator.
27315///
27316/// @return true iff @p l is different from @p r.
27317bool
27318operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
27319{return !operator==(l, r);}
27320// </union_decl>
27321
27322// <template_decl stuff>
27323
27324/// Data type of the private data of the @template_decl type.
27325class template_decl::priv
27326{
27327 friend class template_decl;
27328
27329 std::list<template_parameter_sptr> parms_;
27330public:
27331
27332 priv()
27333 {}
27334}; // end class template_decl::priv
27335
27336/// Add a new template parameter to the current instance of @ref
27337/// template_decl.
27338///
27339/// @param p the new template parameter to add.
27340void
27342{priv_->parms_.push_back(p);}
27343
27344/// Get the list of template parameters of the current instance of
27345/// @ref template_decl.
27346///
27347/// @return the list of template parameters.
27348const std::list<template_parameter_sptr>&
27350{return priv_->parms_;}
27351
27352/// Constructor.
27353///
27354/// @param env the environment we are operating from.
27355///
27356/// @param name the name of the template decl.
27357///
27358/// @param locus the source location where the template declaration is
27359/// defined.
27360///
27361/// @param vis the visibility of the template declaration.
27362template_decl::template_decl(const environment& env,
27363 const string& name,
27364 const location& locus,
27365 visibility vis)
27366 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
27367 decl_base(env, name, locus, /*mangled_name=*/"", vis),
27368 priv_(new priv)
27369{
27371}
27372
27373/// Destructor.
27375{}
27376
27377/// Equality operator.
27378///
27379/// @param o the other instance to compare against.
27380///
27381/// @return true iff @p equals the current instance.
27382bool
27384{
27385 const template_decl* other = dynamic_cast<const template_decl*>(&o);
27386 if (!other)
27387 return false;
27388 return *this == *other;
27389}
27390
27391/// Equality operator.
27392///
27393/// @param o the other instance to compare against.
27394///
27395/// @return true iff @p equals the current instance.
27396bool
27398{
27399 try
27400 {
27401 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
27402 for (t0 = get_template_parameters().begin(),
27403 t1 = o.get_template_parameters().begin();
27404 (t0 != get_template_parameters().end()
27405 && t1 != o.get_template_parameters().end());
27406 ++t0, ++t1)
27407 {
27408 if (**t0 != **t1)
27409 return false;
27410 }
27411
27412 if (t0 != get_template_parameters().end()
27413 || t1 != o.get_template_parameters().end())
27414 return false;
27415
27416 return true;
27417 }
27418 catch(...)
27419 {return false;}
27420}
27421
27422// </template_decl stuff>
27423
27424//<template_parameter>
27425
27426/// The type of the private data of the @ref template_parameter type.
27427class template_parameter::priv
27428{
27429 friend class template_parameter;
27430
27431 unsigned index_;
27432 template_decl_wptr template_decl_;
27433 mutable bool hashing_started_;
27434 mutable bool comparison_started_;
27435
27436 priv();
27437
27438public:
27439
27440 priv(unsigned index, template_decl_sptr enclosing_template_decl)
27441 : index_(index),
27442 template_decl_(enclosing_template_decl),
27443 hashing_started_(),
27444 comparison_started_()
27445 {}
27446}; // end class template_parameter::priv
27447
27448template_parameter::template_parameter(unsigned index,
27449 template_decl_sptr enclosing_template)
27450 : priv_(new priv(index, enclosing_template))
27451 {}
27452
27453unsigned
27454template_parameter::get_index() const
27455{return priv_->index_;}
27456
27458template_parameter::get_enclosing_template_decl() const
27459{return priv_->template_decl_.lock();}
27460
27461
27462bool
27463template_parameter::operator==(const template_parameter& o) const
27464{
27465 if (get_index() != o.get_index())
27466 return false;
27467
27468 if (priv_->comparison_started_)
27469 return true;
27470
27471 bool result = false;
27472
27473 // Avoid inifite loops due to the fact that comparison the enclosing
27474 // template decl might lead to comparing this very same template
27475 // parameter with another one ...
27476 priv_->comparison_started_ = true;
27477
27478 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
27479 ;
27480 else if (get_enclosing_template_decl()
27481 && (*get_enclosing_template_decl()
27482 != *o.get_enclosing_template_decl()))
27483 ;
27484 else
27485 result = true;
27486
27487 priv_->comparison_started_ = false;
27488
27489 return result;
27490}
27491
27492/// Inequality operator.
27493///
27494/// @param other the other instance to compare against.
27495///
27496/// @return true iff the other instance is different from the current
27497/// one.
27498bool
27500{return !operator==(other);}
27501
27502/// Destructor.
27504{}
27505
27506/// The type of the private data of the @ref type_tparameter type.
27507class type_tparameter::priv
27508{
27509 friend class type_tparameter;
27510}; // end class type_tparameter::priv
27511
27512/// Constructor of the @ref type_tparameter type.
27513///
27514/// @param index the index the type template parameter.
27515///
27516/// @param enclosing_tdecl the enclosing template declaration.
27517///
27518/// @param name the name of the template parameter.
27519///
27520/// @param locus the location of the declaration of this type template
27521/// parameter.
27522type_tparameter::type_tparameter(unsigned index,
27523 template_decl_sptr enclosing_tdecl,
27524 const string& name,
27525 const location& locus)
27526 : type_or_decl_base(enclosing_tdecl->get_environment(),
27527 ABSTRACT_DECL_BASE
27528 | ABSTRACT_TYPE_BASE
27529 | BASIC_TYPE),
27530 decl_base(enclosing_tdecl->get_environment(), name, locus),
27531 type_base(enclosing_tdecl->get_environment(), 0, 0),
27532 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
27533 template_parameter(index, enclosing_tdecl),
27534 priv_(new priv)
27535{
27537}
27538
27539/// Equality operator.
27540///
27541/// @param other the other template type parameter to compare against.
27542///
27543/// @return true iff @p other equals the current instance.
27544bool
27546{
27547 if (!type_decl::operator==(other))
27548 return false;
27549
27550 try
27551 {
27552 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27554 }
27555 catch (...)
27556 {return false;}
27557}
27558
27559/// Equality operator.
27560///
27561/// @param other the other template type parameter to compare against.
27562///
27563/// @return true iff @p other equals the current instance.
27564bool
27566{
27567 if (!type_decl::operator==(other))
27568 return false;
27569
27570 try
27571 {
27572 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27574 }
27575 catch (...)
27576 {return false;}
27577}
27578
27579/// Equality operator.
27580///
27581/// @param other the other template type parameter to compare against.
27582///
27583/// @return true iff @p other equals the current instance.
27584bool
27586{
27587 if (!decl_base::operator==(other))
27588 return false;
27589
27590 try
27591 {
27592 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27594 }
27595 catch (...)
27596 {return false;}
27597}
27598
27599/// Equality operator.
27600///
27601/// @param other the other template type parameter to compare against.
27602///
27603/// @return true iff @p other equals the current instance.
27604bool
27606{
27607 try
27608 {
27609 const type_base& o = dynamic_cast<const type_base&>(other);
27610 return *this == o;
27611 }
27612 catch(...)
27613 {return false;}
27614}
27615
27616/// Equality operator.
27617///
27618/// @param other the other template type parameter to compare against.
27619///
27620/// @return true iff @p other equals the current instance.
27621bool
27623{return *this == static_cast<const type_base&>(other);}
27624
27625type_tparameter::~type_tparameter()
27626{}
27627
27628/// The type of the private data of the @ref non_type_tparameter type.
27629class non_type_tparameter::priv
27630{
27631 friend class non_type_tparameter;
27632
27633 type_base_wptr type_;
27634
27635 priv();
27636
27637public:
27638
27639 priv(type_base_sptr type)
27640 : type_(type)
27641 {}
27642}; // end class non_type_tparameter::priv
27643
27644/// The constructor for the @ref non_type_tparameter type.
27645///
27646/// @param index the index of the template parameter.
27647///
27648/// @param enclosing_tdecl the enclosing template declaration that
27649/// holds this parameter parameter.
27650///
27651/// @param name the name of the template parameter.
27652///
27653/// @param type the type of the template parameter.
27654///
27655/// @param locus the location of the declaration of this template
27656/// parameter.
27657non_type_tparameter::non_type_tparameter(unsigned index,
27658 template_decl_sptr enclosing_tdecl,
27659 const string& name,
27660 type_base_sptr type,
27661 const location& locus)
27662 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
27663 decl_base(type->get_environment(), name, locus, ""),
27664 template_parameter(index, enclosing_tdecl),
27665 priv_(new priv(type))
27666{
27668}
27669
27670/// Getter for the type of the template parameter.
27671///
27672/// @return the type of the template parameter.
27673const type_base_sptr
27675{return priv_->type_.lock();}
27676
27677
27678bool
27680{
27681 if (!decl_base::operator==(other))
27682 return false;
27683
27684 try
27685 {
27686 const non_type_tparameter& o =
27687 dynamic_cast<const non_type_tparameter&>(other);
27688 return (template_parameter::operator==(o)
27689 && get_type() == o.get_type());
27690 }
27691 catch(...)
27692 {return false;}
27693}
27694
27695bool
27697{
27698 try
27699 {
27700 const decl_base& o = dynamic_cast<const decl_base&>(other);
27701 return *this == o;
27702 }
27703 catch(...)
27704 {return false;}
27705}
27706
27707non_type_tparameter::~non_type_tparameter()
27708{}
27709
27710// <template_tparameter stuff>
27711
27712/// Type of the private data of the @ref template_tparameter type.
27713class template_tparameter::priv
27714{
27715}; //end class template_tparameter::priv
27716
27717/// Constructor for the @ref template_tparameter.
27718///
27719/// @param index the index of the template parameter.
27720///
27721/// @param enclosing_tdecl the enclosing template declaration.
27722///
27723/// @param name the name of the template parameter.
27724///
27725/// @param locus the location of the declaration of the template
27726/// parameter.
27727template_tparameter::template_tparameter(unsigned index,
27728 template_decl_sptr enclosing_tdecl,
27729 const string& name,
27730 const location& locus)
27731 : type_or_decl_base(enclosing_tdecl->get_environment(),
27732 ABSTRACT_DECL_BASE
27733 | ABSTRACT_TYPE_BASE
27734 | BASIC_TYPE),
27735 decl_base(enclosing_tdecl->get_environment(), name, locus),
27736 type_base(enclosing_tdecl->get_environment(), 0, 0),
27737 type_decl(enclosing_tdecl->get_environment(), name,
27738 0, 0, locus, name, VISIBILITY_DEFAULT),
27739 type_tparameter(index, enclosing_tdecl, name, locus),
27740 template_decl(enclosing_tdecl->get_environment(), name, locus),
27741 priv_(new priv)
27742{
27744}
27745
27746/// Equality operator.
27747///
27748/// @param other the other template parameter to compare against.
27749///
27750/// @return true iff @p other equals the current instance.
27751bool
27753{
27754 try
27755 {
27756 const template_tparameter& o =
27757 dynamic_cast<const template_tparameter&>(other);
27758 return (type_tparameter::operator==(o)
27760 }
27761 catch(...)
27762 {return false;}
27763}
27764
27765/// Equality operator.
27766///
27767/// @param other the other template parameter to compare against.
27768///
27769/// @return true iff @p other equals the current instance.
27770bool
27772{
27773 try
27774 {
27775 const template_tparameter& o =
27776 dynamic_cast<const template_tparameter&>(other);
27777 return (type_tparameter::operator==(o)
27779 }
27780 catch(...)
27781 {return false;}
27782}
27783
27784bool
27786{
27787 try
27788 {
27789 const template_tparameter& other =
27790 dynamic_cast<const template_tparameter&>(o);
27791 return *this == static_cast<const type_base&>(other);
27792 }
27793 catch(...)
27794 {return false;}
27795}
27796
27797bool
27799{
27800 try
27801 {
27802 const template_tparameter& other =
27803 dynamic_cast<const template_tparameter&>(o);
27804 return type_base::operator==(other);
27805 }
27806 catch(...)
27807 {return false;}
27808}
27809
27810template_tparameter::~template_tparameter()
27811{}
27812
27813// </template_tparameter stuff>
27814
27815// <type_composition stuff>
27816
27817/// The type of the private data of the @ref type_composition type.
27818class type_composition::priv
27819{
27820 friend class type_composition;
27821
27822 type_base_wptr type_;
27823
27824 // Forbid this.
27825 priv();
27826
27827public:
27828
27829 priv(type_base_wptr type)
27830 : type_(type)
27831 {}
27832}; //end class type_composition::priv
27833
27834/// Constructor for the @ref type_composition type.
27835///
27836/// @param index the index of the template type composition.
27837///
27838/// @param tdecl the enclosing template parameter that owns the
27839/// composition.
27840///
27841/// @param t the resulting type.
27842type_composition::type_composition(unsigned index,
27843 template_decl_sptr tdecl,
27844 type_base_sptr t)
27845 : type_or_decl_base(tdecl->get_environment(),
27846 ABSTRACT_DECL_BASE),
27847 decl_base(tdecl->get_environment(), "", location()),
27848 template_parameter(index, tdecl),
27849 priv_(new priv(t))
27850{
27852}
27853
27854/// Getter for the resulting composed type.
27855///
27856/// @return the composed type.
27857const type_base_sptr
27859{return priv_->type_.lock();}
27860
27861/// Setter for the resulting composed type.
27862///
27863/// @param t the composed type.
27864void
27866{priv_->type_ = t;}
27867
27868type_composition::~type_composition()
27869{}
27870
27871// </type_composition stuff>
27872
27873//</template_parameter stuff>
27874
27875// <function_template>
27876
27877class function_tdecl::priv
27878{
27879 friend class function_tdecl;
27880
27881 function_decl_sptr pattern_;
27882 binding binding_;
27883
27884 priv();
27885
27886public:
27887
27888 priv(function_decl_sptr pattern, binding bind)
27889 : pattern_(pattern), binding_(bind)
27890 {}
27891
27892 priv(binding bind)
27893 : binding_(bind)
27894 {}
27895}; // end class function_tdecl::priv
27896
27897/// Constructor for a function template declaration.
27898///
27899/// @param env the environment we are operating from.
27900///
27901/// @param locus the location of the declaration.
27902///
27903/// @param vis the visibility of the declaration. This is the
27904/// visibility the functions instantiated from this template are going
27905/// to have.
27906///
27907/// @param bind the binding of the declaration. This is the binding
27908/// the functions instantiated from this template are going to have.
27909function_tdecl::function_tdecl(const environment& env,
27910 const location& locus,
27911 visibility vis,
27912 binding bind)
27913 : type_or_decl_base(env,
27914 ABSTRACT_DECL_BASE
27915 | TEMPLATE_DECL
27916 | ABSTRACT_SCOPE_DECL),
27917 decl_base(env, "", locus, "", vis),
27918 template_decl(env, "", locus, vis),
27919 scope_decl(env, "", locus),
27920 priv_(new priv(bind))
27921{
27923}
27924
27925/// Constructor for a function template declaration.
27926///
27927/// @param pattern the pattern of the template.
27928///
27929/// @param locus the location of the declaration.
27930///
27931/// @param vis the visibility of the declaration. This is the
27932/// visibility the functions instantiated from this template are going
27933/// to have.
27934///
27935/// @param bind the binding of the declaration. This is the binding
27936/// the functions instantiated from this template are going to have.
27937function_tdecl::function_tdecl(function_decl_sptr pattern,
27938 const location& locus,
27939 visibility vis,
27940 binding bind)
27941 : type_or_decl_base(pattern->get_environment(),
27942 ABSTRACT_DECL_BASE
27943 | TEMPLATE_DECL
27944 | ABSTRACT_SCOPE_DECL),
27945 decl_base(pattern->get_environment(), pattern->get_name(), locus,
27946 pattern->get_name(), vis),
27947 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
27948 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
27949 priv_(new priv(pattern, bind))
27950{
27952}
27953
27954/// Set a new pattern to the function template.
27955///
27956/// @param p the new pattern.
27957void
27959{
27960 priv_->pattern_ = p;
27961 add_decl_to_scope(p, this);
27962 set_name(p->get_name());
27963}
27964
27965/// Get the pattern of the function template.
27966///
27967/// @return the pattern.
27970{return priv_->pattern_;}
27971
27972/// Get the binding of the function template.
27973///
27974/// @return the binding
27977{return priv_->binding_;}
27978
27979/// Comparison operator for the @ref function_tdecl type.
27980///
27981/// @param other the other instance of @ref function_tdecl to compare against.
27982///
27983/// @return true iff the two instance are equal.
27984bool
27986{
27987 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
27988 if (o)
27989 return *this == *o;
27990 return false;
27991}
27992
27993/// Comparison operator for the @ref function_tdecl type.
27994///
27995/// @param other the other instance of @ref function_tdecl to compare against.
27996///
27997/// @return true iff the two instance are equal.
27998bool
28000{
28001 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
28002 if (o)
28003 return *this == *o;
28004 return false;
28005}
28006
28007/// Comparison operator for the @ref function_tdecl type.
28008///
28009/// @param o the other instance of @ref function_tdecl to compare against.
28010///
28011/// @return true iff the two instance are equal.
28012bool
28014{
28015 if (!(get_binding() == o.get_binding()
28016 && template_decl::operator==(o)
28017 && scope_decl::operator==(o)
28018 && !!get_pattern() == !!o.get_pattern()))
28019 return false;
28020
28021 if (get_pattern())
28022 return (*get_pattern() == *o.get_pattern());
28023
28024 return true;
28025}
28026
28027/// This implements the ir_traversable_base::traverse pure virtual
28028/// function.
28029///
28030/// @param v the visitor used on the current instance and on the
28031/// function pattern of the template.
28032///
28033/// @return true if the entire IR node tree got traversed, false
28034/// otherwise.
28035bool
28037{
28038 if (visiting())
28039 return true;
28040
28041 if (!v.visit_begin(this))
28042 {
28043 visiting(true);
28044 if (get_pattern())
28045 get_pattern()->traverse(v);
28046 visiting(false);
28047 }
28048 return v.visit_end(this);
28049}
28050
28051function_tdecl::~function_tdecl()
28052{}
28053
28054// </function_template>
28055
28056// <class template>
28057
28058/// Type of the private data of the the @ref class_tdecl type.
28059class class_tdecl::priv
28060{
28061 friend class class_tdecl;
28062 class_decl_sptr pattern_;
28063
28064public:
28065
28066 priv()
28067 {}
28068
28069 priv(class_decl_sptr pattern)
28070 : pattern_(pattern)
28071 {}
28072}; // end class class_tdecl::priv
28073
28074/// Constructor for the @ref class_tdecl type.
28075///
28076/// @param env the environment we are operating from.
28077///
28078/// @param locus the location of the declaration of the class_tdecl
28079/// type.
28080///
28081/// @param vis the visibility of the instance of class instantiated
28082/// from this template.
28083class_tdecl::class_tdecl(const environment& env,
28084 const location& locus,
28085 visibility vis)
28086 : type_or_decl_base(env,
28087 ABSTRACT_DECL_BASE
28088 | TEMPLATE_DECL
28089 | ABSTRACT_SCOPE_DECL),
28090 decl_base(env, "", locus, "", vis),
28091 template_decl(env, "", locus, vis),
28092 scope_decl(env, "", locus),
28093 priv_(new priv)
28094{
28096}
28097
28098/// Constructor for the @ref class_tdecl type.
28099///
28100/// @param pattern The details of the class template. This must NOT be a
28101/// null pointer. If you really this to be null, please use the
28102/// constructor above instead.
28103///
28104/// @param locus the source location of the declaration of the type.
28105///
28106/// @param vis the visibility of the instances of class instantiated
28107/// from this template.
28108class_tdecl::class_tdecl(class_decl_sptr pattern,
28109 const location& locus,
28110 visibility vis)
28111 : type_or_decl_base(pattern->get_environment(),
28112 ABSTRACT_DECL_BASE
28113 | TEMPLATE_DECL
28114 | ABSTRACT_SCOPE_DECL),
28115 decl_base(pattern->get_environment(), pattern->get_name(),
28116 locus, pattern->get_name(), vis),
28117 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
28118 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
28119 priv_(new priv(pattern))
28120{
28122}
28123
28124/// Setter of the pattern of the template.
28125///
28126/// @param p the new template.
28127void
28129{
28130 priv_->pattern_ = p;
28131 add_decl_to_scope(p, this);
28132 set_name(p->get_name());
28133}
28134
28135/// Getter of the pattern of the template.
28136///
28137/// @return p the new template.
28140{return priv_->pattern_;}
28141
28142bool
28144{
28145 try
28146 {
28147 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28148
28149 if (!(template_decl::operator==(o)
28150 && scope_decl::operator==(o)
28151 && !!get_pattern() == !!o.get_pattern()))
28152 return false;
28153
28154 if (!get_pattern() || !o.get_pattern())
28155 return true;
28156
28157 return get_pattern()->decl_base::operator==(*o.get_pattern());
28158 }
28159 catch(...) {}
28160 return false;
28161}
28162
28163bool
28165{
28166 try
28167 {
28168 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28169 return *this == static_cast<const decl_base&>(o);
28170 }
28171 catch(...)
28172 {return false;}
28173}
28174
28175bool
28177{return *this == static_cast<const decl_base&>(o);}
28178
28179/// This implements the ir_traversable_base::traverse pure virtual
28180/// function.
28181///
28182/// @param v the visitor used on the current instance and on the class
28183/// pattern of the template.
28184///
28185/// @return true if the entire IR node tree got traversed, false
28186/// otherwise.
28187bool
28189{
28190 if (visiting())
28191 return true;
28192
28193 if (v.visit_begin(this))
28194 {
28195 visiting(true);
28196 if (class_decl_sptr pattern = get_pattern())
28197 pattern->traverse(v);
28198 visiting(false);
28199 }
28200 return v.visit_end(this);
28201}
28202
28203class_tdecl::~class_tdecl()
28204{}
28205
28206/// This visitor checks if a given type as non-canonicalized sub
28207/// types.
28208class non_canonicalized_subtype_detector : public ir::ir_node_visitor
28209{
28210 type_base* type_;
28211 type_base* has_non_canonical_type_;
28212
28213private:
28214 non_canonicalized_subtype_detector();
28215
28216public:
28217 non_canonicalized_subtype_detector(type_base* type)
28218 : type_(type),
28219 has_non_canonical_type_()
28220 {}
28221
28222 /// Return true if the visitor detected that there is a
28223 /// non-canonicalized sub-type.
28224 ///
28225 /// @return true if the visitor detected that there is a
28226 /// non-canonicalized sub-type.
28227 type_base*
28228 has_non_canonical_type() const
28229 {return has_non_canonical_type_;}
28230
28231 /// The intent of this visitor handler is to avoid looking into
28232 /// sub-types of member functions of the type we are traversing.
28233 bool
28234 visit_begin(function_decl* f)
28235 {
28236 // Do not look at sub-types of non-virtual member functions.
28237 if (is_member_function(f)
28239 return false;
28240 return true;
28241 }
28242
28243 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
28244 /// the 'has_non_canonical_type' flag. And in any case, when
28245 /// visiting a sub-type, do not visit its children nodes. So this
28246 /// function only goes to the level below the level of the top-most
28247 /// type.
28248 ///
28249 /// @return true if we are at the same level as the top-most type,
28250 /// otherwise return false.
28251 bool
28252 visit_begin(type_base* t)
28253 {
28254 if (t != type_)
28255 {
28256 if (!t->get_canonical_type())
28257 // We are looking a sub-type of 'type_' which has no
28258 // canonical type. So tada! we found one! Get out right
28259 // now with the trophy.
28260 has_non_canonical_type_ = t;
28261
28262 return false;
28263 }
28264 return true;
28265 }
28266
28267 /// When we are done visiting a sub-type, if it's been flagged as
28268 /// been non-canonicalized, then stop the traversing.
28269 ///
28270 /// Otherwise, keep going.
28271 ///
28272 /// @return false iff the sub-type that has been visited is
28273 /// non-canonicalized.
28274 bool
28275 visit_end(type_base* )
28276 {
28277 if (has_non_canonical_type_)
28278 return false;
28279 return true;
28280 }
28281}; //end class non_canonicalized_subtype_detector
28282
28283/// Test if a type has sub-types that are non-canonicalized.
28284///
28285/// @param t the type which sub-types to consider.
28286///
28287/// @return true if a type has sub-types that are non-canonicalized.
28288type_base*
28290{
28291 if (!t)
28292 return 0;
28293
28294 non_canonicalized_subtype_detector v(t.get());
28295 t->traverse(v);
28296 return v.has_non_canonical_type();
28297}
28298
28299/// Tests if the change of a given type effectively comes from just
28300/// its sub-types. That is, if the type has changed but its type name
28301/// hasn't changed, then the change of the type mostly likely is a
28302/// sub-type change.
28303///
28304/// @param t_v1 the first version of the type.
28305///
28306/// @param t_v2 the second version of the type.
28307///
28308/// @return true iff the type changed and the change is about its
28309/// sub-types.
28310bool
28311type_has_sub_type_changes(const type_base_sptr t_v1,
28312 const type_base_sptr t_v2)
28313{
28314 type_base_sptr t1 = strip_typedef(t_v1);
28315 type_base_sptr t2 = strip_typedef(t_v2);
28316
28317 string repr1 = get_pretty_representation(t1, /*internal=*/false),
28318 repr2 = get_pretty_representation(t2, /*internal=*/false);
28319 return (t1 != t2 && repr1 == repr2);
28320}
28321
28322/// Make sure that the life time of a given (smart pointer to a) type
28323/// is the same as the life time of the libabigail library.
28324///
28325/// @param t the type to consider.
28326void
28327keep_type_alive(type_base_sptr t)
28328{
28329 const environment& env = t->get_environment();
28330 env.priv_->extra_live_types_.push_back(t);
28331}
28332
28333/// Hash an ABI artifact that is either a type or a decl.
28334///
28335/// This function intends to provides the fastest possible hashing for
28336/// types and decls, while being completely correct.
28337///
28338/// Note that if the artifact is a type and if it has a canonical
28339/// type, the hash value is going to be the pointer value of the
28340/// canonical type. Otherwise, this function computes a hash value
28341/// for the type by recursively walking the type members. This last
28342/// code path is possibly *very* slow and should only be used when
28343/// only handful of types are going to be hashed.
28344///
28345/// If the artifact is a decl, then a combination of the hash of its
28346/// type and the hash of the other properties of the decl is computed.
28347///
28348/// @param tod the type or decl to hash.
28349///
28350/// @return the resulting hash value.
28351size_t
28353{
28354 hash_t result = 0;
28355
28356 if (tod == 0)
28357 ;
28358 else if (const type_base* t = is_type(tod))
28359 result = hash_type(t);
28360 else if (const decl_base* d = is_decl(tod))
28361 {
28362 if (const scope_decl* s = is_scope_decl(d))
28363 {
28364 if (const global_scope* g = is_global_scope(s))
28365 result = reinterpret_cast<size_t>(g);
28366 else
28367 result = reinterpret_cast<size_t>(s);
28368 }
28369 else if (var_decl* v = is_var_decl(d))
28370 {
28371 ABG_ASSERT(v->get_type());
28372 hash_t h = hash_type_or_decl(v->get_type());
28373 string repr = v->get_pretty_representation(/*internal=*/true);
28374 std::hash<string> hash_string;
28375 h = hashing::combine_hashes(h, hash_string(repr));
28376 result = h;
28377 }
28378 else if (function_decl* f = is_function_decl(d))
28379 {
28380 ABG_ASSERT(f->get_type());
28381 hash_t h = hash_type_or_decl(f->get_type());
28382 string repr = f->get_pretty_representation(/*internal=*/true);
28383 std::hash<string> hash_string;
28384 h = hashing::combine_hashes(h, hash_string(repr));
28385 result = h;
28386 }
28388 {
28389 type_base_sptr parm_type = p->get_type();
28390 ABG_ASSERT(parm_type);
28391 std::hash<bool> hash_bool;
28392 std::hash<unsigned> hash_unsigned;
28393 hash_t h = hash_type_or_decl(parm_type);
28394 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
28395 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
28396 result = h;
28397 }
28398 else if (class_decl::base_spec *bs = is_class_base_spec(d))
28399 {
28400 member_base::hash hash_member;
28401 std::hash<size_t> hash_size;
28402 std::hash<bool> hash_bool;
28403 type_base_sptr type = bs->get_base_class();
28404 hash_t h = hash_type_or_decl(type);
28405 h = hashing::combine_hashes(h, hash_member(*bs));
28406 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
28407 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
28408 result = h;
28409 }
28410 else
28411 // This is a *really* *SLOW* path. If it shows up in a
28412 // performance profile, I bet it'd be a good idea to try to
28413 // avoid it altogether.
28414 // TODO: recode this function or get rid of it altogethe.
28415 abort();
28416 }
28417 else
28418 // We should never get here.
28419 abort();
28420 return *result;
28421}
28422
28423/// Hash an ABI artifact that is a type.
28424///
28425/// This function intends to provides the fastest possible hashing for
28426/// types while being completely correct.
28427///
28428/// Note that if the type artifact has a canonical type, the hash
28429/// value is going to be the pointer value of the canonical type.
28430/// Otherwise, this function computes a hash value for the type by
28431/// recursively walking the type members. This last code path is
28432/// possibly *very* slow and should only be used when only handful of
28433/// types are going to be hashed.
28434///
28435/// @param t the type or decl to hash.
28436///
28437/// @return the resulting hash value.
28438size_t
28440{return hash_as_canonical_type_or_constant(t);}
28441
28442/// Hash an ABI artifact that is either a type of a decl.
28443///
28444/// @param tod the ABI artifact to hash.
28445///
28446/// @return the hash value of the ABI artifact.
28447size_t
28449{return hash_type_or_decl(tod.get());}
28450
28451/// Get the hash value associated to an IR node.
28452///
28453/// Unlike type_or_decl_base::hash_value(), if the IR has no
28454/// associated hash value, an empty hash value is returned.
28455///
28456/// @param artefact the IR node to consider.
28457///
28458/// @return the hash value stored on the IR node or an empty hash if
28459/// no hash value is stored in the @p artefact.
28460hash_t
28462{
28463 const type_or_decl_base* artefactp = &artefact;
28464 if (decl_base *d = is_decl(artefactp))
28465 {
28467 if (d->type_or_decl_base::priv_->get_hashing_state()
28469 return d->type_or_decl_base::priv_->hash_value_;
28470 }
28471 else if (artefact.priv_->get_hashing_state() == hashing::HASHING_FINISHED_STATE)
28472 return artefact.priv_->hash_value_;
28473
28474 return hash_t();
28475}
28476
28477/// Test if a given type is allowed to be non canonicalized
28478///
28479/// This is a subroutine of hash_as_canonical_type_or_constant.
28480///
28481/// For now, the only types allowed to be non canonicalized in the
28482/// system are (typedefs & pointers to) decl-only class/union, the
28483/// void type and variadic parameter types.
28484///
28485/// @return true iff @p t is a one of the only types allowed to be
28486/// non-canonicalized in the system.
28487bool
28489{
28490 if (!t)
28491 return true;
28492
28493 return (// The IR nodes for the types below are unique across the
28494 // entire ABI corpus. Thus, no need to canonicalize them.
28495 // Maybe we could say otherwise and canonicalize them once
28496 // for all so that they can be removed from here.
28498
28499 // An IR node for the types below can be equal to several
28500 // other types (i.e, a decl-only type t equals a fully
28501 // defined type of the same name in ODR-supported
28502 // languages). Hence, they can't be given a canonical type.
28503 //
28504 // TODO: Maybe add a mode that would detect ODR violations
28505 // that would make a decl-only type co-exists with several
28506 // different definitions of the type in the ABI corpus.
28509 /*look_through_decl_only=*/true)
28511
28512}
28513
28514/// Test if a type is unique in the entire environment.
28515///
28516/// Examples of unique types are void, void* and variadic parameter
28517/// types.
28518///
28519/// @param t the type to test for.
28520///
28521/// @return true iff the type @p t is unique in the entire
28522/// environment.
28523bool
28524is_unique_type(const type_base_sptr& t)
28525{return is_unique_type(t.get());}
28526
28527/// Test if a type is unique in the entire environment.
28528///
28529/// Examples of unique types are void, void* and variadic parameter
28530/// types.
28531///
28532/// @param t the type to test for.
28533///
28534/// @return true iff the type @p t is unique in the entire
28535/// environment.
28536bool
28538{
28539 if (!t)
28540 return false;
28541
28542 const environment& env = t->get_environment();
28543 return (env.is_void_type(t)
28544 || env.is_void_pointer_type(t)
28545 || env.is_variadic_parameter_type(t));
28546}
28547
28548/// For a given type, return its exemplar type.
28549///
28550/// For a given type, its exemplar type is either its canonical type
28551/// or the canonical type of the definition type of a given
28552/// declaration-only type. If the neither of those two types exist,
28553/// then the exemplar type is the given type itself.
28554///
28555/// @param type the input to consider.
28556///
28557/// @return the exemplar type.
28558type_base*
28560{
28561 if (decl_base * decl = is_decl(type))
28562 {
28563 // Make sure we get the real definition of a decl-only type.
28564 decl = look_through_decl_only(decl);
28565 type = is_type(decl);
28566 ABG_ASSERT(type);
28567 }
28568 type_base *exemplar = type->get_naked_canonical_type();
28569 if (!exemplar)
28570 {
28571 // The type has no canonical type. Let's be sure that it's one
28572 // of those rare types that are allowed to be non canonicalized
28573 // in the system.
28574 exemplar = const_cast<type_base*>(type);
28576 }
28577 return exemplar;
28578}
28579
28580/// Test if a given type is allowed to be non canonicalized
28581///
28582/// This is a subroutine of hash_as_canonical_type_or_constant.
28583///
28584/// For now, the only types allowed to be non canonicalized in the
28585/// system are decl-only class/union and the void type.
28586///
28587/// @return true iff @p t is a one of the only types allowed to be
28588/// non-canonicalized in the system.
28589bool
28590is_non_canonicalized_type(const type_base_sptr& t)
28591{return is_non_canonicalized_type(t.get());}
28592
28593/// Hash a type by either returning the pointer value of its canonical
28594/// type or by returning a constant if the type doesn't have a
28595/// canonical type.
28596///
28597/// This is a subroutine of hash_type.
28598///
28599/// @param t the type to consider.
28600///
28601/// @return the hash value.
28602static size_t
28603hash_as_canonical_type_or_constant(const type_base *t)
28604{
28605 type_base *canonical_type = 0;
28606
28607 if (t)
28608 canonical_type = t->get_naked_canonical_type();
28609
28610 if (!canonical_type)
28611 {
28612 // If the type doesn't have a canonical type, maybe it's because
28613 // it's a declaration-only type? If that's the case, let's try
28614 // to get the canonical type of the definition of this
28615 // declaration.
28616 decl_base *decl = is_decl(t);
28617 if (decl
28618 && decl->get_is_declaration_only()
28620 {
28621 type_base *definition =
28623 ABG_ASSERT(definition);
28624 canonical_type = definition->get_naked_canonical_type();
28625 }
28626 }
28627
28628 if (canonical_type)
28629 return reinterpret_cast<size_t>(canonical_type);
28630
28631 // If we reached this point, it means we are seeing a
28632 // non-canonicalized type. It must be a decl-only class or a void
28633 // type, otherwise it means that for some weird reason, the type
28634 // hasn't been canonicalized. It should be!
28636
28637 return 0xDEADBABE;
28638}
28639
28640/// Test if the pretty representation of a given @ref function_decl is
28641/// lexicographically less then the pretty representation of another
28642/// @ref function_decl.
28643///
28644/// @param f the first @ref function_decl to consider for comparison.
28645///
28646/// @param s the second @ref function_decl to consider for comparison.
28647///
28648/// @return true iff the pretty representation of @p f is
28649/// lexicographically less than the pretty representation of @p s.
28650bool
28652{
28655
28656 if (fr != sr)
28657 return fr < sr;
28658
28659 fr = f.get_pretty_representation(/*internal=*/true),
28660 sr = s.get_pretty_representation(/*internal=*/true);
28661
28662 if (fr != sr)
28663 return fr < sr;
28664
28665 if (f.get_symbol())
28666 fr = f.get_symbol()->get_id_string();
28667 else if (!f.get_linkage_name().empty())
28668 fr = f.get_linkage_name();
28669
28670 if (s.get_symbol())
28671 sr = s.get_symbol()->get_id_string();
28672 else if (!s.get_linkage_name().empty())
28673 sr = s.get_linkage_name();
28674
28675 return fr < sr;
28676}
28677
28678/// Test if two types have similar structures, even though they are
28679/// (or can be) different.
28680///
28681/// const and volatile qualifiers are completely ignored.
28682///
28683/// typedef are resolved to their definitions; their names are ignored.
28684///
28685/// Two indirect types (pointers or references) have similar structure
28686/// if their underlying types are of the same kind and have the same
28687/// name. In the indirect types case, the size of the underlying type
28688/// does not matter.
28689///
28690/// Two direct types (i.e, non indirect) have a similar structure if
28691/// they have the same kind, name and size. Two class types have
28692/// similar structure if they have the same name, size, and if the
28693/// types of their data members have similar types.
28694///
28695/// @param first the first type to consider.
28696///
28697/// @param second the second type to consider.
28698///
28699/// @param indirect_type whether to do an indirect comparison
28700///
28701/// @return true iff @p first and @p second have similar structures.
28702bool
28703types_have_similar_structure(const type_base_sptr& first,
28704 const type_base_sptr& second,
28705 bool indirect_type)
28706{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
28707
28708/// Test if two types have similar structures, even though they are
28709/// (or can be) different.
28710///
28711/// const and volatile qualifiers are completely ignored.
28712///
28713/// typedef are resolved to their definitions; their names are ignored.
28714///
28715/// Two indirect types (pointers, references or arrays) have similar
28716/// structure if their underlying types are of the same kind and have
28717/// the same name. In the indirect types case, the size of the
28718/// underlying type does not matter.
28719///
28720/// Two direct types (i.e, non indirect) have a similar structure if
28721/// they have the same kind, name and size. Two class types have
28722/// similar structure if they have the same name, size, and if the
28723/// types of their data members have similar types.
28724///
28725/// @param first the first type to consider.
28726///
28727/// @param second the second type to consider.
28728///
28729/// @param indirect_type if true, then consider @p first and @p
28730/// second as being underlying types of indirect types. Meaning that
28731/// their size does not matter.
28732///
28733/// @return true iff @p first and @p second have similar structures.
28734bool
28736 const type_base* second,
28737 bool indirect_type)
28738{
28739 if (!!first != !!second)
28740 return false;
28741
28742 if (!first)
28743 return false;
28744
28745 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
28746 first = peel_qualified_or_typedef_type(first);
28747 second = peel_qualified_or_typedef_type(second);
28748
28749 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
28750 // various ty2 below cannot be null.
28751 if (typeid(*first) != typeid(*second))
28752 return false;
28753
28754 // Peel off matching pointers.
28755 if (const pointer_type_def* ty1 = is_pointer_type(first))
28756 {
28757 const pointer_type_def* ty2 = is_pointer_type(second);
28758 return types_have_similar_structure(ty1->get_pointed_to_type(),
28759 ty2->get_pointed_to_type(),
28760 /*indirect_type=*/true);
28761 }
28762
28763 // Peel off matching references.
28764 if (const reference_type_def* ty1 = is_reference_type(first))
28765 {
28766 const reference_type_def* ty2 = is_reference_type(second);
28767 if (ty1->is_lvalue() != ty2->is_lvalue())
28768 return false;
28769 return types_have_similar_structure(ty1->get_pointed_to_type(),
28770 ty2->get_pointed_to_type(),
28771 /*indirect_type=*/true);
28772 }
28773
28774 // Peel off matching pointer-to-member types.
28775 if (const ptr_to_mbr_type* ty1 = is_ptr_to_mbr_type(first))
28776 {
28777 const ptr_to_mbr_type* ty2 = is_ptr_to_mbr_type(second);
28778 return (types_have_similar_structure(ty1->get_member_type(),
28779 ty2->get_member_type(),
28780 /*indirect_type=*/true)
28781 && types_have_similar_structure(ty1->get_containing_type(),
28782 ty2->get_containing_type(),
28783 /*indirect_type=*/true));
28784 }
28785
28786 if (const type_decl* ty1 = is_type_decl(first))
28787 {
28788 const type_decl* ty2 = is_type_decl(second);
28789 if (!indirect_type)
28790 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28791 return false;
28792
28793 return ty1->get_name() == ty2->get_name();
28794 }
28795
28796 if (const enum_type_decl* ty1 = is_enum_type(first))
28797 {
28798 const enum_type_decl* ty2 = is_enum_type(second);
28799 if (!indirect_type)
28800 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28801 return false;
28802
28803 return (get_name(ty1->get_underlying_type())
28804 == get_name(ty2->get_underlying_type()));
28805 }
28806
28807 if (const class_decl* ty1 = is_class_type(first))
28808 {
28809 const class_decl* ty2 = is_class_type(second);
28810 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28811 && ty1->get_name() != ty2->get_name())
28812 return false;
28813
28814 if (!indirect_type)
28815 {
28816 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
28817 || (ty1->get_non_static_data_members().size()
28818 != ty2->get_non_static_data_members().size()))
28819 return false;
28820
28821 for (class_or_union::data_members::const_iterator
28822 i = ty1->get_non_static_data_members().begin(),
28823 j = ty2->get_non_static_data_members().begin();
28824 (i != ty1->get_non_static_data_members().end()
28825 && j != ty2->get_non_static_data_members().end());
28826 ++i, ++j)
28827 {
28828 var_decl_sptr dm1 = *i;
28829 var_decl_sptr dm2 = *j;
28830 if (!types_have_similar_structure(dm1->get_type().get(),
28831 dm2->get_type().get(),
28832 indirect_type))
28833 return false;
28834 }
28835 }
28836
28837 return true;
28838 }
28839
28840 if (const union_decl* ty1 = is_union_type(first))
28841 {
28842 const union_decl* ty2 = is_union_type(second);
28843 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28844 && ty1->get_name() != ty2->get_name())
28845 return false;
28846
28847 if (!indirect_type)
28848 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
28849
28850 return true;
28851 }
28852
28853 if (const array_type_def* ty1 = is_array_type(first))
28854 {
28855 const array_type_def* ty2 = is_array_type(second);
28856 if (!indirect_type)
28857 {
28858 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
28859 || ty1->get_dimension_count() != ty2->get_dimension_count())
28860 return false;
28861
28862 // Handle int[5][2] vs int[2][5] ...
28863 //
28864 // 6.2.5/20 of
28865 // https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
28866 // says:
28867 //
28868 // "Array types are characterized by their element
28869 // type and by the number of elements in the array"
28870 //
28871 // and 6.5.2.1/3 says:
28872 //
28873 // "arrays are stored in row-major order (last subscript
28874 // varies fastest)."
28875 //
28876 // So, let's ensure that all dimensions (sub-ranges) have
28877 // the same length.
28878
28879 for (auto r1 = ty1->get_subranges().begin(),
28880 r2 = ty1->get_subranges().begin();
28881 (r1 != ty1->get_subranges().end()
28882 && r2 != ty2->get_subranges().end());
28883 ++r1, ++r2)
28884 if ((*r1)->get_length() != (*r2)->get_length())
28885 return false;
28886 }
28887
28888 // ... then compare the elements of the arrays.
28889 if (!types_have_similar_structure(ty1->get_element_type(),
28890 ty2->get_element_type(),
28891 /*indirect_type=*/true))
28892 return false;
28893
28894 return true;
28895 }
28896
28897 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
28898 {
28900 if (ty1->get_upper_bound() != ty2->get_upper_bound()
28901 || ty1->get_lower_bound() != ty2->get_lower_bound()
28902 || ty1->get_language() != ty2->get_language()
28903 || !types_have_similar_structure(ty1->get_underlying_type(),
28904 ty2->get_underlying_type(),
28905 indirect_type))
28906 return false;
28907
28908 return true;
28909 }
28910
28911 if (const function_type* ty1 = is_function_type(first))
28912 {
28913 const function_type* ty2 = is_function_type(second);
28914 if (!types_have_similar_structure(ty1->get_return_type(),
28915 ty2->get_return_type(),
28916 indirect_type))
28917 return false;
28918
28919 if (ty1->get_parameters().size() != ty2->get_parameters().size())
28920 return false;
28921
28922 for (function_type::parameters::const_iterator
28923 i = ty1->get_parameters().begin(),
28924 j = ty2->get_parameters().begin();
28925 (i != ty1->get_parameters().end()
28926 && j != ty2->get_parameters().end());
28927 ++i, ++j)
28928 if (!types_have_similar_structure((*i)->get_type(),
28929 (*j)->get_type(),
28930 indirect_type))
28931 return false;
28932
28933 return true;
28934 }
28935
28936 // All kinds of type should have been handled at this point.
28938
28939 return false;
28940}
28941
28942/// Look for a data member of a given class, struct or union type and
28943/// return it.
28944///
28945/// The data member is designated by its name.
28946///
28947/// @param type the class, struct or union type to consider.
28948///
28949/// @param dm_name the name of the data member to lookup.
28950///
28951/// @return the data member iff it was found in @type or NULL if no
28952/// data member with that name was found.
28953const var_decl*
28955 const char* dm_name)
28956
28957{
28959 if (!cou)
28960 return 0;
28961
28962 return cou->find_data_member(dm_name).get();
28963}
28964
28965/// Look for a data member of a given class, struct or union type and
28966/// return it.
28967///
28968/// The data member is designated by its name.
28969///
28970/// @param type the class, struct or union type to consider.
28971///
28972/// @param dm the data member to lookup.
28973///
28974/// @return the data member iff it was found in @type or NULL if no
28975/// data member with that name was found.
28976const var_decl_sptr
28977lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
28978{
28979 class_or_union_sptr cou = is_class_or_union_type(type);
28980 if (!cou)
28981 return var_decl_sptr();
28982
28983 return cou->find_data_member(dm);
28984}
28985
28986/// Get the function parameter designated by its index.
28987///
28988/// Note that the first function parameter has index 0.
28989///
28990/// @param fun the function to consider.
28991///
28992/// @param parm_index the index of the function parameter to get.
28993///
28994/// @return the function parameter designated by its index, of NULL if
28995/// no function parameter with that index was found.
28998 unsigned parm_index)
28999{
29001 if (!fn)
29002 return 0;
29003
29004 const function_decl::parameters &parms = fn->get_type()->get_parameters();
29005 if (parms.size() <= parm_index)
29006 return 0;
29007
29008 return parms[parm_index].get();
29009}
29010
29011/// Build the internal name of the underlying type of an enum.
29012///
29013/// @param base_name the (unqualified) name of the enum the underlying
29014/// type is destined to.
29015///
29016/// @param is_anonymous true if the underlying type of the enum is to
29017/// be anonymous.
29018string
29020 bool is_anonymous,
29021 uint64_t size)
29022{
29023 std::ostringstream o;
29024
29025 if (is_anonymous)
29026 o << "unnamed-enum";
29027 else
29028 o << "enum-" << base_name;
29029
29030 o << "-underlying-type-" << size;
29031
29032 return o.str();
29033}
29034
29035/// Find the first data member of a class or union which name matches
29036/// a regular expression.
29037///
29038/// @param t the class or union to consider.
29039///
29040/// @param r the regular expression to consider.
29041///
29042/// @return the data member matched by @p r or nil if none was found.
29045 const regex::regex_t_sptr& r)
29046{
29047 for (auto data_member : t.get_data_members())
29048 {
29049 if (regex::match(r, data_member->get_name()))
29050 return data_member;
29051 }
29052
29053 return var_decl_sptr();
29054}
29055
29056/// Find the last data member of a class or union which name matches
29057/// a regular expression.
29058///
29059/// @param t the class or union to consider.
29060///
29061/// @param r the regular expression to consider.
29062///
29063/// @return the data member matched by @p r or nil if none was found.
29066 const regex::regex_t_sptr& regex)
29067{
29068 auto d = t.get_data_members().rbegin();
29069 auto e = t.get_data_members().rend();
29070 for (; d != e; ++d)
29071 {
29072 if (regex::match(regex, (*d)->get_name()))
29073 return *d;
29074 }
29075
29076 return var_decl_sptr();
29077}
29078
29079/// Emit the pretty representation of the parameters of a function
29080/// type.
29081///
29082/// @param fn_type the function type to consider.
29083///
29084/// @param o the output stream to emit the pretty representation to.
29085///
29086/// @param qualified if true, emit fully qualified names.
29087///
29088/// @param internal if true, then the result is to be used for the
29089/// purpose of type canonicalization.
29090static void
29091stream_pretty_representation_of_fn_parms(const function_type& fn_type,
29092 ostream& o, bool qualified,
29093 bool internal)
29094{
29095 o << "(";
29096 if (fn_type.get_parameters().empty())
29097 o << "void";
29098 else
29099 {
29100 type_base_sptr type;
29101 auto end = fn_type.get_parameters().end();
29102 auto first_parm = fn_type.get_first_non_implicit_parm();
29104 const environment& env = fn_type.get_environment();
29105 for (auto i = fn_type.get_first_non_implicit_parm(); i != end; ++i)
29106 {
29107 if (i != first_parm)
29108 o << ", ";
29109 parm = *i;
29110 type = parm->get_type();
29111 // If the type is a decl-only class, union or enum that has a
29112 // definition, use the definition instead. That definition
29113 // is what is going to be serialized out in ABIXML anyway,
29114 // so use that for consistency.
29115 if (decl_base_sptr def = look_through_decl_only(is_decl(type)))
29116 type = is_type(def);
29117 if (env.is_variadic_parameter_type(type))
29118 o << "...";
29119 else
29120 o << get_type_name(type, qualified, internal);
29121 }
29122 }
29123 o << ")";
29124}
29125
29126/// When constructing the name of a pointer to function type, add the
29127/// return type to the left of the existing type identifier, and the
29128/// parameters declarator to the right.
29129///
29130/// This function considers the name of the type as an expression.
29131///
29132/// The resulting type expr is going to be made of three parts:
29133/// left_expr inner_expr right_expr.
29134///
29135/// Suppose we want to build the type expression representing:
29136///
29137/// "an array of pointer to function taking a char parameter and
29138/// returning an int".
29139///
29140/// It's going to look like:
29141///
29142/// int(*a[])(char);
29143///
29144/// Suppose the caller of this function started to emit the inner
29145/// "a[]" part of the expression already. It thus calls this
29146/// function with that input "a[]" part. We consider that "a[]" as
29147/// the "type identifier".
29148///
29149/// So the inner_expr is going to be "(*a[])".
29150///
29151/// The left_expr part is "int". The right_expr part is "(char)".
29152///
29153/// In other words, this function adds the left_expr and right_expr to
29154/// the inner_expr. left_expr and right_expr are called "outer
29155/// pointer to function type expression".
29156///
29157/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29158/// array_declaration_name()
29159///
29160/// @param p the pointer to function type to consider.
29161///
29162/// @param input the type-id to use as the inner expression of the
29163/// overall pointer-to-function type expression
29164///
29165/// @param qualified if true then use qualified names in the resulting
29166/// type name.
29167///
29168/// @param internal if true then the resulting type name is going to
29169/// be used for type canonicalization purposes.
29170///
29171/// @return the name of the pointer to function type.
29172static string
29173add_outer_pointer_to_fn_type_expr(const type_base* p,
29174 const string& input,
29175 bool qualified, bool internal)
29176{
29177 if (!p)
29178 return "";
29179
29180 function_type_sptr pointed_to_fn;
29181 string star_or_ref;
29182
29183 if (const pointer_type_def* ptr = is_pointer_type(p))
29184 {
29185 pointed_to_fn = is_function_type(ptr->get_pointed_to_type());
29186 star_or_ref= "*";
29187 }
29188 else if (const reference_type_def* ref = is_reference_type(p))
29189 {
29190 star_or_ref = "&";
29191 pointed_to_fn = is_function_type(ref->get_pointed_to_type());
29192 }
29193
29194 if (!pointed_to_fn)
29195 return "";
29196
29197 if (pointed_to_fn->priv_->is_pretty_printing())
29198 // We have just detected a cycle while walking the sub-tree of
29199 // this function type for the purpose of printing its
29200 // representation. We need to get out of here pronto or else
29201 // we'll be spinning endlessly.
29202 return "";
29203
29204 // Let's mark thie function type to signify that we started walking
29205 // its subtree. This is to detect potential cycles and avoid
29206 // looping endlessly.
29207 pointed_to_fn->priv_->set_is_pretty_printing();
29208
29209 std::ostringstream left, right, inner;
29210
29211 inner << "(" << star_or_ref << input << ")";
29212
29213 type_base_sptr type;
29214 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
29215 qualified, internal);
29216
29217 type_base_sptr return_type = pointed_to_fn->get_return_type();
29218 string result;
29219
29220 if (is_npaf_type(return_type)
29221 || !(is_pointer_to_function_type(return_type)
29222 || is_pointer_to_array_type(return_type)))
29223 {
29224 if (return_type)
29225 left << get_type_name(return_type, qualified, internal);
29226 result = left.str() + " " + inner.str() + right.str();
29227 }
29228 else if (pointer_type_def_sptr p = is_pointer_to_function_type(return_type))
29229 {
29230 string inner_string = inner.str() + right.str();
29231 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
29232 qualified, internal);
29233 }
29234 else if (pointer_type_def_sptr p = is_pointer_to_array_type(return_type))
29235 {
29236 string inner_string = inner.str() + right.str();
29237 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29238 qualified, internal);
29239 }
29240 else
29242
29243 // Lets unmark this function type to signify that we are done
29244 // walking its subtree. This was to detect potential cycles and
29245 // avoid looping endlessly.
29246 pointed_to_fn->priv_->unset_is_pretty_printing();
29247 return result;
29248}
29249
29250/// When constructing the name of a pointer to function type, add the
29251/// return type to the left of the existing type identifier, and the
29252/// parameters declarator to the right.
29253///
29254/// This function considers the name of the type as an expression.
29255///
29256/// The resulting type expr is going to be made of three parts:
29257/// left_expr inner_expr right_expr.
29258///
29259/// Suppose we want to build the type expression representing:
29260///
29261/// "an array of pointer to function taking a char parameter and
29262/// returning an int".
29263///
29264/// It's going to look like:
29265///
29266/// int(*a[])(char);
29267///
29268/// Suppose the caller of this function started to emit the inner
29269/// "a[]" part of the expression already. It thus calls this
29270/// function with that input "a[]" part. We consider that "a[]" as
29271/// the "type identifier".
29272///
29273/// So the inner_expr is going to be "(*a[])".
29274///
29275/// The left_expr part is "int". The right_expr part is "(char)".
29276///
29277/// In other words, this function adds the left_expr and right_expr to
29278/// the inner_expr. left_expr and right_expr are called "outer
29279/// pointer to function type expression".
29280///
29281/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29282/// array_declaration_name()
29283///
29284/// @param p the pointer to function type to consider.
29285///
29286/// @param input the type-id to use as the inner expression of the
29287/// overall pointer-to-function type expression
29288///
29289/// @param qualified if true then use qualified names in the resulting
29290/// type name.
29291///
29292/// @param internal if true then the resulting type name is going to
29293/// be used for type canonicalization purposes.
29294///
29295/// @return the name of the pointer to function type.
29296static string
29297add_outer_pointer_to_fn_type_expr(const type_base_sptr& p,
29298 const string& input,
29299 bool qualified, bool internal)
29300{return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
29301
29302/// When constructing the name of a pointer to array type, add the
29303/// array element type type to the left of the existing type
29304/// identifier, and the array declarator part to the right.
29305///
29306/// This function considers the name of the type as an expression.
29307///
29308/// The resulting type expr is going to be made of three parts:
29309/// left_expr inner_expr right_expr.
29310///
29311/// Suppose we want to build the type expression representing:
29312///
29313/// "a pointer to an array of int".
29314///
29315/// It's going to look like:
29316///
29317/// int(*foo)[];
29318///
29319/// Suppose the caller of this function started to emit the inner
29320/// "foo" part of the expression already. It thus calls this function
29321/// with that input "foo" part. We consider that "foo" as the "type
29322/// identifier".
29323///
29324/// So we are passed an input string that is "foo" and it's going to
29325/// be turned into the inner_expr part, which is going to be "(*foo)".
29326///
29327/// The left_expr part is "int". The right_expr part is "[]".
29328///
29329/// In other words, this function adds the left_expr and right_expr to
29330/// the inner_expr. left_expr and right_expr are called "outer
29331/// pointer to array type expression".
29332///
29333/// The model of this function was taken from the article "Reading C
29334/// type declaration", from Steve Friedl at
29335/// http://unixwiz.net/techtips/reading-cdecl.html.
29336///
29337/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29338/// array_declaration_name()
29339///
29340/// @param p the pointer to array type to consider.
29341///
29342/// @param input the type-id to start from as the inner part of the
29343/// final type name.
29344///
29345/// @param qualified if true then use qualified names in the resulting
29346/// type name.
29347///
29348/// @param internal if true then the resulting type name is going to
29349/// be used for type canonicalization purposes.
29350///
29351/// @return the name of the pointer to array type.
29352static string
29353add_outer_pointer_to_array_type_expr(const type_base* p,
29354 const string& input, bool qualified,
29355 bool internal)
29356{
29357 if (!p)
29358 return "";
29359
29360 string star_or_ref;
29361 type_base_sptr pointed_to_type;
29362
29363 if (const pointer_type_def *ptr = is_pointer_type(p))
29364 {
29365 pointed_to_type = ptr->get_pointed_to_type();
29366 star_or_ref = "*";
29367 }
29368 else if (const reference_type_def *ref = is_reference_type(p))
29369 {
29370 pointed_to_type = ref->get_pointed_to_type();
29371 star_or_ref = "&";
29372 }
29373
29374 array_type_def_sptr array = is_array_type(pointed_to_type);
29375 if (!array)
29376 return "";
29377
29378 std::ostringstream left, right, inner;
29379 inner << "(" << star_or_ref << input << ")";
29380 right << array->get_subrange_representation();
29381 string result;
29382
29383 type_base_sptr array_element_type = array->get_element_type();
29384
29385 if (is_npaf_type(array_element_type)
29386 || !(is_pointer_to_function_type(array_element_type)
29387 || is_pointer_to_array_type(array_element_type)))
29388 {
29389 left << get_type_name(array_element_type, qualified, internal);
29390 result = left.str() + inner.str() + right.str();
29391 }
29392 else if (pointer_type_def_sptr p =
29393 is_pointer_to_function_type(array_element_type))
29394 {
29395 string r = inner.str() + right.str();
29396 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
29397 }
29398 else if (pointer_type_def_sptr p =
29399 is_pointer_to_array_type(array_element_type))
29400 {
29401 string inner_string = inner.str() + right.str();
29402 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29403 qualified, internal);
29404 }
29405 else
29407
29408 return result;
29409}
29410
29411/// When constructing the name of a pointer to array type, add the
29412/// array element type type to the left of the existing type
29413/// identifier, and the array declarator part to the right.
29414///
29415/// This function considers the name of the type as an expression.
29416///
29417/// The resulting type expr is going to be made of three parts:
29418/// left_expr inner_expr right_expr.
29419///
29420/// Suppose we want to build the type expression representing:
29421///
29422/// "a pointer to an array of int".
29423///
29424/// It's going to look like:
29425///
29426/// int(*foo)[];
29427///
29428/// Suppose the caller of this function started to emit the inner
29429/// "foo" part of the expression already. It thus calls this function
29430/// with that input "foo" part. We consider that "foo" as the "type
29431/// identifier".
29432///
29433/// So we are passed an input string that is "foo" and it's going to
29434/// be turned into the inner_expr part, which is going to be "(*foo)".
29435///
29436/// The left_expr part is "int". The right_expr part is "[]".
29437///
29438/// In other words, this function adds the left_expr and right_expr to
29439/// the inner_expr. left_expr and right_expr are called "outer
29440/// pointer to array type expression".
29441///
29442/// The model of this function was taken from the article "Reading C
29443/// type declaration", from Steve Friedl at
29444/// http://unixwiz.net/techtips/reading-cdecl.html.
29445///
29446/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29447/// array_declaration_name()
29448///
29449/// @param p the pointer to array type to consider.
29450///
29451/// @param input the type-id to start from as the inner part of the
29452/// final type name.
29453///
29454/// @param qualified if true then use qualified names in the resulting
29455/// type name.
29456///
29457/// @param internal if true then the resulting type name is going to
29458/// be used for type canonicalization purposes.
29459///
29460/// @return the name of the pointer to array type.
29461static string
29462add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
29463 const string& input, bool qualified,
29464 bool internal)
29465{return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
29466 input, qualified, internal);}
29467
29468/// When constructing the name of a pointer to mebmer type, add the
29469/// return type to the left of the existing type identifier, and the
29470/// parameters declarator to the right.
29471///
29472/// This function considers the name of the type as an expression.
29473///
29474/// The resulting type expr is going to be made of three parts:
29475/// left_expr inner_expr right_expr.
29476///
29477/// Suppose we want to build the type expression representing:
29478///
29479/// "an array of pointer to member function (of a containing struct
29480/// X) taking a char parameter and returning an int".
29481///
29482/// It's going to look like:
29483///
29484/// int (X::* a[])(char);
29485///
29486/// Suppose the caller of this function started to emit the inner
29487/// "a[]" part of the expression already. It thus calls this
29488/// function with that input "a[]" part. We consider that "a[]" as
29489/// the "type identifier".
29490///
29491/// So the inner_expr is going to be "(X::* a[])".
29492///
29493/// The left_expr part is "int". The right_expr part is "(char)".
29494///
29495/// In other words, this function adds the left_expr and right_expr to
29496/// the inner_expr. left_expr and right_expr are called "outer
29497/// pointer to member type expression".
29498///
29499/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29500///
29501/// @param p the pointer to member type to consider.
29502///
29503/// @param input the type-id to use as the inner expression of the
29504/// overall pointer-to-member type expression
29505///
29506/// @param qualified if true then use qualified names in the resulting
29507/// type name.
29508///
29509/// @param internal if true then the resulting type name is going to
29510/// be used for type canonicalization purposes.
29511///
29512/// @return the name of the pointer to member type.
29513static string
29514add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
29515 const string& input, bool qualified,
29516 bool internal)
29517{
29518 if (!p)
29519 return "";
29520
29521 std::ostringstream left, right, inner;
29522 type_base_sptr void_type = p->get_environment().get_void_type();
29523 string containing_type_name = get_type_name(p->get_containing_type(),
29524 qualified, internal);
29525 type_base_sptr mbr_type = p->get_member_type();
29526 string result;
29527 if (function_type_sptr fn_type = is_function_type(mbr_type))
29528 {
29529 inner << "(" << containing_type_name << "::*" << input << ")";
29530 stream_pretty_representation_of_fn_parms(*fn_type, right,
29531 qualified, internal);
29532 type_base_sptr return_type = fn_type->get_return_type();
29533 if (!return_type)
29534 return_type = void_type;
29535 if (is_npaf_type(return_type)
29536 || !(is_pointer_to_function_type(return_type)
29537 || is_pointer_to_array_type(return_type)
29538 || is_pointer_to_ptr_to_mbr_type(return_type)
29539 || is_ptr_to_mbr_type(return_type)))
29540 {
29541 left << get_type_name(return_type, qualified, internal) << " ";;
29542 result = left.str() + inner.str() + right.str();
29543 }
29544 else if (pointer_type_def_sptr p = is_pointer_type(return_type))
29545 {
29546 string inner_str = inner.str() + right.str();
29547 result = pointer_declaration_name(p, inner_str, qualified, internal);
29548 }
29549 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(return_type))
29550 {
29551 string inner_str = inner.str() + right.str();
29552 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
29553 qualified, internal);
29554 }
29555 else
29557 }
29558 else if (ptr_to_mbr_type_sptr ptr_mbr_type = is_ptr_to_mbr_type(mbr_type))
29559 {
29560 inner << "(" << containing_type_name << "::*" << input << ")";
29561 stream_pretty_representation_of_fn_parms(*fn_type, right,
29562 qualified, internal);
29563 string inner_str = inner.str() + right.str();
29564 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
29565 qualified, internal);
29566 }
29567 else
29568 {
29569 left << get_type_name(p->get_member_type(), qualified, internal) << " ";
29570 inner << containing_type_name << "::*" << input;
29571 result = left.str()+ inner.str();
29572 }
29573
29574 return result;
29575}
29576
29577/// Test if two decls have different names.
29578///
29579/// Note that this function takes into account decls whose names are
29580/// relevant from an ABI standpoint. For instance, function parameter
29581/// names are not relevant in that context.
29582///
29583/// @param d1 the first declaration to consider.
29584///
29585/// @param d2 the second declaration to consider.
29586///
29587/// @return true if d1 and d2 have different names.
29588bool
29590{
29591 string d1_name, d2_name;
29592
29593 const decl_base *d1 = dynamic_cast<const decl_base*>(a1);
29594 if (d1 == 0)
29595 return false;
29596
29597 const decl_base *d2 = dynamic_cast<const decl_base*>(a2);
29598 if (d2 == 0)
29599 return false;
29600
29602 // Name changes for fn parms are irrelevant.
29603 return false;
29604
29605 d1_name = d1->get_qualified_name();
29606 d2_name = d2->get_qualified_name();
29607
29608 return d1_name != d2_name;
29609}
29610
29611/// Test if two decls have different names.
29612///
29613/// @param d1 the first declaration to consider.
29614///
29615/// @param d2 the second declaration to consider.
29616///
29617/// @return true if d1 and d2 have different names.
29618bool
29620 const type_or_decl_base_sptr& d2)
29621{return decl_name_changed(d1.get(), d2.get());}
29622
29623/// Test if a diff node carries a change whereby two integral types
29624/// have different names in a harmless way.
29625///
29626/// Basically, if the integral type name change is accompanied by a
29627/// size change then the change is considered harmful. If there are
29628/// modifiers change, the change is considered harmful.
29629bool
29631 const type_base_sptr& s)
29632{
29633 if (is_decl(f)
29634 && is_decl(s)
29635 && (is_integral_type(f) || is_decl(f)->get_name().empty())
29636 && (is_integral_type(s) || is_decl(s)->get_name().empty())
29638 && (f->get_size_in_bits() == s->get_size_in_bits())
29639 && (f->get_alignment_in_bits() == s->get_alignment_in_bits()))
29640 {
29641 real_type fi, si;
29642 ABG_ASSERT(is_decl(f)->get_name().empty()
29643 || parse_real_type(is_decl(f)->get_name(), fi));
29644 ABG_ASSERT(is_decl(s)->get_name().empty()
29645 || parse_real_type(is_decl(s)->get_name(), si));
29646
29647 if (fi.get_base_type() == si.get_base_type()
29648 && fi.get_modifiers() != si.get_modifiers())
29649 // The base type hasn't changed. That means only modifiers
29650 // changed. This is considered has harmful by default.
29651 return false;
29652
29653 return true;
29654 }
29655
29656 return false;
29657}
29658
29659/// Test if a diff node carries a change whereby two integral types
29660/// have different names in a harmless way.
29661///
29662/// Basically, if the integral type name change is accompanied by a
29663/// size change then the change is considered harmful. If there are
29664/// modifiers change, the change is considered harmful.
29665bool
29667 const decl_base_sptr& s)
29669
29670
29671/// When constructing the name of a pointer to mebmer type, add the
29672/// return type to the left of the existing type identifier, and the
29673/// parameters declarator to the right.
29674///
29675/// This function considers the name of the type as an expression.
29676///
29677/// The resulting type expr is going to be made of three parts:
29678/// left_expr inner_expr right_expr.
29679///
29680/// Suppose we want to build the type expression representing:
29681///
29682/// "an array of pointer to member function (of a containing struct
29683/// X) taking a char parameter and returning an int".
29684///
29685/// It's going to look like:
29686///
29687/// int (X::* a[])(char);
29688///
29689/// Suppose the caller of this function started to emit the inner
29690/// "a[]" part of the expression already. It thus calls this
29691/// function with that input "a[]" part. We consider that "a[]" as
29692/// the "type identifier".
29693///
29694/// So the inner_expr is going to be "(X::* a[])".
29695///
29696/// The left_expr part is "int". The right_expr part is "(char)".
29697///
29698/// In other words, this function adds the left_expr and right_expr to
29699/// the inner_expr. left_expr and right_expr are called "outer
29700/// pointer to member type expression".
29701///
29702/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29703///
29704/// @param p the pointer to member type to consider.
29705///
29706/// @param input the type-id to use as the inner expression of the
29707/// overall pointer-to-member type expression
29708///
29709/// @param qualified if true then use qualified names in the resulting
29710/// type name.
29711///
29712/// @param internal if true then the resulting type name is going to
29713/// be used for type canonicalization purposes.
29714///
29715/// @return the name of the pointer to member type.
29716static string
29717add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
29718 const string& input, bool qualified,
29719 bool internal)
29720{return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
29721
29722/// This adds the outer parts of a pointer to a pointer-to-member
29723/// expression.
29724///
29725/// Please read the comments of @ref add_outer_ptr_to_mbr_type_expr to
29726/// learn more about this function, which is similar.
29727///
29728/// This is a sub-routine of @ref pointer_declaration_name().
29729///
29730/// @param a pointer (or reference) to a pointer-to-member type.
29731///
29732/// @param input the inner type-id to add the outer parts to.
29733///
29734/// @param qualified if true then use qualified names in the resulting
29735/// type name.
29736///
29737/// @param internal if true then the resulting type name is going to
29738/// be used for type canonicalization purposes.
29739static string
29740add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
29741 const string& input, bool qualified,
29742 bool internal)
29743{
29744 if (!p)
29745 return "";
29746
29747 string star_or_ref;
29748 type_base_sptr pointed_to_type;
29749
29750 if (const pointer_type_def* ptr = is_pointer_type(p))
29751 {
29752 pointed_to_type = ptr->get_pointed_to_type();
29753 star_or_ref = "*";
29754 }
29755 else if (const reference_type_def* ref = is_reference_type(p))
29756 {
29757 pointed_to_type= ref->get_pointed_to_type();
29758 star_or_ref = "&";
29759 }
29760
29761 if (!pointed_to_type)
29762 return "";
29763
29764 ptr_to_mbr_type_sptr pointed_to_ptr_to_mbr =
29765 is_ptr_to_mbr_type(pointed_to_type);
29766 if (!pointed_to_ptr_to_mbr)
29767 return "";
29768
29769 std::ostringstream inner;
29770 inner << star_or_ref << input;
29771 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
29772 inner.str(),
29773 qualified, internal);
29774 return result;
29775}
29776
29777/// Emit the name of a pointer declaration.
29778///
29779/// @param the pointer to consider.
29780///
29781/// @param idname the name of the variable that has @p as a type or
29782/// the id of the type. If it's empty then the resulting name is
29783/// going to be the abstract name of the type.
29784///
29785/// @param qualified if true then the type name is going to be
29786/// fully qualified.
29787///
29788/// @param internal if true then the type name is going to be used for
29789/// type canonicalization purposes.
29790static interned_string
29791pointer_declaration_name(const type_base* ptr,
29792 const string& idname,
29793 bool qualified, bool internal)
29794{
29795 if (!ptr)
29796 return interned_string();
29797
29798 type_base_sptr pointed_to_type;
29799 string star_or_ref;
29800 if (const pointer_type_def* p = is_pointer_type(ptr))
29801 {
29802 pointed_to_type = p->get_pointed_to_type();
29803 star_or_ref = "*";
29804 }
29805 else if (const reference_type_def* p = is_reference_type(ptr))
29806 {
29807 pointed_to_type = p->get_pointed_to_type();
29808 star_or_ref = "&";
29809 }
29810
29811 if (!pointed_to_type)
29812 return interned_string();
29813
29814 string result;
29815 if (is_npaf_type(pointed_to_type)
29816 || !(is_function_type(pointed_to_type)
29817 || is_array_type(pointed_to_type)
29818 || is_ptr_to_mbr_type(pointed_to_type)))
29819 {
29820 result = get_type_name(pointed_to_type,
29821 qualified,
29822 internal)
29823 + star_or_ref;
29824
29825 if (!idname.empty())
29826 result += idname;
29827 }
29828 else
29829 {
29830 // derived type
29831 if (is_function_type(pointed_to_type))
29832 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
29833 qualified, internal);
29834 else if (is_array_type(pointed_to_type))
29835 result = add_outer_pointer_to_array_type_expr(ptr, idname,
29836 qualified, internal);
29837 else if (is_ptr_to_mbr_type(pointed_to_type))
29838 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
29839 qualified, internal);
29840 else
29842 }
29843 return ptr->get_environment().intern(result);
29844}
29845
29846
29847/// Emit the name of a pointer declaration.
29848///
29849/// @param the pointer to consider.
29850///
29851/// @param the name of the variable that has @p as a type. If it's
29852/// empty then the resulting name is going to be the abstract name of
29853/// the type.
29854///
29855/// @param qualified if true then the type name is going to be
29856/// fully qualified.
29857///
29858/// @param internal if true then the type name is going to be used for
29859/// type canonicalization purposes.
29860static interned_string
29861pointer_declaration_name(const type_base_sptr& ptr,
29862 const string& variable_name,
29863 bool qualified, bool internal)
29864{return pointer_declaration_name(ptr.get(), variable_name,
29865 qualified, internal);}
29866
29867/// Emit the name of a array declaration.
29868///
29869/// @param the array to consider.
29870///
29871/// @param the name of the variable that has @p as a type. If it's
29872/// empty then the resulting name is going to be the abstract name of
29873/// the type.
29874///
29875/// @param qualified if true then the type name is going to be
29876/// fully qualified.
29877///
29878/// @param internal if true then the type name is going to be used for
29879/// type canonicalization purposes.
29880static interned_string
29881array_declaration_name(const array_type_def* array,
29882 const string& variable_name,
29883 bool qualified, bool internal)
29884{
29885 if (!array)
29886 return interned_string();
29887
29888 type_base_sptr e_type = array->get_element_type();
29889 string e_type_repr =
29890 (e_type
29891 ? get_type_name(e_type, qualified, internal)
29892 : string("void"));
29893
29894 string result;
29895 if (is_ada_language(array->get_language()))
29896 {
29897 std::ostringstream o;
29898 if (!variable_name.empty())
29899 o << variable_name << " is ";
29900 o << "array ("
29901 << array->get_subrange_representation()
29902 << ") of " << e_type_repr;
29903 result = o.str();
29904 }
29905 else
29906 {
29907 if (is_npaf_type(e_type)
29908 || !(is_pointer_to_function_type(e_type)
29909 || is_pointer_to_array_type(e_type)
29911 || is_ptr_to_mbr_type(e_type)))
29912 {
29913 result = e_type_repr;
29914 if (!variable_name.empty())
29915 result += variable_name;
29916 result += array->get_subrange_representation();
29917 }
29918 else if (pointer_type_def_sptr p = is_pointer_type(e_type))
29919 {
29920 string s = variable_name + array->get_subrange_representation();
29921 result = pointer_declaration_name(p, s, qualified, internal);
29922 }
29923 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(e_type))
29924 {
29925 string s = variable_name + array->get_subrange_representation();
29926 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
29927 }
29928 else
29930 }
29931 return array->get_environment().intern(result);
29932}
29933
29934/// Emit the name of a array declaration.
29935///
29936/// @param the array to consider.
29937///
29938/// @param the name of the variable that has @p as a type. If it's
29939/// empty then the resulting name is going to be the abstract name of
29940/// the type.
29941///
29942/// @param qualified if true then the type name is going to be
29943/// fully qualified.
29944///
29945/// @param internal if true then the type name is going to be used for
29946/// type canonicalization purposes.
29947static interned_string
29948array_declaration_name(const array_type_def_sptr& array,
29949 const string& variable_name,
29950 bool qualified, bool internal)
29951{return array_declaration_name(array.get(), variable_name,
29952 qualified, internal);}
29953
29954/// Emit the name of a pointer-to-member declaration.
29955///
29956/// @param ptr the pointer-to-member to consider.
29957///
29958/// @param variable_name the name of the variable that has @p as a
29959/// type. If it's empty then the resulting name is going to be the
29960/// abstract name of the type.
29961///
29962/// @param qualified if true then the type name is going to be
29963/// fully qualified.
29964///
29965/// @param internal if true then the type name is going to be used for
29966/// type canonicalization purposes.
29967static interned_string
29968ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
29969 const string& variable_name,
29970 bool qualified, bool internal)
29971{
29972 if (!ptr)
29973 return interned_string();
29974
29975 string input = variable_name;
29976 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
29977 qualified, internal);
29978 return ptr->get_environment().intern(result);
29979}
29980
29981/// Emit the name of a pointer-to-member declaration.
29982///
29983/// @param ptr the pointer-to-member to consider.
29984///
29985/// @param variable_name the name of the variable that has @p as a
29986/// type. If it's empty then the resulting name is going to be the
29987/// abstract name of the type.
29988///
29989/// @param qualified if true then the type name is going to be
29990/// fully qualified.
29991///
29992/// @param internal if true then the type name is going to be used for
29993/// type canonicalization purposes.
29994static interned_string
29995ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
29996 const string& variable_name,
29997 bool qualified, bool internal)
29998{
29999 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
30000 qualified, internal);
30001}
30002
30003/// Sort types right before hashing and canonicalizing them.
30004///
30005/// @param types the vector of types to sort.
30006void
30007sort_types_for_hash_computing_and_c14n(vector<type_base_sptr>& types)
30008{
30009 sort_types_for_hash_computing_and_c14n(types.begin(), types.end());
30010}
30011
30012bool
30014{return true;}
30015
30016// <ir_node_visitor stuff>
30017
30018/// The private data structure of the ir_node_visitor type.
30019struct ir_node_visitor::priv
30020{
30021 pointer_set visited_ir_nodes;
30023
30024 priv()
30026 {}
30027}; // end struct ir_node_visitory::priv
30028
30029/// Default Constructor of the ir_node_visitor type.
30031 : priv_(new priv)
30032{}
30033
30034ir_node_visitor::~ir_node_visitor() = default;
30035
30036/// Set if the walker using this visitor is allowed to re-visit a type
30037/// node that was previously visited or not.
30038///
30039/// @param f if true, then the walker using this visitor is allowed to
30040/// re-visit a type node that was previously visited.
30041void
30043{priv_->allow_visiting_already_visited_type_node = f;}
30044
30045/// Get if the walker using this visitor is allowed to re-visit a type
30046/// node that was previously visited or not.
30047///
30048/// @return true iff the walker using this visitor is allowed to
30049/// re-visit a type node that was previously visited.
30050bool
30052{return priv_->allow_visiting_already_visited_type_node;}
30053
30054/// Mark a given type node as having been visited.
30055///
30056/// Note that for this function to work, the type node must have been
30057/// canonicalized. Otherwise the process is aborted.
30058///
30059/// @param p the type to mark as having been visited.
30060void
30062{
30064 return;
30065
30066 if (p == 0 || type_node_has_been_visited(p))
30067 return;
30068
30069 type_base* canonical_type = p->get_naked_canonical_type();
30071 {
30072 ABG_ASSERT(!canonical_type);
30073 canonical_type = p;
30074 }
30075 ABG_ASSERT(canonical_type);
30076
30077 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
30078 priv_->visited_ir_nodes.insert(canonical_ptr_value);
30079}
30080
30081/// Un-mark all visited type nodes.
30082///
30083/// That is, no type node is going to be considered as having been
30084/// visited anymore.
30085///
30086/// In other words, after invoking this funciton,
30087/// ir_node_visitor::type_node_has_been_visited() is going to return
30088/// false on all type nodes.
30089void
30091{priv_->visited_ir_nodes.clear();}
30092
30093/// Test if a given type node has been marked as visited.
30094///
30095/// @param p the type node to consider.
30096///
30097/// @return true iff the type node @p p has been marked as visited by
30098/// the function ir_node_visitor::mark_type_node_as_visited.
30099bool
30101{
30103 return false;
30104
30105 if (p == 0)
30106 return false;
30107
30108 type_base *canonical_type = p->get_naked_canonical_type();
30110 {
30111 ABG_ASSERT(!canonical_type);
30112 canonical_type = p;
30113 }
30114 ABG_ASSERT(canonical_type);
30115
30116 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
30117 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
30118 if (it == priv_->visited_ir_nodes.end())
30119 return false;
30120
30121 return true;
30122}
30123
30124bool
30125ir_node_visitor::visit_begin(decl_base*)
30126{return true;}
30127
30128bool
30129ir_node_visitor::visit_end(decl_base*)
30130{return true;}
30131
30132bool
30133ir_node_visitor::visit_begin(scope_decl*)
30134{return true;}
30135
30136bool
30137ir_node_visitor::visit_end(scope_decl*)
30138{return true;}
30139
30140bool
30141ir_node_visitor::visit_begin(type_base*)
30142{return true;}
30143
30144bool
30145ir_node_visitor::visit_end(type_base*)
30146{return true;}
30147
30148bool
30149ir_node_visitor::visit_begin(scope_type_decl* t)
30150{return visit_begin(static_cast<type_base*>(t));}
30151
30152bool
30153ir_node_visitor::visit_end(scope_type_decl* t)
30154{return visit_end(static_cast<type_base*>(t));}
30155
30156bool
30157ir_node_visitor::visit_begin(type_decl* t)
30158{return visit_begin(static_cast<type_base*>(t));}
30159
30160bool
30161ir_node_visitor::visit_end(type_decl* t)
30162{return visit_end(static_cast<type_base*>(t));}
30163
30164bool
30165ir_node_visitor::visit_begin(namespace_decl* d)
30166{return visit_begin(static_cast<decl_base*>(d));}
30167
30168bool
30169ir_node_visitor::visit_end(namespace_decl* d)
30170{return visit_end(static_cast<decl_base*>(d));}
30171
30172bool
30173ir_node_visitor::visit_begin(qualified_type_def* t)
30174{return visit_begin(static_cast<type_base*>(t));}
30175
30176bool
30177ir_node_visitor::visit_end(qualified_type_def* t)
30178{return visit_end(static_cast<type_base*>(t));}
30179
30180bool
30181ir_node_visitor::visit_begin(pointer_type_def* t)
30182{return visit_begin(static_cast<type_base*>(t));}
30183
30184bool
30185ir_node_visitor::visit_end(pointer_type_def* t)
30186{return visit_end(static_cast<type_base*>(t));}
30187
30188bool
30189ir_node_visitor::visit_begin(reference_type_def* t)
30190{return visit_begin(static_cast<type_base*>(t));}
30191
30192bool
30193ir_node_visitor::visit_end(reference_type_def* t)
30194{return visit_end(static_cast<type_base*>(t));}
30195
30196bool
30197ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
30198{return visit_begin(static_cast<type_base*>(t));}
30199
30200bool
30201ir_node_visitor::visit_end(ptr_to_mbr_type* t)
30202{return visit_end(static_cast<type_base*>(t));}
30203
30204bool
30205ir_node_visitor::visit_begin(array_type_def* t)
30206{return visit_begin(static_cast<type_base*>(t));}
30207
30208bool
30209ir_node_visitor::visit_end(array_type_def* t)
30210{return visit_end(static_cast<type_base*>(t));}
30211
30212bool
30213ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
30214{return visit_begin(static_cast<type_base*>(t));}
30215
30216bool
30217ir_node_visitor::visit_end(array_type_def::subrange_type* t)
30218{return visit_end(static_cast<type_base*>(t));}
30219
30220bool
30221ir_node_visitor::visit_begin(enum_type_decl* t)
30222{return visit_begin(static_cast<type_base*>(t));}
30223
30224bool
30225ir_node_visitor::visit_end(enum_type_decl* t)
30226{return visit_end(static_cast<type_base*>(t));}
30227
30228bool
30229ir_node_visitor::visit_begin(typedef_decl* t)
30230{return visit_begin(static_cast<type_base*>(t));}
30231
30232bool
30233ir_node_visitor::visit_end(typedef_decl* t)
30234{return visit_end(static_cast<type_base*>(t));}
30235
30236bool
30237ir_node_visitor::visit_begin(function_type* t)
30238{return visit_begin(static_cast<type_base*>(t));}
30239
30240bool
30241ir_node_visitor::visit_end(function_type* t)
30242{return visit_end(static_cast<type_base*>(t));}
30243
30244bool
30245ir_node_visitor::visit_begin(var_decl* d)
30246{return visit_begin(static_cast<decl_base*>(d));}
30247
30248bool
30249ir_node_visitor::visit_end(var_decl* d)
30250{return visit_end(static_cast<decl_base*>(d));}
30251
30252bool
30253ir_node_visitor::visit_begin(function_decl* d)
30254{return visit_begin(static_cast<decl_base*>(d));}
30255
30256bool
30257ir_node_visitor::visit_end(function_decl* d)
30258{return visit_end(static_cast<decl_base*>(d));}
30259
30260bool
30261ir_node_visitor::visit_begin(function_decl::parameter* d)
30262{return visit_begin(static_cast<decl_base*>(d));}
30263
30264bool
30265ir_node_visitor::visit_end(function_decl::parameter* d)
30266{return visit_end(static_cast<decl_base*>(d));}
30267
30268bool
30269ir_node_visitor::visit_begin(function_tdecl* d)
30270{return visit_begin(static_cast<decl_base*>(d));}
30271
30272bool
30273ir_node_visitor::visit_end(function_tdecl* d)
30274{return visit_end(static_cast<decl_base*>(d));}
30275
30276bool
30277ir_node_visitor::visit_begin(class_tdecl* d)
30278{return visit_begin(static_cast<decl_base*>(d));}
30279
30280bool
30281ir_node_visitor::visit_end(class_tdecl* d)
30282{return visit_end(static_cast<decl_base*>(d));}
30283
30284bool
30285ir_node_visitor::visit_begin(class_or_union* t)
30286{return visit_begin(static_cast<type_base*>(t));}
30287
30288bool
30289ir_node_visitor::visit_end(class_or_union* t)
30290{return visit_end(static_cast<type_base*>(t));}
30291
30292bool
30293ir_node_visitor::visit_begin(class_decl* t)
30294{return visit_begin(static_cast<type_base*>(t));}
30295
30296bool
30297ir_node_visitor::visit_end(class_decl* t)
30298{return visit_end(static_cast<type_base*>(t));}
30299
30300bool
30301ir_node_visitor::visit_begin(union_decl* t)
30302{return visit_begin(static_cast<type_base*>(t));}
30303
30304bool
30305ir_node_visitor::visit_end(union_decl* t)
30306{return visit_end(static_cast<type_base*>(t));}
30307
30308bool
30309ir_node_visitor::visit_begin(class_decl::base_spec* d)
30310{return visit_begin(static_cast<decl_base*>(d));}
30311
30312bool
30313ir_node_visitor::visit_end(class_decl::base_spec* d)
30314{return visit_end(static_cast<decl_base*>(d));}
30315
30316bool
30317ir_node_visitor::visit_begin(member_function_template* d)
30318{return visit_begin(static_cast<decl_base*>(d));}
30319
30320bool
30321ir_node_visitor::visit_end(member_function_template* d)
30322{return visit_end(static_cast<decl_base*>(d));}
30323
30324bool
30325ir_node_visitor::visit_begin(member_class_template* d)
30326{return visit_begin(static_cast<decl_base*>(d));}
30327
30328bool
30329ir_node_visitor::visit_end(member_class_template* d)
30330{return visit_end(static_cast<decl_base*>(d));}
30331
30332// </ir_node_visitor stuff>
30333
30334// <debugging facilities>
30335
30336/// Generate a different string at each invocation.
30337///
30338/// @return the resulting string.
30339static string
30340get_next_string()
30341{
30342 static __thread size_t counter;
30343 ++counter;
30344 std::ostringstream o;
30345 o << counter;
30346 return o.str();
30347}
30348
30349/// A hashing functor for a @ref function_decl
30350struct function_decl_hash
30351{
30352 size_t operator()(const function_decl* f) const
30353 {return reinterpret_cast<size_t>(f);}
30354
30355 size_t operator()(const function_decl_sptr& f) const
30356 {return operator()(f.get());}
30357};
30358
30359/// Convenience typedef for a hash map of pointer to function_decl and
30360/// string.
30361typedef unordered_map<const function_decl*, string,
30362 function_decl_hash,
30364
30365/// Return a string associated to a given function. Two functions
30366/// that compare equal would yield the same string, as far as this
30367/// routine is concerned. And two functions that are different would
30368/// yield different strings.
30369///
30370/// This is used to debug core diffing issues on functions. The
30371/// sequence of strings can be given to the 'testdiff2' program that
30372/// is in the tests/ directory of the source tree, to reproduce core
30373/// diffing issues on string and thus ease the debugging.
30374///
30375/// @param fn the function to generate a string for.
30376///
30377/// @param m the function_decl* <-> string map to be used by this
30378/// function to generate strings associated to a function.
30379///
30380/// @return the resulting string.
30381static const string&
30382fn_to_str(const function_decl* fn,
30384{
30385 fns_to_str_map_type::const_iterator i = m.find(fn);
30386 if (i != m.end())
30387 return i->second;
30388 string s = get_next_string();
30389 return m[fn]= s;
30390}
30391
30392/// Generate a sequence of string that matches a given sequence of
30393/// function. In the resulting sequence, each function is "uniquely
30394/// representated" by a string. For instance, if the same function "foo"
30395/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
30396/// we don't care about the actual string) would appear at index 1 and 3.
30397///
30398/// @param begin the beginning of the sequence of functions to consider.
30399///
30400/// @param end the end of the sequence of functions. This points to
30401/// one-passed-the-end of the actual sequence.
30402///
30403/// @param m the function_decl* <-> string map to be used by this
30404/// function to generate strings associated to a function.
30405///
30406/// @param o the output stream where to emit the generated list of
30407/// strings to.
30408static void
30409fns_to_str(vector<function_decl*>::const_iterator begin,
30410 vector<function_decl*>::const_iterator end,
30412 std::ostream& o)
30413{
30414 vector<function_decl*>::const_iterator i;
30415 for (i = begin; i != end; ++i)
30416 o << "'" << fn_to_str(*i, m) << "' ";
30417}
30418
30419/// For each sequence of functions given in argument, generate a
30420/// sequence of string that matches a given sequence of function. In
30421/// the resulting sequence, each function is "uniquely representated"
30422/// by a string. For instance, if the same function "foo" appears at
30423/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30424/// care about the actual string) would appear at index 1 and 3.
30425///
30426/// @param a_begin the beginning of the sequence of functions to consider.
30427///
30428/// @param a_end the end of the sequence of functions. This points to
30429/// one-passed-the-end of the actual sequence.
30430///
30431/// @param b_begin the beginning of the second sequence of functions
30432/// to consider.
30433///
30434/// @param b_end the end of the second sequence of functions.
30435///
30436/// @param m the function_decl* <-> string map to be used by this
30437/// function to generate strings associated to a function.
30438///
30439/// @param o the output stream where to emit the generated list of
30440/// strings to.
30441static void
30442fns_to_str(vector<function_decl*>::const_iterator a_begin,
30443 vector<function_decl*>::const_iterator a_end,
30444 vector<function_decl*>::const_iterator b_begin,
30445 vector<function_decl*>::const_iterator b_end,
30447 std::ostream& o)
30448{
30449 fns_to_str(a_begin, a_end, m, o);
30450 o << "->|<- ";
30451 fns_to_str(b_begin, b_end, m, o);
30452 o << "\n";
30453}
30454
30455/// For each sequence of functions given in argument, generate a
30456/// sequence of string that matches a given sequence of function. In
30457/// the resulting sequence, each function is "uniquely representated"
30458/// by a string. For instance, if the same function "foo" appears at
30459/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30460/// care about the actual string) would appear at index 1 and 3.
30461///
30462/// @param a_begin the beginning of the sequence of functions to consider.
30463///
30464/// @param a_end the end of the sequence of functions. This points to
30465/// one-passed-the-end of the actual sequence.
30466///
30467/// @param b_begin the beginning of the second sequence of functions
30468/// to consider.
30469///
30470/// @param b_end the end of the second sequence of functions.
30471///
30472/// @param o the output stream where to emit the generated list of
30473/// strings to.
30474void
30475fns_to_str(vector<function_decl*>::const_iterator a_begin,
30476 vector<function_decl*>::const_iterator a_end,
30477 vector<function_decl*>::const_iterator b_begin,
30478 vector<function_decl*>::const_iterator b_end,
30479 std::ostream& o)
30480{
30482 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
30483}
30484
30485// </debugging facilities>
30486
30487// </class template>
30488
30489}// end namespace ir
30490}//end namespace abigail
30491
30492namespace
30493{
30494
30495/// Update the qualified parent name, qualified name and scoped name
30496/// of a tree decl node.
30497///
30498/// @return true if the tree walking should continue, false otherwise.
30499///
30500/// @param d the tree node to take in account.
30501bool
30502qualified_name_setter::do_update(abigail::ir::decl_base* d)
30503{
30504 std::string parent_qualified_name;
30505 abigail::ir::scope_decl* parent = d->get_scope();
30506 if (parent)
30507 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
30508 else
30509 d->priv_->qualified_parent_name_ = abigail::interned_string();
30510
30511 const abigail::ir::environment& env = d->get_environment();
30512
30513 if (!d->priv_->qualified_parent_name_.empty())
30514 {
30515 if (d->get_name().empty())
30516 d->priv_->qualified_name_ = abigail::interned_string();
30517 else
30518 {
30519 d->priv_->qualified_name_ =
30520 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
30521 d->priv_->internal_qualified_name_ = env.intern(d->get_name());
30522 }
30523 }
30524 // Make sure the internal qualified name (used for type
30525 // canonicalization puroses) is always the qualified name. For
30526 // integral/real types however, only the non qualified type is used.
30527 if (!is_integral_type(d))
30528 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
30529
30530 if (d->priv_->scoped_name_.empty())
30531 {
30532 if (parent
30533 && !parent->get_is_anonymous()
30534 && !parent->get_name().empty())
30535 d->priv_->scoped_name_ =
30536 env.intern(parent->get_name() + "::" + d->get_name());
30537 else
30538 d->priv_->scoped_name_ =
30539 env.intern(d->get_name());
30540 }
30541
30542 if (!is_scope_decl(d))
30543 return false;
30544
30545 return true;
30546}
30547
30548/// This is called when we start visiting a decl node, during the
30549/// udpate of the qualified name of a given sub-tree.
30550///
30551/// @param d the decl node we are visiting.
30552///
30553/// @return true iff the traversal should keep going.
30554bool
30555qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
30556{return do_update(d);}
30557
30558/// This is called when we start visiting a type node, during the
30559/// udpate of the qualified name of a given sub-tree.
30560///
30561/// @param d the decl node we are visiting.
30562///
30563/// @return true iff the traversal should keep going.
30564bool
30565qualified_name_setter::visit_begin(abigail::ir::type_base* t)
30566{
30568 return do_update(d);
30569 return false;
30570}
30571}// 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:19170
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:19138
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:19131
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition: abg-ir.cc:19145
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition: abg-ir.cc:19182
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition: abg-ir.cc:19153
bound_value()
Default constructor of the array_type_def::subrange_type::bound_value class.
Definition: abg-ir.cc:19103
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition: abg-ir.cc:19160
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:19361
bool is_non_finite() const
Test if the length of the subrange type is infinite.
Definition: abg-ir.cc:19388
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition: abg-ir.cc:19354
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:19328
string as_string() const
Return a string representation of the sub range.
Definition: abg-ir.cc:19410
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:19309
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19610
bool operator!=(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:19549
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition: abg-ir.cc:19340
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:19320
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:19505
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition: abg-ir.cc:19347
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:19588
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition: abg-ir.cc:19433
uint64_t get_length() const
Getter of the length of the subrange type.
Definition: abg-ir.cc:19371
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition: abg-ir.cc:19403
The abstraction of an array type.
Definition: abg-ir.h:2548
virtual bool is_non_finite() const
Definition: abg-ir.cc:20027
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:20057
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:19717
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition: abg-ir.cc:19988
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition: abg-ir.cc:20003
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:20120
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition: abg-ir.cc:20147
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:19966
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:19770
translation_unit::language get_language() const
Get the language of the array.
Definition: abg-ir.cc:19955
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition: abg-ir.cc:20013
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:25287
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition: abg-ir.cc:25294
long get_offset_in_bits() const
Getter of the offset of the base.
Definition: abg-ir.cc:25301
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:25276
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:25317
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Definition: abg-ir.cc:25411
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:25084
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition: abg-ir.cc:25867
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:25153
bool is_struct() const
Test if the class is a struct.
Definition: abg-ir.cc:25091
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:25930
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition: abg-ir.cc:25108
virtual ~class_decl()
Destructor of the class_decl type.
Definition: abg-ir.cc:26444
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:25069
bool has_vtable() const
Test if the current instance has a vtable.
Definition: abg-ir.cc:25895
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition: abg-ir.cc:25909
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition: abg-ir.cc:25876
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26360
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:25098
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition: abg-ir.cc:25134
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition: abg-ir.cc:25158
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition: abg-ir.cc:26028
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition: abg-ir.cc:26208
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:25118
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition: abg-ir.cc:25858
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:25179
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:24026
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:24267
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:24192
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition: abg-ir.cc:24295
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
Definition: abg-ir.cc:23912
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition: abg-ir.cc:24371
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition: abg-ir.cc:24011
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition: abg-ir.cc:24044
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
Definition: abg-ir.cc:24385
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:24151
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:23802
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:24093
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:24346
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:24330
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition: abg-ir.cc:23995
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
Definition: abg-ir.cc:24427
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:23900
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:23818
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition: abg-ir.cc:24399
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
Definition: abg-ir.cc:24242
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:24304
const data_members & get_static_data_members() const
Get the static data memebers of this class_or_union.
Definition: abg-ir.cc:24250
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:23937
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:23891
bool has_no_member() const
Definition: abg-ir.cc:24412
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:24461
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26747
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition: abg-ir.cc:23963
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition: abg-ir.cc:24378
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition: abg-ir.cc:23979
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:24062
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:24162
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:28139
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
Definition: abg-ir.cc:28128
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:28188
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:28143
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:16248
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:20830
bool operator!=(const enumerator &other) const
Inequality operator.
Definition: abg-ir.cc:20890
void set_name(const string &n)
Setter for the name of enum_type_decl::enumerator.
Definition: abg-ir.cc:20932
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition: abg-ir.cc:20954
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition: abg-ir.cc:20899
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition: abg-ir.cc:20961
void set_value(int64_t v)
Setter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:20947
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:20916
int64_t get_value() const
Getter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:20940
bool operator==(const enumerator &other) const
Equality operator.
Definition: abg-ir.cc:20877
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:20861
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:20220
virtual ~enum_type_decl()
Destructor for the enum type declaration.
Definition: abg-ir.cc:20381
const enumerators & get_enumerators() const
Definition: abg-ir.cc:20233
bool find_enumerator_by_value(int64_t value, enum_type_decl::enumerator &result)
Find an enumerator by its value.
Definition: abg-ir.cc:20279
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
Definition: abg-ir.cc:20245
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:20359
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition: abg-ir.cc:20228
bool find_enumerator_by_name(const string &name, enum_type_decl::enumerator &result)
Find an enumerator by its name.
Definition: abg-ir.cc:20303
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:20751
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:20334
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:23636
interned_string get_type_name() const
Definition: abg-ir.cc:23435
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition: abg-ir.cc:23473
const string get_type_pretty_representation() const
Definition: abg-ir.cc:23454
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition: abg-ir.cc:23612
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:23656
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:22836
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition: abg-ir.cc:22907
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:23297
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition: abg-ir.cc:22987
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition: abg-ir.cc:23212
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition: abg-ir.cc:22873
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition: abg-ir.cc:22892
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:22699
const type_base_sptr get_return_type() const
Definition: abg-ir.cc:22968
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition: abg-ir.cc:23000
const std::vector< parameter_sptr > & get_parameters() const
Definition: abg-ir.cc:22973
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition: abg-ir.cc:22980
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition: abg-ir.cc:22929
virtual ~function_decl()
Destructor of the function_decl type.
Definition: abg-ir.cc:23313
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:22945
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition: abg-ir.cc:23198
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:22952
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:22768
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:23228
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:27976
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
Definition: abg-ir.cc:27958
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition: abg-ir.cc:27969
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:28036
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition: abg-ir.cc:27985
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:21941
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:22360
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition: abg-ir.cc:22048
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:22257
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:21848
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition: abg-ir.cc:22319
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:22033
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition: abg-ir.cc:22010
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition: abg-ir.cc:22277
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:21989
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition: abg-ir.cc:21952
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition: abg-ir.cc:21960
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:22235
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition: abg-ir.cc:21969
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:22343
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:30051
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition: abg-ir.cc:30100
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition: abg-ir.cc:30090
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition: abg-ir.cc:30030
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition: abg-ir.cc:30061
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:26607
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26692
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:26586
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:25558
const method_type_sptr get_type() const
Definition: abg-ir.cc:25585
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:22561
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:22542
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition: abg-ir.cc:22593
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
Definition: abg-ir.cc:22608
virtual ~method_type()
The destructor of method_type.
Definition: abg-ir.cc:22641
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:22585
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition: abg-ir.cc:22552
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition: abg-ir.cc:22600
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:17369
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17400
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition: abg-ir.cc:17303
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition: abg-ir.cc:17355
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:17341
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:27674
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:27679
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:18062
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:18188
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18052
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:17979
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18282
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition: abg-ir.cc:18124
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition: abg-ir.cc:18168
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition: abg-ir.cc:18175
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:18952
virtual const interned_string & get_name() const
Getter of the name of the current ptr-to-mbr-type.
Definition: abg-ir.cc:18862
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18875
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:18895
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
Definition: abg-ir.cc:18936
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:19003
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
Definition: abg-ir.cc:18886
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
Definition: abg-ir.cc:19028
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:17705
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition: abg-ir.cc:17830
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition: abg-ir.cc:17569
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:17557
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:17818
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:17495
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition: abg-ir.cc:17809
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17778
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition: abg-ir.cc:17804
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition: abg-ir.cc:17823
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition: abg-ir.cc:17649
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition: abg-ir.cc:17472
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:16745
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
Definition: abg-ir.cc:16768
base_type get_base_type() const
Getter of the base type of the real_type.
Definition: abg-ir.cc:16731
bool operator==(const real_type &) const
Equality operator for the real_type.
Definition: abg-ir.cc:16755
real_type()
Default constructor of the real_type.
Definition: abg-ir.cc:16701
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:16738
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:18611
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18474
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:18376
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18733
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:18484
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition: abg-ir.cc:18553
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:18712
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:17262
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition: abg-ir.cc:17224
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:27349
virtual ~template_decl()
Destructor.
Definition: abg-ir.cc:27374
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:27341
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:27383
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:27503
bool operator!=(const template_parameter &) const
Inequality operator.
Definition: abg-ir.cc:27499
Abstracts a template template parameter.
Definition: abg-ir.h:3695
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:27752
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:16331
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition: abg-ir.cc:16307
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition: abg-ir.cc:16410
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:16277
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:16436
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:16010
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition: abg-ir.cc:16403
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition: abg-ir.cc:16396
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition: abg-ir.cc:16386
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition: abg-ir.cc:16424
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition: abg-ir.cc:16417
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition: abg-ir.cc:16291
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:27858
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition: abg-ir.cc:27865
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:17056
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:16896
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17135
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:16994
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:16950
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:17115
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:11100
friend hash_t peek_hash_value(const type_or_decl_base &)
Get the hash value associated to an IR node.
Definition: abg-ir.cc:28461
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:10705
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:10778
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:27545
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:21216
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition: abg-ir.cc:21201
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition: abg-ir.cc:21056
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:21043
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:21248
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition: abg-ir.cc:21194
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:21136
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition: abg-ir.cc:21073
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:21177
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:27026
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:27143
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition: abg-ir.cc:27083
virtual ~union_decl()
Destructor of the union_decl type.
Definition: abg-ir.cc:27216
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:27050
Abstracts a variable declaration.
Definition: abg-ir.h:3068
binding get_binding() const
Getter of the binding of the variable.
Definition: abg-ir.cc:21362
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition: abg-ir.cc:21344
void set_binding(binding b)
Setter of the binding of the variable.
Definition: abg-ir.cc:21369
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:21407
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:21658
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:21355
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:21337
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:21820
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:21797
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition: abg-ir.cc:21384
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:21400
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition: abg-ir.cc:21593
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:21688
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:21612
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:11703
real_type::modifiers_type operator~(real_type::modifiers_type l)
Bitwise one's complement operator for real_type::modifiers_type.
Definition: abg-ir.cc:16493
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:11297
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:20393
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:13786
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:12884
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition: abg-ir.cc:28488
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:28461
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:28439
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:12235
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:11563
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:10672
class_decl_sptr is_class_type(const type_or_decl_base_sptr &d)
Test whether a type is a class.
Definition: abg-ir.cc:11118
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:12022
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:16169
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:11480
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:10142
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:10125
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:14220
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:13701
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:9004
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition: abg-ir.cc:23279
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:11462
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:15751
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:14624
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:14114
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:14269
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:13627
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:11657
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:11082
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:11738
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:27299
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:25814
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:19850
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:13968
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:9652
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10765
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:13874
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:10639
translation_unit * get_translation_unit(const type_or_decl_base_sptr &decl)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:10501
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:10947
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:26501
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:12141
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:14056
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:13511
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:10039
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
Definition: abg-ir.cc:28559
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:13226
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:10999
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:16686
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:11969
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:10207
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:13999
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:29065
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:11637
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:13246
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:11332
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:9684
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:12261
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:10192
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:11391
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition: abg-ir.cc:11091
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:15197
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:11834
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:13536
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:14174
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:11275
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:14497
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:9286
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:14139
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:14390
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:10925
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:10905
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:11804
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:28703
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:11884
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:11322
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:11953
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:10841
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:12004
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:12097
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:10867
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10745
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:11893
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:11784
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:11934
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition: abg-ir.cc:10969
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:10793
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:9833
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:15280
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:21468
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:13486
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:10756
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:11577
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:29666
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:11032
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:10695
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:11864
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:13739
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:11041
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:28651
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:10608
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:10052
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:28352
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:12065
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:12164
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:13833
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:12013
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:29630
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:11676
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:30363
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition: abg-ir.cc:12170
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:28289
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:10682
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:13646
class_or_union * is_at_class_scope(const decl_base &decl)
Tests whether a given decl is at class scope.
Definition: abg-ir.cc:10588
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:13193
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:12498
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:9041
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:14654
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:20474
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:9243
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:11050
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:11262
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:14444
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:28997
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:11985
string get_pretty_representation(const method_type_sptr method, bool internal)
Get the pretty representation of a method type.
Definition: abg-ir.cc:9488
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:10705
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:28327
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:25647
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:9508
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:12154
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:29019
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:10852
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:12951
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:10875
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:10565
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:11405
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:9805
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:10450
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:11445
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:10461
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:9118
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:12036
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:11844
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:11371
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition: abg-ir.cc:10071
bool is_global_scope(const shared_ptr< scope_decl >scope)
Tests whether if a given scope is the global scope.
Definition: abg-ir.cc:10529
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:14094
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:9071
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:12120
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
Definition: abg-ir.cc:10510
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:11497
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:29044
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition: abg-ir.cc:10229
bool is_at_global_scope(const decl_base *decl)
Tests whether a given declaration is at global scope.
Definition: abg-ir.cc:10556
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26747
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:12049
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:28954
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:9180
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:9775
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:10262
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:14319
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:11995
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:15354
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition: abg-ir.cc:28524
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:15091
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:9155
decl_base_sptr is_decl(const type_or_decl_base_sptr &d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10734
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:9019
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:29589
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
Definition: abg-ir.cc:10630
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10653
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:28311
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:14562
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:11180
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:11814
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:11764
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:11517
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:24760
decl_base_sptr get_type_declaration(const type_base_sptr t)
Get the declaration for a given type.
Definition: abg-ir.cc:10247
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:15384
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:11429
type_decl * is_real_type(const type_or_decl_base *t)
Test if a type is a real type.
Definition: abg-ir.cc:10885
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:13801
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:11774
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:11361
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:11621
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:11311
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:13931
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:30013
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.