libabigail
Loading...
Searching...
No Matches
abg-ir.cc
Go to the documentation of this file.
1// C++ -*-
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// -*- Mode: C++ -*-
4
5// Copyright (C) 2013-2024 Red Hat, Inc.
6//
7//Author: Dodji Seketeli
8
9/// @file
10///
11/// Definitions for the Internal Representation artifacts of libabigail.
12
13#include <cxxabi.h>
14#include <cstdint>
15#include <functional>
16#include <iterator>
17#include <memory>
18#include <sstream>
19#include <typeinfo>
20#include <unordered_map>
21#include <utility>
22#include <vector>
23
24#include "abg-internal.h"
25// <headers defining libabigail's API go under here>
26ABG_BEGIN_EXPORT_DECLARATIONS
27
28#include "abg-interned-str.h"
29#include "abg-ir.h"
30#include "abg-corpus.h"
31#include "abg-regex.h"
32
33ABG_END_EXPORT_DECLARATIONS
34// </headers defining libabigail's API>
35
36#include "abg-corpus-priv.h"
37#include "abg-comp-filter.h"
38#include "abg-ir-priv.h"
39
40namespace
41{
42/// This internal type is a tree walking that is used to set the
43/// qualified name of a tree of decls and types. It used by the
44/// function update_qualified_name().
45class qualified_name_setter : public abigail::ir::ir_node_visitor
46{
47
48public:
49 bool
50 do_update(abigail::ir::decl_base* d);
51
52 bool
53 visit_begin(abigail::ir::decl_base* d);
54
55 bool
56 visit_begin(abigail::ir::type_base* d);
57}; // end class qualified_name_setter
58
59}// end anon namespace
60
61namespace abigail
62{
63
64// Inject.
65using std::string;
66using std::list;
67using std::vector;
68using std::unordered_map;
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
71
72/// Convenience typedef for a map of string -> string*.
73typedef unordered_map<string, string*> pool_map_type;
74
75/// The type of the private data structure of type @ref
76/// intered_string_pool.
77struct interned_string_pool::priv
78{
79 pool_map_type map;
80}; //end struc struct interned_string_pool::priv
81
82/// Default constructor.
84 : priv_(new priv)
85{
86 priv_->map[""] = 0;
87}
88
89/// Test if the interned string pool already contains a string with a
90/// given value.
91///
92/// @param s the string to test for.
93///
94/// @return true if the pool contains a string with the value @p s.
95bool
97{return priv_->map.find(s) != priv_->map.end();}
98
99/// Get a pointer to the interned string which has a given value.
100///
101/// @param s the value of the interned string to look for.
102///
103/// @return a pointer to the raw string of characters which has the
104/// value of @p s. Or null if no string with value @p s was interned.
105const char*
107{
108 unordered_map<string, string*>::const_iterator i =
109 priv_->map.find(s);
110 if (i == priv_->map.end())
111 return 0;
112 if (i->second)
113 return i->second->c_str();
114 return "";
115}
116
117/// Create an interned string with a given value.
118///
119/// @param str_value the value of the interned string to create.
120///
121/// @return the new created instance of @ref interned_string created.
123interned_string_pool::create_string(const std::string& str_value)
124{
125 string*& result = priv_->map[str_value];
126 if (!result && !str_value.empty())
127 result = new string(str_value);
128 return interned_string(result);
129}
130
131/// Destructor.
133{
134 for (pool_map_type::iterator i = priv_->map.begin();
135 i != priv_->map.end();
136 ++i)
137 if (i->second)
138 delete i->second;
139}
140
141/// Equality operator.
142///
143/// @param l the instance of std::string on the left-hand-side of the
144/// equality operator.
145///
146/// @param r the instance of @ref interned_string on the
147/// right-hand-side of the equality operator.
148///
149/// @return true iff the two string are equal.
150bool
151operator==(const std::string& l, const interned_string& r)
152{return r.operator==(l);}
153
154bool
155operator!=(const std::string& l, const interned_string& r)
156{return !(l == r);}
157
158/// Streaming operator.
159///
160/// Streams an instance of @ref interned_string to an output stream.
161///
162/// @param o the destination output stream.
163///
164/// @param s the instance of @ref interned_string to stream out.
165///
166/// @return the output stream this function just streamed to.
167std::ostream&
168operator<<(std::ostream& o, const interned_string& s)
169{
170 o << static_cast<std::string>(s);
171 return o;
172}
173
174/// Concatenation operator.
175///
176/// Concatenate two instances of @ref interned_string, builds an
177/// instance of std::string with the resulting string and return it.
178///
179/// @param s1 the first string to consider.
180///
181/// @param s2 the second string to consider.
182///
183/// @return the resuting concatenated string.
184std::string
185operator+(const interned_string& s1,const std::string& s2)
186{return static_cast<std::string>(s1) + s2;}
187
188/// Concatenation operator.
189///
190/// Concatenate two instances of @ref interned_string, builds an
191/// instance of std::string with the resulting string and return it.
192///
193/// @param s1 the first string to consider.
194///
195/// @param s2 the second string to consider.
196///
197/// @return the resuting concatenated string.
198std::string
199operator+(const std::string& s1, const interned_string& s2)
200{return s1 + static_cast<std::string>(s2);}
201
202namespace ir
203{
204
205static size_t
206hash_as_canonical_type_or_constant(const type_base *t);
207
208static bool
209has_generic_anonymous_internal_type_name(const decl_base *d);
210
211static interned_string
212get_generic_anonymous_internal_type_name(const decl_base *d);
213
214static string
215get_internal_real_type_name(const type_base*);
216
217static void
218update_qualified_name(decl_base * d);
219
220static void
221update_qualified_name(decl_base_sptr d);
222
223static interned_string
224pointer_declaration_name(const type_base* ptr,
225 const string& variable_name,
226 bool qualified, bool internal);
227
228static interned_string
229pointer_declaration_name(const type_base_sptr& ptr,
230 const string& variable_name,
231 bool qualified, bool internal);
232
233static interned_string
234ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
235 const string& variable_name,
236 bool qualified, bool internal);
237
238static interned_string
239ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
240 const string& variable_name,
241 bool qualified, bool internal);
242
243static interned_string
244array_declaration_name(const array_type_def* array,
245 const string& variable_name,
246 bool qualified, bool internal);
247
248static interned_string
249array_declaration_name(const array_type_def_sptr& array,
250 const string& variable_name,
251 bool qualified, bool internal);
252
253static void
254stream_pretty_representation_of_fn_parms(const function_type& fn_type,
255 ostream& o, bool qualified,
256 bool internal);
257static string
258add_outer_pointer_to_fn_type_expr(const type_base* pointer_to_fn,
259 const string& input, bool qualified,
260 bool internal);
261
262static string
263add_outer_pointer_to_fn_type_expr(const type_base_sptr& pointer_to_fn,
264 const string& input, bool qualified,
265 bool internal);
266
267static string
268add_outer_pointer_to_array_type_expr(const type_base* pointer_to_ar,
269 const string& input, bool qualified,
270 bool internal);
271
272static string
273add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
274 const string& input, bool qualified,
275 bool internal);
276
277static string
278add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
279 const string& input, bool qualified,
280 bool internal);
281
282static string
283add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
284 const string& input, bool qualified,
285 bool internal);
286
287static string
288add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
289 const string& input,
290 bool qualified, bool internal);
291
292void
293push_composite_type_comparison_operands(const type_base& left,
294 const type_base& right);
295
296void
297pop_composite_type_comparison_operands(const type_base& left,
298 const type_base& right);
299
300
301/// Push a pair of operands on the stack of operands of the current
302/// type comparison, during type canonicalization.
303///
304/// For more information on this, please look at the description of
305/// the environment::priv::right_type_comp_operands_ data member.
306///
307/// @param left the left-hand-side comparison operand to push.
308///
309/// @param right the right-hand-side comparison operand to push.
310void
312 const type_base& right)
313{
314 const environment& env = left.get_environment();
315 env.priv_->push_composite_type_comparison_operands(&left, &right);
316}
317
318/// Pop a pair of operands from the stack of operands to the current
319/// type comparison.
320///
321/// For more information on this, please look at the description of
322/// the environment::privright_type_comp_operands_ data member.
323///
324/// @param left the left-hand-side comparison operand we expect to
325/// pop from the top of the stack. If this doesn't match the
326/// operand found on the top of the stack, the function aborts.
327///
328/// @param right the right-hand-side comparison operand we expect to
329/// pop from the bottom of the stack. If this doesn't match the
330/// operand found on the top of the stack, the function aborts.
331void
333 const type_base& right)
334{
335 const environment& env = left.get_environment();
336 env.priv_->pop_composite_type_comparison_operands(&left, &right);
337}
338
339/// Getter of the canonical type index of a given type.
340///
341/// @param t the type to consider.
342///
343/// @return the CTI of the type.
344size_t
346{return t.priv_->canonical_type_index;}
347
348/// Getter of the canonical type index of a given type.
349///
350/// @param t the type to consider.
351///
352/// @return the CTI of the type.
353size_t
356
357/// Getter of the canonical type index of a given type.
358///
359/// @param t the type to consider.
360///
361/// @return the CTI of the type.
362size_t
363get_canonical_type_index(const type_base_sptr& t)
364{return get_canonical_type_index(t.get());}
365
366/// Test if a type originates from a corpus.
367///
368/// Note that this function supports testing if a type originates from
369/// a corpus group.
370///
371/// @param t the type to consider.
372///
373/// @param c the corpus or corpus group to consider.
374///
375/// @return true iff the type @p t originates from the corpus (or
376/// group) @p c.
377bool
378type_originates_from_corpus(type_base_sptr t, corpus_sptr& c)
379{
380 bool result = false;
381 if (c && t->get_corpus())
382 {
383 corpus_group_sptr g = is_corpus_group(c);
384 if (g)
385 {
386 if (t->get_corpus()->get_group() == g.get())
387 result = true;
388 }
389 else
390 {
391 if (t->get_corpus() == c.get())
392 result = true;
393 }
394 }
395 return result;
396}
397/// @brief the location of a token represented in its simplest form.
398/// Instances of this type are to be stored in a sorted vector, so the
399/// type must have proper relational operators.
400class expanded_location
401{
402 string path_;
403 unsigned line_;
404 unsigned column_;
405
406 expanded_location();
407
408public:
409
410 friend class location_manager;
411
412 expanded_location(const string& path, unsigned line, unsigned column)
413 : path_(path), line_(line), column_(column)
414 {}
415
416 bool
417 operator==(const expanded_location& l) const
418 {
419 return (path_ == l.path_
420 && line_ == l.line_
421 && column_ && l.column_);
422 }
423
424 bool
425 operator<(const expanded_location& l) const
426 {
427 if (path_ < l.path_)
428 return true;
429 else if (path_ > l.path_)
430 return false;
431
432 if (line_ < l.line_)
433 return true;
434 else if (line_ > l.line_)
435 return false;
436
437 return column_ < l.column_;
438 }
439};
440
441/// Expand the location into a tripplet path, line and column number.
442///
443/// @param path the output parameter where this function sets the
444/// expanded path.
445///
446/// @param line the output parameter where this function sets the
447/// expanded line.
448///
449/// @param column the ouptut parameter where this function sets the
450/// expanded column.
451void
452location::expand(std::string& path, unsigned& line, unsigned& column) const
453{
454 if (!get_location_manager())
455 {
456 // We don't have a location manager maybe because this location
457 // was just freshly instanciated. We still want to be able to
458 // expand to default values.
459 path = "";
460 line = 0;
461 column = 0;
462 return;
463 }
464 get_location_manager()->expand_location(*this, path, line, column);
465}
466
467
468/// Expand the location into a string.
469///
470/// @return the string representing the location.
471string
473{
474 string path, result;
475 unsigned line = 0, column = 0;
476 expand(path, line, column);
477
478 std::ostringstream o;
479 o << path << ":" << line << ":" << column;
480 return o.str();
481}
482
483struct location_manager::priv
484{
485 /// This sorted vector contains the expanded locations of the tokens
486 /// coming from a given ABI Corpus. The index of a given expanded
487 /// location in the table gives us an integer that is used to build
488 /// instance of location types.
489 std::vector<expanded_location> locs;
490};
491
492location_manager::location_manager()
493 : priv_(new location_manager::priv)
494{}
495
496location_manager::~location_manager() = default;
497
498/// Insert the triplet representing a source locus into our internal
499/// vector of location triplet. Return an instance of location type,
500/// built from an real type that represents the index of the
501/// source locus triplet into our source locus table.
502///
503/// @param file_path the file path of the source locus
504/// @param line the line number of the source location
505/// @param col the column number of the source location
506location
507location_manager::create_new_location(const std::string& file_path,
508 size_t line,
509 size_t col)
510{
511 expanded_location l(file_path, line, col);
512
513 // Just append the new expanded location to the end of the vector
514 // and return its index. Note that indexes start at 1.
515 priv_->locs.push_back(l);
516 return location(priv_->locs.size(), this);
517}
518
519/// Given an instance of location type, return the triplet
520/// {path,line,column} that represents the source locus. Note that
521/// the location must have been previously created from the function
522/// location_manager::create_new_location, otherwise this function yields
523/// unexpected results, including possibly a crash.
524///
525/// @param location the instance of location type to expand
526/// @param path the resulting path of the source locus
527/// @param line the resulting line of the source locus
528/// @param column the resulting colum of the source locus
529void
531 std::string& path,
532 unsigned& line,
533 unsigned& column) const
534{
535 if (location.value_ == 0)
536 return;
537 expanded_location &l = priv_->locs[location.value_ - 1];
538 path = l.path_;
539 line = l.line_;
540 column = l.column_;
541}
542
543typedef unordered_map<function_type_sptr,
544 bool,
546 type_shared_ptr_equal> fn_type_ptr_map;
547
548// <type_maps stuff>
549
550struct type_maps::priv
551{
552 mutable istring_type_base_wptrs_map_type basic_types_;
553 mutable istring_type_base_wptrs_map_type class_types_;
554 mutable istring_type_base_wptrs_map_type union_types_;
555 mutable istring_type_base_wptrs_map_type enum_types_;
556 mutable istring_type_base_wptrs_map_type typedef_types_;
557 mutable istring_type_base_wptrs_map_type qualified_types_;
558 mutable istring_type_base_wptrs_map_type pointer_types_;
559 mutable istring_type_base_wptrs_map_type ptr_to_mbr_types_;
560 mutable istring_type_base_wptrs_map_type reference_types_;
561 mutable istring_type_base_wptrs_map_type array_types_;
562 mutable istring_type_base_wptrs_map_type subrange_types_;
563 mutable istring_type_base_wptrs_map_type function_types_;
564 mutable vector<type_base_wptr> sorted_types_;
565}; // end struct type_maps::priv
566
567type_maps::type_maps()
568 : priv_(new priv)
569{}
570
571type_maps::~type_maps() = default;
572
573/// Test if the type_maps is empty.
574///
575/// @return true iff the type_maps is empty.
576bool
578{
579 return (basic_types().empty()
580 && class_types().empty()
581 && union_types().empty()
582 && enum_types().empty()
583 && typedef_types().empty()
585 && pointer_types().empty()
587 && array_types().empty()
588 && subrange_types().empty()
589 && function_types().empty());
590}
591
592/// Getter for the map that associates the name of a basic type to the
593/// vector instances of type_decl_sptr that represents that type.
596{return priv_->basic_types_;}
597
598/// Getter for the map that associates the name of a basic type to the
599/// vector of instances of @ref type_decl_sptr that represents that
600/// type.
603{return priv_->basic_types_;}
604
605/// Getter for the map that associates the name of a class type to the
606/// vector of instances of @ref class_decl_sptr that represents that
607/// type.
610{return priv_->class_types_;}
611
612/// Getter for the map that associates the name of a class type to the
613/// vector of instances of @ref class_decl_sptr that represents that
614/// type.
617{return priv_->class_types_;}
618
619/// Getter for the map that associates the name of a union type to the
620/// vector of instances of @ref union_decl_sptr that represents that
621/// type.
624{return priv_->union_types_;}
625
626/// Getter for the map that associates the name of a union type to the
627/// vector of instances of @ref union_decl_sptr that represents that
628/// type.
631{return priv_->union_types_;}
632
633/// Getter for the map that associates the name of an enum type to the
634/// vector of instances of @ref enum_type_decl_sptr that represents
635/// that type.
638{return priv_->enum_types_;}
639
640/// Getter for the map that associates the name of an enum type to the
641/// vector of instances of @ref enum_type_decl_sptr that represents
642/// that type.
645{return priv_->enum_types_;}
646
647/// Getter for the map that associates the name of a typedef to the
648/// vector of instances of @ref typedef_decl_sptr that represents tha
649/// type.
652{return priv_->typedef_types_;}
653
654/// Getter for the map that associates the name of a typedef to the
655/// vector of instances of @ref typedef_decl_sptr that represents tha
656/// type.
659{return priv_->typedef_types_;}
660
661/// Getter for the map that associates the name of a qualified type to
662/// the vector of instances of @ref qualified_type_def_sptr.
665{return priv_->qualified_types_;}
666
667/// Getter for the map that associates the name of a qualified type to
668/// the vector of instances of @ref qualified_type_def_sptr.
671{return priv_->qualified_types_;}
672
673/// Getter for the map that associates the name of a pointer type to
674/// the vector of instances of @ref pointer_type_def_sptr that
675/// represents that type.
678{return priv_->pointer_types_;}
679
680/// Getter for the map that associates the name of a pointer-to-member
681/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
682/// represents that type.
685{return priv_->ptr_to_mbr_types_;}
686
687/// Getter for the map that associates the name of a pointer-to-member
688/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
689/// represents that type.
692{return priv_->ptr_to_mbr_types_;}
693
694/// Getter for the map that associates the name of a pointer type to
695/// the vector of instances of @ref pointer_type_def_sptr that
696/// represents that type.
699{return priv_->pointer_types_;}
700
701/// Getter for the map that associates the name of a reference type to
702/// the vector of instances of @ref reference_type_def_sptr that
703/// represents that type.
706{return priv_->reference_types_;}
707
708/// Getter for the map that associates the name of a reference type to
709/// the vector of instances of @ref reference_type_def_sptr that
710/// represents that type.
713{return priv_->reference_types_;}
714
715/// Getter for the map that associates the name of an array type to
716/// the vector of instances of @ref array_type_def_sptr that
717/// represents that type.
720{return priv_->array_types_;}
721
722/// Getter for the map that associates the name of an array type to
723/// the vector of instances of @ref array_type_def_sptr that
724/// represents that type.
727{return priv_->array_types_;}
728
729/// Getter for the map that associates the name of a subrange type to
730/// the vector of instances of @ref array_type_def::subrange_sptr that
731/// represents that type.
734{return priv_->subrange_types_;}
735
736/// Getter for the map that associates the name of a subrange type to
737/// the vector of instances of @ref array_type_def::subrange_sptr that
738/// represents that type.
741{return priv_->subrange_types_;}
742
743/// Getter for the map that associates the name of a function type to
744/// the vector of instances of @ref function_type_sptr that represents
745/// that type.
748{return priv_->function_types_;}
749
750/// Getter for the map that associates the name of a function type to
751/// the vector of instances of @ref function_type_sptr that represents
752/// that type.
755{return priv_->function_types_;}
756
757/// A comparison functor to compare/sort types based on their pretty
758/// representations.
759struct type_name_comp
760{
761 /// Comparison operator for two instances of @ref type_base.
762 ///
763 /// This compares the two types by lexicographically comparing their
764 /// pretty representation.
765 ///
766 /// @param l the left-most type to compare.
767 ///
768 /// @param r the right-most type to compare.
769 ///
770 /// @return true iff @p l < @p r.
771 bool
772 operator()(type_base *l, type_base *r) const
773 {
774 if (l == 0 && r == 0)
775 return false;
776
777 string l_repr = get_pretty_representation(l);
778 string r_repr = get_pretty_representation(r);
779 return l_repr < r_repr;
780 }
781
782 /// Comparison operator for two instances of @ref type_base.
783 ///
784 /// This compares the two types by lexicographically comparing their
785 /// pretty representation.
786 ///
787 /// @param l the left-most type to compare.
788 ///
789 /// @param r the right-most type to compare.
790 ///
791 /// @return true iff @p l < @p r.
792 bool
793 operator()(const type_base_sptr &l, const type_base_sptr &r) const
794 {return operator()(l.get(), r.get());}
795
796 /// Comparison operator for two instances of @ref type_base.
797 ///
798 /// This compares the two types by lexicographically comparing their
799 /// pretty representation.
800 ///
801 /// @param l the left-most type to compare.
802 ///
803 /// @param r the right-most type to compare.
804 ///
805 /// @return true iff @p l < @p r.
806 bool
807 operator()(const type_base_wptr &l, const type_base_wptr &r) const
808 {return operator()(type_base_sptr(l), type_base_sptr(r));}
809}; // end struct type_name_comp
810
811#ifdef WITH_DEBUG_SELF_COMPARISON
812
813/// This is a function called when the ABG_RETURN* macros defined
814/// below return false.
815///
816/// The purpose of this function is to ease debugging. To know where
817/// the equality functions first compare non-equal, we can just set a
818/// breakpoint on this notify_equality_failed function and run the
819/// equality functions. Because all the equality functions use the
820/// ABG_RETURN* macros to return their values, this function is always
821/// called when any of those equality function return false.
822///
823/// @param l the first operand of the equality.
824///
825/// @param r the second operand of the equality.
826static void
827notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
828 const type_or_decl_base &r __attribute__((unused)))
829{}
830
831/// This is a function called when the ABG_RETURN* macros defined
832/// below return false.
833///
834/// The purpose of this function is to ease debugging. To know where
835/// the equality functions first compare non-equal, we can just set a
836/// breakpoint on this notify_equality_failed function and run the
837/// equality functions. Because all the equality functions use the
838/// ABG_RETURN* macros to return their values, this function is always
839/// called when any of those equality function return false.
840///
841/// @param l the first operand of the equality.
842///
843/// @param r the second operand of the equality.
844static void
845notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
846 const type_or_decl_base *r __attribute__((unused)))
847{}
848
849#define ABG_RETURN_EQUAL(l, r) \
850 do \
851 { \
852 if (l != r) \
853 notify_equality_failed(l, r); \
854 return (l == r); \
855 } \
856 while(false)
857
858
859#define ABG_RETURN_FALSE \
860 do \
861 { \
862 notify_equality_failed(l, r); \
863 return false; \
864 } while(false)
865
866#define ABG_RETURN(value) \
867 do \
868 { \
869 if (value == false) \
870 notify_equality_failed(l, r); \
871 return value; \
872 } while (false)
873
874#else // WITH_DEBUG_SELF_COMPARISON
875
876#define ABG_RETURN_FALSE return false
877#define ABG_RETURN(value) return (value)
878#define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
879#endif
880
881/// Get the canonical type of a given type T* as a T*.
882///
883/// Note that normally, canonical types are returned as @ref
884/// type_base* (un-typed form, kind of). This function returns the
885/// canonical type as a T*, just like the T* it is looking at.
886///
887///
888/// @param t the type to consider.
889///
890/// @return either the canonical type of @p t or @p t itself if it
891/// doesn't have any canonical type.
892template<typename T>
893T*
895{
896 if (!t)
897 return nullptr;
898 if (type_base* type = t->get_naked_canonical_type())
899 return dynamic_cast<T*>(type);
900 return t;
901}
902
903/// Compare two types by comparing their canonical types if present.
904///
905/// If the canonical types are not present (because the types have not
906/// yet been canonicalized, for instance) then the types are compared
907/// structurally.
908///
909/// @param l the first type to take into account in the comparison.
910///
911/// @param r the second type to take into account in the comparison.
912template<typename T>
913bool
914try_canonical_compare(const T *l, const T *r)
915{
916#if WITH_DEBUG_TYPE_CANONICALIZATION
917 // We are debugging the canonicalization of a type down the stack.
918 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
919 // type being canonicalized. We are at a point where we can compare
920 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
921 // have canonical types) or structural comparison.
922 //
923 // Because we are debugging the process of type canonicalization, we
924 // want to compare 'l' and 'r' canonically *AND* structurally. Both
925 // kinds of comparison should yield the same result, otherwise type
926 // canonicalization just failed for the subtype 'r' of the type
927 // being canonicalized.
928 //
929 // In concrete terms, this function is going to be called twice with
930 // the same pair {'l', 'r'} to compare: The first time with
931 // environment::priv_->use_canonical_type_comparison_ set to true,
932 // instructing us to compare them canonically, and the second time
933 // with that boolean set to false, instructing us to compare them
934 // structurally.
935 const environment&env = l->get_environment();
936 if (env.priv_->use_canonical_type_comparison_)
937 {
938 if (const type_base *lc = l->get_naked_canonical_type())
939 if (const type_base *rc = r->get_naked_canonical_type())
940 ABG_RETURN_EQUAL(lc, rc);
941 }
942
943 // If the two types have a non-empty hash value, then consider those
944 // hash values. If the hashes are different then the two types are
945 // different. If the hashes are equal then we'll compare then
946 // structurally.
947 if (hash_t l_hash = peek_hash_value(*l))
948 if (hash_t r_hash = peek_hash_value(*r))
949 if (l_hash != r_hash)
951
952 // If a type has a canonical type, use its canonical type, always.
955
956 return equals(*l, *r, 0);
957#else
958 if (const type_base *lc = l->get_naked_canonical_type())
959 if (const type_base *rc = r->get_naked_canonical_type())
960 ABG_RETURN_EQUAL(lc, rc);
961
962 // If the two types have a non-empty hash value, then consider those
963 // hash values. If the hashes are different then the two types are
964 // different. If the hashes are equal then we'll compare then
965 // structurally.
966 if (hash_t l_hash = peek_hash_value(*l))
967 if (hash_t r_hash = peek_hash_value(*r))
968 if (l_hash != r_hash)
970
971 // If a type has a canonical type, use its canonical type, always.
974
975 return equals(*l, *r, 0);
976#endif
977}
978
979/// Detect if a recursive comparison cycle is detected while
980/// structurally comparing two types (a.k.a member-wise comparison).
981///
982/// @param l the left-hand-side operand of the current comparison.
983///
984/// @param r the right-hand-side operand of the current comparison.
985///
986/// @return true iff a comparison cycle is detected.
987template<typename T>
988bool
990{
991 bool result = l.priv_->comparison_started(l, r);
992 return result ;
993}
994
995/// Detect if a recursive comparison cycle is detected while
996/// structurally comparing two @ref class_decl types.
997///
998/// @param l the left-hand-side operand of the current comparison.
999///
1000/// @param r the right-hand-side operand of the current comparison.
1001///
1002/// @return true iff a comparison cycle is detected.
1003template<>
1004bool
1006{
1007 return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
1008 static_cast<const class_or_union&>(r));
1009}
1010
1011/// This macro is to be used while comparing composite types that
1012/// might recursively refer to themselves. Comparing two such types
1013/// might get us into a cyle.
1014///
1015/// Practically, if we detect that we are already into comparing 'l'
1016/// and 'r'; then, this is a cycle.
1017//
1018/// To break the cycle, we assume the result of the comparison is true
1019/// for now. Comparing the other sub-types of l & r will tell us later
1020/// if l & r are actually different or not.
1021///
1022/// In the mean time, returning true from this macro should not be
1023/// used to propagate the canonical type of 'l' onto 'r' as we don't
1024/// know yet if l equals r. All the types that depend on l and r
1025/// can't (and that are in the comparison stack currently) can't have
1026/// their canonical type propagated either. So this macro disallows
1027/// canonical type propagation for those types that depend on a
1028/// recursively defined sub-type for now.
1029///
1030/// @param l the left-hand-side operand of the comparison.
1031#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
1032 do \
1033 { \
1034 if (is_comparison_cycle_detected(l, r)) \
1035 return true; \
1036 } \
1037 while(false)
1038
1039
1040/// Mark a pair of types as being compared.
1041///
1042/// This is helpful to later detect recursive cycles in the comparison
1043/// stack.
1044///
1045/// @param l the left-hand-side operand of the comparison.
1046///
1047/// @parm r the right-hand-side operand of the comparison.
1048template<typename T>
1049void
1051{
1052 l.priv_->mark_as_being_compared(l, r);
1054}
1055
1056/// Mark a pair of @ref class_decl types as being compared.
1057///
1058/// This is helpful to later detect recursive cycles in the comparison
1059/// stack.
1060///
1061/// @param l the left-hand-side operand of the comparison.
1062///
1063/// @parm r the right-hand-side operand of the comparison.
1064template<>
1065void
1067{
1068 return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
1069 static_cast<const class_or_union&>(r));
1070}
1071
1072/// Mark a pair of types as being not compared anymore.
1073///
1074/// This is helpful to later detect recursive cycles in the comparison
1075/// stack.
1076///
1077/// Note that the types must have been passed to
1078/// mark_types_as_being_compared prior to calling this function.
1079///
1080/// @param l the left-hand-side operand of the comparison.
1081///
1082/// @parm r the right-hand-side operand of the comparison.
1083template<typename T>
1084void
1086{
1087 l.priv_->unmark_as_being_compared(l, r);
1089}
1090
1091/// Mark a pair of @ref class_decl types as being not compared
1092/// anymore.
1093///
1094/// This is helpful to later detect recursive cycles in the comparison
1095/// stack.
1096///
1097/// Note that the types must have been passed to
1098/// mark_types_as_being_compared prior to calling this function.
1099///
1100/// @param l the left-hand-side operand of the comparison.
1101///
1102/// @parm r the right-hand-side operand of the comparison.
1103template<>
1104void
1106{
1107 return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
1108 static_cast<const class_or_union&>(r));
1109}
1110
1111/// Return the result of the comparison of two (sub) types.
1112///
1113/// The function does the necessary book keeping before returning the
1114/// result of the comparison of two (sub) types.
1115///
1116/// The book-keeping done is essentially about type comparison cycle detection.
1117///
1118/// @param l the left-hand-side operand of the type comparison
1119///
1120/// @param r the right-hand-side operand of the type comparison
1121///
1122/// @param value the result of the comparison of @p l and @p r.
1123///
1124/// @return the value @p value.
1125template<typename T>
1126bool
1127return_comparison_result(T& l, T& r, bool value)
1128{
1130 ABG_RETURN(value);
1131}
1132
1133#define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1134 do \
1135 { \
1136 bool res = return_comparison_result(l, r, value); \
1137 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1138 return res; \
1139 } while (false)
1140
1141/// Cache the result of a comparison between too artifacts (l & r) and
1142/// return immediately.
1143///
1144/// @param value the value to cache.
1145#define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1146 do \
1147 { \
1148 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1149 return value; \
1150 } while (false)
1151
1152/// Getter of all types types sorted by their pretty representation.
1153///
1154/// @return a sorted vector of all types sorted by their pretty
1155/// representation.
1156const vector<type_base_wptr>&
1158{
1159 if (priv_->sorted_types_.empty())
1160 {
1161 istring_type_base_wptrs_map_type::const_iterator i;
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
1485
1486/// Ensure that the life time of a function type is bound to the life
1487/// time of the current translation unit.
1488///
1489/// @param ftype the function time which life time to bind to the life
1490/// time of the current instance of @ref translation_unit. That is,
1491/// it's onlyh when the translation unit is destroyed that the
1492/// function type can be destroyed to.
1493void
1495{
1496 const environment& env = get_environment();
1497
1498 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1499
1500 interned_string repr = get_type_name(ftype);
1501 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1502 push_back(ftype);
1503
1504 // The function type must be out of the same environment as its
1505 // translation unit.
1506 {
1507 const environment& e = ftype->get_environment();
1508 ABG_ASSERT(&env == &e);
1509 }
1510
1511 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1512 ABG_ASSERT(existing_tu == this);
1513 else
1514 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1515
1517}
1518
1519/// This implements the ir_traversable_base::traverse virtual
1520/// function.
1521///
1522/// @param v the visitor used on the member nodes of the translation
1523/// unit during the traversal.
1524///
1525/// @return true if the entire type IR tree got traversed, false
1526/// otherwise.
1527bool
1530
1531translation_unit::~translation_unit()
1532{}
1533
1534/// Converts a translation_unit::language enumerator into a string.
1535///
1536/// @param l the language enumerator to translate.
1537///
1538/// @return the resulting string.
1539string
1541{
1542 switch (l)
1543 {
1544 case translation_unit::LANG_UNKNOWN:
1545 return "LANG_UNKNOWN";
1546 case translation_unit::LANG_Cobol74:
1547 return "LANG_Cobol74";
1548 case translation_unit::LANG_Cobol85:
1549 return "LANG_Cobol85";
1550 case translation_unit::LANG_C89:
1551 return "LANG_C89";
1552 case translation_unit::LANG_C99:
1553 return "LANG_C99";
1554 case translation_unit::LANG_C11:
1555 return "LANG_C11";
1556 case translation_unit::LANG_C:
1557 return "LANG_C";
1558 case translation_unit::LANG_C_plus_plus_11:
1559 return "LANG_C_plus_plus_11";
1560 case translation_unit::LANG_C_plus_plus_14:
1561 return "LANG_C_plus_plus_14";
1562 case translation_unit::LANG_C_plus_plus:
1563 return "LANG_C_plus_plus";
1564 case translation_unit::LANG_ObjC:
1565 return "LANG_ObjC";
1566 case translation_unit::LANG_ObjC_plus_plus:
1567 return "LANG_ObjC_plus_plus";
1568 case translation_unit::LANG_Fortran77:
1569 return "LANG_Fortran77";
1570 case translation_unit::LANG_Fortran90:
1571 return "LANG_Fortran90";
1572 case translation_unit::LANG_Fortran95:
1573 return "LANG_Fortran95";
1574 case translation_unit::LANG_Ada83:
1575 return "LANG_Ada83";
1576 case translation_unit::LANG_Ada95:
1577 return "LANG_Ada95";
1578 case translation_unit::LANG_Pascal83:
1579 return "LANG_Pascal83";
1580 case translation_unit::LANG_Modula2:
1581 return "LANG_Modula2";
1582 case translation_unit::LANG_Java:
1583 return "LANG_Java";
1584 case translation_unit::LANG_PLI:
1585 return "LANG_PLI";
1586 case translation_unit::LANG_UPC:
1587 return "LANG_UPC";
1588 case translation_unit::LANG_D:
1589 return "LANG_D";
1590 case translation_unit::LANG_Python:
1591 return "LANG_Python";
1592 case translation_unit::LANG_Go:
1593 return "LANG_Go";
1594 case translation_unit::LANG_Mips_Assembler:
1595 return "LANG_Mips_Assembler";
1596 default:
1597 return "LANG_UNKNOWN";
1598 }
1599
1600 return "LANG_UNKNOWN";
1601}
1602
1603/// Parse a string representing a language into a
1604/// translation_unit::language enumerator into a string.
1605///
1606/// @param l the string representing the language.
1607///
1608/// @return the resulting translation_unit::language enumerator.
1611{
1612 if (l == "LANG_Cobol74")
1613 return translation_unit::LANG_Cobol74;
1614 else if (l == "LANG_Cobol85")
1615 return translation_unit::LANG_Cobol85;
1616 else if (l == "LANG_C89")
1617 return translation_unit::LANG_C89;
1618 else if (l == "LANG_C99")
1619 return translation_unit::LANG_C99;
1620 else if (l == "LANG_C11")
1621 return translation_unit::LANG_C11;
1622 else if (l == "LANG_C")
1623 return translation_unit::LANG_C;
1624 else if (l == "LANG_C_plus_plus_11")
1625 return translation_unit::LANG_C_plus_plus_11;
1626 else if (l == "LANG_C_plus_plus_14")
1627 return translation_unit::LANG_C_plus_plus_14;
1628 else if (l == "LANG_C_plus_plus")
1629 return translation_unit::LANG_C_plus_plus;
1630 else if (l == "LANG_ObjC")
1631 return translation_unit::LANG_ObjC;
1632 else if (l == "LANG_ObjC_plus_plus")
1633 return translation_unit::LANG_ObjC_plus_plus;
1634 else if (l == "LANG_Fortran77")
1635 return translation_unit::LANG_Fortran77;
1636 else if (l == "LANG_Fortran90")
1637 return translation_unit::LANG_Fortran90;
1638 else if (l == "LANG_Fortran95")
1639 return translation_unit::LANG_Fortran95;
1640 else if (l == "LANG_Ada83")
1641 return translation_unit::LANG_Ada83;
1642 else if (l == "LANG_Ada95")
1643 return translation_unit::LANG_Ada95;
1644 else if (l == "LANG_Pascal83")
1645 return translation_unit::LANG_Pascal83;
1646 else if (l == "LANG_Modula2")
1647 return translation_unit::LANG_Modula2;
1648 else if (l == "LANG_Java")
1649 return translation_unit::LANG_Java;
1650 else if (l == "LANG_PLI")
1651 return translation_unit::LANG_PLI;
1652 else if (l == "LANG_UPC")
1653 return translation_unit::LANG_UPC;
1654 else if (l == "LANG_D")
1655 return translation_unit::LANG_D;
1656 else if (l == "LANG_Python")
1657 return translation_unit::LANG_Python;
1658 else if (l == "LANG_Go")
1659 return translation_unit::LANG_Go;
1660 else if (l == "LANG_Mips_Assembler")
1661 return translation_unit::LANG_Mips_Assembler;
1662
1663 return translation_unit::LANG_UNKNOWN;
1664}
1665
1666/// Test if a language enumerator designates the C language.
1667///
1668/// @param l the language enumerator to consider.
1669///
1670/// @return true iff @p l designates the C language.
1671bool
1673{
1674 return (l == translation_unit::LANG_C89
1675 || l == translation_unit::LANG_C99
1676 || l == translation_unit::LANG_C11
1677 || l == translation_unit::LANG_C);
1678}
1679
1680/// Test if a language enumerator designates the C++ language.
1681///
1682/// @param l the language enumerator to consider.
1683///
1684/// @return true iff @p l designates the C++ language.
1685bool
1687{
1688 return (l == translation_unit::LANG_C_plus_plus_03
1689 || l == translation_unit::LANG_C_plus_plus_11
1690 || l == translation_unit::LANG_C_plus_plus_14
1691 || l == translation_unit::LANG_C_plus_plus);
1692}
1693
1694/// Test if a language enumerator designates the Java language.
1695///
1696/// @param l the language enumerator to consider.
1697///
1698/// @return true iff @p l designates the Java language.
1699bool
1701{return l == translation_unit::LANG_Java;}
1702
1703/// Test if a language enumerator designates the Ada language.
1704///
1705/// @param l the language enumerator to consider.
1706///
1707/// @return true iff @p l designates the Ada language.
1708bool
1710{
1711 return (l == translation_unit::LANG_Ada83
1712 || l == translation_unit::LANG_Ada95);
1713}
1714
1715/// A deep comparison operator for pointers to translation units.
1716///
1717/// @param l the first translation unit to consider for the comparison.
1718///
1719/// @param r the second translation unit to consider for the comparison.
1720///
1721/// @return true if the two translation units are equal, false otherwise.
1722bool
1724{
1725 if (l.get() == r.get())
1726 return true;
1727
1728 if (!!l != !!r)
1729 return false;
1730
1731 return *l == *r;
1732}
1733
1734/// A deep inequality operator for pointers to translation units.
1735///
1736/// @param l the first translation unit to consider for the comparison.
1737///
1738/// @param r the second translation unit to consider for the comparison.
1739///
1740/// @return true iff the two translation units are different.
1741bool
1743{return !operator==(l, r);}
1744
1745// </translation_unit stuff>
1746
1747// <elf_symbol stuff>
1748struct elf_symbol::priv
1749{
1750 const environment& env_;
1751 size_t index_;
1752 size_t size_;
1753 string name_;
1754 elf_symbol::type type_;
1755 elf_symbol::binding binding_;
1756 elf_symbol::version version_;
1757 elf_symbol::visibility visibility_;
1758 bool is_defined_;
1759 // This flag below says if the symbol is a common elf symbol. In
1760 // relocatable files, a common symbol is a symbol defined in a
1761 // section of kind SHN_COMMON.
1762 //
1763 // Note that a symbol of kind STT_COMMON is also considered a common
1764 // symbol. Here is what the gABI says about STT_COMMON and
1765 // SHN_COMMON:
1766 //
1767 // Symbols with type STT_COMMON label uninitialized common
1768 // blocks. In relocatable objects, these symbols are not
1769 // allocated and must have the special section index SHN_COMMON
1770 // (see below). In shared objects and executables these symbols
1771 // must be allocated to some section in the defining object.
1772 //
1773 // In relocatable objects, symbols with type STT_COMMON are
1774 // treated just as other symbols with index SHN_COMMON. If the
1775 // link-editor allocates space for the SHN_COMMON symbol in an
1776 // output section of the object it is producing, it must
1777 // preserve the type of the output symbol as STT_COMMON.
1778 //
1779 // When the dynamic linker encounters a reference to a symbol
1780 // that resolves to a definition of type STT_COMMON, it may (but
1781 // is not required to) change its symbol resolution rules as
1782 // follows: instead of binding the reference to the first symbol
1783 // found with the given name, the dynamic linker searches for
1784 // the first symbol with that name with type other than
1785 // STT_COMMON. If no such symbol is found, it looks for the
1786 // STT_COMMON definition of that name that has the largest size.
1787 bool is_common_;
1788 bool is_in_ksymtab_;
1791 bool is_suppressed_;
1792 elf_symbol_wptr main_symbol_;
1793 elf_symbol_wptr next_alias_;
1794 elf_symbol_wptr next_common_instance_;
1795 string id_string_;
1796
1797 priv(const environment& e)
1798 : env_(e),
1799 index_(),
1800 size_(),
1801 type_(elf_symbol::NOTYPE_TYPE),
1802 binding_(elf_symbol::GLOBAL_BINDING),
1803 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1804 is_defined_(false),
1805 is_common_(false),
1806 is_in_ksymtab_(false),
1807 crc_(),
1808 namespace_(),
1809 is_suppressed_(false)
1810 {}
1811
1812 priv(const environment& e,
1813 size_t i,
1814 size_t s,
1815 const string& n,
1818 bool d,
1819 bool c,
1820 const elf_symbol::version& ve,
1822 bool is_in_ksymtab,
1825 bool is_suppressed)
1826 : env_(e),
1827 index_(i),
1828 size_(s),
1829 name_(n),
1830 type_(t),
1831 binding_(b),
1832 version_(ve),
1833 visibility_(vi),
1834 is_defined_(d),
1835 is_common_(c),
1836 is_in_ksymtab_(is_in_ksymtab),
1837 crc_(crc),
1838 namespace_(ns),
1839 is_suppressed_(is_suppressed)
1840 {
1841 if (!is_common_)
1842 is_common_ = type_ == COMMON_TYPE;
1843 }
1844}; // end struct elf_symbol::priv
1845
1846/// Constructor of the @ref elf_symbol type.
1847///
1848/// Note that this constructor is private, so client code cannot use
1849/// it to create instances of @ref elf_symbol. Rather, client code
1850/// should use the @ref elf_symbol::create() function to create
1851/// instances of @ref elf_symbol instead.
1852///
1853/// @param e the environment we are operating from.
1854///
1855/// @param i the index of the symbol in the (ELF) symbol table.
1856///
1857/// @param s the size of the symbol.
1858///
1859/// @param n the name of the symbol.
1860///
1861/// @param t the type of the symbol.
1862///
1863/// @param b the binding of the symbol.
1864///
1865/// @param d true if the symbol is defined, false otherwise.
1866///
1867/// @param c true if the symbol is a common symbol, false otherwise.
1868///
1869/// @param ve the version of the symbol.
1870///
1871/// @param vi the visibility of the symbol.
1872///
1873/// @param crc the CRC (modversions) value of Linux Kernel symbols
1874///
1875/// @param ns the namespace of Linux Kernel symbols, if any
1876elf_symbol::elf_symbol(const environment& e,
1877 size_t i,
1878 size_t s,
1879 const string& n,
1880 type t,
1881 binding b,
1882 bool d,
1883 bool c,
1884 const version& ve,
1885 visibility vi,
1886 bool is_in_ksymtab,
1889 bool is_suppressed)
1890 : priv_(new priv(e,
1891 i,
1892 s,
1893 n,
1894 t,
1895 b,
1896 d,
1897 c,
1898 ve,
1899 vi,
1900 is_in_ksymtab,
1901 crc,
1902 ns,
1903 is_suppressed))
1904{}
1905
1906/// Factory of instances of @ref elf_symbol.
1907///
1908/// This is the function to use to create instances of @ref elf_symbol.
1909///
1910/// @param e the environment we are operating from.
1911///
1912/// @param i the index of the symbol in the (ELF) symbol table.
1913///
1914/// @param s the size of the symbol.
1915///
1916/// @param n the name of the symbol.
1917///
1918/// @param t the type of the symbol.
1919///
1920/// @param b the binding of the symbol.
1921///
1922/// @param d true if the symbol is defined, false otherwise.
1923///
1924/// @param c true if the symbol is a common symbol.
1925///
1926/// @param ve the version of the symbol.
1927///
1928/// @param vi the visibility of the symbol.
1929///
1930/// @param crc the CRC (modversions) value of Linux Kernel symbols
1931///
1932/// @param ns the namespace of Linux Kernel symbols, if any
1933///
1934/// @return a (smart) pointer to a newly created instance of @ref
1935/// elf_symbol.
1938 size_t i,
1939 size_t s,
1940 const string& n,
1941 type t,
1942 binding b,
1943 bool d,
1944 bool c,
1945 const version& ve,
1946 visibility vi,
1947 bool is_in_ksymtab,
1950 bool is_suppressed)
1951{
1952 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
1953 is_in_ksymtab, crc, ns, is_suppressed));
1954 sym->priv_->main_symbol_ = sym;
1955 return sym;
1956}
1957
1958/// Test textual equality between two symbols.
1959///
1960/// Textual equality means that the aliases of the compared symbols
1961/// are not taken into account. Only the name, type, and version of
1962/// the symbols are compared.
1963///
1964/// @return true iff the two symbols are textually equal.
1965static bool
1966textually_equals(const elf_symbol&l,
1967 const elf_symbol&r)
1968{
1969 bool equals = (l.get_name() == r.get_name()
1970 && l.get_type() == r.get_type()
1971 && l.is_public() == r.is_public()
1972 && l.is_defined() == r.is_defined()
1974 && l.get_version() == r.get_version()
1975 && l.get_crc() == r.get_crc()
1976 && l.get_namespace() == r.get_namespace());
1977
1978 if (equals && l.is_variable())
1979 // These are variable symbols. Let's compare their symbol size.
1980 // The symbol size in this case is the size taken by the storage
1981 // of the variable. If that size changes, then it's an ABI
1982 // change.
1983 equals = l.get_size() == r.get_size();
1984
1985 return equals;
1986}
1987
1988/// Getter of the environment used by the current instance of @ref
1989/// elf_symbol.
1990///
1991/// @return the enviroment used by the current instance of @ref elf_symbol.
1992const environment&
1994{return priv_->env_;}
1995
1996/// Getter for the index
1997///
1998/// @return the index of the symbol.
1999size_t
2001{return priv_->index_;}
2002
2003/// Setter for the index.
2004///
2005/// @param s the new index.
2006void
2008{priv_->index_ = s;}
2009
2010/// Getter for the name of the @ref elf_symbol.
2011///
2012/// @return a reference to the name of the @ref symbol.
2013const string&
2015{return priv_->name_;}
2016
2017/// Setter for the name of the current intance of @ref elf_symbol.
2018///
2019/// @param n the new name.
2020void
2021elf_symbol::set_name(const string& n)
2022{
2023 priv_->name_ = n;
2024 priv_->id_string_.clear();
2025}
2026
2027/// Getter for the type of the current instance of @ref elf_symbol.
2028///
2029/// @return the type of the elf symbol.
2032{return priv_->type_;}
2033
2034/// Setter for the type of the current instance of @ref elf_symbol.
2035///
2036/// @param t the new symbol type.
2037void
2039{priv_->type_ = t;}
2040
2041/// Getter of the size of the symbol.
2042///
2043/// @return the size of the symbol, in bytes.
2044size_t
2046{return priv_->size_;}
2047
2048/// Setter of the size of the symbol.
2049///
2050/// @param size the new size of the symbol, in bytes.
2051void
2053{priv_->size_ = size;}
2054
2055/// Getter for the binding of the current instance of @ref elf_symbol.
2056///
2057/// @return the binding of the symbol.
2060{return priv_->binding_;}
2061
2062/// Setter for the binding of the current instance of @ref elf_symbol.
2063///
2064/// @param b the new binding.
2065void
2067{priv_->binding_ = b;}
2068
2069/// Getter for the version of the current instanc of @ref elf_symbol.
2070///
2071/// @return the version of the elf symbol.
2074{return priv_->version_;}
2075
2076/// Setter for the version of the current instance of @ref elf_symbol.
2077///
2078/// @param v the new version of the elf symbol.
2079void
2081{
2082 priv_->version_ = v;
2083 priv_->id_string_.clear();
2084}
2085
2086/// Setter of the visibility of the current instance of @ref
2087/// elf_symbol.
2088///
2089/// @param v the new visibility of the elf symbol.
2090void
2092{priv_->visibility_ = v;}
2093
2094/// Getter of the visibility of the current instance of @ref
2095/// elf_symbol.
2096///
2097/// @return the visibility of the elf symbol.
2100{return priv_->visibility_;}
2101
2102/// Test if the current instance of @ref elf_symbol is defined or not.
2103///
2104/// @return true if the current instance of @ref elf_symbol is
2105/// defined, false otherwise.
2106bool
2108{return priv_->is_defined_;}
2109
2110/// Sets a flag saying if the current instance of @ref elf_symbol is
2111/// defined
2112///
2113/// @param b the new value of the flag.
2114void
2116{priv_->is_defined_ = d;}
2117
2118/// Test if the current instance of @ref elf_symbol is public or not.
2119///
2120/// This tests if the symbol is defined, has default or protected
2121///visibility, and either:
2122/// - has global binding
2123/// - has weak binding
2124/// - or has a GNU_UNIQUE binding.
2125///
2126/// return true if the current instance of @ref elf_symbol is public,
2127/// false otherwise.
2128bool
2130{
2131 return (is_defined()
2132 && (get_binding() == GLOBAL_BINDING
2133 || get_binding() == WEAK_BINDING
2134 || get_binding() == GNU_UNIQUE_BINDING)
2135 && (get_visibility() == DEFAULT_VISIBILITY
2136 || get_visibility() == PROTECTED_VISIBILITY));
2137}
2138
2139/// Test if the current instance of @ref elf_symbol is a function
2140/// symbol or not.
2141///
2142/// @return true if the current instance of @ref elf_symbol is a
2143/// function symbol, false otherwise.
2144bool
2146{return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2147
2148/// Test if the current instance of @ref elf_symbol is a variable
2149/// symbol or not.
2150///
2151/// @return true if the current instance of @ref elf_symbol is a
2152/// variable symbol, false otherwise.
2153bool
2155{
2156 return (get_type() == OBJECT_TYPE
2157 || get_type() == TLS_TYPE
2158 // It appears that undefined variables have NOTYPE type.
2159 || (get_type() == NOTYPE_TYPE
2160 && !is_defined()));
2161}
2162
2163/// Getter of the 'is-in-ksymtab' property.
2164///
2165/// @return true iff the current symbol is in the Linux Kernel
2166/// specific 'ksymtab' symbol table.
2167bool
2169{return priv_->is_in_ksymtab_;}
2170
2171/// Setter of the 'is-in-ksymtab' property.
2172///
2173/// @param is_in_ksymtab this is true iff the current symbol is in the
2174/// Linux Kernel specific 'ksymtab' symbol table.
2175void
2177{priv_->is_in_ksymtab_ = is_in_ksymtab;}
2178
2179/// Getter of the 'crc' property.
2180///
2181/// @return the CRC (modversions) value for Linux Kernel symbols, if any
2184{return priv_->crc_;}
2185
2186/// Setter of the 'crc' property.
2187///
2188/// @param crc the new CRC (modversions) value for Linux Kernel symbols
2189void
2191{priv_->crc_ = crc;}
2192
2193/// Getter of the 'namespace' property.
2194///
2195/// @return the namespace for Linux Kernel symbols, if any
2198{return priv_->namespace_;}
2199
2200/// Setter of the 'namespace' property.
2201///
2202/// @param ns the new namespace for Linux Kernel symbols, if any
2203void
2205{priv_->namespace_ = ns;}
2206
2207/// Getter for the 'is-suppressed' property.
2208///
2209/// @return true iff the current symbol has been suppressed by a
2210/// suppression specification that was provided in the context that
2211/// led to the creation of the corpus this ELF symbol belongs to.
2212bool
2214{return priv_->is_suppressed_;}
2215
2216/// Setter for the 'is-suppressed' property.
2217///
2218/// @param true iff the current symbol has been suppressed by a
2219/// suppression specification that was provided in the context that
2220/// led to the creation of the corpus this ELF symbol belongs to.
2221void
2223{priv_->is_suppressed_ = is_suppressed;}
2224
2225/// @name Elf symbol aliases
2226///
2227/// An alias A for an elf symbol S is a symbol that is defined at the
2228/// same address as S. S is chained to A through the
2229/// elf_symbol::get_next_alias() method.
2230///
2231/// When there are several aliases to a symbol, the main symbol is the
2232/// the first symbol found in the symbol table for a given address.
2233///
2234/// The alias chain is circular. That means if S is the main symbol
2235/// and A is the alias, S is chained to A and A
2236/// is chained back to the main symbol S. The last alias in an alias
2237///chain is always chained to the main symbol.
2238///
2239/// Thus, when looping over the aliases of an elf_symbol A, detecting
2240/// an alias that is equal to the main symbol should logically be a
2241/// loop exit condition.
2242///
2243/// Accessing and adding aliases for instances of elf_symbol is done
2244/// through the member functions below.
2245
2246/// @{
2247
2248/// Get the main symbol of an alias chain.
2249///
2250///@return the main symbol.
2251const elf_symbol_sptr
2253{return priv_->main_symbol_.lock();}
2254
2255/// Get the main symbol of an alias chain.
2256///
2257///@return the main symbol.
2260{return priv_->main_symbol_.lock();}
2261
2262/// Tests whether this symbol is the main symbol.
2263///
2264/// @return true iff this symbol is the main symbol.
2265bool
2267{return get_main_symbol().get() == this;}
2268
2269/// Get the next alias of the current symbol.
2270///
2271///@return the alias, or NULL if there is no alias.
2274{return priv_->next_alias_.lock();}
2275
2276
2277/// Check if the current elf_symbol has an alias.
2278///
2279///@return true iff the current elf_symbol has an alias.
2280bool
2282{return bool(get_next_alias());}
2283
2284/// Get the number of aliases to this elf symbol
2285///
2286/// @return the number of aliases to this elf symbol.
2287int
2289{
2290 int result = 0;
2291
2293 a && a.get() != get_main_symbol().get();
2294 a = a->get_next_alias())
2295 ++result;
2296
2297 return result;
2298}
2299
2300/// Add an alias to the current elf symbol.
2301///
2302/// @param alias the new alias. Note that this elf_symbol should *NOT*
2303/// have aliases prior to the invocation of this function.
2304void
2306{
2307 if (!alias)
2308 return;
2309
2310 ABG_ASSERT(!alias->has_aliases());
2312
2313 if (has_aliases())
2314 {
2315 elf_symbol_sptr last_alias;
2317 a && !a->is_main_symbol();
2318 a = a->get_next_alias())
2319 {
2320 if (a->get_next_alias()->is_main_symbol())
2321 {
2322 ABG_ASSERT(last_alias == 0);
2323 last_alias = a;
2324 }
2325 }
2326 ABG_ASSERT(last_alias);
2327
2328 last_alias->priv_->next_alias_ = alias;
2329 }
2330 else
2331 priv_->next_alias_ = alias;
2332
2333 alias->priv_->next_alias_ = get_main_symbol();
2334 alias->priv_->main_symbol_ = get_main_symbol();
2335}
2336
2337/// Update the main symbol for a group of aliased symbols
2338///
2339/// If after the construction of the symbols (in order of discovery), the
2340/// actual main symbol can be identified (e.g. as the symbol that actually is
2341/// defined in the code), this method offers a way of updating the main symbol
2342/// through one of the aliased symbols.
2343///
2344/// For that, locate the new main symbol by name and update all references to
2345/// the main symbol among the group of aliased symbols.
2346///
2347/// @param name the name of the main symbol
2348///
2349/// @return the new main elf_symbol
2351elf_symbol::update_main_symbol(const std::string& name)
2352{
2354 if (!has_aliases() || get_name() == name)
2355 return get_main_symbol();
2356
2357 // find the new main symbol
2358 elf_symbol_sptr new_main;
2359 // we've already checked this; check the rest of the aliases
2360 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2361 a = a->get_next_alias())
2362 if (a->get_name() == name)
2363 {
2364 new_main = a;
2365 break;
2366 }
2367
2368 if (!new_main)
2369 return get_main_symbol();
2370
2371 // now update all main symbol references
2372 priv_->main_symbol_ = new_main;
2373 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2374 a = a->get_next_alias())
2375 a->priv_->main_symbol_ = new_main;
2376
2377 return new_main;
2378}
2379
2380/// Return true if the symbol is a common one.
2381///
2382/// @return true iff the symbol is common.
2383bool
2385{return priv_->is_common_;}
2386
2387/// Return true if this common common symbol has other common instances.
2388///
2389/// A common instance of a given common symbol is another common
2390/// symbol with the same name. Those exist in relocatable files. The
2391/// linker normally allocates all the instances into a common block in
2392/// the final output file.
2393///
2394/// Note that the current object must be a common symbol, otherwise,
2395/// this function aborts.
2396///
2397/// @return true iff the current common symbol has other common
2398/// instances.
2399bool
2405
2406/// Get the next common instance of the current common symbol.
2407///
2408/// A common instance of a given common symbol is another common
2409/// symbol with the same name. Those exist in relocatable files. The
2410/// linker normally allocates all the instances into a common block in
2411/// the final output file.
2412///
2413/// @return the next common instance, or nil if there is not any.
2416{return priv_->next_common_instance_.lock();}
2417
2418/// Add a common instance to the current common elf symbol.
2419///
2420/// Note that this symbol must be the main symbol. Being the main
2421/// symbol means being the first common symbol to appear in the symbol
2422/// table.
2423///
2424/// @param common the other common instance to add.
2425void
2427{
2428 if (!common)
2429 return;
2430
2431 ABG_ASSERT(!common->has_other_common_instances());
2434
2436 {
2437 elf_symbol_sptr last_common_instance;
2439 c && (c.get() != get_main_symbol().get());
2440 c = c->get_next_common_instance())
2441 {
2442 if (c->get_next_common_instance().get() == get_main_symbol().get())
2443 {
2444 ABG_ASSERT(last_common_instance == 0);
2445 last_common_instance = c;
2446 }
2447 }
2448 ABG_ASSERT(last_common_instance);
2449
2450 last_common_instance->priv_->next_common_instance_ = common;
2451 }
2452 else
2453 priv_->next_common_instance_ = common;
2454
2455 common->priv_->next_common_instance_ = get_main_symbol();
2456 common->priv_->main_symbol_ = get_main_symbol();
2457}
2458
2459/// Get a string that is representative of a given elf_symbol.
2460///
2461/// If the symbol has a version, then the ID string is the
2462/// concatenation of the name of the symbol, the '@' character, and
2463/// the version of the symbol. If the version is the default version
2464/// of the symbol then the '@' character is replaced by a "@@" string.
2465///
2466/// Otherwise, if the symbol does not have any version, this function
2467/// returns the name of the symbol.
2468///
2469/// @return a the ID string.
2470const string&
2472{
2473 if (priv_->id_string_.empty())
2474 {
2475 string s = get_name ();
2476
2477 if (!get_version().is_empty())
2478 {
2479 if (get_version().is_default())
2480 s += "@@";
2481 else
2482 s += "@";
2483 s += get_version().str();
2484 }
2485 priv_->id_string_ = s;
2486 }
2487
2488 return priv_->id_string_;
2489}
2490
2491/// From the aliases of the current symbol, lookup one with a given name.
2492///
2493/// @param name the name of symbol alias we are looking for.
2494///
2495/// @return the symbol alias that has the name @p name, or nil if none
2496/// has been found.
2498elf_symbol::get_alias_from_name(const string& name) const
2499{
2500 if (name == get_name())
2501 return elf_symbol_sptr(priv_->main_symbol_);
2502
2504 a && a.get() != get_main_symbol().get();
2505 a = a->get_next_alias())
2506 if (a->get_name() == name)
2507 return a;
2508
2509 return elf_symbol_sptr();
2510}
2511
2512/// In the list of aliases of a given elf symbol, get the alias that
2513/// equals this current symbol.
2514///
2515/// @param other the elf symbol to get the potential aliases from.
2516///
2517/// @return the alias of @p other that texually equals the current
2518/// symbol, or nil if no alias textually equals the current symbol.
2521{
2522 for (elf_symbol_sptr a = other.get_next_alias();
2523 a && a.get() != a->get_main_symbol().get();
2524 a = a->get_next_alias())
2525 if (textually_equals(*this, *a))
2526 return a;
2527 return elf_symbol_sptr();
2528}
2529
2530/// Return a comma separated list of the id of the current symbol as
2531/// well as the id string of its aliases.
2532///
2533/// @param syms a map of all the symbols of the corpus the current
2534/// symbol belongs to.
2535///
2536/// @param include_symbol_itself if set to true, then the name of the
2537/// current symbol is included in the list of alias names that is emitted.
2538///
2539/// @return the string.
2540string
2542 bool include_symbol_itself) const
2543{
2544 string result;
2545
2546 if (include_symbol_itself)
2547 result = get_id_string();
2548
2549 vector<elf_symbol_sptr> aliases;
2550 compute_aliases_for_elf_symbol(*this, syms, aliases);
2551 if (!aliases.empty() && include_symbol_itself)
2552 result += ", ";
2553
2554 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2555 i != aliases.end();
2556 ++i)
2557 {
2558 if (i != aliases.begin())
2559 result += ", ";
2560 result += (*i)->get_id_string();
2561 }
2562 return result;
2563}
2564
2565/// Return a comma separated list of the id of the current symbol as
2566/// well as the id string of its aliases.
2567///
2568/// @param include_symbol_itself if set to true, then the name of the
2569/// current symbol is included in the list of alias names that is emitted.
2570///
2571/// @return the string.
2572string
2573elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2574{
2575 vector<elf_symbol_sptr> aliases;
2576 if (include_symbol_itself)
2577 aliases.push_back(get_main_symbol());
2578
2580 a && a.get() != get_main_symbol().get();
2581 a = a->get_next_alias())
2582 aliases.push_back(a);
2583
2584 string result;
2585 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2586 i != aliases.end();
2587 ++i)
2588 {
2589 if (i != aliases.begin())
2590 result += ", ";
2591 result += (*i)->get_id_string();
2592 }
2593
2594 return result;
2595}
2596
2597/// Given the ID of a symbol, get the name and the version of said
2598/// symbol.
2599///
2600/// @param id the symbol ID to consider.
2601///
2602/// @param name the symbol name extracted from the ID. This is set
2603/// only if the function returned true.
2604///
2605/// @param ver the symbol version extracted from the ID.
2606bool
2608 string& name,
2609 string& ver)
2610{
2611 name.clear(), ver.clear();
2612
2613 string::size_type i = id.find('@');
2614 if (i == string::npos)
2615 {
2616 name = id;
2617 return true;
2618 }
2619
2620 name = id.substr(0, i);
2621 ++i;
2622
2623 if (i >= id.size())
2624 return true;
2625
2626 string::size_type j = id.find('@', i);
2627 if (j == string::npos)
2628 j = i;
2629 else
2630 ++j;
2631
2632 if (j >= id.size())
2633 {
2634 ver = "";
2635 return true;
2636 }
2637
2638 ver = id.substr(j);
2639 return true;
2640}
2641
2642///@}
2643
2644/// Test if two main symbols are textually equal, or, if they have
2645/// aliases that are textually equal.
2646///
2647/// @param other the symbol to compare against.
2648///
2649/// @return true iff the current instance of elf symbol equals the @p
2650/// other.
2651bool
2653{
2654 bool are_equal = textually_equals(*this, other);
2655 if (!are_equal)
2656 are_equal = bool(get_alias_which_equals(other));
2657 return are_equal;
2658}
2659
2660/// Test if the current symbol aliases another one.
2661///
2662/// @param o the other symbol to test against.
2663///
2664/// @return true iff the current symbol aliases @p o.
2665bool
2667{
2668 if (*this == o)
2669 return true;
2670
2671 if (get_main_symbol() == o.get_main_symbol())
2672 return true;
2673
2675 a && !a->is_main_symbol();
2676 a = a->get_next_alias())
2677 {
2678 if (o == *a)
2679 return true;
2680 }
2681 return false;
2682}
2683
2684/// Equality operator for smart pointers to elf_symbol.
2685///
2686/// @param lhs the first elf symbol to consider.
2687///
2688/// @param rhs the second elf symbol to consider.
2689///
2690/// @return true iff @p lhs equals @p rhs.
2691bool
2693{
2694 if (!!lhs != !!rhs)
2695 return false;
2696
2697 if (!lhs)
2698 return true;
2699
2700 return *lhs == *rhs;
2701}
2702
2703/// Inequality operator for smart pointers to elf_symbol.
2704///
2705/// @param lhs the first elf symbol to consider.
2706///
2707/// @param rhs the second elf symbol to consider.
2708///
2709/// @return true iff @p lhs is different from @p rhs.
2710bool
2712{return !operator==(lhs, rhs);}
2713
2714/// Test if two symbols alias.
2715///
2716/// @param s1 the first symbol to consider.
2717///
2718/// @param s2 the second symbol to consider.
2719///
2720/// @return true if @p s1 aliases @p s2.
2721bool
2723{return s1.does_alias(s2) || s2.does_alias(s1);}
2724
2725void
2726compute_aliases_for_elf_symbol(const elf_symbol& sym,
2727 const string_elf_symbols_map_type& symtab,
2728 vector<elf_symbol_sptr>& aliases)
2729{
2730
2731 if (elf_symbol_sptr a = sym.get_next_alias())
2732 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2733 aliases.push_back(a);
2734 else
2735 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2736 i != symtab.end();
2737 ++i)
2738 for (elf_symbols::const_iterator j = i->second.begin();
2739 j != i->second.end();
2740 ++j)
2741 {
2742 if (**j == sym)
2743 for (elf_symbol_sptr s = (*j)->get_next_alias();
2744 s && !s->is_main_symbol();
2745 s = s->get_next_alias())
2746 aliases.push_back(s);
2747 else
2748 for (elf_symbol_sptr s = (*j)->get_next_alias();
2749 s && !s->is_main_symbol();
2750 s = s->get_next_alias())
2751 if (*s == sym)
2752 aliases.push_back(*j);
2753 }
2754}
2755
2756/// Test if two symbols alias.
2757///
2758/// @param s1 the first symbol to consider.
2759///
2760/// @param s2 the second symbol to consider.
2761///
2762/// @return true if @p s1 aliases @p s2.
2763bool
2765{
2766 if (!!s1 != !!s2)
2767 return false;
2768 if (s1 == s2)
2769 return true;
2770 return elf_symbols_alias(*s1, *s2);
2771}
2772
2773/// Test if two symbols alias.
2774///
2775/// @param s1 the first symbol to consider.
2776///
2777/// @param s2 the second symbol to consider.
2778///
2779/// @return true if @p s1 aliases @p s2.
2780bool
2782{return elf_symbols_alias(s1.get(), s2.get());}
2783
2784/// Serialize an instance of @ref symbol_type and stream it to a given
2785/// output stream.
2786///
2787/// @param o the output stream to serialize the symbole type to.
2788///
2789/// @param t the symbol type to serialize.
2790std::ostream&
2791operator<<(std::ostream& o, elf_symbol::type t)
2792{
2793 string repr;
2794
2795 switch (t)
2796 {
2797 case elf_symbol::NOTYPE_TYPE:
2798 repr = "unspecified symbol type";
2799 break;
2800 case elf_symbol::OBJECT_TYPE:
2801 repr = "variable symbol type";
2802 break;
2803 case elf_symbol::FUNC_TYPE:
2804 repr = "function symbol type";
2805 break;
2806 case elf_symbol::SECTION_TYPE:
2807 repr = "section symbol type";
2808 break;
2809 case elf_symbol::FILE_TYPE:
2810 repr = "file symbol type";
2811 break;
2812 case elf_symbol::COMMON_TYPE:
2813 repr = "common data object symbol type";
2814 break;
2815 case elf_symbol::TLS_TYPE:
2816 repr = "thread local data object symbol type";
2817 break;
2818 case elf_symbol::GNU_IFUNC_TYPE:
2819 repr = "indirect function symbol type";
2820 break;
2821 default:
2822 {
2823 std::ostringstream s;
2824 s << "unknown symbol type (" << (char)t << ')';
2825 repr = s.str();
2826 }
2827 break;
2828 }
2829
2830 o << repr;
2831 return o;
2832}
2833
2834/// Serialize an instance of @ref symbol_binding and stream it to a
2835/// given output stream.
2836///
2837/// @param o the output stream to serialize the symbole type to.
2838///
2839/// @param b the symbol binding to serialize.
2840std::ostream&
2841operator<<(std::ostream& o, elf_symbol::binding b)
2842{
2843 string repr;
2844
2845 switch (b)
2846 {
2847 case elf_symbol::LOCAL_BINDING:
2848 repr = "local binding";
2849 break;
2850 case elf_symbol::GLOBAL_BINDING:
2851 repr = "global binding";
2852 break;
2853 case elf_symbol::WEAK_BINDING:
2854 repr = "weak binding";
2855 break;
2856 case elf_symbol::GNU_UNIQUE_BINDING:
2857 repr = "GNU unique binding";
2858 break;
2859 default:
2860 {
2861 std::ostringstream s;
2862 s << "unknown binding (" << (unsigned char) b << ")";
2863 repr = s.str();
2864 }
2865 break;
2866 }
2867
2868 o << repr;
2869 return o;
2870}
2871
2872/// Serialize an instance of @ref elf_symbol::visibility and stream it
2873/// to a given output stream.
2874///
2875/// @param o the output stream to serialize the symbole type to.
2876///
2877/// @param v the symbol visibility to serialize.
2878std::ostream&
2879operator<<(std::ostream& o, elf_symbol::visibility v)
2880{
2881 string repr;
2882
2883 switch (v)
2884 {
2885 case elf_symbol::DEFAULT_VISIBILITY:
2886 repr = "default visibility";
2887 break;
2888 case elf_symbol::PROTECTED_VISIBILITY:
2889 repr = "protected visibility";
2890 break;
2891 case elf_symbol::HIDDEN_VISIBILITY:
2892 repr = "hidden visibility";
2893 break;
2894 case elf_symbol::INTERNAL_VISIBILITY:
2895 repr = "internal visibility";
2896 break;
2897 default:
2898 {
2899 std::ostringstream s;
2900 s << "unknown visibility (" << (unsigned char) v << ")";
2901 repr = s.str();
2902 }
2903 break;
2904 }
2905
2906 o << repr;
2907 return o;
2908}
2909
2910/// Convert a string representing a symbol type into an
2911/// elf_symbol::type.
2912///
2913///@param s the string to convert.
2914///
2915///@param t the resulting elf_symbol::type.
2916///
2917/// @return true iff the conversion completed successfully.
2918bool
2920{
2921 if (s == "no-type")
2922 t = elf_symbol::NOTYPE_TYPE;
2923 else if (s == "object-type")
2924 t = elf_symbol::OBJECT_TYPE;
2925 else if (s == "func-type")
2926 t = elf_symbol::FUNC_TYPE;
2927 else if (s == "section-type")
2928 t = elf_symbol::SECTION_TYPE;
2929 else if (s == "file-type")
2930 t = elf_symbol::FILE_TYPE;
2931 else if (s == "common-type")
2932 t = elf_symbol::COMMON_TYPE;
2933 else if (s == "tls-type")
2934 t = elf_symbol::TLS_TYPE;
2935 else if (s == "gnu-ifunc-type")
2936 t = elf_symbol::GNU_IFUNC_TYPE;
2937 else
2938 return false;
2939
2940 return true;
2941}
2942
2943/// Convert a string representing a an elf symbol binding into an
2944/// elf_symbol::binding.
2945///
2946/// @param s the string to convert.
2947///
2948/// @param b the resulting elf_symbol::binding.
2949///
2950/// @return true iff the conversion completed successfully.
2951bool
2953{
2954 if (s == "local-binding")
2955 b = elf_symbol::LOCAL_BINDING;
2956 else if (s == "global-binding")
2957 b = elf_symbol::GLOBAL_BINDING;
2958 else if (s == "weak-binding")
2959 b = elf_symbol::WEAK_BINDING;
2960 else if (s == "gnu-unique-binding")
2961 b = elf_symbol::GNU_UNIQUE_BINDING;
2962 else
2963 return false;
2964
2965 return true;
2966}
2967
2968/// Convert a string representing a an elf symbol visibility into an
2969/// elf_symbol::visibility.
2970///
2971/// @param s the string to convert.
2972///
2973/// @param b the resulting elf_symbol::visibility.
2974///
2975/// @return true iff the conversion completed successfully.
2976bool
2978{
2979 if (s == "default-visibility")
2980 v = elf_symbol::DEFAULT_VISIBILITY;
2981 else if (s == "protected-visibility")
2982 v = elf_symbol::PROTECTED_VISIBILITY;
2983 else if (s == "hidden-visibility")
2984 v = elf_symbol::HIDDEN_VISIBILITY;
2985 else if (s == "internal-visibility")
2986 v = elf_symbol::INTERNAL_VISIBILITY;
2987 else
2988 return false;
2989
2990 return true;
2991}
2992
2993/// Test if the type of an ELF symbol denotes a function symbol.
2994///
2995/// @param t the type of the ELF symbol.
2996///
2997/// @return true iff elf symbol type @p t denotes a function symbol
2998/// type.
2999bool
3001{return t == elf_symbol::FUNC_TYPE;}
3002
3003/// Test if the type of an ELF symbol denotes a function symbol.
3004///
3005/// @param t the type of the ELF symbol.
3006///
3007/// @return true iff elf symbol type @p t denotes a function symbol
3008/// type.
3009bool
3011{return t == elf_symbol::OBJECT_TYPE;}
3012
3013// <elf_symbol::version stuff>
3014
3015struct elf_symbol::version::priv
3016{
3017 string version_;
3018 bool is_default_;
3019
3020 priv()
3021 : is_default_(false)
3022 {}
3023
3024 priv(const string& v,
3025 bool d)
3026 : version_(v),
3027 is_default_(d)
3028 {}
3029}; // end struct elf_symbol::version::priv
3030
3031elf_symbol::version::version()
3032 : priv_(new priv)
3033{}
3034
3035/// @param v the name of the version.
3036///
3037/// @param is_default true if this is a default version.
3038elf_symbol::version::version(const string& v,
3039 bool is_default)
3040 : priv_(new priv(v, is_default))
3041{}
3042
3043elf_symbol::version::version(const elf_symbol::version& v)
3044 : priv_(new priv(v.str(), v.is_default()))
3045{
3046}
3047
3048elf_symbol::version::~version() = default;
3049
3050/// Cast the version_type into a string that is its name.
3051///
3052/// @return the name of the version.
3053elf_symbol::version::operator const string&() const
3054{return priv_->version_;}
3055
3056/// Getter for the version name.
3057///
3058/// @return the version name.
3059const string&
3061{return priv_->version_;}
3062
3063/// Setter for the version name.
3064///
3065/// @param s the version name.
3066void
3068{priv_->version_ = s;}
3069
3070/// Getter for the 'is_default' property of the version.
3071///
3072/// @return true iff this is a default version.
3073bool
3075{return priv_->is_default_;}
3076
3077/// Setter for the 'is_default' property of the version.
3078///
3079/// @param f true if this is the default version.
3080void
3082{priv_->is_default_ = f;}
3083
3084bool
3085elf_symbol::version::is_empty() const
3086{return str().empty();}
3087
3088/// Compares the current version against another one.
3089///
3090/// @param o the other version to compare the current one to.
3091///
3092/// @return true iff the current version equals @p o.
3093bool
3095{return str() == o.str();}
3096
3097/// Inequality operator.
3098///
3099/// @param o the version to compare against the current one.
3100///
3101/// @return true iff both versions are different.
3102bool
3104{return !operator==(o);}
3105
3106/// Assign a version to the current one.
3107///
3108/// @param o the other version to assign to this one.
3109///
3110/// @return a reference to the assigned version.
3113{
3114 str(o.str());
3115 is_default(o.is_default());
3116 return *this;
3117}
3118
3119// </elf_symbol::version stuff>
3120
3121// </elf_symbol stuff>
3122
3123// <class dm_context_rel stuff>
3124struct dm_context_rel::priv
3125{
3126 bool is_laid_out_;
3127 size_t offset_in_bits_;
3128 var_decl* anonymous_data_member_;
3129
3130 priv(bool is_static = false)
3131 : is_laid_out_(!is_static),
3132 offset_in_bits_(0),
3133 anonymous_data_member_()
3134 {}
3135
3136 priv(bool is_laid_out, size_t offset_in_bits)
3137 : is_laid_out_(is_laid_out),
3138 offset_in_bits_(offset_in_bits),
3139 anonymous_data_member_()
3140 {}
3141}; //end struct dm_context_rel::priv
3142
3143dm_context_rel::dm_context_rel()
3144 : context_rel(),
3145 priv_(new priv)
3146{}
3147
3148dm_context_rel::dm_context_rel(scope_decl* s,
3149 bool is_laid_out,
3150 size_t offset_in_bits,
3152 bool is_static)
3153 : context_rel(s, a, is_static),
3154 priv_(new priv(is_laid_out, offset_in_bits))
3155{}
3156
3157dm_context_rel::dm_context_rel(scope_decl* s)
3158 : context_rel(s),
3159 priv_(new priv())
3160{}
3161
3162bool
3163dm_context_rel::get_is_laid_out() const
3164{return priv_->is_laid_out_;}
3165
3166void
3167dm_context_rel::set_is_laid_out(bool f)
3168{priv_->is_laid_out_ = f;}
3169
3170size_t
3171dm_context_rel::get_offset_in_bits() const
3172{return priv_->offset_in_bits_;}
3173
3174void
3175dm_context_rel::set_offset_in_bits(size_t o)
3176{priv_->offset_in_bits_ = o;}
3177
3178bool
3179dm_context_rel::operator==(const dm_context_rel& o) const
3180{
3181 if (!context_rel::operator==(o))
3182 return false;
3183
3184 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3185 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3186}
3187
3188bool
3189dm_context_rel::operator!=(const dm_context_rel& o) const
3190{return !operator==(o);}
3191
3192/// Return a non-nil value if this data member context relationship
3193/// has an anonymous data member. That means, if the data member this
3194/// relation belongs to is part of an anonymous data member.
3195///
3196/// @return the containing anonymous data member of this data member
3197/// relationship. Nil if there is none.
3198const var_decl*
3200{return priv_->anonymous_data_member_;}
3201
3202/// Set the containing anonymous data member of this data member
3203/// context relationship. That means that the data member this
3204/// relation belongs to is part of an anonymous data member.
3205///
3206/// @param anon_dm the containing anonymous data member of this data
3207/// member relationship. Nil if there is none.
3208void
3210{priv_->anonymous_data_member_ = anon_dm;}
3211
3212dm_context_rel::~dm_context_rel()
3213{}
3214// </class dm_context_rel stuff>
3215
3216// <environment stuff>
3217
3218/// Convenience typedef for a map of interned_string -> bool.
3219typedef unordered_map<interned_string,
3221
3222
3223/// Default constructor of the @ref environment type.
3225 :priv_(new priv)
3226{}
3227
3228/// Destructor for the @ref environment type.
3231
3232/// Getter the map of canonical types.
3233///
3234/// @return the map of canonical types. The key of the map is the
3235/// hash of the canonical type and its value if the canonical type.
3238{return priv_->canonical_types_;}
3239
3240/// Getter the map of canonical types.
3241///
3242/// @return the map of canonical types. The key of the map is the
3243/// hash of the canonical type and its value if the canonical type.
3247
3248/// Helper to detect if a type is either a reference, a pointer, or a
3249/// qualified type.
3250bool
3252{
3253 if (is_pointer_type(t)
3254 || is_reference_type(t)
3255 || is_qualified_type(t))
3256 return true;
3257 return false;
3258}
3259
3260/// Compare decls using their locations.
3261///
3262/// @param f the first decl to compare.
3263///
3264/// @param s the second decl to compare.
3265///
3266/// @return true if @p f compares less than @p s.
3267bool
3269 const decl_base *s)
3270{
3271 // If a decl has artificial location, then use that one over the
3272 // natural one.
3275
3276 ABG_ASSERT(fl.get_value() && sl.get_value());
3277 if (fl.get_is_artificial() == sl.get_is_artificial())
3278 {
3279 // The locations of the two artfifacts have the same
3280 // artificial-ness so they can be compared.
3281 string p1, p2;
3282 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3283 fl.expand(p1, l1, c1);
3284 sl.expand(p2, l2, c2);
3285 if (p1 != p2)
3286 return p1 < p2;
3287 if (l1 != l2)
3288 return l1 < l2;
3289 if (c1 != c2)
3290 return c1 < c2;
3291 }
3292
3293 return (get_pretty_representation(f, /*internal=*/false)
3294 < get_pretty_representation(s, /*internal=*/false));
3295}
3296
3297/// Sort types in a hopefully stable manner.
3298///
3299/// @param types a set of types with canonical types to sort.
3300///
3301/// @param result the resulting sorted vector.
3302void
3304 vector<type_base_sptr>& result)
3305{
3306 for (auto t: types)
3307 result.push_back(t);
3308
3309 type_topo_comp comp;
3310 std::stable_sort(result.begin(), result.end(), comp);
3311}
3312
3313/// Get the unique @ref type_decl that represents a "void" type for
3314/// the current environment. This node must be the only one
3315/// representing a void type in the system.
3316///
3317/// Note that upon first use of this IR node (by the relevant
3318/// front-end, for instance) it must be added to a scope using e.g,
3319/// the @ref add_decl_to_scope() function.
3320///
3321/// @return the @ref type_decl that represents a "void" type.
3322const type_base_sptr&
3324{
3325 if (!priv_->void_type_)
3326 priv_->void_type_.reset(new type_decl(*this,
3327 intern("void"),
3328 0, 0, location()));
3329 return priv_->void_type_;
3330}
3331
3332/// Getter of the "pointer-to-void" IR node that is shared across the
3333/// ABI corpus. This node must be the only one representing a void
3334/// pointer type in the system.
3335///
3336/// Note that upon first use of this IR node (by the relevant
3337/// front-end, for instance) it must be added to a scope using e.g,
3338/// the @ref add_decl_to_scope() function.
3339///
3340/// @return the "pointer-to-void" IR node.
3341const type_base_sptr&
3343{
3344 if (!priv_->void_pointer_type_)
3345 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3346 0, 0, location()));
3347 return priv_->void_pointer_type_;
3348}
3349
3350/// Get a @ref type_decl instance that represents a the type of a
3351/// variadic function parameter. This node must be the only one
3352/// representing a variadic parameter type in the system.
3353///
3354/// Note that upon first use of this IR node (by the relevant
3355/// front-end, for instance) it must be added to a scope using e.g,
3356/// the @ref add_decl_to_scope() function.
3357///
3358/// @return the Get a @ref type_decl instance that represents a the
3359/// type of a variadic function parameter.
3360const type_base_sptr&
3362{
3363 if (!priv_->variadic_marker_type_)
3364 priv_->variadic_marker_type_.
3366 0, 0, location()));
3367 return priv_->variadic_marker_type_;
3368}
3369
3370/// Getter of the name of the variadic parameter type.
3371///
3372/// @return the name of the variadic parameter type.
3373string&
3375{
3376 static string variadic_parameter_type_name = "variadic parameter type";
3377 return variadic_parameter_type_name;
3378}
3379
3380/// Test if the canonicalization of types created out of the current
3381/// environment is done.
3382///
3383/// @return true iff the canonicalization of types created out of the current
3384/// environment is done.
3385bool
3387{return priv_->canonicalization_is_done_;}
3388
3389/// Set a flag saying if the canonicalization of types created out of
3390/// the current environment is done or not.
3391///
3392/// Note that this function must only be called by internal code of
3393/// the library that creates ABI artifacts (e.g, read an abi corpus
3394/// from elf or from our own xml format and creates representations of
3395/// types out of it) and thus needs to canonicalize types to speed-up
3396/// further type comparison.
3397///
3398/// @param f the new value of the flag.
3399void
3401{
3402 priv_->canonicalization_is_done_ = f;
3403 if (priv_->canonicalization_is_done_)
3405}
3406
3407/// Getter of a flag saying if the canonicalization process has
3408/// started or not.
3409///
3410/// @return the flag saying if the canonicalization process has
3411/// started or not.
3412bool
3414{return priv_->canonicalization_started_;}
3415
3416/// Setter of a flag saying if the canonicalization process has
3417/// started or not.
3418///
3419/// @param f the new value of the flag saying if the canonicalization
3420/// process has started or not.
3421void
3423{priv_->canonicalization_started_ = f;}
3424
3425/// Getter of the "decl-only-class-equals-definition" flag.
3426///
3427/// Usually, a declaration-only class named 'struct foo' compares
3428/// equal to any class definition named "struct foo'. This is at
3429/// least true for C++.
3430///
3431/// In C, though, because there can be multiple definitions of 'struct
3432/// foo' in the binary, a declaration-only "struct foo" might be
3433/// considered to *NOT* resolve to any of the struct foo defined. In
3434/// that case, the declaration-only "struct foo" is considered
3435/// different from the definitions.
3436///
3437/// This flag controls the behaviour of the comparison of an
3438/// unresolved decl-only class against a definition of the same name.
3439///
3440/// If set to false, the the declaration equals the definition. If
3441/// set to false, then the decalration is considered different from
3442/// the declaration.
3443///
3444/// @return the value of the "decl-only-class-equals-definition" flag.
3445bool
3447{return priv_->decl_only_class_equals_definition_;}
3448
3449/// Setter of the "decl-only-class-equals-definition" flag.
3450///
3451/// Usually, a declaration-only class named 'struct foo' compares
3452/// equal to any class definition named "struct foo'. This is at
3453/// least true for C++.
3454///
3455/// In C, though, because there can be multiple definitions of 'struct
3456/// foo' in the binary, a declaration-only "struct foo" might be
3457/// considered to *NOT* resolve to any of the struct foo defined. In
3458/// that case, the declaration-only "struct foo" is considered
3459/// different from the definitions.
3460///
3461/// This flag controls the behaviour of the comparison of an
3462/// unresolved decl-only class against a definition of the same name.
3463///
3464/// If set to false, the the declaration equals the definition. If
3465/// set to false, then the decalration is considered different from
3466/// the declaration.
3467///
3468/// @param the new value of the "decl-only-class-equals-definition"
3469/// flag.
3470void
3472{priv_->decl_only_class_equals_definition_ = f;}
3473
3474/// Test if a given type is a void type as defined in the current
3475/// environment.
3476///
3477/// @param t the type to consider.
3478///
3479/// @return true iff @p t is a void type as defined in the current
3480/// environment.
3481bool
3482environment::is_void_type(const type_base_sptr& t) const
3483{
3484 if (!t)
3485 return false;
3486 return is_void_type(t.get());
3487}
3488
3489/// Test if a given type is a void type as defined in the current
3490/// environment.
3491///
3492/// @param t the type to consider.
3493///
3494/// @return true iff @p t is a void type as defined in the current
3495/// environment.
3496bool
3498{
3499 if (!t)
3500 return false;
3501 return (t == get_void_type().get()
3502 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3503}
3504
3505/// Test if a given type is the same as the void pointer type of the
3506/// environment.
3507///
3508/// @param t the IR type to test.
3509///
3510/// @return true iff @p t is the void pointer returned by
3511/// environment::get_void_pointer_type().
3512bool
3513environment::is_void_pointer_type(const type_base_sptr& t) const
3514{
3515 if (!t)
3516 return false;
3517
3518 return t.get() == get_void_pointer_type().get();
3519}
3520
3521/// Test if a given type is the same as the void pointer type of the
3522/// environment.
3523///
3524/// @param t the IR type to test.
3525///
3526/// @return true iff @p t is the void pointer returned by
3527/// environment::get_void_pointer_type().
3528bool
3530{
3531 if (!t)
3532 return false;
3533
3534 return t == get_void_pointer_type().get();
3535}
3536
3537/// Test if a type is a variadic parameter type as defined in the
3538/// current environment.
3539///
3540/// @param t the type to consider.
3541///
3542/// @return true iff @p t is a variadic parameter type as defined in
3543/// the current environment.
3544bool
3546{
3547 if (!t)
3548 return false;
3549 return t == get_variadic_parameter_type().get();
3550}
3551
3552/// Test if a type is a variadic parameter type as defined in the
3553/// current environment.
3554///
3555/// @param t the type to consider.
3556///
3557/// @return true iff @p t is a variadic parameter type as defined in
3558/// the current environment.
3559bool
3560environment::is_variadic_parameter_type(const type_base_sptr& t) const
3561{return is_variadic_parameter_type(t.get());}
3562
3563/// Do intern a string.
3564///
3565/// If a value of this string already exists in the interned string
3566/// pool of the current environment, then this function returns a new
3567/// interned_string pointing to that already existing string.
3568/// Otherwise, a new string is created, stored in the interned string
3569/// pool and a new interned_string instance is created to point to
3570/// that new intrerned string, and it's return.
3571///
3572/// @param s the value of the string to intern.
3573///
3574/// @return the interned string.
3576environment::intern(const string& s) const
3577{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3578
3579/// Getter of the general configuration object.
3580///
3581/// @return the configuration object.
3582const config&
3584{return priv_->config_;}
3585
3586/// Getter for a property that says if the user actually did set the
3587/// analyze_exported_interfaces_only() property. If not, it means
3588/// the default behaviour prevails.
3589///
3590/// @return tru iff the user did set the
3591/// analyze_exported_interfaces_only() property.
3592bool
3594{return priv_->analyze_exported_interfaces_only_.has_value();}
3595
3596/// Setter for the property that controls if we are to restrict the
3597/// analysis to the types that are only reachable from the exported
3598/// interfaces only, or if the set of types should be more broad than
3599/// that. Typically, we'd restrict the analysis to types reachable
3600/// from exported interfaces only (stricto sensu, that would really be
3601/// only the types that are part of the ABI of well designed
3602/// libraries) for performance reasons.
3603///
3604/// @param f the value of the flag.
3605void
3607{priv_->analyze_exported_interfaces_only_ = f;}
3608
3609/// Getter for the property that controls if we are to restrict the
3610/// analysis to the types that are only reachable from the exported
3611/// interfaces only, or if the set of types should be more broad than
3612/// that. Typically, we'd restrict the analysis to types reachable
3613/// from exported interfaces only (stricto sensu, that would really be
3614/// only the types that are part of the ABI of well designed
3615/// libraries) for performance reasons.
3616///
3617/// @param f the value of the flag.
3618bool
3620{return priv_->analyze_exported_interfaces_only_.value_or(false);}
3621
3622#ifdef WITH_DEBUG_SELF_COMPARISON
3623/// Setter of the corpus of the input corpus of the self comparison
3624/// that takes place when doing "abidw --debug-abidiff <binary>".
3625///
3626/// The first invocation of this function sets the first corpus of the
3627/// self comparison. The second invocation of this very same function
3628/// sets the second corpus of the self comparison. That second corpus
3629/// is supposed to come from the abixml serialization of the first
3630/// corpus.
3631///
3632/// @param c the corpus of the input binary or the corpus of the
3633/// abixml serialization of the initial binary input.
3634void
3635environment::set_self_comparison_debug_input(const corpus_sptr& c)
3636{
3637 self_comparison_debug_is_on(true);
3638 if (priv_->first_self_comparison_corpus_.expired())
3639 priv_->first_self_comparison_corpus_ = c;
3640 else if (priv_->second_self_comparison_corpus_.expired()
3641 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3642 priv_->second_self_comparison_corpus_ = c;
3643}
3644
3645/// Getter for the corpora of the input binary and the intermediate
3646/// abixml of the self comparison that takes place when doing
3647/// 'abidw --debug-abidiff <binary>'.
3648///
3649/// @param first_corpus output parameter that is set to the corpus of
3650/// the input corpus.
3651///
3652/// @param second_corpus output parameter that is set to the corpus of
3653/// the second corpus.
3654void
3655environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3656 corpus_sptr& second_corpus)
3657{
3658 first_corpus = priv_->first_self_comparison_corpus_.lock();
3659 second_corpus = priv_->second_self_comparison_corpus_.lock();
3660}
3661
3662/// Turn on/off the self comparison debug mode.
3663///
3664/// @param f true iff the self comparison debug mode is turned on.
3665void
3666environment::self_comparison_debug_is_on(bool f)
3667{priv_->self_comparison_debug_on_ = f;}
3668
3669/// Test if we are in the process of the 'self-comparison
3670/// debugging' as triggered by 'abidw --debug-abidiff' command.
3671///
3672/// @return true if self comparison debug is on.
3673bool
3674environment::self_comparison_debug_is_on() const
3675{return priv_->self_comparison_debug_on_;}
3676#endif
3677
3678#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3679/// Set the "type canonicalization debugging" mode, triggered by using
3680/// the command: "abidw --debug-tc".
3681///
3682/// @param flag if true then the type canonicalization debugging mode
3683/// is enabled.
3684void
3685environment::debug_type_canonicalization_is_on(bool flag)
3686{priv_->debug_type_canonicalization_ = flag;}
3687
3688/// Getter of the "type canonicalization debugging" mode, triggered by
3689/// using the command: "abidw --debug-tc".
3690///
3691/// @return true iff the type canonicalization debugging mode is
3692/// enabled.
3693bool
3694environment::debug_type_canonicalization_is_on() const
3695{return priv_->debug_type_canonicalization_;}
3696
3697/// Setter of the "DIE canonicalization debugging" mode, triggered by
3698/// using the command: "abidw --debug-dc".
3699///
3700/// @param flag true iff the DIE canonicalization debugging mode is
3701/// enabled.
3702void
3703environment::debug_die_canonicalization_is_on(bool flag)
3704{priv_->debug_die_canonicalization_ = flag;}
3705
3706/// Getter of the "DIE canonicalization debugging" mode, triggered by
3707/// using the command: "abidw --debug-dc".
3708///
3709/// @return true iff the DIE canonicalization debugging mode is
3710/// enabled.
3711bool
3712environment::debug_die_canonicalization_is_on() const
3713{return priv_->debug_die_canonicalization_;}
3714#endif // WITH_DEBUG_TYPE_CANONICALIZATION
3715
3716/// Get the vector of canonical types which have a given "string
3717/// representation".
3718///
3719/// @param 'name', the textual representation of the type as returned
3720/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3721/// /*qualified=*/true)
3722///
3723/// This is useful to for debugging purposes as it's handy to use from
3724/// inside a debugger like GDB.
3725///
3726/// @return a pointer to the vector of canonical types having the
3727/// representation @p name, or nullptr if no type with that
3728/// representation exists.
3729const vector<type_base_sptr>*
3731{
3732 auto ti = get_canonical_types_map().find(name);
3733 if (ti == get_canonical_types_map().end())
3734 return nullptr;
3735 return &ti->second;
3736}
3737
3738/// Get a given canonical type which has a given "string
3739/// representation".
3740///
3741/// @param 'name', the textual representation of the type as returned
3742/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3743/// /*qualified=*/true).
3744///
3745/// @param index, the index of the type in the vector of types that
3746/// all have the same textual representation @p 'name'. That vector
3747/// is returned by the function environment::get_canonical_types().
3748///
3749/// @return the canonical type which has the representation @p name,
3750/// and which is at index @p index in the vector of canonical types
3751/// having that same textual representation.
3752type_base*
3753environment::get_canonical_type(const char* name, unsigned index)
3754{
3755 const vector<type_base_sptr> *types = get_canonical_types(name);
3756 if (!types ||index >= types->size())
3757 return nullptr;
3758 return (*types)[index].get();
3759}
3760
3761#ifdef WITH_DEBUG_SELF_COMPARISON
3762/// Get the set of abixml type-id and the pointer value of the
3763/// (canonical) type it's associated to.
3764///
3765/// This is useful for debugging purposes, especially in the context
3766/// of the use of the command:
3767/// 'abidw --debug-abidiff <binary>'.
3768///
3769/// @return the set of abixml type-id and the pointer value of the
3770/// (canonical) type it's associated to.
3771const unordered_map<string, uintptr_t>&
3772environment::get_type_id_canonical_type_map() const
3773{return priv_->get_type_id_canonical_type_map();}
3774
3775/// Get the set of abixml type-id and the pointer value of the
3776/// (canonical) type it's associated to.
3777///
3778/// This is useful for debugging purposes, especially in the context
3779/// of the use of the command:
3780/// 'abidw --debug-abidiff <binary>'.
3781///
3782/// @return the set of abixml type-id and the pointer value of the
3783/// (canonical) type it's associated to.
3784unordered_map<string, uintptr_t>&
3785environment::get_type_id_canonical_type_map()
3786{return priv_->get_type_id_canonical_type_map();}
3787
3788/// Getter of the map that associates the values of type pointers to
3789/// their type-id strings.
3790///
3791/// Note that this map is populated at abixml reading time, (by
3792/// build_type()) when a given XML element representing a type is
3793/// read into a corresponding abigail::ir::type_base.
3794///
3795/// This is used only for the purpose of debugging the
3796/// self-comparison process. That is, when invoking "abidw
3797/// --debug-abidiff".
3798///
3799/// @return the map that associates the values of type pointers to
3800/// their type-id strings.
3801const unordered_map<uintptr_t, string>&
3802environment::get_pointer_type_id_map() const
3803{return priv_->get_pointer_type_id_map();}
3804
3805/// Getter of the map that associates the values of type pointers to
3806/// their type-id strings.
3807///
3808/// Note that this map is populated at abixml reading time, (by
3809/// build_type()) when a given XML element representing a type is
3810/// read into a corresponding abigail::ir::type_base.
3811///
3812/// This is used only for the purpose of debugging the
3813/// self-comparison process. That is, when invoking "abidw
3814/// --debug-abidiff".
3815///
3816/// @return the map that associates the values of type pointers to
3817/// their type-id strings.
3818unordered_map<uintptr_t, string>&
3819environment::get_pointer_type_id_map()
3820{return priv_->get_pointer_type_id_map();}
3821
3822/// Getter of the type-id that corresponds to the value of a pointer
3823/// to abigail::ir::type_base that was created from the abixml reader.
3824///
3825/// That value is retrieved from the map returned from
3826/// environment::get_pointer_type_id_map().
3827///
3828/// That map is populated at abixml reading time, (by build_type())
3829/// when a given XML element representing a type is read into a
3830/// corresponding abigail::ir::type_base.
3831///
3832/// This is used only for the purpose of debugging the
3833/// self-comparison process. That is, when invoking "abidw
3834/// --debug-abidiff".
3835///
3836/// @return the type-id strings that corresponds
3837string
3838environment::get_type_id_from_pointer(uintptr_t ptr) const
3839{return priv_->get_type_id_from_pointer(ptr);}
3840
3841/// Getter of the type-id that corresponds to the value of an
3842/// abigail::ir::type_base that was created from the abixml reader.
3843///
3844/// That value is retrieved from the map returned from
3845/// environment::get_pointer_type_id_map().
3846///
3847/// That map is populated at abixml reading time, (by build_type())
3848/// when a given XML element representing a type is read into a
3849/// corresponding abigail::ir::type_base.
3850///
3851/// This is used only for the purpose of debugging the
3852/// self-comparison process. That is, when invoking "abidw
3853/// --debug-abidiff".
3854///
3855/// @return the type-id strings that corresponds
3856string
3857environment::get_type_id_from_type(const type_base *t) const
3858{return priv_->get_type_id_from_type(t);}
3859
3860/// Getter of the canonical type of the artifact designated by a
3861/// type-id.
3862///
3863/// That type-id was generated by the abixml writer at the emitting
3864/// time of the abixml file. The corresponding canonical type was
3865/// stored in the map returned by
3866/// environment::get_type_id_canonical_type_map().
3867///
3868/// This is useful for debugging purposes, especially in the context
3869/// of the use of the command:
3870/// 'abidw --debug-abidiff <binary>'.
3871///
3872/// @return the set of abixml type-id and the pointer value of the
3873/// (canonical) type it's associated to.
3874uintptr_t
3875environment::get_canonical_type_from_type_id(const char* type_id) const
3876{return priv_->get_canonical_type_from_type_id(type_id);}
3877#endif
3878
3879// </environment stuff>
3880
3881// <type_or_decl_base stuff>
3882
3883/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
3884/// bitmap type.
3888{
3889 return static_cast<type_or_decl_base::type_or_decl_kind>
3890 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
3891}
3892
3893/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
3894/// bitmap type.
3898{
3899 l = l | r;
3900 return l;
3901}
3902
3903/// bitwise "AND" operator for the
3904/// type_or_decl_base::type_or_decl_kind bitmap type.
3908{
3909 return static_cast<type_or_decl_base::type_or_decl_kind>
3910 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
3911}
3912
3913/// bitwise "A&=" operator for the
3914/// type_or_decl_base::type_or_decl_kind bitmap type.
3918{
3919 l = l & r;
3920 return l;
3921}
3922
3923/// Constructor of @ref type_or_decl_base.
3924///
3925/// @param the environment the current ABI artifact is constructed
3926/// from.
3927///
3928/// @param k the runtime identifier bitmap of the type being built.
3929type_or_decl_base::type_or_decl_base(const environment& e,
3930 enum type_or_decl_kind k)
3931 :priv_(new priv(e, k))
3932{}
3933
3934/// The destructor of the @ref type_or_decl_base type.
3937
3938/// Getter of the flag that says if the artefact is artificial.
3939///
3940/// Being artificial means it was not explicitely mentionned in the
3941/// source code, but was rather artificially created by the compiler
3942/// or libabigail.
3943///
3944/// @return true iff the declaration is artificial.
3945bool
3947{return priv_->is_artificial_;}
3948
3949/// Setter of the flag that says if the artefact is artificial.
3950///
3951/// Being artificial means the artefact was not explicitely
3952/// mentionned in the source code, but was rather artificially created
3953/// by the compiler or by libabigail.
3954///
3955/// @param f the new value of the flag that says if the artefact is
3956/// artificial.
3957void
3959{priv_->is_artificial_ = f;}
3960
3961/// Getter for the "kind" property of @ref type_or_decl_base type.
3962///
3963/// This property holds the identifier bitmap of the runtime type of
3964/// an ABI artifact.
3965///
3966/// @return the runtime type identifier bitmap of the current ABI
3967/// artifact.
3970{return priv_->kind();}
3971
3972/// Setter for the "kind" property of @ref type_or_decl_base type.
3973///
3974/// This property holds the identifier bitmap of the runtime type of
3975/// an ABI artifact.
3976///
3977/// @param the runtime type identifier bitmap of the current ABI
3978/// artifact.
3979void
3981{priv_->kind(k);}
3982
3983/// Getter of the pointer to the runtime type sub-object of the
3984/// current instance.
3985///
3986/// @return the pointer to the runtime type sub-object of the current
3987/// instance.
3988const void*
3990{return priv_->rtti_;}
3991
3992/// Getter of the pointer to the runtime type sub-object of the
3993/// current instance.
3994///
3995/// @return the pointer to the runtime type sub-object of the current
3996/// instance.
3997void*
3999{return priv_->rtti_;}
4000
4001/// Setter of the pointer to the runtime type sub-object of the
4002/// current instance.
4003///
4004/// @param i the new pointer to the runtime type sub-object of the
4005/// current instance.
4006void
4008{
4009 priv_->rtti_ = i;
4010 if (type_base* t = dynamic_cast<type_base*>(this))
4011 priv_->type_or_decl_ptr_ = t;
4012 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4013 priv_->type_or_decl_ptr_ = d;
4014}
4015
4016/// Getter of the pointer to either the type_base sub-object of the
4017/// current instance if it's a type, or to the decl_base sub-object of
4018/// the current instance if it's a decl.
4019///
4020/// @return the pointer to either the type_base sub-object of the
4021/// current instance if it's a type, or to the decl_base sub-object of
4022/// the current instance if it's a decl.
4023const void*
4026
4027/// Getter of the pointer to either the type_base sub-object of the
4028/// current instance if it's a type, or to the decl_base sub-object of
4029/// the current instance if it's a decl.
4030///
4031/// @return the pointer to either the type_base sub-object of the
4032/// current instance if it's a type, or to the decl_base sub-object of
4033/// the current instance if it's a decl.
4034void*
4036{return priv_->type_or_decl_ptr_;}
4037
4038/// Return the hash value of the current IR node.
4039///
4040/// Note that upon the first invocation, this member functions
4041/// computes the hash value and returns it. Subsequent invocations
4042/// just return the hash value that was previously calculated.
4043///
4044/// @return the hash value of the current IR node.
4045hash_t
4047{return priv_->hash_value_;}
4048
4049void
4050type_or_decl_base::set_hash_value(hash_t h) const
4051{priv_->set_hash_value(h);}
4052
4053/// Getter of the environment of the current ABI artifact.
4054///
4055/// @return the environment of the artifact.
4056const environment&
4058{return priv_->env_;}
4059
4060/// Setter of the artificial location of the artificat.
4061///
4062/// The artificial location is a location that was artificially
4063/// generated by libabigail, not generated by the original emitter of
4064/// the ABI meta-data. For instance, when reading an XML element from
4065/// an abixml file, the artificial location is the source location of
4066/// the XML element within the file, not the value of the
4067/// 'location'property that might be carried by the element.
4068///
4069/// Artificial locations might be useful to ensure that abixml emitted
4070/// by the abixml writer are sorted the same way as the input abixml
4071/// read by the reader.
4072///
4073/// @param l the new artificial location.
4074void
4076{priv_->artificial_location_ = l;}
4077
4078/// Getter of the artificial location of the artifact.
4079///
4080/// The artificial location is a location that was artificially
4081/// generated by libabigail, not generated by the original emitter of
4082/// the ABI meta-data. For instance, when reading an XML element from
4083/// an abixml file, the artificial location is the source location of
4084/// the XML element within the file, not the value of the
4085/// 'location'property that might be carried by the element.
4086///
4087/// Artificial locations might be useful to ensure that the abixml
4088/// emitted by the abixml writer is sorted the same way as the input
4089/// abixml read by the reader.
4090///
4091/// @return the new artificial location.
4092location&
4094{return priv_->artificial_location_;}
4095
4096/// Test if the current ABI artifact carries an artificial location.
4097///
4098/// @return true iff the current ABI artifact carries an artificial location.
4099bool
4101{
4102 return (priv_->artificial_location_
4103 && priv_->artificial_location_.get_is_artificial());
4104}
4105
4106/// Get the @ref corpus this ABI artifact belongs to.
4107///
4108/// @return the corpus this ABI artifact belongs to, or nil if it
4109/// belongs to none for now.
4110corpus*
4112{
4114 if (!tu)
4115 return 0;
4116 return tu->get_corpus();
4117}
4118
4119
4120/// Get the @ref corpus this ABI artifact belongs to.
4121///
4122/// @return the corpus this ABI artifact belongs to, or nil if it
4123/// belongs to none for now.
4124const corpus*
4126{return const_cast<type_or_decl_base*>(this)->get_corpus();}
4127
4128/// Set the @ref translation_unit this ABI artifact belongs to.
4129///
4130/// Note that adding an ABI artifact to a containining on should
4131/// invoke this member function.
4132void
4134{priv_->translation_unit_ = tu;}
4135
4136
4137/// Get the @ref translation_unit this ABI artifact belongs to.
4138///
4139/// @return the translation unit this ABI artifact belongs to, or nil
4140/// if belongs to none for now.
4143{return priv_->translation_unit_;}
4144
4145/// Get the @ref translation_unit this ABI artifact belongs to.
4146///
4147/// @return the translation unit this ABI artifact belongs to, or nil
4148/// if belongs to none for now.
4149const translation_unit*
4152
4153/// Traverse the the ABI artifact.
4154///
4155/// @param v the visitor used to traverse the sub-tree nodes of the
4156/// artifact.
4157bool
4160
4161/// Non-member equality operator for the @type_or_decl_base type.
4162///
4163/// @param lr the left-hand operand of the equality.
4164///
4165/// @param rr the right-hand operatnr of the equality.
4166///
4167/// @return true iff @p lr equals @p rr.
4168bool
4170{
4171 const type_or_decl_base* l = &lr;
4172 const type_or_decl_base* r = &rr;
4173
4174 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4175 *dr = dynamic_cast<const decl_base*>(r);
4176
4177 if (!!dl != !!dr)
4178 return false;
4179
4180 if (dl && dr)
4181 return *dl == *dr;
4182
4183 const type_base* tl = dynamic_cast<const type_base*>(l),
4184 *tr = dynamic_cast<const type_base*>(r);
4185
4186 if (!!tl != !!tr)
4187 return false;
4188
4189 if (tl && tr)
4190 return *tl == *tr;
4191
4192 return false;
4193}
4194
4195/// Non-member equality operator for the @type_or_decl_base type.
4196///
4197/// @param l the left-hand operand of the equality.
4198///
4199/// @param r the right-hand operatnr of the equality.
4200///
4201/// @return true iff @p l equals @p r.
4202bool
4204{
4205 if (!! l != !!r)
4206 return false;
4207
4208 if (!l)
4209 return true;
4210
4211 return *r == *l;
4212}
4213
4214/// Non-member inequality operator for the @type_or_decl_base type.
4215///
4216/// @param l the left-hand operand of the equality.
4217///
4218/// @param r the right-hand operator of the equality.
4219///
4220/// @return true iff @p l is different from @p r.
4221bool
4224
4225// </type_or_decl_base stuff>
4226
4227// <Decl definition>
4228
4229struct decl_base::priv
4230{
4231 bool in_pub_sym_tab_;
4232 bool is_anonymous_;
4233 location location_;
4234 context_rel *context_;
4235 interned_string name_;
4236 interned_string qualified_parent_name_;
4237 // This temporary qualified name is the cache used for the qualified
4238 // name before the type associated to this decl (if applicable) is
4239 // canonicalized. Once the type is canonicalized, the cached use is
4240 // the data member qualified_parent_name_ above.
4241 interned_string temporary_qualified_name_;
4242 // This is the fully qualified name of the decl. It contains the
4243 // name of the decl and the qualified name of its scope. So if in
4244 // the parent scopes of the decl, there is one anonymous struct,
4245 // somewhere in the name, there is going to by an
4246 // __anonymous_struct__ string, even if the anonymous struct is not
4247 // the direct containing scope of this decl.
4248 interned_string qualified_name_;
4249 interned_string temporary_internal_qualified_name_;
4250 interned_string internal_qualified_name_;
4251 interned_string internal_cached_repr_;
4252 interned_string cached_repr_;
4253 // Unline qualified_name_, scoped_name_ contains the name of the
4254 // decl and the name of its scope; not the qualified name of the
4255 // scope.
4256 interned_string scoped_name_;
4257 interned_string linkage_name_;
4258 visibility visibility_;
4259 decl_base_sptr declaration_;
4260 decl_base_wptr definition_of_declaration_;
4261 decl_base* naked_definition_of_declaration_;
4262 bool is_declaration_only_;
4263 typedef_decl_sptr naming_typedef_;
4264
4265 priv()
4266 : in_pub_sym_tab_(false),
4267 is_anonymous_(true),
4268 context_(),
4269 visibility_(VISIBILITY_DEFAULT),
4270 naked_definition_of_declaration_(),
4271 is_declaration_only_(false)
4272 {}
4273
4274 priv(interned_string name, interned_string linkage_name, visibility vis)
4275 : in_pub_sym_tab_(false),
4276 context_(),
4277 name_(name),
4278 qualified_name_(name),
4279 linkage_name_(linkage_name),
4280 visibility_(vis),
4281 naked_definition_of_declaration_(),
4282 is_declaration_only_(false)
4283 {
4284 is_anonymous_ = name_.empty();
4285 }
4286
4287 ~priv()
4288 {
4289 delete context_;
4290 }
4291};// end struct decl_base::priv
4292
4293/// Constructor for the @ref decl_base type.
4294///
4295/// @param e the environment the current @ref decl_base is being
4296/// created in.
4297///
4298/// @param name the name of the declaration.
4299///
4300/// @param locus the location where to find the declaration in the
4301/// source code.
4302///
4303/// @param linkage_name the linkage name of the declaration.
4304///
4305/// @param vis the visibility of the declaration.
4306decl_base::decl_base(const environment& e,
4307 const string& name,
4308 const location& locus,
4309 const string& linkage_name,
4310 visibility vis)
4311 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4312 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4313{
4314 set_location(locus);
4315}
4316
4317/// Constructor.
4318///
4319/// @param e the environment this instance of @ref decl_base is
4320/// created in.
4321///
4322/// @param name the name of the declaration being constructed.
4323///
4324/// @param locus the source location of the declaration being constructed.
4325///
4326/// @param linkage_name the linkage name of the declaration being
4327/// constructed.
4328///
4329/// @param vis the visibility of the declaration being constructed.
4330decl_base::decl_base(const environment& e,
4331 const interned_string& name,
4332 const location& locus,
4333 const interned_string& linkage_name,
4334 visibility vis)
4335 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4336 priv_(new priv(name, linkage_name, vis))
4337{
4338 set_location(locus);
4339}
4340
4341/// Constructor for the @ref decl_base type.
4342///
4343///@param environment the environment this instance of @ref decl_base
4344/// is being constructed in.
4345///
4346/// @param l the location where to find the declaration in the source
4347/// code.
4348decl_base::decl_base(const environment& e, const location& l)
4349 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4350 priv_(new priv())
4351{
4352 set_location(l);
4353}
4354
4355/// Getter for the qualified name.
4356///
4357/// Unlike decl_base::get_qualified_name() this doesn't try to update
4358/// the qualified name.
4359///
4360/// @return the qualified name.
4361const interned_string&
4363{return priv_->qualified_name_;}
4364
4365/// Clear the qualified name of this decl.
4366///
4367/// This is useful to ensure that the cache for the qualified name of
4368/// the decl is refreshed right after type canonicalization, for
4369/// instance.
4370void
4372{priv_->qualified_name_.clear();}
4373
4374/// Setter for the qualified name.
4375///
4376/// @param n the new qualified name.
4377void
4379{priv_->qualified_name_ = n;}
4380
4381/// Getter of the temporary qualified name of the current declaration.
4382///
4383/// This temporary qualified name is used as a qualified name cache by
4384/// the type for which this is the declaration (when applicable)
4385/// before the type is canonicalized. Once the type is canonicalized,
4386/// it's the result of decl_base::peek_qualified_name() that becomes
4387/// the qualified name cached.
4388///
4389/// @return the temporary qualified name.
4390const interned_string&
4392{return priv_->temporary_qualified_name_;}
4393
4394/// Setter for the temporary qualified name of the current
4395/// declaration.
4396///
4397///@param n the new temporary qualified name.
4398///
4399/// This temporary qualified name is used as a qualified name cache by
4400/// the type for which this is the declaration (when applicable)
4401/// before the type is canonicalized. Once the type is canonicalized,
4402/// it's the result of decl_base::peek_qualified_name() that becomes
4403/// the qualified name cached.
4404void
4406{priv_->temporary_qualified_name_ = n;}
4407
4408///Getter for the context relationship.
4409///
4410///@return the context relationship for the current decl_base.
4411const context_rel*
4413{return priv_->context_;}
4414
4415///Getter for the context relationship.
4416///
4417///@return the context relationship for the current decl_base.
4420{return priv_->context_;}
4421
4422void
4423decl_base::set_context_rel(context_rel *c)
4424{priv_->context_ = c;}
4425
4426/// Test if the decl is defined in a ELF symbol table as a public
4427/// symbol.
4428///
4429/// @return true iff the decl is defined in a ELF symbol table as a
4430/// public symbol.
4431bool
4433{return priv_->in_pub_sym_tab_;}
4434
4435/// Set the flag saying if this decl is from a symbol that is in
4436/// a public symbols table, defined as public (global or weak).
4437///
4438/// @param f the new flag value.
4439void
4441{priv_->in_pub_sym_tab_ = f;}
4442
4443/// Get the location of a given declaration.
4444///
4445/// The location is an abstraction for the tripplet {file path,
4446/// line, column} that defines where the declaration appeared in the
4447/// source code.
4448///
4449/// To get the value of the tripplet {file path, line, column} from
4450/// the @ref location, you need to use the
4451/// location_manager::expand_location() method.
4452///
4453/// The instance of @ref location_manager that you want is
4454/// accessible from the instance of @ref translation_unit that the
4455/// current instance of @ref decl_base belongs to, via a call to
4456/// translation_unit::get_loc_mgr().
4457///
4458/// @return the location of the current instance of @ref decl_base.
4459const location&
4461{return priv_->location_;}
4462
4463/// Set the location for a given declaration.
4464///
4465/// The location is an abstraction for the tripplet {file path,
4466/// line, column} that defines where the declaration appeared in the
4467/// source code.
4468///
4469/// To create a location from a tripplet {file path, line, column},
4470/// you need to use the method @ref
4471/// location_manager::create_new_location().
4472///
4473/// Note that there can be two kinds of location. An artificial
4474/// location and a non-artificial one. The non-artificial location is
4475/// the one emitted by the original emitter of the ABI artifact, for
4476/// instance, if the ABI artifact comes from debug info, then the
4477/// source location that is present in the debug info represent a
4478/// non-artificial location. When looking at an abixml file on the
4479/// other hand, the value of the 'location' attribute of an XML
4480/// element describing an artifact is the non-artificial location.
4481/// The artificial location is the location (line number from the
4482/// beginning of the file) of the XML element within the abixml file.
4483///
4484/// So, if the location that is being set is artificial, note that the
4485/// type_or_decl_base::has_artificial_location() method of this decl will
4486/// subsequently return true and that artificial location will have to
4487/// be retrieved using type_or_decl_base::get_artificial_location().
4488/// If the location is non-artificial however,
4489/// type_or_decl_base::has_artificial_location() will subsequently
4490/// return false and the non-artificial location will have to be
4491/// retrieved using decl_base::get_location().
4492///
4493/// The instance of @ref location_manager that you want is
4494/// accessible from the instance of @ref translation_unit that the
4495/// current instance of @ref decl_base belongs to, via a call to
4496/// translation_unit::get_loc_mgr().
4497void
4499{
4500 if (l.get_is_artificial())
4502 else
4503 priv_->location_ = l;
4504}
4505
4506/// Setter for the name of the decl.
4507///
4508/// @param n the new name to set.
4509void
4510decl_base::set_name(const string& n)
4511{
4512 priv_->name_ = get_environment().intern(n);
4513 priv_->is_anonymous_ = n.empty();
4514}
4515
4516/// Test if the current declaration is anonymous.
4517///
4518/// Being anonymous means that the declaration was created without a
4519/// name. This can usually happen for enum or struct types.
4520///
4521/// @return true iff the type is anonymous.
4522bool
4524{return priv_->is_anonymous_;}
4525
4526/// Set the "is_anonymous" flag of the current declaration.
4527///
4528/// Being anonymous means that the declaration was created without a
4529/// name. This can usually happen for enum or struct types.
4530///
4531/// @param f the new value of the flag.
4532void
4534{priv_->is_anonymous_ = f;}
4535
4536
4537/// Get the "has_anonymous_parent" flag of the current declaration.
4538///
4539/// Having an anoymous parent means having a anonymous parent scope
4540/// (containing type or namespace) which is either direct or indirect.
4541///
4542/// @return true iff the current decl has a direct or indirect scope
4543/// which is anonymous.
4544bool
4546{
4547 scope_decl *scope = get_scope();
4548 if (!scope)
4549 return false;
4550 return scope->get_is_anonymous();
4551}
4552
4553/// @return the logical "OR" of decl_base::get_is_anonymous() and
4554/// decl_base::get_has_anonymous_parent().
4555bool
4558
4559/// Getter for the naming typedef of the current decl.
4560///
4561/// Consider the C idiom:
4562///
4563/// typedef struct {int member;} foo_type;
4564///
4565/// In that idiom, foo_type is the naming typedef of the anonymous
4566/// struct that is declared.
4567///
4568/// @return the naming typedef, if any. Otherwise, returns nil.
4571{return priv_->naming_typedef_;}
4572
4573/// Set the naming typedef of the current instance of @ref decl_base.
4574///
4575/// Consider the C idiom:
4576///
4577/// typedef struct {int member;} foo_type;
4578///
4579/// In that idiom, foo_type is the naming typedef of the anonymous
4580/// struct that is declared.
4581///
4582/// After completion of this function, the decl will not be considered
4583/// anonymous anymore. It's name is going to be the name of the
4584/// naming typedef.
4585///
4586/// @param typedef_type the new naming typedef.
4587void
4589{
4590 // A naming typedef is usually for an anonymous type.
4592 // Whe the typedef-named decl is saved into abixml, it's
4593 // not anonymous anymore. Its name is the typedef name.
4594 // So when we read it back, we must still be able to
4595 // apply the naming typedef to the decl.
4596 || t->get_name() == get_name());
4597 // Only non canonicalized types can be edited this way.
4598 ABG_ASSERT(is_type(this)
4599 && is_type(this)->get_naked_canonical_type() == nullptr);
4600
4601 priv_->naming_typedef_ = t;
4602 set_name(t->get_name());
4603 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4604 set_qualified_name(get_environment().intern(qualified_name));
4605 set_is_anonymous(false);
4606 // Now that the qualified type of the decl has changed, let's update
4607 // the qualified names of the member types of this decls.
4608 update_qualified_name(this);
4609}
4610
4611/// Getter for the mangled name.
4612///
4613/// @return the new mangled name.
4614const interned_string&
4616{return priv_->linkage_name_;}
4617
4618/// Setter for the linkage name.
4619///
4620/// @param m the new linkage name.
4621void
4623{
4624 const environment& env = get_environment();
4625 priv_->linkage_name_ = env.intern(m);
4626}
4627
4628/// Getter for the visibility of the decl.
4629///
4630/// @return the new visibility.
4633{return priv_->visibility_;}
4634
4635/// Setter for the visibility of the decl.
4636///
4637/// @param v the new visibility.
4638void
4640{priv_->visibility_ = v;}
4641
4642/// Return the type containing the current decl, if any.
4643///
4644/// @return the type that contains the current decl, or NULL if there
4645/// is none.
4648{
4649 if (priv_->context_)
4650 return priv_->context_->get_scope();
4651 return 0;
4652}
4653
4654/// Return a copy of the qualified name of the parent of the current
4655/// decl.
4656///
4657/// @return the newly-built qualified name of the of the current decl.
4658const interned_string&
4660{return priv_->qualified_parent_name_;}
4661
4662/// Getter for the name of the current decl.
4663///
4664/// @return the name of the current decl.
4665const interned_string&
4667{return priv_->name_;}
4668
4669/// Compute the qualified name of the decl.
4670///
4671/// @param qn the resulting qualified name.
4672///
4673/// @param internal set to true if the call is intended for an
4674/// internal use (for technical use inside the library itself), false
4675/// otherwise. If you don't know what this is for, then set it to
4676/// false.
4677void
4679{qn = get_qualified_name(internal);}
4680
4681/// Get the pretty representatin of the current declaration.
4682///
4683///
4684/// @param internal set to true if the call is intended to get a
4685/// representation of the decl (or type) for the purpose of canonical
4686/// type comparison. This is mainly used in the function
4687/// type_base::get_canonical_type_for().
4688///
4689/// In other words if the argument for this parameter is true then the
4690/// call is meant for internal use (for technical use inside the
4691/// library itself), false otherwise. If you don't know what this is
4692/// for, then set it to false.
4693///
4694/// @param qualified_name if true, names emitted in the pretty
4695/// representation are fully qualified.
4696///
4697/// @return the default pretty representation for a decl. This is
4698/// basically the fully qualified name of the decl optionally prefixed
4699/// with a meaningful string to add context for the user.
4700string
4702 bool qualified_name) const
4703{
4704 if (internal
4705 && get_is_anonymous()
4706 && has_generic_anonymous_internal_type_name(this))
4707 {
4708 // We are looking at an anonymous enum, union or class and we
4709 // want an *internal* pretty representation for it. All
4710 // anonymous types of this kind in the same namespace must have
4711 // the same internal representation for type canonicalization to
4712 // work properly.
4713 //
4714 // OK, in practise, we are certainly looking at an enum because
4715 // classes and unions should have their own overloaded virtual
4716 // member function for this.
4717 string name = get_generic_anonymous_internal_type_name(this);
4718 if (qualified_name && !get_qualified_parent_name().empty())
4719 name = get_qualified_parent_name() + "::" + name;
4720 return name;
4721 }
4722
4723 if (qualified_name)
4724 return get_qualified_name(internal);
4725 return get_name();
4726}
4727
4728/// Get the pretty representation of the current decl.
4729///
4730/// The pretty representation is retrieved from a cache. If the cache
4731/// is empty, this function computes the pretty representation, put it
4732/// in the cache and returns it.
4733///
4734/// Please note that if this function is called too early in the life
4735/// cycle of the decl (before it is fully constructed), then the
4736/// pretty representation that is cached is going to represent a
4737/// non-complete (and thus wrong) representation of the decl. Thus
4738/// this function must be called only once the decl is fully
4739/// constructed.
4740///
4741/// @param internal if true, then the pretty representation is to be
4742/// used for purpuses that are internal to the libabigail library
4743/// itself. If you don't know what this means, then you probably
4744/// should set this parameter to "false".
4745///
4746/// @return a reference to a cached @ref interned_string holding the
4747/// pretty representation of the current decl.
4748const interned_string&
4750{
4751 if (internal)
4752 {
4753 if (priv_->internal_cached_repr_.empty())
4754 {
4755 string r = ir::get_pretty_representation(this, internal);
4756 priv_->internal_cached_repr_ = get_environment().intern(r);
4757 }
4758 return priv_->internal_cached_repr_;
4759 }
4760
4761 if (priv_->cached_repr_.empty())
4762 {
4763 string r = ir::get_pretty_representation(this, internal);
4764 priv_->cached_repr_ = get_environment().intern(r);
4765 }
4766
4767 return priv_->cached_repr_;
4768}
4769
4770/// Return the qualified name of the decl.
4771///
4772/// This is the fully qualified name of the decl. It's made of the
4773/// concatenation of the name of the decl with the qualified name of
4774/// its scope.
4775///
4776/// Note that the value returned by this function is computed by @ref
4777/// update_qualified_name when the decl is added to its scope.
4778///
4779/// @param internal set to true if the call is intended for an
4780/// internal use (for technical use inside the library itself), false
4781/// otherwise. If you don't know what this is for, then set it to
4782/// false.
4783///
4784/// @return the resulting qualified name.
4785const interned_string&
4786decl_base::get_qualified_name(bool /*internal*/) const
4787{return priv_->qualified_name_;}
4788
4789/// Return the scoped name of the decl.
4790///
4791/// This is made of the concatenation of the name of the decl with the
4792/// name of its scope. It doesn't contain the qualified name of its
4793/// scope, unlike what is returned by decl_base::get_qualified_name.
4794///
4795/// Note that the value returned by this function is computed by @ref
4796/// update_qualified_name when the decl is added to its scope.
4797///
4798/// @return the scoped name of the decl.
4799const interned_string&
4801{return priv_->scoped_name_;}
4802
4803/// If this @ref decl_base is a definition, get its earlier
4804/// declaration.
4805///
4806/// @return the earlier declaration of the class, if any.
4807const decl_base_sptr
4809{return priv_->declaration_;}
4810
4811/// set the earlier declaration of this @ref decl_base definition.
4812///
4813/// @param d the earlier declaration to set. Note that it's set only
4814/// if it's a pure declaration.
4815void
4817{
4818 if (d && d->get_is_declaration_only())
4819 priv_->declaration_ = d;
4820}
4821
4822
4823/// If this @ref decl_base is declaration-only, get its definition, if
4824/// any.
4825///
4826/// @return the definition of this decl-only @ref decl_base.
4827const decl_base_sptr
4829{return priv_->definition_of_declaration_.lock();}
4830
4831/// If this @ref decl_base is declaration-only, get its definition,
4832/// if any.
4833///
4834/// Note that this function doesn't return a smart pointer, but rather
4835/// the underlying pointer managed by the smart pointer. So it's as
4836/// fast as possible. This getter is to be used in code paths that
4837/// are proven to be performance hot spots; especially, when comparing
4838/// sensitive types like enums, classes or unions. Those are compared
4839/// extremely frequently and thus, their access to the definition of
4840/// declaration must be fast.
4841///
4842/// @return the definition of the declaration.
4843const decl_base*
4845{return priv_->naked_definition_of_declaration_;}
4846
4847/// Test if a @ref decl_base is a declaration-only decl.
4848///
4849/// @return true iff the current @ref decl_base is declaration-only.
4850bool
4852{return priv_->is_declaration_only_;}
4853
4854/// Set a flag saying if the @ref enum_type_decl is a declaration-only
4855/// @ref enum_type_decl.
4856///
4857/// @param f true if the @ref enum_type_decl is a declaration-only
4858/// @ref enum_type_decl.
4859void
4861{
4862 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
4863
4864 priv_->is_declaration_only_ = f;
4865
4866 if (update_types_lookup_map)
4867 if (scope_decl* s = get_scope())
4868 {
4869 scope_decl::declarations::iterator i;
4870 if (s->find_iterator_for_member(this, i))
4872 else
4874 }
4875}
4876
4879{
4880 return static_cast<change_kind>(static_cast<unsigned>(l)
4881 | static_cast<unsigned>(r));
4882}
4883
4886{
4887 return static_cast<change_kind>(static_cast<unsigned>(l)
4888 & static_cast<unsigned>(r));
4889}
4890
4891change_kind&
4892operator|=(change_kind& l, change_kind r)
4893{
4894 l = l | r;
4895 return l;
4896}
4897
4898change_kind&
4899operator&=(change_kind& l, change_kind r)
4900{
4901 l = l & r;
4902 return l;
4903}
4904
4905/// Compare the properties that belong to the "is-a-member-relation"
4906/// of a decl.
4907///
4908/// For instance, access specifiers are part of the
4909/// "is-a-member-relation" of a decl.
4910///
4911/// This comparison however doesn't take decl names into account. So
4912/// typedefs for instance are decls that we want to compare with this
4913/// function.
4914///
4915/// This function is a sub-routine of the more general 'equals'
4916/// overload for instances of decl_base.
4917///
4918/// @param l the left-hand side operand of the comparison.
4919///
4920/// @param r the right-hand side operand of the comparison.
4921///
4922/// @return true iff @p l compare equals, as a member decl, to @p r.
4923bool
4925 const decl_base& r,
4926 change_kind* k)
4927{
4928 bool result = true;
4929 if (is_member_decl(l) && is_member_decl(r))
4930 {
4931 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
4932 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
4933
4934 access_specifier la = no_access, ra = no_access;
4935 bool member_types_or_functions =
4936 ((is_type(l) && is_type(r))
4937 || (is_function_decl(l) && is_function_decl(r)));
4938
4939 if (member_types_or_functions)
4940 {
4941 // Access specifiers on member types in DWARF is not
4942 // reliable; in the same DSO, the same struct can be either
4943 // a class or a struct, and the access specifiers of its
4944 // member types are not necessarily given, so they
4945 // effectively can be considered differently, again, in the
4946 // same DSO. So, here, let's avoid considering those!
4947 // during comparison.
4948 la = r1->get_access_specifier();
4949 ra = r2->get_access_specifier();
4950 r1->set_access_specifier(no_access);
4951 r2->set_access_specifier(no_access);
4952 }
4953
4954 bool rels_are_different = *r1 != *r2;
4955
4956 if (member_types_or_functions)
4957 {
4958 // restore the access specifiers.
4959 r1->set_access_specifier(la);
4960 r2->set_access_specifier(ra);
4961 }
4962
4963 if (rels_are_different)
4964 {
4965 result = false;
4966 if (k)
4968 }
4969 }
4970 ABG_RETURN(result);
4971}
4972
4973/// Compares two instances of @ref decl_base.
4974///
4975/// If the two intances are different, set a bitfield to give some
4976/// insight about the kind of differences there are.
4977///
4978/// @param l the first artifact of the comparison.
4979///
4980/// @param r the second artifact of the comparison.
4981///
4982/// @param k a pointer to a bitfield that gives information about the
4983/// kind of changes there are between @p l and @p r. This one is set
4984/// iff it's non-null and if the function returns false.
4985///
4986/// Please note that setting k to a non-null value does have a
4987/// negative performance impact because even if @p l and @p r are not
4988/// equal, the function keeps up the comparison in order to determine
4989/// the different kinds of ways in which they are different.
4990///
4991/// @return true if @p l equals @p r, false otherwise.
4992bool
4993equals(const decl_base& l, const decl_base& r, change_kind* k)
4994{
4995 bool result = true;
4996 const interned_string &l_linkage_name = l.get_linkage_name();
4997 const interned_string &r_linkage_name = r.get_linkage_name();
4998 if (!l_linkage_name.empty() && !r_linkage_name.empty())
4999 {
5000 if (l_linkage_name != r_linkage_name)
5001 {
5002 // Linkage names are different. That usually means the two
5003 // decls are different, unless we are looking at two
5004 // function declarations which have two different symbols
5005 // that are aliases of each other.
5006 const function_decl *f1 = is_function_decl(&l),
5007 *f2 = is_function_decl(&r);
5008 if (f1 && f2 && function_decls_alias(*f1, *f2))
5009 ;// The two functions are aliases, so they are not
5010 // different.
5011 else
5012 {
5013 result = false;
5014 if (k)
5016 else
5018 }
5019 }
5020 }
5021
5022 if (r.get_is_anonymous() && l.get_is_anonymous())
5023 // We are looking at too anonymous types (or two members of
5024 // anonymous types) with one not yet been added to the IR. That
5025 // means we want to compare just the object part of the
5026 // anonymous type and not their qualified names. This is used
5027 // when looking up an anonymous type inside a class type.
5028 ABG_RETURN(result);
5029
5030 // This is the name of the decls that we want to compare.
5031 interned_string ln = l.get_name(), rn = r.get_name();
5032
5033 /// If both of the current decls have an anonymous scope then let's
5034 /// compare their name component by component by properly handling
5035 /// anonymous scopes. That's the slow path.
5036 ///
5037 /// Otherwise, let's just compare their name, the obvious way.
5038 /// That's the fast path because in that case the names are
5039 /// interned_string and comparing them is much faster.
5040 bool decls_are_same = (ln == rn);
5041
5042 if (!decls_are_same)
5043 {
5044 result = false;
5045 if (k)
5047 else
5049 }
5050
5051 result &= maybe_compare_as_member_decls(l, r, k);
5052
5053 ABG_RETURN(result);
5054}
5055
5056/// Return true iff the two decls have the same name.
5057///
5058/// This function doesn't test if the scopes of the the two decls are
5059/// equal.
5060///
5061/// Note that this virtual function is to be implemented by classes
5062/// that extend the \p decl_base class.
5063bool
5065{return equals(*this, other, 0);}
5066
5067/// Inequality operator.
5068///
5069/// @param other to other instance of @ref decl_base to compare the
5070/// current instance to.
5071///
5072/// @return true iff the current instance of @ref decl_base is
5073/// different from @p other.
5074bool
5076{return !operator==(other);}
5077
5078/// Destructor of the @ref decl_base type.
5080{delete priv_;}
5081
5082/// This implements the ir_traversable_base::traverse pure virtual
5083/// function.
5084///
5085/// @param v the visitor used on the member nodes of the translation
5086/// unit during the traversal.
5087///
5088/// @return true if the entire IR node tree got traversed, false
5089/// otherwise.
5090bool
5092{
5093 // Do nothing in the base class.
5094 return true;
5095}
5096
5097/// Setter of the scope of the current decl.
5098///
5099/// Note that the decl won't hold a reference on the scope. It's
5100/// rather the scope that holds a reference on its members.
5101void
5103{
5104 if (!priv_->context_)
5105 priv_->context_ = new context_rel(scope);
5106 else
5107 priv_->context_->set_scope(scope);
5108}
5109
5110// </decl_base definition>
5111
5112/// Streaming operator for the decl_base::visibility.
5113///
5114/// @param o the output stream to serialize the visibility to.
5115///
5116/// @param v the visibility to serialize.
5117///
5118/// @return the output stream.
5119std::ostream&
5120operator<<(std::ostream& o, decl_base::visibility v)
5121{
5122 string r;
5123 switch (v)
5124 {
5125 case decl_base::VISIBILITY_NONE:
5126 r = "none";
5127 break;
5128 case decl_base::VISIBILITY_DEFAULT:
5129 r = "default";
5130 break;
5131 case decl_base::VISIBILITY_PROTECTED:
5132 r = "protected";
5133 break;
5134 case decl_base::VISIBILITY_HIDDEN:
5135 r = "hidden";
5136 break;
5137 case decl_base::VISIBILITY_INTERNAL:
5138 r = "internal";
5139 break;
5140 }
5141 return o;
5142}
5143
5144/// Streaming operator for decl_base::binding.
5145///
5146/// @param o the output stream to serialize the visibility to.
5147///
5148/// @param b the binding to serialize.
5149///
5150/// @return the output stream.
5151std::ostream&
5152operator<<(std::ostream& o, decl_base::binding b)
5153{
5154 string r;
5155 switch (b)
5156 {
5157 case decl_base::BINDING_NONE:
5158 r = "none";
5159 break;
5160 case decl_base::BINDING_LOCAL:
5161 r = "local";
5162 break;
5163 case decl_base::BINDING_GLOBAL:
5164 r = "global";
5165 break;
5166 case decl_base::BINDING_WEAK:
5167 r = "weak";
5168 break;
5169 }
5170 o << r;
5171 return o;
5172}
5173
5174/// Turn equality of shared_ptr of decl_base into a deep equality;
5175/// that is, make it compare the pointed to objects, not just the
5176/// pointers.
5177///
5178/// @param l the shared_ptr of decl_base on left-hand-side of the
5179/// equality.
5180///
5181/// @param r the shared_ptr of decl_base on right-hand-side of the
5182/// equality.
5183///
5184/// @return true if the decl_base pointed to by the shared_ptrs are
5185/// equal, false otherwise.
5186bool
5187operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5188{
5189 if (l.get() == r.get())
5190 return true;
5191 if (!!l != !!r)
5192 return false;
5193
5194 return *l == *r;
5195}
5196
5197/// Inequality operator of shared_ptr of @ref decl_base.
5198///
5199/// This is a deep equality operator, that is, it compares the
5200/// pointed-to objects, rather than just the pointers.
5201///
5202/// @param l the left-hand-side operand.
5203///
5204/// @param r the right-hand-side operand.
5205///
5206/// @return true iff @p l is different from @p r.
5207bool
5208operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5209{return !operator==(l, r);}
5210
5211/// Turn equality of shared_ptr of type_base into a deep equality;
5212/// that is, make it compare the pointed to objects too.
5213///
5214/// @param l the shared_ptr of type_base on left-hand-side of the
5215/// equality.
5216///
5217/// @param r the shared_ptr of type_base on right-hand-side of the
5218/// equality.
5219///
5220/// @return true if the type_base pointed to by the shared_ptrs are
5221/// equal, false otherwise.
5222bool
5223operator==(const type_base_sptr& l, const type_base_sptr& r)
5224{
5225 if (l.get() == r.get())
5226 return true;
5227 if (!!l != !!r)
5228 return false;
5229
5230 return *l == *r;
5231}
5232
5233/// Turn inequality of shared_ptr of type_base into a deep equality;
5234/// that is, make it compare the pointed to objects..
5235///
5236/// @param l the shared_ptr of type_base on left-hand-side of the
5237/// equality.
5238///
5239/// @param r the shared_ptr of type_base on right-hand-side of the
5240/// equality.
5241///
5242/// @return true iff the type_base pointed to by the shared_ptrs are
5243/// different.
5244bool
5245operator!=(const type_base_sptr& l, const type_base_sptr& r)
5246{return !operator==(l, r);}
5247
5248/// Tests if a declaration has got a scope.
5249///
5250/// @param d the declaration to consider.
5251///
5252/// @return true if the declaration has got a scope, false otherwise.
5253bool
5255{return (d.get_scope());}
5256
5257/// Tests if a declaration has got a scope.
5258///
5259/// @param d the declaration to consider.
5260///
5261/// @return true if the declaration has got a scope, false otherwise.
5262bool
5263has_scope(const decl_base_sptr d)
5264{return has_scope(*d.get());}
5265
5266/// Tests if a declaration is a class member.
5267///
5268/// @param d the declaration to consider.
5269///
5270/// @return true if @p d is a class member, false otherwise.
5271bool
5272is_member_decl(const decl_base_sptr d)
5273{return is_at_class_scope(d) || is_method_decl(d);}
5274
5275/// Tests if a declaration is a class member.
5276///
5277/// @param d the declaration to consider.
5278///
5279/// @return true if @p d is a class member, false otherwise.
5280bool
5283
5284/// Tests if a declaration is a class member.
5285///
5286/// @param d the declaration to consider.
5287///
5288/// @return true if @p d is a class member, false otherwise.
5289bool
5292
5293/// Test if a declaration is a @ref scope_decl.
5294///
5295/// @param d the declaration to take in account.
5296///
5297/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5298/// if d is a @ref scope_decl.
5299const scope_decl*
5301{return dynamic_cast<const scope_decl*>(d);}
5302
5303/// Test if a declaration is a @ref scope_decl.
5304///
5305/// @param d the declaration to take in account.
5306///
5307/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5308/// if d is a @ref scope_decl.
5310is_scope_decl(const decl_base_sptr& d)
5311{return dynamic_pointer_cast<scope_decl>(d);}
5312
5313/// Tests if a type is a class member.
5314///
5315/// @param t the type to consider.
5316///
5317/// @return true if @p t is a class member type, false otherwise.
5318bool
5319is_member_type(const type_base_sptr& t)
5320{
5321 decl_base_sptr d = get_type_declaration(t);
5322 return is_member_decl(d);
5323}
5324
5325/// Test if a type is user-defined.
5326///
5327/// A type is considered user-defined if it's a
5328/// struct/class/union/enum that is *NOT* artificial.
5329///
5330/// @param t the type to consider.
5331///
5332/// @return true iff the type @p t is user-defined.
5333bool
5335{
5336 if (t == 0)
5337 return false;
5338
5340 decl_base *d = is_decl(t);
5341
5343 && d && !d->get_is_artificial())
5344 return true;
5345
5346 return false;
5347}
5348
5349/// Test if a type is user-defined.
5350///
5351/// A type is considered user-defined if it's a
5352/// struct/class/union/enum.
5353///
5354///
5355/// @param t the type to consider.
5356///
5357/// @return true iff the type @p t is user-defined.
5358bool
5359is_user_defined_type(const type_base_sptr& t)
5360{return is_user_defined_type(t.get());}
5361
5362/// Gets the access specifier for a class member.
5363///
5364/// @param d the declaration of the class member to consider. Note
5365/// that this must be a class member otherwise the function aborts the
5366/// current process.
5367///
5368/// @return the access specifier for the class member @p d.
5371{
5373
5374 const context_rel* c = d.get_context_rel();
5375 ABG_ASSERT(c);
5376
5377 return c->get_access_specifier();
5378}
5379
5380/// Gets the access specifier for a class member.
5381///
5382/// @param d the declaration of the class member to consider. Note
5383/// that this must be a class member otherwise the function aborts the
5384/// current process.
5385///
5386/// @return the access specifier for the class member @p d.
5388get_member_access_specifier(const decl_base_sptr& d)
5389{return get_member_access_specifier(*d);}
5390
5391/// Sets the access specifier for a class member.
5392///
5393/// @param d the class member to set the access specifier for. Note
5394/// that this must be a class member otherwise the function aborts the
5395/// current process.
5396///
5397/// @param a the new access specifier to set the class member to.
5398void
5401{
5403
5405 ABG_ASSERT(c);
5406
5407 c->set_access_specifier(a);
5408}
5409
5410/// Sets the access specifier for a class member.
5411///
5412/// @param d the class member to set the access specifier for. Note
5413/// that this must be a class member otherwise the function aborts the
5414/// current process.
5415///
5416/// @param a the new access specifier to set the class member to.
5417void
5418set_member_access_specifier(const decl_base_sptr& d,
5421
5422/// Gets a flag saying if a class member is static or not.
5423///
5424/// @param d the declaration for the class member to consider. Note
5425/// that this must be a class member otherwise the function aborts the
5426/// current process.
5427///
5428/// @return true if the class member @p d is static, false otherwise.
5429bool
5431{
5433
5434 const context_rel* c = d.get_context_rel();
5435 ABG_ASSERT(c);
5436
5437 return c->get_is_static();
5438}
5439
5440/// Gets a flag saying if a class member is static or not.
5441///
5442/// @param d the declaration for the class member to consider. Note
5443/// that this must be a class member otherwise the function aborts the
5444/// current process.
5445///
5446/// @return true if the class member @p d is static, false otherwise.
5447bool
5450
5451/// Gets a flag saying if a class member is static or not.
5452///
5453/// @param d the declaration for the class member to consider. Note
5454/// that this must be a class member otherwise the function aborts the
5455/// current process.
5456///
5457/// @return true if the class member @p d is static, false otherwise.
5458bool
5459get_member_is_static(const decl_base_sptr& d)
5460{return get_member_is_static(*d);}
5461
5462/// Test if a var_decl is a data member.
5463///
5464/// @param v the var_decl to consider.
5465///
5466/// @return true if @p v is data member, false otherwise.
5467bool
5469{return is_at_class_scope(v);}
5470
5471/// Test if a var_decl is a data member.
5472///
5473/// @param v the var_decl to consider.
5474///
5475/// @return true if @p v is data member, false otherwise.
5476bool
5478{return is_data_member(*v);}
5479
5480/// Test if a var_decl is a data member.
5481///
5482/// @param v the var_decl to consider.
5483///
5484/// @return true if @p v is data member, false otherwise.
5485bool
5488
5489/// Test if a decl is a data member.
5490///
5491/// @param d the decl to consider.
5492///
5493/// @return a pointer to the data member iff @p d is a data member, or
5494/// a null pointer.
5496is_data_member(const decl_base_sptr& d)
5497{
5498 if (var_decl_sptr v = is_var_decl(d))
5499 {
5500 if (is_data_member(v))
5501 return v;
5502 }
5503 return var_decl_sptr();
5504}
5505
5506/// Test if a decl is a data member.
5507///
5508/// @param d the decl to consider.
5509///
5510/// @return a pointer to the data member iff @p d is a data member, or
5511/// a null pointer.
5514{
5515 if (var_decl_sptr v = is_var_decl(d))
5516 {
5517 if (is_data_member(v))
5518 return v;
5519 }
5520 return var_decl_sptr();
5521}
5522
5523/// Test if a decl is a data member.
5524///
5525/// @param d the decl to consider.
5526///
5527/// @return a pointer to the data member iff @p d is a data member, or
5528/// a null pointer.
5529var_decl*
5531{
5532 if (var_decl *v = is_var_decl(d))
5533 if (is_data_member(v))
5534 return v;
5535 return 0;
5536}
5537
5538/// Test if a decl is a data member.
5539///
5540/// @param d the decl to consider.
5541///
5542/// @return a pointer to the data member iff @p d is a data member, or
5543/// a null pointer.
5544var_decl*
5546{
5547 if (var_decl *v = is_var_decl(d))
5548 if (is_data_member(v))
5549 return v;
5550 return 0;
5551}
5552
5553/// Get the first non-anonymous data member of a given anonymous data
5554/// member.
5555///
5556/// E.g:
5557///
5558/// struct S
5559/// {
5560/// union // <-- for this anonymous data member, the function
5561/// // returns a.
5562/// {
5563/// int a;
5564/// charb;
5565/// };
5566/// };
5567///
5568/// @return anon_dm the anonymous data member to consider.
5569///
5570/// @return the first non-anonymous data member of @p anon_dm. If no
5571/// data member was found then this function returns @p anon_dm.
5572const var_decl_sptr
5574{
5575 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5576 return anon_dm;
5577
5578 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5579 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5580
5581 if (is_anonymous_data_member(first))
5583
5584 return first;
5585}
5586
5587/// In the context of a given class or union, this function returns
5588/// the data member that is located after a given data member.
5589///
5590/// @param klass the class or union to consider.
5591///
5592/// @param the data member to consider.
5593///
5594/// @return the data member that is located right after @p
5595/// data_member.
5596const var_decl_sptr
5598 const var_decl_sptr &data_member)
5599{
5600 if (!klass ||!data_member)
5601 return var_decl_sptr();
5602
5603 for (class_or_union::data_members::const_iterator it =
5604 klass->get_non_static_data_members().begin();
5605 it != klass->get_non_static_data_members().end();
5606 ++it)
5607 if (**it == *data_member)
5608 {
5609 ++it;
5610 if (it != klass->get_non_static_data_members().end())
5612 break;
5613 }
5614
5615 return var_decl_sptr();
5616}
5617
5618/// In the context of a given class or union, this function returns
5619/// the data member that is located after a given data member.
5620///
5621/// @param klass the class or union to consider.
5622///
5623/// @param the data member to consider.
5624///
5625/// @return the data member that is located right after @p
5626/// data_member.
5627const var_decl_sptr
5628get_next_data_member(const class_or_union_sptr& klass,
5629 const var_decl_sptr &data_member)
5630{return get_next_data_member(klass.get(), data_member);}
5631
5632/// Get the last data member of a class type.
5633///
5634/// @param klass the class type to consider.
5637{return klass.get_non_static_data_members().back();}
5638
5639/// Get the last data member of a class type.
5640///
5641/// @param klass the class type to consider.
5645
5646/// Get the last data member of a class type.
5647///
5648/// @param klass the class type to consider.
5650get_last_data_member(const class_or_union_sptr &klass)
5651{return get_last_data_member(klass.get());}
5652
5653/// Collect all the non-anonymous data members of a class or union type.
5654///
5655/// If the class contains any anonymous data member, this function
5656/// looks through it to collect the non-anonymous data members that it
5657/// contains. The function also also looks through the base classes
5658/// of the current type.
5659///
5660/// @param cou the class or union type to consider.
5661///
5662/// @param dms output parameter. This is populated by the function
5663/// with a map containing the non-anonymous data members that were
5664/// collected. The key of the map is the name of the data member.
5665/// This is set iff the function returns true.
5666///
5667/// @return true iff at least one non-anonymous data member was
5668/// collected.
5669bool
5672{
5673 if (!cou)
5674 return false;
5675
5676 bool result = false;
5677 class_decl* klass = is_class_type(cou);
5678 if (klass)
5679 // First look into base classes for data members.
5681 result |= collect_non_anonymous_data_members(base->get_base_class().get(), dms);
5682
5683 // Then look into our data members
5684 for (var_decl_sptr member : cou->get_non_static_data_members())
5685 {
5686 if (is_anonymous_data_member(member))
5687 {
5688 class_or_union_sptr cl = anonymous_data_member_to_class_or_union(member);
5689 ABG_ASSERT(cl);
5690 result |= collect_non_anonymous_data_members(cl.get(), dms);
5691 }
5692 else
5693 {
5694 dms[member->get_name()] = member;
5695 result = true;
5696 }
5697 }
5698 return true;
5699}
5700
5701/// Collect all the non-anonymous data members of a class or union type.
5702///
5703/// If the class contains any anonymous data member, this function
5704/// looks through it to collect the non-anonymous data members that it
5705/// contains. The function also also looks through the base classes
5706/// of the current type.
5707///
5708/// @param cou the class or union type to consider.
5709///
5710/// @param dms output parameter. This is populated by the function
5711/// with a map containing the non-anonymous data members that were
5712/// collected. The key of the map is the name of the data member.
5713/// This is set iff the function returns true.
5714///
5715/// @return true iff at least one non-anonymous data member was
5716/// collected.
5717bool
5719{return collect_non_anonymous_data_members(cou.get(), dms);}
5720
5721/// Test if a decl is an anonymous data member.
5722///
5723/// @param d the decl to consider.
5724///
5725/// @return true iff @p d is an anonymous data member.
5726bool
5729
5730/// Test if a decl is an anonymous data member.
5731///
5732/// @param d the decl to consider.
5733///
5734/// @return the var_decl representing the data member iff @p d is an
5735/// anonymous data member.
5736const var_decl*
5738{
5739 if (const var_decl* v = is_data_member(d))
5740 {
5742 return v;
5743 }
5744 return 0;
5745}
5746
5747/// Test if a decl is an anonymous data member.
5748///
5749/// @param d the decl to consider.
5750///
5751/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5752/// it's an anonymous data member. Otherwise returns a nil pointer.
5753const var_decl*
5755{
5756 if (const var_decl* v = is_data_member(d))
5757 {
5759 return v;
5760 }
5761 return 0;
5762}
5763
5764/// Test if a decl is an anonymous data member.
5765///
5766/// @param d the decl to consider.
5767///
5768/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5769/// it's an anonymous data member. Otherwise returns a nil pointer.
5772{
5773 if (var_decl_sptr v = is_data_member(d))
5774 {
5776 return v;
5777 }
5778 return var_decl_sptr();
5779}
5780
5781/// Test if a decl is an anonymous data member.
5782///
5783/// @param d the decl to consider.
5784///
5785/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5786/// it's an anonymous data member. Otherwise returns a nil pointer.
5788is_anonymous_data_member(const decl_base_sptr& d)
5789{
5790 if (var_decl_sptr v = is_data_member(d))
5791 return is_anonymous_data_member(v);
5792 return var_decl_sptr();
5793}
5794
5795/// Test if a @ref var_decl is an anonymous data member.
5796///
5797/// @param d the @ref var_decl to consider.
5798///
5799/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5800/// it's an anonymous data member. Otherwise returns a nil pointer.
5803{
5804 if (is_anonymous_data_member(d.get()))
5805 return d;
5806 return var_decl_sptr();
5807}
5808
5809/// Test if a @ref var_decl is an anonymous data member.
5810///
5811/// @param d the @ref var_decl to consider.
5812///
5813/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5814/// it's an anonymous data member. Otherwise returns a nil pointer.
5815const var_decl*
5817{
5818 if (d && is_anonymous_data_member(*d))
5819 return d;
5820 return 0;
5821}
5822
5823/// Test if a @ref var_decl is an anonymous data member.
5824///
5825/// @param d the @ref var_decl to consider.
5826///
5827/// @return true iff @p d is an anonymous data member.
5828bool
5830{
5831 return (is_data_member(d)
5832 && d.get_is_anonymous()
5833 && d.get_name().empty()
5835}
5836
5837/// Test if a @ref var_decl is a data member belonging to an anonymous
5838/// type.
5839///
5840/// @param d the @ref var_decl to consider.
5841///
5842/// @return true iff @p d is a data member belonging to an anonymous
5843/// type.
5844bool
5846{
5847 if (is_data_member(d))
5848 {
5849 scope_decl* scope = d.get_scope();
5850 if (scope && scope->get_is_anonymous())
5851 return true;
5852 }
5853 return false;
5854}
5855
5856/// Test if a @ref var_decl is a data member belonging to an anonymous
5857/// type.
5858///
5859/// @param d the @ref var_decl to consider.
5860///
5861/// @return true iff @p d is a data member belonging to an anonymous
5862/// type.
5863bool
5866
5867/// Test if a @ref var_decl is a data member belonging to an anonymous
5868/// type.
5869///
5870/// @param d the @ref var_decl to consider.
5871///
5872/// @return true iff @p d is a data member belonging to an anonymous
5873/// type.
5874bool
5877
5878/// Get the @ref class_or_union type of a given anonymous data member.
5879///
5880/// @param d the anonymous data member to consider.
5881///
5882/// @return the @ref class_or_union type of the anonymous data member
5883/// @p d.
5886{
5887 if ((d = is_anonymous_data_member(d)))
5888 return is_class_or_union_type(d->get_type().get());
5889 return 0;
5890}
5891
5892/// Get the @ref class_or_union type of a given anonymous data member.
5893///
5894/// @param d the anonymous data member to consider.
5895///
5896/// @return the @ref class_or_union type of the anonymous data member
5897/// @p d.
5898class_or_union_sptr
5900{
5902 return is_class_or_union_type(d.get_type());
5903 return class_or_union_sptr();
5904}
5905
5906/// Test if a data member has annonymous type or not.
5907///
5908/// @param d the data member to consider.
5909///
5910/// @return the anonymous class or union type iff @p turns out to have
5911/// an anonymous type. Otherwise, returns nil.
5912const class_or_union_sptr
5914{
5915 if (is_data_member(d))
5916 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
5917 if (cou->get_is_anonymous())
5918 return cou;
5919
5920 return class_or_union_sptr();
5921}
5922
5923/// Test if a data member has annonymous type or not.
5924///
5925/// @param d the data member to consider.
5926///
5927/// @return the anonymous class or union type iff @p turns out to have
5928/// an anonymous type. Otherwise, returns nil.
5929const class_or_union_sptr
5931{
5932 if (d)
5934 return class_or_union_sptr();
5935}
5936
5937/// Test if a data member has annonymous type or not.
5938///
5939/// @param d the data member to consider.
5940///
5941/// @return the anonymous class or union type iff @p turns out to have
5942/// an anonymous type. Otherwise, returns nil.
5943const class_or_union_sptr
5946
5947/// Get the @ref class_or_union type of a given anonymous data member.
5948///
5949/// @param d the anonymous data member to consider.
5950///
5951/// @return the @ref class_or_union type of the anonymous data member
5952/// @p d.
5953class_or_union_sptr
5955{
5957 return is_class_or_union_type(v->get_type());
5958 return class_or_union_sptr();
5959}
5960
5961/// Test if a given anonymous data member exists in a class or union.
5962///
5963/// @param anon_dm the anonymous data member to consider.
5964///
5965/// @param clazz the class to consider.
5966///
5967/// @return true iff @p anon_dm exists in the @clazz.
5968bool
5970 const class_or_union& clazz)
5971{
5972 if (!anon_dm.get_is_anonymous()
5973 || !is_class_or_union_type(anon_dm.get_type()))
5974 return false;
5975
5976 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
5977 ABG_ASSERT(cl);
5978
5979 // Look for the presence of each data member of anon_dm in clazz.
5980 //
5981 // If one data member of anon_dm is not present in clazz, then the
5982 // data member anon_dm is considered to not exist in clazz.
5983 for (auto anon_dm_m : cl->get_non_static_data_members())
5984 {
5985 // If the data member anon_dm_m is not an anonymous data member,
5986 // it's easy to look for it.
5987 if (!is_anonymous_data_member(anon_dm_m))
5988 {
5989 if (!clazz.find_data_member(anon_dm_m->get_name()))
5990 return false;
5991 }
5992 // If anon_dm_m is itself an anonymous data member then recurse
5993 else
5994 {
5995 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
5996 return false;
5997 }
5998 }
5999
6000 return true;
6001}
6002
6003/// Test if a given decl is anonymous or has a naming typedef.
6004///
6005/// @param d the decl to consider.
6006///
6007/// @return true iff @p d is anonymous or has a naming typedef.
6008bool
6010{
6011 if (d.get_is_anonymous() || d.get_naming_typedef())
6012 return true;
6013 return false;
6014}
6015
6016/// Set the offset of a data member into its containing class.
6017///
6018/// @param m the data member to consider.
6019///
6020/// @param o the offset, in bits.
6021void
6023{
6025
6026 dm_context_rel* ctxt_rel =
6027 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6028 ABG_ASSERT(ctxt_rel);
6029
6030 ctxt_rel->set_offset_in_bits(o);
6031}
6032
6033/// Get the offset of a data member.
6034///
6035/// @param m the data member to consider.
6036///
6037/// @return the offset (in bits) of @p m in its containing class.
6038uint64_t
6040{
6042 const dm_context_rel* ctxt_rel =
6043 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6044 ABG_ASSERT(ctxt_rel);
6045 return ctxt_rel->get_offset_in_bits();
6046}
6047
6048/// Get the offset of a data member.
6049///
6050/// @param m the data member to consider.
6051///
6052/// @return the offset (in bits) of @p m in its containing class.
6053uint64_t
6056
6057/// Get the offset of a data member.
6058///
6059/// @param m the data member to consider.
6060///
6061/// @return the offset (in bits) of @p m in its containing class.
6062uint64_t
6063get_data_member_offset(const decl_base_sptr d)
6064{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6065
6066/// Get the offset of the non-static data member that comes after a
6067/// given one.
6068///
6069/// If there is no data member after after the one given to this
6070/// function (maybe because the given one is the last data member of
6071/// the class type) then the function return false.
6072///
6073/// @param klass the class to consider.
6074///
6075/// @param dm the data member before the one we want to retrieve.
6076///
6077/// @param offset out parameter. This parameter is set by the
6078/// function to the offset of the data member that comes right after
6079/// the data member @p dm, iff the function returns true.
6080///
6081/// @return true iff the data member coming right after @p dm was
6082/// found.
6083bool
6085 const var_decl_sptr& dm,
6086 uint64_t& offset)
6087{
6088 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6089 if (!next_dm)
6090 return false;
6091 offset = get_data_member_offset(next_dm);
6092 return true;
6093}
6094
6095/// Get the offset of the non-static data member that comes after a
6096/// given one.
6097///
6098/// If there is no data member after after the one given to this
6099/// function (maybe because the given one is the last data member of
6100/// the class type) then the function return false.
6101///
6102/// @param klass the class to consider.
6103///
6104/// @param dm the data member before the one we want to retrieve.
6105///
6106/// @param offset out parameter. This parameter is set by the
6107/// function to the offset of the data member that comes right after
6108/// the data member @p dm, iff the function returns true.
6109///
6110/// @return true iff the data member coming right after @p dm was
6111/// found.
6112bool
6113get_next_data_member_offset(const class_or_union_sptr& klass,
6114 const var_decl_sptr& dm,
6115 uint64_t& offset)
6116{return get_next_data_member_offset(klass.get(), dm, offset);}
6117
6118/// Get the absolute offset of a data member.
6119///
6120/// If the data member is part of an anonymous data member then this
6121/// returns the absolute offset -- relative to the beginning of the
6122/// containing class of the anonymous data member.
6123///
6124/// @param m the data member to consider.
6125///
6126/// @return the aboslute offset of the data member @p m.
6127uint64_t
6129{
6131 const dm_context_rel* ctxt_rel =
6132 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6133 ABG_ASSERT(ctxt_rel);
6134
6135 const var_decl *containing_anonymous_data_member =
6136 ctxt_rel->get_anonymous_data_member();
6137
6138 uint64_t containing_anonymous_data_member_offset = 0;
6139 if (containing_anonymous_data_member)
6140 containing_anonymous_data_member_offset =
6141 get_absolute_data_member_offset(*containing_anonymous_data_member);
6142
6143 return (ctxt_rel->get_offset_in_bits()
6144 +
6145 containing_anonymous_data_member_offset);
6146}
6147
6148/// Get the absolute offset of a data member.
6149///
6150/// If the data member is part of an anonymous data member then this
6151/// returns the absolute offset -- relative to the beginning of the
6152/// containing class of the anonymous data member.
6153///
6154/// @param m the data member to consider.
6155///
6156/// @return the aboslute offset of the data member @p m.
6157uint64_t
6159{
6160 if (!m)
6161 return 0;
6163}
6164
6165/// Get the size of a given variable.
6166///
6167/// @param v the variable to consider.
6168///
6169/// @return the size of variable @p v.
6170uint64_t
6172{
6173 type_base_sptr t = v->get_type();
6174 ABG_ASSERT(t);
6175
6176 return t->get_size_in_bits();
6177}
6178
6179/// Set a flag saying if a data member is laid out.
6180///
6181/// @param m the data member to consider.
6182///
6183/// @param l true if @p m is to be considered as laid out.
6184void
6186{
6188 dm_context_rel* ctxt_rel =
6189 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6190 ctxt_rel->set_is_laid_out(l);
6191}
6192
6193/// Test whether a data member is laid out.
6194///
6195/// @param m the data member to consider.
6196///
6197/// @return true if @p m is laid out, false otherwise.
6198bool
6200{
6202 const dm_context_rel* ctxt_rel =
6203 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6204
6205 return ctxt_rel->get_is_laid_out();
6206}
6207
6208/// Test whether a data member is laid out.
6209///
6210/// @param m the data member to consider.
6211///
6212/// @return true if @p m is laid out, false otherwise.
6213bool
6216
6217/// Test whether a function_decl is a member function.
6218///
6219/// @param f the function_decl to test.
6220///
6221/// @return true if @p f is a member function, false otherwise.
6222bool
6225
6226/// Test whether a function_decl is a member function.
6227///
6228/// @param f the function_decl to test.
6229///
6230/// @return true if @p f is a member function, false otherwise.
6231bool
6234
6235/// Test whether a function_decl is a member function.
6236///
6237/// @param f the function_decl to test.
6238///
6239/// @return true if @p f is a member function, false otherwise.
6240bool
6243
6244/// Test whether a member function is a constructor.
6245///
6246/// @param f the member function to test.
6247///
6248/// @return true if @p f is a constructor, false otherwise.
6249bool
6251{
6253
6254 const method_decl* m = is_method_decl(&f);
6255 ABG_ASSERT(m);
6256
6257 const mem_fn_context_rel* ctxt =
6258 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6259
6260 return ctxt->is_constructor();
6261}
6262
6263/// Test whether a member function is a constructor.
6264///
6265/// @param f the member function to test.
6266///
6267/// @return true if @p f is a constructor, false otherwise.
6268bool
6271
6272
6273/// Setter for the is_ctor property of the member function.
6274///
6275/// @param f the member function to set.
6276///
6277/// @param f the new boolean value of the is_ctor property. Is true
6278/// if @p f is a constructor, false otherwise.
6279void
6281{
6283
6284 method_decl* m = is_method_decl(&f);
6285 ABG_ASSERT(m);
6286
6287 mem_fn_context_rel* ctxt =
6288 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6289
6290 ctxt->is_constructor(c);
6291}
6292
6293/// Setter for the is_ctor property of the member function.
6294///
6295/// @param f the member function to set.
6296///
6297/// @param f the new boolean value of the is_ctor property. Is true
6298/// if @p f is a constructor, false otherwise.
6299void
6302
6303/// Test whether a member function is a destructor.
6304///
6305/// @param f the function to test.
6306///
6307/// @return true if @p f is a destructor, false otherwise.
6308bool
6310{
6312
6313 const method_decl* m = is_method_decl(&f);
6314 ABG_ASSERT(m);
6315
6316 const mem_fn_context_rel* ctxt =
6317 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6318
6319 return ctxt->is_destructor();
6320}
6321
6322/// Test whether a member function is a destructor.
6323///
6324/// @param f the function to test.
6325///
6326/// @return true if @p f is a destructor, false otherwise.
6327bool
6330
6331/// Set the destructor-ness property of a member function.
6332///
6333/// @param f the function to set.
6334///
6335/// @param d true if @p f is a destructor, false otherwise.
6336void
6338{
6340
6341 method_decl* m = is_method_decl(&f);
6342 ABG_ASSERT(m);
6343
6344 mem_fn_context_rel* ctxt =
6345 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6346
6347 ctxt->is_destructor(d);
6348}
6349
6350/// Set the destructor-ness property of a member function.
6351///
6352/// @param f the function to set.
6353///
6354/// @param d true if @p f is a destructor, false otherwise.
6355void
6358
6359/// Test whether a member function is const.
6360///
6361/// @param f the function to test.
6362///
6363/// @return true if @p f is const, false otherwise.
6364bool
6366{
6368
6369 const method_decl* m = is_method_decl(&f);
6370 ABG_ASSERT(m);
6371
6372 const mem_fn_context_rel* ctxt =
6373 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6374
6375 return ctxt->is_const();
6376}
6377
6378/// Test whether a member function is const.
6379///
6380/// @param f the function to test.
6381///
6382/// @return true if @p f is const, false otherwise.
6383bool
6386
6387/// set the const-ness property of a member function.
6388///
6389/// @param f the function to set.
6390///
6391/// @param is_const the new value of the const-ness property of @p f
6392void
6394{
6396
6397 method_decl* m = is_method_decl(&f);
6398 ABG_ASSERT(m);
6399
6400 mem_fn_context_rel* ctxt =
6401 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6402
6403 ctxt->is_const(is_const);
6404}
6405
6406/// set the const-ness property of a member function.
6407///
6408/// @param f the function to set.
6409///
6410/// @param is_const the new value of the const-ness property of @p f
6411void
6414
6415/// Test if a virtual member function has a vtable offset set.
6416///
6417/// @param f the virtual member function to consider.
6418///
6419/// @return true iff the virtual member function has its vtable offset
6420/// set, i.e, if the vtable offset of @p is different from -1.
6421bool
6424
6425/// Get the vtable offset of a member function.
6426///
6427/// @param f the member function to consider.
6428///
6429/// @return the vtable offset of @p f. Note that a vtable offset of
6430/// value -1 means that the member function does *NOT* yet have a
6431/// vtable offset associated to it.
6432ssize_t
6434{
6436
6437 const method_decl* m =
6438 dynamic_cast<const method_decl*>(&f);
6439 ABG_ASSERT(m);
6440
6441 const mem_fn_context_rel* ctxt =
6442 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6443
6444 return ctxt->vtable_offset();
6445}
6446
6447/// Get the vtable offset of a member function.
6448///
6449/// @param f the member function to consider.
6450///
6451/// @return the vtable offset of @p f. Note that a vtable offset of
6452/// value -1 means that the member function does *NOT* yet have a
6453/// vtable offset associated to it.
6454ssize_t
6457
6458/// Set the vtable offset of a member function.
6459///
6460/// @param f the member function to consider.
6461///
6462/// @param s the new vtable offset. Please note that a vtable offset
6463/// of value -1 means that the virtual member function does not (yet)
6464/// have any vtable offset associated to it.
6465static void
6466set_member_function_vtable_offset(function_decl& f, ssize_t s)
6467{
6469
6470 method_decl* m = is_method_decl(&f);
6471 ABG_ASSERT(m);
6472
6473 mem_fn_context_rel* ctxt =
6474 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6475
6476 ctxt->vtable_offset(s);
6477}
6478
6479/// Get the vtable offset of a member function.
6480///
6481/// @param f the member function to consider.
6482///
6483/// @param s the new vtable offset. Please note that a vtable offset
6484/// of value -1 means that the virtual member function does not (yet)
6485/// have any vtable offset associated to it.
6486static void
6487set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
6488{return set_member_function_vtable_offset(*f, s);}
6489
6490/// Test if a given member function is virtual.
6491///
6492/// @param mem_fn the member function to consider.
6493///
6494/// @return true iff a @p mem_fn is virtual.
6495bool
6497{
6499
6500 const method_decl* m =
6501 dynamic_cast<const method_decl*>(&f);
6502 ABG_ASSERT(m);
6503
6504 const mem_fn_context_rel* ctxt =
6505 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6506
6507 return ctxt->is_virtual();
6508}
6509
6510/// Test if a given member function is virtual.
6511///
6512/// @param mem_fn the member function to consider.
6513///
6514/// @return true iff a @p mem_fn is virtual.
6515bool
6517{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6518
6519/// Test if a given member function is virtual.
6520///
6521/// @param mem_fn the member function to consider.
6522///
6523/// @return true iff a @p mem_fn is virtual.
6524bool
6526{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6527
6528/// Set the virtual-ness of a member function.
6529///
6530/// @param f the member function to consider.
6531///
6532/// @param is_virtual set to true if the function is virtual.
6533static void
6534set_member_function_is_virtual(function_decl& f, bool is_virtual)
6535{
6537
6538 method_decl* m = is_method_decl(&f);
6539 ABG_ASSERT(m);
6540
6541 mem_fn_context_rel* ctxt =
6542 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6543
6544 ctxt->is_virtual(is_virtual);
6545}
6546
6547/// Set the virtual-ness of a member function.
6548///
6549/// @param f the member function to consider.
6550///
6551/// @param is_virtual set to true if the function is virtual.
6552static void
6553set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
6554{
6555 if (fn)
6556 {
6557 set_member_function_is_virtual(*fn, is_virtual);
6559 }
6560}
6561
6562/// Set the virtual-ness of a member fcuntion
6563///
6564/// @param fn the member function to consider.
6565///
6566/// @param is_virtual whether the function is virtual.
6567///
6568/// @param voffset the virtual offset of the virtual function.
6569void
6571 bool is_virtual,
6572 ssize_t voffset)
6573{
6574 // Setting the offset must come first because the second function
6575 // does assume the voffset is set, in case of virtuality
6576 set_member_function_vtable_offset(fn, voffset);
6577 set_member_function_is_virtual(fn, is_virtual);
6578}
6579
6580/// Set the virtual-ness of a member fcuntion
6581///
6582/// @param fn the member function to consider.
6583///
6584/// @param is_virtual whether the function is virtual.
6585///
6586/// @param voffset the virtual offset of the virtual function.
6587void
6589 bool is_virtual,
6590 ssize_t voffset)
6591{
6592 if (fn)
6593 set_member_function_virtuality(*fn, is_virtual, voffset);
6594}
6595
6596/// Set the virtual-ness of a member fcuntion
6597///
6598/// @param fn the member function to consider.
6599///
6600/// @param is_virtual whether the function is virtual.
6601///
6602/// @param voffset the virtual offset of the virtual function.
6603void
6605 bool is_virtual,
6606 ssize_t voffset)
6607{
6608 set_member_function_vtable_offset(fn, voffset);
6609 set_member_function_is_virtual(fn, is_virtual);
6610}
6611
6612/// Recursively returns the the underlying type of a typedef. The
6613/// return type should not be a typedef of anything anymore.
6614///
6615///
6616/// Also recursively strip typedefs from the sub-types of the type
6617/// given in arguments.
6618///
6619/// Note that this function builds types in which typedefs are
6620/// stripped off. Usually, types are held by their scope, so their
6621/// life time is bound to the life time of their scope. But as this
6622/// function cannot really insert the built type into it's scope, it
6623/// must ensure that the newly built type stays live long enough.
6624///
6625/// So, if the newly built type has a canonical type, this function
6626/// returns the canonical type. Otherwise, this function ensure that
6627/// the newly built type has a life time that is the same as the life
6628/// time of the entire libabigail library.
6629///
6630/// @param type the type to strip the typedefs from.
6631///
6632/// @return the resulting type stripped from its typedefs, or just
6633/// return @p type if it has no typedef in any of its sub-types.
6634type_base_sptr
6635strip_typedef(const type_base_sptr type)
6636{
6637 if (!type)
6638 return type;
6639
6640 // If type is a class type then do not try to strip typedefs from it.
6641 // And if it has no canonical type (which can mean that it's a
6642 // declaration-only class), then, make sure its live for ever and
6643 // return it.
6644 if (class_decl_sptr cl = is_class_type(type))
6645 {
6646 if (!cl->get_canonical_type())
6647 keep_type_alive(type);
6648 return type;
6649 }
6650
6651 const environment& env = type->get_environment();
6652 type_base_sptr t = type;
6653
6654 if (const typedef_decl_sptr ty = is_typedef(t))
6655 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6656 else if (const reference_type_def_sptr ty = is_reference_type(t))
6657 {
6658 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6659 env));
6660 ABG_ASSERT(p);
6661 t.reset(new reference_type_def(p,
6662 ty->is_lvalue(),
6663 ty->get_size_in_bits(),
6664 ty->get_alignment_in_bits(),
6665 ty->get_location()));
6666 }
6667 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6668 {
6669 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6670 env));
6671 ABG_ASSERT(p);
6672 t.reset(new pointer_type_def(p,
6673 ty->get_size_in_bits(),
6674 ty->get_alignment_in_bits(),
6675 ty->get_location()));
6676 }
6677 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6678 {
6679 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6680 env));
6681 ABG_ASSERT(p);
6682 t.reset(new qualified_type_def(p,
6683 ty->get_cv_quals(),
6684 ty->get_location()));
6685 }
6686 else if (const array_type_def_sptr ty = is_array_type(t))
6687 {
6688 type_base_sptr p = strip_typedef(ty->get_element_type());
6689 ABG_ASSERT(p);
6690 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6691 }
6692 else if (const method_type_sptr ty = is_method_type(t))
6693 {
6695 for (function_decl::parameters::const_iterator i =
6696 ty->get_parameters().begin();
6697 i != ty->get_parameters().end();
6698 ++i)
6699 {
6701 type_base_sptr typ = strip_typedef(p->get_type());
6702 ABG_ASSERT(typ);
6704 (new function_decl::parameter(typ,
6705 p->get_index(),
6706 p->get_name(),
6707 p->get_location(),
6708 p->get_variadic_marker(),
6709 p->get_is_artificial()));
6710 parm.push_back(stripped);
6711 }
6712 type_base_sptr p = strip_typedef(ty->get_return_type());
6713 ABG_ASSERT(!!p == !!ty->get_return_type());
6714 t.reset(new method_type(p, ty->get_class_type(),
6715 parm, ty->get_is_const(),
6716 ty->get_size_in_bits(),
6717 ty->get_alignment_in_bits()));
6718 }
6719 else if (const function_type_sptr ty = is_function_type(t))
6720 {
6722 for (function_decl::parameters::const_iterator i =
6723 ty->get_parameters().begin();
6724 i != ty->get_parameters().end();
6725 ++i)
6726 {
6728 type_base_sptr typ = strip_typedef(p->get_type());
6729 ABG_ASSERT(typ);
6731 (new function_decl::parameter(typ,
6732 p->get_index(),
6733 p->get_name(),
6734 p->get_location(),
6735 p->get_variadic_marker(),
6736 p->get_is_artificial()));
6737 parm.push_back(stripped);
6738 }
6739 type_base_sptr p = strip_typedef(ty->get_return_type());
6740 ABG_ASSERT(!!p == !!ty->get_return_type());
6741 t.reset(new function_type(p, parm,
6742 ty->get_size_in_bits(),
6743 ty->get_alignment_in_bits()));
6744 }
6745
6746 if (!t->get_translation_unit())
6747 t->set_translation_unit(type->get_translation_unit());
6748
6749 if (!(type->get_canonical_type() && canonicalize(t)))
6750 keep_type_alive(t);
6751
6752 return t->get_canonical_type() ? t->get_canonical_type() : t;
6753}
6754
6755/// Strip qualification from a qualified type, when it makes sense.
6756///
6757/// DWARF constructs "const reference". This is redundant because a
6758/// reference is always const. It also constructs the useless "const
6759/// void" type. The issue is these redundant types then leak into the
6760/// IR and make for bad diagnostics.
6761///
6762/// This function thus strips the const qualifier from the type in
6763/// that case. It might contain code to strip other cases like this
6764/// in the future.
6765///
6766/// @param t the type to strip const qualification from.
6767///
6768/// @return the stripped type or just return @p t.
6769decl_base_sptr
6770strip_useless_const_qualification(const qualified_type_def_sptr t)
6771{
6772 if (!t)
6773 return t;
6774
6775 decl_base_sptr result = t;
6776 type_base_sptr u = t->get_underlying_type();
6777 const environment& env = t->get_environment();
6778
6779 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6780 && (is_reference_type(u)))
6781 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6782 && env.is_void_type(u))
6783 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6784 // Let's strip the const qualifier because a reference is always
6785 // 'const' and a const void doesn't make sense. They will just
6786 // lead to spurious changes later down the pipeline, that we'll
6787 // have to deal with by doing painful and error-prone editing of
6788 // the diff IR. Dropping that useless and inconsistent artefact
6789 // right here seems to be a good way to go.
6790 result = is_decl(u);
6791
6792 return result;
6793}
6794
6795/// Merge redundant qualifiers from a tree of qualified types.
6796///
6797/// Suppose a tree of qualified types leads to:
6798///
6799/// const virtual const restrict const int;
6800///
6801/// Suppose the IR tree of qualified types ressembles (with C meaning
6802/// const, V meaning virtual and R meaning restrict):
6803///
6804/// [C|V]-->[C|R] -->[C] --> [int].
6805///
6806/// This function walks the IR and remove the redundant CV qualifiers
6807/// so the IR becomes:
6808///
6809/// [C|V] --> [R] --> [] -->[int].
6810///
6811/// Note that the empty qualified type (noted []) represents a
6812/// qualified type with no qualifier. It's rare, but it can exist.
6813/// I've put it here just for the sake of example.
6814///
6815/// The resulting IR thus represents the (merged) type:
6816///
6817/// const virtual restrict int.
6818///
6819/// This function is a sub-routine of the overload @ref
6820/// strip_useless_const_qualification which doesn't return any value.
6821///
6822/// @param t the qualified type to consider.
6823///
6824/// @param redundant_quals the (redundant) qualifiers to be removed
6825/// from the qualifiers of the underlying types of @p t.
6826///
6827/// @return the underlying type of @p t which might have had its
6828/// redundant qualifiers removed.
6829static qualified_type_def_sptr
6830strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
6831 qualified_type_def::CV redundant_quals)
6832{
6833 if (!t)
6834 return t;
6835
6836 // We must NOT edit canonicalized types.
6837 ABG_ASSERT(!t->get_canonical_type());
6838
6839 qualified_type_def_sptr underlying_qualified_type =
6840 is_qualified_type(t->get_underlying_type());
6841
6842 // Let's build 'currated qualifiers' that are the qualifiers of the
6843 // current type from which redundant qualifiers are removed.
6844 qualified_type_def::CV currated_quals = t->get_cv_quals();
6845
6846 // Remove the redundant qualifiers from these currated qualifiers
6847 currated_quals &= ~redundant_quals;
6848 t->set_cv_quals(currated_quals);
6849
6850 // The redundant qualifiers, moving forward, is now the union of the
6851 // previous set of redundant qualifiers and the currated qualifiers.
6852 redundant_quals |= currated_quals;
6853
6854 qualified_type_def_sptr result = t;
6855 if (underlying_qualified_type)
6856 // Now remove the redundant qualifiers from the qualified types
6857 // potentially carried by the underlying type.
6858 result =
6859 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
6860 redundant_quals);
6861
6862 return result;
6863}
6864
6865/// Merge redundant qualifiers from a tree of qualified types.
6866///
6867/// Suppose a tree of qualified types leads to:
6868///
6869/// const virtual const restrict const int;
6870///
6871/// Suppose the IR tree of qualified types ressembles (with C meaning
6872/// const, V meaning virtual and R meaning restrict):
6873///
6874/// [C|V]-->[C|R] -->[C] --> [int].
6875///
6876/// This function walks the IR and remove the redundant CV qualifiers
6877/// so the IR becomes:
6878///
6879/// [C|V] --> [R] --> [] -->[int].
6880///
6881/// Note that the empty qualified type (noted []) represents a
6882/// qualified type with no qualifier. It's rare, but it can exist.
6883/// I've put it here just for the sake of example.
6884///
6885/// The resulting IR thus represents the (merged) type:
6886///
6887/// const virtual restrict int.
6888///
6889/// @param t the qualified type to consider. The IR below the
6890/// argument to this parameter will be edited to remove redundant
6891/// qualifiers where applicable.
6892void
6893strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
6894{
6895 if (!t)
6896 return;
6897
6898 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
6899 strip_redundant_quals_from_underyling_types(t, redundant_quals);
6900}
6901
6902/// Return the leaf underlying type node of a @ref typedef_decl node.
6903///
6904/// If the underlying type of a @ref typedef_decl node is itself a
6905/// @ref typedef_decl node, then recursively look at the underlying
6906/// type nodes to get the first one that is not a a @ref typedef_decl
6907/// node. This is what a leaf underlying type node means.
6908///
6909/// Otherwise, if the underlying type node of @ref typedef_decl is
6910/// *NOT* a @ref typedef_decl node, then just return the underlying
6911/// type node.
6912///
6913/// And if the type node considered is not a @ref typedef_decl node,
6914/// then just return it.
6915///
6916/// @return the leaf underlying type node of a @p type.
6917type_base_sptr
6918peel_typedef_type(const type_base_sptr& type)
6919{
6920 typedef_decl_sptr t = is_typedef(type);
6921 if (!t)
6922 return type;
6923
6924 if (is_typedef(t->get_underlying_type()))
6925 return peel_typedef_type(t->get_underlying_type());
6926 return t->get_underlying_type();
6927}
6928
6929/// Return the leaf underlying type node of a @ref typedef_decl node.
6930///
6931/// If the underlying type of a @ref typedef_decl node is itself a
6932/// @ref typedef_decl node, then recursively look at the underlying
6933/// type nodes to get the first one that is not a a @ref typedef_decl
6934/// node. This is what a leaf underlying type node means.
6935///
6936/// Otherwise, if the underlying type node of @ref typedef_decl is
6937/// *NOT* a @ref typedef_decl node, then just return the underlying
6938/// type node.
6939///
6940/// And if the type node considered is not a @ref typedef_decl node,
6941/// then just return it.
6942///
6943/// @return the leaf underlying type node of a @p type.
6944const type_base*
6946{
6947 const typedef_decl* t = is_typedef(type);
6948 if (!t)
6949 return type;
6950
6951 return peel_typedef_type(t->get_underlying_type()).get();
6952}
6953
6954/// Return the leaf pointed-to type node of a @ref pointer_type_def
6955/// node.
6956///
6957/// If the pointed-to type of a @ref pointer_type_def node is itself a
6958/// @ref pointer_type_def node, then recursively look at the
6959/// pointed-to type nodes to get the first one that is not a a @ref
6960/// pointer_type_def node. This is what a leaf pointed-to type node
6961/// means.
6962///
6963/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
6964/// *NOT* a @ref pointer_type_def node, then just return the
6965/// pointed-to type node.
6966///
6967/// And if the type node considered is not a @ref pointer_type_def
6968/// node, then just return it.
6969///
6970/// @return the leaf pointed-to type node of a @p type.
6971type_base_sptr
6972peel_pointer_type(const type_base_sptr& type)
6973{
6975 if (!t)
6976 return type;
6977
6978 if (is_pointer_type(t->get_pointed_to_type()))
6979 return peel_pointer_type(t->get_pointed_to_type());
6980 return t->get_pointed_to_type();
6981}
6982
6983/// Return the leaf pointed-to type node of a @ref pointer_type_def
6984/// node.
6985///
6986/// If the pointed-to type of a @ref pointer_type_def node is itself a
6987/// @ref pointer_type_def node, then recursively look at the
6988/// pointed-to type nodes to get the first one that is not a a @ref
6989/// pointer_type_def node. This is what a leaf pointed-to type node
6990/// means.
6991///
6992/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
6993/// *NOT* a @ref pointer_type_def node, then just return the
6994/// pointed-to type node.
6995///
6996/// And if the type node considered is not a @ref pointer_type_def
6997/// node, then just return it.
6998///
6999/// @return the leaf pointed-to type node of a @p type.
7000const type_base*
7002{
7003 const pointer_type_def* t = is_pointer_type(type);
7004 if (!t)
7005 return type;
7006
7007 return peel_pointer_type(t->get_pointed_to_type()).get();
7008}
7009
7010/// Return the leaf pointed-to type node of a @ref reference_type_def
7011/// node.
7012///
7013/// If the pointed-to type of a @ref reference_type_def node is itself
7014/// a @ref reference_type_def node, then recursively look at the
7015/// pointed-to type nodes to get the first one that is not a a @ref
7016/// reference_type_def node. This is what a leaf pointed-to type node
7017/// means.
7018///
7019/// Otherwise, if the pointed-to type node of @ref reference_type_def
7020/// is *NOT* a @ref reference_type_def node, then just return the
7021/// pointed-to type node.
7022///
7023/// And if the type node considered is not a @ref reference_type_def
7024/// node, then just return it.
7025///
7026/// @return the leaf pointed-to type node of a @p type.
7027type_base_sptr
7028peel_reference_type(const type_base_sptr& type)
7029{
7031 if (!t)
7032 return type;
7033
7034 if (is_reference_type(t->get_pointed_to_type()))
7035 return peel_reference_type(t->get_pointed_to_type());
7036 return t->get_pointed_to_type();
7037}
7038
7039/// Return the leaf pointed-to type node of a @ref reference_type_def
7040/// node.
7041///
7042/// If the pointed-to type of a @ref reference_type_def node is itself
7043/// a @ref reference_type_def node, then recursively look at the
7044/// pointed-to type nodes to get the first one that is not a a @ref
7045/// reference_type_def node. This is what a leaf pointed-to type node
7046/// means.
7047///
7048/// Otherwise, if the pointed-to type node of @ref reference_type_def
7049/// is *NOT* a @ref reference_type_def node, then just return the
7050/// pointed-to type node.
7051///
7052/// And if the type node considered is not a @ref reference_type_def
7053/// node, then just return it.
7054///
7055/// @return the leaf pointed-to type node of a @p type.
7056const type_base*
7058{
7059 const reference_type_def* t = is_reference_type(type);
7060 if (!t)
7061 return type;
7062
7063 return peel_reference_type(t->get_pointed_to_type()).get();
7064}
7065
7066/// Return the leaf element type of an array.
7067///
7068/// If the element type is itself an array, then recursively return
7069/// the element type of that array itself.
7070///
7071/// @param type the array type to consider. If this is not an array
7072/// type, this type is returned by the function.
7073///
7074/// @return the leaf element type of the array @p type, or, if it's
7075/// not an array type, then just return @p.
7076const type_base_sptr
7077peel_array_type(const type_base_sptr& type)
7078{
7079 const array_type_def_sptr t = is_array_type(type);
7080 if (!t)
7081 return type;
7082
7083 return peel_array_type(t->get_element_type());
7084}
7085
7086/// Return the leaf element type of an array.
7087///
7088/// If the element type is itself an array, then recursively return
7089/// the element type of that array itself.
7090///
7091/// @param type the array type to consider. If this is not an array
7092/// type, this type is returned by the function.
7093///
7094/// @return the leaf element type of the array @p type, or, if it's
7095/// not an array type, then just return @p.
7096const type_base*
7098{
7099 const array_type_def* t = is_array_type(type);
7100 if (!t)
7101 return type;
7102
7103 return peel_array_type(t->get_element_type()).get();
7104}
7105
7106/// Return the leaf underlying type of a qualified type.
7107///
7108/// If the underlying type is itself a qualified type, then
7109/// recursively return the first underlying type of that qualified
7110/// type to return the first underlying type that is not a qualified type.
7111///
7112/// If the underlying type is NOT a qualified type, then just return
7113/// that underlying type.
7114///
7115/// @param type the qualified type to consider.
7116///
7117/// @return the leaf underlying type.
7118const type_base*
7120{
7121 const qualified_type_def* t = is_qualified_type(type);
7122 if (!t)
7123 return type;
7124
7125 return peel_qualified_type(t->get_underlying_type().get());
7126}
7127
7128/// Return the leaf underlying type of a qualified type.
7129///
7130/// If the underlying type is itself a qualified type, then
7131/// recursively return the first underlying type of that qualified
7132/// type to return the first underlying type that is not a qualified type.
7133///
7134/// If the underlying type is NOT a qualified type, then just return
7135/// that underlying type.
7136///
7137/// @param type the qualified type to consider.
7138///
7139/// @return the leaf underlying type.
7140const type_base_sptr
7141peel_qualified_type(const type_base_sptr& type)
7142{
7143 const qualified_type_def_sptr t = is_qualified_type(type);
7144 if (!t)
7145 return type;
7146
7147 return peel_qualified_type(t->get_underlying_type());
7148}
7149
7150/// Test if a given qualified type is const.
7151///
7152/// @pram t the qualified type to consider.
7153///
7154/// @return true iff @p t is a const qualified type.
7155bool
7156is_const_qualified_type(const qualified_type_def_sptr& t)
7157{
7158 if (!t)
7159 return false;
7160
7161 if (t->get_cv_quals() == qualified_type_def::CV_CONST)
7162 return true;
7163
7164 return false;
7165}
7166
7167/// Test if a given type is const-qualified.
7168///
7169/// @pram t the type to consider.
7170///
7171/// @return true iff @p t is a const qualified type.
7172bool
7173is_const_qualified_type(const type_base_sptr& t)
7174{
7175 qualified_type_def_sptr q = is_qualified_type(t);
7176 if (!q)
7177 return false;
7178 return is_const_qualified_type(q);
7179}
7180
7181/// If a qualified type is const, then return its underlying type.
7182///
7183/// @param q the qualified type to consider.
7184///
7185/// @return the underlying type of @p q if it's a const-qualified
7186/// type, otherwise, return @p q itself.
7187type_base_sptr
7188peel_const_qualified_type(const qualified_type_def_sptr& q)
7189{
7190 if (!q)
7191 return q;
7192
7194 return q->get_underlying_type();
7195
7196 return q;
7197}
7198
7199/// Return the leaf underlying type of a qualified or typedef type.
7200///
7201/// If the underlying type is itself a qualified or typedef type, then
7202/// recursively return the first underlying type of that qualified or
7203/// typedef type to return the first underlying type that is not a
7204/// qualified or typedef type.
7205///
7206/// If the underlying type is NOT a qualified nor a typedef type, then
7207/// just return that underlying type.
7208///
7209/// @param type the qualified or typedef type to consider.
7210///
7211/// @return the leaf underlying type.
7212type_base*
7214{
7215 while (is_typedef(type) || is_qualified_type(type))
7216 {
7217 if (const typedef_decl* t = is_typedef(type))
7218 type = peel_typedef_type(t);
7219
7220 if (const qualified_type_def* t = is_qualified_type(type))
7221 type = peel_qualified_type(t);
7222 }
7223
7224 return const_cast<type_base*>(type);
7225}
7226
7227/// Return the leaf underlying type of a qualified or typedef type.
7228///
7229/// If the underlying type is itself a qualified or typedef type, then
7230/// recursively return the first underlying type of that qualified or
7231/// typedef type to return the first underlying type that is not a
7232/// qualified or typedef type.
7233///
7234/// If the underlying type is NOT a qualified nor a typedef type, then
7235/// just return that underlying type.
7236///
7237/// @param type the qualified or typedef type to consider.
7238///
7239/// @return the leaf underlying type.
7240type_base_sptr
7241peel_qualified_or_typedef_type(const type_base_sptr &t)
7242{
7243 type_base_sptr type = t;
7244 while (is_typedef(type) || is_qualified_type(type))
7245 {
7246 if (typedef_decl_sptr t = is_typedef(type))
7247 type = peel_typedef_type(t);
7248
7249 if (qualified_type_def_sptr t = is_qualified_type(type))
7250 type = peel_qualified_type(t);
7251 }
7252
7253 return type;
7254}
7255
7256/// Return the leaf underlying or pointed-to type node of a @ref
7257/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7258/// or @ref array_type_def node.
7259///
7260/// @param type the type to peel.
7261///
7262/// @return the leaf underlying or pointed-to type node of @p type.
7263type_base_sptr
7265{
7266 type_base_sptr typ = type;
7267 while (is_typedef(typ)
7268 || is_pointer_type(typ)
7269 || is_reference_type(typ)
7270 || is_array_type(typ))
7271 {
7272 if (typedef_decl_sptr t = is_typedef(typ))
7273 typ = peel_typedef_type(t);
7274
7276 typ = peel_pointer_type(t);
7277
7279 typ = peel_reference_type(t);
7280
7281 if (const array_type_def_sptr t = is_array_type(typ))
7282 typ = peel_array_type(t);
7283 }
7284
7285 return typ;
7286}
7287
7288/// Return the leaf underlying or pointed-to type node of a @ref
7289/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7290/// node.
7291///
7292/// @param type the type to peel.
7293///
7294/// @return the leaf underlying or pointed-to type node of @p type.
7295type_base*
7297{
7298 while (is_typedef(type)
7299 || is_pointer_type(type)
7300 || is_reference_type(type)
7301 || is_array_type(type))
7302 {
7303 if (const typedef_decl* t = is_typedef(type))
7304 type = peel_typedef_type(t);
7305
7306 if (const pointer_type_def* t = is_pointer_type(type))
7307 type = peel_pointer_type(t);
7308
7309 if (const reference_type_def* t = is_reference_type(type))
7310 type = peel_reference_type(t);
7311
7312 if (const array_type_def* t = is_array_type(type))
7313 type = peel_array_type(t);
7314 }
7315
7316 return const_cast<type_base*>(type);
7317}
7318
7319/// Return the leaf underlying or pointed-to type node of a @ref
7320/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7321/// node.
7322///
7323/// @param type the type to peel.
7324///
7325/// @return the leaf underlying or pointed-to type node of @p type.
7326type_base*
7328 bool peel_qual_type)
7329{
7330 while (is_typedef(type)
7331 || is_pointer_type(type)
7332 || is_reference_type(type)
7333 || is_array_type(type)
7334 || (peel_qual_type && is_qualified_type(type)))
7335 {
7336 if (const typedef_decl* t = is_typedef(type))
7337 type = peel_typedef_type(t);
7338
7339 if (const pointer_type_def* t = is_pointer_type(type))
7340 type = peel_pointer_type(t);
7341
7342 if (const reference_type_def* t = is_reference_type(type))
7343 type = peel_reference_type(t);
7344
7345 if (const array_type_def* t = is_array_type(type))
7346 type = peel_array_type(t);
7347
7348 if (peel_qual_type)
7349 if (const qualified_type_def* t = is_qualified_type(type))
7350 type = peel_qualified_type(t);
7351 }
7352
7353 return const_cast<type_base*>(type);
7354}
7355
7356/// Return the leaf underlying or pointed-to type node of a, @ref
7357/// pointer_type_def, @ref reference_type_def or @ref
7358/// qualified_type_def type node.
7359///
7360/// @param type the type to peel.
7361///
7362/// @param peel_qualified_type if true, also peel qualified types.
7363///
7364/// @return the leaf underlying or pointed-to type node of @p type.
7365type_base*
7367 bool peel_qual_type)
7368{
7369 while (is_pointer_type(type)
7370 || is_reference_type(type)
7371 || is_array_type(type)
7372 || (peel_qual_type && is_qualified_type(type)))
7373 {
7374 if (const pointer_type_def* t = is_pointer_type(type))
7375 type = peel_pointer_type(t);
7376
7377 if (const reference_type_def* t = is_reference_type(type))
7378 type = peel_reference_type(t);
7379
7380 if (const array_type_def* t = is_array_type(type))
7381 type = peel_array_type(t);
7382
7383 if (peel_qual_type)
7384 if (const qualified_type_def* t = is_qualified_type(type))
7385 type = peel_qualified_type(t);
7386 }
7387
7388 return const_cast<type_base*>(type);
7389}
7390
7391/// Clone an array type.
7392///
7393/// Note that the element type of the new array is shared witht the
7394/// old one.
7395///
7396/// @param array the array type to clone.
7397///
7398/// @return a newly built array type. Note that it needs to be added
7399/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7400/// bound to the one of that scope. Otherwise, its lifetime is bound
7401/// to the lifetime of its containing shared pointer.
7404{
7405 vector<array_type_def::subrange_sptr> subranges;
7406
7407 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7408 array->get_subranges().begin();
7409 i != array->get_subranges().end();
7410 ++i)
7411 {
7413 (new array_type_def::subrange_type(array->get_environment(),
7414 (*i)->get_name(),
7415 (*i)->get_lower_bound(),
7416 (*i)->get_upper_bound(),
7417 (*i)->get_underlying_type(),
7418 (*i)->get_location(),
7419 (*i)->get_language()));
7420 subrange->is_non_finite((*i)->is_non_finite());
7421 if (scope_decl *scope = (*i)->get_scope())
7422 add_decl_to_scope(subrange, scope);
7423 subranges.push_back(subrange);
7424 }
7425
7426 array_type_def_sptr result
7427 (new array_type_def(array->get_element_type(),
7428 subranges, array->get_location()));
7429
7430 return result;
7431}
7432
7433/// Clone a typedef type.
7434///
7435/// Note that the underlying type of the newly constructed typedef is
7436/// shared with the old one.
7437///
7438/// @param t the typedef to clone.
7439///
7440/// @return the newly constructed typedef. Note that it needs to be
7441/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7442/// to be bound to the one of that scope. Otherwise, its lifetime is
7443/// bound to the lifetime of its containing shared pointer.
7446{
7447 if (!t)
7448 return t;
7449
7450 typedef_decl_sptr result
7451 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7452 t->get_location(), t->get_linkage_name(),
7453 t->get_visibility()));
7454 return result;
7455}
7456
7457/// Clone a qualifiend type.
7458///
7459/// Note that underlying type of the newly constructed qualified type
7460/// is shared with the old one.
7461///
7462/// @param t the qualified type to clone.
7463///
7464/// @return the newly constructed qualified type. Note that it needs
7465/// to be added to a scope (e.g, using add_decl_to_scope) for its
7466/// lifetime to be bound to the one of that scope. Otherwise, its
7467/// lifetime is bound to the lifetime of its containing shared
7468/// pointer.
7469qualified_type_def_sptr
7470clone_qualified_type(const qualified_type_def_sptr& t)
7471{
7472 if (!t)
7473 return t;
7474
7475 qualified_type_def_sptr result
7476 (new qualified_type_def(t->get_underlying_type(),
7477 t->get_cv_quals(), t->get_location()));
7478
7479 return result;
7480}
7481
7482/// Clone a typedef, an array or a qualified tree.
7483///
7484/// @param type the typedef, array or qualified tree to clone. any
7485/// order.
7486///
7487/// @return the cloned type, or NULL if @type was neither a typedef,
7488/// array nor a qualified type.
7489static type_base_sptr
7490clone_typedef_array_qualified_type(type_base_sptr type)
7491{
7492 if (!type)
7493 return type;
7494
7495 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7496 type_base_sptr result;
7497
7498 if (typedef_decl_sptr t = is_typedef(type))
7499 result = clone_typedef(is_typedef(t));
7500 else if (qualified_type_def_sptr t = is_qualified_type(type))
7501 result = clone_qualified_type(t);
7502 else if (array_type_def_sptr t = is_array_type(type))
7503 result = clone_array(t);
7504 else
7505 return type_base_sptr();
7506
7507 if (scope)
7508 add_decl_to_scope(is_decl(result), scope);
7509
7510 return result;
7511}
7512
7513/// Clone a type tree made of an array or a typedef of array.
7514///
7515/// Note that this can be a tree which root node is a typedef an which
7516/// sub-tree can be any arbitrary combination of typedef, qualified
7517/// type and arrays.
7518///
7519/// @param t the array or typedef of qualified array to consider.
7520///
7521/// @return a clone of @p t.
7522type_base_sptr
7523clone_array_tree(const type_base_sptr t)
7524{
7526
7527 scope_decl* scope = is_decl(t)->get_scope();
7528 type_base_sptr result = clone_typedef_array_qualified_type(t);
7529 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7530
7531 type_base_sptr subtree;
7532 if (typedef_decl_sptr type = is_typedef(result))
7533 {
7534 type_base_sptr s =
7535 clone_typedef_array_qualified_type(type->get_underlying_type());
7536 if (s)
7537 {
7538 subtree = s;
7539 type->set_underlying_type(subtree);
7540 }
7541 }
7542 else if (array_type_def_sptr type = is_array_type(result))
7543 {
7544 type_base_sptr s =
7545 clone_typedef_array_qualified_type(type->get_element_type());
7546 if (s)
7547 {
7548 subtree = s;
7549 type->set_element_type(subtree);
7550 }
7551 }
7552 add_decl_to_scope(is_decl(subtree), scope);
7553
7554 for (;;)
7555 {
7556 if (typedef_decl_sptr t = is_typedef(subtree))
7557 {
7558 type_base_sptr s =
7559 clone_typedef_array_qualified_type(t->get_underlying_type());
7560 if (s)
7561 {
7562 scope_decl* scope =
7563 is_decl(t->get_underlying_type())->get_scope();
7564 ABG_ASSERT(scope);
7565 add_decl_to_scope(is_decl(s), scope);
7566 t->set_underlying_type (s);
7567 subtree = s;
7568 }
7569 else
7570 break;
7571 }
7572 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7573 {
7574 type_base_sptr s =
7575 clone_typedef_array_qualified_type(t->get_underlying_type());
7576 if (s)
7577 {
7578 scope_decl* scope =
7579 is_decl(t->get_underlying_type())->get_scope();
7580 ABG_ASSERT(scope);
7581 add_decl_to_scope(is_decl(s), scope);
7582 t->set_underlying_type(s);
7583 subtree = s;
7584 }
7585 else
7586 break;
7587 }
7588 else if (array_type_def_sptr t = is_array_type(subtree))
7589 {
7590 type_base_sptr e = t->get_element_type();
7591 if (is_typedef(e) || is_qualified_type(e))
7592 {
7593 type_base_sptr s =
7594 clone_typedef_array_qualified_type(e);
7595 if (s)
7596 {
7597 scope_decl* scope = is_decl(e)->get_scope();
7598 ABG_ASSERT(scope);
7599 add_decl_to_scope(is_decl(s), scope);
7600 t->set_element_type(s);
7601 }
7602 else
7603 break;
7604 }
7605 break;
7606 }
7607 else
7608 break;
7609 }
7610 return result;
7611}
7612
7613/// Update the qualified name of a given sub-tree.
7614///
7615/// @param d the sub-tree for which to update the qualified name.
7616static void
7617update_qualified_name(decl_base * d)
7618{
7619 ::qualified_name_setter setter;
7620 d->traverse(setter);
7621}
7622
7623/// Update the qualified name of a given sub-tree.
7624///
7625/// @param d the sub-tree for which to update the qualified name.
7626static void
7627update_qualified_name(decl_base_sptr d)
7628{return update_qualified_name(d.get());}
7629
7630// <scope_decl stuff>
7631
7632/// Hash a type by returning the pointer value of its canonical type.
7633///
7634/// @param l the type to hash.
7635///
7636/// @return the the pointer value of the canonical type of @p l.
7637size_t
7638canonical_type_hash::operator()(const type_base_sptr& l) const
7639{return operator()(l.get());}
7640
7641/// Hash a (canonical) type by returning its pointer value
7642///
7643/// @param l the canonical type to hash.
7644///
7645/// @return the pointer value of the canonical type of @p l.
7646size_t
7648{return reinterpret_cast<size_t>(l);}
7649
7650struct scope_decl::priv
7651{
7652 declarations members_;
7653 declarations sorted_members_;
7654 type_base_sptrs_type member_types_;
7655 type_base_sptrs_type sorted_member_types_;
7656 scopes member_scopes_;
7657 canonical_type_sptr_set_type canonical_types_;
7658 type_base_sptrs_type sorted_canonical_types_;
7659 bool clear_sorted_member_types_cache_ = false;
7660}; // end struct scope_decl::priv
7661
7662/// Constructor of the @ref scope_decl type.
7663///
7664/// @param the environment to use for the new instance.
7665///
7666/// @param the name of the scope decl.
7667///
7668/// @param locus the source location where the scope_decl is defined.
7669///
7670/// @param vis the visibility of the declaration.
7671scope_decl::scope_decl(const environment& env,
7672 const string& name,
7673 const location& locus,
7674 visibility vis)
7675 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7676 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7677 priv_(new priv)
7678{}
7679
7680/// Constructor of the @ref scope_decl type.
7681///
7682/// @param the environment to use for the new instance.
7683///
7684/// @param l the source location where the scope_decl is defined.
7685///
7686/// @param vis the visibility of the declaration.
7687scope_decl::scope_decl(const environment& env, location& l)
7688 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7689 decl_base(env, "", l),
7690 priv_(new priv)
7691{}
7692
7693/// @eturn the set of canonical types of the the current scope.
7696{return priv_->canonical_types_;}
7697
7698/// @eturn the set of canonical types of the the current scope.
7701{return const_cast<scope_decl*>(this)->get_canonical_types();}
7702
7703/// Return a vector of sorted canonical types of the current scope.
7704///
7705/// The types are sorted "almost topologically". That means, they are
7706/// sorted using the lexicographic order of the string representing
7707/// the location their definition point. If a type doesn't have a
7708/// location, then its pretty representation is used.
7709///
7710/// @return a vector of sorted canonical types of the current scope.
7713{
7714 if (priv_->sorted_canonical_types_.empty())
7715 {
7716 for (canonical_type_sptr_set_type::const_iterator e =
7717 get_canonical_types().begin();
7718 e != get_canonical_types().end();
7719 ++e)
7720 priv_->sorted_canonical_types_.push_back(*e);
7721
7722 type_topo_comp comp;
7723 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7724 priv_->sorted_canonical_types_.end(),
7725 comp);
7726 }
7727 return priv_->sorted_canonical_types_;
7728}
7729
7730/// Getter for the member declarations carried by the current @ref
7731/// scope_decl.
7732///
7733/// @return the member declarations carried by the current @ref
7734/// scope_decl.
7737{return priv_->members_;}
7738
7739/// Getter for the member declarations carried by the current @ref
7740/// scope_decl.
7741///
7742/// @return the member declarations carried by the current @ref
7743/// scope_decl.
7746{return priv_->members_;}
7747
7748/// Getter for the sorted member declarations carried by the current
7749/// @ref scope_decl.
7750///
7751/// @return the sorted member declarations carried by the current @ref
7752/// scope_decl. The declarations are sorted topologically.
7755{
7756 decl_topo_comp comp;
7757 if (priv_->sorted_members_.empty())
7758 {
7759 for (declarations::const_iterator i = get_member_decls().begin();
7760 i != get_member_decls().end();
7761 ++i)
7762 priv_->sorted_members_.push_back(*i);
7763
7764 std::stable_sort(priv_->sorted_members_.begin(),
7765 priv_->sorted_members_.end(),
7766 comp);
7767 }
7768 return priv_->sorted_members_;
7769}
7770
7771/// Getter for the number of anonymous classes contained in this
7772/// scope.
7773///
7774/// @return the number of anonymous classes contained in this scope.
7775size_t
7777{
7778 int result = 0;
7779 for (declarations::const_iterator it = get_member_decls().begin();
7780 it != get_member_decls().end();
7781 ++it)
7782 if (class_decl_sptr t = is_class_type(*it))
7783 if (t->get_is_anonymous())
7784 ++result;
7785
7786 return result;
7787}
7788
7789/// Getter for the number of anonymous unions contained in this
7790/// scope.
7791///
7792/// @return the number of anonymous unions contained in this scope.
7793size_t
7795{
7796 int result = 0;
7797 for (declarations::const_iterator it = get_member_decls().begin();
7798 it != get_member_decls().end();
7799 ++it)
7800 if (union_decl_sptr t = is_union_type(*it))
7801 if (t->get_is_anonymous())
7802 ++result;
7803
7804 return result;
7805}
7806
7807/// Getter for the number of anonymous enums contained in this
7808/// scope.
7809///
7810/// @return the number of anonymous enums contained in this scope.
7811size_t
7813{
7814 int result = 0;
7815 for (declarations::const_iterator it = get_member_decls().begin();
7816 it != get_member_decls().end();
7817 ++it)
7818 if (enum_type_decl_sptr t = is_enum_type(*it))
7819 if (t->get_is_anonymous())
7820 ++result;
7821
7822 return result;
7823}
7824
7825/// Getter for the scopes carried by the current scope.
7826///
7827/// @return the scopes carried by the current scope.
7830{return priv_->member_scopes_;}
7831
7832/// Getter for the scopes carried by the current scope.
7833///
7834/// @return the scopes carried by the current scope.
7835const scope_decl::scopes&
7837{return priv_->member_scopes_;}
7838
7839/// Test if the current scope is empty.
7840///
7841/// @return true iff the current scope is empty.
7842bool
7844{
7845 return (get_member_decls().empty()
7846 && get_canonical_types().empty());
7847}
7848
7849/// Set the translation unit of a decl
7850///
7851/// It also perform some IR integrity checks.
7852///
7853/// This is a sub-routine of scope_decl::{insert,add}_member_decl.
7854///
7855/// @param decl the decl to set the translation unit for.
7856///
7857/// @param tu the translation unit to set.
7858static void
7859maybe_set_translation_unit(const decl_base_sptr& decl,
7860 translation_unit* tu)
7861{
7862 ABG_ASSERT(tu);
7863
7864 if (translation_unit* existing_tu = decl->get_translation_unit())
7865 // The decl already belongs to a translation unit.
7866 // Either:
7867 //
7868 // 1/ it's a unique type, in which case we should not add it to
7869 // any translation unique since unique types are "logically"
7870 // supposed to belong to no translation unit in particular, as
7871 // they are unique.
7872 //
7873 // 2/ or the decl was already added to this translation unit.
7874 ABG_ASSERT(tu == existing_tu || is_unique_type(is_type(decl)));
7875 else
7876 decl->set_translation_unit(tu);
7877}
7878
7879/// Add a member decl to this scope. Note that user code should not
7880/// use this, but rather use add_decl_to_scope.
7881///
7882/// Note that this function updates the qualified name of the member
7883/// decl that is added. It also sets the scope of the member. Thus,
7884/// it ABG_ASSERTs that member should not have its scope set, prior to
7885/// calling this function.
7886///
7887/// @param member the new member decl to add to this scope.
7888decl_base_sptr
7889scope_decl::add_member_decl(const decl_base_sptr& member)
7890{
7891 ABG_ASSERT(!has_scope(member));
7892
7893 member->set_scope(this);
7894 priv_->members_.push_back(member);
7895 if (is_type(member))
7896 {
7897 priv_->member_types_.push_back(is_type(member));
7898 priv_->clear_sorted_member_types_cache_ = true;
7899 }
7900
7901 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
7902 priv_->member_scopes_.push_back(m);
7903
7904 update_qualified_name(member);
7905
7907 maybe_set_translation_unit(member, tu);
7908
7910
7911 return member;
7912}
7913
7914/// Get the member types of this @ref scope_decl.
7915///
7916/// @return a vector of the member types of this ref class_or_union.
7919{return priv_->member_types_;}
7920
7921/// Find a member type of a given name, inside the current @ref
7922/// scope_decl.
7923///
7924/// @param name the name of the member type to look for.
7925///
7926/// @return a pointer to the @ref type_base that represents the member
7927/// type of name @p name, for the current scope.
7928type_base_sptr
7929scope_decl::find_member_type(const string& name) const
7930{
7931 for (auto t : get_member_types())
7932 if (get_type_name(t, /*qualified*/false) == name)
7933 return t;
7934 return type_base_sptr();
7935}
7936
7937/// Insert a member type.
7938///
7939/// @param t the type to insert in the @ref scope_decl type.
7940///
7941/// @param an iterator right before which @p t has to be inserted.
7942void
7944 declarations::iterator before)
7945{
7946 decl_base_sptr d = get_type_declaration(t);
7947 ABG_ASSERT(d);
7948 ABG_ASSERT(!has_scope(d));
7949
7950 priv_->member_types_.push_back(t);
7951 priv_->clear_sorted_member_types_cache_= true;
7952 insert_member_decl(d, before);
7953}
7954
7955/// Add a member type to the current instance of class_or_union.
7956///
7957/// @param t the member type to add. It must not have been added to a
7958/// scope, otherwise this will violate an ABG_ASSERTion.
7959void
7962
7963/// Add a member type to the current instance of class_or_union.
7964///
7965/// @param t the type to be added as a member type to the current
7966/// instance of class_or_union. An instance of class_or_union::member_type
7967/// will be created out of @p t and and added to the the class.
7968///
7969/// @param a the access specifier for the member type to be created.
7970type_base_sptr
7972{
7973 decl_base_sptr d = get_type_declaration(t);
7974 ABG_ASSERT(d);
7976 add_member_type(t);
7978 return t;
7979}
7980
7981/// Remove a member type from the current @ref class_or_union scope.
7982///
7983/// @param t the type to remove.
7984void
7986{
7987 for (auto i = priv_->member_types_.begin();
7988 i != priv_->member_types_.end();
7989 ++i)
7990 {
7991 if (*((*i)) == *t)
7992 {
7993 priv_->member_types_.erase(i);
7994 return;
7995 }
7996 }
7997}
7998
7999/// Get the sorted member types of this @ref scope_decl
8000///
8001/// @return a vector of the sorted member types of this ref
8002/// class_or_union.
8005{
8006 if (priv_->clear_sorted_member_types_cache_)
8007 {
8008 priv_->sorted_member_types_.clear();
8009 priv_->clear_sorted_member_types_cache_ = false;
8010 }
8011
8012 if (priv_->sorted_member_types_.empty())
8013 {
8014 unordered_set<type_base_sptr> canonical_pointer_types;
8015 for (auto t : get_member_types())
8016 {
8018 priv_->sorted_member_types_.push_back(t);
8019 else if (auto c = t->get_canonical_type())
8020 canonical_pointer_types.insert(c);
8021 else
8022 canonical_pointer_types.insert(t);
8023 }
8024
8025 for (auto t : canonical_pointer_types)
8026 priv_->sorted_member_types_.push_back(t);
8027
8028 type_topo_comp comp;
8029 std::stable_sort(priv_->sorted_member_types_.begin(),
8030 priv_->sorted_member_types_.end(),
8031 comp);
8032 }
8033
8034 const ir::environment& env = get_environment();
8036 priv_->clear_sorted_member_types_cache_ = true;
8037
8038 return priv_->sorted_member_types_;
8039}
8040
8041/// Insert a member decl to this scope, right before an element
8042/// pointed to by a given iterator. Note that user code should not
8043/// use this, but rather use insert_decl_into_scope.
8044///
8045/// Note that this function updates the qualified name of the inserted
8046/// member.
8047///
8048/// @param member the new member decl to add to this scope.
8049///
8050/// @param before an interator pointing to the element before which
8051/// the new member should be inserted.
8052decl_base_sptr
8054 declarations::iterator before)
8055{
8056 ABG_ASSERT(!member->get_scope());
8057
8058 member->set_scope(this);
8059 priv_->members_.insert(before, member);
8060
8061 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8062 priv_-> member_scopes_.push_back(m);
8063
8064 update_qualified_name(member);
8065
8067 maybe_set_translation_unit(member, tu);
8068
8070
8071 return member;
8072}
8073
8074/// Remove a declaration from the current scope.
8075///
8076/// @param member the declaration to remove from the scope.
8077void
8079{
8080 for (declarations::iterator i = priv_->members_.begin();
8081 i != priv_->members_.end();
8082 ++i)
8083 {
8084 if (**i == *member)
8085 {
8086 priv_->members_.erase(i);
8087 // Do not access i after this point as it's invalided by the
8088 // erase call.
8089 break;
8090 }
8091 }
8092
8093 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8094 if (scope)
8095 {
8096 for (scopes::iterator i = priv_->member_scopes_.begin();
8097 i != priv_->member_scopes_.end();
8098 ++i)
8099 {
8100 if (**i == *member)
8101 {
8102 priv_->member_scopes_.erase(i);
8103 break;
8104 }
8105 }
8106 }
8107
8108 member->set_scope(nullptr);
8109 member->set_translation_unit(nullptr);
8110}
8111
8112/// Compares two instances of @ref scope_decl.
8113///
8114/// If the two intances are different, set a bitfield to give some
8115/// insight about the kind of differences there are.
8116///
8117/// @param l the first artifact of the comparison.
8118///
8119/// @param r the second artifact of the comparison.
8120///
8121/// @param k a pointer to a bitfield that gives information about the
8122/// kind of changes there are between @p l and @p r. This one is set
8123/// iff @p k is non-null and the function returns false.
8124///
8125/// Please note that setting k to a non-null value does have a
8126/// negative performance impact because even if @p l and @p r are not
8127/// equal, the function keeps up the comparison in order to determine
8128/// the different kinds of ways in which they are different.
8129///
8130/// @return true if @p l equals @p r, false otherwise.
8131bool
8133{
8134 bool result = true;
8135
8136 if (!l.decl_base::operator==(r))
8137 {
8138 result = false;
8139 if (k)
8141 else
8143 }
8144
8145 scope_decl::declarations::const_iterator i, j;
8146 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8147 i != l.get_member_decls().end() && j != r.get_member_decls().end();
8148 ++i, ++j)
8149 {
8150 if (**i != **j)
8151 {
8152 result = false;
8153 if (k)
8154 {
8155 *k |= SUBTYPE_CHANGE_KIND;
8156 break;
8157 }
8158 else
8160 }
8161 }
8162
8163 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8164 {
8165 result = false;
8166 if (k)
8168 else
8170 }
8171
8172 ABG_RETURN(result);
8173}
8174
8175/// Return true iff both scopes have the same names and have the same
8176/// member decls.
8177///
8178/// This function doesn't check for equality of the scopes of its
8179/// arguments.
8180bool
8182{
8183 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8184 if (!other)
8185 return false;
8186
8187 return equals(*this, *other, 0);
8188}
8189
8190/// Equality operator for @ref scope_decl_sptr.
8191///
8192/// @param l the left hand side operand of the equality operator.
8193///
8194/// @pram r the right hand side operand of the equalify operator.
8195///
8196/// @return true iff @p l equals @p r.
8197bool
8199{
8200 if (!!l != !!r)
8201 return false;
8202 if (l.get() == r.get())
8203 return true;
8204 return *l == *r;
8205}
8206
8207/// Inequality operator for @ref scope_decl_sptr.
8208///
8209/// @param l the left hand side operand of the equality operator.
8210///
8211/// @pram r the right hand side operand of the equalify operator.
8212///
8213/// @return true iff @p l equals @p r.
8214bool
8216{return !operator==(l, r);}
8217
8218/// Find a member of the current scope and return an iterator on it.
8219///
8220/// @param decl the scope member to find.
8221///
8222/// @param i the iterator to set to the member @p decl. This is set
8223/// iff the function returns true.
8224///
8225/// @return true if the member decl was found, false otherwise.
8226bool
8228 declarations::iterator& i)
8229{
8230 if (!decl)
8231 return false;
8232
8233 if (get_member_decls().empty())
8234 {
8235 i = get_member_decls().end();
8236 return false;
8237 }
8238
8239 for (declarations::iterator it = get_member_decls().begin();
8240 it != get_member_decls().end();
8241 ++it)
8242 {
8243 if ((*it).get() == decl)
8244 {
8245 i = it;
8246 return true;
8247 }
8248 }
8249
8250 return false;
8251}
8252
8253/// Find a member of the current scope and return an iterator on it.
8254///
8255/// @param decl the scope member to find.
8256///
8257/// @param i the iterator to set to the member @p decl. This is set
8258/// iff the function returns true.
8259///
8260/// @return true if the member decl was found, false otherwise.
8261bool
8263 declarations::iterator& i)
8264{return find_iterator_for_member(decl.get(), i);}
8265
8266/// This implements the ir_traversable_base::traverse pure virtual
8267/// function.
8268///
8269/// @param v the visitor used on the current instance of scope_decl
8270/// and on its member nodes.
8271///
8272/// @return true if the traversal of the tree should continue, false
8273/// otherwise.
8274bool
8276{
8277 if (visiting())
8278 return true;
8279
8280 if (v.visit_begin(this))
8281 {
8282 visiting(true);
8283 for (scope_decl::declarations::const_iterator i =
8284 get_member_decls().begin();
8285 i != get_member_decls ().end();
8286 ++i)
8287 if (!(*i)->traverse(v))
8288 break;
8289 visiting(false);
8290 }
8291 return v.visit_end(this);
8292}
8293
8294scope_decl::~scope_decl()
8295{}
8296
8297/// Appends a declaration to a given scope, if the declaration
8298/// doesn't already belong to one and if the declaration is not for a
8299/// type that is supposed to be unique.
8300///
8301/// @param decl the declaration to add to the scope
8302///
8303/// @param scope the scope to append the declaration to
8304decl_base_sptr
8305add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8306{
8307 if (!scope)
8308 return decl;
8309
8310 if (scope && decl && !decl->get_scope())
8311 decl = scope->add_member_decl(decl);
8312
8313 return decl;
8314}
8315
8316/// Appends a declaration to a given scope, if the declaration doesn't
8317/// already belong to a scope.
8318///
8319/// @param decl the declaration to add append to the scope
8320///
8321/// @param scope the scope to append the decl to
8322decl_base_sptr
8323add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8324{return add_decl_to_scope(decl, scope.get());}
8325
8326/// Remove a given decl from its scope
8327///
8328/// @param decl the decl to remove from its scope.
8329void
8330remove_decl_from_scope(decl_base_sptr decl)
8331{
8332 if (!decl)
8333 return;
8334
8335 scope_decl* scope = decl->get_scope();
8336 scope->remove_member_decl(decl);
8337}
8338
8339/// Inserts a declaration into a given scope, before a given IR child
8340/// node of the scope.
8341///
8342/// @param decl the declaration to insert into the scope.
8343///
8344/// @param before an iterator pointing to the child IR node before
8345/// which to insert the declaration.
8346///
8347/// @param scope the scope into which to insert the declaration.
8348decl_base_sptr
8349insert_decl_into_scope(decl_base_sptr decl,
8350 scope_decl::declarations::iterator before,
8351 scope_decl* scope)
8352{
8353 if (scope && decl && !decl->get_scope())
8354 {
8355 decl_base_sptr d = scope->insert_member_decl(decl, before);
8356 decl = d;
8357 }
8358 return decl;
8359}
8360
8361/// Inserts a declaration into a given scope, before a given IR child
8362/// node of the scope.
8363///
8364/// @param decl the declaration to insert into the scope.
8365///
8366/// @param before an iterator pointing to the child IR node before
8367/// which to insert the declaration.
8368///
8369/// @param scope the scope into which to insert the declaration.
8370decl_base_sptr
8371insert_decl_into_scope(decl_base_sptr decl,
8372 scope_decl::declarations::iterator before,
8373 scope_decl_sptr scope)
8374{return insert_decl_into_scope(decl, before, scope.get());}
8375
8376/// Constructor of the @ref global_scope type.
8377///
8378/// @param tu the translation unit the scope belongs to.
8379global_scope::global_scope(translation_unit *tu)
8380 : type_or_decl_base(tu->get_environment(),
8381 GLOBAL_SCOPE_DECL
8382 | ABSTRACT_DECL_BASE
8383 | ABSTRACT_SCOPE_DECL),
8384 decl_base(tu->get_environment(), "", location()),
8385 scope_decl(tu->get_environment(), "", location()),
8386 translation_unit_(tu)
8387{
8388 runtime_type_instance(this);
8389}
8390
8391/// return the global scope as seen by a given declaration.
8392///
8393/// @param decl the declaration to consider.
8394///
8395/// @return the global scope of the decl, or a null pointer if the
8396/// decl is not yet added to a translation_unit.
8397const global_scope*
8399{
8400 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8401 return s;
8402
8403 scope_decl* scope = decl.get_scope();
8404 while (scope && !dynamic_cast<global_scope*>(scope))
8405 scope = scope->get_scope();
8406
8407 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8408}
8409
8410/// return the global scope as seen by a given declaration.
8411///
8412/// @param decl the declaration to consider.
8413///
8414/// @return the global scope of the decl, or a null pointer if the
8415/// decl is not yet added to a translation_unit.
8416const global_scope*
8418{return get_global_scope(*decl);}
8419
8420/// Return the global scope as seen by a given declaration.
8421///
8422/// @param decl the declaration to consider.
8423///
8424/// @return the global scope of the decl, or a null pointer if the
8425/// decl is not yet added to a translation_unit.
8426const global_scope*
8427get_global_scope(const shared_ptr<decl_base> decl)
8428{return get_global_scope(decl.get());}
8429
8430/// Return the a scope S containing a given declaration and that is
8431/// right under a given scope P.
8432///
8433/// Note that @p scope must come before @p decl in topological
8434/// order.
8435///
8436/// @param decl the decl for which to find a scope.
8437///
8438/// @param scope the scope under which the resulting scope must be.
8439///
8440/// @return the resulting scope.
8441const scope_decl*
8443 const scope_decl* scope)
8444{
8445 if (!decl)
8446 return 0;
8447
8448 if (scope == 0)
8449 return get_global_scope(decl);
8450
8451 // Handle the case where decl is a scope itself.
8452 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8453 if (!s)
8454 s = decl->get_scope();
8455
8456 if (is_global_scope(s))
8457 return scope;
8458
8459 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8460 // same. The caller needs to be prepared to deal with this case.
8461 if (s == scope)
8462 return s;
8463
8464 while (s && !is_global_scope(s) && s->get_scope() != scope)
8465 s = s->get_scope();
8466
8467 if (!s || is_global_scope(s))
8468 // SCOPE must come before decl in topological order, but I don't
8469 // know how to ensure that ...
8470 return scope;
8471 ABG_ASSERT(s);
8472
8473 return s;
8474}
8475
8476/// Return the a scope S containing a given declaration and that is
8477/// right under a given scope P.
8478///
8479/// @param decl the decl for which to find a scope.
8480///
8481/// @param scope the scope under which the resulting scope must be.
8482///
8483/// @return the resulting scope.
8484const scope_decl*
8485get_top_most_scope_under(const decl_base_sptr decl,
8486 const scope_decl* scope)
8487{return get_top_most_scope_under(decl.get(), scope);}
8488
8489/// Return the a scope S containing a given declaration and that is
8490/// right under a given scope P.
8491///
8492/// @param decl the decl for which to find a scope.
8493///
8494/// @param scope the scope under which the resulting scope must be.
8495///
8496/// @return the resulting scope.
8497const scope_decl*
8498get_top_most_scope_under(const decl_base_sptr decl,
8499 const scope_decl_sptr scope)
8500{return get_top_most_scope_under(decl, scope.get());}
8501
8502// </scope_decl stuff>
8503
8504
8505/// Get the string representation of a CV qualifier bitmap.
8506///
8507/// @param cv_quals the bitmap of CV qualifiers to consider.
8508///
8509/// @return the string representation.
8510string
8512{
8513 string repr;
8514 if (cv_quals & qualified_type_def::CV_RESTRICT)
8515 repr = "restrict";
8516 if (cv_quals & qualified_type_def::CV_CONST)
8517 {
8518 if (!repr.empty())
8519 repr += ' ';
8520 repr += "const";
8521 }
8522 if (cv_quals & qualified_type_def::CV_VOLATILE)
8523 {
8524 if (!repr.empty())
8525 repr += ' ';
8526 repr += "volatile";
8527 }
8528 return repr;
8529}
8530
8531/// Build and return a copy of the name of an ABI artifact that is
8532/// either a type or a decl.
8533///
8534/// @param tod the ABI artifact to get the name for.
8535///
8536/// @param qualified if yes, return the qualified name of @p tod;
8537/// otherwise, return the non-qualified name;
8538///
8539/// @return the name of @p tod.
8540string
8541get_name(const type_or_decl_base *tod, bool qualified)
8542{
8543 string result;
8544
8545 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8546
8547 if (type_base* t = dynamic_cast<type_base*>(a))
8548 result = get_type_name(t, qualified);
8549 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8550 {
8551 if (qualified)
8552 result = d->get_qualified_name();
8553 else
8554 result = d->get_name();
8555 }
8556 else
8557 // We should never reach this point.
8558 abort();
8559
8560 return result;
8561}
8562
8563/// Build and return a copy of the name of an ABI artifact that is
8564/// either a type of a decl.
8565///
8566/// @param tod the ABI artifact to get the name for.
8567///
8568/// @param qualified if yes, return the qualified name of @p tod;
8569/// otherwise, return the non-qualified name;
8570///
8571/// @return the name of @p tod.
8572string
8573get_name(const type_or_decl_base_sptr& tod, bool qualified)
8574{return get_name(tod.get(), qualified);}
8575
8576/// Build and return a qualified name from a name and its scope.
8577///
8578/// The name is supposed to be for an entity that is part of the
8579/// scope.
8580///
8581/// @param the scope to consider.
8582///
8583/// @param name of the name to consider.
8584///
8585/// @return a copy of the string that represents the qualified name.
8586string
8587build_qualified_name(const scope_decl* scope, const string& name)
8588{
8589 if (name.empty())
8590 return "";
8591
8592 string qualified_name;
8593 if (scope)
8594 qualified_name = scope->get_qualified_name();
8595
8596 if (qualified_name.empty())
8597 qualified_name = name;
8598 else
8599 qualified_name = qualified_name + "::" + name;
8600
8601 return qualified_name;
8602}
8603
8604/// Build and return the qualified name of a type in its scope.
8605///
8606/// @param scope the scope of the type to consider.
8607///
8608/// @param type the type to consider.
8609string
8610build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8611{return build_qualified_name(scope, get_name((type)));}
8612
8613// </scope_decl stuff>
8614
8615/// Get the location of the declaration of a given type.
8616///
8617/// @param type the type to consider.
8618///
8619/// @return the location of the declaration of type @p type.
8621get_location(const type_base_sptr& type)
8622{
8623 if (decl_base_sptr decl = get_type_declaration(type))
8624 return get_location(decl);
8625 return location();
8626}
8627
8628/// Get the location of a given declaration.
8629///
8630/// @param decl the declaration to consider.
8631///
8632/// @return the location of the declaration @p decl.
8634get_location(const decl_base_sptr& decl)
8635{
8636 location loc = decl->get_location();
8637 if (!loc)
8638 {
8639 if (class_or_union_sptr c = is_class_or_union_type(decl))
8640 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8641 {
8642 c = is_class_or_union_type(c->get_definition_of_declaration());
8643 loc = c->get_location();
8644 }
8645 }
8646 return loc;
8647}
8648
8649/// Get the scope of a given type.
8650///
8651/// @param t the type to consider.
8652///
8653/// @return the scope of type @p t or 0 if the type has no scope yet.
8656{
8657 if (!t)
8658 return 0;
8659
8661 if (d)
8662 return d->get_scope();
8663 return 0;
8664}
8665
8666/// Get the scope of a given type.
8667///
8668/// @param t the type to consider.
8669///
8670/// @return the scope of type @p t or 0 if the type has no scope yet.
8672get_type_scope(const type_base_sptr& t)
8673{return get_type_scope(t.get());}
8674
8675/// Get the name of a given type and return a copy of it.
8676///
8677/// @param t the type to consider.
8678///
8679/// @param qualified if true then return the qualified name of the
8680/// type.
8681///
8682/// @param internal set to true if the call is intended for an
8683/// internal use (for technical use inside the library itself), false
8684/// otherwise. If you don't know what this is for, then set it to
8685/// false.
8686///
8687/// @return a copy of the type name if the type has a name, or the
8688/// empty string if it does not.
8690get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8691{return get_type_name(t.get(), qualified, internal);}
8692
8693/// Return true iff a decl is for a type type that has a generic
8694/// anonymous internal type name.
8695///
8696/// @param d the decl to considier.
8697///
8698/// @return true iff @p d is for a type type that has a generic
8699/// anonymous internal type name.
8700static bool
8701has_generic_anonymous_internal_type_name(const decl_base *d)
8702{
8703 return (is_class_or_union_type(d)
8704 || is_enum_type(d)
8705 || is_subrange_type(d));
8706}
8707
8708/// Return the generic internal name of an anonymous type.
8709///
8710/// For internal purposes, we want to define a generic name for all
8711/// anonymous types of a certain kind. For instance, all anonymous
8712/// structs will be have a generic name of "__anonymous_struct__", all
8713/// anonymous unions will have a generic name of
8714/// "__anonymous_union__", etc.
8715///
8716/// That generic name can be used as a hash to put all anonymous types
8717/// of a certain kind in the same hash table bucket, for instance.
8718static interned_string
8719get_generic_anonymous_internal_type_name(const decl_base *d)
8720{
8721 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8722
8723 const environment&env = d->get_environment();
8724
8725 interned_string result;
8726 if (is_class_type(d))
8727 result =
8729 else if (is_union_type(d))
8730 result =
8732 else if (is_enum_type(d))
8733 result =
8735 else if (is_subrange_type(d))
8736 result =
8738 else
8740
8741 return result;
8742}
8743
8744/// Get the internal name for a given real type.
8745///
8746/// All real types that have the modifiers 'short, long or long
8747/// long' have the same internal name. This is so that they can all
8748/// have the same canonical type if they are of the same size.
8749/// Otherwise, 'long int' and 'long long int' would have different
8750/// canonical types even though they are equivalent from an ABI point
8751/// of view.
8752///
8753/// @param t the real type to consider
8754///
8755/// @return the internal name for @p t if it's an integral type, or
8756/// the empty string if @p t is not a real type.
8757static string
8758get_internal_real_type_name(const type_base* t)
8759{
8760 string name;
8761 type_decl *type = is_real_type(t);
8762
8763 if (!type)
8764 return name;
8765
8766 real_type int_type;
8767 if (parse_real_type(type->get_name(), int_type))
8768 name = int_type.to_string(/*internal=*/true);
8769
8770 return name;
8771}
8772
8773/// Get the name of a given type and return a copy of it.
8774///
8775/// @param t the type to consider.
8776///
8777/// @param qualified if true then return the qualified name of the
8778/// type.
8779///
8780/// @param internal set to true if the call is intended for an
8781/// internal use (for technical use inside the library itself), false
8782/// otherwise. If you don't know what this is for, then set it to
8783/// false.
8784///
8785/// @return a copy of the type name if the type has a name, or the
8786/// empty string if it does not.
8787interned_string
8788get_type_name(const type_base* t, bool qualified, bool internal)
8789{
8790 const decl_base* d = dynamic_cast<const decl_base*>(t);
8791 if (!d)
8792 {
8793 const function_type* fn_type = is_function_type(t);
8794 ABG_ASSERT(fn_type);
8795 return fn_type->get_cached_name(internal);
8796 }
8797
8798 const environment&env = d->get_environment();
8799
8800 // All anonymous types of a given kind get to have the same internal
8801 // name for internal purpose. This to allow them to be compared
8802 // among themselves during type canonicalization.
8803 if (internal)
8804 {
8805 if (d->get_is_anonymous() && !is_type_decl(t))
8806 {
8807 // Note that anonymous type_decl that are used for
8808 // enumerators are not handled here because they don't have
8809 // generic internal type names.
8810 string r;
8811 r += get_generic_anonymous_internal_type_name(d);
8812 return t->get_environment().intern(r);
8813 }
8814
8815 if (is_typedef(t))
8816 return d->get_name();
8817
8818 if (qualified)
8819 return d->get_qualified_name(internal);
8820
8821 return env.intern(get_internal_real_type_name(t));
8822 }
8823
8824 if (d->get_is_anonymous())
8825 {
8827 return env.intern
8829 /*one_line=*/true,
8830 internal, qualified));
8831 }
8832
8833 if (qualified)
8834 return d->get_qualified_name(internal);
8835 return d->get_name();
8836}
8837
8838/// Get the name of a given type and return a copy of it.
8839///
8840/// @param t the type to consider.
8841///
8842/// @param qualified if true then return the qualified name of the
8843/// type.
8844///
8845/// @param internal set to true if the call is intended for an
8846/// internal use (for technical use inside the library itself), false
8847/// otherwise. If you don't know what this is for, then set it to
8848/// false.
8849///
8850/// @return a copy of the type name if the type has a name, or the
8851/// empty string if it does not.
8853get_type_name(const type_base& t, bool qualified, bool internal)
8854{return get_type_name(&t, qualified, internal);}
8855
8856/// Get the name of the pointer to a given type.
8857///
8858/// @param pointed_to_type the pointed-to-type to consider.
8859///
8860/// @param qualified this is true if the resulting name should be of a
8861/// pointer to a *fully-qualified* pointed-to-type.
8862///
8863/// @param internal true if the name is for libabigail-internal
8864/// purposes.
8865///
8866/// @return the name (string representation) of the pointer.
8869 bool qualified, bool internal)
8870{
8871 const environment& env = pointed_to_type.get_environment();
8872 string tn = get_type_name(pointed_to_type, qualified, internal);
8873 tn = tn + "*";
8874
8875 return env.intern(tn);
8876}
8877
8878/// Get the name of the reference to a given type.
8879///
8880/// @param pointed_to_type the pointed-to-type to consider.
8881///
8882/// @param qualified this is true if the resulting name should be of a
8883/// reference to a *fully-qualified* pointed-to-type.
8884///
8885/// @param internal true if the name is for libabigail-internal
8886/// purposes.
8887///
8888/// @return the name (string representation) of the reference.
8891 bool lvalue_reference,
8892 bool qualified, bool internal)
8893{
8894 const environment& env = pointed_to_type.get_environment();
8895
8896 string name = get_type_name(pointed_to_type, qualified, internal);
8897 if (lvalue_reference)
8898 name = name + "&";
8899 else
8900 name = name + "&&";
8901
8902 return env.intern(name);
8903}
8904
8905/// Get the name of a qualified type, given the underlying type and
8906/// its qualifiers.
8907///
8908/// @param underlying_type the underlying type to consider.
8909///
8910/// @param quals the CV qualifiers of the name.
8911///
8912/// @param qualified true if we should consider the fully qualified
8913/// name of @p underlying_type.
8914///
8915/// @param internal true if the result is to be used for
8916/// libabigail-internal purposes.
8917///
8918/// @return the name (string representation) of the qualified type.
8920get_name_of_qualified_type(const type_base_sptr& underlying_type,
8922 bool qualified, bool internal)
8923{
8924 const environment& env = underlying_type->get_environment();
8925
8926 string quals_repr = get_string_representation_of_cv_quals(quals);
8927 string name = get_type_name(underlying_type, qualified, internal);
8928
8929 if (quals_repr.empty() && internal)
8930 // We are asked to return the internal name, that might be used
8931 // for type canonicalization. For that canonicalization, we need
8932 // to make a difference between a no-op qualified type which
8933 // underlying type is foo (the qualified type is named "none
8934 // foo"), and the name of foo, which is just "foo".
8935 //
8936 // Please remember that this has to be kept in sync with what is
8937 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
8938 // change this code here, please change that code there too.
8939 quals_repr = "";
8940
8941 if (!quals_repr.empty())
8942 {
8943 if (is_pointer_type(peel_qualified_type(underlying_type))
8944 || is_reference_type(peel_qualified_type(underlying_type)))
8945 {
8946 name += " ";
8947 name += quals_repr;
8948 }
8949 else
8950 name = quals_repr + " " + name;
8951 }
8952
8953 return env.intern(name);
8954}
8955
8956/// Get the name of a given function type and return a copy of it.
8957///
8958/// @param fn_type the function type to consider.
8959///
8960/// @param internal set to true if the call is intended for an
8961/// internal use (for technical use inside the library itself), false
8962/// otherwise. If you don't know what this is for, then set it to
8963/// false.
8964///
8965/// @return a copy of the function type name
8968 bool internal)
8969{return get_function_type_name(fn_type.get(), internal);}
8970
8971/// Get the name of a given function type and return a copy of it.
8972///
8973/// @param fn_type the function type to consider.
8974///
8975/// @param internal set to true if the call is intended for an
8976/// internal use (for technical use inside the library itself), false
8977/// otherwise. If you don't know what this is for, then set it to
8978/// false.
8979///
8980/// @return a copy of the function type name
8983 bool internal)
8984{
8985 ABG_ASSERT(fn_type);
8986
8987 if (const method_type* method = is_method_type(fn_type))
8988 return get_method_type_name(method, internal);
8989
8990 return get_function_type_name(*fn_type, internal);
8991}
8992
8993/// Get the name of a given function type and return a copy of it.
8994///
8995/// @param fn_type the function type to consider.
8996///
8997/// @param internal set to true if the call is intended for an
8998/// internal use (for technical use inside the library itself), false
8999/// otherwise. If you don't know what this is for, then set it to
9000/// false.
9001///
9002/// @return a copy of the function type name
9005 bool internal)
9006{
9007 std::ostringstream o;
9008 // When the function name is used for internal purposes (e.g, for
9009 // canonicalization), we want its representation to stay the same,
9010 // regardless of typedefs. So let's strip typedefs from the return
9011 // type.
9012 type_base_sptr return_type = fn_type.get_return_type();
9013 const environment& env = fn_type.get_environment();
9014
9015 o << get_type_name(return_type, /*qualified=*/true, internal) << " ";
9016 stream_pretty_representation_of_fn_parms(fn_type, o,
9017 /*qualified=*/true,
9018 internal);
9019 return env.intern(o.str());
9020}
9021
9022/// Get the ID of a function, or, if the ID can designate several
9023/// different functions, get its pretty representation.
9024///
9025/// @param fn the function to consider
9026///
9027/// @return the function ID of pretty representation of @p fn.
9030{
9031 ABG_ASSERT(fn);
9032
9033 interned_string result = fn->get_environment().intern(fn->get_id());
9034
9035 if (const corpus *c = fn->get_corpus())
9036 {
9038 c->get_exported_decls_builder();
9039 if (b->fn_id_maps_to_several_fns(fn))
9040 result = fn->get_environment().intern(fn->get_pretty_representation());
9041 }
9042
9043 return result;
9044}
9045
9046/// Get the name of a given method type and return a copy of it.
9047///
9048/// @param fn_type the function type to consider.
9049///
9050/// @param internal set to true if the call is intended for an
9051/// internal use (for technical use inside the library itself), false
9052/// otherwise. If you don't know what this is for, then set it to
9053/// false.
9054///
9055/// @return a copy of the function type name
9058 bool internal)
9059{return get_method_type_name(fn_type.get(), internal);}
9060
9061/// Get the name of a given method type and return a copy of it.
9062///
9063/// @param fn_type the function type to consider.
9064///
9065/// @param internal set to true if the call is intended for an
9066/// internal use (for technical use inside the library itself), false
9067/// otherwise. If you don't know what this is for, then set it to
9068/// false.
9069///
9070/// @return a copy of the function type name
9073 bool internal)
9074{
9075 if (fn_type)
9076 return get_method_type_name(*fn_type, internal);
9077
9078 return interned_string();
9079}
9080
9081/// Get the name of a given method type and return a copy of it.
9082///
9083/// @param fn_type the function type to consider.
9084///
9085/// @param internal set to true if the call is intended for an
9086/// internal use (for technical use inside the library itself), false
9087/// otherwise. If you don't know what this is for, then set it to
9088/// false.
9089///
9090/// @return a copy of the function type name
9093 bool internal)
9094{
9095 std::ostringstream o;
9096 // When the function name is used for internal purposes (e.g, for
9097 // canonicalization), we want its representation to stay the same,
9098 // regardless of typedefs. So let's strip typedefs from the return
9099 // type.
9100 type_base_sptr return_type = fn_type.get_return_type();
9101
9102 const environment& env = fn_type.get_environment();
9103
9104 if (return_type)
9105 o << get_type_name(return_type, /*qualified=*/true, internal);
9106 else
9107 // There are still some abixml files out there in which "void"
9108 // can be expressed as an empty type.
9109 o << "void";
9110
9111 class_or_union_sptr class_type = fn_type.get_class_type();
9112 ABG_ASSERT(class_type);
9113
9114 o << " (" << class_type->get_qualified_name(internal) << "::*) ";
9115 stream_pretty_representation_of_fn_parms(fn_type, o,
9116 /*qualified=*/true,
9117 internal);
9118
9119 return env.intern(o.str());
9120}
9121
9122/// Build and return a copy of the pretty representation of an ABI
9123/// artifact that could be either a type of a decl.
9124///
9125/// param tod the ABI artifact to consider.
9126///
9127/// @param internal set to true if the call is intended for an
9128/// internal use (for technical use inside the library itself), false
9129/// otherwise. If you don't know what this is for, then set it to
9130/// false.
9131///
9132/// @return a copy of the pretty representation of an ABI artifact
9133/// that could be either a type of a decl.
9134string
9136{
9137 string result;
9138
9139 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9140 result = get_pretty_representation(t, internal);
9141 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9142 result = get_pretty_representation(d, internal);
9143 else
9144 // We should never reach this point
9145 abort();
9146
9147 return result;
9148}
9149
9150/// Build and return a copy of the pretty representation of an ABI
9151/// artifact that could be either a type of a decl.
9152///
9153/// param tod the ABI artifact to consider.
9154///
9155/// @param internal set to true if the call is intended for an
9156/// internal use (for technical use inside the library itself), false
9157/// otherwise. If you don't know what this is for, then set it to
9158/// false.
9159///
9160/// @return a copy of the pretty representation of an ABI artifact
9161/// that could be either a type of a decl.
9162string
9164{return get_pretty_representation(tod.get(), internal);}
9165
9166/// Get a copy of the pretty representation of a decl.
9167///
9168/// @param d the decl to consider.
9169///
9170/// @param internal set to true if the call is intended for an
9171/// internal use (for technical use inside the library itself), false
9172/// otherwise. If you don't know what this is for, then set it to
9173/// false.
9174///
9175/// @return the pretty representation of the decl.
9176string
9177get_pretty_representation(const decl_base* d, bool internal)
9178{
9179 if (!d)
9180 return "";
9181 return d->get_pretty_representation(internal);
9182}
9183
9184/// Get a copy of the pretty representation of a type.
9185///
9186/// @param d the type to consider.
9187///
9188/// @param internal set to true if the call is intended for an
9189/// internal use (for technical use inside the library itself), false
9190/// otherwise. If you don't know what this is for, then set it to
9191/// false.
9192///
9193/// @return the pretty representation of the type.
9194string
9195get_pretty_representation(const type_base* t, bool internal)
9196{
9197 if (!t)
9198 return "void";
9199 if (const function_type* fn_type = is_function_type(t))
9200 return get_pretty_representation(fn_type, internal);
9201
9202 const decl_base* d = get_type_declaration(t);
9203 ABG_ASSERT(d);
9204 return get_pretty_representation(d, internal);
9205}
9206
9207/// Get a copy of the pretty representation of a decl.
9208///
9209/// @param d the decl to consider.
9210///
9211/// @param internal set to true if the call is intended for an
9212/// internal use (for technical use inside the library itself), false
9213/// otherwise. If you don't know what this is for, then set it to
9214/// false.
9215///
9216/// @return the pretty representation of the decl.
9217string
9218get_pretty_representation(const decl_base_sptr& d, bool internal)
9219{return get_pretty_representation(d.get(), internal);}
9220
9221/// Get a copy of the pretty representation of a type.
9222///
9223/// @param d the type to consider.
9224///
9225/// @param internal set to true if the call is intended for an
9226/// internal use (for technical use inside the library itself), false
9227/// otherwise. If you don't know what this is for, then set it to
9228/// false.
9229///
9230/// @return the pretty representation of the type.
9231string
9232get_pretty_representation(const type_base_sptr& t, bool internal)
9233{return get_pretty_representation(t.get(), internal);}
9234
9235/// Get the pretty representation of a function type.
9236///
9237/// @param fn_type the function type to consider.
9238///
9239/// @param internal set to true if the call is intended for an
9240/// internal use (for technical use inside the library itself), false
9241/// otherwise. If you don't know what this is for, then set it to
9242/// false.
9243///
9244/// @return the string represenation of the function type.
9245string
9247 bool internal)
9248{return get_pretty_representation(fn_type.get(), internal);}
9249
9250/// Get the pretty representation of a function type.
9251///
9252/// @param fn_type the function type to consider.
9253///
9254/// @param internal set to true if the call is intended for an
9255/// internal use (for technical use inside the library itself), false
9256/// otherwise. If you don't know what this is for, then set it to
9257/// false.
9258///
9259/// @return the string represenation of the function type.
9260string
9261get_pretty_representation(const function_type* fn_type, bool internal)
9262{
9263 if (!fn_type)
9264 return "void";
9265
9266 if (const method_type* method = is_method_type(fn_type))
9267 return get_pretty_representation(method, internal);
9268
9269 return get_pretty_representation(*fn_type, internal);
9270}
9271
9272/// Get the pretty representation of a function type.
9273///
9274/// @param fn_type the function type to consider.
9275///
9276/// @param internal set to true if the call is intended for an
9277/// internal use (for technical use inside the library itself), false
9278/// otherwise. If you don't know what this is for, then set it to
9279/// false.
9280///
9281/// @return the string represenation of the function type.
9282string
9283get_pretty_representation(const function_type& fn_type, bool internal)
9284{
9285 std::ostringstream o;
9286 o << "function type " << get_function_type_name(fn_type, internal);
9287 return o.str();
9288}
9289
9290/// Get the pretty representation of a method type.
9291///
9292/// @param method the method type to consider.
9293///
9294/// @param internal set to true if the call is intended for an
9295/// internal use (for technical use inside the library itself), false
9296/// otherwise. If you don't know what this is for, then set it to
9297/// false.
9298///
9299/// @return the string represenation of the method type.
9300string
9301get_pretty_representation(const method_type& method, bool internal)
9302{
9303 std::ostringstream o;
9304 o << "method type " << get_method_type_name(method, internal);
9305 return o.str();
9306}
9307
9308/// Get the pretty representation of a method type.
9309///
9310/// @param method the method type to consider.
9311///
9312/// @param internal set to true if the call is intended for an
9313/// internal use (for technical use inside the library itself), false
9314/// otherwise. If you don't know what this is for, then set it to
9315/// false.
9316///
9317/// @return the string represenation of the method type.
9318string
9319get_pretty_representation(const method_type* method, bool internal)
9320{
9321 if (!method)
9322 return "void";
9323 return get_pretty_representation(*method, internal);
9324}
9325
9326/// Get the pretty representation of a method type.
9327///
9328/// @param method the method type to consider.
9329///
9330/// @param internal set to true if the call is intended for an
9331/// internal use (for technical use inside the library itself), false
9332/// otherwise. If you don't know what this is for, then set it to
9333/// false.
9334///
9335/// @return the string represenation of the method type.
9336string
9338{return get_pretty_representation(method.get(), internal);}
9339
9340/// Get the flat representation of an instance of @ref class_or_union
9341/// type.
9342///
9343/// The flat representation of a given @ref class_or_union type is the
9344/// actual definition of the type, for instance:
9345///
9346/// struct foo {int a; char b;}
9347///
9348///@param cou the instance of @ref class_or_union to consider.
9349///
9350///@param indent the identation spaces to use in the representation.
9351///
9352///@param one_line if true, then the flat representation stands on one
9353///line. Otherwise, it stands on multiple lines.
9354///
9355///@return the resulting flat representation.
9356string
9358 const string& indent,
9359 bool one_line,
9360 bool internal,
9361 bool qualified_names)
9362{
9363 string repr;
9364 string local_indent = " ";
9365
9366 if (class_decl* clazz = is_class_type(&cou))
9367 {
9368 repr = indent;
9369 if (!internal && clazz->is_struct())
9370 repr += "struct";
9371 else
9372 repr += "class";
9373 }
9374 else if (is_union_type(cou))
9375 repr = indent + "union";
9376 else
9377 return "";
9378
9379 repr += " ";
9380
9381 string name = cou.get_qualified_name();
9382
9383 if (!cou.get_is_anonymous())
9384 repr += name;
9385
9386 if (cou.priv_->is_printing_flat_representation())
9387 {
9388 // We have just detected a cycle while walking the sub-tree
9389 // of this class or union type for the purpose of printing
9390 // its flat representation. We need to get out of here
9391 // pronto or else we'll be spinning endlessly.
9392 repr += "{}";
9393 return repr;
9394 }
9395
9396 // Let's mark this class or union type to signify that we started
9397 // walking its sub-tree. This is to detect potential cycles and
9398 // avoid looping endlessly.
9400
9401 repr += "{";
9402
9403 if (!one_line)
9404 repr += "\n";
9405
9406 string real_indent;
9408 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9409 dm != dmems.end();
9410 ++dm)
9411 {
9412 if (dm != dmems.begin())
9413 {
9414 if (one_line)
9415 real_indent = " ";
9416 else
9417 real_indent = "\n" + indent + local_indent;
9418 }
9419
9421 repr +=
9424 real_indent, one_line, internal, qualified_names);
9425 else
9426 {
9427 if (one_line)
9428 {
9429 if (dm != dmems.begin())
9430 repr += real_indent;
9431 repr += (*dm)->get_pretty_representation(internal,
9432 qualified_names);
9433 }
9434 else
9435 repr +=
9436 real_indent+ (*dm)->get_pretty_representation(internal,
9437 qualified_names);
9438 }
9439 repr += ";";
9440 }
9441
9442 if (one_line)
9443 repr += "}";
9444 else
9445 repr += indent + "}";
9446
9447 // Let's unmark this class or union type to signify that we are done
9448 // walking its sub-tree. This was to detect potential cycles and
9449 // avoid looping endlessly.
9451
9452 return repr;
9453}
9454
9455/// Get the flat representation of an instance of @ref class_or_union
9456/// type.
9457///
9458/// The flat representation of a given @ref class_or_union type is the
9459/// actual definition of the type, for instance:
9460///
9461/// struct foo {int a; char b;}
9462///
9463///@param cou the instance of @ref class_or_union to consider.
9464///
9465///@param indent the identation spaces to use in the representation.
9466///
9467///@param one_line if true, then the flat representation stands on one
9468///line. Otherwise, it stands on multiple lines.
9469///
9470///@return the resulting flat representation.
9471string
9473 const string& indent,
9474 bool one_line,
9475 bool internal,
9476 bool qualified_names)
9477{
9478 if (cou)
9479 return get_class_or_union_flat_representation(*cou, indent, one_line,
9480 internal, qualified_names);
9481 return "";
9482}
9483
9484/// Get the flat representation of an instance of @ref class_or_union
9485/// type.
9486///
9487/// The flat representation of a given @ref class_or_union type is the
9488/// actual definition of the type, for instance:
9489///
9490/// struct foo {int a; char b;}
9491///
9492///@param cou the instance of @ref class_or_union to consider.
9493///
9494///@param indent the identation spaces to use in the representation.
9495///
9496///@param one_line if true, then the flat representation stands on one
9497///line. Otherwise, it stands on multiple lines.
9498///
9499///@return the resulting flat representation.
9500string
9501get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9502 const string& indent,
9503 bool one_line,
9504 bool internal,
9505 bool qualified_names)
9507 indent,
9508 one_line,
9509 internal,
9510 qualified_names);}
9511
9512/// Get the flat representation of an instance of @ref enum_type_decl
9513/// type.
9514///
9515/// The flat representation of a given @ref enum_type_decl type is the
9516/// actual definition of the type, for instance:
9517///
9518/// enum {E_0 =0, E_1 = 1}
9519///
9520///@param enum_type the enum type to consider.
9521///
9522///@param indent the identation spaces to use in the representation.
9523///
9524///@param one_line if true, then the flat representation stands on one
9525///line. Otherwise, it stands on multiple lines.
9526///
9527///@param qualified_names use qualified names when applicable.
9528///Typically, if this is true, the name of the enum is going to be
9529///qualified.
9530///
9531///@return the resulting flat representation.
9532string
9534 const string& indent, bool one_line,
9535 bool qualified_names)
9536{
9537 string repr;
9538 std::ostringstream o;
9539 string local_indent = " ";
9540
9541 repr = indent + "enum ";
9542
9543 if (!enum_type.get_is_anonymous())
9544 o << (qualified_names
9545 ? enum_type.get_qualified_name()
9546 : enum_type.get_name()) + " ";
9547
9548 o << "{";
9549
9550 if (!one_line)
9551 o << "\n";
9552
9553 for (const auto &enumerator : enum_type.get_sorted_enumerators())
9554 {
9555 if (!one_line)
9556 o << "\n" + indent;
9557
9558 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
9559 }
9560
9561 if (!one_line)
9562 o << "\n" + indent << "}";
9563 else
9564 o << "}";
9565
9566 repr =o.str();
9567
9568 return repr;
9569}
9570
9571/// Get the flat representation of an instance of @ref enum_type_decl
9572/// type.
9573///
9574/// The flat representation of a given @ref enum_type_decl type is the
9575/// actual definition of the type, for instance:
9576///
9577/// enum {E_0 =0, E_1 = 1}
9578///
9579///@param enum_type the enum type to consider.
9580///
9581///@param indent the identation spaces to use in the representation.
9582///
9583///@param one_line if true, then the flat representation stands on one
9584///line. Otherwise, it stands on multiple lines.
9585///
9586///@param qualified_names use qualified names when applicable.
9587///Typically, if this is true, the name of the enum is going to be
9588///qualified.
9589///
9590///@return the resulting flat representation.
9591string
9593 const string& indent, bool one_line,
9594 bool qualified_names)
9595{
9596 if (!enum_type)
9597 return "";
9598
9599 return get_enum_flat_representation(*enum_type, indent,
9600 one_line, qualified_names);
9601}
9602
9603/// Get the flat representation of an instance of @ref enum_type_decl
9604/// type.
9605///
9606/// The flat representation of a given @ref enum_type_decl type is the
9607/// actual definition of the type, for instance:
9608///
9609/// enum {E_0 =0, E_1 = 1}
9610///
9611///@param enum_type the enum type to consider.
9612///
9613///@param indent the identation spaces to use in the representation.
9614///
9615///@param one_line if true, then the flat representation stands on one
9616///line. Otherwise, it stands on multiple lines.
9617///
9618///@param qualified_names use qualified names when applicable.
9619///Typically, if this is true, the name of the enum is going to be
9620///qualified.
9621///
9622///@return the resulting flat representation.
9623string
9625 const string& indent, bool one_line,
9626 bool qualified_names)
9627{
9628 return get_enum_flat_representation(enum_type.get(),
9629 indent, one_line,
9630 qualified_names);
9631}
9632
9633/// Get the flat representation of an instance of @ref enum_type_decl
9634/// type.
9635///
9636/// The flat representation of a given @ref enum_type_decl type is the
9637/// actual definition of the type, for instance:
9638///
9639/// enum {E_0 =0, E_1 = 1}
9640///
9641///@param enum_type the enum type to consider.
9642///
9643///@param indent the identation spaces to use in the representation.
9644///
9645///@param one_line if true, then the flat representation stands on one
9646///line. Otherwise, it stands on multiple lines.
9647///
9648///@param qualified_names use qualified names when applicable.
9649///Typically, if this is true, the name of the enum is going to be
9650///qualified.
9651///
9652///@return the resulting flat representation.
9653string
9655 const string& indent,
9656 bool one_line,
9657 bool internal,
9658 bool qualified_name)
9659
9660{
9661 string repr;
9662 if (const class_or_union* cou = is_class_or_union_type(&coe))
9663 repr = get_class_or_union_flat_representation(cou, indent, one_line,
9664 internal, qualified_name);
9665 else if (const enum_type_decl* enom = is_enum_type(&coe))
9666 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9667
9668 return repr;
9669}
9670
9671/// Get the textual representation of a type for debugging purposes.
9672///
9673/// If the type is a class/union, this shows the data members, virtual
9674/// member functions, size, pointer value of its canonical type, etc.
9675/// Otherwise, this just shows the name of the artifact as returned by
9676/// type_or_decl_base:get_pretty_representation().
9677///
9678/// @param artifact the artifact to show a debugging representation of.
9679///
9680/// @return a debugging string representation of @p artifact.
9681string
9683{
9684 string nil_str;
9685 if (!artifact)
9686 return nil_str;
9687
9688 class_or_union * c = is_class_or_union_type(artifact);
9689 if (c)
9690 {
9691 class_decl *clazz = is_class_type(c);
9692 string name = c->get_qualified_name();
9693 std::ostringstream o;
9694 if (clazz)
9695 {
9696 if (clazz->is_struct())
9697 o << "struct ";
9698 else
9699 o << "class ";
9700 }
9701 else if (is_union_type(c))
9702 o << "union ";
9703 o << name;
9704
9705 if (clazz)
9706 {
9707 if (!clazz->get_base_specifiers().empty())
9708 o << " :" << std::endl;
9709 for (auto &b : clazz->get_base_specifiers())
9710 {
9711 o << " ";
9712 if (b->get_is_virtual())
9713 o << "virtual ";
9714 o << b->get_base_class()->get_qualified_name()
9715 << " // hash: ";
9716 hash_t h = peek_hash_value(*b->get_base_class());
9717 if (h)
9718 o << std::hex << *h << std::dec;
9719 else
9720 o << "none";
9721 o << std::endl;
9722 }
9723 }
9724 o << std::endl
9725 << "{"
9726 << " // size in bits: " << c->get_size_in_bits() << "\n"
9727 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9728 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9729 << " // translation unit: "
9730 << (c->get_translation_unit()
9732 : nil_str)
9733 << std::endl
9734 << " // @: " << std::hex << is_type(c)
9735 << ", @canonical: " << c->get_canonical_type().get() << std::dec << "\n"
9736 << " // hash: " ;
9737
9738 hash_t h = peek_hash_value(*c);
9739 if (h)
9740 o << std::hex << *h << std::dec;
9741 else
9742 o << "none";
9743 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*c);
9744 o << "\n\n";
9745
9746
9747 for (auto member_type : c->get_sorted_member_types())
9748 {
9749 o << " "
9750 << member_type->get_pretty_representation(/*internal=*/false,
9751 /*qualified=*/false)
9752 << ";";
9753 if (member_type->get_canonical_type())
9754 {
9755 o << " // uses canonical type: '@"
9756 << std::hex << member_type->get_canonical_type().get() << "'";
9757 o << " / h:";
9758 hash_t h = peek_hash_value(*member_type);
9759 o << std::hex << *h << std::dec;
9760 if (get_canonical_type_index(*member_type))
9761 o << "#" << get_canonical_type_index(*member_type);
9762 }
9763 o << "\n";
9764 }
9765
9766 if (!c->get_sorted_member_types().empty())
9767 o << std::endl;
9768
9769 for (auto m : c->get_data_members())
9770 {
9771 type_base_sptr t = m->get_type();
9773
9774 o << " "
9775 << m->get_pretty_representation(/*internal=*/false,
9776 /*qualified=*/false)
9777 << ";";
9778
9779 if (t && t->get_canonical_type())
9780 o << " // uses canonical type '@"
9781 << std::hex << t->get_canonical_type().get() << "'";
9782
9783 o << "/ h:";
9784 hash_t h = peek_hash_value(*m->get_type());
9785 if (h)
9786 o << std::hex << *h << std::dec;
9787 else
9788 o << "none";
9789 o << std::endl;
9790 }
9791
9792 if (!c->get_data_members().empty())
9793 o << std::endl;
9794
9795 if (clazz && clazz->has_vtable())
9796 {
9797 o << " // virtual member functions\n\n";
9798 for (auto f : clazz->get_virtual_mem_fns())
9799 {
9800 o << " " << f->get_pretty_representation(/*internal=*/false,
9801 /*qualified=*/false)
9802 << " // voffset: " << get_member_function_vtable_offset(f)
9803 << ", h: ";
9804 hash_t h = peek_hash_value(*f->get_type());
9805 if (h)
9806 o << std::hex << *h << std::dec;
9807 else
9808 o << "none";
9809 o << ";" << std::endl;
9810 }
9811 }
9812
9813 o << "};" << std::endl;
9814
9815 return o.str();
9816 }
9817 else if (const enum_type_decl* e = is_enum_type(artifact))
9818 {
9819 string name = e->get_qualified_name();
9820 std::ostringstream o;
9821 o << "enum " << name
9822 << " : "
9823 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9824 true)
9825 << "\n"
9826 << "{\n"
9827 << " // size in bits: " << e->get_size_in_bits() << "\n"
9828 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9829 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9830 << " // translation unit: "
9831 << e->get_translation_unit()->get_absolute_path() << "\n"
9832 << " // @: " << std::hex << is_type(e)
9833 << ", @canonical: " << e->get_canonical_type().get() << std::dec << "\n"
9834 << " // hash: ";
9835
9836 hash_t h = peek_hash_value(*e);
9837 if (h)
9838 o << std::hex << *h << std::dec;
9839 else
9840 o << "none";
9841 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*e);
9842 o << "\n\n";
9843
9844 for (const auto &enom : e->get_enumerators())
9845 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9846
9847 o << "};\n";
9848
9849 return o.str();
9850 }
9851 else if (type_base *t = is_type(artifact))
9852 {
9853 std::ostringstream o;
9854 o << t->get_pretty_representation(/*internal=*/true,
9855 /*qualified=*/true)
9856 << " // cti: " << get_canonical_type_index(*t)
9857 << "\n";
9858 return o.str();
9859 }
9860
9861 return artifact->get_pretty_representation(/*internal=*/true,
9862 /*qualified=*/true);
9863}
9864
9865/// Get a given data member, referred to by its name, of a class type.
9866///
9867/// @param clazz the class to consider.
9868///
9869/// @param member_name name of the data member to get.
9870///
9871/// @return the resulting data member or nullptr if none was found.
9873get_data_member(class_or_union *clazz, const char* member_name)
9874{
9875 if (!clazz)
9876 return var_decl_sptr();
9877 return clazz->find_data_member(member_name);
9878}
9879
9880/// Get a given data member, referred to by its name, of a class type.
9881///
9882/// @param clazz the class to consider.
9883///
9884/// @param member_name name of the data member to get.
9885///
9886/// @return the resulting data member or nullptr if none was found.
9888get_data_member(type_base *clazz, const char* member_name)
9889{return get_data_member(is_class_or_union_type(clazz), member_name);}
9890
9891/// Get the non-artificial (natural) location of a decl.
9892///
9893/// If the decl doesn't have a natural location then return its
9894/// artificial one.
9895///
9896/// @param decl the decl to consider.
9897///
9898/// @return the natural location @p decl if it has one; otherwise,
9899/// return its artificial one.
9900const location&
9902{
9903 ABG_ASSERT(decl);
9904
9905 if (decl->get_location())
9906 return decl->get_location();
9907 return decl->get_artificial_location();
9908}
9909
9910/// Get the artificial location of a decl.
9911///
9912/// If the decl doesn't have an artificial location then return its
9913/// natural one.
9914///
9915/// @param decl the decl to consider.
9916///
9917/// @return the artificial location @p decl if it has one; otherwise,
9918/// return its natural one.
9919const location&
9921{
9922 ABG_ASSERT(decl);
9923
9924 if (decl->has_artificial_location())
9925 return decl->get_artificial_location();
9926 return decl->get_location();
9927}
9928
9929/// Emit a textual representation of an artifact to std error stream
9930/// for debugging purposes.
9931///
9932/// This is useful to invoke from within a command line debugger like
9933/// GDB to help make sense of a given ABI artifact.
9934///
9935/// @param artifact the ABI artifact to emit the debugging
9936/// representation for.
9937///
9938/// @return the artifact @p artifact.
9940debug(const type_or_decl_base* artifact)
9941{
9942 std::cerr << get_debug_representation(artifact) << std::endl;
9943 return const_cast<type_or_decl_base*>(artifact);
9944}
9945
9946/// Emit a textual representation of an artifact to std error stream
9947/// for debugging purposes.
9948///
9949/// This is useful to invoke from within a command line debugger like
9950/// GDB to help make sense of a given ABI artifact.
9951///
9952/// @param artifact the ABI artifact to emit the debugging
9953/// representation for.
9954///
9955/// @return the artifact @p artifact.
9956type_base*
9957debug(const type_base* artifact)
9958{
9959 debug(static_cast<const type_or_decl_base*>(artifact));
9960 return const_cast<type_base*>(artifact);
9961}
9962
9963/// Emit a textual representation of an artifact to std error stream
9964/// for debugging purposes.
9965///
9966/// This is useful to invoke from within a command line debugger like
9967/// GDB to help make sense of a given ABI artifact.
9968///
9969/// @param artifact the ABI artifact to emit the debugging
9970/// representation for.
9971///
9972/// @return the artifact @p artifact.
9973decl_base*
9974debug(const decl_base* artifact)
9975{
9976 debug(static_cast<const type_or_decl_base*>(artifact));
9977 return const_cast<decl_base*>(artifact);
9978}
9979
9980/// Test if two ABI artifacts are equal.
9981///
9982/// This can be useful when used from the command line of a debugger
9983/// like GDB.
9984///
9985/// @param l the first ABI artifact to consider in the comparison.
9986///
9987/// @param r the second ABI artifact to consider in the comparison.
9988///
9989/// @return true iff @p l equals @p r.
9990bool
9992{
9993 if (!!l != !!r)
9994 return false;
9995 if (!l && !r)
9996 return true;
9997
9998 return (*l == *r);
9999}
10000
10001/// Emit a trace of a comparison operand stack.
10002///
10003/// @param vect the operand stack to emit the trace for.
10004///
10005/// @param o the output stream to emit the trace to.
10006static void
10007debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
10008{
10009 for (auto t : vect)
10010 {
10011 o << "|" << t->get_pretty_representation()
10012 << "@" << std::hex << t << std::dec;
10013 }
10014 if (!vect.empty())
10015 o << "|";
10016}
10017
10018/// Construct a trace of the two comparison operand stacks.
10019///
10020/// @param the environment in which the comparison operand stacks are.
10021///
10022/// @return a string representing the trace.
10023static string
10024print_comp_stack(const environment& env)
10025{
10026 std::ostringstream o;
10027 o << "left-operands: ";
10028 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
10029 o << "\n" << "right-operands: ";
10030 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10031 o << "\n";
10032 return o.str();
10033}
10034
10035/// Emit a trace of the two comparison operands stack on the standard
10036/// error stream.
10037///
10038/// @param env the environment the comparison operands stack belong
10039/// to.
10040void
10042{
10043 std::cerr << print_comp_stack(env);
10044 std::cerr << std::endl;
10045}
10046
10047/// By looking at the language of the TU a given ABI artifact belongs
10048/// to, test if the ONE Definition Rule should apply.
10049///
10050/// To date, it applies to c++, java and ada.
10051///
10052/// @param artifact the ABI artifact to consider.
10053///
10054/// @return true iff the One Definition Rule should apply.
10055bool
10057{
10058 if (!artifact.get_translation_unit())
10059 return false;
10060
10062 artifact.get_translation_unit()->get_language();
10063
10065 || is_java_language(l)
10066 || is_ada_language(l))
10067 return true;
10068
10069 return false;
10070}
10071
10072/// Get the declaration for a given type.
10073///
10074/// @param t the type to consider.
10075///
10076/// @return the declaration for the type to return.
10077const decl_base*
10079{return dynamic_cast<const decl_base*>(t);}
10080
10081/// Get the declaration for a given type.
10082///
10083/// @param t the type to consider.
10084///
10085/// @return the declaration for the type to return.
10086decl_base*
10088{return dynamic_cast<decl_base*>(t);}
10089
10090/// Get the declaration for a given type.
10091///
10092/// @param t the type to consider.
10093///
10094/// @return the declaration for the type to return.
10095decl_base_sptr
10096get_type_declaration(const type_base_sptr t)
10097{return dynamic_pointer_cast<decl_base>(t);}
10098
10099/// Test if two types are equal modulo a typedef.
10100///
10101/// Type A and B are compatible if
10102///
10103/// - A and B are equal
10104/// - or if one type is a typedef of the other one.
10105///
10106/// @param type1 the first type to consider.
10107///
10108/// @param type2 the second type to consider.
10109///
10110/// @return true iff @p type1 and @p type2 are compatible.
10111bool
10112types_are_compatible(const type_base_sptr type1,
10113 const type_base_sptr type2)
10114{
10115 if (!type1 || !type2)
10116 return false;
10117
10118 if (type1 == type2)
10119 return true;
10120
10121 // Normally we should strip typedefs entirely, but this is
10122 // potentially costly, especially on binaries with huge changesets
10123 // like the Linux Kernel. So we just get the leaf types for now.
10124 //
10125 // Maybe there should be an option by which users accepts to pay the
10126 // CPU usage toll in exchange for finer filtering?
10127
10128 // type_base_sptr t1 = strip_typedef(type1);
10129 // type_base_sptr t2 = strip_typedef(type2);
10130
10131 type_base_sptr t1 = peel_typedef_type(type1);
10132 type_base_sptr t2 = peel_typedef_type(type2);
10133
10134 return t1 == t2;
10135}
10136
10137/// Test if two types are equal modulo a typedef.
10138///
10139/// Type A and B are compatible if
10140///
10141/// - A and B are equal
10142/// - or if one type is a typedef of the other one.
10143///
10144/// @param type1 the declaration of the first type to consider.
10145///
10146/// @param type2 the declaration of the second type to consider.
10147///
10148/// @return true iff @p type1 and @p type2 are compatible.
10149bool
10150types_are_compatible(const decl_base_sptr d1,
10151 const decl_base_sptr d2)
10152{return types_are_compatible(is_type(d1), is_type(d2));}
10153
10154/// Return the translation unit a declaration belongs to.
10155///
10156/// @param decl the declaration to consider.
10157///
10158/// @return the resulting translation unit, or null if the decl is not
10159/// yet added to a translation unit.
10162{
10163 translation_unit* result =
10164 const_cast<translation_unit*>(t.get_translation_unit());
10165
10166 if (result)
10167 return result;
10168
10169 if (decl_base* decl = is_decl(&t))
10170 {
10171 scope_decl* scope = decl->get_scope();
10172 while (scope)
10173 {
10174 result = scope->get_translation_unit();
10175 if (result)
10176 break;
10177 scope = scope->get_scope();
10178 }
10179 }
10180
10181 return result;
10182}
10183
10184/// Return the translation unit a declaration belongs to.
10185///
10186/// @param decl the declaration to consider.
10187///
10188/// @return the resulting translation unit, or null if the decl is not
10189/// yet added to a translation unit.
10192{return decl ? get_translation_unit(*decl) : nullptr;}
10193
10194/// Return the translation unit a declaration belongs to.
10195///
10196/// @param decl the declaration to consider.
10197///
10198/// @return the resulting translation unit, or null if the decl is not
10199/// yet added to a translation unit.
10203
10204/// Tests whether if a given scope is the global scope.
10205///
10206/// @param scope the scope to consider.
10207///
10208/// @return true iff the current scope is the global one.
10209bool
10211{return !!dynamic_cast<const global_scope*>(&scope);}
10212
10213/// Tests whether if a given scope is the global scope.
10214///
10215/// @param scope the scope to consider.
10216///
10217/// @return the @ref global_scope* representing the scope @p scope or
10218/// 0 if @p scope is not a global scope.
10219const global_scope*
10221{return dynamic_cast<const global_scope*>(scope);}
10222
10223/// Tests whether if a given scope is the global scope.
10224///
10225/// @param scope the scope to consider.
10226///
10227/// @return true iff the current scope is the global one.
10228bool
10229is_global_scope(const shared_ptr<scope_decl>scope)
10230{return is_global_scope(scope.get());}
10231
10232/// Tests whether a given declaration is at global scope.
10233///
10234/// @param decl the decl to consider.
10235///
10236/// @return true iff decl is at global scope.
10237bool
10239{return (is_global_scope(decl.get_scope()));}
10240
10241/// Tests whether a given declaration is at global scope.
10242///
10243/// @param decl the decl to consider.
10244///
10245/// @return true iff decl is at global scope.
10246bool
10247is_at_global_scope(const decl_base_sptr decl)
10248{return (decl && is_global_scope(decl->get_scope()));}
10249
10250/// Tests whether a given declaration is at global scope.
10251///
10252/// @param decl the decl to consider.
10253///
10254/// @return true iff decl is at global scope.
10255bool
10257{return is_at_global_scope(*decl);}
10258
10259/// Tests whether a given decl is at class scope.
10260///
10261/// @param decl the decl to consider.
10262///
10263/// @return true iff decl is at class scope.
10265is_at_class_scope(const decl_base_sptr decl)
10266{return is_at_class_scope(decl.get());}
10267
10268/// Tests whether a given decl is at class scope.
10269///
10270/// @param decl the decl to consider.
10271///
10272/// @return true iff decl is at class scope.
10275{
10276 if (!decl)
10277 return 0;
10278
10279 return is_at_class_scope(*decl);
10280}
10281
10282/// Tests whether a given decl is at class scope.
10283///
10284/// @param decl the decl to consider.
10285///
10286/// @return true iff decl is at class scope.
10289{
10290 scope_decl* scope = decl.get_scope();
10291 if (class_or_union* cl = is_class_type(scope))
10292 return cl;
10293 if (class_or_union* cl = is_union_type(scope))
10294 return cl;
10295 return 0;
10296}
10297
10298/// Find a data member inside an anonymous data member.
10299///
10300/// An anonymous data member has a type which is a class or union.
10301/// This function looks for a data member inside the type of that
10302/// anonymous data member.
10303///
10304/// @param anon_dm the anonymous data member to consider.
10305///
10306/// @param name the name of the data member to look for.
10309 const string& name)
10310{
10311 const class_or_union* containing_class_or_union =
10313
10314 if (!containing_class_or_union)
10315 return var_decl_sptr();
10316
10317 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10318 return result;
10319}
10320
10321/// Tests whether a given decl is at template scope.
10322///
10323/// Note that only template parameters , types that are compositions,
10324/// and template patterns (function or class) can be at template scope.
10325///
10326/// @param decl the decl to consider.
10327///
10328/// @return true iff the decl is at template scope.
10329bool
10330is_at_template_scope(const shared_ptr<decl_base> decl)
10331{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10332
10333/// Tests whether a decl is a template parameter.
10334///
10335/// @param decl the decl to consider.
10336///
10337/// @return true iff decl is a template parameter.
10338bool
10339is_template_parameter(const shared_ptr<decl_base> decl)
10340{
10341 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10342 || dynamic_pointer_cast<non_type_tparameter>(decl)
10343 || dynamic_pointer_cast<template_tparameter>(decl)));
10344}
10345
10346/// Test whether a declaration is a @ref function_decl.
10347///
10348/// @param d the declaration to test for.
10349///
10350/// @return a shared pointer to @ref function_decl if @p d is a @ref
10351/// function_decl. Otherwise, a nil shared pointer.
10354{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10355
10356/// Test whether a declaration is a @ref function_decl.
10357///
10358/// @param d the declaration to test for.
10359///
10360/// @return true if @p d is a function_decl.
10361bool
10364
10365/// Test whether a declaration is a @ref function_decl.
10366///
10367/// @param d the declaration to test for.
10368///
10369/// @return a shared pointer to @ref function_decl if @p d is a @ref
10370/// function_decl. Otherwise, a nil shared pointer.
10373{return dynamic_pointer_cast<function_decl>(d);}
10374
10375/// Test whether a declaration is a @ref function_decl.
10376///
10377/// @param d the declaration to test for.
10378///
10379/// @return a pointer to @ref function_decl if @p d is a @ref
10380/// function_decl. Otherwise, a nil shared pointer.
10383{
10384 return dynamic_cast<function_decl::parameter*>
10385 (const_cast<type_or_decl_base*>(tod));
10386}
10387
10388/// Test whether an ABI artifact is a @ref function_decl.
10389///
10390/// @param tod the declaration to test for.
10391///
10392/// @return a pointer to @ref function_decl if @p d is a @ref
10393/// function_decl. Otherwise, a nil shared pointer.
10396{return dynamic_pointer_cast<function_decl::parameter>(tod);}
10397
10398/// Test if an ABI artifact is a declaration.
10399///
10400/// @param d the artifact to consider.
10401///
10402/// @param return the declaration sub-object of @p d if it's a
10403/// declaration, or NULL if it is not.
10404decl_base*
10406{
10407 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10408 {
10409 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10410 // The artifact is a decl-only (like a function or a
10411 // variable). That is, it's not a type that also has a
10412 // declaration. In this case, we are in the fast path and we
10413 // have a pointer to the decl sub-object handy. Just return
10414 // it ...
10415 return reinterpret_cast<decl_base*>
10416 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10417
10418 // ... Otherwise, we are in the slow path, which is that the
10419 // artifact is a type which has a declaration. In that case,
10420 // let's use the slow dynamic_cast because we don't have the
10421 // pointer to the decl sub-object handily present.
10422 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10423 }
10424 return 0;
10425}
10426
10427/// Test if an ABI artifact is a declaration.
10428///
10429/// @param d the artifact to consider.
10430///
10431/// @param return the declaration sub-object of @p d if it's a
10432/// declaration, or NULL if it is not.
10433decl_base_sptr
10435{return dynamic_pointer_cast<decl_base>(d);}
10436
10437/// Test if an ABI artifact is a declaration.
10438///
10439/// This is done using a slow path that uses dynamic_cast.
10440///
10441/// @param d the artifact to consider.
10442///
10443/// @param return the declaration sub-object of @p d if it's a
10444decl_base*
10446{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10447
10448/// Test if an ABI artifact is a declaration.
10449///
10450/// This is done using a slow path that uses dynamic_cast.
10451///
10452/// @param d the artifact to consider.
10453///
10454/// @param return the declaration sub-object of @p d if it's a
10455decl_base_sptr
10457{return dynamic_pointer_cast<decl_base>(t);}
10458
10459/// Test whether a declaration is a type.
10460///
10461/// @param d the IR artefact to test for.
10462///
10463/// @return true if the artifact is a type, false otherwise.
10464bool
10466{
10467 if (dynamic_cast<const type_base*>(&tod))
10468 return true;
10469 return false;
10470}
10471
10472/// Test whether a declaration is a type.
10473///
10474/// @param d the IR artefact to test for.
10475///
10476/// @return true if the artifact is a type, false otherwise.
10477type_base*
10479{
10480 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10481 return reinterpret_cast<type_base*>
10482 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10483
10484 return 0;
10485}
10486
10487/// Test whether a declaration is a type.
10488///
10489/// @param d the IR artefact to test for.
10490///
10491/// @return true if the artifact is a type, false otherwise.
10492type_base_sptr
10494{return dynamic_pointer_cast<type_base>(tod);}
10495
10496/// Test whether a declaration is a type.
10497///
10498/// @param d the declaration to test for.
10499///
10500/// @return true if the declaration is a type, false otherwise.
10501
10502/// Test if a given type is anonymous.
10503///
10504/// Note that this function considers that an anonymous class that is
10505/// named by a typedef is not anonymous anymore. This is the C idiom:
10506///
10507/// typedef struct {int member;} s_type;
10508///
10509/// The typedef s_type becomes the name of the originally anonymous
10510/// struct.
10511///
10512/// @param t the type to consider.
10513///
10514/// @return true iff @p t is anonymous.
10515bool
10517{
10518 const decl_base* d = get_type_declaration(t);
10519 if (d)
10520 if (d->get_is_anonymous())
10521 {
10523 {
10524 // An anonymous class that is named by a typedef is not
10525 // considered anonymous anymore.
10526 if (!cou->get_naming_typedef())
10527 return true;
10528 }
10529 else
10530 return true;
10531 }
10532 return false;
10533}
10534
10535/// Test if a given type is anonymous.
10536///
10537/// @param t the type to consider.
10538///
10539/// @return true iff @p t is anonymous.
10540bool
10541is_anonymous_type(const type_base_sptr& t)
10542{return is_anonymous_type(t.get());}
10543
10544/// Test if a type is a neither a pointer, an array nor a function
10545/// type.
10546///
10547/// @param t the type to consider.
10548///
10549/// @return true if the @p t is NOT a pointer, an array nor a
10550/// function.
10551bool
10552is_npaf_type(const type_base_sptr& t)
10553{
10554 if (!(is_pointer_type(t)
10555 || is_array_type(t)
10556 || is_function_type(t)
10557 || is_ptr_to_mbr_type(t)))
10558 return true;
10559 return false;
10560}
10561
10562/// Test whether a type is a type_decl (a builtin type).
10563///
10564/// @return the type_decl* for @t if it's type_decl, otherwise, return
10565/// nil.
10566const type_decl*
10568{return dynamic_cast<const type_decl*>(t);}
10569
10570/// Test whether a type is a type_decl (a builtin type).
10571///
10572/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10573/// return nil.
10576{return dynamic_pointer_cast<type_decl>(t);}
10577
10578/// Test if a type is a real type.
10579///
10580/// @param t the type to test.
10581///
10582/// @return the real type @p t can be converted to, or nil if @p
10583/// is not a real type.
10584type_decl*
10586{
10587 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10588 if (!type)
10589 return nullptr;
10590
10591 real_type int_type;
10592 if (!parse_real_type(type->get_name(), int_type))
10593 return nullptr;
10594
10595 return type;
10596}
10597
10598/// Test if a type is a real type.
10599///
10600/// @param t the type to test.
10601///
10602/// @return the real type @p t can be converted to, or nil if @p is
10603/// not a real type.
10606{
10607 const type_decl_sptr type = is_type_decl(t);
10608 if (!type)
10609 return type_decl_sptr();
10610
10611 real_type int_type;
10612 if (!parse_real_type(type->get_name(), int_type))
10613 return type_decl_sptr();
10614
10615 return type;
10616}
10617
10618/// Test if a type is an integral type.
10619///
10620/// @param t the type to test.
10621///
10622/// @return the integral type @p t can be converted to, or nil if @p
10623/// is not an integral type.
10624type_decl*
10626{
10627 type_decl* type = is_real_type(t);
10628 if (!type)
10629 return nullptr;
10630
10631 real_type rt;
10632 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10635 return nullptr;
10636
10637 return type;
10638}
10639
10640/// Test if a type is an integral type.
10641///
10642/// @param t the type to test.
10643///
10644/// @return the integral type @p t can be converted to, or nil if @p
10645/// is not an integral type.
10648{
10649 type_decl_sptr type = is_real_type(t);
10650 if (!type)
10651 return type;
10652
10653 real_type rt;
10654 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10657 return type_decl_sptr();
10658
10659 return type;
10660}
10661
10662/// Test whether a type is a typedef.
10663///
10664/// @param t the type to test for.
10665///
10666/// @return the typedef declaration of the @p t, or NULL if it's not a
10667/// typedef.
10670{return dynamic_pointer_cast<typedef_decl>(t);}
10671
10672/// Test whether a type is a typedef.
10673///
10674/// @param t the declaration of the type to test for.
10675///
10676/// @return the typedef declaration of the @p t, or NULL if it's not a
10677/// typedef.
10678const typedef_decl*
10680{return dynamic_cast<const typedef_decl*>(t);}
10681
10682/// Test whether a type is a typedef.
10683///
10684/// @param t the declaration of the type to test for.
10685///
10686/// @return the typedef declaration of the @p t, or NULL if it's not a
10687/// typedef.
10690{return dynamic_cast<typedef_decl*>(t);}
10691
10692/// Test whether a type is a typedef.
10693///
10694/// @param t the declaration of the type to test for.
10695///
10696/// @return the typedef declaration of the @p t, or NULL if it's not a
10697/// typedef.
10698const typedef_decl*
10700{return dynamic_cast<const typedef_decl*>(t);}
10701/// Test if a type is an enum. This function looks through typedefs.
10702///
10703/// @parm t the type to consider.
10704///
10705/// @return the enum_decl if @p t is an @ref enum_decl or null
10706/// otherwise.
10708is_compatible_with_enum_type(const type_base_sptr& t)
10709{
10710 if (!t)
10711 return enum_type_decl_sptr();
10712
10713 // Normally we should strip typedefs entirely, but this is
10714 // potentially costly, especially on binaries with huge changesets
10715 // like the Linux Kernel. So we just get the leaf types for now.
10716 //
10717 // Maybe there should be an option by which users accepts to pay the
10718 // CPU usage toll in exchange for finer filtering?
10719
10720 // type_base_sptr ty = strip_typedef(t);
10721 type_base_sptr ty = peel_typedef_type(t);;
10722 return is_enum_type(ty);
10723}
10724
10725/// Test if a type is an enum. This function looks through typedefs.
10726///
10727/// @parm t the type to consider.
10728///
10729/// @return the enum_decl if @p t is an @ref enum_decl or null
10730/// otherwise.
10732is_compatible_with_enum_type(const decl_base_sptr& t)
10734
10735/// Test if a decl is an enum_type_decl
10736///
10737/// @param d the decl to test for.
10738///
10739/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
10740const enum_type_decl*
10742{return dynamic_cast<const enum_type_decl*>(d);}
10743
10744/// Test if a decl is an enum_type_decl
10745///
10746/// @param d the decl to test for.
10747///
10748/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
10751{return dynamic_pointer_cast<enum_type_decl>(d);}
10752
10753/// Test if a type is a class. This function looks through typedefs.
10754///
10755/// @parm t the type to consider.
10756///
10757/// @return the class_decl if @p t is a class_decl or null otherwise.
10759is_compatible_with_class_type(const type_base_sptr& t)
10760{
10761 if (!t)
10762 return class_decl_sptr();
10763
10764 // Normally we should strip typedefs entirely, but this is
10765 // potentially costly, especially on binaries with huge changesets
10766 // like the Linux Kernel. So we just get the leaf types for now.
10767 //
10768 // Maybe there should be an option by which users accepts to pay the
10769 // CPU usage toll in exchange for finer filtering?
10770
10771 // type_base_sptr ty = strip_typedef(t);
10772 type_base_sptr ty = peel_typedef_type(t);
10773 return is_class_type(ty);
10774}
10775
10776/// Test if a type is a class. This function looks through typedefs.
10777///
10778/// @parm t the type to consider.
10779///
10780/// @return the class_decl if @p t is a class_decl or null otherwise.
10782is_compatible_with_class_type(const decl_base_sptr& t)
10784
10785/// Test whether a type is a class.
10786///
10787/// @parm t the type to consider.
10788///
10789/// @return true iff @p t is a class_decl.
10790bool
10792{return is_class_type(&t);}
10793
10794/// Test whether a type is a class.
10795///
10796/// @parm t the type to consider.
10797///
10798/// @return the class_decl if @p t is a class_decl or null otherwise.
10801{
10802 if (!t)
10803 return 0;
10804
10805 if (t->kind() & type_or_decl_base::CLASS_TYPE)
10806 return reinterpret_cast<class_decl*>
10807 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10808
10809 return 0;
10810}
10811
10812/// Test whether a type is a class.
10813///
10814/// @parm t the type to consider.
10815///
10816/// @return the class_decl if @p t is a class_decl or null otherwise.
10819{return dynamic_pointer_cast<class_decl>(d);}
10820
10821/// Test if the last data member of a class is an array with
10822/// non-finite data member.
10823///
10824/// The flexible data member idiom is a well known C idiom:
10825/// https://en.wikipedia.org/wiki/Flexible_array_member.
10826///
10827/// @param klass the class to consider.
10828///
10829/// @return the data member which type is a flexible array, if any, or
10830/// nil.
10833{
10834 var_decl_sptr nil;
10836 if (dms.empty())
10837 return nil;
10838
10839 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
10840 {// The type of the last data member is an array.
10841 if (array->is_non_finite())
10842 // The array has a non-finite size. We are thus looking at a
10843 // flexible array data member. Let's return it.
10844 return dms.back();
10845 }
10846
10847 return nil;
10848}
10849
10850/// Test if the last data member of a class is an array with
10851/// non-finite data member.
10852///
10853/// The flexible data member idiom is a well known C idiom:
10854/// https://en.wikipedia.org/wiki/Flexible_array_member.
10855///
10856/// @param klass the class to consider.
10857///
10858/// @return the data member which type is a flexible array, if any, or
10859/// nil.
10862{
10863 if (!klass)
10864 return var_decl_sptr();
10865
10866 return has_flexible_array_data_member(*klass);
10867}
10868
10869/// Test if the last data member of a class is an array with
10870/// non-finite data member.
10871///
10872/// The flexible data member idiom is a well known C idiom:
10873/// https://en.wikipedia.org/wiki/Flexible_array_member.
10874///
10875/// @param klass the class to consider.
10876///
10877/// @return the data member which type is a flexible array, if any, or
10878/// nil.
10882
10883/// Test if the last data member of a class is an array with
10884/// one element.
10885///
10886/// An array with one element is a way to mimic the flexible data
10887/// member idiom that was later standardized in C99.
10888///
10889/// To learn more about the flexible data member idiom, please
10890/// consider reading :
10891/// https://en.wikipedia.org/wiki/Flexible_array_member.
10892///
10893/// The various ways of representing that idiom pre-standardization
10894/// are presented in this article:
10895/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10896///
10897/// @param klass the class to consider.
10898///
10899/// @return the data member which type is a fake flexible array, if
10900/// any, or nil.
10903{
10904 var_decl_sptr nil;
10906 if (dms.empty())
10907 return nil;
10908
10909 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
10910 {// The type of the last data member is an array.
10911 if (array->get_subranges().size() == 1
10912 && array->get_subranges()[0]->get_length() == 1)
10913 // The array has a size of one. We are thus looking at a
10914 // "fake" flexible array data member. Let's return it.
10915 return dms.back();
10916 }
10917
10918 return nil;
10919}
10920
10921/// Test if the last data member of a class is an array with
10922/// one element.
10923///
10924/// An array with one element is a way to mimic the flexible data
10925/// member idiom that was later standardized in C99.
10926///
10927/// To learn more about the flexible data member idiom, please
10928/// consider reading :
10929/// https://en.wikipedia.org/wiki/Flexible_array_member.
10930///
10931/// The various ways of representing that idiom pre-standardization
10932/// are presented in this article:
10933/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10934///
10935/// @param klass the class to consider.
10936///
10937/// @return the data member which type is a fake flexible array, if
10938/// any, or nil.
10942
10943/// Test if the last data member of a class is an array with
10944/// one element.
10945///
10946/// An array with one element is a way to mimic the flexible data
10947/// member idiom that was later standardized in C99.
10948///
10949/// To learn more about the flexible data member idiom, please
10950/// consider reading :
10951/// https://en.wikipedia.org/wiki/Flexible_array_member.
10952///
10953/// The various ways of representing that idiom pre-standardization
10954/// are presented in this article:
10955/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10956///
10957/// @param klass the class to consider.
10958///
10959/// @return the data member which type is a fake flexible array, if
10960/// any, or nil.
10964
10965/// Test wheter a type is a declaration-only class.
10966///
10967/// @param t the type to considier.
10968///
10969/// @param look_through_decl_only if true, then look through the
10970/// decl-only class to see if it actually has a class definition in
10971/// the same ABI corpus.
10972///
10973/// @return true iff @p t is a declaration-only class.
10974bool
10977{
10978 if (class_or_union *klass = is_class_or_union_type(t))
10979 {
10981 klass = look_through_decl_only_class(klass);
10982 return klass->get_is_declaration_only();
10983 }
10984 return false;
10985}
10986
10987/// Test wheter a type is a declaration-only class.
10988///
10989/// @param t the type to considier.
10990///
10991/// @param look_through_decl_only if true, then look through the
10992/// decl-only class to see if it actually has a class definition in
10993/// the same ABI corpus.
10994///
10995/// @return true iff @p t is a declaration-only class.
10996bool
11000
11001/// Test wheter a type is a declaration-only class.
11002///
11003/// @param t the type to considier.
11004///
11005/// @param look_through_decl_only if true, then look through the
11006/// decl-only class to see if it actually has a class definition in
11007/// the same ABI corpus.
11008///
11009/// @return true iff @p t is a declaration-only class.
11010bool
11014
11015/// Test if a type is a @ref class_or_union.
11016///
11017/// @param t the type to consider.
11018///
11019/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11020/// nil otherwise.
11023{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
11024
11025/// Test if a type is a @ref class_or_union.
11026///
11027/// @param t the type to consider.
11028///
11029/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11030/// nil otherwise.
11031shared_ptr<class_or_union>
11032is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
11033{return dynamic_pointer_cast<class_or_union>(t);}
11034
11035/// Test if two class or union types are of the same kind.
11036///
11037/// @param first the first type to consider.
11038///
11039/// @param second the second type to consider.
11040///
11041/// @return true iff @p first is of the same kind as @p second.
11042bool
11044 const class_or_union* second)
11045{
11046 if ((is_class_type(first) && is_class_type(second))
11047 || (is_union_type(first) && is_union_type(second)))
11048 return true;
11049
11050 return false;
11051}
11052
11053/// Test if two class or union types are of the same kind.
11054///
11055/// @param first the first type to consider.
11056///
11057/// @param second the second type to consider.
11058///
11059/// @return true iff @p first is of the same kind as @p second.
11060bool
11061class_or_union_types_of_same_kind(const class_or_union_sptr& first,
11062 const class_or_union_sptr& second)
11063{return class_or_union_types_of_same_kind(first.get(), second.get());}
11064
11065/// Test if a type is a @ref union_decl.
11066///
11067/// @param t the type to consider.
11068///
11069/// @return true iff @p t is a union_decl.
11070bool
11072{return is_union_type(&t);}
11073
11074/// Test if a type is a @ref union_decl.
11075///
11076/// @param t the type to consider.
11077///
11078/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11079/// otherwise.
11082{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
11083
11084/// Test if a type is a @ref union_decl.
11085///
11086/// @param t the type to consider.
11087///
11088/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11089/// otherwise.
11090union_decl_sptr
11091is_union_type(const shared_ptr<type_or_decl_base>& t)
11092{return dynamic_pointer_cast<union_decl>(t);}
11093
11094/// Test whether a type is a pointer_type_def.
11095///
11096/// @param t the type to test.
11097///
11098/// @param look_through_decl_only if this is true, then look through
11099/// qualified types to see if the underlying type is a
11100/// pointer_type_def.
11101///
11102/// @return the @ref pointer_type_def_sptr if @p t is a
11103/// pointer_type_def, null otherwise.
11104const pointer_type_def*
11106 bool look_through_qualifiers)
11107{
11108 if (!t)
11109 return 0;
11110
11111 const type_base* type = is_type(t);
11112 if (look_through_qualifiers)
11113 type = peel_qualified_type(is_type(t));
11114
11115 return dynamic_cast<pointer_type_def*>(const_cast<type_base*>(type));
11116}
11117
11118/// Test whether a type is a pointer_type_def.
11119///
11120/// @param t the type to test.
11121///
11122/// @param look_through_decl_only if this is true, then look through
11123/// qualified types to see if the underlying type is a
11124/// pointer_type_def.
11125///
11126/// @return the @ref pointer_type_def_sptr if @p t is a
11127/// pointer_type_def, null otherwise.
11130 bool look_through_qualifiers)
11131{
11132 type_base_sptr type = is_type(t);
11133 if (look_through_qualifiers)
11134 type = peel_qualified_type(type);
11135 return dynamic_pointer_cast<pointer_type_def>(type);
11136}
11137
11138/// Test if a type is a pointer to function type.
11139///
11140/// @param t the type to consider.
11141///
11142/// @return the @ref pointer_type_def_sptr iff @p t is a pointer to
11143/// function type.
11145is_pointer_to_function_type(const type_base_sptr& t)
11146{
11148 {
11149 if (is_function_type(p->get_pointed_to_type()))
11150 return p;
11151 }
11152 return pointer_type_def_sptr();
11153}
11154
11155/// Test if a type is a pointer to array type.
11156///
11157/// @param t the type to consider.
11158///
11159/// @return the pointer_type_def_sptr iff @p t is a pointer to array
11160/// type.
11162is_pointer_to_array_type(const type_base_sptr& t)
11163{
11165 {
11166 if (is_array_type(p->get_pointed_to_type()))
11167 return p;
11168 }
11169 return pointer_type_def_sptr();
11170}
11171
11172/// Test if we are looking at a pointer to a
11173/// neither-a-pointer-to-an-array-nor-a-function type.
11174///
11175/// @param t the type to consider.
11176///
11177/// @return the @ref pointer_type_def_sptr type iff @p t is a
11178/// neither-a-pointer-an-array-nor-a-function type.
11180is_pointer_to_npaf_type(const type_base_sptr& t)
11181{
11183 {
11184 if (is_npaf_type(p->get_pointed_to_type()))
11185 return p;
11186 }
11187 return pointer_type_def_sptr();
11188}
11189
11190/// Test if we are looking at a pointer to pointer to member type.
11191///
11192/// @param t the type to consider.
11193///
11194/// @return the @ref pointer_type_def_sptr type iff @p t is a pointer
11195/// to pointer to member type.
11197is_pointer_to_ptr_to_mbr_type(const type_base_sptr& t)
11198{
11200 {
11201 if (is_ptr_to_mbr_type(p->get_pointed_to_type()))
11202 return p;
11203 }
11204 return pointer_type_def_sptr();
11205}
11206
11207/// Test if a type is a typedef, pointer or reference to a decl-only
11208/// class/union.
11209///
11210/// This looks into qualified types too.
11211///
11212/// @param t the type to consider.
11213///
11214/// @return true iff @p t is a type is a typedef, pointer or reference
11215/// to a decl-only class/union.
11216bool
11218{
11219 const type_base * type =
11220 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11221
11223 /*look_through_decl_only=*/true))
11224 return true;
11225
11226 return false;
11227}
11228
11229/// Test if a type is a typedef of a class or union type, or a typedef
11230/// of a qualified class or union type.
11231///
11232/// Note that if the type is directly a class or union type, the
11233/// function returns true as well.
11234///
11235/// @param t the type to consider.
11236///
11237/// @return true iff @p t is a typedef of a class or union type, or a
11238/// typedef of a qualified class or union type.
11239bool
11241{
11242 if (!t)
11243 return false;
11244
11247 return true;
11248
11249return false;
11250}
11251
11252/// Test if a type is a typedef of a class or union type, or a typedef
11253/// of a qualified class or union type.
11254///
11255/// Note that if the type is directly a class or union type, the
11256/// function returns true as well.
11257///
11258/// @param t the type to consider.
11259///
11260/// @return true iff @p t is a typedef of a class or union type, or a
11261/// typedef of a qualified class or union type.
11262bool
11265
11266/// Test whether a type is a reference_type_def.
11267///
11268/// @param t the type to test.
11269///
11270/// @param look_through_decl_only if this is true, then look through
11271/// qualified types to see if the underlying type is a
11272/// reference_type_def.
11273///
11274/// @return the @ref reference_type_def_sptr if @p t is a
11275/// reference_type_def, null otherwise.
11278 bool look_through_qualifiers)
11279{
11280 const type_base* type = is_type(t);
11281 if (!type)
11282 return nullptr;
11283
11284 if (look_through_qualifiers)
11285 type = peel_qualified_type(type);
11286 return dynamic_cast<reference_type_def*>(const_cast<type_base*>(type));
11287}
11288
11289/// Test whether a type is a reference_type_def.
11290///
11291/// @param t the type to test.
11292///
11293/// @param look_through_decl_only if this is true, then look through
11294/// qualified types to see if the underlying type is a
11295/// reference_type_def.
11296///
11297/// @return the @ref reference_type_def_sptr if @p t is a
11298/// reference_type_def, null otherwise.
11299const reference_type_def*
11301 bool look_through_qualifiers)
11302{
11303 const type_base* type = is_type(t);
11304
11305 if (look_through_qualifiers)
11306 type = peel_qualified_type(type);
11307 return dynamic_cast<const reference_type_def*>(type);
11308}
11309
11310/// Test whether a type is a reference_type_def.
11311///
11312/// @param t the type to test.
11313///
11314/// @param look_through_decl_only if this is true, then look through
11315/// qualified types to see if the underlying type is a
11316/// reference_type_def.
11317///
11318/// @return the @ref reference_type_def_sptr if @p t is a
11319/// reference_type_def, null otherwise.
11322 bool look_through_qualifiers)
11323{
11324 type_base_sptr type = is_type(t);
11325 if (look_through_qualifiers)
11326 type = peel_qualified_type(type);
11327 return dynamic_pointer_cast<reference_type_def>(type);
11328}
11329
11330/// Test whether a type is a @ref ptr_to_mbr_type.
11331///
11332/// @param t the type to test.
11333///
11334/// @return the @ref ptr_to_mbr_type* if @p t is a @ref
11335/// ptr_to_mbr_type type, null otherwise.
11336const ptr_to_mbr_type*
11338 bool look_through_qualifiers)
11339{
11340 const type_base* type = is_type(t);
11341 if (look_through_qualifiers)
11342 type = peel_qualified_type(type);
11343 return dynamic_cast<const ptr_to_mbr_type*>(type);
11344}
11345
11346/// Test whether a type is a @ref ptr_to_mbr_type_sptr.
11347///
11348/// @param t the type to test.
11349///
11350/// @param look_through_decl_only if this is true, then look through
11351/// qualified types to see if the underlying type is a
11352/// ptr_to_mbr_type..
11353///
11354/// @return the @ref ptr_to_mbr_type_sptr if @p t is a @ref
11355/// ptr_to_mbr_type type, null otherwise.
11358 bool look_through_qualifiers)
11359{
11360 type_base_sptr type = is_type(t);
11361 if (look_through_qualifiers)
11362 type = peel_qualified_type(type);
11363 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
11364}
11365
11366/// Test if a type is equivalent to a pointer to void type.
11367///
11368/// Note that this looks trough typedefs or CV qualifiers to look for
11369/// the void pointer.
11370///
11371/// @param type the type to consider.
11372///
11373/// @return the actual void pointer if @p is eqivalent to a void
11374/// pointer or NULL if it's not.
11375const type_base*
11377{
11378 type = peel_qualified_or_typedef_type(type);
11379
11380 const pointer_type_def * t = is_pointer_type(type);
11381 if (!t)
11382 return 0;
11383
11384 // Look through typedefs in the pointed-to type as well.
11385 type_base * ty = t->get_pointed_to_type().get();
11387 if (ty && ty->get_environment().is_void_type(ty))
11388 return ty;
11389
11390 return 0;
11391}
11392
11393/// Test if a type is equivalent to a pointer to void type.
11394///
11395/// Note that this looks trough typedefs or CV qualifiers to look for
11396/// the void pointer.
11397///
11398/// @param type the type to consider.
11399///
11400/// @return the actual void pointer if @p is eqivalent to a void
11401/// pointer or NULL if it's not.
11402const type_base*
11405
11406/// Test if a type is a pointer to void type.
11407///
11408/// @param type the type to consider.
11409///
11410/// @return the actual void pointer if @p is a void pointer or NULL if
11411/// it's not.
11412const type_base*
11414{
11415 if (!t)
11416 return nullptr;
11417
11418 if (t->get_environment().get_void_pointer_type().get() == t)
11419 return t;
11420
11421 const pointer_type_def* ptr = is_pointer_type(t);
11422 if (!ptr)
11423 return nullptr;
11424
11426 return t;
11427
11428 return nullptr;
11429}
11430
11431/// Test if a type is a pointer to void type.
11432///
11433/// @param type the type to consider.
11434///
11435/// @return the actual void pointer if @p is a void pointer or NULL if
11436/// it's not.
11437const type_base_sptr
11438is_void_pointer_type(const type_base_sptr& t)
11439{
11440 type_base_sptr nil;
11441 if (!t)
11442 return nil;
11443
11444 if (t->get_environment().get_void_pointer_type().get() == t.get())
11445 return t;
11446
11447 const pointer_type_def* ptr = is_pointer_type(t.get());
11448 if (!ptr)
11449 return nil;
11450
11451 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11452 return t;
11453
11454 return nil;
11455}
11456
11457/// Test whether a type is a reference_type_def.
11458///
11459/// @param t the type to test.
11460///
11461/// @return the @ref reference_type_def_sptr if @p t is a
11462/// reference_type_def, null otherwise.
11465{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11466
11467/// Test whether a type is a qualified_type_def.
11468///
11469/// @param t the type to test.
11470///
11471/// @return the @ref qualified_type_def_sptr if @p t is a
11472/// qualified_type_def, null otherwise.
11473qualified_type_def_sptr
11475{return dynamic_pointer_cast<qualified_type_def>(t);}
11476
11477/// Test whether a type is a function_type.
11478///
11479/// @param t the type to test.
11480///
11481/// @return the @ref function_type_sptr if @p t is a
11482/// function_type, null otherwise.
11485{return dynamic_pointer_cast<function_type>(t);}
11486
11487/// Test whether a type is a function_type.
11488///
11489/// @param t the type to test.
11490///
11491/// @return the @ref function_type_sptr if @p t is a
11492/// function_type, null otherwise.
11495{return dynamic_cast<function_type*>(t);}
11496
11497/// Test whether a type is a function_type.
11498///
11499/// @param t the type to test.
11500///
11501/// @return the @ref function_type_sptr if @p t is a
11502/// function_type, null otherwise.
11503const function_type*
11505{return dynamic_cast<const function_type*>(t);}
11506
11507/// Test whether a type is a method_type.
11508///
11509/// @param t the type to test.
11510///
11511/// @return the @ref method_type_sptr if @p t is a
11512/// method_type, null otherwise.
11515{return dynamic_pointer_cast<method_type>(t);}
11516
11517/// Test whether a type is a method_type.
11518///
11519/// @param t the type to test.
11520///
11521/// @return the @ref method_type_sptr if @p t is a
11522/// method_type, null otherwise.
11523const method_type*
11525{return dynamic_cast<const method_type*>(t);}
11526
11527/// Test whether a type is a method_type.
11528///
11529/// @param t the type to test.
11530///
11531/// @return the @ref method_type_sptr if @p t is a
11532/// method_type, null otherwise.
11535{return dynamic_cast<method_type*>(t);}
11536
11537/// If a class (or union) is a decl-only class, get its definition.
11538/// Otherwise, just return the initial class.
11539///
11540/// @param the_class the class (or union) to consider.
11541///
11542/// @return either the definition of the class, or the class itself.
11546
11547/// If a class (or union) is a decl-only class, get its definition.
11548/// Otherwise, just return the initial class.
11549///
11550/// @param the_class the class (or union) to consider.
11551///
11552/// @return either the definition of the class, or the class itself.
11553class_or_union_sptr
11556
11557/// If a class (or union) is a decl-only class, get its definition.
11558/// Otherwise, just return the initial class.
11559///
11560/// @param klass the class (or union) to consider.
11561///
11562/// @return either the definition of the class, or the class itself.
11563class_or_union_sptr
11564look_through_decl_only_class(class_or_union_sptr klass)
11566
11567/// If an enum is a decl-only enum, get its definition.
11568/// Otherwise, just return the initial enum.
11569///
11570/// @param the_enum the enum to consider.
11571///
11572/// @return either the definition of the enum, or the enum itself.
11576
11577/// If an enum is a decl-only enum, get its definition.
11578/// Otherwise, just return the initial enum.
11579///
11580/// @param enom the enum to consider.
11581///
11582/// @return either the definition of the enum, or the enum itself.
11586
11587/// If a decl is decl-only get its definition. Otherwise, just return nil.
11588///
11589/// @param d the decl to consider.
11590///
11591/// @return either the definition of the decl, or nil.
11592decl_base_sptr
11594{
11595 decl_base_sptr decl;
11598
11599 if (!decl)
11600 return decl;
11601
11602 while (decl->get_is_declaration_only()
11603 && decl->get_definition_of_declaration())
11604 decl = decl->get_definition_of_declaration();
11605
11606 return decl;
11607}
11608
11609/// If a decl is decl-only enum, get its definition. Otherwise, just
11610/// return the initial decl.
11611///
11612/// @param d the decl to consider.
11613///
11614/// @return either the definition of the enum, or the decl itself.
11615decl_base*
11617{
11618 if (!d)
11619 return d;
11620
11621 decl_base* result = look_through_decl_only(*d).get();
11622 if (!result)
11623 result = d;
11624
11625 return result;
11626}
11627
11628/// If a decl is decl-only get its definition. Otherwise, just return nil.
11629///
11630/// @param d the decl to consider.
11631///
11632/// @return either the definition of the decl, or nil.
11633decl_base_sptr
11634look_through_decl_only(const decl_base_sptr& d)
11635{
11636 if (!d)
11637 return d;
11638
11639 decl_base_sptr result = look_through_decl_only(*d);
11640 if (!result)
11641 result = d;
11642
11643 return result;
11644}
11645
11646/// If a type is is decl-only, then get its definition. Otherwise,
11647/// just return the initial type.
11648///
11649/// @param d the decl to consider.
11650///
11651/// @return either the definition of the decl, or the initial type.
11652type_base*
11654{
11655 decl_base* d = is_decl(t);
11656 if (!d)
11657 return t;
11659 return is_type(d);
11660}
11661
11662/// If a type is is decl-only, then get its definition. Otherwise,
11663/// just return the initial type.
11664///
11665/// @param d the decl to consider.
11666///
11667/// @return either the definition of the decl, or the initial type.
11668type_base_sptr
11669look_through_decl_only_type(const type_base_sptr& t)
11670{
11671 decl_base_sptr d = is_decl(t);
11672 if (!d)
11673 return t;
11675 return is_type(d);
11676}
11677
11678/// Tests if a declaration is a variable declaration.
11679///
11680/// @param decl the decl to test.
11681///
11682/// @return the var_decl_sptr iff decl is a variable declaration; nil
11683/// otherwise.
11684var_decl*
11686{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
11687
11688/// Tests if a declaration is a variable declaration.
11689///
11690/// @param decl the decl to test.
11691///
11692/// @return the var_decl_sptr iff decl is a variable declaration; nil
11693/// otherwise.
11696{return dynamic_pointer_cast<var_decl>(decl);}
11697
11698/// Tests if a declaration is a namespace declaration.
11699///
11700/// @param d the decalration to consider.
11701///
11702/// @return the namespace declaration if @p d is a namespace.
11704is_namespace(const decl_base_sptr& d)
11705{return dynamic_pointer_cast<namespace_decl>(d);}
11706
11707/// Tests if a declaration is a namespace declaration.
11708///
11709/// @param d the decalration to consider.
11710///
11711/// @return the namespace declaration if @p d is a namespace.
11714{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
11715
11716/// Tests whether a decl is a template parameter composition type.
11717///
11718/// @param decl the declaration to consider.
11719///
11720/// @return true iff decl is a template parameter composition type.
11721bool
11722is_template_parm_composition_type(const shared_ptr<decl_base> decl)
11723{
11724 return (decl
11725 && is_at_template_scope(decl)
11726 && is_type(decl)
11727 && !is_template_parameter(decl));
11728}
11729
11730/// Test whether a decl is the pattern of a function template.
11731///
11732/// @param decl the decl to consider.
11733///
11734/// @return true iff decl is the pattern of a function template.
11735bool
11736is_function_template_pattern(const shared_ptr<decl_base> decl)
11737{
11738 return (decl
11739 && dynamic_pointer_cast<function_decl>(decl)
11740 && dynamic_cast<template_decl*>(decl->get_scope()));
11741}
11742
11743/// Test if a type is an array_type_def.
11744///
11745/// @param type the type to consider.
11746///
11747/// @return true iff @p type is an array_type_def.
11750 bool look_through_qualifiers)
11751{
11752 const type_base* t = is_type(type);
11753
11754 if (look_through_qualifiers)
11755 t = peel_qualified_type(t);
11756 return dynamic_cast<array_type_def*>(const_cast<type_base*>(t));
11757}
11758
11759/// Test if a type is an array_type_def.
11760///
11761/// @param type the type to consider.
11762///
11763/// @return true iff @p type is an array_type_def.
11766 bool look_through_qualifiers)
11767{
11768 type_base_sptr t = is_type(type);
11769
11770 if (look_through_qualifiers)
11771 t = peel_qualified_type(t);
11772 return dynamic_pointer_cast<array_type_def>(t);
11773}
11774
11775/// Tests if the element of a given array is a qualified type.
11776///
11777/// @param array the array type to consider.
11778///
11779/// @return the qualified element of the array iff it's a qualified
11780/// type. Otherwise, return a nil object.
11781qualified_type_def_sptr
11783{
11784 if (!array)
11785 return qualified_type_def_sptr();
11786
11787 return is_qualified_type(array->get_element_type());
11788}
11789
11790/// Test if an array type is an array to a qualified element type.
11791///
11792/// @param type the array type to consider.
11793///
11794/// @return true the array @p type iff it's an array to a qualified
11795/// element type.
11797is_array_of_qualified_element(const type_base_sptr& type)
11798{
11799 if (array_type_def_sptr array = is_array_type(type))
11801 return array;
11802
11803 return array_type_def_sptr();
11804}
11805
11806/// Test if a type is a typedef of an array.
11807///
11808/// Note that the function looks through qualified and typedefs types
11809/// of the underlying type of the current typedef. In other words, if
11810/// we are looking at a typedef of a CV-qualified array, or at a
11811/// typedef of a CV-qualified typedef of an array, this function will
11812/// still return TRUE.
11813///
11814/// @param t the type to consider.
11815///
11816/// @return true if t is a typedef which underlying type is an array.
11817/// That array might be either cv-qualified array or a typedef'ed
11818/// array, or a combination of both.
11820is_typedef_of_array(const type_base_sptr& t)
11821{
11822 array_type_def_sptr result;
11823
11824 if (typedef_decl_sptr typdef = is_typedef(t))
11825 {
11826 type_base_sptr u =
11827 peel_qualified_or_typedef_type(typdef->get_underlying_type());
11828 result = is_array_type(u);
11829 }
11830
11831 return result;
11832}
11833
11834/// Test if a type is an array_type_def::subrange_type.
11835///
11836/// @param type the type to consider.
11837///
11838/// @return the array_type_def::subrange_type which @p type is a type
11839/// of, or nil if it's not of that type.
11842{
11843 return dynamic_cast<array_type_def::subrange_type*>
11844 (const_cast<type_or_decl_base*>(type));
11845}
11846
11847/// Test if a type is an array_type_def::subrange_type.
11848///
11849/// @param type the type to consider.
11850///
11851/// @return the array_type_def::subrange_type which @p type is a type
11852/// of, or nil if it's not of that type.
11855{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
11856
11857/// Tests whether a decl is a template.
11858///
11859/// @param decl the decl to consider.
11860///
11861/// @return true iff decl is a function template, class template, or
11862/// template template parameter.
11863bool
11864is_template_decl(const decl_base_sptr& decl)
11865{return decl && dynamic_pointer_cast<template_decl>(decl);}
11866
11867/// This enum describe the kind of entity to lookup, while using the
11868/// lookup API.
11870{
11871 LOOKUP_ENTITY_TYPE,
11872 LOOKUP_ENTITY_VAR,
11873};
11874
11875/// Find the first relevant delimiter (the "::" string) in a fully
11876/// qualified C++ type name, starting from a given position. The
11877/// delimiter returned separates a type name from the name of its
11878/// context.
11879///
11880/// This is supposed to work correctly on names in cases like this:
11881///
11882/// foo<ns1::name1, ns2::name2>
11883///
11884/// In that case when called with with parameter @p begin set to 0, no
11885/// delimiter is returned, because the type name in this case is:
11886/// 'foo<ns1::name1, ns2::name2>'.
11887///
11888/// But in this case:
11889///
11890/// foo<p1, bar::name>::some_type
11891///
11892/// The "::" returned is the one right before 'some_type'.
11893///
11894/// @param fqn the fully qualified name of the type to consider.
11895///
11896/// @param begin the position from which to look for the delimiter.
11897///
11898/// @param delim_pos out parameter. Is set to the position of the
11899/// delimiter iff the function returned true.
11900///
11901/// @return true iff the function found and returned the delimiter.
11902static bool
11903find_next_delim_in_cplus_type(const string& fqn,
11904 size_t begin,
11905 size_t& delim_pos)
11906{
11907 int angle_count = 0;
11908 bool found = false;
11909 size_t i = begin;
11910 for (; i < fqn.size(); ++i)
11911 {
11912 if (fqn[i] == '<')
11913 ++angle_count;
11914 else if (fqn[i] == '>')
11915 --angle_count;
11916 else if (i + 1 < fqn.size()
11917 && !angle_count
11918 && fqn[i] == ':'
11919 && fqn[i+1] == ':')
11920 {
11921 delim_pos = i;
11922 found = true;
11923 break;
11924 }
11925 }
11926 return found;
11927}
11928
11929/// Decompose a fully qualified name into the list of its components.
11930///
11931/// @param fqn the fully qualified name to decompose.
11932///
11933/// @param comps the resulting list of component to fill.
11934void
11935fqn_to_components(const string& fqn,
11936 list<string>& comps)
11937{
11938 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
11939 do
11940 {
11941 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
11942 comp_end = fqn_size;
11943
11944 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
11945 comps.push_back(comp);
11946
11947 comp_begin = comp_end + 2;
11948 if (comp_begin >= fqn_size)
11949 break;
11950 } while (true);
11951}
11952
11953/// Turn a set of qualified name components (that name a type) into a
11954/// qualified name string.
11955///
11956/// @param comps the name components
11957///
11958/// @return the resulting string, which would be the qualified name of
11959/// a type.
11960string
11961components_to_type_name(const list<string>& comps)
11962{
11963 string result;
11964 for (list<string>::const_iterator c = comps.begin();
11965 c != comps.end();
11966 ++c)
11967 if (c == comps.begin())
11968 result = *c;
11969 else
11970 result += "::" + *c;
11971 return result;
11972}
11973
11974/// This predicate returns true if a given container iterator points
11975/// to the last element of the container, false otherwise.
11976///
11977/// @tparam T the type of the container of the iterator.
11978///
11979/// @param container the container the iterator points into.
11980///
11981/// @param i the iterator to consider.
11982///
11983/// @return true iff the iterator points to the last element of @p
11984/// container.
11985template<typename T>
11986static bool
11987iterator_is_last(T& container,
11988 typename T::const_iterator i)
11989{
11990 typename T::const_iterator next = i;
11991 ++next;
11992 return (next == container.end());
11993}
11994
11995//--------------------------------
11996// <type and decls lookup stuff>
11997// ------------------------------
11998
11999/// Lookup all the type*s* that have a given fully qualified name.
12000///
12001/// @param type_name the fully qualified name of the type to
12002/// lookup.
12003///
12004/// @param type_map the map to look into.
12005///
12006/// @return the vector containing the types named @p type_name. If
12007/// the lookup didn't yield any type, then this function returns nil.
12008static const type_base_wptrs_type*
12009lookup_types_in_map(const interned_string& type_name,
12010 const istring_type_base_wptrs_map_type& type_map)
12011{
12012 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12013 if (i != type_map.end())
12014 return &i->second;
12015 return 0;
12016}
12017
12018/// Lookup a type (with a given name) in a map that associates a type
12019/// name to a type. If there are several types with a given name,
12020/// then try to return the first one that is not decl-only.
12021/// Otherwise, return the last of such types, that is, the last one
12022/// that got registered.
12023///
12024/// @tparam TypeKind the type of the type this function is supposed to
12025/// return.
12026///
12027/// @param type_name the name of the type to lookup.
12028///
12029/// @param type_map the map in which to look.
12030///
12031/// @return a shared_ptr to the type found. If no type was found or
12032/// if the type found was not of type @p TypeKind then the function
12033/// returns nil.
12034template <class TypeKind>
12035static shared_ptr<TypeKind>
12036lookup_type_in_map(const interned_string& type_name,
12037 const istring_type_base_wptrs_map_type& type_map)
12038{
12039 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12040 if (i != type_map.end())
12041 {
12042 // Walk the types that have the name "type_name" and return the
12043 // first one that is not declaration-only ...
12044 for (auto j : i->second)
12045 {
12046 type_base_sptr t(j);
12047 decl_base_sptr d = is_decl(t);
12048 if (d && !d->get_is_declaration_only())
12049 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
12050 }
12051 // ... or return the last type with the name "type_name" that
12052 // was recorded. It's likely to be declaration-only if we
12053 // reached this point.
12054 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
12055 }
12056 return shared_ptr<TypeKind>();
12057}
12058
12059/// Lookup a basic type from a translation unit.
12060///
12061/// This is done by looking the type up in the type map that is
12062/// maintained in the translation unit. So this is as fast as
12063/// possible.
12064///
12065/// @param type_name the name of the basic type to look for.
12066///
12067/// @param tu the translation unit to look into.
12068///
12069/// @return the basic type found or nil if no basic type was found.
12072{
12073 return lookup_type_in_map<type_decl>(type_name,
12074 tu.get_types().basic_types());
12075}
12076
12077/// Lookup a basic type from a translation unit.
12078///
12079/// This is done by looking the type up in the type map that is
12080/// maintained in the translation unit. So this is as fast as
12081/// possible.
12082///
12083/// @param type_name the name of the basic type to look for.
12084///
12085/// @param tu the translation unit to look into.
12086///
12087/// @return the basic type found or nil if no basic type was found.
12089lookup_basic_type(const string& type_name, const translation_unit& tu)
12090{
12091 const environment& env = tu.get_environment();
12092
12093 interned_string s = env.intern(type_name);
12094 return lookup_basic_type(s, tu);
12095}
12096
12097/// Lookup a class type from a translation unit.
12098///
12099/// This is done by looking the type up in the type map that is
12100/// maintained in the translation unit. So this is as fast as
12101/// possible.
12102///
12103/// @param fqn the fully qualified name of the class type node to look
12104/// up.
12105///
12106/// @param tu the translation unit to perform lookup from.
12107///
12108/// @return the declaration of the class type IR node found, NULL
12109/// otherwise.
12111lookup_class_type(const string& fqn, const translation_unit& tu)
12112{
12113 const environment& env = tu.get_environment();
12114 interned_string s = env.intern(fqn);
12115 return lookup_class_type(s, tu);
12116}
12117
12118/// Lookup a class type from a translation unit.
12119///
12120/// This is done by looking the type up in the type map that is
12121/// maintained in the translation unit. So this is as fast as
12122/// possible.
12123///
12124/// @param type_name the name of the class type to look for.
12125///
12126/// @param tu the translation unit to look into.
12127///
12128/// @return the class type found or nil if no class type was found.
12131{
12132 return lookup_type_in_map<class_decl>(type_name,
12133 tu.get_types().class_types());
12134}
12135
12136/// Lookup a union type from a translation unit.
12137///
12138/// This is done by looking the type up in the type map that is
12139/// maintained in the translation unit. So this is as fast as
12140/// possible.
12141///
12142/// @param type_name the name of the union type to look for.
12143///
12144/// @param tu the translation unit to look into.
12145///
12146/// @return the union type found or nil if no union type was found.
12147union_decl_sptr
12149{
12150 return lookup_type_in_map<union_decl>(type_name,
12151 tu.get_types().union_types());
12152}
12153
12154/// Lookup a union type from a translation unit.
12155///
12156/// This is done by looking the type up in the type map that is
12157/// maintained in the translation unit. So this is as fast as
12158/// possible.
12159///
12160/// @param fqn the fully qualified name of the type to lookup.
12161///
12162/// @param tu the translation unit to look into.
12163///
12164/// @return the union type found or nil if no union type was found.
12165union_decl_sptr
12166lookup_union_type(const string& fqn, const translation_unit& tu)
12167{
12168 const environment& env = tu.get_environment();
12169 interned_string s = env.intern(fqn);
12170 return lookup_union_type(s, tu);
12171}
12172
12173/// Lookup a union type in a given corpus, from its location.
12174///
12175/// @param loc the location of the union type to look for.
12176///
12177/// @param corp the corpus to look it from.
12178///
12179/// @return the resulting union_decl.
12180union_decl_sptr
12182{
12185 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
12186
12187 return result;
12188}
12189
12190/// Lookup a union type in a given corpus, from its location.
12191///
12192/// @param loc the location of the union type to look for.
12193///
12194/// @param corp the corpus to look it from.
12195///
12196/// @return the resulting union_decl.
12197union_decl_sptr
12198lookup_union_type_per_location(const string& loc, const corpus& corp)
12199{
12200 const environment& env = corp.get_environment();
12201 return lookup_union_type_per_location(env.intern(loc), corp);
12202}
12203
12204/// Lookup an enum type from a translation unit.
12205///
12206/// This is done by looking the type up in the type map that is
12207/// maintained in the translation unit. So this is as fast as
12208/// possible.
12209///
12210/// @param type_name the name of the enum type to look for.
12211///
12212/// @param tu the translation unit to look into.
12213///
12214/// @return the enum type found or nil if no enum type was found.
12217{
12218 return lookup_type_in_map<enum_type_decl>(type_name,
12219 tu.get_types().enum_types());
12220}
12221
12222/// Lookup an enum type from a translation unit.
12223///
12224/// This is done by looking the type up in the type map that is
12225/// maintained in the translation unit. So this is as fast as
12226/// possible.
12227///
12228/// @param type_name the name of the enum type to look for.
12229///
12230/// @param tu the translation unit to look into.
12231///
12232/// @return the enum type found or nil if no enum type was found.
12234lookup_enum_type(const string& type_name, const translation_unit& tu)
12235{
12236 const environment& env = tu.get_environment();
12237 interned_string s = env.intern(type_name);
12238 return lookup_enum_type(s, tu);
12239}
12240
12241/// Lookup a typedef type from a translation unit.
12242///
12243/// This is done by looking the type up in the type map that is
12244/// maintained in the translation unit. So this is as fast as
12245/// possible.
12246///
12247/// @param type_name the name of the typedef type to look for.
12248///
12249/// @param tu the translation unit to look into.
12250///
12251/// @return the typedef type found or nil if no typedef type was
12252/// found.
12255 const translation_unit& tu)
12256{
12257 return lookup_type_in_map<typedef_decl>(type_name,
12258 tu.get_types().typedef_types());
12259}
12260
12261/// Lookup a typedef type from a translation unit.
12262///
12263/// This is done by looking the type up in the type map that is
12264/// maintained in the translation unit. So this is as fast as
12265/// possible.
12266///
12267/// @param type_name the name of the typedef type to look for.
12268///
12269/// @param tu the translation unit to look into.
12270///
12271/// @return the typedef type found or nil if no typedef type was
12272/// found.
12274lookup_typedef_type(const string& type_name, const translation_unit& tu)
12275{
12276 const environment& env = tu.get_environment();
12277 interned_string s = env.intern(type_name);
12278 return lookup_typedef_type(s, tu);
12279}
12280
12281/// Lookup a qualified type from a translation unit.
12282///
12283/// This is done by looking the type up in the type map that is
12284/// maintained in the translation unit. So this is as fast as
12285/// possible.
12286///
12287/// @param type_name the name of the qualified type to look for.
12288///
12289/// @param tu the translation unit to look into.
12290///
12291/// @return the qualified type found or nil if no qualified type was
12292/// found.
12293qualified_type_def_sptr
12295 const translation_unit& tu)
12296{
12297 const type_maps& m = tu.get_types();
12298 return lookup_type_in_map<qualified_type_def>(type_name,
12299 m.qualified_types());
12300}
12301
12302/// Lookup a qualified type from a translation unit.
12303///
12304/// This is done by looking the type up in the type map that is
12305/// maintained in the translation unit. So this is as fast as
12306/// possible.
12307///
12308/// @param underlying_type the underying type of the qualified type to
12309/// look up.
12310///
12311/// @param quals the CV-qualifiers of the qualified type to look for.
12312///
12313/// @param tu the translation unit to look into.
12314///
12315/// @return the qualified type found or nil if no qualified type was
12316/// found.
12317qualified_type_def_sptr
12318lookup_qualified_type(const type_base_sptr& underlying_type,
12320 const translation_unit& tu)
12321{
12322 interned_string type_name = get_name_of_qualified_type(underlying_type,
12323 quals);
12324 return lookup_qualified_type(type_name, tu);
12325}
12326
12327/// Lookup a pointer type from a translation unit.
12328///
12329/// This is done by looking the type up in the type map that is
12330/// maintained in the translation unit. So this is as fast as
12331/// possible.
12332///
12333/// @param type_name the name of the pointer type to look for.
12334///
12335/// @param tu the translation unit to look into.
12336///
12337/// @return the pointer type found or nil if no pointer type was
12338/// found.
12341 const translation_unit& tu)
12342{
12343 const type_maps& m = tu.get_types();
12344 return lookup_type_in_map<pointer_type_def>(type_name,
12345 m.pointer_types());
12346}
12347
12348/// Lookup a pointer type from a translation unit.
12349///
12350/// This is done by looking the type up in the type map that is
12351/// maintained in the translation unit. So this is as fast as
12352/// possible.
12353///
12354/// @param type_name the name of the pointer type to look for.
12355///
12356/// @param tu the translation unit to look into.
12357///
12358/// @return the pointer type found or nil if no pointer type was
12359/// found.
12361lookup_pointer_type(const string& type_name, const translation_unit& tu)
12362{
12363 const environment& env = tu.get_environment();
12364 interned_string s = env.intern(type_name);
12365 return lookup_pointer_type(s, tu);
12366}
12367
12368/// Lookup a pointer type from a translation unit.
12369///
12370/// This is done by looking the type up in the type map that is
12371/// maintained in the translation unit. So this is as fast as
12372/// possible.
12373///
12374/// @param pointed_to_type the pointed-to-type of the pointer to look for.
12375///
12376/// @param tu the translation unit to look into.
12377///
12378/// @return the pointer type found or nil if no pointer type was
12379/// found.
12381lookup_pointer_type(const type_base_sptr& pointed_to_type,
12382 const translation_unit& tu)
12383{
12384 type_base_sptr t = look_through_decl_only_type(pointed_to_type);
12386 return lookup_pointer_type(type_name, tu);
12387}
12388
12389/// Lookup a reference type from a translation unit.
12390///
12391/// This is done by looking the type up in the type map that is
12392/// maintained in the translation unit. So this is as fast as
12393/// possible.
12394///
12395/// @param type_name the name of the reference type to look for.
12396///
12397/// @param tu the translation unit to look into.
12398///
12399/// @return the reference type found or nil if no reference type was
12400/// found.
12403 const translation_unit& tu)
12404{
12405 const type_maps& m = tu.get_types();
12406 return lookup_type_in_map<reference_type_def>(type_name,
12407 m.reference_types());
12408}
12409
12410/// Lookup a reference type from a translation unit.
12411///
12412/// This is done by looking the type up in the type map that is
12413/// maintained in the translation unit. So this is as fast as
12414/// possible.
12415///
12416/// @param pointed_to_type the pointed-to-type of the reference to
12417/// look up.
12418///
12419/// @param tu the translation unit to look into.
12420///
12421/// @return the reference type found or nil if no reference type was
12422/// found.
12424lookup_reference_type(const type_base_sptr& pointed_to_type,
12425 bool lvalue_reference,
12426 const translation_unit& tu)
12427{
12428 interned_string type_name =
12430 lvalue_reference);
12431 return lookup_reference_type(type_name, tu);
12432}
12433
12434/// Lookup an array type from a translation unit.
12435///
12436/// This is done by looking the type up in the type map that is
12437/// maintained in the translation unit. So this is as fast as
12438/// possible.
12439///
12440/// @param type_name the name of the array type to look for.
12441///
12442/// @param tu the translation unit to look into.
12443///
12444/// @return the array type found or nil if no array type was found.
12447 const translation_unit& tu)
12448{
12449 const type_maps& m = tu.get_types();
12450 return lookup_type_in_map<array_type_def>(type_name,
12451 m.array_types());
12452}
12453
12454/// Lookup a function 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 type_name the name of the type to lookup.
12461///
12462/// @param tu the translation unit to look into.
12463///
12464/// @return the function type found, or NULL of none was found.
12467 const translation_unit& tu)
12468{
12469 const type_maps& m = tu.get_types();
12470 return lookup_type_in_map<function_type>(type_name,
12471 m.function_types());
12472}
12473
12474/// Lookup a function type from a translation unit.
12475///
12476/// This walks all the function types held by the translation unit and
12477/// compare their sub-type *names*. If the names match then return
12478/// the function type found in the translation unit.
12479///
12480/// @param t the function type to look for.
12481///
12482/// @param tu the translation unit to look into.
12483///
12484/// @return the function type found, or NULL of none was found.
12487 const translation_unit& tu)
12488{
12489 interned_string type_name = get_type_name(t);
12490 return lookup_function_type(type_name, tu);
12491}
12492
12493/// Lookup a function type from a translation unit.
12494///
12495/// This is done by looking the type up in the type map that is
12496/// maintained in the translation unit. So this is as fast as
12497/// possible.
12498///
12499/// @param t the function type to look for.
12500///
12501/// @param tu the translation unit to look into.
12502///
12503/// @return the function type found, or NULL of none was found.
12506 const translation_unit& tu)
12507{return lookup_function_type(*t, tu);}
12508
12509/// Lookup a type in a translation unit.
12510///
12511/// @param fqn the fully qualified name of the type to lookup.
12512///
12513/// @param tu the translation unit to consider.
12514///
12515/// @return the declaration of the type if found, NULL otherwise.
12516const type_base_sptr
12518 const translation_unit& tu)
12519{
12520 type_base_sptr result;
12521 ((result = lookup_typedef_type(fqn, tu))
12522 || (result = lookup_class_type(fqn, tu))
12523 || (result = lookup_union_type(fqn, tu))
12524 || (result = lookup_enum_type(fqn, tu))
12525 || (result = lookup_qualified_type(fqn, tu))
12526 || (result = lookup_pointer_type(fqn, tu))
12527 || (result = lookup_reference_type(fqn, tu))
12528 || (result = lookup_array_type(fqn, tu))
12529 || (result = lookup_function_type(fqn, tu))
12530 || (result = lookup_basic_type(fqn, tu)));
12531
12532 return result;
12533}
12534
12535/// Lookup a type in a translation unit, starting from the global
12536/// namespace.
12537///
12538/// @param fqn the fully qualified name of the type to lookup.
12539///
12540/// @param tu the translation unit to consider.
12541///
12542/// @return the declaration of the type if found, NULL otherwise.
12543type_base_sptr
12544lookup_type(const string& fqn, const translation_unit& tu)
12545{
12546 const environment&env = tu.get_environment();
12547 interned_string ifqn = env.intern(fqn);
12548 return lookup_type(ifqn, tu);
12549}
12550
12551/// Lookup a type from a translation unit.
12552///
12553/// @param fqn the components of the fully qualified name of the node
12554/// to look up.
12555///
12556/// @param tu the translation unit to perform lookup from.
12557///
12558/// @return the declaration of the IR node found, NULL otherwise.
12559const type_base_sptr
12560lookup_type(const type_base_sptr type,
12561 const translation_unit& tu)
12562{
12563 interned_string type_name = get_type_name(type);
12564 return lookup_type(type_name, tu);
12565}
12566
12567/// Lookup a type in a scope.
12568///
12569/// This is really slow as it walks the member types of the scope in
12570/// sequence to find the type with a given name.
12571///
12572/// If possible, users should prefer looking up types from the
12573/// enclosing translation unit or even ABI corpus because both the
12574/// translation unit and the corpus have a map of type, indexed by
12575/// their name. Looking up a type from those maps is thus much
12576/// faster.
12577///
12578/// @param fqn the fully qualified name of the type to lookup.
12579///
12580/// @param skope the scope to look into.
12581///
12582/// @return the declaration of the type if found, NULL otherwise.
12583const type_base_sptr
12584lookup_type_in_scope(const string& fqn,
12585 const scope_decl_sptr& skope)
12586{
12587 list<string> comps;
12588 fqn_to_components(fqn, comps);
12589 return lookup_type_in_scope(comps, skope);
12590}
12591
12592/// Lookup a @ref var_decl in a scope.
12593///
12594/// @param fqn the fuly qualified name of the @var_decl to lookup.
12595///
12596/// @param skope the scope to look into.
12597///
12598/// @return the declaration of the @ref var_decl if found, NULL
12599/// otherwise.
12600const decl_base_sptr
12602 const scope_decl_sptr& skope)
12603{
12604 list<string> comps;
12605 fqn_to_components(fqn, comps);
12606 return lookup_var_decl_in_scope(comps, skope);
12607}
12608
12609/// A generic function (template) to get the name of a node, whatever
12610/// node it is. This has to be specialized for the kind of node we
12611/// want.
12612///
12613/// Note that a node is a member of a scope.
12614///
12615/// @tparam NodeKind the kind of node to consider.
12616///
12617/// @param node the node to get the name from.
12618///
12619/// @return the name of the node.
12620template<typename NodeKind>
12621static const interned_string&
12622get_node_name(shared_ptr<NodeKind> node);
12623
12624/// Gets the name of a class_decl node.
12625///
12626/// @param node the decl_base node to get the name from.
12627///
12628/// @return the name of the node.
12629template<>
12630const interned_string&
12631get_node_name(class_decl_sptr node)
12632{return node->get_name();}
12633
12634/// Gets the name of a type_base node.
12635///
12636/// @param node the type_base node to get the name from.
12637///
12638/// @return the name of the node.
12639template<>
12640const interned_string&
12641get_node_name(type_base_sptr node)
12642{return get_type_declaration(node)->get_name();}
12643
12644/// Gets the name of a var_decl node.
12645///
12646/// @param node the var_decl node to get the name from.
12647///
12648/// @return the name of the node.
12649template<>
12650const interned_string&
12651get_node_name(var_decl_sptr node)
12652{return node->get_name();}
12653
12654/// Generic function to get the declaration of a given node, whatever
12655/// it is. There has to be specializations for the kind of the nodes
12656/// we want to support.
12657///
12658/// @tparam NodeKind the type of the node we are looking at.
12659///
12660/// @return the declaration.
12661template<typename NodeKind>
12662static decl_base_sptr
12663convert_node_to_decl(shared_ptr<NodeKind> node);
12664
12665/// Lookup a node in a given scope.
12666///
12667/// @tparam the type of the node to lookup.
12668///
12669/// @param fqn the components of the fully qualified name of the node
12670/// to lookup.
12671///
12672/// @param skope the scope to look into.
12673///
12674/// @return the declaration of the looked up node, or NULL if it
12675/// wasn't found.
12676template<typename NodeKind>
12677static const type_or_decl_base_sptr
12678lookup_node_in_scope(const list<string>& fqn,
12679 const scope_decl_sptr& skope)
12680{
12681 type_or_decl_base_sptr resulting_decl;
12682 shared_ptr<NodeKind> node;
12683 bool it_is_last = false;
12684 scope_decl_sptr cur_scope = skope, new_scope, scope;
12685
12686 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
12687 {
12688 new_scope.reset();
12689 it_is_last = iterator_is_last(fqn, c);
12690 for (scope_decl::declarations::const_iterator m =
12691 cur_scope->get_member_decls().begin();
12692 m != cur_scope->get_member_decls().end();
12693 ++m)
12694 {
12695 if (!it_is_last)
12696 {
12697 // looking for a scope
12698 scope = dynamic_pointer_cast<scope_decl>(*m);
12699 if (scope && scope->get_name() == *c)
12700 {
12701 new_scope = scope;
12702 break;
12703 }
12704 }
12705 else
12706 {
12707 //looking for a final type.
12708 node = dynamic_pointer_cast<NodeKind>(*m);
12709 if (node && get_node_name(node) == *c)
12710 {
12711 if (class_decl_sptr cl =
12712 dynamic_pointer_cast<class_decl>(node))
12713 if (cl->get_is_declaration_only()
12714 && !cl->get_definition_of_declaration())
12715 continue;
12716 resulting_decl = node;
12717 break;
12718 }
12719 }
12720 }
12721 if (!new_scope && !resulting_decl)
12722 return decl_base_sptr();
12723 cur_scope = new_scope;
12724 }
12725 ABG_ASSERT(resulting_decl);
12726 return resulting_decl;
12727}
12728
12729/// lookup a type in a scope.
12730///
12731///
12732/// This is really slow as it walks the member types of the scope in
12733/// sequence to find the type with a given name.
12734///
12735/// If possible, users should prefer looking up types from the
12736/// enclosing translation unit or even ABI corpus because both the
12737/// translation unit and the corpus have a map of type, indexed by
12738/// their name. Looking up a type from those maps is thus much
12739/// faster.
12740///
12741/// @param comps the components of the fully qualified name of the
12742/// type to lookup.
12743///
12744/// @param skope the scope to look into.
12745///
12746/// @return the declaration of the type found.
12747const type_base_sptr
12748lookup_type_in_scope(const list<string>& comps,
12749 const scope_decl_sptr& scope)
12750{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
12751
12752/// lookup a type in a scope.
12753///
12754/// This is really slow as it walks the member types of the scope in
12755/// sequence to find the type with a given name.
12756///
12757/// If possible, users should prefer looking up types from the
12758/// enclosing translation unit or even ABI corpus because both the
12759/// translation unit and the corpus have a map of type, indexed by
12760/// their name. Looking up a type from those maps is thus much
12761/// faster.
12762///
12763/// @param type the type to look for.
12764///
12765/// @param access_path a vector of scopes the path of scopes to follow
12766/// before reaching the scope into which to look for @p type. Note
12767/// that the deepest scope (the one immediately containing @p type) is
12768/// at index 0 of this vector, and the top-most scope is the last
12769/// element of the vector.
12770///
12771/// @param scope the top-most scope into which to look for @p type.
12772///
12773/// @return the scope found in @p scope, or NULL if it wasn't found.
12774static const type_base_sptr
12776 const vector<scope_decl*>& access_path,
12777 const scope_decl* scope)
12778{
12779 vector<scope_decl*> a = access_path;
12780 type_base_sptr result;
12781
12782 scope_decl* first_scope = 0;
12783 if (!a.empty())
12784 {
12785 first_scope = a.back();
12786 ABG_ASSERT(first_scope->get_name() == scope->get_name());
12787 a.pop_back();
12788 }
12789
12790 if (a.empty())
12791 {
12792 interned_string n = get_type_name(type, false);
12793 for (scope_decl::declarations::const_iterator i =
12794 scope->get_member_decls().begin();
12795 i != scope->get_member_decls().end();
12796 ++i)
12797 if (is_type(*i) && (*i)->get_name() == n)
12798 {
12799 result = is_type(*i);
12800 break;
12801 }
12802 }
12803 else
12804 {
12805 first_scope = a.back();
12806 interned_string scope_name, cur_scope_name = first_scope->get_name();
12807 for (scope_decl::scopes::const_iterator i =
12808 scope->get_member_scopes().begin();
12809 i != scope->get_member_scopes().end();
12810 ++i)
12811 {
12812 scope_name = (*i)->get_name();
12813 if (scope_name == cur_scope_name)
12814 {
12815 result = lookup_type_in_scope(type, a, (*i).get());
12816 break;
12817 }
12818 }
12819 }
12820 return result;
12821}
12822
12823/// lookup a type in a scope.
12824///
12825/// This is really slow as it walks the member types of the scope in
12826/// sequence to find the type with a given name.
12827///
12828/// If possible, users should prefer looking up types from the
12829/// enclosing translation unit or even ABI corpus because both the
12830/// translation unit and the corpus have a map of type, indexed by
12831/// their name. Looking up a type from those maps is thus much
12832/// faster.
12833///
12834/// @param type the type to look for.
12835///
12836/// @param scope the top-most scope into which to look for @p type.
12837///
12838/// @return the scope found in @p scope, or NULL if it wasn't found.
12839static const type_base_sptr
12840lookup_type_in_scope(const type_base_sptr type,
12841 const scope_decl* scope)
12842{
12843 if (!type || is_function_type(type))
12844 return type_base_sptr();
12845
12846 decl_base_sptr type_decl = get_type_declaration(type);
12847 ABG_ASSERT(type_decl);
12848 vector<scope_decl*> access_path;
12849 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
12850 {
12851 access_path.push_back(s);
12852 if (is_global_scope(s))
12853 break;
12854 }
12855 return lookup_type_in_scope(*type, access_path, scope);
12856}
12857
12858/// Lookup a type from a translation unit by walking the scopes of the
12859/// translation unit in sequence and looking into them.
12860///
12861/// This is really slow as it walks the member types of the scopes in
12862/// sequence to find the type with a given name.
12863///
12864/// If possible, users should prefer looking up types from the
12865/// translation unit or even ABI corpus in a more direct way, by using
12866/// the lookup_type() functins.
12867///
12868///
12869/// This is because both the translation unit and the corpus have a
12870/// map of types, indexed by their name. Looking up a type from those
12871/// maps is thus much faster. @param fqn the components of the fully
12872/// qualified name of the node to look up.
12873///
12874/// @param tu the translation unit to perform lookup from.
12875///
12876/// @return the declaration of the IR node found, NULL otherwise.
12877const type_base_sptr
12878lookup_type_through_scopes(const type_base_sptr type,
12879 const translation_unit& tu)
12880{
12881 if (function_type_sptr fn_type = is_function_type(type))
12882 return lookup_function_type(fn_type, tu);
12883 return lookup_type_in_scope(type, tu.get_global_scope().get());
12884}
12885
12886/// lookup a var_decl in a scope.
12887///
12888/// @param comps the components of the fully qualified name of the
12889/// var_decl to lookup.
12890///
12891/// @param skope the scope to look into.
12892const decl_base_sptr
12893lookup_var_decl_in_scope(const std::list<string>& comps,
12894 const scope_decl_sptr& skope)
12895{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
12896
12897/// Lookup an IR node from a translation unit.
12898///
12899/// @tparam NodeKind the type of the IR node to lookup from the
12900/// translation unit.
12901///
12902/// @param fqn the components of the fully qualified name of the node
12903/// to look up.
12904///
12905/// @param tu the translation unit to perform lookup from.
12906///
12907/// @return the declaration of the IR node found, NULL otherwise.
12908template<typename NodeKind>
12909static const type_or_decl_base_sptr
12910lookup_node_in_translation_unit(const list<string>& fqn,
12911 const translation_unit& tu)
12912{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
12913
12914/// Lookup a type from a translation unit by walking its scopes in
12915/// sequence and by looking into them.
12916///
12917/// This is much slower than using the lookup_type() function.
12918///
12919/// @param fqn the components of the fully qualified name of the node
12920/// to look up.
12921///
12922/// @param tu the translation unit to perform lookup from.
12923///
12924/// @return the declaration of the IR node found, NULL otherwise.
12925type_base_sptr
12926lookup_type_through_scopes(const list<string>& fqn,
12927 const translation_unit& tu)
12928{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
12929
12930
12931/// Lookup a class type from a translation unit by walking its scopes
12932/// in sequence and by looking into them.
12933///
12934/// This is much slower than using the lookup_class_type() function
12935/// because it walks all the scopes of the translation unit in
12936/// sequence and lookup the types to find one that has a given name.
12937///
12938/// @param fqn the components of the fully qualified name of the class
12939/// type node to look up.
12940///
12941/// @param tu the translation unit to perform lookup from.
12942///
12943/// @return the declaration of the class type IR node found, NULL
12944/// otherwise.
12946lookup_class_type_through_scopes(const list<string>& fqn,
12947 const translation_unit& tu)
12948{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
12949
12950/// Lookup a basic type from all the translation units of a given
12951/// corpus.
12952///
12953/// @param fqn the components of the fully qualified name of the basic
12954/// type node to look up.
12955///
12956/// @param tu the translation unit to perform lookup from.
12957///
12958/// @return the declaration of the basic type IR node found, NULL
12959/// otherwise.
12960static type_decl_sptr
12961lookup_basic_type_through_translation_units(const interned_string& type_name,
12962 const corpus& abi_corpus)
12963{
12964 type_decl_sptr result;
12965
12966 for (translation_units::const_iterator tu =
12967 abi_corpus.get_translation_units().begin();
12968 tu != abi_corpus.get_translation_units().end();
12969 ++tu)
12970 if ((result = lookup_basic_type(type_name, **tu)))
12971 break;
12972
12973 return result;
12974}
12975
12976/// Lookup a union type from all the translation units of a given
12977/// corpus.
12978///
12979/// @param fqn the components of the fully qualified name of the union
12980/// type node to look up.
12981///
12982/// @param tu the translation unit to perform lookup from.
12983///
12984/// @return the declaration of the union type IR node found, NULL
12985/// otherwise.
12986static union_decl_sptr
12987lookup_union_type_through_translation_units(const interned_string& type_name,
12988 const corpus & abi_corpus)
12989{
12990 union_decl_sptr result;
12991
12992 for (translation_units::const_iterator tu =
12993 abi_corpus.get_translation_units().begin();
12994 tu != abi_corpus.get_translation_units().end();
12995 ++tu)
12996 if ((result = lookup_union_type(type_name, **tu)))
12997 break;
12998
12999 return result;
13000}
13001
13002/// Lookup an enum type from all the translation units of a given
13003/// corpus.
13004///
13005/// @param fqn the components of the fully qualified name of the enum
13006/// type node to look up.
13007///
13008/// @param tu the translation unit to perform lookup from.
13009///
13010/// @return the declaration of the enum type IR node found, NULL
13011/// otherwise.
13013lookup_enum_type_through_translation_units(const interned_string& type_name,
13014 const corpus & abi_corpus)
13015{
13016 enum_type_decl_sptr result;
13017
13018 for (translation_units::const_iterator tu =
13019 abi_corpus.get_translation_units().begin();
13020 tu != abi_corpus.get_translation_units().end();
13021 ++tu)
13022 if ((result = lookup_enum_type(type_name, **tu)))
13023 break;
13024
13025 return result;
13026}
13027
13028/// Lookup a typedef type definition in all the translation units of a
13029/// given ABI corpus.
13030///
13031/// @param @param qn the fully qualified name of the typedef type to lookup.
13032///
13033/// @param abi_corpus the ABI corpus which to look the type up in.
13034///
13035/// @return the type definition if any was found, or a NULL pointer.
13036static typedef_decl_sptr
13037lookup_typedef_type_through_translation_units(const interned_string& type_name,
13038 const corpus & abi_corpus)
13039{
13040 typedef_decl_sptr result;
13041
13042 for (translation_units::const_iterator tu =
13043 abi_corpus.get_translation_units().begin();
13044 tu != abi_corpus.get_translation_units().end();
13045 ++tu)
13046 if ((result = lookup_typedef_type(type_name, **tu)))
13047 break;
13048
13049 return result;
13050}
13051
13052/// Lookup a qualified type definition in all the translation units of a
13053/// given ABI corpus.
13054///
13055/// @param @param qn the fully qualified name of the qualified type to
13056/// lookup.
13057///
13058/// @param abi_corpus the ABI corpus which to look the type up in.
13059///
13060/// @return the type definition if any was found, or a NULL pointer.
13061static qualified_type_def_sptr
13062lookup_qualified_type_through_translation_units(const interned_string& t_name,
13063 const corpus & abi_corpus)
13064{
13065 qualified_type_def_sptr result;
13066
13067 for (translation_units::const_iterator tu =
13068 abi_corpus.get_translation_units().begin();
13069 tu != abi_corpus.get_translation_units().end();
13070 ++tu)
13071 if ((result = lookup_qualified_type(t_name, **tu)))
13072 break;
13073
13074 return result;
13075}
13076
13077/// Lookup a pointer type definition in all the translation units of a
13078/// given ABI corpus.
13079///
13080/// @param @param qn the fully qualified name of the pointer type to
13081/// lookup.
13082///
13083/// @param abi_corpus the ABI corpus which to look the type up in.
13084///
13085/// @return the type definition if any was found, or a NULL pointer.
13087lookup_pointer_type_through_translation_units(const interned_string& type_name,
13088 const corpus & abi_corpus)
13089{
13090 pointer_type_def_sptr result;
13091
13092 for (translation_units::const_iterator tu =
13093 abi_corpus.get_translation_units().begin();
13094 tu != abi_corpus.get_translation_units().end();
13095 ++tu)
13096 if ((result = lookup_pointer_type(type_name, **tu)))
13097 break;
13098
13099 return result;
13100}
13101
13102/// Lookup a reference type definition in all the translation units of a
13103/// given ABI corpus.
13104///
13105/// @param @param qn the fully qualified name of the reference type to
13106/// lookup.
13107///
13108/// @param abi_corpus the ABI corpus which to look the type up in.
13109///
13110/// @return the type definition if any was found, or a NULL pointer.
13112lookup_reference_type_through_translation_units(const interned_string& t_name,
13113 const corpus & abi_corpus)
13114{
13116
13117 for (translation_units::const_iterator tu =
13118 abi_corpus.get_translation_units().begin();
13119 tu != abi_corpus.get_translation_units().end();
13120 ++tu)
13121 if ((result = lookup_reference_type(t_name, **tu)))
13122 break;
13123
13124 return result;
13125}
13126
13127/// Lookup a array type definition in all the translation units of a
13128/// given ABI corpus.
13129///
13130/// @param @param qn the fully qualified name of the array type to
13131/// lookup.
13132///
13133/// @param abi_corpus the ABI corpus which to look the type up in.
13134///
13135/// @return the type definition if any was found, or a NULL pointer.
13137lookup_array_type_through_translation_units(const interned_string& type_name,
13138 const corpus & abi_corpus)
13139{
13140 array_type_def_sptr result;
13141
13142 for (translation_units::const_iterator tu =
13143 abi_corpus.get_translation_units().begin();
13144 tu != abi_corpus.get_translation_units().end();
13145 ++tu)
13146 if ((result = lookup_array_type(type_name, **tu)))
13147 break;
13148
13149 return result;
13150}
13151
13152/// Lookup a function type definition in all the translation units of
13153/// a given ABI corpus.
13154///
13155/// @param @param qn the fully qualified name of the function type to
13156/// lookup.
13157///
13158/// @param abi_corpus the ABI corpus which to look the type up in.
13159///
13160/// @return the type definition if any was found, or a NULL pointer.
13161static function_type_sptr
13162lookup_function_type_through_translation_units(const interned_string& type_name,
13163 const corpus & abi_corpus)
13164{
13165 function_type_sptr result;
13166
13167 for (translation_units::const_iterator tu =
13168 abi_corpus.get_translation_units().begin();
13169 tu != abi_corpus.get_translation_units().end();
13170 ++tu)
13171 if ((result = lookup_function_type(type_name, **tu)))
13172 break;
13173
13174 return result;
13175}
13176
13177/// Lookup a type definition in all the translation units of a given
13178/// ABI corpus.
13179///
13180/// @param @param qn the fully qualified name of the type to lookup.
13181///
13182/// @param abi_corpus the ABI corpus which to look the type up in.
13183///
13184/// @return the type definition if any was found, or a NULL pointer.
13185type_base_sptr
13187 const corpus& abi_corpus)
13188{
13189 type_base_sptr result;
13190
13191 for (translation_units::const_iterator tu =
13192 abi_corpus.get_translation_units().begin();
13193 tu != abi_corpus.get_translation_units().end();
13194 ++tu)
13195 if ((result = lookup_type(qn, **tu)))
13196 break;
13197
13198 return result;
13199}
13200
13201/// Lookup a type from a given translation unit present in a give corpus.
13202///
13203/// @param type_name the name of the type to look for.
13204///
13205/// @parm tu_path the path of the translation unit to consider.
13206///
13207/// @param corp the corpus to consider.
13208///
13209/// @return the resulting type, if any.
13210type_base_sptr
13212 const string& tu_path,
13213 const corpus& corp)
13214{
13215 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
13216 if (i == corp.priv_->path_tu_map.end())
13217 return type_base_sptr();
13218
13219 translation_unit_sptr tu = i->second;
13220 ABG_ASSERT(tu);
13221
13222 type_base_sptr t = lookup_type(type_name, *tu);
13223 return t;
13224}
13225
13226/// Look into an ABI corpus for a function type.
13227///
13228/// @param fn_type the function type to be looked for in the ABI
13229/// corpus.
13230///
13231/// @param corpus the ABI corpus into which to look for the function
13232/// type.
13233///
13234/// @return the function type found in the corpus.
13237 const corpus& corpus)
13238{
13239 ABG_ASSERT(fn_t);
13240
13241 function_type_sptr result;
13242
13243 if ((result = lookup_function_type(fn_t, corpus)))
13244 return result;
13245
13246 for (translation_units::const_iterator i =
13247 corpus.get_translation_units().begin();
13248 i != corpus.get_translation_units().end();
13249 ++i)
13251 **i)))
13252 return result;
13253
13254 return result;
13255}
13256
13257/// Look into a given corpus to find a type which has the same
13258/// qualified name as a giventype.
13259///
13260/// If the per-corpus type map is non-empty (because the corpus allows
13261/// the One Definition Rule) then the type islooked up in that
13262/// per-corpus type map. Otherwise, the type is looked-up in each
13263/// translation unit.
13264///
13265/// @param t the type which has the same qualified name as the type we
13266/// are looking for.
13267///
13268/// @param corp the ABI corpus to look into for the type.
13270lookup_basic_type(const type_decl& t, const corpus& corp)
13271{return lookup_basic_type(t.get_name(), corp);}
13272
13273/// Look into a given corpus to find a basic type which has a given
13274/// qualified name.
13275///
13276/// If the per-corpus type map is non-empty (because the corpus allows
13277/// the One Definition Rule) then the type islooked up in that
13278/// per-corpus type map. Otherwise, the type is looked-up in each
13279/// translation unit.
13280///
13281/// @param qualified_name the qualified name of the basic type to look
13282/// for.
13283///
13284/// @param corp the corpus to look into.
13286lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
13287{
13289 type_decl_sptr result;
13290
13291 if (!m.empty())
13292 result = lookup_type_in_map<type_decl>(qualified_name, m);
13293 else
13294 result = lookup_basic_type_through_translation_units(qualified_name, corp);
13295
13296 return result;
13297}
13298
13299/// Lookup a @ref type_decl type from a given corpus, by its location.
13300///
13301/// @param loc the location to consider.
13302///
13303/// @param corp the corpus to consider.
13304///
13305/// @return the resulting basic type, if any.
13308 const corpus &corp)
13309{
13312 type_decl_sptr result;
13313
13314 result = lookup_type_in_map<type_decl>(loc, m);
13315
13316 return result;
13317}
13318
13319/// Lookup a @ref type_decl type from a given corpus, by its location.
13320///
13321/// @param loc the location to consider.
13322///
13323/// @param corp the corpus to consider.
13324///
13325/// @return the resulting basic type, if any.
13327lookup_basic_type_per_location(const string &loc, const corpus &corp)
13328{
13329 const environment& env = corp.get_environment();
13330 return lookup_basic_type_per_location(env.intern(loc), corp);
13331}
13332
13333/// Look into a given corpus to find a basic type which has a given
13334/// qualified name.
13335///
13336/// If the per-corpus type map is non-empty (because the corpus allows
13337/// the One Definition Rule) then the type islooked up in that
13338/// per-corpus type map. Otherwise, the type is looked-up in each
13339/// translation unit.
13340///
13341/// @param qualified_name the qualified name of the basic type to look
13342/// for.
13343///
13344/// @param corp the corpus to look into.
13346lookup_basic_type(const string& qualified_name, const corpus& corp)
13347{
13348 return lookup_basic_type(corp.get_environment().intern(qualified_name),
13349 corp);
13350}
13351
13352/// Look into a given corpus to find a class type which has the same
13353/// qualified name as a given type.
13354///
13355/// If the per-corpus type map is non-empty (because the corpus allows
13356/// the One Definition Rule) then the type islooked up in that
13357/// per-corpus type map. Otherwise, the type is looked-up in each
13358/// translation unit.
13359///
13360/// @param t the class decl type which has the same qualified name as
13361/// the type we are looking for.
13362///
13363/// @param corp the corpus to look into.
13366{
13368 return lookup_class_type(s, corp);
13369}
13370
13371/// Look into a given corpus to find a class type which has a given
13372/// qualified name.
13373///
13374/// If the per-corpus type map is non-empty (because the corpus allows
13375/// the One Definition Rule) then the type islooked up in that
13376/// per-corpus type map. Otherwise, the type is looked-up in each
13377/// translation unit.
13378///
13379/// @param qualified_name the qualified name of the type to look for.
13380///
13381/// @param corp the corpus to look into.
13383lookup_class_type(const string& qualified_name, const corpus& corp)
13384{
13385 interned_string s = corp.get_environment().intern(qualified_name);
13386 return lookup_class_type(s, corp);
13387}
13388
13389/// Look into a given corpus to find a class type which has a given
13390/// qualified name.
13391///
13392/// If the per-corpus type map is non-empty (because the corpus allows
13393/// the One Definition Rule) then the type islooked up in that
13394/// per-corpus type map. Otherwise, the type is looked-up in each
13395/// translation unit.
13396///
13397/// @param qualified_name the qualified name of the type to look for.
13398///
13399/// @param corp the corpus to look into.
13401lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13402{
13404
13405 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13406
13407 return result;
13408}
13409
13410/// Look into a given corpus to find the class type*s* that have a
13411/// given qualified name.
13412///
13413/// @param qualified_name the qualified name of the type to look for.
13414///
13415/// @param corp the corpus to look into.
13416///
13417/// @return the vector of class types named @p qualified_name.
13419lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13420{
13422
13423 return lookup_types_in_map(qualified_name, m);
13424}
13425
13426/// Look into a given corpus to find the class type*s* that have a
13427/// given qualified name and that are declaration-only.
13428///
13429/// @param qualified_name the qualified name of the type to look for.
13430///
13431/// @param corp the corpus to look into.
13432///
13433/// @param result the vector of decl-only class types named @p
13434/// qualified_name. This is populated iff the function returns true.
13435///
13436/// @return true iff @p result was populated with the decl-only
13437/// classes named @p qualified_name.
13438bool
13440 const corpus& corp,
13441 type_base_wptrs_type& result)
13442{
13444
13445 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13446 if (!v)
13447 return false;
13448
13449 for (auto type : *v)
13450 {
13451 type_base_sptr t(type);
13453 if (c->get_is_declaration_only()
13454 && !c->get_definition_of_declaration())
13455 result.push_back(type);
13456 }
13457
13458 return !result.empty();
13459}
13460
13461/// Look into a given corpus to find the union type*s* that have a
13462/// given qualified name.
13463///
13464/// @param qualified_name the qualified name of the type to look for.
13465///
13466/// @param corp the corpus to look into.
13467///
13468/// @return the vector of union types named @p qualified_name.
13470lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13471{
13473
13474 return lookup_types_in_map(qualified_name, m);
13475}
13476
13477/// Look into a given corpus to find the class type*s* that have a
13478/// given qualified name.
13479///
13480/// @param qualified_name the qualified name of the type to look for.
13481///
13482/// @param corp the corpus to look into.
13483///
13484/// @return the vector of class types which name is @p qualified_name.
13486lookup_class_types(const string& qualified_name, const corpus& corp)
13487{
13488 interned_string s = corp.get_environment().intern(qualified_name);
13489 return lookup_class_types(s, corp);
13490}
13491
13492/// Look into a given corpus to find the union types that have a given
13493/// qualified name.
13494///
13495/// @param qualified_name the qualified name of the type to look for.
13496///
13497/// @param corp the corpus to look into.
13498///
13499/// @return the vector of union types which name is @p qualified_name.
13501lookup_union_types(const string& qualified_name, const corpus& corp)
13502{
13503 interned_string s = corp.get_environment().intern(qualified_name);
13504 return lookup_union_types(s, corp);
13505}
13506
13507/// Look up a @ref class_decl from a given corpus by its location.
13508///
13509/// @param loc the location to consider.
13510///
13511/// @param corp the corpus to consider.
13512///
13513/// @return the resulting class decl, if any.
13516 const corpus& corp)
13517{
13520 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13521
13522 return result;
13523}
13524
13525/// Look up a @ref class_decl from a given corpus by its location.
13526///
13527/// @param loc the location to consider.
13528///
13529/// @param corp the corpus to consider.
13530///
13531/// @return the resulting class decl, if any.
13533lookup_class_type_per_location(const string &loc, const corpus &corp)
13534{
13535 const environment& env = corp.get_environment();
13536 return lookup_class_type_per_location(env.intern(loc), corp);
13537}
13538
13539/// Look into a given corpus to find a union type which has a given
13540/// qualified name.
13541///
13542/// If the per-corpus type map is non-empty (because the corpus allows
13543/// the One Definition Rule) then the type islooked up in that
13544/// per-corpus type map. Otherwise, the type is looked-up in each
13545/// translation unit.
13546///
13547/// @param qualified_name the qualified name of the type to look for.
13548///
13549/// @param corp the corpus to look into.
13550union_decl_sptr
13551lookup_union_type(const interned_string& type_name, const corpus& corp)
13552{
13554
13555 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13556 if (!result)
13557 result = lookup_union_type_through_translation_units(type_name, corp);
13558
13559 return result;
13560}
13561
13562/// Look into a given corpus to find a union type which has a given
13563/// qualified name.
13564///
13565/// If the per-corpus type map is non-empty (because the corpus allows
13566/// the One Definition Rule) then the type islooked up in that
13567/// per-corpus type map. Otherwise, the type is looked-up in each
13568/// translation unit.
13569///
13570/// @param qualified_name the qualified name of the type to look for.
13571///
13572/// @param corp the corpus to look into.
13573union_decl_sptr
13574lookup_union_type(const string& type_name, const corpus& corp)
13575{
13576 interned_string s = corp.get_environment().intern(type_name);
13577 return lookup_union_type(s, corp);
13578}
13579
13580/// Look into a given corpus to find an enum type which has the same
13581/// qualified name as a given enum type.
13582///
13583/// If the per-corpus type map is non-empty (because the corpus allows
13584/// the One Definition Rule) then the type islooked up in that
13585/// per-corpus type map. Otherwise, the type is looked-up in each
13586/// translation unit.
13587///
13588/// @param t the enum type which has the same qualified name as the
13589/// type we are looking for.
13590///
13591/// @param corp the corpus to look into.
13594{
13596 return lookup_enum_type(s, corp);
13597}
13598
13599/// Look into a given corpus to find an enum type which has a given
13600/// qualified name.
13601///
13602/// If the per-corpus type map is non-empty (because the corpus allows
13603/// the One Definition Rule) then the type islooked up in that
13604/// per-corpus type map. Otherwise, the type is looked-up in each
13605/// translation unit.
13606///
13607/// @param qualified_name the qualified name of the enum type to look
13608/// for.
13609///
13610/// @param corp the corpus to look into.
13612lookup_enum_type(const string& qualified_name, const corpus& corp)
13613{
13614 interned_string s = corp.get_environment().intern(qualified_name);
13615 return lookup_enum_type(s, corp);
13616}
13617
13618/// Look into a given corpus to find an enum type which has a given
13619/// qualified name.
13620///
13621/// If the per-corpus type map is non-empty (because the corpus allows
13622/// the One Definition Rule) then the type islooked up in that
13623/// per-corpus type map. Otherwise, the type is looked-up in each
13624/// translation unit.
13625///
13626/// @param qualified_name the qualified name of the enum type to look
13627/// for.
13628///
13629/// @param corp the corpus to look into.
13631lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
13632{
13634
13635 enum_type_decl_sptr result =
13636 lookup_type_in_map<enum_type_decl>(qualified_name, m);
13637 if (!result)
13638 result = lookup_enum_type_through_translation_units(qualified_name, corp);
13639
13640 return result;
13641}
13642
13643/// Look into a given corpus to find the enum type*s* that have a
13644/// given qualified name.
13645///
13646/// @param qualified_name the qualified name of the type to look for.
13647///
13648/// @param corp the corpus to look into.
13649///
13650/// @return the vector of enum types that which name is @p qualified_name.
13652lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
13653{
13655
13656 return lookup_types_in_map(qualified_name, m);
13657}
13658
13659/// Look into a given corpus to find the enum type*s* that have a
13660/// given qualified name.
13661///
13662/// @param qualified_name the qualified name of the type to look for.
13663///
13664/// @param corp the corpus to look into.
13665///
13666/// @return the vector of enum types that which name is @p qualified_name.
13668lookup_enum_types(const string& qualified_name, const corpus& corp)
13669{
13670 interned_string s = corp.get_environment().intern(qualified_name);
13671 return lookup_enum_types(s, corp);
13672}
13673
13674/// Look up an @ref enum_type_decl from a given corpus, by its location.
13675///
13676/// @param loc the location to consider.
13677///
13678/// @param corp the corpus to look the type from.
13679///
13680/// @return the resulting enum type, if any.
13683{
13686 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
13687
13688 return result;
13689}
13690
13691/// Look up an @ref enum_type_decl from a given corpus, by its location.
13692///
13693/// @param loc the location to consider.
13694///
13695/// @param corp the corpus to look the type from.
13696///
13697/// @return the resulting enum type, if any.
13699lookup_enum_type_per_location(const string &loc, const corpus &corp)
13700{
13701 const environment& env = corp.get_environment();
13702 return lookup_enum_type_per_location(env.intern(loc), corp);
13703}
13704
13705/// Look into a given corpus to find a typedef type which has the
13706/// same qualified name as a given typedef type.
13707///
13708/// If the per-corpus type map is non-empty (because the corpus allows
13709/// the One Definition Rule) then the type islooked up in that
13710/// per-corpus type map. Otherwise, the type is looked-up in each
13711/// translation unit.
13712///
13713/// @param t the typedef type which has the same qualified name as the
13714/// typedef type we are looking for.
13715///
13716/// @param corp the corpus to look into.
13719{
13721 return lookup_typedef_type(s, corp);
13722}
13723
13724/// Look into a given corpus to find a typedef type which has the
13725/// same qualified name as a given typedef type.
13726///
13727/// If the per-corpus type map is non-empty (because the corpus allows
13728/// the One Definition Rule) then the type islooked up in that
13729/// per-corpus type map. Otherwise, the type is looked-up in each
13730/// translation unit.
13731///
13732/// @param t the typedef type which has the same qualified name as the
13733/// typedef type we are looking for.
13734///
13735/// @param corp the corpus to look into.
13737lookup_typedef_type(const string& qualified_name, const corpus& corp)
13738{
13739 interned_string s = corp.get_environment().intern(qualified_name);
13740 return lookup_typedef_type(s, corp);
13741}
13742
13743/// Look into a given corpus to find a typedef type which has a
13744/// given qualified name.
13745///
13746/// If the per-corpus type map is non-empty (because the corpus allows
13747/// the One Definition Rule) then the type islooked up in that
13748/// per-corpus type map. Otherwise, the type is looked-up in each
13749/// translation unit.
13750///
13751/// @param qualified_name the qualified name of the typedef type to
13752/// look for.
13753///
13754/// @param corp the corpus to look into.
13756lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
13757{
13759
13760 typedef_decl_sptr result =
13761 lookup_type_in_map<typedef_decl>(qualified_name, m);
13762 if (!result)
13763 result = lookup_typedef_type_through_translation_units(qualified_name,
13764 corp);
13765
13766 return result;
13767}
13768
13769/// Lookup a @ref typedef_decl from a corpus, by its location.
13770///
13771/// @param loc the location to consider.
13772///
13773/// @param corp the corpus to consider.
13774///
13775/// @return the typedef_decl found, if any.
13778{
13781 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
13782
13783 return result;
13784}
13785
13786/// Lookup a @ref typedef_decl from a corpus, by its location.
13787///
13788/// @param loc the location to consider.
13789///
13790/// @param corp the corpus to consider.
13791///
13792/// @return the typedef_decl found, if any.
13794lookup_typedef_type_per_location(const string &loc, const corpus &corp)
13795{
13796 const environment& env = corp.get_environment();
13797 return lookup_typedef_type_per_location(env.intern(loc), corp);
13798}
13799
13800/// Look into a corpus to find a class, union or typedef type which
13801/// has a given qualified name.
13802///
13803/// If the per-corpus type map is non-empty (because the corpus allows
13804/// the One Definition Rule) then the type islooked up in that
13805/// per-corpus type map. Otherwise, the type is looked-up in each
13806/// translation unit.
13807///
13808/// @param qualified_name the name of the type to find.
13809///
13810/// @param corp the corpus to look into.
13811///
13812/// @return the typedef or class type found.
13813type_base_sptr
13814lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
13815{
13816 type_base_sptr result = lookup_class_type(qualified_name, corp);
13817 if (!result)
13818 result = lookup_union_type(qualified_name, corp);
13819
13820 if (!result)
13821 result = lookup_typedef_type(qualified_name, corp);
13822 return result;
13823}
13824
13825/// Look into a corpus to find a class, typedef or enum type which has
13826/// a given qualified name.
13827///
13828/// If the per-corpus type map is non-empty (because the corpus allows
13829/// the One Definition Rule) then the type islooked up in that
13830/// per-corpus type map. Otherwise, the type is looked-up in each
13831/// translation unit.
13832///
13833/// @param qualified_name the qualified name of the type to look for.
13834///
13835/// @param corp the corpus to look into.
13836///
13837/// @return the typedef, class or enum type found.
13838type_base_sptr
13839lookup_class_typedef_or_enum_type(const string& qualified_name,
13840 const corpus& corp)
13841{
13842 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
13843 if (!result)
13844 result = lookup_enum_type(qualified_name, corp);
13845
13846 return result;
13847}
13848
13849/// Look into a given corpus to find a qualified type which has the
13850/// same qualified name as a given type.
13851///
13852/// @param t the type which has the same qualified name as the
13853/// qualified type we are looking for.
13854///
13855/// @param corp the corpus to look into.
13856///
13857/// @return the qualified type found.
13858qualified_type_def_sptr
13860{
13862 return lookup_qualified_type(s, corp);
13863}
13864
13865/// Look into a given corpus to find a qualified type which has a
13866/// given qualified name.
13867///
13868/// @param qualified_name the qualified name of the type to look for.
13869///
13870/// @param corp the corpus to look into.
13871///
13872/// @return the type found.
13873qualified_type_def_sptr
13874lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
13875{
13877 corp.get_types().qualified_types();
13878
13879 qualified_type_def_sptr result =
13880 lookup_type_in_map<qualified_type_def>(qualified_name, m);
13881
13882 if (!result)
13883 result = lookup_qualified_type_through_translation_units(qualified_name,
13884 corp);
13885
13886 return result;
13887}
13888
13889/// Look into a given corpus to find a pointer type which has the same
13890/// qualified name as a given pointer type.
13891///
13892/// @param t the pointer type which has the same qualified name as the
13893/// type we are looking for.
13894///
13895/// @param corp the corpus to look into.
13896///
13897/// @return the pointer type found.
13900{
13902 return lookup_pointer_type(s, corp);
13903}
13904
13905/// Look into a given corpus to find a pointer type which has a given
13906/// qualified name.
13907///
13908/// If the per-corpus type map is non-empty (because the corpus allows
13909/// the One Definition Rule) then the type islooked up in that
13910/// per-corpus type map. Otherwise, the type is looked-up in each
13911/// translation unit.
13912///
13913/// @param qualified_name the qualified name of the pointer type to
13914/// look for.
13915///
13916/// @param corp the corpus to look into.
13917///
13918/// @return the pointer type found.
13920lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
13921{
13923
13924 pointer_type_def_sptr result =
13925 lookup_type_in_map<pointer_type_def>(qualified_name, m);
13926 if (!result)
13927 result = lookup_pointer_type_through_translation_units(qualified_name,
13928 corp);
13929
13930 return result;
13931}
13932
13933/// Look into a given corpus to find a reference type which has the
13934/// same qualified name as a given reference type.
13935///
13936/// If the per-corpus type map is non-empty (because the corpus allows
13937/// the One Definition Rule) then the type islooked up in that
13938/// per-corpus type map. Otherwise, the type is looked-up in each
13939/// translation unit.
13940///
13941/// @param t the reference type which has the same qualified name as
13942/// the reference type we are looking for.
13943///
13944/// @param corp the corpus to look into.
13945///
13946/// @return the reference type found.
13949{
13951 return lookup_reference_type(s, corp);
13952}
13953
13954/// Look into a given corpus to find a reference type which has a
13955/// given qualified name.
13956///
13957/// If the per-corpus type map is non-empty (because the corpus allows
13958/// the One Definition Rule) then the type islooked up in that
13959/// per-corpus type map. Otherwise, the type is looked-up in each
13960/// translation unit.
13961///
13962/// @param qualified_name the qualified name of the reference type to
13963/// look for.
13964///
13965/// @param corp the corpus to look into.
13966///
13967/// @return the reference type found.
13969lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
13970{
13972 corp.get_types().reference_types();
13973
13975 lookup_type_in_map<reference_type_def>(qualified_name, m);
13976 if (!result)
13977 result = lookup_reference_type_through_translation_units(qualified_name,
13978 corp);
13979
13980 return result;
13981}
13982
13983/// Look into a given corpus to find an array type which has a given
13984/// qualified name.
13985///
13986/// If the per-corpus type map is non-empty (because the corpus allows
13987/// the One Definition Rule) then the type islooked up in that
13988/// per-corpus type map. Otherwise, the type is looked-up in each
13989/// translation unit.
13990///
13991/// @param qualified_name the qualified name of the array type to look
13992/// for.
13993///
13994/// @param corp the corpus to look into.
13995///
13996/// @return the array type found.
13999{
14001 return lookup_array_type(s, corp);
14002}
14003
14004/// Look into a given corpus to find an array type which has the same
14005/// qualified name as a given array type.
14006///
14007/// If the per-corpus type map is non-empty (because the corpus allows
14008/// the One Definition Rule) then the type islooked up in that
14009/// per-corpus type map. Otherwise, the type is looked-up in each
14010/// translation unit.
14011///
14012/// @param t the type which has the same qualified name as the type we
14013/// are looking for.
14014///
14015/// @param corp the corpus to look into.
14016///
14017/// @return the type found.
14019lookup_array_type(const interned_string& qualified_name, const corpus& corp)
14020{
14022
14023 array_type_def_sptr result =
14024 lookup_type_in_map<array_type_def>(qualified_name, m);
14025 if (!result)
14026 result = lookup_array_type_through_translation_units(qualified_name, corp);
14027
14028 return result;
14029}
14030
14031/// Look into a given corpus to find a function type which has the same
14032/// qualified name as a given function type.
14033///
14034/// If the per-corpus type map is non-empty (because the corpus allows
14035/// the One Definition Rule) then the type islooked up in that
14036/// per-corpus type map. Otherwise, the type is looked-up in each
14037/// translation unit.
14038///
14039/// @param t the function type which has the same qualified name as
14040/// the function type we are looking for.
14041///
14042/// @param corp the corpus to look into.
14043///
14044/// @return the function type found.
14047{
14048 interned_string type_name = get_type_name(t);
14049 return lookup_function_type(type_name, corp);
14050}
14051
14052/// Look into a given corpus to find a function type which has the same
14053/// qualified name as a given function type.
14054///
14055/// If the per-corpus type map is non-empty (because the corpus allows
14056/// the One Definition Rule) then the type islooked up in that
14057/// per-corpus type map. Otherwise, the type is looked-up in each
14058/// translation unit.
14059///
14060/// @param t the function type which has the same qualified name as
14061/// the function type we are looking for.
14062///
14063/// @param corp the corpus to look into.
14064///
14065/// @return the function type found.
14068 const corpus& corpus)
14069{
14070 if (fn_t)
14071 return lookup_function_type(*fn_t, corpus);
14072 return function_type_sptr();
14073}
14074
14075/// Look into a given corpus to find a function type which has a given
14076/// qualified name.
14077///
14078/// If the per-corpus type map is non-empty (because the corpus allows
14079/// the One Definition Rule) then the type islooked up in that
14080/// per-corpus type map. Otherwise, the type is looked-up in each
14081/// translation unit.
14082///
14083/// @param qualified_name the qualified name of the function type to
14084/// look for.
14085///
14086/// @param corp the corpus to look into.
14087///
14088/// @return the function type found.
14090lookup_function_type(const interned_string& qualified_name, const corpus& corp)
14091{
14093
14094 function_type_sptr result =
14095 lookup_type_in_map<function_type>(qualified_name, m);
14096 if (!result)
14097 result = lookup_function_type_through_translation_units(qualified_name,
14098 corp);
14099
14100 return result;
14101}
14102
14103/// Look into a given corpus to find a type which has a given
14104/// qualified name.
14105///
14106/// If the per-corpus type map is non-empty (because the corpus allows
14107/// the One Definition Rule) then the type islooked up in that
14108/// per-corpus type map. Otherwise, the type is looked-up in each
14109/// translation unit.
14110///
14111/// @param qualified_name the qualified name of the function type to
14112/// look for.
14113///
14114/// @param corp the corpus to look into.
14115///
14116/// @return the function type found.
14117type_base_sptr
14118lookup_type(const interned_string& n, const corpus& corp)
14119{
14120 type_base_sptr result;
14121
14122 ((result = lookup_basic_type(n, corp))
14123 || (result = lookup_class_type(n, corp))
14124 || (result = lookup_union_type(n, corp))
14125 || (result = lookup_enum_type(n, corp))
14126 || (result = lookup_typedef_type(n, corp))
14127 || (result = lookup_qualified_type(n, corp))
14128 || (result = lookup_pointer_type(n, corp))
14129 || (result = lookup_reference_type(n, corp))
14130 || (result = lookup_array_type(n, corp))
14131 || (result= lookup_function_type(n, corp)));
14132
14133 return result;
14134}
14135
14136/// Lookup a type from a corpus, by its location.
14137///
14138/// @param loc the location to consider.
14139///
14140/// @param corp the corpus to look the type from.
14141///
14142/// @return the resulting type, if any found.
14143type_base_sptr
14145{
14146 // TODO: finish this.
14147
14148 //TODO: when we fully support types indexed by their location, this
14149 //function should return a vector of types because at each location,
14150 //there can be several types that are defined (yay, C and C++,
14151 //*sigh*).
14152
14153 type_base_sptr result;
14154 ((result = lookup_basic_type_per_location(loc, corp))
14155 || (result = lookup_class_type_per_location(loc, corp))
14156 || (result = lookup_union_type_per_location(loc, corp))
14157 || (result = lookup_enum_type_per_location(loc, corp))
14158 || (result = lookup_typedef_type_per_location(loc, corp)));
14159
14160 return result;
14161}
14162
14163/// Look into a given corpus to find a type
14164///
14165/// If the per-corpus type map is non-empty (because the corpus allows
14166/// the One Definition Rule) then the type islooked up in that
14167/// per-corpus type map. Otherwise, the type is looked-up in each
14168/// translation unit.
14169///
14170/// @param qualified_name the qualified name of the function type to
14171/// look for.
14172///
14173/// @param corp the corpus to look into.
14174///
14175/// @return the function type found.
14176type_base_sptr
14177lookup_type(const type_base&t, const corpus& corp)
14178{
14180 return lookup_type(n, corp);
14181}
14182
14183/// Look into a given corpus to find a type
14184///
14185/// If the per-corpus type map is non-empty (because the corpus allows
14186/// the One Definition Rule) then the type islooked up in that
14187/// per-corpus type map. Otherwise, the type is looked-up in each
14188/// translation unit.
14189///
14190/// @param qualified_name the qualified name of the function type to
14191/// look for.
14192///
14193/// @param corp the corpus to look into.
14194///
14195/// @return the function type found.
14196type_base_sptr
14197lookup_type(const type_base_sptr&t, const corpus& corp)
14198{
14199 if (t)
14200 return lookup_type(*t, corp);
14201 return type_base_sptr();
14202}
14203
14204/// Update the map that associates a fully qualified name of a given
14205/// type to that type.
14206///
14207///
14208/// @param type the type we are considering.
14209///
14210/// @param types_map the map to update. It's a map that assciates a
14211/// fully qualified name of a type to the type itself.
14212///
14213/// @param use_type_name_as_key if true, use the name of the type as
14214/// the key to look it up later. If false, then use the location of
14215/// the type as a key to look it up later.
14216///
14217/// @return true iff the type was added to the map.
14218template<typename TypeKind>
14219bool
14220maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
14222 bool use_type_name_as_key = true)
14223{
14225
14226 if (use_type_name_as_key)
14227 s = get_type_name(type);
14228 else if (location l = type->get_location())
14229 {
14230 string str = l.expand();
14231 s = type->get_environment().intern(str);
14232 }
14233
14234 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14235 bool result = false;
14236
14237 if (i == types_map.end())
14238 {
14239 types_map[s].push_back(type);
14240 result = true;
14241 }
14242 else
14243 i->second.push_back(type);
14244
14245 return result;
14246}
14247
14248/// This is the specialization for type @ref class_decl of the
14249/// function template:
14250///
14251/// maybe_update_types_lookup_map<T>(scope_decl*,
14252/// const shared_ptr<T>&,
14253/// istring_type_base_wptrs_map_type&)
14254///
14255/// @param class_type the type to consider.
14256///
14257/// @param types_map the type map to update.
14258///
14259/// @return true iff the type was added to the map.
14260template<>
14261bool
14264 bool use_type_name_as_key)
14265{
14266 class_decl_sptr type = class_type;
14267
14268 bool update_qname_map = true;
14269 if (type->get_is_declaration_only())
14270 {
14271 // Let's try to look through decl-only classes to get their
14272 // definition. But if the class doesn't have a definition then
14273 // we'll keep it.
14274 if (class_decl_sptr def =
14275 is_class_type(class_type->get_definition_of_declaration()))
14276 type = def;
14277 }
14278
14279 if (!update_qname_map)
14280 return false;
14281
14283 if (use_type_name_as_key)
14284 {
14285 string qname = type->get_qualified_name();
14286 s = type->get_environment().intern(qname);
14287 }
14288 else if (location l = type->get_location())
14289 {
14290 string str = l.expand();
14291 s = type->get_environment().intern(str);
14292 }
14293
14294 bool result = false;
14295 istring_type_base_wptrs_map_type::iterator i = map.find(s);
14296 if (i == map.end())
14297 {
14298 map[s].push_back(type);
14299 result = true;
14300 }
14301 else
14302 i->second.push_back(type);
14303
14304 return result;
14305}
14306
14307/// This is the specialization for type @ref function_type of the
14308/// function template:
14309///
14310/// maybe_update_types_lookup_map<T>(scope_decl*,
14311/// const shared_ptr<T>&,
14312/// istring_type_base_wptrs_map_type&)
14313///
14314/// @param scope the scope of the type to consider.
14315///
14316/// @param class_type the type to consider.
14317///
14318/// @param types_map the type map to update.
14319///
14320/// @return true iff the type was added to the map.
14321template<>
14322bool
14324(const function_type_sptr& type,
14326 bool /*use_type_name_as_key*/)
14327{
14328 bool result = false;
14330 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14331 if (i == types_map.end())
14332 {
14333 types_map[s].push_back(type);
14334 result = true;
14335 }
14336 else
14337 i->second.push_back(type);
14338
14339 return result;
14340}
14341
14342/// Update the map that associates the fully qualified name of a basic
14343/// type with the type itself.
14344///
14345/// The per-translation unit type map is updated if no type with this
14346/// name was already existing in that map.
14347///
14348/// If no type with this name did already exist in the per-corpus type
14349/// map, then that per-corpus type map is updated. Otherwise, that
14350/// type is erased from that per-corpus map.
14351///
14352/// @param basic_type the basic type to consider.
14353void
14355{
14356 if (translation_unit *tu = basic_type->get_translation_unit())
14358 (basic_type, tu->get_types().basic_types());
14359
14360 if (corpus *type_corpus = basic_type->get_corpus())
14361 {
14363 (basic_type,
14364 type_corpus->priv_->get_types().basic_types());
14365
14367 (basic_type,
14368 type_corpus->get_type_per_loc_map().basic_types(),
14369 /*use_type_name_as_key*/false);
14370
14371 if (corpus *group = type_corpus->get_group())
14372 {
14374 (basic_type,
14375 group->priv_->get_types().basic_types());
14376
14378 (basic_type,
14379 group->get_type_per_loc_map().basic_types(),
14380 /*use_type_name_as_key*/false);
14381 }
14382 }
14383
14384}
14385
14386/// Update the map that associates the fully qualified name of a class
14387/// type with the type itself.
14388///
14389/// The per-translation unit type map is updated if no type with this
14390/// name was already existing in that map.
14391///
14392/// If no type with this name did already exist in the per-corpus type
14393/// map, then that per-corpus type map is updated. Otherwise, that
14394/// type is erased from that per-corpus map.
14395///
14396/// @param class_type the class type to consider.
14397void
14399{
14400 if (translation_unit *tu = class_type->get_translation_unit())
14402 (class_type, tu->get_types().class_types());
14403
14404 if (corpus *type_corpus = class_type->get_corpus())
14405 {
14407 (class_type,
14408 type_corpus->priv_->get_types().class_types());
14409
14411 (class_type,
14412 type_corpus->get_type_per_loc_map().class_types(),
14413 /*use_type_name_as_key*/false);
14414
14415 if (corpus *group = type_corpus->get_group())
14416 {
14418 (class_type,
14419 group->priv_->get_types().class_types());
14420
14422 (class_type,
14423 group->get_type_per_loc_map().class_types(),
14424 /*use_type_name_as_key*/false);
14425 }
14426 }
14427}
14428
14429/// Update the map that associates the fully qualified name of a union
14430/// type with the type itself.
14431///
14432/// The per-translation unit type map is updated if no type with this
14433/// name was already existing in that map.
14434///
14435/// If no type with this name did already exist in the per-corpus type
14436/// map, then that per-corpus type map is updated. Otherwise, that
14437/// type is erased from that per-corpus map.
14438///
14439/// @param union_type the union type to consider.
14440void
14441maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14442{
14443 if (translation_unit *tu = union_type->get_translation_unit())
14445 (union_type, tu->get_types().union_types());
14446
14447 if (corpus *type_corpus = union_type->get_corpus())
14448 {
14450 (union_type,
14451 type_corpus->priv_->get_types().union_types());
14452
14454 (union_type,
14455 type_corpus->get_type_per_loc_map().union_types(),
14456 /*use_type_name_as_key*/false);
14457
14458 if (corpus *group = type_corpus->get_group())
14459 {
14461 (union_type,
14462 group->priv_->get_types().union_types());
14463
14465 (union_type,
14466 group->get_type_per_loc_map().union_types(),
14467 /*use_type_name_as_key*/false);
14468 }
14469 }
14470}
14471
14472/// Update the map that associates the fully qualified name of an enum
14473/// type with the type itself.
14474///
14475/// The per-translation unit type map is updated if no type with this
14476/// name was already existing in that map.
14477///
14478/// If no type with this name did already exist in the per-corpus type
14479/// map, then that per-corpus type map is updated. Otherwise, that
14480/// type is erased from that per-corpus map.
14481///
14482/// @param enum_type the type to consider.
14483void
14485{
14486 if (translation_unit *tu = enum_type->get_translation_unit())
14488 (enum_type, tu->get_types().enum_types());
14489
14490 if (corpus *type_corpus = enum_type->get_corpus())
14491 {
14493 (enum_type,
14494 type_corpus->priv_->get_types().enum_types());
14495
14497 (enum_type,
14498 type_corpus->get_type_per_loc_map().enum_types(),
14499 /*use_type_name_as_key*/false);
14500
14501 if (corpus *group = type_corpus->get_group())
14502 {
14504 (enum_type,
14505 group->priv_->get_types().enum_types());
14506
14508 (enum_type,
14509 group->get_type_per_loc_map().enum_types(),
14510 /*use_type_name_as_key*/false);
14511 }
14512 }
14513
14514}
14515
14516/// Update the map that associates the fully qualified name of a
14517/// typedef type with the type itself.
14518///
14519/// The per-translation unit type map is updated if no type with this
14520/// name was already existing in that map.
14521///
14522/// If no type with this name did already exist in the per-corpus type
14523/// map, then that per-corpus type map is updated. Otherwise, that
14524/// type is erased from that per-corpus map.
14525///
14526/// @param typedef_type the type to consider.
14527void
14529{
14530 if (translation_unit *tu = typedef_type->get_translation_unit())
14532 (typedef_type, tu->get_types().typedef_types());
14533
14534 if (corpus *type_corpus = typedef_type->get_corpus())
14535 {
14537 (typedef_type,
14538 type_corpus->priv_->get_types().typedef_types());
14539
14541 (typedef_type,
14542 type_corpus->get_type_per_loc_map().typedef_types(),
14543 /*use_type_name_as_key*/false);
14544
14545 if (corpus *group = type_corpus->get_group())
14546 {
14548 (typedef_type,
14549 group->priv_->get_types().typedef_types());
14550
14552 (typedef_type,
14553 group->get_type_per_loc_map().typedef_types(),
14554 /*use_type_name_as_key*/false);
14555 }
14556 }
14557}
14558
14559/// Update the map that associates the fully qualified name of a
14560/// qualified type with the type itself.
14561///
14562/// The per-translation unit type map is updated if no type with this
14563/// name was already existing in that map.
14564///
14565/// If no type with this name did already exist in the per-corpus type
14566/// map, then that per-corpus type map is updated. Otherwise, that
14567/// type is erased from that per-corpus map.
14568///
14569/// @param qualified_type the type to consider.
14570void
14571maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14572{
14573 if (translation_unit *tu = qualified_type->get_translation_unit())
14575 (qualified_type, tu->get_types().qualified_types());
14576
14577 if (corpus *type_corpus = qualified_type->get_corpus())
14578 {
14580 (qualified_type,
14581 type_corpus->priv_->get_types().qualified_types());
14582
14583 if (corpus *group = type_corpus->get_group())
14584 {
14586 (qualified_type,
14587 group->priv_->get_types().qualified_types());
14588 }
14589 }
14590}
14591
14592/// Update the map that associates the fully qualified name of a
14593/// pointer type with the type itself.
14594///
14595/// The per-translation unit type map is updated if no type with this
14596/// name was already existing in that map.
14597///
14598/// If no type with this name did already exist in the per-corpus type
14599/// map, then that per-corpus type map is updated. Otherwise, that
14600/// type is erased from that per-corpus map.
14601///
14602/// @param pointer_type the type to consider.
14603void
14605{
14606 if (translation_unit *tu = pointer_type->get_translation_unit())
14608 (pointer_type, tu->get_types().pointer_types());
14609
14610 if (corpus *type_corpus = pointer_type->get_corpus())
14611 {
14613 (pointer_type,
14614 type_corpus->priv_->get_types().pointer_types());
14615
14616 if (corpus *group = type_corpus->get_group())
14617 {
14619 (pointer_type,
14620 group->priv_->get_types().pointer_types());
14621 }
14622 }
14623}
14624
14625/// Update the map that associates the fully qualified name of a
14626/// pointer-to-member type with the type itself.
14627///
14628/// The per-translation unit type map is updated if no type with this
14629/// name was already existing in that map.
14630///
14631/// If no type with this name did already exist in the per-corpus type
14632/// map, then that per-corpus type map is updated. Otherwise, that
14633/// type is erased from that per-corpus map.
14634///
14635/// @param ptr_to_mbr_type the type to consider.
14636void
14638{
14639 if (translation_unit *tu = ptr_to_member->get_translation_unit())
14641 (ptr_to_member, tu->get_types().ptr_to_mbr_types());
14642
14643 if (corpus *type_corpus = ptr_to_member->get_corpus())
14644 {
14646 (ptr_to_member,
14647 type_corpus->priv_->get_types().ptr_to_mbr_types());
14648
14649 if (corpus *group = type_corpus->get_group())
14650 {
14652 (ptr_to_member,
14653 group->priv_->get_types().ptr_to_mbr_types());
14654 }
14655 }
14656}
14657
14658/// Update the map that associates the fully qualified name of a
14659/// reference type with the type itself.
14660///
14661/// The per-translation unit type map is updated if no type with this
14662/// name was already existing in that map.
14663///
14664/// If no type with this name did already exist in the per-corpus type
14665/// map, then that per-corpus type map is updated. Otherwise, that
14666/// type is erased from that per-corpus map.
14667///
14668/// @param reference_type the type to consider.
14669void
14671{
14672 if (translation_unit *tu = reference_type->get_translation_unit())
14674 (reference_type, tu->get_types().reference_types());
14675
14676 if (corpus *type_corpus = reference_type->get_corpus())
14677 {
14679 (reference_type,
14680 type_corpus->priv_->get_types().reference_types());
14681
14682 if (corpus *group = type_corpus->get_group())
14683 {
14685 (reference_type,
14686 group->priv_->get_types().reference_types());
14687 }
14688 }
14689}
14690
14691/// Update the map that associates the fully qualified name of a type
14692/// with the type itself.
14693///
14694/// The per-translation unit type map is updated if no type with this
14695/// name was already existing in that map.
14696///
14697/// If no type with this name did already exist in the per-corpus type
14698/// map, then that per-corpus type map is updated. Otherwise, that
14699/// type is erased from that per-corpus map.
14700///
14701/// @param array_type the type to consider.
14702void
14704{
14705 if (translation_unit *tu = array_type->get_translation_unit())
14707 (array_type, tu->get_types().array_types());
14708
14709 if (corpus *type_corpus = array_type->get_corpus())
14710 {
14712 (array_type,
14713 type_corpus->priv_->get_types().array_types());
14714
14716 (array_type,
14717 type_corpus->get_type_per_loc_map().array_types(),
14718 /*use_type_name_as_key*/false);
14719
14720 if (corpus *group = type_corpus->get_group())
14721 {
14723 (array_type,
14724 group->priv_->get_types().array_types());
14725
14727 (array_type,
14728 group->get_type_per_loc_map().array_types(),
14729 /*use_type_name_as_key*/false);
14730 }
14731 }
14732}
14733
14734/// Update the map that associates the fully qualified name of a type
14735/// with the type itself.
14736///
14737/// The per-translation unit type map is updated if no type with this
14738/// name was already existing in that map.
14739///
14740/// If no type with this name did already exist in the per-corpus type
14741/// map, then that per-corpus type map is updated. Otherwise, that
14742/// type is erased from that per-corpus map.
14743///
14744/// @param subrange_type the type to consider.
14745void
14747(const array_type_def::subrange_sptr& subrange_type)
14748{
14749 if (translation_unit *tu = subrange_type->get_translation_unit())
14751 (subrange_type, tu->get_types().subrange_types());
14752
14753 if (corpus *type_corpus = subrange_type->get_corpus())
14754 {
14756 (subrange_type,
14757 type_corpus->priv_->get_types().subrange_types());
14758
14760 (subrange_type,
14761 type_corpus->get_type_per_loc_map().subrange_types(),
14762 /*use_type_name_as_key*/false);
14763
14764 if (corpus *group = subrange_type->get_corpus())
14765 {
14767 (subrange_type,
14768 group->priv_->get_types().subrange_types());
14769
14771 (subrange_type,
14772 group->get_type_per_loc_map().subrange_types(),
14773 /*use_type_name_as_key*/false);
14774 }
14775 }
14776}
14777
14778/// Update the map that associates the fully qualified name of a
14779/// function type with the type itself.
14780///
14781/// The per-translation unit type map is updated if no type with this
14782/// name was already existing in that map.
14783///
14784/// If no type with this name did already exist in the per-corpus type
14785/// map, then that per-corpus type map is updated. Otherwise, that
14786/// type is erased from that per-corpus map.
14787///
14788/// @param scope the scope of the function type.
14789/// @param fn_type the type to consider.
14790void
14792{
14793 if (translation_unit *tu = fn_type->get_translation_unit())
14795 (fn_type, tu->get_types().function_types());
14796
14797 if (corpus *type_corpus = fn_type->get_corpus())
14798 {
14800 (fn_type,
14801 type_corpus->priv_->get_types().function_types());
14802
14803 if (corpus *group = fn_type->get_corpus())
14804 {
14806 (fn_type,
14807 group->priv_->get_types().function_types());
14808 }
14809 }
14810}
14811
14812/// Update the map that associates the fully qualified name of a type
14813/// declaration with the type itself.
14814///
14815/// The per-translation unit type map is updated if no type with this
14816/// name was already existing in that map.
14817///
14818/// If no type with this name did already exist in the per-corpus type
14819/// map, then that per-corpus type map is updated. Otherwise, that
14820/// type is erased from that per-corpus map.
14821///
14822/// @param decl the declaration of the type to consider.
14823void
14824maybe_update_types_lookup_map(const decl_base_sptr& decl)
14825{
14826 if (!is_type(decl))
14827 return;
14828
14829 if (type_decl_sptr basic_type = is_type_decl(decl))
14831 else if (class_decl_sptr class_type = is_class_type(decl))
14833 else if (union_decl_sptr union_type = is_union_type(decl))
14835 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
14837 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
14838 maybe_update_types_lookup_map(typedef_type);
14839 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
14840 maybe_update_types_lookup_map(qualified_type);
14841 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
14842 maybe_update_types_lookup_map(pointer_type);
14843 else if (ptr_to_mbr_type_sptr ptr_to_member = is_ptr_to_mbr_type(decl))
14844 maybe_update_types_lookup_map(ptr_to_member);
14845 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
14846 maybe_update_types_lookup_map(reference_type);
14847 else if (array_type_def_sptr array_type = is_array_type(decl))
14849 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
14850 maybe_update_types_lookup_map(subrange_type);
14851 else if (function_type_sptr fn_type = is_function_type(decl))
14853 else
14855}
14856
14857/// Update the map that associates the fully qualified name of a type
14858/// with the type itself.
14859///
14860/// The per-translation unit type map is updated if no type with this
14861/// name was already existing in that map.
14862///
14863/// If no type with this name did already exist in the per-corpus type
14864/// map, then that per-corpus type map is updated. Otherwise, that
14865/// type is erased from that per-corpus map.
14866///
14867/// @param type the type to consider.
14868void
14869maybe_update_types_lookup_map(const type_base_sptr& type)
14870{
14871 if (decl_base_sptr decl = get_type_declaration(type))
14873 else if (function_type_sptr fn_type = is_function_type(type))
14875 else
14877}
14878
14879//--------------------------------
14880// </type and decls lookup stuff>
14881// ------------------------------
14882
14883/// In a translation unit, lookup a given type or synthesize it if
14884/// it's a qualified type.
14885///
14886/// So this function first looks the type up in the translation unit.
14887/// If it's found, then OK, it's returned. Otherwise, if it's a
14888/// qualified, reference or pointer or function type (a composite
14889/// type), lookup the underlying type, synthesize the type we want
14890/// from it and return it.
14891///
14892/// If the underlying types is not not found, then give up and return
14893/// nil.
14894///
14895/// @return the type that was found or the synthesized type.
14896type_base_sptr
14897synthesize_type_from_translation_unit(const type_base_sptr& type,
14898 translation_unit& tu)
14899{
14900 type_base_sptr result;
14901
14902 result = lookup_type(type, tu);
14903
14904 if (!result)
14905 {
14906 if (qualified_type_def_sptr qual = is_qualified_type(type))
14907 {
14908 type_base_sptr underlying_type =
14909 synthesize_type_from_translation_unit(qual->get_underlying_type(),
14910 tu);
14911 if (underlying_type)
14912 {
14913 result.reset(new qualified_type_def(underlying_type,
14914 qual->get_cv_quals(),
14915 qual->get_location()));
14916 }
14917 }
14918 else if (pointer_type_def_sptr p = is_pointer_type(type))
14919 {
14920 type_base_sptr pointed_to_type =
14921 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
14922 tu);
14923 if (pointed_to_type)
14924 {
14925 result.reset(new pointer_type_def(pointed_to_type,
14926 p->get_size_in_bits(),
14927 p->get_alignment_in_bits(),
14928 p->get_location()));
14929 }
14930 }
14931 else if (reference_type_def_sptr r = is_reference_type(type))
14932 {
14933 type_base_sptr pointed_to_type =
14934 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
14935 if (pointed_to_type)
14936 {
14937 result.reset(new reference_type_def(pointed_to_type,
14938 r->is_lvalue(),
14939 r->get_size_in_bits(),
14940 r->get_alignment_in_bits(),
14941 r->get_location()));
14942 }
14943 }
14944 else if (function_type_sptr f = is_function_type(type))
14946
14947 if (result)
14948 {
14950 canonicalize(result);
14951 }
14952 }
14953
14954 if (result)
14955 tu.priv_->synthesized_types_.push_back(result);
14956
14957 return result;
14958}
14959
14960/// In a translation unit, lookup the sub-types that make up a given
14961/// function type and if the sub-types are all found, synthesize and
14962/// return a function_type with them.
14963///
14964/// This function is like lookup_function_type_in_translation_unit()
14965/// execept that it constructs the function type from the sub-types
14966/// found in the translation, rather than just looking for the
14967/// function types held by the translation unit. This can be useful
14968/// if the translation unit doesnt hold the function type we are
14969/// looking for (i.e, lookup_function_type_in_translation_unit()
14970/// returned NULL) but we still want to see if the sub-types of the
14971/// function types are present in the translation unit.
14972///
14973/// @param fn_type the function type to consider.
14974///
14975/// @param tu the translation unit to look into.
14976///
14977/// @return the resulting synthesized function type if all its
14978/// sub-types have been found, NULL otherwise.
14981 translation_unit& tu)
14982{
14984
14985 const environment& env = tu.get_environment();
14986
14987 type_base_sptr return_type = fn_type.get_return_type();
14988 type_base_sptr result_return_type;
14989 if (!return_type || env.is_void_type(return_type))
14990 result_return_type = env.get_void_type();
14991 else
14992 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
14993 if (!result_return_type)
14994 return nil;
14995
14997 type_base_sptr parm_type;
14999 for (function_type::parameters::const_iterator i =
15000 fn_type.get_parameters().begin();
15001 i != fn_type.get_parameters().end();
15002 ++i)
15003 {
15004 type_base_sptr t = (*i)->get_type();
15005 parm_type = synthesize_type_from_translation_unit(t, tu);
15006 if (!parm_type)
15007 return nil;
15008 parm.reset(new function_decl::parameter(parm_type,
15009 (*i)->get_index(),
15010 (*i)->get_name(),
15011 (*i)->get_location(),
15012 (*i)->get_variadic_marker(),
15013 (*i)->get_is_artificial()));
15014 parms.push_back(parm);
15015 }
15016
15017 class_or_union_sptr class_type;
15018 const method_type* method = is_method_type(&fn_type);
15019 if (method)
15020 {
15021 class_type = is_class_or_union_type
15023 ABG_ASSERT(class_type);
15024 }
15025
15026 function_type_sptr result_fn_type;
15027
15028 if (class_type)
15029 result_fn_type.reset(new method_type(result_return_type,
15030 class_type,
15031 parms,
15032 method->get_is_const(),
15033 fn_type.get_size_in_bits(),
15034 fn_type.get_alignment_in_bits()));
15035 else
15036 result_fn_type.reset(new function_type(result_return_type,
15037 parms,
15038 fn_type.get_size_in_bits(),
15039 fn_type.get_alignment_in_bits()));
15040
15041 tu.priv_->synthesized_types_.push_back(result_fn_type);
15042 tu.bind_function_type_life_time(result_fn_type);
15043
15044 canonicalize(result_fn_type);
15045 return result_fn_type;
15046}
15047
15048/// Demangle a C++ mangled name and return the resulting string
15049///
15050/// @param mangled_name the C++ mangled name to demangle.
15051///
15052/// @return the resulting mangled name.
15053string
15054demangle_cplus_mangled_name(const string& mangled_name)
15055{
15056 if (mangled_name.empty())
15057 return "";
15058
15059 size_t l = 0;
15060 int status = 0;
15061 char * str = abi::__cxa_demangle(mangled_name.c_str(),
15062 NULL, &l, &status);
15063 string demangled_name = mangled_name;
15064 if (str)
15065 {
15066 ABG_ASSERT(status == 0);
15067 demangled_name = str;
15068 free(str);
15069 str = 0;
15070 }
15071 return demangled_name;
15072}
15073
15074/// Return either the type given in parameter if it's non-null, or the
15075/// void type.
15076///
15077/// @param t the type to consider.
15078///
15079/// @param env the environment to use. If NULL, just abort the
15080/// process.
15081///
15082/// @return either @p t if it is non-null, or the void type.
15083type_base_sptr
15084type_or_void(const type_base_sptr t, const environment& env)
15085{
15086 type_base_sptr r;
15087
15088 if (t)
15089 r = t;
15090 else
15091 r = type_base_sptr(env.get_void_type());
15092
15093 return r;
15094}
15095
15096global_scope::~global_scope()
15097{
15098}
15099
15100/// Test if two types are eligible to the "Linux Kernel Fast Type
15101/// Comparison Optimization", a.k.a LKFTCO.
15102///
15103/// Two types T1 and T2 (who are presumably of the same name and kind)
15104/// are eligible to the LKFTCO if they fulfill the following criteria/
15105///
15106/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
15107/// either class, union or enums.
15108///
15109/// 2/ They are defined in the same translation unit.
15110///
15111/// @param t1 the first type to consider.
15112///
15113/// @param t2 the second type to consider.
15114///
15115/// @return true iff t1 and t2 are eligible to the LKFTCO.
15116static bool
15117types_defined_same_linux_kernel_corpus_public(const type_base& t1,
15118 const type_base& t2)
15119{
15120 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
15121 string t1_file_path, t2_file_path;
15122
15123 /// If the t1 (and t2) are classes/unions/enums from the same linux
15124 /// kernel corpus, let's move on. Otherwise bail out.
15125 if (!(t1_corpus && t2_corpus
15126 && t1_corpus == t2_corpus
15127 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
15128 && (is_class_or_union_type(&t1)
15129 || is_enum_type(&t1))))
15130 return false;
15131
15132 class_or_union *c1 = 0, *c2 = 0;
15133 c1 = is_class_or_union_type(&t1);
15134 c2 = is_class_or_union_type(&t2);
15135
15136 // Two anonymous class types with no naming typedefs cannot be
15137 // eligible to this optimization.
15138 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
15139 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
15140 return false;
15141
15142 // Two anonymous classes with naming typedefs should have the same
15143 // typedef name.
15144 if (c1
15145 && c2
15146 && c1->get_is_anonymous() && c1->get_naming_typedef()
15147 && c2->get_is_anonymous() && c2->get_naming_typedef())
15148 if (c1->get_naming_typedef()->get_name()
15149 != c2->get_naming_typedef()->get_name())
15150 return false;
15151
15152 // Two anonymous enum types cannot be eligible to this optimization.
15153 if (const enum_type_decl *e1 = is_enum_type(&t1))
15154 if (const enum_type_decl *e2 = is_enum_type(&t2))
15155 if (e1->get_is_anonymous() || e2->get_is_anonymous())
15156 return false;
15157
15158 // Look through declaration-only types. That is, get the associated
15159 // definition type.
15162
15163 if (c1 && c2)
15164 {
15165 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
15166 {
15167 if (c1->get_environment().decl_only_class_equals_definition())
15168 // At least one of classes/union is declaration-only.
15169 // Because we are in a context in which a declaration-only
15170 // class/union is equal to all definitions of that
15171 // class/union, we can assume that the two types are
15172 // equal.
15173 return true;
15174 }
15175 }
15176
15177 if (t1.get_size_in_bits() != t2.get_size_in_bits())
15178 return false;
15179
15180 // Look at the file names of the locations of t1 and t2. If they
15181 // are equal, then t1 and t2 are defined in the same file.
15182 {
15183 location l;
15184
15185 if (c1)
15186 l = c1->get_location();
15187 else
15188 l = dynamic_cast<const decl_base&>(t1).get_location();
15189
15190 unsigned line = 0, col = 0;
15191 if (l)
15192 l.expand(t1_file_path, line, col);
15193 if (c2)
15194 l = c2->get_location();
15195 else
15196 l = dynamic_cast<const decl_base&>(t2).get_location();
15197 if (l)
15198 l.expand(t2_file_path, line, col);
15199 }
15200
15201 if (t1_file_path.empty() || t2_file_path.empty())
15202 return false;
15203
15204 if (t1_file_path == t2_file_path)
15205 return true;
15206
15207 return false;
15208}
15209
15210
15211/// Compare a type T against a canonical type.
15212///
15213/// This function is called during the canonicalization process of the
15214/// type T. T is called the "candidate type" because it's in the
15215/// process of being canonicalized. Meaning, it's going to be
15216/// compared to a canonical type C. If T equals C, then the canonical
15217/// type of T is C.
15218///
15219/// The purpose of this function is to allow the debugging of the
15220/// canonicalization of T, if that debugging is activated by
15221/// configuring the libabigail package with
15222/// --enable-debug-type-canonicalization and by running "abidw
15223/// --debug-tc". In that case, T is going to be compared to C twice:
15224/// once with canonical equality and once with structural equality.
15225/// The two comparisons must be equal. Otherwise, the
15226/// canonicalization process is said to be faulty and this function
15227/// aborts.
15228///
15229/// This is a sub-routine of type_base::get_canonical_type_for.
15230///
15231/// @param canonical_type the canonical type to compare the candidate
15232/// type against.
15233///
15234/// @param candidate_type the candidate type to compare against the
15235/// canonical type.
15236///
15237/// @return true iff @p canonical_type equals @p candidate_type.
15238///
15239static bool
15240compare_types_during_canonicalization(const type_base& canonical_type,
15241 const type_base& candidate_type)
15242{
15243#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
15244 const environment& env = canonical_type.get_environment();
15245 if (env.debug_type_canonicalization_is_on())
15246 {
15247 bool canonical_equality = false, structural_equality = false;
15248 env.priv_->allow_type_comparison_results_caching(false);
15249 env.priv_->use_canonical_type_comparison_ = false;
15250 structural_equality = canonical_type == candidate_type;
15251 env.priv_->use_canonical_type_comparison_ = true;
15252 canonical_equality = canonical_type == candidate_type;
15253 env.priv_->allow_type_comparison_results_caching(true);
15254 if (canonical_equality != structural_equality)
15255 {
15256 std::cerr << "structural & canonical equality different for type: "
15257 << canonical_type.get_pretty_representation(true, true)
15258 << std::endl;
15260 }
15261 return structural_equality;
15262 }
15263#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
15264 return canonical_type == candidate_type;
15265}
15266
15267/// Compare a canonical type against a candidate canonical type.
15268///
15269/// This is ultimately a sub-routine of the
15270/// type_base::get_canonical_type_for().
15271///
15272/// The goal of this function is to ease debugging because it can be
15273/// called from within type_base::get_canonical_type_for() from the
15274/// prompt of the debugger (with some breakpoint appropriately set) to
15275/// debug the comparison that happens during type canonicalization,
15276/// between a candidate type being canonicalized, and an existing
15277/// canonical type that is registered in the system, in as returned by
15278/// environment::get_canonical_types()
15279///
15280/// @param canonical_type the canonical type to consider.
15281///
15282/// @param candidate_type the candidate type that is being
15283/// canonicalized, and thus compared to @p canonical_type.
15284///
15285/// @return true iff @p canonical_type compares equal to @p
15286/// candidate_type.
15287static bool
15288compare_canonical_type_against_candidate(const type_base& canonical_type,
15289 const type_base& candidate_type)
15290{
15291 environment& env = const_cast<environment&>(canonical_type.get_environment());
15292
15293 // Before the "*it == it" comparison below is done, let's
15294 // perform on-the-fly-canonicalization. For C types, let's
15295 // consider that an unresolved struct declaration 'struct S'
15296 // is different from a definition 'struct S'. This is
15297 // because normally, at this point all the declarations of
15298 // struct S that are compatible with the definition of
15299 // struct S have already been resolved to that definition,
15300 // during the DWARF parsing. The remaining unresolved
15301 // declaration are thus considered different. With this
15302 // setup we can properly handle cases of two *different*
15303 // struct S being defined in the same binary (in different
15304 // translation units), and a third struct S being only
15305 // declared as an opaque type in a third translation unit of
15306 // its own, with no definition in there. In that case, the
15307 // declaration-only struct S should be left alone and not
15308 // resolved to any of the two definitions of struct S.
15309 bool saved_decl_only_class_equals_definition =
15310 env.decl_only_class_equals_definition();
15311
15312 // Compare types by considering that decl-only classes don't
15313 // equal their definition.
15314 env.decl_only_class_equals_definition(false);
15315 env.priv_->allow_type_comparison_results_caching(true);
15316 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
15317 candidate_type)
15318 || compare_types_during_canonicalization(canonical_type,
15319 candidate_type));
15320 // Restore the state of the on-the-fly-canonicalization and
15321 // the decl-only-class-being-equal-to-a-matching-definition
15322 // flags.
15323 env.priv_->clear_type_comparison_results_cache();
15324 env.priv_->allow_type_comparison_results_caching(false);
15325 env.decl_only_class_equals_definition
15326 (saved_decl_only_class_equals_definition);
15327 return equal;
15328}
15329
15330/// Compare a canonical type against a candidate canonical type.
15331///
15332/// This is ultimately a sub-routine of the
15333/// type_base::get_canonical_type_for().
15334///
15335/// The goal of this function is to ease debugging because it can be
15336/// called from within type_base::get_canonical_type_for() from the
15337/// prompt of the debugger (with some breakpoint appropriately set) to
15338/// debug the comparison that happens during type canonicalization,
15339/// between a candidate type being canonicalized, and an existing
15340/// canonical type that is registered in the system, in as returned by
15341/// environment::get_canonical_types()
15342///
15343/// @param canonical_type the canonical type to consider.
15344///
15345/// @param candidate_type the candidate type that is being
15346/// canonicalized, and thus compared to @p canonical_type.
15347///
15348/// @return true iff @p canonical_type compares equal to @p
15349/// candidate_type.
15350static bool
15351compare_canonical_type_against_candidate(const type_base* canonical_type,
15352 const type_base* candidate_type)
15353{
15354 return compare_canonical_type_against_candidate(*canonical_type,
15355 *candidate_type);
15356}
15357
15358/// Compare a canonical type against a candidate canonical type.
15359///
15360/// This is ultimately a sub-routine of the
15361/// type_base::get_canonical_type_for().
15362///
15363/// The goal of this function is to ease debugging because it can be
15364/// called from within type_base::get_canonical_type_for() from the
15365/// prompt of the debugger (with some breakpoint appropriately set) to
15366/// debug the comparison that happens during type canonicalization,
15367/// between a candidate type being canonicalized, and an existing
15368/// canonical type that is registered in the system, in as returned by
15369/// environment::get_canonical_types()
15370///
15371/// @param canonical_type the canonical type to consider.
15372///
15373/// @param candidate_type the candidate type that is being
15374/// canonicalized, and thus compared to @p canonical_type.
15375///
15376/// @return true iff @p canonical_type compares equal to @p
15377/// candidate_type.
15378static bool
15379compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15380 const type_base_sptr& candidate_type)
15381{
15382 return compare_canonical_type_against_candidate(canonical_type.get(),
15383 candidate_type.get());
15384}
15385
15386/// Test if a candidate for type canonicalization coming from ABIXML
15387/// matches a canonical type by first looking at their hash values.
15388///
15389/// If the two hash values are equal then the candidate is
15390/// structurally compared to the canonical type. If the two hashes
15391/// are different then the two types are considered different and the
15392/// function returns nullptr.
15393///
15394/// If the candidate doesn't come from ABIXML then the function
15395/// returns nullptr.
15396///
15397/// @param cncls the vector of canonical types to consider.
15398///
15399/// @param type the candidate to consider for canonicalization.
15400///
15401/// @return the canonical type from @p cncls that matches the
15402/// candidate @p type.
15403static type_base_sptr
15404candidate_matches_a_canonical_type_hash(const vector<type_base_sptr>& cncls,
15405 type_base& type)
15406{
15407 if (type.get_corpus()
15408 && type.get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
15409 && peek_hash_value(type))
15410 {
15411 // The candidate type comes from ABIXML and does have a stashed
15412 // hash value coming from the ABIXML.
15413
15414 // Let's see if we find a potential canonical type whose hash
15415 // matches the stashed hash and whose canonical type index
15416 // matches it too.
15417 for (const auto& c : cncls)
15418 if (peek_hash_value(type) == peek_hash_value(*c))
15420 // We found a potential canonical type which hash matches the
15421 // stashed hash of the candidate type. Let's compare them to
15422 // see if they match.
15423 if (compare_canonical_type_against_candidate(*c, type))
15424 return c;
15425
15426 // Let's do the same things, but just consideing hash values.
15427 for (const auto& c : cncls)
15428 if (peek_hash_value(type) == peek_hash_value(*c))
15429 // We found a potential canonical type which hash matches the
15430 // stashed hash of the candidate type. Let's compare them to
15431 // see if they match.
15432 if (compare_canonical_type_against_candidate(*c, type))
15433 return c;
15434 }
15435
15436 return nullptr;
15437}
15438
15439/// Test if we should attempt to compute a hash value for a given
15440/// type.
15441///
15442/// For now this function returns true only for types originating from
15443/// ELF. For types originating from ABIXML, for instance, the
15444/// function return false, meaning that types originating from ABIXML
15445/// should NOT be hashed.
15446///
15447/// @param t the type to consider.
15448///
15449/// @return true iff @p type should be considered for hashing.
15450bool
15452{
15453 if (t.get_corpus()
15454 && (t.get_corpus()->get_origin() & corpus::ELF_ORIGIN))
15455 return true;
15456 return false;
15457}
15458
15459/// Compute the canonical type for a given instance of @ref type_base.
15460///
15461/// Consider two types T and T'. The canonical type of T, denoted
15462/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
15463/// otherwise, to compare two types, one just needs to compare their
15464/// canonical types using pointer equality. That makes type
15465/// comparison faster than the structural comparison performed by the
15466/// abigail::ir::equals() overloads.
15467///
15468/// If there is not yet any canonical type for @p t, then @p t is its
15469/// own canonical type. Otherwise, this function returns the
15470/// canonical type of @p t which is the canonical type that has the
15471/// same hash value as @p t and that structurally equals @p t. Note
15472/// that after invoking this function, the life time of the returned
15473/// canonical time is then equals to the life time of the current
15474/// process.
15475///
15476/// @param t a smart pointer to instance of @ref type_base we want to
15477/// compute a canonical type for.
15478///
15479/// @return the canonical type for the current instance of @ref
15480/// type_base.
15481type_base_sptr
15482type_base::get_canonical_type_for(type_base_sptr t)
15483{
15484 if (!t)
15485 return t;
15486
15487 environment& env = const_cast<environment&>(t->get_environment());
15488
15490 // This type should not be canonicalized!
15491 return type_base_sptr();
15492
15493 if (is_decl(t))
15495
15496 // Look through decl-only types (classes, unions and enums)
15497 bool decl_only_class_equals_definition =
15499
15500 class_or_union_sptr class_or_union = is_class_or_union_type(t);
15501
15502 // In the context of types from C++ or languages where we assume the
15503 // "One Definition Rule", we assume that a declaration-only
15504 // non-anonymous class equals all fully defined classes of the same
15505 // name.
15506 //
15507 // Otherwise, all classes, including declaration-only classes are
15508 // canonicalized and only canonical comparison is going to be used
15509 // in the system.
15510 if (decl_only_class_equals_definition)
15511 if (class_or_union)
15513 return type_base_sptr();
15514
15515 class_decl_sptr is_class = is_class_type(t);
15516 if (t->get_canonical_type())
15517 return t->get_canonical_type();
15518
15519 // For classes and union, ensure that an anonymous class doesn't
15520 // have a linkage name. If it does in the future, then me must be
15521 // mindful that the linkage name respects the type identity
15522 // constraints which states that "if two linkage names are different
15523 // then the two types are different".
15527
15528 // We want the pretty representation of the type, but for an
15529 // internal use, not for a user-facing purpose.
15530 //
15531 // If two classe types Foo are declared, one as a class and the
15532 // other as a struct, but are otherwise equivalent, we want their
15533 // pretty representation to be the same. Hence the 'internal'
15534 // argument of ir::get_pretty_representation() is set to true here.
15535 // So in this case, the pretty representation of Foo is going to be
15536 // "class Foo", regardless of its struct-ness. This also applies to
15537 // composite types which would have "class Foo" as a sub-type.
15538 string repr = t->get_cached_pretty_representation(/*internal=*/true);
15539
15540 // If 't' already has a canonical type 'inside' its corpus
15541 // (t_corpus), then this variable is going to contain that canonical
15542 // type.
15543 type_base_sptr canonical_type_present_in_corpus;
15546
15547 type_base_sptr result;
15548 environment::canonical_types_map_type::iterator i = types.find(repr);
15549
15550 if (i == types.end())
15551 {
15552 vector<type_base_sptr> v;
15553 v.push_back(t);
15554 types[repr] = v;
15555 result = t;
15556 }
15557 else
15558 {
15559 vector<type_base_sptr> &v = i->second;
15560 // Look at the canonical types and if the current candidate type
15561 // coming from abixml has the same hash as one of the canonical
15562 // types, then compare the current candidate with the one with a
15563 // matching hash.
15564 result = candidate_matches_a_canonical_type_hash(v, *t);
15565
15566 // Let's compare 't' structurally (i.e, compare its sub-types
15567 // recursively) against the canonical types of the system. If it
15568 // equals a given canonical type C, then it means C is the
15569 // canonical type of 't'. Otherwise, if 't' is different from
15570 // all the canonical types of the system, then it means 't' is a
15571 // canonical type itself.
15572 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15573 !result && it != v.rend();
15574 ++it)
15575 {
15576 bool equal = compare_canonical_type_against_candidate(*it, t);
15577 if (equal)
15578 {
15579 result = *it;
15580 break;
15581 }
15582 }
15583#ifdef WITH_DEBUG_SELF_COMPARISON
15584 if (env.self_comparison_debug_is_on())
15585 {
15586 // So we are debugging the canonicalization process,
15587 // possibly via the use of 'abidw --debug-abidiff <binary>'.
15588 corpus_sptr corp1, corp2;
15589 env.get_self_comparison_debug_inputs(corp1, corp2);
15590 if (corp1 && corp2 && type_originates_from_corpus(t, corp2)
15591 && corp1->get_origin() != corp2->get_origin()
15592 && corp2->get_origin() & corpus::NATIVE_XML_ORIGIN)
15593 {
15594 // If 't' comes from the second corpus, then it *must*
15595 // be equal to its matching canonical type coming from
15596 // the first corpus because the second corpus is the
15597 // abixml representation of the first corpus. In other
15598 // words, all types coming from the second corpus must
15599 // have canonical types coming from the first corpus.
15600 if (result)
15601 {
15602 if (!env.priv_->
15603 check_canonical_type_from_abixml_during_self_comp(t,
15604 result))
15605 {
15606 // The canonical type of the type re-read from abixml
15607 // type doesn't match the canonical type that was
15608 // initially serialized down.
15609 uintptr_t should_have_canonical_type = 0;
15610 string type_id = env.get_type_id_from_type(t.get());
15611 if (type_id.empty())
15612 type_id = "type-id-<not-found>";
15613 else
15614 should_have_canonical_type =
15615 env.get_canonical_type_from_type_id(type_id.c_str());
15616 std::cerr << "error: wrong canonical type for '"
15617 << repr
15618 << "' / type: @"
15619 << std::hex
15620 << t.get()
15621 << "/ canon: @"
15622 << result.get()
15623 << ", type-id: '"
15624 << type_id
15625 << "'. Should have had canonical type: "
15626 << std::hex
15627 << should_have_canonical_type
15628 << std::dec
15629 << std::endl;
15630 }
15631 }
15632 else //!result
15633 {
15634 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
15635 string type_id = env.get_type_id_from_pointer(ptr_val);
15636 if (type_id.empty())
15637 type_id = "type-id-<not-found>";
15638 // We are in the case where 't' is different from all
15639 // the canonical types of the same name that come from
15640 // the first corpus.
15641 //
15642 // If 't' indeed comes from the second corpus then this
15643 // clearly is a canonicalization failure.
15644 //
15645 // There was a problem either during the serialization
15646 // of 't' into abixml, or during the de-serialization
15647 // from abixml into abigail::ir. Further debugging is
15648 // needed to determine what that root cause problem is.
15649 //
15650 // Note that the first canonicalization problem of this
15651 // kind must be fixed before looking at the subsequent
15652 // ones, because the later might well just be
15653 // consequences of the former.
15654 std::cerr << "error: wrong induced canonical type for '"
15655 << repr
15656 << "' from second corpus"
15657 << ", ptr: " << std::hex << t.get()
15658 << " type-id: " << type_id
15659 << " /hash="
15660 << *t->hash_value()
15661 << std::dec
15662 << std::endl;
15663 }
15664 }
15665 if (result)
15666 {
15667 if (!is_type_decl(t))
15668 if (hash_t t_hash = peek_hash_value(*t))
15669 if (hash_t result_hash = peek_hash_value(*result))
15670 if (t_hash != result_hash)
15671 {
15672 std::cerr << "error: type hash mismatch"
15673 << " between type: '"
15674 << repr
15675 << "' @ "
15676 << std::hex
15677 << t.get()
15678 << "/hash="
15679 << *t->hash_value()
15680 << " and its computed canonical type @"
15681 << std::hex
15682 << result.get()
15683 << "/hash="
15684 << std::hex
15685 << *result->hash_value()
15686 << std::dec
15687 << std::endl;
15688 }
15689 }
15690 }
15691#endif //WITH_DEBUG_SELF_COMPARISON
15692
15693 if (!result)
15694 {
15695 v.push_back(t);
15696 result = t;
15697 // we need to generate a canonical type index to sort these
15698 // types that have the same representation and potentially
15699 // same hash value but are canonically different.
15700 t->priv_->canonical_type_index = v.size();
15701 }
15702 }
15703
15704 return result;
15705}
15706
15707/// This method is invoked automatically right after the current
15708/// instance of @ref class_decl has been canonicalized.
15709void
15712
15713/// This is a subroutine of the canonicalize() function.
15714///
15715/// When the canonical type C of type T has just been computed, there
15716/// can be cases where T has member functions that C doesn't have.
15717///
15718/// This is possible because non virtual member functions are not
15719/// taken in account when comparing two types.
15720///
15721/// In that case, this function updates C so that it contains the
15722/// member functions.
15723///
15724/// There can also be cases where C has a method M which is not linked
15725/// to any underlying symbol, whereas in T, M is to link to an
15726/// underlying symbol. In that case, this function updates M in C so
15727/// that it's linked to the same underlying symbol as for M in T.
15728static void
15729maybe_adjust_canonical_type(const type_base_sptr& canonical,
15730 const type_base_sptr& type)
15731{
15732 if (type->get_naked_canonical_type())
15733 return;
15734
15735 class_decl_sptr canonical_class = is_class_type(canonical);
15736
15737 if (class_decl_sptr cl = is_class_type(type))
15738 {
15740 if (canonical_class
15741 && canonical_class.get() != cl.get())
15742 {
15743 // Set symbols of member functions that might be missing
15744 // theirs.
15745 for (class_decl::member_functions::const_iterator i =
15746 cl->get_member_functions().begin();
15747 i != cl->get_member_functions().end();
15748 ++i)
15749 if ((*i)->get_symbol())
15750 {
15751 if (method_decl *m = canonical_class->
15752 find_member_function((*i)->get_linkage_name()))
15753 {
15754 elf_symbol_sptr s1 = (*i)->get_symbol();
15755 if (s1 && !m->get_symbol())
15756 // Method 'm' in the canonical type is not
15757 // linked to the underlying symbol of '*i'.
15758 // Let's link it now. have th
15759 m->set_symbol(s1);
15760 }
15761 else
15762 if (canonical_class->get_corpus()
15763 && cl->get_corpus()
15764 && (cl->get_corpus() == canonical_class->get_corpus()))
15765 // There is a member function defined and publicly
15766 // exported in the other class and the canonical
15767 // class doesn't have that member function. This
15768 // should not have happened! For instance, the
15769 // DWARF reader does merge the member functions of
15770 // classes having the same name so that all of them
15771 // end-up having the same member functions. What's
15772 // going on here?
15774 }
15775
15776 // Set symbols of static data members that might be missing
15777 // theirs.
15778 for (const auto& data_member : cl->get_data_members())
15779 {
15780 if (!get_member_is_static(data_member))
15781 continue;
15782 elf_symbol_sptr sym = data_member->get_symbol();
15783 if (!sym)
15784 continue;
15785 const auto& canonical_data_member =
15786 canonical_class->find_data_member(data_member->get_name());
15787 if (!canonical_data_member)
15788 // Hmmh, maybe we
15789 // should consider
15790 // static data members
15791 // when comparing two
15792 // classes for the
15793 // purpose of type
15794 // canonicalization?
15795 continue;
15796 if (!canonical_data_member->get_symbol())
15797 canonical_data_member->set_symbol(sym);
15798 }
15799 }
15800 }
15801
15802 // Make sure the virtual member functions with exported symbols are
15803 // all added to the set of exported functions of the corpus.
15804
15805 // If we are looking at a non-canonicalized class (for instance, a
15806 // decl-only class that has virtual member functions), let's pretend
15807 // it does have a canonical class so that we can perform the
15808 // necessary virtual member function adjustments
15809 if (class_decl_sptr cl = is_class_type(type))
15811 {
15812 ABG_ASSERT(!canonical_class);
15813 canonical_class = cl;
15814 }
15815
15816 if (canonical_class)
15817 {
15818 if (auto abi_corpus = canonical_class->get_corpus())
15819 {
15820 for (auto& fn : canonical_class->get_member_functions())
15821 {
15822 if (elf_symbol_sptr sym = fn->get_symbol())
15823 {
15824 if (sym->is_defined() && sym->is_public())
15825 {
15826 fn->set_is_in_public_symbol_table(true);
15827 auto b = abi_corpus->get_exported_decls_builder();
15828 b->maybe_add_fn_to_exported_fns(fn.get());
15829 }
15830 else if (!sym->is_defined())
15831 abi_corpus->get_undefined_functions().insert(fn.get());
15832 }
15833 }
15834 }
15835 }
15836
15837 // If an artificial function type equals a non-artfificial one in
15838 // the system, then the canonical type of both should be deemed
15839 // non-artificial. This is important because only non-artificial
15840 // canonical function types are emitted out into abixml, so if don't
15841 // do this we risk missing to emit some function types.
15842 if (is_function_type(type))
15843 if (type->get_is_artificial() != canonical->get_is_artificial())
15844 canonical->set_is_artificial(false);
15845}
15846
15847/// Compute the canonical type of a given type.
15848///
15849/// It means that after invoking this function, comparing the intance
15850/// instance @ref type_base and another one (on which
15851/// type_base::enable_canonical_equality() would have been invoked as
15852/// well) is performed by just comparing the pointer values of the
15853/// canonical types of both types. That equality comparison is
15854/// supposedly faster than structural comparison of the types.
15855///
15856/// @param t a smart pointer to the instance of @ref type_base for
15857/// which to compute the canonical type. After this call,
15858/// t->get_canonical_type() will return the newly computed canonical
15859/// type.
15860///
15861/// @param do_log if true then logs are emitted about canonicalization
15862/// progress.
15863///
15864/// @param show_stats if true and if @p do_log is true as well, then
15865/// more detailed logs are emitted about canonicalization.
15866///
15867/// @return the canonical type computed for @p t.
15868type_base_sptr
15869canonicalize(type_base_sptr t, bool do_log, bool show_stats)
15870{
15871 if (!t)
15872 return t;
15873
15874 if (t->get_canonical_type())
15875 return t->get_canonical_type();
15876
15877 if (do_log && show_stats)
15878 std::cerr << "Canonicalization of type '"
15879 << t->get_pretty_representation(true, true)
15880 << "/@#" << std::hex << t.get() << ": ";
15881
15883
15884 if (do_log && show_stats)
15885 tmr.start();
15886 type_base_sptr canonical = type_base::get_canonical_type_for(t);
15887
15888 if (do_log && show_stats)
15889 tmr.stop();
15890
15891 if (do_log && show_stats)
15892 std::cerr << tmr << "\n";
15893
15894 maybe_adjust_canonical_type(canonical, t);
15895
15896 t->priv_->canonical_type = canonical;
15897 t->priv_->naked_canonical_type = canonical.get();
15898
15899 if (canonical)
15900 if (!t->priv_->canonical_type_index)
15901 t->priv_->canonical_type_index = canonical->priv_->canonical_type_index;
15902
15903 if (class_decl_sptr cl = is_class_type(t))
15904 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
15905 if ((canonical = d->get_canonical_type()))
15906 {
15907 d->priv_->canonical_type = canonical;
15908 d->priv_->naked_canonical_type = canonical.get();
15909 }
15910
15911 if (canonical)
15912 {
15913 if (decl_base_sptr d = is_decl_slow(canonical))
15914 {
15915 scope_decl *scope = d->get_scope();
15916 // Add the canonical type to the set of canonical types
15917 // belonging to its scope.
15918 if (scope)
15919 {
15920 if (is_type(scope))
15921 // The scope in question is itself a type (e.g, a class
15922 // or union). Let's call that type ST. We want to add
15923 // 'canonical' to the set of canonical types belonging
15924 // to ST.
15925 if (type_base_sptr c = is_type(scope)->get_canonical_type())
15926 // We want to add 'canonical' to the set of
15927 // canonical types belonging to the canonical type
15928 // of ST. That way, just looking at the canonical
15929 // type of ST is enough to get the types that belong
15930 // to the scope of the class of equivalence of ST.
15931 scope = is_scope_decl(is_decl(c)).get();
15932 scope->get_canonical_types().insert(canonical);
15933 }
15934 // else, if the type doesn't have a scope, it's not meant to be
15935 // emitted. This can be the case for the result of the
15936 // function strip_typedef, for instance.
15937 }
15938 }
15939
15940 t->on_canonical_type_set();
15941 return canonical;
15942}
15943
15944/// Set the definition of this declaration-only @ref decl_base.
15945///
15946/// @param d the new definition to set.
15947void
15949{
15951 priv_->definition_of_declaration_ = d;
15952 if (type_base *t = is_type(this))
15953 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
15954 t->priv_->canonical_type = canonical_type;
15955
15956 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
15957}
15958
15959/// The constructor of @ref type_base.
15960///
15961/// @param s the size of the type, in bits.
15962///
15963/// @param a the alignment of the type, in bits.
15964type_base::type_base(const environment& e, size_t s, size_t a)
15965 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
15966 priv_(new priv(s, a))
15967{}
15968
15969/// Return the hash value of the current IR node.
15970///
15971/// Note that upon the first invocation, this member functions
15972/// computes the hash value and returns it. Subsequent invocations
15973/// just return the hash value that was previously calculated.
15974///
15975/// @return the hash value of the current IR node.
15976hash_t
15978{
15979 type_base::hash do_hash;
15980 return do_hash(this);
15981}
15982
15983/// Getter of the canonical type of the current instance of @ref
15984/// type_base.
15985///
15986/// @return a smart pointer to the canonical type of the current
15987/// intance of @ref type_base, or an empty smart pointer if the
15988/// current instance of @ref type_base doesn't have any canonical
15989/// type.
15990type_base_sptr
15992{return priv_->canonical_type.lock();}
15993
15994/// Getter of the canonical type pointer.
15995///
15996/// Note that this function doesn't return a smart pointer, but rather
15997/// the underlying pointer managed by the smart pointer. So it's as
15998/// fast as possible. This getter is to be used in code paths that
15999/// are proven to be performance hot spots; especially, when comparing
16000/// sensitive types like class, function, pointers and reference
16001/// types. Those are compared extremely frequently and thus, their
16002/// accessing the canonical type must be fast.
16003///
16004/// @return the canonical type pointer, not managed by a smart
16005/// pointer.
16006type_base*
16008{return priv_->naked_canonical_type;}
16009
16010/// Get the pretty representation of the current type.
16011///
16012/// The pretty representation is retrieved from a cache. If the cache
16013/// is empty, this function computes the pretty representation, put it
16014/// in the cache and returns it.
16015///
16016/// Please note that if this function is called too early in the life
16017/// cycle of the type (before the type is fully constructed), then the
16018/// pretty representation that is cached is going to represent a
16019/// non-complete (and thus wrong) representation of the type. Thus
16020/// this function must be called only once the type is fully
16021/// constructed.
16022///
16023/// @param internal if true, then the pretty representation is to be
16024/// used for purpuses that are internal to the libabigail library
16025/// itself. If you don't know what this means, then you probably
16026/// should set this parameter to "false".
16027///
16028/// @return a reference to a cached @ref interned_string holding the
16029/// pretty representation of the current type.
16030const interned_string&
16032{
16033 if (internal)
16034 {
16035 if (priv_->internal_cached_repr_.empty())
16036 {
16037 string r = ir::get_pretty_representation(this, internal);
16038 priv_->internal_cached_repr_ = get_environment().intern(r);
16039 }
16040 return priv_->internal_cached_repr_;
16041 }
16042
16043 if (priv_->cached_repr_.empty())
16044 {
16045 string r = ir::get_pretty_representation(this, internal);
16046 priv_->cached_repr_ = get_environment().intern(r);
16047 }
16048
16049 return priv_->cached_repr_;
16050}
16051
16052/// Compares two instances of @ref type_base.
16053///
16054/// If the two intances are different, set a bitfield to give some
16055/// insight about the kind of differences there are.
16056///
16057/// @param l the first artifact of the comparison.
16058///
16059/// @param r the second artifact of the comparison.
16060///
16061/// @param k a pointer to a bitfield that gives information about the
16062/// kind of changes there are between @p l and @p r. This one is set
16063/// iff @p is non-null and if the function returns false.
16064///
16065/// Please note that setting k to a non-null value does have a
16066/// negative performance impact because even if @p l and @p r are not
16067/// equal, the function keeps up the comparison in order to determine
16068/// the different kinds of ways in which they are different.
16069///
16070/// @return true if @p l equals @p r, false otherwise.
16071bool
16072equals(const type_base& l, const type_base& r, change_kind* k)
16073{
16074 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
16076 if (!result)
16077 if (k)
16079 ABG_RETURN(result);
16080}
16081
16082/// Return true iff both type declarations are equal.
16083///
16084/// Note that this doesn't test if the scopes of both types are equal.
16085bool
16087{return equals(*this, other, 0);}
16088
16089/// Inequality operator.
16090///
16091///@param other the instance of @ref type_base to compare the current
16092/// instance against.
16093///
16094/// @return true iff the current instance is different from @p other.
16095bool
16097{return !operator==(other);}
16098
16099/// Setter for the size of the type.
16100///
16101/// @param s the new size -- in bits.
16102void
16104{priv_->size_in_bits = s;}
16105
16106/// Getter for the size of the type.
16107///
16108/// @return the size in bits of the type.
16109size_t
16111{return priv_->size_in_bits;}
16112
16113/// Setter for the alignment of the type.
16114///
16115/// @param a the new alignment -- in bits.
16116void
16118{priv_->alignment_in_bits = a;}
16119
16120/// Getter for the alignment of the type.
16121///
16122/// @return the alignment of the type in bits.
16123size_t
16125{return priv_->alignment_in_bits;}
16126
16127/// Default implementation of traversal for types. This function does
16128/// nothing. It must be implemented by every single new type that is
16129/// written.
16130///
16131/// Please look at e.g, class_decl::traverse() for an example of how
16132/// to implement this.
16133///
16134/// @param v the visitor used to visit the type.
16135bool
16137{
16138 if (v.type_node_has_been_visited(this))
16139 return true;
16140
16141 v.visit_begin(this);
16142 bool result = v.visit_end(this);
16144
16145 return result;
16146}
16147
16148type_base::~type_base()
16149{delete priv_;}
16150
16151// </type_base definitions>
16152
16153// <real_type definitions>
16154
16155/// Bitwise OR operator for real_type::modifiers_type.
16156///
16157/// @param l the left-hand side operand.
16158///
16159/// @param r the right-hand side operand.
16160///
16161/// @return the result of the bitwise OR.
16164{
16165 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16166 |
16167 static_cast<unsigned>(r));
16168}
16169
16170/// Bitwise AND operator for real_type::modifiers_type.
16171///
16172/// @param l the left-hand side operand.
16173///
16174/// @param r the right-hand side operand.
16175///
16176/// @return the result of the bitwise AND.
16179{
16180 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16181 &
16182 static_cast<unsigned>(r));
16183}
16184
16185/// Bitwise one's complement operator for real_type::modifiers_type.
16186///
16187/// @param l the left-hand side operand.
16188///
16189/// @param r the right-hand side operand.
16190///
16191/// @return the result of the bitwise one's complement operator.
16194{
16195 return static_cast<real_type::modifiers_type>(~static_cast<unsigned>(l));
16196}
16197
16198/// Bitwise |= operator for real_type::modifiers_type.
16199///
16200/// @param l the left-hand side operand.
16201///
16202/// @param r the right-hand side operand.
16203///
16204/// @return the result of the bitwise |=.
16207{
16208 l = l | r;
16209 return l;
16210}
16211
16212/// Bitwise &= operator for real_type::modifiers_type.
16213///
16214/// @param l the left-hand side operand.
16215///
16216/// @param r the right-hand side operand.
16217///
16218/// @return the result of the bitwise &=.
16221{
16222 l = l & r;
16223 return l;
16224}
16225
16226/// Parse a word containing one real type modifier.
16227///
16228/// A word is considered to be a string of characters that doesn't
16229/// contain any white space.
16230///
16231/// @param word the word to parse. It is considered to be a string of
16232/// characters that doesn't contain any white space.
16233///
16234/// @param modifiers out parameter. It's set by this function to the
16235/// parsed modifier iff the function returned true.
16236///
16237/// @return true iff @word was successfully parsed.
16238static bool
16239parse_real_type_modifier(const string& word,
16240 real_type::modifiers_type &modifiers)
16241{
16242 if (word == "signed")
16243 modifiers |= real_type::SIGNED_MODIFIER;
16244 else if (word == "unsigned")
16245 modifiers |= real_type::UNSIGNED_MODIFIER;
16246 else if (word == "short")
16247 modifiers |= real_type::SHORT_MODIFIER;
16248 else if (word == "long")
16249 modifiers |= real_type::LONG_MODIFIER;
16250 else if (word == "long long")
16251 modifiers |= real_type::LONG_LONG_MODIFIER;
16252 else
16253 return false;
16254
16255 return true;
16256}
16257
16258/// Parse a base type of a real type from a string.
16259///
16260/// @param type_name the type name to parse.
16261///
16262/// @param base out parameter. This is set to the resulting base type
16263/// parsed, iff the function returned true.
16264///
16265/// @return true iff the function could successfully parse the base
16266/// type.
16267static bool
16268parse_base_real_type(const string& type_name,
16270{
16271 if (type_name == "int")
16273 else if (type_name == "char")
16275 else if (type_name == "bool" || type_name == "_Bool")
16277 else if (type_name == "double")
16279 else if (type_name =="float")
16281 else if (type_name == "char16_t")
16283 else if (type_name == "char32_t")
16285 else if (type_name == "wchar_t")
16287 else if (type_name == "__ARRAY_SIZE_TYPE__")
16289 else if (type_name == "sizetype")
16290 base = real_type::SIZE_BASE_TYPE;
16291 else if (type_name == "ssizetype")
16292 base = real_type::SSIZE_BASE_TYPE;
16293 else if (type_name == "bitsizetype")
16294 base = real_type::BIT_SIZE_BASE_TYPE;
16295 else if (type_name == "sbitsizetype")
16296 base = real_type::SBIT_SIZE_BASE_TYPE;
16297 else
16298 return false;
16299
16300 return true;
16301}
16302
16303/// Parse a real type from a string.
16304///
16305/// @param type_name the string containing the real type to parse.
16306///
16307/// @param base out parameter. Is set by this function to the base
16308/// type of the real type, iff the function returned true.
16309///
16310/// @param modifiers out parameter If set by this function to the
16311/// modifier of the real type, iff the function returned true.
16312///
16313/// @return true iff the function could parse a real type from @p
16314/// type_name.
16315static bool
16316parse_real_type(const string& type_name,
16318 real_type::modifiers_type& modifiers)
16319{
16320 string input = type_name;
16321 string::size_type len = input.length();
16322 string::size_type cur_pos = 0, prev_pos = 0;
16323 string cur_word, prev_word;
16324 bool ok = false;
16325
16326 while (cur_pos < len)
16327 {
16328 if (cur_pos < len && isspace(input[cur_pos]))
16329 do
16330 ++cur_pos;
16331 while (cur_pos < len && isspace(input[cur_pos]));
16332
16333 prev_pos = cur_pos;
16334 cur_pos = input.find(' ', prev_pos);
16335 prev_word = cur_word;
16336 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16337
16338 if (cur_pos < len
16339 && cur_word == "long"
16340 && prev_word != "long")
16341 {
16342 if (cur_pos < len && isspace(input[cur_pos]))
16343 do
16344 ++cur_pos;
16345 while (cur_pos < len && isspace(input[cur_pos]));
16346 prev_pos = cur_pos;
16347
16348 cur_pos = input.find(' ', prev_pos);
16349 string saved_prev_word = prev_word;
16350 prev_word = cur_word;
16351 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16352 if (cur_word == "long")
16353 cur_word = "long long";
16354 else
16355 {
16356 cur_pos = prev_pos;
16357 cur_word = prev_word;
16358 prev_word = saved_prev_word;
16359 }
16360 }
16361
16362 if (!parse_real_type_modifier(cur_word, modifiers))
16363 {
16364 if (!parse_base_real_type(cur_word, base))
16365 return false;
16366 else
16367 ok = true;
16368 }
16369 else
16370 ok = true;
16371 }
16372
16373 return ok;
16374}
16375
16376/// Parse a real type from a string.
16377///
16378/// @param str the string containing the real type to parse.
16379///
16380///@param type the resulting @ref real_type. Is set to the result
16381///of the parse, iff the function returns true.
16382///
16383/// @return true iff the function could parse a real type from @p
16384/// str.
16385bool
16386parse_real_type(const string& str, real_type& type)
16387{
16389 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16390
16391 if (!parse_real_type(str, base_type, modifiers))
16392 return false;
16393
16394 // So this is a real type.
16395 real_type int_type(base_type, modifiers);
16396 type = int_type;
16397 return true;
16398}
16399
16400/// Default constructor of the @ref real_type.
16402 : base_(INT_BASE_TYPE),
16403 modifiers_(NO_MODIFIER)
16404{}
16405
16406/// Constructor of the @ref real_type.
16407///
16408/// @param b the base type of the real type.
16409///
16410/// @param m the modifiers of the real type.
16412 : base_(b), modifiers_(m)
16413{}
16414
16415/// Constructor of the @ref real_type.
16416///
16417/// @param the name of the real type to parse to initialize the
16418/// current instance of @ref real_type.
16419real_type::real_type(const string& type_name)
16420 : base_(INT_BASE_TYPE),
16421 modifiers_(NO_MODIFIER)
16422{
16423 bool could_parse = parse_real_type(type_name, base_, modifiers_);
16424 ABG_ASSERT(could_parse);
16425}
16426
16427/// Getter of the base type of the @ref real_type.
16428///
16429/// @return the base type of the @ref real_type.
16432{return base_;}
16433
16434/// Getter of the modifiers bitmap of the @ref real_type.
16435///
16436/// @return the modifiers bitmap of the @ref real_type.
16439{return modifiers_;}
16440
16441/// Setter of the modifiers bitmap of the @ref real_type.
16442///
16443/// @param m the new modifiers.
16444void
16446{modifiers_ = m;}
16447
16448/// Equality operator for the @ref real_type.
16449///
16450/// @param other the other real type to compare against.
16451///
16452/// @return true iff @p other equals the current instance of @ref
16453/// real_type.
16454bool
16456{return base_ == other.base_ && modifiers_ == other.modifiers_;}
16457
16458/// Return the string representation of the current instance of @ref
16459/// real_type.
16460///
16461/// @param internal if true the string representation is to be used
16462/// for internal purposes. In general, it means it's for type
16463/// canonicalization purposes.
16464///
16465/// @return the string representation of the current instance of @ref
16466/// real_type.
16467string
16468real_type::to_string(bool internal) const
16469{
16470 string result;
16471
16472 // Look at modifiers ...
16473 if (modifiers_ & SIGNED_MODIFIER)
16474 result += "signed ";
16475 if (modifiers_ & UNSIGNED_MODIFIER)
16476 result += "unsigned ";
16477 if (!internal)
16478 {
16479 // For canonicalization purposes, we won't emit the "short, long, or
16480 // long long" modifiers. This is because on some platforms, "long
16481 // int" and "long long int" might have the same size. In those
16482 // cases, we want the two types to be equivalent if they have the
16483 // same size. If they don't have the same internal string
16484 // representation, they'd automatically have different canonical
16485 // types and thus be canonically different.
16486 if (modifiers_ & SHORT_MODIFIER)
16487 result += "short ";
16488 if (modifiers_ & LONG_MODIFIER)
16489 result += "long ";
16490 if (modifiers_ & LONG_LONG_MODIFIER)
16491 result += "long long ";
16492 }
16493
16494 // ... and look at base types.
16495 if (base_ == INT_BASE_TYPE)
16496 result += "int";
16497 else if (base_ == CHAR_BASE_TYPE)
16498 result += "char";
16499 else if (base_ == BOOL_BASE_TYPE)
16500 result += "bool";
16501 else if (base_ == DOUBLE_BASE_TYPE)
16502 result += "double";
16503 else if (base_ == FLOAT_BASE_TYPE)
16504 result += "float";
16505 else if (base_ == CHAR16_T_BASE_TYPE)
16506 result += "char16_t";
16507 else if (base_ == CHAR32_T_BASE_TYPE)
16508 result += "char32_t";
16509 else if (base_ == WCHAR_T_BASE_TYPE)
16510 result += "wchar_t";
16511 else if (base_ == ARRAY_SIZE_BASE_TYPE)
16512 result += "__ARRAY_SIZE_TYPE__";
16513 else if (base_ == SIZE_BASE_TYPE)
16514 result += "sizetype";
16515 else if (base_ == SSIZE_BASE_TYPE)
16516 result += "ssizetype";
16517 else if (base_ == BIT_SIZE_BASE_TYPE)
16518 result += "bitsizetype";
16519 else if (base_ == SBIT_SIZE_BASE_TYPE)
16520 result += "sbitsizetype";
16521 return result;
16522}
16523
16524/// Convert the current instance of @ref real_type into its string
16525/// representation.
16526///
16527/// @return the string representation of the current instance of @ref
16528/// real_type.
16529real_type::operator string() const
16530{return to_string();}
16531
16532// </real_type definitions>
16533
16534//<type_decl definitions>
16535
16536/// Constructor.
16537///
16538/// @param env the environment we are operating from.
16539///
16540/// @param name the name of the type declaration.
16541///
16542/// @param size_in_bits the size of the current type_decl, in bits.
16543///
16544/// @param alignment_in_bits the alignment of the current typ, in
16545/// bits.
16546///
16547/// @param locus the source location of the current type declaration.
16548///
16549/// @param linkage_name the linkage_name of the current type declaration.
16550///
16551/// @param vis the visibility of the type declaration.
16552type_decl::type_decl(const environment& env,
16553 const string& name,
16554 size_t size_in_bits,
16555 size_t alignment_in_bits,
16556 const location& locus,
16557 const string& linkage_name,
16558 visibility vis)
16559
16560 : type_or_decl_base(env,
16561 BASIC_TYPE
16562 | ABSTRACT_TYPE_BASE
16563 | ABSTRACT_DECL_BASE),
16564 decl_base(env, name, locus, linkage_name, vis),
16565 type_base(env, size_in_bits, alignment_in_bits)
16566{
16568
16570 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16571 real_type int_type(base_type, modifiers);
16572 if (parse_real_type(name, int_type))
16573 {
16574 // Convert the real_type into its canonical string
16575 // representation.
16576 string real_type_name = int_type;
16577
16578 // Set the name of this type_decl to the canonical string
16579 // representation above
16580 set_name(real_type_name);
16582
16583 if (!get_linkage_name().empty())
16584 set_linkage_name(real_type_name);
16585 }
16586}
16587
16588/// Return the hash value of the current IR node.
16589///
16590/// Note that upon the first invocation, this member functions
16591/// computes the hash value and returns it. Subsequent invocations
16592/// just return the hash value that was previously calculated.
16593///
16594/// @return the hash value of the current IR node.
16595hash_t
16597{
16599 return h;
16600}
16601
16602/// Compares two instances of @ref type_decl.
16603///
16604/// If the two intances are different, set a bitfield to give some
16605/// insight about the kind of differences there are.
16606///
16607/// @param l the first artifact of the comparison.
16608///
16609/// @param r the second artifact of the comparison.
16610///
16611/// @param k a pointer to a bitfield that gives information about the
16612/// kind of changes there are between @p l and @p r. This one is set
16613/// iff @p k is non-null and the function returns false.
16614///
16615/// Please note that setting k to a non-null value does have a
16616/// negative performance impact because even if @p l and @p r are not
16617/// equal, the function keeps up the comparison in order to determine
16618/// the different kinds of ways in which they are different.
16619///
16620/// @return true if @p l equals @p r, false otherwise.
16621bool
16622equals(const type_decl& l, const type_decl& r, change_kind* k)
16623{
16624 bool result = false;
16625
16626 // Consider the types as decls to compare their decls-related
16627 // properties.
16628 result = equals(static_cast<const decl_base&>(l),
16629 static_cast<const decl_base&>(r),
16630 k);
16631 if (!k && !result)
16633
16634 // Now consider the types a "types' to compare their size-related
16635 // properties.
16636 result &= equals(static_cast<const type_base&>(l),
16637 static_cast<const type_base&>(r),
16638 k);
16639 ABG_RETURN(result);
16640}
16641
16642/// Return true if both types equals.
16643///
16644/// This operator re-uses the overload that takes a decl_base.
16645///
16646/// Note that this does not check the scopes of any of the types.
16647///
16648/// @param o the other type_decl to check agains.
16649bool
16651{
16652 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16653 if (!other)
16654 return false;
16655 return *this == *other;
16656}
16657
16658/// Return true if both types equals.
16659///
16660/// Note that this does not check the scopes of any of the types.
16661///
16662/// @param o the other type_decl to check against.
16663bool
16665{
16666 const type_decl* other = dynamic_cast<const type_decl*>(&o);
16667 if (!other)
16668 return false;
16669 return try_canonical_compare(this, other);
16670}
16671
16672/// Return true if both types equals.
16673///
16674/// Note that this does not check the scopes of any of the types.
16675///
16676/// @param o the other type_decl to check against.
16677///
16678/// @return true iff the current isntance equals @p o
16679bool
16681{
16682 const decl_base& other = o;
16683 return *this == other;
16684}
16685
16686/// Return true if both types equals.
16687///
16688/// Note that this does not check the scopes of any of the types.
16689///
16690/// @param o the other type_decl to check against.
16691///
16692/// @return true iff the current isntance equals @p o
16693bool
16695{return !operator==(o);}
16696
16697/// Return true if both types equals.
16698///
16699/// Note that this does not check the scopes of any of the types.
16700///
16701/// @param o the other type_decl to check against.
16702///
16703/// @return true iff the current isntance equals @p o
16704bool
16706{return !operator==(o);}
16707
16708/// Inequality operator.
16709///
16710/// @param o the other type to compare against.
16711///
16712/// @return true iff the current instance is different from @p o.
16713bool
16715{return !operator==(o);}
16716
16717/// Equality operator for @ref type_decl_sptr.
16718///
16719/// @param l the first operand to compare.
16720///
16721/// @param r the second operand to compare.
16722///
16723/// @return true iff @p l equals @p r.
16724bool
16726{
16727 if (!!l != !!r)
16728 return false;
16729 if (l.get() == r.get())
16730 return true;
16731 return *l == *r;
16732}
16733
16734/// Inequality operator for @ref type_decl_sptr.
16735///
16736/// @param l the first operand to compare.
16737///
16738/// @param r the second operand to compare.
16739///
16740/// @return true iff @p l is different from @p r.
16741bool
16743{return !operator==(l, r);}
16744
16745/// Implementation for the virtual qualified name builder for @ref
16746/// type_decl.
16747///
16748/// @param qualified_name the output parameter to hold the resulting
16749/// qualified name.
16750///
16751/// @param internal set to true if the call is intended for an
16752/// internal use (for technical use inside the library itself), false
16753/// otherwise. If you don't know what this is for, then set it to
16754/// false.
16755void
16757 bool internal) const
16758{qualified_name = get_qualified_name(internal);}
16759
16760/// Implementation for the virtual qualified name builder for @ref
16761/// type_decl.
16762///
16763/// @param qualified_name the output parameter to hold the resulting
16764/// qualified name.
16765///
16766/// @param internal set to true if the call is intended for an
16767/// internal use (for technical use inside the library itself), false
16768/// otherwise. If you don't know what this is for, then set it to
16769/// false.
16770const interned_string&
16772{
16773 const environment& env = get_environment();
16774
16775
16776 if (internal)
16777 if (is_real_type(this))
16778 {
16780 {
16781 if (decl_base::priv_->internal_qualified_name_.empty())
16782 decl_base::priv_->internal_qualified_name_ =
16783 env.intern(get_internal_real_type_name(this));
16784 return decl_base::priv_->internal_qualified_name_;
16785 }
16786 else
16787 {
16788 decl_base::priv_->temporary_internal_qualified_name_ =
16789 env.intern(get_internal_real_type_name(this));
16790 return decl_base::priv_->temporary_internal_qualified_name_;
16791 }
16792 }
16793
16794 return decl_base::get_qualified_name(/*internal=*/false);
16795}
16796
16797/// Get the pretty representation of the current instance of @ref
16798/// type_decl.
16799///
16800/// @param internal set to true if the call is intended to get a
16801/// representation of the decl (or type) for the purpose of canonical
16802/// type comparison. This is mainly used in the function
16803/// type_base::get_canonical_type_for().
16804///
16805/// In other words if the argument for this parameter is true then the
16806/// call is meant for internal use (for technical use inside the
16807/// library itself), false otherwise. If you don't know what this is
16808/// for, then set it to false.
16809///
16810/// @param qualified_name if true, names emitted in the pretty
16811/// representation are fully qualified.
16812///
16813/// @return the pretty representatin of the @ref type_decl.
16814string
16816 bool qualified_name) const
16817{
16818 if (internal)
16819 if (is_real_type(this))
16820 return get_internal_real_type_name(this);
16821
16822 if (qualified_name)
16823 return get_qualified_name(internal);
16824 return get_name();
16825}
16826
16827/// This implements the ir_traversable_base::traverse pure virtual
16828/// function.
16829///
16830/// @param v the visitor used on the current instance.
16831///
16832/// @return true if the entire IR node tree got traversed, false
16833/// otherwise.
16834bool
16836{
16837 if (v.type_node_has_been_visited(this))
16838 return true;
16839
16840 v.visit_begin(this);
16841 bool result = v.visit_end(this);
16843
16844 return result;
16845}
16846
16847type_decl::~type_decl()
16848{}
16849//</type_decl definitions>
16850
16851// <scope_type_decl definitions>
16852
16853/// Constructor.
16854///
16855/// @param env the environment we are operating from.
16856///
16857/// @param name the name of the type.
16858///
16859/// @param size_in_bits the size of the type, in bits.
16860///
16861/// @param alignment_in_bits the alignment of the type, in bits.
16862///
16863/// @param locus the source location where the type is defined.
16864///
16865/// @param vis the visibility of the type.
16866scope_type_decl::scope_type_decl(const environment& env,
16867 const string& name,
16868 size_t size_in_bits,
16869 size_t alignment_in_bits,
16870 const location& locus,
16871 visibility vis)
16872 : type_or_decl_base(env,
16873 ABSTRACT_SCOPE_TYPE_DECL
16874 | ABSTRACT_TYPE_BASE
16875 | ABSTRACT_DECL_BASE),
16876 decl_base(env, name, locus, "", vis),
16877 type_base(env, size_in_bits, alignment_in_bits),
16878 scope_decl(env, name, locus)
16879{}
16880
16881/// Compares two instances of @ref scope_type_decl.
16882///
16883/// If the two intances are different, set a bitfield to give some
16884/// insight about the kind of differences there are.
16885///
16886/// @param l the first artifact of the comparison.
16887///
16888/// @param r the second artifact of the comparison.
16889///
16890/// @param k a pointer to a bitfield that gives information about the
16891/// kind of changes there are between @p l and @p r. This one is set
16892/// iff @p k is non-null and the function returns false.
16893///
16894/// Please note that setting k to a non-null value does have a
16895/// negative performance impact because even if @p l and @p r are not
16896/// equal, the function keeps up the comparison in order to determine
16897/// the different kinds of ways in which they are different.
16898///
16899/// @return true if @p l equals @p r, false otherwise.
16900bool
16902{
16903 bool result = equals(static_cast<const scope_decl&>(l),
16904 static_cast<const scope_decl&>(r),
16905 k);
16906
16907 if (!k && !result)
16909
16910 result &= equals(static_cast<const type_base&>(l),
16911 static_cast<const type_base&>(r),
16912 k);
16913
16914 ABG_RETURN(result);
16915}
16916
16917/// Equality operator between two scope_type_decl.
16918///
16919/// Note that this function does not consider the scope of the scope
16920/// types themselves.
16921///
16922/// @return true iff both scope types are equal.
16923bool
16925{
16926 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
16927 if (!other)
16928 return false;
16929 return try_canonical_compare(this, other);
16930}
16931
16932/// Equality operator between two scope_type_decl.
16933///
16934/// This re-uses the equality operator that takes a decl_base.
16935///
16936/// @param o the other scope_type_decl to compare against.
16937///
16938/// @return true iff both scope types are equal.
16939bool
16941{
16942 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16943 if (!other)
16944 return false;
16945
16946 return *this == *other;
16947}
16948
16949/// Traverses an instance of @ref scope_type_decl, visiting all the
16950/// sub-types and decls that it might contain.
16951///
16952/// @param v the visitor that is used to visit every IR sub-node of
16953/// the current node.
16954///
16955/// @return true if either
16956/// - all the children nodes of the current IR node were traversed
16957/// and the calling code should keep going with the traversing.
16958/// - or the current IR node is already being traversed.
16959/// Otherwise, returning false means that the calling code should not
16960/// keep traversing the tree.
16961bool
16963{
16964 if (visiting())
16965 return true;
16966
16967 if (v.type_node_has_been_visited(this))
16968 return true;
16969
16970 if (v.visit_begin(this))
16971 {
16972 visiting(true);
16973 for (scope_decl::declarations::const_iterator i =
16974 get_member_decls().begin();
16975 i != get_member_decls ().end();
16976 ++i)
16977 if (!(*i)->traverse(v))
16978 break;
16979 visiting(false);
16980 }
16981
16982 bool result = v.visit_end(this);
16984
16985 return result;
16986}
16987
16988scope_type_decl::~scope_type_decl()
16989{}
16990// </scope_type_decl definitions>
16991
16992// <namespace_decl>
16993
16994/// Constructor.
16995///
16996/// @param the environment we are operatin from.
16997///
16998/// @param name the name of the namespace.
16999///
17000/// @param locus the source location where the namespace is defined.
17001///
17002/// @param vis the visibility of the namespace.
17004 const string& name,
17005 const location& locus,
17006 visibility vis)
17007 // We need to call the constructor of decl_base directly here
17008 // because it is virtually inherited by scope_decl. Note that we
17009 // just implicitely call the default constructor for scope_decl
17010 // here, as what we really want is to initialize the decl_base
17011 // subobject. Wow, virtual inheritance is useful, but setting it
17012 // up is ugly.
17013 : type_or_decl_base(env,
17014 NAMESPACE_DECL
17015 | ABSTRACT_DECL_BASE
17016 | ABSTRACT_SCOPE_DECL),
17017 decl_base(env, name, locus, "", vis),
17018 scope_decl(env, name, locus)
17019{
17021}
17022
17023/// Build and return a copy of the pretty representation of the
17024/// namespace.
17025///
17026/// @param internal set to true if the call is intended to get a
17027/// representation of the decl (or type) for the purpose of canonical
17028/// type comparison. This is mainly used in the function
17029/// type_base::get_canonical_type_for().
17030///
17031/// In other words if the argument for this parameter is true then the
17032/// call is meant for internal use (for technical use inside the
17033/// library itself), false otherwise. If you don't know what this is
17034/// for, then set it to false.
17035///
17036/// @param qualified_name if true, names emitted in the pretty
17037/// representation are fully qualified.
17038///
17039/// @return a copy of the pretty representation of the namespace.
17040string
17042 bool qualified_name) const
17043{
17044 string r =
17045 "namespace " + scope_decl::get_pretty_representation(internal,
17046 qualified_name);
17047 return r;
17048}
17049
17050/// Return true iff both namespaces and their members are equal.
17051///
17052/// Note that this function does not check if the scope of these
17053/// namespaces are equal.
17054bool
17056{
17057 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
17058 if (!other)
17059 return false;
17060 return scope_decl::operator==(*other);
17061}
17062
17063/// Test if the current namespace_decl is empty or contains empty
17064/// namespaces itself.
17065///
17066/// @return true iff the current namespace_decl is empty or contains
17067/// empty itself.
17068bool
17070{
17071 if (is_empty())
17072 return true;
17073
17074 for (declarations::const_iterator i = get_member_decls().begin();
17075 i != get_member_decls().end();
17076 ++i)
17077 {
17078 if (!is_namespace(*i))
17079 return false;
17080
17082 ABG_ASSERT(ns);
17083
17084 if (!ns->is_empty_or_has_empty_sub_namespaces())
17085 return false;
17086 }
17087
17088 return true;
17089}
17090
17091/// This implements the ir_traversable_base::traverse pure virtual
17092/// function.
17093///
17094/// @param v the visitor used on the current instance and on its
17095/// member nodes.
17096///
17097/// @return true if the entire IR node tree got traversed, false
17098/// otherwise.
17099bool
17101{
17102 if (visiting())
17103 return true;
17104
17105 if (v.visit_begin(this))
17106 {
17107 visiting(true);
17108 scope_decl::declarations::const_iterator i;
17109 for (i = get_member_decls().begin();
17110 i != get_member_decls ().end();
17111 ++i)
17112 {
17114 dynamic_pointer_cast<ir_traversable_base>(*i);
17115 if (t)
17116 if (!t->traverse (v))
17117 break;
17118 }
17119 visiting(false);
17120 }
17121 return v.visit_end(this);
17122}
17123
17124namespace_decl::~namespace_decl()
17125{
17126}
17127
17128// </namespace_decl>
17129
17130// <qualified_type_def>
17131
17132/// Type of the private data of qualified_type_def.
17133class qualified_type_def::priv
17134{
17135 friend class qualified_type_def;
17136
17137 qualified_type_def::CV cv_quals_;
17138 // Before the type is canonicalized, this is used as a temporary
17139 // internal name.
17140 interned_string temporary_internal_name_;
17141 // Once the type is canonicalized, this is used as the internal
17142 // name.
17143 interned_string internal_name_;
17144 weak_ptr<type_base> underlying_type_;
17145
17146 priv()
17147 : cv_quals_(CV_NONE)
17148 {}
17149
17150 priv(qualified_type_def::CV quals,
17151 type_base_sptr t)
17152 : cv_quals_(quals),
17153 underlying_type_(t)
17154 {}
17155
17156 priv(qualified_type_def::CV quals)
17157 : cv_quals_(quals)
17158 {}
17159};// end class qualified_type_def::priv
17160
17161/// Build the name of the current instance of qualified type.
17162///
17163/// @param fully_qualified if true, build a fully qualified name.
17164///
17165/// @param internal set to true if the call is intended for an
17166/// internal use (for technical use inside the library itself), false
17167/// otherwise. If you don't know what this is for, then set it to
17168/// false.
17169///
17170/// @return a copy of the newly-built name.
17171string
17172qualified_type_def::build_name(bool fully_qualified, bool internal) const
17173{
17174 type_base_sptr t = get_underlying_type();
17175 if (!t)
17176 // The qualified type might temporarily have no underlying type,
17177 // especially during the construction of the type, while the
17178 // underlying type is not yet constructed. In that case, let's do
17179 // like if the underlying type is the 'void' type.
17181
17183 fully_qualified,
17184 internal);
17185}
17186
17187/// This function is automatically invoked whenever an instance of
17188/// this type is canonicalized.
17189///
17190/// It's an overload of the virtual type_base::on_canonical_type_set.
17191///
17192/// We put here what is thus meant to be executed only at the point of
17193/// type canonicalization.
17194void
17197
17198/// Constructor of the qualified_type_def
17199///
17200/// @param type the underlying type
17201///
17202/// @param quals a bitfield representing the const/volatile qualifiers
17203///
17204/// @param locus the location of the qualified type definition
17205qualified_type_def::qualified_type_def(type_base_sptr type,
17206 CV quals,
17207 const location& locus)
17208 : type_or_decl_base(type->get_environment(),
17209 QUALIFIED_TYPE
17210 | ABSTRACT_TYPE_BASE
17211 | ABSTRACT_DECL_BASE),
17212 type_base(type->get_environment(), type->get_size_in_bits(),
17213 type->get_alignment_in_bits()),
17214 decl_base(type->get_environment(), "", locus, "",
17215 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
17216 priv_(new priv(quals, type))
17217{
17219 interned_string name = type->get_environment().intern(build_name(false));
17220 set_name(name);
17221}
17222
17223/// Constructor of the qualified_type_def
17224///
17225/// @param env the environment of the type.
17226///
17227/// @param quals a bitfield representing the const/volatile qualifiers
17228///
17229/// @param locus the location of the qualified type definition
17230qualified_type_def::qualified_type_def(const environment& env,
17231 CV quals,
17232 const location& locus)
17233 : type_or_decl_base(env,
17234 QUALIFIED_TYPE
17235 | ABSTRACT_TYPE_BASE
17236 | ABSTRACT_DECL_BASE),
17237 type_base(env, /*size_in_bits=*/0,
17238 /*alignment_in_bits=*/0),
17239 decl_base(env, "", locus, ""),
17240 priv_(new priv(quals))
17241{
17243 // We don't yet have an underlying type. So for naming purpose,
17244 // let's temporarily pretend the underlying type is 'void'.
17245 interned_string name = env.intern("void");
17246 set_name(name);
17247}
17248
17249/// Return the hash value of the current IR node.
17250///
17251/// Note that upon the first invocation, this member functions
17252/// computes the hash value and returns it. Subsequent invocations
17253/// just return the hash value that was previously calculated.
17254///
17255/// @return the hash value of the current IR node.
17256hash_t
17258{
17260 return h;
17261}
17262
17263/// Get the size of the qualified type def.
17264///
17265/// This is an overload for type_base::get_size_in_bits().
17266///
17267/// @return the size of the qualified type.
17268size_t
17270{
17271 size_t s = 0;
17272 if (type_base_sptr ut = get_underlying_type())
17273 {
17274 // We do have the underlying type properly set, so let's make
17275 // the size of the qualified type match the size of its
17276 // underlying type.
17277 s = ut->get_size_in_bits();
17278 if (s != type_base::get_size_in_bits())
17279 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
17280 }
17282}
17283
17284/// Compares two instances of @ref qualified_type_def.
17285///
17286/// If the two intances are different, set a bitfield to give some
17287/// insight about the kind of differences there are.
17288///
17289/// @param l the first artifact of the comparison.
17290///
17291/// @param r the second artifact of the comparison.
17292///
17293/// @param k a pointer to a bitfield that gives information about the
17294/// kind of changes there are between @p l and @p r. This one is set
17295/// iff @p k is non-null and the function returns false.
17296///
17297/// Please note that setting k to a non-null value does have a
17298/// negative performance impact because even if @p l and @p r are not
17299/// equal, the function keeps up the comparison in order to determine
17300/// the different kinds of ways in which they are different.
17301///
17302/// @return true if @p l equals @p r, false otherwise.
17303bool
17305{
17306 bool result = true;
17307 if (l.get_cv_quals() != r.get_cv_quals())
17308 {
17309 result = false;
17310 if (k)
17312 else
17314 }
17315
17317 {
17318 result = false;
17319 if (k)
17320 {
17322 r.get_underlying_type().get()))
17323 // Underlying type changes in which the structure of the
17324 // type changed are considered local changes to the
17325 // qualified type.
17327 else
17328 *k |= SUBTYPE_CHANGE_KIND;
17329 }
17330 else
17331 // okay strictly speaking this is not necessary, but I am
17332 // putting it here to maintenance; that is, so that adding
17333 // subsequent clauses needed to compare two qualified types
17334 // later still works.
17336 }
17337
17338 ABG_RETURN(result);
17339}
17340
17341/// Equality operator for qualified types.
17342///
17343/// Note that this function does not check for equality of the scopes.
17344///
17345///@param o the other qualified type to compare against.
17346///
17347/// @return true iff both qualified types are equal.
17348bool
17350{
17351 const qualified_type_def* other =
17352 dynamic_cast<const qualified_type_def*>(&o);
17353 if (!other)
17354 return false;
17355 return try_canonical_compare(this, other);
17356}
17357
17358/// Equality operator for qualified types.
17359///
17360/// Note that this function does not check for equality of the scopes.
17361/// Also, this re-uses the equality operator above that takes a
17362/// decl_base.
17363///
17364///@param o the other qualified type to compare against.
17365///
17366/// @return true iff both qualified types are equal.
17367bool
17369{
17370 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17371 if (!other)
17372 return false;
17373 return *this == *other;
17374}
17375
17376/// Equality operator for qualified types.
17377///
17378/// Note that this function does not check for equality of the scopes.
17379/// Also, this re-uses the equality operator above that takes a
17380/// decl_base.
17381///
17382///@param o the other qualified type to compare against.
17383///
17384/// @return true iff both qualified types are equal.
17385bool
17387{
17388 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17389 if (!other)
17390 return false;
17391 return *this == *other;
17392}
17393
17394/// Implementation for the virtual qualified name builder for @ref
17395/// qualified_type_def.
17396///
17397/// @param qualified_name the output parameter to hold the resulting
17398/// qualified name.
17399///
17400/// @param internal set to true if the call is intended for an
17401/// internal use (for technical use inside the library itself), false
17402/// otherwise. If you don't know what this is for, then set it to
17403/// false.
17404void
17406 bool internal) const
17407{qualified_name = get_qualified_name(internal);}
17408
17409/// Implementation of the virtual qualified name builder/getter.
17410///
17411/// @param internal set to true if the call is intended for an
17412/// internal use (for technical use inside the library itself), false
17413/// otherwise. If you don't know what this is for, then set it to
17414/// false.
17415///
17416/// @return the resulting qualified name.
17417const interned_string&
17419{
17420 const environment& env = get_environment();
17421
17422
17423 if (!get_canonical_type())
17424 {
17425 // The type hasn't been canonicalized yet. We want to return a
17426 // temporary name that is not cached because the structure of
17427 // this type (and so its name) can change until its
17428 // canonicalized.
17429 if (internal)
17430 {
17431 // We are asked to return a temporary *internal* name.
17432 // Lets compute it and return a reference to where it's
17433 // stored.
17434 if (priv_->temporary_internal_name_.empty())
17435 priv_->temporary_internal_name_ =
17436 env.intern(build_name(true, /*internal=*/true));
17437 return priv_->temporary_internal_name_;
17438 }
17439 else
17440 {
17441 // We are asked to return a temporary non-internal name.
17443 (env.intern(build_name(true, /*internal=*/false)));
17445 }
17446 }
17447 else
17448 {
17449 // The type has already been canonicalized. We want to return
17450 // the definitive name and cache it.
17451 if (internal)
17452 {
17453 if (priv_->internal_name_.empty())
17454 priv_->internal_name_ =
17455 env.intern(build_name(/*qualified=*/true,
17456 /*internal=*/true));
17457 return priv_->internal_name_;
17458 }
17459 else
17460 {
17461 if (peek_qualified_name().empty())
17463 (env.intern(build_name(/*qualified=*/true,
17464 /*internal=*/false)));
17465 return peek_qualified_name();
17466 }
17467 }
17468}
17469
17470/// This implements the ir_traversable_base::traverse pure virtual
17471/// function.
17472///
17473/// @param v the visitor used on the current instance.
17474///
17475/// @return true if the entire IR node tree got traversed, false
17476/// otherwise.
17477bool
17479{
17480 if (v.type_node_has_been_visited(this))
17481 return true;
17482
17483 if (visiting())
17484 return true;
17485
17486 if (v.visit_begin(this))
17487 {
17488 visiting(true);
17489 if (type_base_sptr t = get_underlying_type())
17490 t->traverse(v);
17491 visiting(false);
17492 }
17493 bool result = v.visit_end(this);
17495 return result;
17496}
17497
17498qualified_type_def::~qualified_type_def()
17499{
17500}
17501
17502/// Getter of the const/volatile qualifier bit field
17505{return priv_->cv_quals_;}
17506
17507/// Setter of the const/value qualifiers bit field
17508void
17510{priv_->cv_quals_ = cv_quals;}
17511
17512/// Compute and return the string prefix or suffix representing the
17513/// qualifiers hold by the current instance of @ref
17514/// qualified_type_def.
17515///
17516/// @return the newly-built cv string.
17517string
17520
17521/// Getter of the underlying type
17522type_base_sptr
17524{return priv_->underlying_type_.lock();}
17525
17526/// Setter of the underlying type.
17527///
17528/// @param t the new underlying type.
17529void
17531{
17532 ABG_ASSERT(t);
17533 priv_->underlying_type_ = t;
17534 // Now we need to update other properties that depend on the new underlying type.
17535 set_size_in_bits(t->get_size_in_bits());
17536 set_alignment_in_bits(t->get_alignment_in_bits());
17538 set_name(name);
17539 if (scope_decl* s = get_scope())
17540 {
17541 // Now that the name has been updated, we need to update the
17542 // lookup maps accordingly.
17543 scope_decl::declarations::iterator i;
17544 if (s->find_iterator_for_member(this, i))
17546 else
17548 }
17549}
17550
17551/// Non-member equality operator for @ref qualified_type_def
17552///
17553/// @param l the left-hand side of the equality operator
17554///
17555/// @param r the right-hand side of the equality operator
17556///
17557/// @return true iff @p l and @p r equals.
17558bool
17559operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17560{
17561 if (l.get() == r.get())
17562 return true;
17563 if (!!l != !!r)
17564 return false;
17565
17566 return *l == *r;
17567}
17568
17569/// Non-member inequality operator for @ref qualified_type_def
17570///
17571/// @param l the left-hand side of the equality operator
17572///
17573/// @param r the right-hand side of the equality operator
17574///
17575/// @return true iff @p l and @p r equals.
17576bool
17577operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17578{return ! operator==(l, r);}
17579
17580/// Overloaded bitwise OR operator for cv qualifiers.
17583{
17584 return static_cast<qualified_type_def::CV>
17585 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
17586}
17587
17588/// Overloaded bitwise |= operator for cv qualifiers.
17591{
17592 l = l | r;
17593 return l;
17594}
17595
17596/// Overloaded bitwise &= operator for cv qualifiers.
17599{
17600 l = l & r;
17601 return l;
17602}
17603
17604/// Overloaded bitwise AND operator for CV qualifiers.
17607{
17608 return static_cast<qualified_type_def::CV>
17609 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
17610}
17611
17612/// Overloaded bitwise inverting operator for CV qualifiers.
17615{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
17616
17617/// Streaming operator for qualified_type_decl::CV
17618///
17619/// @param o the output stream to serialize the cv qualifier to.
17620///
17621/// @param cv the cv qualifier to serialize.
17622///
17623/// @return the output stream used.
17624std::ostream&
17625operator<<(std::ostream& o, qualified_type_def::CV cv)
17626{
17627 string str;
17628
17629 switch (cv)
17630 {
17631 case qualified_type_def::CV_NONE:
17632 str = "none";
17633 break;
17634 case qualified_type_def::CV_CONST:
17635 str = "const";
17636 break;
17637 case qualified_type_def::CV_VOLATILE:
17638 str = "volatile";
17639 break;
17640 case qualified_type_def::CV_RESTRICT:
17641 str = "restrict";
17642 break;
17643 }
17644
17645 o << str;
17646 return o;
17647}
17648
17649// </qualified_type_def>
17650
17651//<pointer_type_def definitions>
17652
17653/// Private data structure of the @ref pointer_type_def.
17654struct pointer_type_def::priv
17655{
17656 type_base_wptr pointed_to_type_;
17657 type_base* naked_pointed_to_type_;
17658 interned_string internal_qualified_name_;
17659 interned_string temp_internal_qualified_name_;
17660
17661 priv(const type_base_sptr& t)
17662 : pointed_to_type_(type_or_void(t, t->get_environment())),
17663 naked_pointed_to_type_(t.get())
17664 {}
17665
17666 priv()
17667 : naked_pointed_to_type_()
17668 {}
17669}; //end struct pointer_type_def
17670
17671/// This function is automatically invoked whenever an instance of
17672/// this type is canonicalized.
17673///
17674/// It's an overload of the virtual type_base::on_canonical_type_set.
17675///
17676/// We put here what is thus meant to be executed only at the point of
17677/// type canonicalization.
17678void
17681
17682
17683///Constructor of @ref pointer_type_def.
17684///
17685/// @param pointed_to the pointed-to type.
17686///
17687/// @param size_in_bits the size of the type, in bits.
17688///
17689/// @param align_in_bits the alignment of the type, in bits.
17690///
17691/// @param locus the source location where the type was defined.
17692pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
17693 size_t size_in_bits,
17694 size_t align_in_bits,
17695 const location& locus)
17696 : type_or_decl_base(pointed_to->get_environment(),
17697 POINTER_TYPE
17698 | ABSTRACT_TYPE_BASE
17699 | ABSTRACT_DECL_BASE),
17700 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17701 decl_base(pointed_to->get_environment(), "", locus, ""),
17702 priv_(new priv(pointed_to))
17703{
17705 try
17706 {
17707 ABG_ASSERT(pointed_to);
17708 const environment& env = pointed_to->get_environment();
17709 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
17710 string name = (pto ? pto->get_name() : string("void")) + "*";
17711 set_name(env.intern(name));
17712 if (pto)
17713 set_visibility(pto->get_visibility());
17714 }
17715 catch (...)
17716 {}
17717}
17718
17719///Constructor of @ref pointer_type_def.
17720///
17721/// @param env the environment of the type.
17722///
17723/// @param size_in_bits the size of the type, in bits.
17724///
17725/// @param align_in_bits the alignment of the type, in bits.
17726///
17727/// @param locus the source location where the type was defined.
17728pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
17729 size_t alignment_in_bits,
17730 const location& locus)
17731 : type_or_decl_base(env,
17732 POINTER_TYPE
17733 | ABSTRACT_TYPE_BASE
17734 | ABSTRACT_DECL_BASE),
17735 type_base(env, size_in_bits, alignment_in_bits),
17736 decl_base(env, "", locus, ""),
17737 priv_(new priv())
17738{
17740 string name = string("void") + "*";
17741 set_name(env.intern(name));
17742}
17743
17744/// Return the hash value of the current IR node.
17745///
17746/// Note that upon the first invocation, this member functions
17747/// computes the hash value and returns it. Subsequent invocations
17748/// just return the hash value that was previously calculated.
17749///
17750/// @return the hash value of the current IR node.
17751hash_t
17753{
17755 return h;
17756}
17757
17758/// Set the pointed-to type of the pointer.
17759///
17760/// @param t the new pointed-to type.
17761void
17763{
17764 ABG_ASSERT(t);
17765 priv_->pointed_to_type_ = t;
17766 priv_->naked_pointed_to_type_ = t.get();
17767
17768 try
17769 {
17770 const environment& env = t->get_environment();
17771 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
17772 string name = (pto ? pto->get_name() : string("void")) + "*";
17773 set_name(env.intern(name));
17774 if (pto)
17775 set_visibility(pto->get_visibility());
17776 }
17777 catch (...)
17778 {}
17779}
17780
17781/// Compares two instances of @ref pointer_type_def.
17782///
17783/// If the two intances are different, set a bitfield to give some
17784/// insight about the kind of differences there are.
17785///
17786/// @param l the first artifact of the comparison.
17787///
17788/// @param r the second artifact of the comparison.
17789///
17790/// @param k a pointer to a bitfield that gives information about the
17791/// kind of changes there are between @p l and @p r. This one is set
17792/// iff @p k is non-null and the function returns false.
17793///
17794/// Please note that setting k to a non-null value does have a
17795/// negative performance impact because even if @p l and @p r are not
17796/// equal, the function keeps up the comparison in order to determine
17797/// the different kinds of ways in which they are different.
17798///
17799/// @return true if @p l equals @p r, false otherwise.
17800bool
17802{
17803 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
17804 bool result = p1 == p2;
17805 if (!result)
17806 if (k)
17807 {
17808 if (!types_have_similar_structure(&l, &r))
17809 // pointed-to type changes in which the structure of the
17810 // type changed are considered local changes to the pointer
17811 // type.
17813 *k |= SUBTYPE_CHANGE_KIND;
17814 }
17815
17816 ABG_RETURN(result);
17817}
17818
17819/// Return true iff both instances of pointer_type_def are equal.
17820///
17821/// Note that this function does not check for the scopes of the this
17822/// types.
17823bool
17825{
17826 const pointer_type_def* other = is_pointer_type(&o);
17827 if (!other)
17828 return false;
17829 return try_canonical_compare(this, other);
17830}
17831
17832/// Return true iff both instances of pointer_type_def are equal.
17833///
17834/// Note that this function does not check for the scopes of the
17835/// types.
17836///
17837/// @param other the other type to compare against.
17838///
17839/// @return true iff @p other equals the current instance.
17840bool
17842{
17843 const decl_base* o = is_decl(&other);
17844 if (!o)
17845 return false;
17846 return *this == *o;
17847}
17848
17849/// Return true iff both instances of pointer_type_def are equal.
17850///
17851/// Note that this function does not check for the scopes of the
17852/// types.
17853///
17854/// @param other the other type to compare against.
17855///
17856/// @return true iff @p other equals the current instance.
17857bool
17859{
17860 const decl_base& o = other;
17861 return *this == o;
17862}
17863
17864/// Getter of the pointed-to type.
17865///
17866/// @return the pointed-to type.
17867const type_base_sptr
17869{return priv_->pointed_to_type_.lock();}
17870
17871/// Getter of a naked pointer to the pointed-to type.
17872///
17873/// @return a naked pointed to the pointed-to type.
17874type_base*
17876{return priv_->naked_pointed_to_type_;}
17877
17878/// Build and return the qualified name of the current instance of
17879/// @ref pointer_type_def.
17880///
17881/// @param qn output parameter. The resulting qualified name.
17882///
17883/// @param internal set to true if the call is intended for an
17884/// internal use (for technical use inside the library itself), false
17885/// otherwise. If you don't know what this is for, then set it to
17886/// false.
17887void
17889{qn = get_qualified_name(internal);}
17890
17891/// Build, cache and return the qualified name of the current instance
17892/// of @ref pointer_type_def. Subsequent invocations of this function
17893/// return the cached value.
17894///
17895/// Note that this function should work even if the underlying type is
17896/// momentarily empty.
17897///
17898/// @param internal set to true if the call is intended for an
17899/// internal use (for technical use inside the library itself), false
17900/// otherwise. If you don't know what this is for, then set it to
17901/// false.
17902///
17903/// @return the resulting qualified name.
17904const interned_string&
17906{
17907 type_base* pointed_to_type = get_naked_pointed_to_type();
17908 pointed_to_type = look_through_decl_only_type(pointed_to_type);
17909
17910 if (internal)
17911 {
17912 if (get_canonical_type())
17913 {
17914 if (priv_->internal_qualified_name_.empty())
17915 if (pointed_to_type)
17916 priv_->internal_qualified_name_ =
17917 pointer_declaration_name(this,
17918 /*variable_name=*/"",
17919 /*qualified_name=*/
17920 is_typedef(pointed_to_type)
17921 ? false
17922 : true,
17923 /*internal=*/true);
17924 return priv_->internal_qualified_name_;
17925 }
17926 else
17927 {
17928 // As the type hasn't yet been canonicalized, its structure
17929 // (and so its name) can change. So let's invalidate the
17930 // cache where we store its name at each invocation of this
17931 // function.
17932 if (pointed_to_type)
17933 if (priv_->temp_internal_qualified_name_.empty())
17934 priv_->temp_internal_qualified_name_ =
17935 pointer_declaration_name(this,
17936 /*variable_name=*/"",
17937 /*qualified_name=*/
17938 is_typedef(pointed_to_type)
17939 ? false
17940 : true,
17941 /*internal=*/true);
17942 return priv_->temp_internal_qualified_name_;
17943 }
17944 }
17945 else
17946 {
17948 {
17949 if (decl_base::peek_qualified_name().empty())
17951 (pointer_declaration_name(this,
17952 /*variable_name=*/"",
17953 /*qualified_name=*/true,
17954 /*internal=*/false));
17956 }
17957 else
17958 {
17959 // As the type hasn't yet been canonicalized, its structure
17960 // (and so its name) can change. So let's invalidate the
17961 // cache where we store its name at each invocation of this
17962 // function.
17963 if (pointed_to_type)
17965 (pointer_declaration_name(this,
17966 /*variable_name=*/"",
17967 /*qualified_name=*/true,
17968 /*internal=*/false));
17970 }
17971 }
17972}
17973
17974/// This implements the ir_traversable_base::traverse pure virtual
17975/// function.
17976///
17977/// @param v the visitor used on the current instance.
17978///
17979/// @return true if the entire IR node tree got traversed, false
17980/// otherwise.
17981bool
17983{
17984 if (v.type_node_has_been_visited(this))
17985 return true;
17986
17987 if (visiting())
17988 return true;
17989
17990 if (v.visit_begin(this))
17991 {
17992 visiting(true);
17993 if (type_base_sptr t = get_pointed_to_type())
17994 t->traverse(v);
17995 visiting(false);
17996 }
17997
17998 bool result = v.visit_end(this);
18000 return result;
18001}
18002
18003pointer_type_def::~pointer_type_def()
18004{}
18005
18006/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
18007/// equality; that is, make it compare the pointed to objects too.
18008///
18009/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18010/// of the equality.
18011///
18012/// @param r the shared_ptr of @ref pointer_type_def on
18013/// right-hand-side of the equality.
18014///
18015/// @return true if the @ref pointer_type_def pointed to by the
18016/// shared_ptrs are equal, false otherwise.
18017bool
18019{
18020 if (l.get() == r.get())
18021 return true;
18022 if (!!l != !!r)
18023 return false;
18024
18025 return *l == *r;
18026}
18027
18028/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
18029/// equality; that is, make it compare the pointed to objects too.
18030///
18031/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18032/// of the equality.
18033///
18034/// @param r the shared_ptr of @ref pointer_type_def on
18035/// right-hand-side of the equality.
18036///
18037/// @return true iff the @ref pointer_type_def pointed to by the
18038/// shared_ptrs are different.
18039bool
18041{return !operator==(l, r);}
18042
18043// </pointer_type_def definitions>
18044
18045// <reference_type_def definitions>
18046
18047/// Private data structure of the @ref reference_type_def type.
18048struct reference_type_def::priv
18049{
18050
18051 type_base_wptr pointed_to_type_;
18052 bool is_lvalue_;
18053 interned_string internal_qualified_name_;
18054 interned_string temp_internal_qualified_name_;
18055
18056 priv(const type_base_sptr& t, bool is_lvalue)
18057 : pointed_to_type_(type_or_void(t, t->get_environment())),
18058 is_lvalue_(is_lvalue)
18059 {}
18060
18061 priv(bool is_lvalue)
18062 : is_lvalue_(is_lvalue)
18063 {}
18064
18065 priv() = delete;
18066};
18067
18068/// This function is automatically invoked whenever an instance of
18069/// this type is canonicalized.
18070///
18071/// It's an overload of the virtual type_base::on_canonical_type_set.
18072///
18073/// We put here what is thus meant to be executed only at the point of
18074/// type canonicalization.
18075void
18078
18079/// Constructor of the reference_type_def type.
18080///
18081/// @param pointed_to the pointed to type.
18082///
18083/// @param lvalue wether the reference is an lvalue reference. If
18084/// false, the reference is an rvalue one.
18085///
18086/// @param size_in_bits the size of the type, in bits.
18087///
18088/// @param align_in_bits the alignment of the type, in bits.
18089///
18090/// @param locus the source location of the type.
18091reference_type_def::reference_type_def(const type_base_sptr pointed_to,
18092 bool lvalue,
18093 size_t size_in_bits,
18094 size_t align_in_bits,
18095 const location& locus)
18096 : type_or_decl_base(pointed_to->get_environment(),
18097 REFERENCE_TYPE
18098 | ABSTRACT_TYPE_BASE
18099 | ABSTRACT_DECL_BASE),
18100 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18101 decl_base(pointed_to->get_environment(), "", locus, ""),
18102 priv_(new priv(pointed_to, lvalue))
18103{
18105
18106 try
18107 {
18108 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18109 string name;
18110 if (pto)
18111 {
18112 set_visibility(pto->get_visibility());
18113 name = string(pto->get_name()) + "&";
18114 }
18115 else
18116 name = string(get_type_name(is_function_type(pointed_to),
18117 /*qualified_name=*/true)) + "&";
18118
18119 if (!is_lvalue())
18120 name += "&";
18121 const environment& env = pointed_to->get_environment();
18122 set_name(env.intern(name));
18123 }
18124 catch (...)
18125 {}
18126}
18127
18128/// Constructor of the reference_type_def type.
18129///
18130/// This one creates a type that has no pointed-to type, temporarily.
18131/// This is useful for cases where the underlying type is not yet
18132/// available. It can be set later using
18133/// reference_type_def::set_pointed_to_type().
18134///
18135/// @param env the environment of the type.
18136///
18137/// @param lvalue wether the reference is an lvalue reference. If
18138/// false, the reference is an rvalue one.
18139///
18140/// @param size_in_bits the size of the type, in bits.
18141///
18142/// @param align_in_bits the alignment of the type, in bits.
18143///
18144/// @param locus the source location of the type.
18145reference_type_def::reference_type_def(const environment& env, bool lvalue,
18146 size_t size_in_bits,
18147 size_t alignment_in_bits,
18148 const location& locus)
18149 : type_or_decl_base(env,
18150 REFERENCE_TYPE
18151 | ABSTRACT_TYPE_BASE
18152 | ABSTRACT_DECL_BASE),
18153 type_base(env, size_in_bits, alignment_in_bits),
18154 decl_base(env, "", locus, ""),
18155 priv_(new priv(lvalue))
18156{
18158 string name = "void&";
18159 if (!is_lvalue())
18160 name += "&";
18161
18162 set_name(env.intern(name));
18163 priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
18164}
18165
18166/// Return the hash value of the current IR node.
18167///
18168/// Note that upon the first invocation, this member functions
18169/// computes the hash value and returns it. Subsequent invocations
18170/// just return the hash value that was previously calculated.
18171///
18172/// @return the hash value of the current IR node.
18173hash_t
18175{
18177 return h;
18178}
18179
18180/// Setter of the pointed_to type of the current reference type.
18181///
18182/// @param pointed_to the new pointed to type.
18183void
18184reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
18185{
18186 ABG_ASSERT(pointed_to_type);
18187 priv_->pointed_to_type_ = pointed_to_type;
18188
18189 decl_base_sptr pto;
18190 try
18191 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
18192 catch (...)
18193 {}
18194
18195 if (pto)
18196 {
18197 set_visibility(pto->get_visibility());
18198 string name = string(pto->get_name()) + "&";
18199 if (!is_lvalue())
18200 name += "&";
18201 const environment& env = pto->get_environment();
18202 set_name(env.intern(name));
18203 }
18204}
18205
18206/// Compares two instances of @ref reference_type_def.
18207///
18208/// If the two intances are different, set a bitfield to give some
18209/// insight about the kind of differences there are.
18210///
18211/// @param l the first artifact of the comparison.
18212///
18213/// @param r the second artifact of the comparison.
18214///
18215/// @param k a pointer to a bitfield that gives information about the
18216/// kind of changes there are between @p l and @p r. This one is set
18217/// iff @p k is non-null and the function returns false.
18218///
18219/// Please note that setting k to a non-null value does have a
18220/// negative performance impact because even if @p l and @p r are not
18221/// equal, the function keeps up the comparison in order to determine
18222/// the different kinds of ways in which they are different.
18223///
18224/// @return true if @p l equals @p r, false otherwise.
18225bool
18227{
18228 if (l.is_lvalue() != r.is_lvalue())
18229 {
18230 if (k)
18233 }
18234 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18235 bool result = p1 == p2;
18236 if (!result)
18237 if (k)
18238 {
18239 if (!types_have_similar_structure(&l, &r))
18241 *k |= SUBTYPE_CHANGE_KIND;
18242 }
18243 ABG_RETURN(result);
18244}
18245
18246/// Equality operator of the @ref reference_type_def type.
18247///
18248/// @param o the other instance of @ref reference_type_def to compare
18249/// against.
18250///
18251/// @return true iff the two instances are equal.
18252bool
18254{
18255 const reference_type_def* other =
18256 dynamic_cast<const reference_type_def*>(&o);
18257 if (!other)
18258 return false;
18259 return try_canonical_compare(this, other);
18260}
18261
18262/// Equality operator of the @ref reference_type_def type.
18263///
18264/// @param o the other instance of @ref reference_type_def to compare
18265/// against.
18266///
18267/// @return true iff the two instances are equal.
18268bool
18270{
18271 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18272 if (!other)
18273 return false;
18274 return *this == *other;
18275}
18276
18277/// Equality operator of the @ref reference_type_def type.
18278///
18279/// @param o the other instance of @ref reference_type_def to compare
18280/// against.
18281///
18282/// @return true iff the two instances are equal.
18283bool
18285{
18286 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18287 if (!other)
18288 return false;
18289 return *this == *other;
18290}
18291
18292type_base_sptr
18293reference_type_def::get_pointed_to_type() const
18294{return priv_->pointed_to_type_.lock();}
18295
18296bool
18297reference_type_def::is_lvalue() const
18298{return priv_->is_lvalue_;}
18299
18300/// Build and return the qualified name of the current instance of the
18301/// @ref reference_type_def.
18302///
18303/// @param qn output parameter. Is set to the newly-built qualified
18304/// name of the current instance of @ref reference_type_def.
18305///
18306/// @param internal set to true if the call is intended for an
18307/// internal use (for technical use inside the library itself), false
18308/// otherwise. If you don't know what this is for, then set it to
18309/// false.
18310void
18312{qn = get_qualified_name(internal);}
18313
18314/// Build, cache and return the qualified name of the current instance
18315/// of the @ref reference_type_def. Subsequent invocations of this
18316/// function return the cached value.
18317///
18318/// @param internal set to true if the call is intended for an
18319/// internal use (for technical use inside the library itself), false
18320/// otherwise. If you don't know what this is for, then set it to
18321/// false.
18322///
18323/// @return the newly-built qualified name of the current instance of
18324/// @ref reference_type_def.
18325const interned_string&
18327{
18328 type_base_sptr pointed_to_type = get_pointed_to_type();
18329 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18330
18331 if (internal)
18332 {
18333 if (get_canonical_type())
18334 {
18335 if (priv_->internal_qualified_name_.empty())
18336 if (pointed_to_type)
18337 priv_->internal_qualified_name_ =
18338 get_name_of_reference_to_type(*pointed_to_type,
18339 is_lvalue(),
18340 /*qualified_name=*/
18341 is_typedef(pointed_to_type)
18342 ? false
18343 : true,
18344 /*internal=*/true);
18345 return priv_->internal_qualified_name_;
18346 }
18347 else
18348 {
18349 // As the type hasn't yet been canonicalized, its structure
18350 // (and so its name) can change. So let's invalidate the
18351 // cache where we store its name at each invocation of this
18352 // function.
18353 if (pointed_to_type)
18354 if (priv_->temp_internal_qualified_name_.empty())
18355 priv_->temp_internal_qualified_name_ =
18356 get_name_of_reference_to_type(*pointed_to_type,
18357 is_lvalue(),
18358 /*qualified_name=*/
18359 is_typedef(pointed_to_type)
18360 ? false
18361 : true,
18362 /*internal=*/true);
18363 return priv_->temp_internal_qualified_name_;
18364 }
18365 }
18366 else
18367 {
18369 {
18371 (get_name_of_reference_to_type(*pointed_to_type,
18372 is_lvalue(),
18373 /*qualified_name=*/true,
18374 /*internal=*/false));
18376 }
18377 else
18378 {
18379 // As the type hasn't yet been canonicalized, its structure
18380 // (and so its name) can change. So let's invalidate the
18381 // cache where we store its name at each invocation of this
18382 // function.
18383 if (pointed_to_type)
18385 (get_name_of_reference_to_type(*pointed_to_type,
18386 is_lvalue(),
18387 /*qualified_name=*/true,
18388 /*internal=*/false));
18390 }
18391 }
18392}
18393
18394/// Get the pretty representation of the current instance of @ref
18395/// reference_type_def.
18396///
18397/// @param internal set to true if the call is intended to get a
18398/// representation of the decl (or type) for the purpose of canonical
18399/// type comparison. This is mainly used in the function
18400/// type_base::get_canonical_type_for().
18401///
18402/// In other words if the argument for this parameter is true then the
18403/// call is meant for internal use (for technical use inside the
18404/// library itself), false otherwise. If you don't know what this is
18405/// for, then set it to false.
18406///
18407/// @param qualified_name if true, names emitted in the pretty
18408/// representation are fully qualified.
18409///
18410/// @return the pretty representatin of the @ref reference_type_def.
18411string
18413 bool qualified_name) const
18414{
18415 string result =
18417 (get_pointed_to_type()),
18418 is_lvalue(),
18419 qualified_name,
18420 internal);
18421
18422 return result;
18423}
18424
18425/// This implements the ir_traversable_base::traverse pure virtual
18426/// function.
18427///
18428/// @param v the visitor used on the current instance.
18429///
18430/// @return true if the entire IR node tree got traversed, false
18431/// otherwise.
18432bool
18434{
18435 if (v.type_node_has_been_visited(this))
18436 return true;
18437
18438 if (visiting())
18439 return true;
18440
18441 if (v.visit_begin(this))
18442 {
18443 visiting(true);
18444 if (type_base_sptr t = get_pointed_to_type())
18445 t->traverse(v);
18446 visiting(false);
18447 }
18448
18449 bool result = v.visit_end(this);
18451 return result;
18452}
18453
18454reference_type_def::~reference_type_def()
18455{}
18456
18457/// Turn equality of shared_ptr of @ref reference_type_def into a deep
18458/// equality; that is, make it compare the pointed to objects too.
18459///
18460/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18461/// of the equality.
18462///
18463/// @param r the shared_ptr of @ref reference_type_def on
18464/// right-hand-side of the equality.
18465///
18466/// @return true if the @ref reference_type_def pointed to by the
18467/// shared_ptrs are equal, false otherwise.
18468bool
18470{
18471 if (l.get() == r.get())
18472 return true;
18473 if (!!l != !!r)
18474 return false;
18475
18476 return *l == *r;
18477}
18478
18479/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
18480/// equality; that is, make it compare the pointed to objects too.
18481///
18482/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18483/// of the equality.
18484///
18485/// @param r the shared_ptr of @ref reference_type_def on
18486/// right-hand-side of the equality.
18487///
18488/// @return true iff the @ref reference_type_def pointed to by the
18489/// shared_ptrs are different.
18490bool
18493
18494// </reference_type_def definitions>
18495
18496// <ptr_to_mbr_type definitions>
18497
18498/// The private data type of @ref ptr_to_mbr_type.
18499struct ptr_to_mbr_type::priv
18500{
18501 // The type of the data member this pointer-to-member-type
18502 // designates.
18503 type_base_sptr dm_type_;
18504 // The class (or typedef to potentially qualified class) containing
18505 // the data member this pointer-to-member-type designates.
18506 type_base_sptr containing_type_;
18507 interned_string internal_qualified_name_;
18508 interned_string temp_internal_qualified_name_;
18509
18510 priv()
18511 {}
18512
18513 priv(const type_base_sptr& dm_type, const type_base_sptr& containing_type)
18514 : dm_type_(dm_type),
18515 containing_type_(containing_type)
18516 {}
18517};// end struct ptr_to_mbr_type::priv
18518
18519/// A constructor for a @ref ptr_to_mbr_type type.
18520///
18521/// @param env the environment to construct the @ref ptr_to_mbr_type in.
18522///
18523/// @param member_type the member type of the of the @ref
18524/// ptr_to_mbr_type to construct.
18525///
18526/// @param containing_type the containing type of the @ref
18527/// ptr_to_mbr_type to construct.
18528///
18529/// @param size_in_bits the size (in bits) of the resulting type.
18530///
18531/// @param alignment_in_bits the alignment (in bits) of the resulting
18532/// type.
18533///
18534/// @param locus the source location of the definition of the
18535/// resulting type.
18536ptr_to_mbr_type::ptr_to_mbr_type(const environment& env,
18537 const type_base_sptr& member_type,
18538 const type_base_sptr& containing_type,
18539 size_t size_in_bits,
18540 size_t alignment_in_bits,
18541 const location& locus)
18542 : type_or_decl_base(env,
18543 POINTER_TO_MEMBER_TYPE
18544 | ABSTRACT_TYPE_BASE
18545 | ABSTRACT_DECL_BASE),
18546 type_base(env, size_in_bits, alignment_in_bits),
18547 decl_base(env, "", locus, ""),
18548 priv_(new priv(member_type, containing_type))
18549{
18551 ABG_ASSERT(member_type);
18552 ABG_ASSERT(containing_type);
18553 set_is_anonymous(false);
18554}
18555
18556/// Getter of the name of the current ptr-to-mbr-type.
18557///
18558/// This just returns the qualified name.
18559///
18560/// @return the (qualified) name of the the type.
18561const interned_string&
18563{
18564 return get_qualified_name(/*internal=*/false);
18565}
18566
18567/// Return the hash value of the current IR node.
18568///
18569/// Note that upon the first invocation, this member functions
18570/// computes the hash value and returns it. Subsequent invocations
18571/// just return the hash value that was previously calculated.
18572///
18573/// @return the hash value of the current IR node.
18574hash_t
18576{
18578 return h;
18579}
18580
18581/// Getter of the member type of the current @ref ptr_to_mbr_type.
18582///
18583/// @return the type of the member referred to by the current
18584/// @ptr_to_mbr_type.
18585const type_base_sptr&
18587{return priv_->dm_type_;}
18588
18589/// Getter of the type containing the member pointed-to by the current
18590/// @ref ptr_to_mbr_type.
18591///
18592/// @return the type containing the member pointed-to by the current
18593/// @ref ptr_to_mbr_type.
18594const type_base_sptr&
18596{return priv_->containing_type_;}
18597
18598/// Equality operator for the current @ref ptr_to_mbr_type.
18599///
18600///@param o the other instance of @ref ptr_to_mbr_type to compare the
18601///current instance to.
18602///
18603/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18604bool
18606{
18607 const ptr_to_mbr_type* other =
18608 dynamic_cast<const ptr_to_mbr_type*>(&o);
18609 if (!other)
18610 return false;
18611 return try_canonical_compare(this, other);
18612}
18613
18614/// Equality operator for the current @ref ptr_to_mbr_type.
18615///
18616///@param o the other instance of @ref ptr_to_mbr_type to compare the
18617///current instance to.
18618///
18619/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18620bool
18622{
18623 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18624 if (!other)
18625 return false;
18626 return *this == *other;
18627}
18628
18629/// Equality operator for the current @ref ptr_to_mbr_type.
18630///
18631///@param o the other instance of @ref ptr_to_mbr_type to compare the
18632///current instance to.
18633///
18634/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18635bool
18637{
18638 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18639 if (!other)
18640 return false;
18641 return *this == *other;
18642}
18643
18644/// Get the qualified name for the current @ref ptr_to_mbr_type.
18645///
18646/// @param qualified_name out parameter. This is set to the name of
18647/// the current @ref ptr_to_mbr_type.
18648///
18649/// @param internal if this is true, then the qualified name is for
18650/// the purpose of type canoicalization.
18651void
18653 bool internal) const
18654{qualified_name = get_qualified_name(internal);}
18655
18656/// Get the qualified name for the current @ref ptr_to_mbr_type.
18657///
18658/// @param internal if this is true, then the qualified name is for
18659/// the purpose of type canoicalization.
18660///
18661/// @return the qualified name for the current @ref ptr_to_mbr_type.
18662const interned_string&
18664{
18665 type_base_sptr member_type = get_member_type();
18666 type_base_sptr containing_type = get_containing_type();
18667
18668 if (internal)
18669 {
18670 if (get_canonical_type())
18671 {
18672 if (priv_->internal_qualified_name_.empty())
18673 priv_->internal_qualified_name_ =
18674 ptr_to_mbr_declaration_name(this, "",
18675 /*qualified=*/true,
18676 internal);
18677 return priv_->internal_qualified_name_;
18678 }
18679 else
18680 {
18681 priv_->temp_internal_qualified_name_ =
18682 ptr_to_mbr_declaration_name(this, "", /*qualified=*/true, internal);
18683 return priv_->temp_internal_qualified_name_;
18684 }
18685 }
18686 else
18687 {
18689 (ptr_to_mbr_declaration_name(this, "", /*qualified=*/true,
18690 /*internal=*/false));
18692 }
18693}
18694
18695/// This implements the ir_traversable_base::traverse pure virtual
18696/// function for @ref ptr_to_mbr_type.
18697///
18698/// @param v the visitor used on the current instance.
18699///
18700/// @return true if the entire IR node tree got traversed, false
18701/// otherwise.
18702bool
18704{
18705 if (v.type_node_has_been_visited(this))
18706 return true;
18707
18708 if (visiting())
18709 return true;
18710
18711 if (v.visit_begin(this))
18712 {
18713 visiting(true);
18714 if (type_base_sptr t = get_member_type())
18715 t->traverse(v);
18716
18717 if (type_base_sptr t = get_containing_type())
18718 t->traverse(v);
18719 visiting(false);
18720 }
18721
18722 bool result = v.visit_end(this);
18724 return result;
18725}
18726
18727/// Desctructor for @ref ptr_to_mbr_type.
18730
18731
18732/// Compares two instances of @ref ptr_to_mbr_type.
18733///
18734/// If the two intances are different, set a bitfield to give some
18735/// insight about the kind of differences there are.
18736///
18737/// @param l the first artifact of the comparison.
18738///
18739/// @param r the second artifact of the comparison.
18740///
18741/// @param k a pointer to a bitfield that gives information about the
18742/// kind of changes there are between @p l and @p r. This one is set
18743/// iff @p k is non-null and the function returns false.
18744///
18745/// Please note that setting k to a non-null value does have a
18746/// negative performance impact because even if @p l and @p r are not
18747/// equal, the function keeps up the comparison in order to determine
18748/// the different kinds of ways in which they are different.
18749///
18750/// @return true if @p l equals @p r, false otherwise.
18751bool
18753{
18754 bool result = true;
18755
18756 if (!(l.decl_base::operator==(r)))
18757 {
18758 result = false;
18759 if (k)
18761 else
18762 result = false;
18763 }
18764
18765 if (l.get_member_type() != r.get_member_type())
18766 {
18767 if (k)
18768 {
18769 if (!types_have_similar_structure(&l, &r))
18771 *k |= SUBTYPE_CHANGE_KIND;
18772 }
18773 result = false;
18774 }
18775
18777 {
18778 if (k)
18779 {
18780 if (!types_have_similar_structure(&l, &r))
18782 *k |= SUBTYPE_CHANGE_KIND;
18783 }
18784 result = false;
18785 }
18786
18787 ABG_RETURN(result);
18788}
18789
18790// </ptr_to_mbr_type definitions>
18791
18792// <array_type_def definitions>
18793
18794// <array_type_def::subrange_type>
18795array_type_def::subrange_type::~subrange_type() = default;
18796
18797// <array_type_def::subrante_type::bound_value>
18798
18799/// Default constructor of the @ref
18800/// array_type_def::subrange_type::bound_value class.
18801///
18802/// Constructs an unsigned bound_value of value zero.
18804 : s_(UNSIGNED_SIGNEDNESS)
18805{
18806 v_.unsigned_ = 0;
18807}
18808
18809/// Initialize an unsigned bound_value with a given value.
18810///
18811/// @param v the initial bound value.
18813 : s_(UNSIGNED_SIGNEDNESS)
18814{
18815 v_.unsigned_ = v;
18816}
18817
18818/// Initialize a signed bound_value with a given value.
18819///
18820/// @param v the initial bound value.
18822 : s_(SIGNED_SIGNEDNESS)
18823{
18824 v_.signed_ = v;
18825}
18826
18827/// Getter of the signedness (unsigned VS signed) of the bound value.
18828///
18829/// @return the signedness of the bound value.
18830enum array_type_def::subrange_type::bound_value::signedness
18833
18834/// Setter of the signedness (unsigned VS signed) of the bound value.
18835///
18836/// @param s the new signedness of the bound value.
18837void
18840
18841/// Getter of the bound value as a signed value.
18842///
18843/// @return the bound value as signed.
18844int64_t
18848
18849/// Getter of the bound value as an unsigned value.
18850///
18851/// @return the bound value as unsigned.
18852uint64_t
18855
18856/// Setter of the bound value as unsigned.
18857///
18858/// @param v the new unsigned value.
18859void
18861{
18862 s_ = UNSIGNED_SIGNEDNESS;
18863 v_.unsigned_ = v;
18864}
18865
18866/// Setter of the bound value as signed.
18867///
18868/// @param v the new signed value.
18869void
18871{
18872 s_ = SIGNED_SIGNEDNESS;
18873 v_.signed_ = v;
18874}
18875
18876/// Equality operator of the bound value.
18877///
18878/// @param v the other bound value to compare with.
18879///
18880/// @return true iff the current bound value equals @p v.
18881bool
18883{
18884 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
18885}
18886
18887// </array_type_def::subrante_type::bound_value>
18888
18889struct array_type_def::subrange_type::priv
18890{
18891 bound_value lower_bound_;
18892 bound_value upper_bound_;
18893 type_base_wptr underlying_type_;
18895 bool infinite_;
18896
18897 priv(bound_value ub,
18898 translation_unit::language l = translation_unit::LANG_C11)
18899 : upper_bound_(ub), language_(l), infinite_(false)
18900 {}
18901
18902 priv(bound_value lb, bound_value ub,
18903 translation_unit::language l = translation_unit::LANG_C11)
18904 : lower_bound_(lb), upper_bound_(ub),
18905 language_(l), infinite_(false)
18906 {}
18907
18908 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
18909 translation_unit::language l = translation_unit::LANG_C11)
18910 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
18911 language_(l), infinite_(false)
18912 {}
18913};
18914
18915/// Constructor of an array_type_def::subrange_type type.
18916///
18917/// @param env the environment this type was created from.
18918///
18919/// @param name the name of the subrange type.
18920///
18921/// @param lower_bound the lower bound of the array. This is
18922/// generally zero (at least for C and C++).
18923///
18924/// @param upper_bound the upper bound of the array.
18925///
18926/// @param underlying_type the underlying type of the subrange type.
18927///
18928/// @param loc the source location where the type is defined.
18929array_type_def::subrange_type::subrange_type(const environment& env,
18930 const string& name,
18931 bound_value lower_bound,
18932 bound_value upper_bound,
18933 const type_base_sptr& utype,
18934 const location& loc,
18936 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18937 type_base(env,
18938 utype
18939 ? utype->get_size_in_bits()
18940 : 0,
18941 0),
18942 decl_base(env, name, loc, ""),
18943 priv_(new priv(lower_bound, upper_bound, utype, l))
18944{
18946}
18947
18948/// Constructor of the array_type_def::subrange_type type.
18949///
18950/// @param env the environment this type is being created in.
18951///
18952/// @param name the name of the subrange type.
18953///
18954/// @param lower_bound the lower bound of the array. This is
18955/// generally zero (at least for C and C++).
18956///
18957/// @param upper_bound the upper bound of the array.
18958///
18959/// @param loc the source location where the type is defined.
18960///
18961/// @param l the language that generated this subrange.
18962array_type_def::subrange_type::subrange_type(const environment& env,
18963 const string& name,
18964 bound_value lower_bound,
18965 bound_value upper_bound,
18966 const location& loc,
18968 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18969 type_base(env, /*size-in-bits=*/0, /*alignment=*/0),
18970 decl_base(env, name, loc, ""),
18971 priv_(new priv(lower_bound, upper_bound, l))
18972{
18974}
18975
18976/// Constructor of the array_type_def::subrange_type type.
18977///
18978/// @param env the environment this type is being created from.
18979///
18980/// @param name of the name of type.
18981///
18982/// @param upper_bound the upper bound of the array. The lower bound
18983/// is considered to be zero.
18984///
18985/// @param loc the source location of the type.
18986///
18987/// @param the language that generated this type.
18988array_type_def::subrange_type::subrange_type(const environment& env,
18989 const string& name,
18990 bound_value upper_bound,
18991 const location& loc,
18993 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18994 type_base(env, upper_bound.get_unsigned_value(), 0),
18995 decl_base(env, name, loc, ""),
18996 priv_(new priv(upper_bound, l))
18997{
18999}
19000
19001/// Return the hash value of the current IR node.
19002///
19003/// Note that upon the first invocation, this member functions
19004/// computes the hash value and returns it. Subsequent invocations
19005/// just return the hash value that was previously calculated.
19006///
19007/// @return the hash value of the current IR node.
19008hash_t
19010{
19012 return h;
19013}
19014
19015/// Getter of the underlying type of the subrange, that is, the type
19016/// that defines the range.
19017///
19018/// @return the underlying type.
19019type_base_sptr
19021{return priv_->underlying_type_.lock();}
19022
19023/// Setter of the underlying type of the subrange, that is, the type
19024/// that defines the range.
19025///
19026/// @param u the new underlying type.
19027void
19029{
19030 ABG_ASSERT(priv_->underlying_type_.expired());
19031 priv_->underlying_type_ = u;
19032 if (u)
19033 set_size_in_bits(u->get_size_in_bits());
19034}
19035
19036/// Getter of the upper bound of the subrange type.
19037///
19038/// @return the upper bound of the subrange type.
19039int64_t
19041{return priv_->upper_bound_.get_signed_value();}
19042
19043/// Getter of the lower bound of the subrange type.
19044///
19045/// @return the lower bound of the subrange type.
19046int64_t
19048{return priv_->lower_bound_.get_signed_value();}
19049
19050/// Setter of the upper bound of the subrange type.
19051///
19052/// @param ub the new value of the upper bound.
19053void
19055{priv_->upper_bound_ = ub;}
19056
19057/// Setter of the lower bound.
19058///
19059/// @param lb the new value of the lower bound.
19060void
19062{priv_->lower_bound_ = lb;}
19063
19064/// Getter of the length of the subrange type.
19065///
19066/// Note that a length of zero means the array has an infinite (or
19067/// rather a non-known) size.
19068///
19069/// @return the length of the subrange type.
19070uint64_t
19072{
19073 if (is_non_finite())
19074 return 0;
19075
19076 // A subrange can have an upper bound that is lower than its lower
19077 // bound. This is possible in Ada for instance. In that case, the
19078 // length of the subrange is considered to be zero.
19079 if (get_upper_bound() >= get_lower_bound())
19080 return get_upper_bound() - get_lower_bound() + 1;
19081 return 0;
19082}
19083
19084/// Test if the length of the subrange type is infinite.
19085///
19086/// @return true iff the length of the subrange type is infinite.
19087bool
19089{return priv_->infinite_;}
19090
19091/// Set the infinite-ness status of the subrange type.
19092///
19093/// @param f true iff the length of the subrange type should be set to
19094/// being infinite.
19095void
19097{priv_->infinite_ = f;}
19098
19099/// Getter of the language that generated this type.
19100///
19101/// @return the language of this type.
19104{return priv_->language_;}
19105
19106/// Return a string representation of the sub range.
19107///
19108/// @return the string representation of the sub range.
19109string
19111{
19112 std::ostringstream o;
19113
19115 {
19116 type_base_sptr underlying_type = get_underlying_type();
19117 if (underlying_type)
19118 o << ir::get_pretty_representation(underlying_type, false) << " ";
19119 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
19120 }
19121 else if (is_non_finite())
19122 o << "[]";
19123 else
19124 o << "[" << get_length() << "]";
19125
19126 return o.str();
19127}
19128
19129/// Return a string representation of a vector of subranges
19130///
19131/// @return the string representation of a vector of sub ranges.
19132string
19134{
19135 if (v.empty())
19136 return "[]";
19137
19138 string r;
19139 for (vector<subrange_sptr>::const_iterator i = v.begin();
19140 i != v.end();
19141 ++i)
19142 r += (*i)->as_string();
19143
19144 return r;
19145}
19146
19147/// Compares two isntances of @ref array_type_def::subrange_type.
19148///
19149/// If the two intances are different, set a bitfield to give some
19150/// insight about the kind of differences there are.
19151///
19152/// @param l the first artifact of the comparison.
19153///
19154/// @param r the second artifact of the comparison.
19155///
19156/// @param k a pointer to a bitfield that gives information about the
19157/// kind of changes there are between @p l and @p r. This one is set
19158/// iff @p k is non-null and the function returns false.
19159///
19160/// Please note that setting k to a non-null value does have a
19161/// negative performance impact because even if @p l and @p r are not
19162/// equal, the function keeps up the comparison in order to determine
19163/// the different kinds of ways in which they are different.
19164///
19165/// @return true if @p l equals @p r, false otherwise.
19166bool
19169 change_kind* k)
19170{
19171 bool result = true;
19172
19173 if (l.get_lower_bound() != r.get_lower_bound()
19174 || l.get_upper_bound() != r.get_upper_bound()
19175 || l.get_name() != r.get_name())
19176 {
19177 result = false;
19178 if (k)
19180 else
19181 ABG_RETURN(result);
19182 }
19183
19184 if (l.get_underlying_type()
19185 && r.get_underlying_type()
19186 && (*l.get_underlying_type() != *r.get_underlying_type()))
19187 {
19188 result = false;
19189 if (k)
19190 *k |= SUBTYPE_CHANGE_KIND;
19191 else
19192 ABG_RETURN(result);
19193 }
19194
19195 ABG_RETURN(result);
19196}
19197
19198/// Equality operator.
19199///
19200/// @param o the other subrange to test against.
19201///
19202/// @return true iff @p o equals the current instance of
19203/// array_type_def::subrange_type.
19204bool
19206{
19207 const subrange_type* other =
19208 dynamic_cast<const subrange_type*>(&o);
19209 if (!other)
19210 return false;
19211 return try_canonical_compare(this, other);
19212}
19213
19214/// Equality operator.
19215///
19216/// @param o the other subrange to test against.
19217///
19218/// @return true iff @p o equals the current instance of
19219/// array_type_def::subrange_type.
19220bool
19222{
19223 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19224 if (!other)
19225 return false;
19226 return *this == *other;
19227}
19228
19229/// Equality operator.
19230///
19231/// @param o the other subrange to test against.
19232///
19233/// @return true iff @p o equals the current instance of
19234/// array_type_def::subrange_type.
19235bool
19237{
19238 const type_base &t = o;
19239 return operator==(t);
19240}
19241
19242/// Equality operator.
19243///
19244/// @param o the other subrange to test against.
19245///
19246/// @return true iff @p o equals the current instance of
19247/// array_type_def::subrange_type.
19248bool
19251
19252/// Equality operator.
19253///
19254/// @param o the other subrange to test against.
19255///
19256/// @return true iff @p o equals the current instance of
19257/// array_type_def::subrange_type.
19258bool
19261
19262/// Inequality operator.
19263///
19264/// @param o the other subrange to test against.
19265///
19266/// @return true iff @p o is different from the current instance of
19267/// array_type_def::subrange_type.
19268bool
19271
19272/// Build a pretty representation for an
19273/// array_type_def::subrange_type.
19274///
19275/// @param internal set to true if the call is intended to get a
19276/// representation of the decl (or type) for the purpose of canonical
19277/// type comparison. This is mainly used in the function
19278/// type_base::get_canonical_type_for().
19279///
19280/// In other words if the argument for this parameter is true then the
19281/// call is meant for internal use (for technical use inside the
19282/// library itself), false otherwise. If you don't know what this is
19283/// for, then set it to false.
19284///
19285/// @return a copy of the pretty representation of the current
19286/// instance of typedef_decl.
19287string
19289{
19290 string name = get_name();
19291 string repr;
19292
19293 if (name.empty())
19294 repr += "<anonymous range>";
19295 else
19296 repr += "<range " + get_name() + ">";
19297 repr += as_string();
19298
19299 return repr;
19300}
19301
19302/// This implements the ir_traversable_base::traverse pure virtual
19303/// function.
19304///
19305/// @param v the visitor used on the current instance.
19306///
19307/// @return true if the entire IR node tree got traversed, false
19308/// otherwise.
19309bool
19311{
19312 if (v.type_node_has_been_visited(this))
19313 return true;
19314
19315 if (v.visit_begin(this))
19316 {
19317 visiting(true);
19318 if (type_base_sptr u = get_underlying_type())
19319 u->traverse(v);
19320 visiting(false);
19321 }
19322
19323 bool result = v.visit_end(this);
19325 return result;
19326}
19327
19328// </array_type_def::subrange_type>
19329
19330struct array_type_def::priv
19331{
19332 type_base_wptr element_type_;
19333 subranges_type subranges_;
19334 interned_string temp_internal_qualified_name_;
19335 interned_string internal_qualified_name_;
19336
19337 priv(type_base_sptr t)
19338 : element_type_(t)
19339 {}
19340
19341 priv(type_base_sptr t, subranges_type subs)
19342 : element_type_(t), subranges_(subs)
19343 {}
19344
19345 priv()
19346 {}
19347};
19348
19349/// Constructor for the type array_type_def
19350///
19351/// Note how the constructor expects a vector of subrange
19352/// objects. Parsing of the array information always entails
19353/// parsing the subrange info as well, thus the class subrange_type
19354/// is defined inside class array_type_def and also parsed
19355/// simultaneously.
19356///
19357/// @param e_type the type of the elements contained in the array
19358///
19359/// @param subs a vector of the array's subranges(dimensions)
19360///
19361/// @param locus the source location of the array type definition.
19362array_type_def::array_type_def(const type_base_sptr e_type,
19363 const std::vector<subrange_sptr>& subs,
19364 const location& locus)
19366 ARRAY_TYPE
19367 | ABSTRACT_TYPE_BASE
19368 | ABSTRACT_DECL_BASE),
19369 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
19370 decl_base(e_type->get_environment(), locus),
19371 priv_(new priv(e_type))
19372{
19374 append_subranges(subs);
19375}
19376
19377/// Constructor for the type array_type_def
19378///
19379/// This constructor builds a temporary array that has no element type
19380/// associated. Later when the element type is available, it be set
19381/// with the array_type_def::set_element_type() member function.
19382///
19383/// Note how the constructor expects a vector of subrange
19384/// objects. Parsing of the array information always entails
19385/// parsing the subrange info as well, thus the class subrange_type
19386/// is defined inside class array_type_def and also parsed
19387/// simultaneously.
19388///
19389/// @param env the environment of the array type.
19390///
19391/// @param subs a vector of the array's subranges(dimensions)
19392///
19393/// @param locus the source location of the array type definition.
19394array_type_def::array_type_def(const environment& env,
19395 const std::vector<subrange_sptr>& subs,
19396 const location& locus)
19397 : type_or_decl_base(env,
19398 ARRAY_TYPE
19399 | ABSTRACT_TYPE_BASE
19400 | ABSTRACT_DECL_BASE),
19401 type_base(env, 0, 0),
19402 decl_base(env, locus),
19403 priv_(new priv)
19404{
19406 append_subranges(subs);
19407}
19408
19409/// Return the hash value of the current IR node.
19410///
19411/// Note that upon the first invocation, this member functions
19412/// computes the hash value and returns it. Subsequent invocations
19413/// just return the hash value that was previously calculated.
19414///
19415/// @return the hash value of the current IR node.
19416hash_t
19418{
19420 return h;
19421}
19422
19423/// Update the size of the array.
19424///
19425/// This function computes the size of the array and sets it using
19426/// type_base::set_size_in_bits().
19427void
19428array_type_def::update_size()
19429{
19430 type_base_sptr e = priv_->element_type_.lock();
19431 if (e)
19432 {
19433 size_t s = e->get_size_in_bits();
19434 if (s)
19435 {
19436 for (const auto &sub : get_subranges())
19437 s *= sub->get_length();
19439 }
19440 set_alignment_in_bits(e->get_alignment_in_bits());
19441 }
19442}
19443
19444string
19445array_type_def::get_subrange_representation() const
19446{
19448 return r;
19449}
19450
19451/// Get the pretty representation of the current instance of @ref
19452/// array_type_def.
19453///
19454/// @param internal set to true if the call is intended to get a
19455/// representation of the decl (or type) for the purpose of canonical
19456/// type comparison. This is mainly used in the function
19457/// type_base::get_canonical_type_for().
19458///
19459/// In other words if the argument for this parameter is true then the
19460/// call is meant for internal use (for technical use inside the
19461/// library itself), false otherwise. If you don't know what this is
19462/// for, then set it to false.
19463/// @param internal set to true if the call is intended for an
19464/// internal use (for technical use inside the library itself), false
19465/// otherwise. If you don't know what this is for, then set it to
19466/// false.
19467///
19468/// @return the pretty representation of the ABI artifact.
19469string
19471 bool qualified_name) const
19472{
19473 return array_declaration_name(this, /*variable_name=*/"",
19474 qualified_name, internal);
19475}
19476
19477/// Compares two instances of @ref array_type_def.
19478///
19479/// If the two intances are different, set a bitfield to give some
19480/// insight about the kind of differences there are.
19481///
19482/// @param l the first artifact of the comparison.
19483///
19484/// @param r the second artifact of the comparison.
19485///
19486/// @param k a pointer to a bitfield that gives information about the
19487/// kind of changes there are between @p l and @p r. This one is set
19488/// iff @p k is non-null and the function returns false.
19489///
19490/// Please note that setting k to a non-null value does have a
19491/// negative performance impact because even if @p l and @p r are not
19492/// equal, the function keeps up the comparison in order to determine
19493/// the different kinds of ways in which they are different.
19494///
19495/// @return true if @p l equals @p r, false otherwise.
19496bool
19498{
19499 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
19500 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
19501
19502 bool result = true;
19503 if (this_subs.size() != other_subs.size())
19504 {
19505 result = false;
19506 if (k)
19508 else
19510 }
19511
19512 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19513 for (i = this_subs.begin(), j = other_subs.begin();
19514 i != this_subs.end() && j != other_subs.end();
19515 ++i, ++j)
19516 if (**i != **j)
19517 {
19518 result = false;
19519 if (k)
19520 {
19522 break;
19523 }
19524 else
19526 }
19527
19528 // Compare the element types modulo the typedefs they might have
19529 if (l.get_element_type() != r.get_element_type())
19530 {
19531 result = false;
19532 if (k)
19533 *k |= SUBTYPE_CHANGE_KIND;
19534 else
19536 }
19537
19538 ABG_RETURN(result);
19539}
19540
19541/// Test if two variables are equals modulo CV qualifiers.
19542///
19543/// @param l the first array of the comparison.
19544///
19545/// @param r the second array of the comparison.
19546///
19547/// @return true iff @p l equals @p r or, if they are different, the
19548/// difference between the too is just a matter of CV qualifiers.
19549bool
19551{
19552 if (l == r)
19553 return true;
19554
19555 if (!l || !r)
19557
19560
19561 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
19562 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
19563
19564 if (this_subs.size() != other_subs.size())
19566
19567 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19568 for (i = this_subs.begin(), j = other_subs.begin();
19569 i != this_subs.end() && j != other_subs.end();
19570 ++i, ++j)
19571 if (**i != **j)
19573
19574 type_base *first_element_type =
19576 type_base *second_element_type =
19578
19579 if (*first_element_type != *second_element_type)
19581
19582 return true;
19583}
19584
19585/// Get the language of the array.
19586///
19587/// @return the language of the array.
19590{
19591 const std::vector<subrange_sptr>& subranges =
19592 get_subranges();
19593
19594 if (subranges.empty())
19595 return translation_unit::LANG_C11;
19596 return subranges.front()->get_language();
19597}
19598
19599bool
19601{
19602 const array_type_def* other =
19603 dynamic_cast<const array_type_def*>(&o);
19604 if (!other)
19605 return false;
19606 return try_canonical_compare(this, other);
19607}
19608
19609bool
19611{
19612 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19613 if (!other)
19614 return false;
19615 return *this == *other;
19616}
19617
19618/// Getter of the type of an array element.
19619///
19620/// @return the type of an array element.
19621const type_base_sptr
19623{return priv_->element_type_.lock();}
19624
19625/// Setter of the type of array element.
19626///
19627/// Beware that after using this function, one might want to
19628/// re-compute the canonical type of the array, if one has already
19629/// been computed.
19630///
19631/// The intended use of this method is to permit in-place adjustment
19632/// of the element type's qualifiers. In particular, the size of the
19633/// element type should not be changed.
19634///
19635/// @param element_type the new element type to set.
19636void
19637array_type_def::set_element_type(const type_base_sptr& element_type)
19638{
19639 priv_->element_type_ = element_type;
19640 update_size();
19642}
19643
19644/// Append subranges from the vector @param subs to the current
19645/// vector of subranges.
19646void
19647array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
19648{
19649
19650 for (const auto &sub : subs)
19651 priv_->subranges_.push_back(sub);
19652
19653 update_size();
19655}
19656
19657/// @return true if one of the sub-ranges of the array is infinite, or
19658/// if the array has no sub-range at all, also meaning that the size
19659/// of the array is infinite.
19660bool
19662{
19663 if (priv_->subranges_.empty())
19664 return true;
19665
19666 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
19667 priv_->subranges_.begin();
19668 i != priv_->subranges_.end();
19669 ++i)
19670 if ((*i)->is_non_finite())
19671 return true;
19672
19673 return false;
19674}
19675
19676int
19677array_type_def::get_dimension_count() const
19678{return priv_->subranges_.size();}
19679
19680/// Build and return the qualified name of the current instance of the
19681/// @ref array_type_def.
19682///
19683/// @param qn output parameter. Is set to the newly-built qualified
19684/// name of the current instance of @ref array_type_def.
19685///
19686/// @param internal set to true if the call is intended for an
19687/// internal use (for technical use inside the library itself), false
19688/// otherwise. If you don't know what this is for, then set it to
19689/// false.
19690void
19692{qn = get_qualified_name(internal);}
19693
19694/// Compute the qualified name of the array.
19695///
19696/// @param internal set to true if the call is intended for an
19697/// internal use (for technical use inside the library itself), false
19698/// otherwise. If you don't know what this is for, then set it to
19699/// false.
19700///
19701/// @return the resulting qualified name.
19702const interned_string&
19704{
19705 if (internal)
19706 {
19707 if (get_canonical_type())
19708 {
19709 if (priv_->internal_qualified_name_.empty())
19710 priv_->internal_qualified_name_ =
19711 array_declaration_name(this, /*variable_name=*/"",
19712 /*qualified=*/false,
19713 /*internal=*/true);
19714 return priv_->internal_qualified_name_;
19715 }
19716 else
19717 {
19718 priv_->temp_internal_qualified_name_ =
19719 array_declaration_name(this, /*variable_name=*/"",
19720 /*qualified*/false, /*internal*/true);
19721 return priv_->temp_internal_qualified_name_;
19722 }
19723 }
19724 else
19725 {
19726 if (get_canonical_type())
19727 {
19728 if (decl_base::peek_qualified_name().empty())
19729 set_qualified_name(array_declaration_name(this,
19730 /*variable_name=*/"",
19731 /*qualified=*/false,
19732 /*internal=*/false));
19734 }
19735 else
19736 {
19738 (array_declaration_name(this, /*variable_name=*/"",
19739 /*qualified=*/false,
19740 /*internal=*/false));
19742 }
19743 }
19744}
19745
19746/// This implements the ir_traversable_base::traverse pure virtual
19747/// function.
19748///
19749/// @param v the visitor used on the current instance.
19750///
19751/// @return true if the entire IR node tree got traversed, false
19752/// otherwise.
19753bool
19755{
19756 if (v.type_node_has_been_visited(this))
19757 return true;
19758
19759 if (visiting())
19760 return true;
19761
19762 if (v.visit_begin(this))
19763 {
19764 visiting(true);
19765 if (type_base_sptr t = get_element_type())
19766 t->traverse(v);
19767 visiting(false);
19768 }
19769
19770 bool result = v.visit_end(this);
19772 return result;
19773}
19774
19775const location&
19776array_type_def::get_location() const
19777{return decl_base::get_location();}
19778
19779/// Get the array's subranges
19780const std::vector<array_type_def::subrange_sptr>&
19782{return priv_->subranges_;}
19783
19784array_type_def::~array_type_def()
19785{}
19786
19787// </array_type_def definitions>
19788
19789// <enum_type_decl definitions>
19790
19791class enum_type_decl::priv
19792{
19793 type_base_sptr underlying_type_;
19794 enumerators enumerators_;
19795 mutable enumerators sorted_enumerators_;
19796
19797 friend class enum_type_decl;
19798
19799 priv();
19800
19801public:
19802 priv(type_base_sptr underlying_type,
19804 : underlying_type_(underlying_type),
19805 enumerators_(enumerators)
19806 {}
19807}; // end class enum_type_decl::priv
19808
19809/// Constructor.
19810///
19811/// @param name the name of the type declaration.
19812///
19813/// @param locus the source location where the type was defined.
19814///
19815/// @param underlying_type the underlying type of the enum.
19816///
19817/// @param enums the enumerators of this enum type.
19818///
19819/// @param linkage_name the linkage name of the enum.
19820///
19821/// @param vis the visibility of the enum type.
19822enum_type_decl::enum_type_decl(const string& name,
19823 const location& locus,
19824 type_base_sptr underlying_type,
19825 enumerators& enums,
19826 const string& linkage_name,
19827 visibility vis)
19828 : type_or_decl_base(underlying_type->get_environment(),
19829 ENUM_TYPE
19830 | ABSTRACT_TYPE_BASE
19831 | ABSTRACT_DECL_BASE),
19832 type_base(underlying_type->get_environment(),
19833 underlying_type->get_size_in_bits(),
19834 underlying_type->get_alignment_in_bits()),
19835 decl_base(underlying_type->get_environment(),
19836 name, locus, linkage_name, vis),
19837 priv_(new priv(underlying_type, enums))
19838{
19840 for (enumerators::iterator e = get_enumerators().begin();
19841 e != get_enumerators().end();
19842 ++e)
19843 e->set_enum_type(this);
19844}
19845
19846/// Return the hash value of the current IR node.
19847///
19848/// Note that upon the first invocation, this member functions
19849/// computes the hash value and returns it. Subsequent invocations
19850/// just return the hash value that was previously calculated.
19851///
19852/// @return the hash value of the current IR node.
19853hash_t
19855{
19857 return h;
19858}
19859
19860/// Return the underlying type of the enum.
19861type_base_sptr
19863{return priv_->underlying_type_;}
19864
19865/// @return the list of enumerators of the enum.
19868{return priv_->enumerators_;}
19869
19870/// @return the list of enumerators of the enum.
19873{return priv_->enumerators_;}
19874
19875/// Get the lexicographically sorted vector of enumerators.
19876///
19877/// @return the lexicographically sorted vector of enumerators.
19880{
19881 if (priv_->sorted_enumerators_.empty())
19882 {
19883 for (auto e = get_enumerators().rbegin();
19884 e != get_enumerators().rend();
19885 ++e)
19886 priv_->sorted_enumerators_.push_back(*e);
19887
19888 std::sort(priv_->sorted_enumerators_.begin(),
19889 priv_->sorted_enumerators_.end(),
19890 [](const enum_type_decl::enumerator& l,
19892 {
19893 if (l.get_name() == r.get_name())
19894 return l.get_value() < r.get_value();
19895 return (l.get_name() < r.get_name());
19896 });
19897 }
19898
19899 return priv_->sorted_enumerators_;
19900}
19901
19902/// Get the pretty representation of the current instance of @ref
19903/// enum_type_decl.
19904///
19905/// @param internal set to true if the call is intended to get a
19906/// representation of the decl (or type) for the purpose of canonical
19907/// type comparison. This is mainly used in the function
19908/// type_base::get_canonical_type_for().
19909///
19910/// In other words if the argument for this parameter is true then the
19911/// call is meant for internal use (for technical use inside the
19912/// library itself), false otherwise. If you don't know what this is
19913/// for, then set it to false.
19914///
19915/// @param qualified_name if true, names emitted in the pretty
19916/// representation are fully qualified.
19917///
19918/// @return the pretty representation of the enum type.
19919string
19921 bool qualified_name) const
19922{
19923 string r = "enum ";
19924
19925 if (internal && get_is_anonymous())
19926 r += get_type_name(this, qualified_name, /*internal=*/true);
19927 else if (get_is_anonymous())
19928 r += get_enum_flat_representation(*this, "",
19929 /*one_line=*/true,
19930 qualified_name);
19931 else
19933 qualified_name);
19934 return r;
19935}
19936
19937/// This implements the ir_traversable_base::traverse pure virtual
19938/// function.
19939///
19940/// @param v the visitor used on the current instance.
19941///
19942/// @return true if the entire IR node tree got traversed, false
19943/// otherwise.
19944bool
19946{
19947 if (v.type_node_has_been_visited(this))
19948 return true;
19949
19950 if (visiting())
19951 return true;
19952
19953 if (v.visit_begin(this))
19954 {
19955 visiting(true);
19956 if (type_base_sptr t = get_underlying_type())
19957 t->traverse(v);
19958 visiting(false);
19959 }
19960
19961 bool result = v.visit_end(this);
19963 return result;
19964}
19965
19966/// Destructor for the enum type declaration.
19969
19970/// Test if two enums differ, but not by a name change.
19971///
19972/// @param l the first enum to consider.
19973///
19974/// @param r the second enum to consider.
19975///
19976/// @return true iff @p l differs from @p r by anything but a name
19977/// change.
19978bool
19980 const enum_type_decl& r,
19981 change_kind* k)
19982{
19983 bool result = false;
19985 {
19986 result = true;
19987 if (k)
19988 *k |= SUBTYPE_CHANGE_KIND;
19989 else
19990 return true;
19991 }
19992
19993 enum_type_decl::enumerators::const_iterator i, j;
19994 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
19995 i != l.get_enumerators().end() && j != r.get_enumerators().end();
19996 ++i, ++j)
19997 if (*i != *j)
19998 {
19999 result = true;
20000 if (k)
20001 {
20003 break;
20004 }
20005 else
20006 return true;
20007 }
20008
20009 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
20010 {
20011 result = true;
20012 if (k)
20014 else
20015 return true;
20016 }
20017
20018 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
20021 string n_l = l.get_name();
20022 string n_r = r.get_name();
20023 local_r.set_qualified_name(qn_l);
20024 local_r.set_name(n_l);
20025
20026 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
20027 {
20028 result = true;
20029 if (k)
20030 {
20031 if (!l.decl_base::operator==(r))
20033 if (!l.type_base::operator==(r))
20035 }
20036 else
20037 {
20038 local_r.set_name(n_r);
20039 local_r.set_qualified_name(qn_r);
20040 return true;
20041 }
20042 }
20043 local_r.set_qualified_name(qn_r);
20044 local_r.set_name(n_r);
20045
20046 return result;
20047}
20048
20049/// Test if a given enumerator is found present in an enum.
20050///
20051/// This is a subroutine of the equals function for enums.
20052///
20053/// @param enr the enumerator to consider.
20054///
20055/// @param enom the enum to consider.
20056///
20057/// @return true iff the enumerator @p enr is present in the enum @p
20058/// enom.
20059bool
20061 const enum_type_decl &enom)
20062{
20063 for (const auto &e : enom.get_enumerators())
20064 if (e == enr)
20065 return true;
20066 return false;
20067}
20068
20069/// Check if two enumerators values are equal.
20070///
20071/// This function doesn't check if the names of the enumerators are
20072/// equal or not.
20073///
20074/// @param enr the first enumerator to consider.
20075///
20076/// @param enl the second enumerator to consider.
20077///
20078/// @return true iff @p enr has the same value as @p enl.
20079static bool
20080enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
20081 const enum_type_decl::enumerator &enl)
20082{return enr.get_value() == enl.get_value();}
20083
20084/// Detect if a given enumerator value is present in an enum.
20085///
20086/// This function looks inside the enumerators of a given enum and
20087/// detect if the enum contains at least one enumerator or a given
20088/// value. The function also detects if the enumerator value we are
20089/// looking at is present in the enum with a different name. An
20090/// enumerator with the same value but with a different name is named
20091/// a "redundant enumerator". The function returns the set of
20092/// enumerators that are redundant with the value we are looking at.
20093///
20094/// @param enr the enumerator to consider.
20095///
20096/// @param enom the enum to consider.
20097///
20098/// @param redundant_enrs if the function returns true, then this
20099/// vector is filled with enumerators that are redundant with the
20100/// value of @p enr.
20101///
20102/// @return true iff the function detects that @p enom contains
20103/// enumerators with the same value as @p enr.
20104static bool
20105is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
20106 const enum_type_decl &enom,
20107 vector<enum_type_decl::enumerator>& redundant_enrs)
20108{
20109 bool found = false;
20110 for (const auto &e : enom.get_enumerators())
20111 if (enumerators_values_are_equal(e, enr))
20112 {
20113 found = true;
20114 if (e != enr)
20115 redundant_enrs.push_back(e);
20116 }
20117
20118 return found;
20119}
20120
20121/// Check if an enumerator value is redundant in a given enum.
20122///
20123/// Given an enumerator value, this function detects if an enum
20124/// contains at least one enumerator with the the same value but with
20125/// a different name.
20126///
20127/// @param enr the enumerator to consider.
20128///
20129/// @param enom the enum to consider.
20130///
20131/// @return true iff @p enr is a redundant enumerator in enom.
20132static bool
20133is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
20134 const enum_type_decl &enom)
20135{
20136 vector<enum_type_decl::enumerator> redundant_enrs;
20137 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
20138 {
20139 if (!redundant_enrs.empty())
20140 return true;
20141 }
20142 return false;
20143}
20144
20145/// Compares two instances of @ref enum_type_decl.
20146///
20147/// If the two intances are different, set a bitfield to give some
20148/// insight about the kind of differences there are.
20149///
20150/// @param l the first artifact of the comparison.
20151///
20152/// @param r the second artifact of the comparison.
20153///
20154/// @param k a pointer to a bitfield that gives information about the
20155/// kind of changes there are between @p l and @p r. This one is set
20156/// iff @p k is non-null and the function returns false.
20157///
20158/// Please note that setting k to a non-null value does have a
20159/// negative performance impact because even if @p l and @p r are not
20160/// equal, the function keeps up the comparison in order to determine
20161/// the different kinds of ways in which they are different.
20162///
20163/// @return true if @p l equals @p r, false otherwise.
20164bool
20166{
20167 bool result = true;
20168
20169 //
20170 // Look through decl-only-enum.
20171 //
20172
20173 const enum_type_decl *def1 =
20176 : &l;
20177
20178 const enum_type_decl *def2 =
20181 : &r;
20182
20183 if (!!def1 != !!def2)
20184 {
20185 // One enum is decl-only while the other is not.
20186 // So the two enums are different.
20187 result = false;
20188 if (k)
20189 *k |= SUBTYPE_CHANGE_KIND;
20190 else
20192 }
20193
20194 //
20195 // At this point, both enums have the same state of decl-only-ness.
20196 // So we can compare oranges to oranges.
20197 //
20198
20199 if (!def1)
20200 def1 = &l;
20201 if (!def2)
20202 def2 = &r;
20203
20204 if (def1->get_underlying_type() != def2->get_underlying_type())
20205 {
20206 result = false;
20207 if (k)
20208 *k |= SUBTYPE_CHANGE_KIND;
20209 else
20211 }
20212
20213 if (!(def1->decl_base::operator==(*def2)
20214 && def1->type_base::operator==(*def2)))
20215 {
20216 result = false;
20217 if (k)
20218 {
20219 if (!def1->decl_base::operator==(*def2))
20221 if (!def1->type_base::operator==(*def2))
20223 }
20224 else
20226 }
20227
20228 // Now compare the enumerators.
20229
20230 // First in a naive (but potentially fast) way in case both enums
20231 // are equal in a naive manner.
20232
20233 if (def1->get_enumerators().size() == def2->get_enumerators().size())
20234 {
20235 bool equals = true;
20236 for (auto e1 = def1->get_enumerators().begin(),
20237 e2 = def2->get_enumerators().begin();
20238 (e1 != def1->get_enumerators().end()
20239 && e2 != def2->get_enumerators().end());
20240 ++e1, ++e2)
20241 {
20242 if (*e1 != *e2)
20243 {
20244 equals = false;
20245 break;
20246 }
20247 }
20248 if (equals)
20249 ABG_RETURN(result);
20250 }
20251
20252 // If the two enums where not naively equals, let's try a more
20253 // clever (and slow) way.
20254
20255 // Note that the order of declaration
20256 // of enumerators should not matter in the comparison.
20257 //
20258 // Also if an enumerator value is redundant, that shouldn't impact
20259 // the comparison.
20260 //
20261 // In that case, note that the two enums below are considered equal:
20262 //
20263 // enum foo
20264 // {
20265 // e0 = 0;
20266 // e1 = 1;
20267 // e2 = 2;
20268 // };
20269 //
20270 // enum foo
20271 // {
20272 // e0 = 0;
20273 // e1 = 1;
20274 // e2 = 2;
20275 // e_added = 1; // <-- this value is redundant with the value
20276 // // of the enumerator e1.
20277 // };
20278 //
20279 // Note however that in the case below, the enums are different.
20280 //
20281 // enum foo
20282 // {
20283 // e0 = 0;
20284 // e1 = 1;
20285 // };
20286 //
20287 // enum foo
20288 // {
20289 // e0 = 0;
20290 // e2 = 1; // <-- this enum value is present in the first version
20291 // // of foo, but is not redundant with any enumerator
20292 // // in the second version of of enum foo.
20293 // };
20294 //
20295 // These two enums are considered equal.
20296
20297 for(const auto &e : def1->get_enumerators())
20298 if (!is_enumerator_present_in_enum(e, *def2)
20299 && (!is_enumerator_value_redundant(e, *def2)
20300 || !is_enumerator_value_redundant(e, *def1)))
20301 {
20302 result = false;
20303 if (k)
20304 {
20306 break;
20307 }
20308 else
20310 }
20311
20312 for(const auto &e : def2->get_enumerators())
20313 if (!is_enumerator_present_in_enum(e, *def1)
20314 && (!is_enumerator_value_redundant(e, *def1)
20315 || !is_enumerator_value_redundant(e, *def2)))
20316 {
20317 result = false;
20318 if (k)
20319 {
20321 break;
20322 }
20323 else
20325 }
20326
20327 ABG_RETURN(result);
20328}
20329
20330/// Equality operator.
20331///
20332/// @param o the other enum to test against.
20333///
20334/// @return true iff @p o equals the current instance of enum type
20335/// decl.
20336bool
20338{
20339 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
20340 if (!op)
20341 return false;
20342 return try_canonical_compare(this, op);
20343}
20344
20345/// Equality operator.
20346///
20347/// @param o the other enum to test against.
20348///
20349/// @return true iff @p o is equals the current instance of enum type
20350/// decl.
20351bool
20353{
20354 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20355 if (!other)
20356 return false;
20357 return *this == *other;
20358}
20359
20360/// Equality operator for @ref enum_type_decl_sptr.
20361///
20362/// @param l the first operand to compare.
20363///
20364/// @param r the second operand to compare.
20365///
20366/// @return true iff @p l equals @p r.
20367bool
20369{
20370 if (!!l != !!r)
20371 return false;
20372 if (l.get() == r.get())
20373 return true;
20374 decl_base_sptr o = r;
20375 return *l == *o;
20376}
20377
20378/// Inequality operator for @ref enum_type_decl_sptr.
20379///
20380/// @param l the first operand to compare.
20381///
20382/// @param r the second operand to compare.
20383///
20384/// @return true iff @p l equals @p r.
20385bool
20387{return !operator==(l, r);}
20388
20389/// The type of the private data of an @ref
20390/// enum_type_decl::enumerator.
20391class enum_type_decl::enumerator::priv
20392{
20393 string name_;
20394 int64_t value_;
20395 string qualified_name_;
20396 enum_type_decl* enum_type_;
20397
20398 friend class enum_type_decl::enumerator;
20399
20400public:
20401
20402 priv()
20403 : enum_type_()
20404 {}
20405
20406 priv(const string& name,
20407 int64_t value,
20408 enum_type_decl* e = 0)
20409 : name_(name),
20410 value_(value),
20411 enum_type_(e)
20412 {}
20413}; // end class enum_type_def::enumerator::priv
20414
20415/// Default constructor of the @ref enum_type_decl::enumerator type.
20417 : priv_(new priv)
20418{}
20419
20420enum_type_decl::enumerator::~enumerator() = default;
20421
20422/// Constructor of the @ref enum_type_decl::enumerator type.
20423///
20424/// @param env the environment we are operating from.
20425///
20426/// @param name the name of the enumerator.
20427///
20428/// @param value the value of the enumerator.
20430 int64_t value)
20431 : priv_(new priv(name, value))
20432{}
20433
20434/// Copy constructor of the @ref enum_type_decl::enumerator type.
20435///
20436/// @param other enumerator to copy.
20438 : priv_(new priv(other.get_name(),
20439 other.get_value(),
20440 other.get_enum_type()))
20441{}
20442
20443/// Assignment operator of the @ref enum_type_decl::enumerator type.
20444///
20445/// @param o
20448{
20449 priv_->name_ = o.get_name();
20450 priv_->value_ = o.get_value();
20451 priv_->enum_type_ = o.get_enum_type();
20452 return *this;
20453}
20454
20455/// Equality operator
20456///
20457/// @param other the enumerator to compare to the current
20458/// instance of enum_type_decl::enumerator.
20459///
20460/// @return true if @p other equals the current instance of
20461/// enum_type_decl::enumerator.
20462bool
20464{
20465 bool names_equal = true;
20466 names_equal = (get_name() == other.get_name());
20467 return names_equal && (get_value() == other.get_value());
20468}
20469
20470/// Inequality operator.
20471///
20472/// @param other the other instance to compare against.
20473///
20474/// @return true iff @p other is different from the current instance.
20475bool
20477{return !operator==(other);}
20478
20479/// Getter for the name of the current instance of
20480/// enum_type_decl::enumerator.
20481///
20482/// @return a reference to the name of the current instance of
20483/// enum_type_decl::enumerator.
20484const string&
20486{return priv_->name_;}
20487
20488/// Getter for the qualified name of the current instance of
20489/// enum_type_decl::enumerator. The first invocation of the method
20490/// builds the qualified name, caches it and return a reference to the
20491/// cached qualified name. Subsequent invocations just return the
20492/// cached value.
20493///
20494/// @param internal set to true if the call is intended for an
20495/// internal use (for technical use inside the library itself), false
20496/// otherwise. If you don't know what this is for, then set it to
20497/// false.
20498///
20499/// @return the qualified name of the current instance of
20500/// enum_type_decl::enumerator.
20501const string&
20503{
20504 if (priv_->qualified_name_.empty())
20505 {
20506 priv_->qualified_name_ =
20507 get_enum_type()->get_qualified_name(internal)
20508 + "::"
20509 + get_name();
20510 }
20511 return priv_->qualified_name_;
20512}
20513
20514/// Setter for the name of @ref enum_type_decl::enumerator.
20515///
20516/// @param n the new name.
20517void
20519{priv_->name_ = n;}
20520
20521/// Getter for the value of @ref enum_type_decl::enumerator.
20522///
20523/// @return the value of the current instance of
20524/// enum_type_decl::enumerator.
20525int64_t
20527{return priv_->value_;}
20528
20529/// Setter for the value of @ref enum_type_decl::enumerator.
20530///
20531/// @param v the new value of the enum_type_decl::enumerator.
20532void
20534{priv_->value_= v;}
20535
20536/// Getter for the enum type that this enumerator is for.
20537///
20538/// @return the enum type that this enumerator is for.
20541{return priv_->enum_type_;}
20542
20543/// Setter for the enum type that this enumerator is for.
20544///
20545/// @param e the new enum type.
20546void
20549// </enum_type_decl definitions>
20550
20551// <typedef_decl definitions>
20552
20553/// Private data structure of the @ref typedef_decl.
20554struct typedef_decl::priv
20555{
20556 type_base_wptr underlying_type_;
20557
20558 priv(const type_base_sptr& t)
20559 : underlying_type_(t)
20560 {}
20561}; // end struct typedef_decl::priv
20562
20563/// Constructor of the typedef_decl type.
20564///
20565/// @param name the name of the typedef.
20566///
20567/// @param underlying_type the underlying type of the typedef.
20568///
20569/// @param locus the source location of the typedef declaration.
20570///
20571/// @param linkage_name the mangled name of the typedef.
20572///
20573/// @param vis the visibility of the typedef type.
20574typedef_decl::typedef_decl(const string& name,
20575 const type_base_sptr underlying_type,
20576 const location& locus,
20577 const string& linkage_name,
20578 visibility vis)
20579 : type_or_decl_base(underlying_type->get_environment(),
20580 TYPEDEF_TYPE
20581 | ABSTRACT_TYPE_BASE
20582 | ABSTRACT_DECL_BASE),
20583 type_base(underlying_type->get_environment(),
20584 underlying_type->get_size_in_bits(),
20585 underlying_type->get_alignment_in_bits()),
20586 decl_base(underlying_type->get_environment(),
20587 name, locus, linkage_name, vis),
20588 priv_(new priv(underlying_type))
20589{
20591}
20592
20593/// Constructor of the typedef_decl type.
20594///
20595/// @param name the name of the typedef.
20596///
20597/// @param env the environment of the current typedef.
20598///
20599/// @param locus the source location of the typedef declaration.
20600///
20601/// @param mangled_name the mangled name of the typedef.
20602///
20603/// @param vis the visibility of the typedef type.
20604typedef_decl::typedef_decl(const string& name,
20605 const environment& env,
20606 const location& locus,
20607 const string& mangled_name,
20608 visibility vis)
20609 : type_or_decl_base(env,
20610 TYPEDEF_TYPE
20611 | ABSTRACT_TYPE_BASE
20612 | ABSTRACT_DECL_BASE),
20613 type_base(env, /*size_in_bits=*/0,
20614 /*alignment_in_bits=*/0),
20615 decl_base(env, name, locus, mangled_name, vis),
20616 priv_(new priv(nullptr))
20617{
20619}
20620
20621/// Return the hash value of the current IR node.
20622///
20623/// Note that upon the first invocation, this member functions
20624/// computes the hash value and returns it. Subsequent invocations
20625/// just return the hash value that was previously calculated.
20626///
20627/// @return the hash value of the current IR node.
20628hash_t
20630{
20632 return h;
20633}
20634
20635/// Return the size of the typedef.
20636///
20637/// This function looks at the size of the underlying type and ensures
20638/// that it's the same as the size of the typedef.
20639///
20640/// @return the size of the typedef.
20641size_t
20643{
20644 if (!get_underlying_type())
20645 return 0;
20646 size_t s = get_underlying_type()->get_size_in_bits();
20647 if (s != type_base::get_size_in_bits())
20648 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
20650}
20651
20652/// Return the alignment of the typedef.
20653///
20654/// This function looks at the alignment of the underlying type and
20655/// ensures that it's the same as the alignment of the typedef.
20656///
20657/// @return the size of the typedef.
20658size_t
20660{
20661 if (!get_underlying_type())
20662 return 0;
20663 size_t s = get_underlying_type()->get_alignment_in_bits();
20665 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
20667}
20668
20669/// Compares two instances of @ref typedef_decl.
20670///
20671/// If the two intances are different, set a bitfield to give some
20672/// insight about the kind of differences there are.
20673///
20674/// @param l the first artifact of the comparison.
20675///
20676/// @param r the second artifact of the comparison.
20677///
20678/// @param k a pointer to a bitfield that gives information about the
20679/// kind of changes there are between @p l and @p r. This one is set
20680/// iff @p k is non-null and the function returns false.
20681///
20682/// Please note that setting k to a non-null value does have a
20683/// negative performance impact because even if @p l and @p r are not
20684/// equal, the function keeps up the comparison in order to determine
20685/// the different kinds of ways in which they are different.
20686///
20687/// @return true if @p l equals @p r, false otherwise.
20688bool
20690{
20691 bool result = true;
20692
20693 // No need to go further if the types have different names or
20694 // different size / alignment.
20695 if (!(l.decl_base::operator==(r)))
20696 {
20697 result = false;
20698 if (k)
20700 else
20702 }
20703
20705 {
20706 // Changes to the underlying type of a typedef are considered
20707 // local, a bit like for pointers.
20708 result = false;
20709 if (k)
20711 else
20713 }
20714
20715 ABG_RETURN(result);
20716}
20717
20718/// Equality operator
20719///
20720/// @param o the other typedef_decl to test against.
20721bool
20723{
20724 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
20725 if (!other)
20726 return false;
20727 return try_canonical_compare(this, other);
20728}
20729
20730/// Equality operator
20731///
20732/// @param o the other typedef_decl to test against.
20733///
20734/// @return true if the current instance of @ref typedef_decl equals
20735/// @p o.
20736bool
20738{
20739 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20740 if (!other)
20741 return false;
20742 return *this == *other;
20743}
20744
20745/// Build a pretty representation for a typedef_decl.
20746///
20747/// @param internal set to true if the call is intended to get a
20748/// representation of the decl (or type) for the purpose of canonical
20749/// type comparison. This is mainly used in the function
20750/// type_base::get_canonical_type_for().
20751///
20752/// In other words if the argument for this parameter is true then the
20753/// call is meant for internal use (for technical use inside the
20754/// library itself), false otherwise. If you don't know what this is
20755/// for, then set it to false.
20756
20757/// @param qualified_name if true, names emitted in the pretty
20758/// representation are fully qualified.
20759///
20760/// @return a copy of the pretty representation of the current
20761/// instance of typedef_decl.
20762string
20764 bool qualified_name) const
20765{
20766
20767 string result = "typedef ";
20768 if (qualified_name)
20769 result += get_qualified_name(internal);
20770 else
20771 result += get_name();
20772
20773 return result;
20774}
20775
20776/// Getter of the underlying type of the typedef.
20777///
20778/// @return the underlying_type.
20779type_base_sptr
20781{return priv_->underlying_type_.lock();}
20782
20783/// Setter ofthe underlying type of the typedef.
20784///
20785/// @param t the new underlying type of the typedef.
20786void
20788{
20789 priv_->underlying_type_ = t;
20790 set_size_in_bits(t->get_size_in_bits());
20791 set_alignment_in_bits(t->get_alignment_in_bits());
20792}
20793
20794/// Implementation of the virtual "get_qualified_name" method.
20795///
20796/// @param qualified_name the resuling qualified name of the typedef type.
20797///
20798/// @param internal if true, then it means the qualified name is for
20799/// "internal" purposes, meaning mainly for type canonicalization
20800/// purposes.
20801void
20803 bool internal) const
20804{qualified_name = get_qualified_name(internal);}
20805
20806/// Implementation of the virtual "get_qualified_name" method.
20807///
20808/// @param internal if true, then it means the qualified name is for
20809/// "internal" purposes, meaning mainly for type canonicalization
20810/// purposes.
20811///
20812/// @return the qualified name.
20813const interned_string&
20815{
20816 // Note that the qualified name has been already set by
20817 // qualified_name_setter::do_update, which is invoked by
20818 // update_qualified_name. The latter is itself invoked whenever the
20819 // typedef is added to its scope, in scope_decl::add_member_decl.
20820 if (internal)
20821 return decl_base::priv_->internal_qualified_name_;
20822 else
20823 return decl_base::priv_->qualified_name_;
20824}
20825
20826/// This implements the ir_traversable_base::traverse pure virtual
20827/// function.
20828///
20829/// @param v the visitor used on the current instance.
20830///
20831/// @return true if the entire IR node tree got traversed, false
20832/// otherwise.
20833bool
20835{
20836 if (v.type_node_has_been_visited(this))
20837 return true;
20838
20839 if (visiting())
20840 return true;
20841
20842 if (v.visit_begin(this))
20843 {
20844 visiting(true);
20845 if (type_base_sptr t = get_underlying_type())
20846 t->traverse(v);
20847 visiting(false);
20848 }
20849
20850 bool result = v.visit_end(this);
20852 return result;
20853}
20854
20855typedef_decl::~typedef_decl()
20856{}
20857// </typedef_decl definitions>
20858
20859// <var_decl definitions>
20860
20861struct var_decl::priv
20862{
20863 type_base_wptr type_;
20864 type_base* naked_type_;
20865 decl_base::binding binding_;
20866 elf_symbol_sptr symbol_;
20867 interned_string id_;
20868
20869 priv()
20870 : naked_type_(),
20871 binding_(decl_base::BINDING_GLOBAL)
20872 {}
20873
20874 priv(type_base_sptr t,
20876 : type_(t),
20877 naked_type_(t.get()),
20878 binding_(b)
20879 {}
20880
20881 /// Setter of the type of the variable.
20882 ///
20883 /// @param t the new variable type.
20884 void
20885 set_type(type_base_sptr t)
20886 {
20887 type_ = t;
20888 naked_type_ = t.get();
20889 }
20890}; // end struct var_decl::priv
20891
20892/// Constructor of the @ref var_decl type.
20893///
20894/// @param name the name of the variable declaration
20895///
20896/// @param type the type of the variable declaration
20897///
20898/// @param locus the source location where the variable was defined.
20899///
20900/// @param linkage_name the linkage name of the variable.
20901///
20902/// @param vis the visibility of of the variable.
20903///
20904/// @param bind the binding kind of the variable.
20905var_decl::var_decl(const string& name,
20906 type_base_sptr type,
20907 const location& locus,
20908 const string& linkage_name,
20909 visibility vis,
20910 binding bind)
20911 : type_or_decl_base(type->get_environment(),
20912 VAR_DECL | ABSTRACT_DECL_BASE),
20913 decl_base(type->get_environment(), name, locus, linkage_name, vis),
20914 priv_(new priv(type, bind))
20915{
20917}
20918
20919/// Getter of the type of the variable.
20920///
20921/// @return the type of the variable.
20922const type_base_sptr
20924{return priv_->type_.lock();}
20925
20926/// Setter of the type of the variable.
20927///
20928/// @param the new type of the variable.
20929void
20930var_decl::set_type(type_base_sptr& t)
20931{priv_->set_type(t);}
20932
20933/// Getter of the type of the variable.
20934///
20935/// This getter returns a bare pointer, as opposed to a smart pointer.
20936/// It's to be used on performance sensitive code paths identified by
20937/// careful profiling.
20938///
20939/// @return the type of the variable, as a bare pointer.
20940const type_base*
20942{return priv_->naked_type_;}
20943
20944/// Getter of the binding of the variable.
20945///
20946/// @return the biding of the variable.
20949{return priv_->binding_;}
20950
20951/// Setter of the binding of the variable.
20952///
20953/// @param b the new binding value.
20954void
20956{priv_->binding_ = b;}
20957
20958/// Sets the underlying ELF symbol for the current variable.
20959///
20960/// And underlyin$g ELF symbol for the current variable might exist
20961/// only if the corpus that this variable originates from was
20962/// constructed from an ELF binary file.
20963///
20964/// Note that comparing two variables that have underlying ELF symbols
20965/// involves comparing their underlying elf symbols. The decl name
20966/// for the variable thus becomes irrelevant in the comparison.
20967///
20968/// @param sym the new ELF symbol for this variable decl.
20969void
20971{
20972 priv_->symbol_ = sym;
20973 // The variable id cache that depends on the symbol must be
20974 // invalidated because the symbol changed.
20975 priv_->id_ = get_environment().intern("");
20976}
20977
20978/// Gets the the underlying ELF symbol for the current variable,
20979/// that was set using var_decl::set_symbol(). Please read the
20980/// documentation for that member function for more information about
20981/// "underlying ELF symbols".
20982///
20983/// @return sym the underlying ELF symbol for this variable decl, if
20984/// one exists.
20985const elf_symbol_sptr&
20987{return priv_->symbol_;}
20988
20989/// Create a new var_decl that is a clone of the current one.
20990///
20991/// @return the cloned var_decl.
20994{
20996 get_type(),
20997 get_location(),
21000 get_binding()));
21001
21002 v->set_symbol(get_symbol());
21003
21004 if (is_member_decl(*this))
21005 {
21009 get_member_is_static(*this),
21010 get_data_member_offset(*this));
21011 }
21012 else
21014
21015 return v;
21016}
21017/// Setter of the scope of the current var_decl.
21018///
21019/// Note that the decl won't hold a reference on the scope. It's
21020/// rather the scope that holds a reference on its members.
21021///
21022/// @param scope the new scope.
21023void
21024var_decl::set_scope(scope_decl* scope)
21025{
21026 if (!get_context_rel())
21027 set_context_rel(new dm_context_rel(scope));
21028 else
21029 get_context_rel()->set_scope(scope);
21030}
21031
21032/// Compares two instances of @ref var_decl without taking their type
21033/// into account.
21034///
21035/// If the two intances are different modulo their type, set a
21036/// bitfield to give some insight about the kind of differences there
21037/// are.
21038///
21039/// @param l the first artifact of the comparison.
21040///
21041/// @param r the second artifact of the comparison.
21042///
21043/// @param k a pointer to a bitfield that gives information about the
21044/// kind of changes there are between @p l and @p r. This one is set
21045/// iff @p k is non-null and the function returns false.
21046///
21047/// Please note that setting k to a non-null value does have a
21048/// negative performance impact because even if @p l and @p r are not
21049/// equal, the function keeps up the comparison in order to determine
21050/// the different kinds of ways in which they are different.
21051///
21052/// @return true if @p l equals @p r, false otherwise.
21053bool
21055{
21056 bool result = true;
21057
21058 // If there are underlying elf symbols for these variables,
21059 // compare them. And then compare the other parts.
21060 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
21061 if (!!s0 != !!s1)
21062 {
21063 result = false;
21064 if (k)
21066 else
21068 }
21069 else if (s0 && s0 != s1)
21070 {
21071 result = false;
21072 if (k)
21074 else
21076 }
21077 bool symbols_are_equal = (s0 && s1 && result);
21078
21079 if (symbols_are_equal)
21080 {
21081 // The variables have underlying elf symbols that are equal, so
21082 // now, let's compare the decl_base part of the variables w/o
21083 // considering their decl names.
21084 const environment& env = l.get_environment();
21085 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
21086 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
21087 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
21088 bool decl_bases_different = !l.decl_base::operator==(r);
21089 const_cast<var_decl&>(l).set_qualified_name(n1);
21090 const_cast<var_decl&>(r).set_qualified_name(n2);
21091
21092 if (decl_bases_different)
21093 {
21094 result = false;
21095 if (k)
21097 else
21099 }
21100 }
21101 else
21102 if (!l.decl_base::operator==(r))
21103 {
21104 result = false;
21105 if (k)
21107 else
21109 }
21110
21111 const dm_context_rel* c0 =
21112 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
21113 const dm_context_rel* c1 =
21114 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
21115 ABG_ASSERT(c0 && c1);
21116
21117 if (*c0 != *c1)
21118 {
21119 result = false;
21120 if (k)
21122 else
21124 }
21125
21126 ABG_RETURN(result);
21127}
21128
21129/// Compares two instances of @ref var_decl.
21130///
21131/// If the two intances are different, set a bitfield to give some
21132/// insight about the kind of differences there are.
21133///
21134/// @param l the first artifact of the comparison.
21135///
21136/// @param r the second artifact of the comparison.
21137///
21138/// @param k a pointer to a bitfield that gives information about the
21139/// kind of changes there are between @p l and @p r. This one is set
21140/// iff @p k is non-null and the function returns false.
21141///
21142/// Please note that setting k to a non-null value does have a
21143/// negative performance impact because even if @p l and @p r are not
21144/// equal, the function keeps up the comparison in order to determine
21145/// the different kinds of ways in which they are different.
21146///
21147/// @return true if @p l equals @p r, false otherwise.
21148bool
21149equals(const var_decl& l, const var_decl& r, change_kind* k)
21150{
21151 bool result = true;
21152
21153 // First test types of variables. This should be fast because in
21154 // the general case, most types should be canonicalized.
21155 if (*l.get_naked_type() != *r.get_naked_type())
21156 {
21157 result = false;
21158 if (k)
21159 {
21161 r.get_naked_type()))
21162 *k |= (LOCAL_TYPE_CHANGE_KIND);
21163 else
21164 *k |= SUBTYPE_CHANGE_KIND;
21165 }
21166 else
21168 }
21169
21170 result &= var_equals_modulo_types(l, r, k);
21171
21172 ABG_RETURN(result);
21173}
21174
21175/// Comparison operator of @ref var_decl.
21176///
21177/// @param o the instance of @ref var_decl to compare against.
21178///
21179/// @return true iff the current instance of @ref var_decl equals @p o.
21180bool
21182{
21183 const var_decl* other = dynamic_cast<const var_decl*>(&o);
21184 if (!other)
21185 return false;
21186
21187 return equals(*this, *other, 0);
21188}
21189
21190/// Return an ID that tries to uniquely identify the variable inside a
21191/// program or a library.
21192///
21193/// So if the variable has an underlying elf symbol, the ID is the
21194/// concatenation of the symbol name and its version. Otherwise, the
21195/// ID is the linkage name if its non-null. Otherwise, it's the
21196/// pretty representation of the variable.
21197///
21198/// @return the ID.
21201{
21202 if (priv_->id_.empty())
21203 {
21204 string repr = get_name();
21205 string sym_str;
21206 if (elf_symbol_sptr s = get_symbol())
21207 sym_str = s->get_id_string();
21208 else if (!get_linkage_name().empty())
21209 sym_str = get_linkage_name();
21210
21211 const environment& env = get_type()->get_environment();
21212 priv_->id_ = env.intern(repr);
21213 if (!sym_str.empty())
21214 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
21215 }
21216 return priv_->id_;
21217}
21218
21219/// Get the qualified name of a given variable or data member.
21220///
21221///
21222/// Note that if the current instance of @ref var_decl is an anonymous
21223/// data member, then the qualified name is actually the flat
21224/// representation (the definition) of the type of the anonymous data
21225/// member. We chose the flat representation because otherwise, the
21226/// name of an *anonymous* data member is empty, by construction, e.g:
21227///
21228/// struct foo {
21229/// int a;
21230/// union {
21231/// char b;
21232/// char c;
21233/// }; // <---- this data member is anonymous.
21234/// int d;
21235/// }
21236///
21237/// The string returned for the anonymous member here is going to be:
21238///
21239/// "union {char b; char c}"
21240///
21241/// @param internal if true then this is for a purpose to the library,
21242/// otherwise, it's for being displayed to users.
21243///
21244/// @return the resulting qualified name.
21245const interned_string&
21247{
21248 if (is_anonymous_data_member(this)
21249 && decl_base::get_qualified_name().empty())
21250 {
21251 // Display the anonymous data member in a way that makes sense.
21252 string r = get_pretty_representation(internal);
21254 }
21255
21256 return decl_base::get_qualified_name(internal);
21257}
21258
21259/// Build and return the pretty representation of this variable.
21260///
21261/// @param internal set to true if the call is intended to get a
21262/// representation of the decl (or type) for the purpose of canonical
21263/// type comparison. This is mainly used in the function
21264/// type_base::get_canonical_type_for().
21265///
21266/// In other words if the argument for this parameter is true then the
21267/// call is meant for internal use (for technical use inside the
21268/// library itself), false otherwise. If you don't know what this is
21269/// for, then set it to false.
21270///
21271/// @param qualified_name if true, names emitted in the pretty
21272/// representation are fully qualified.
21273///
21274/// @return a copy of the pretty representation of this variable.
21275string
21276var_decl::get_pretty_representation(bool internal, bool qualified_name) const
21277{
21278 string result;
21279
21280 if (is_member_decl(this) && get_member_is_static(this))
21281 result = "static ";
21282
21283 // Detect if the current instance of var_decl is a member of
21284 // an anonymous class or union.
21285 bool member_of_anonymous_class = false;
21286 if (class_or_union* scope = is_at_class_scope(this))
21287 if (scope->get_is_anonymous())
21288 member_of_anonymous_class = true;
21289
21290 type_base_sptr type = get_type();
21291 if (is_array_type(type, /*look_through_qualifiers=*/true)
21292 || is_pointer_type(type, /*look_through_qualifiers=*/true)
21293 || is_reference_type(type, /*look_through_qualifiers=*/true)
21294 || is_ptr_to_mbr_type(type, /*look_through_qualifiers=*/true))
21295 {
21296 string name;
21297 if (member_of_anonymous_class || !qualified_name)
21298 name = get_name();
21299 else
21300 name = get_qualified_name(internal);
21301
21302 if (qualified_type_def_sptr q = is_qualified_type(type))
21303 {
21304 string quals_repr =
21305 get_string_representation_of_cv_quals(q->get_cv_quals());
21306 if (!quals_repr.empty())
21307 name = quals_repr + " " + name;
21308 type = peel_qualified_type(type);
21309 }
21310
21311 name = string(" ") + name;
21312 if (array_type_def_sptr t = is_array_type(type))
21313 result += array_declaration_name(t, name, qualified_name, internal);
21314 else if (pointer_type_def_sptr t = is_pointer_type(type))
21315 result += pointer_declaration_name(t, name, qualified_name, internal);
21316 else if (reference_type_def_sptr t = is_reference_type(type))
21317 result += pointer_declaration_name(t, name, qualified_name, internal);
21318 else if (ptr_to_mbr_type_sptr t = is_ptr_to_mbr_type(type))
21319 result += ptr_to_mbr_declaration_name(t, name,
21320 qualified_name,
21321 internal);
21322 }
21323 else
21324 {
21325 if (/*The current var_decl is to be used as an anonymous data
21326 member. */
21327 get_name().empty())
21328 {
21329 // Display the anonymous data member in a way that
21330 // makes sense.
21331 result +=
21334 "", /*one_line=*/true, internal);
21335 }
21336 else if (data_member_has_anonymous_type(this))
21337 {
21340 "", /*one_line=*/true, internal);
21341 result += " ";
21342 if (!internal
21343 && (member_of_anonymous_class || !qualified_name))
21344 // It doesn't make sense to name the member of an
21345 // anonymous class or union like:
21346 // "__anonymous__::data_member_name". So let's just use
21347 // its non-qualified name.
21348 result += get_name();
21349 else
21350 result += get_qualified_name(internal);
21351 }
21352 else
21353 {
21354 result +=
21356 + " ";
21357
21358 if (!internal
21359 && (member_of_anonymous_class || !qualified_name))
21360 // It doesn't make sense to name the member of an
21361 // anonymous class or union like:
21362 // "__anonymous__::data_member_name". So let's just use
21363 // its non-qualified name.
21364 result += get_name();
21365 else
21366 result += get_qualified_name(internal);
21367 }
21368 }
21369 return result;
21370}
21371
21372/// Get a name that is valid even for an anonymous data member.
21373///
21374/// If the current @ref var_decl is an anonymous data member, then
21375/// return its pretty representation. As of now, that pretty
21376/// representation is actually its flat representation as returned by
21377/// get_class_or_union_flat_representation().
21378///
21379/// Otherwise, just return the name of the current @ref var_decl.
21380///
21381/// @param qualified if true, return the qualified name. This doesn't
21382/// have an effet if the current @ref var_decl represents an anonymous
21383/// data member.
21384string
21386{
21387 string name;
21388 if (is_anonymous_data_member(this))
21389 // This function is used in the comparison engine to determine
21390 // which anonymous data member was deleted. So it's not involved
21391 // in type comparison or canonicalization. We don't want to use
21392 // the 'internal' version of the pretty presentation.
21393 name = get_pretty_representation(/*internal=*/false, qualified);
21394 else
21395 name = get_name();
21396
21397 return name;
21398}
21399
21400/// This implements the ir_traversable_base::traverse pure virtual
21401/// function.
21402///
21403/// @param v the visitor used on the current instance.
21404///
21405/// @return true if the entire IR node tree got traversed, false
21406/// otherwise.
21407bool
21409{
21410 if (visiting())
21411 return true;
21412
21413 if (v.visit_begin(this))
21414 {
21415 visiting(true);
21416 if (type_base_sptr t = get_type())
21417 t->traverse(v);
21418 visiting(false);
21419 }
21420 return v.visit_end(this);
21421}
21422
21423var_decl::~var_decl()
21424{}
21425
21426// </var_decl definitions>
21427
21428/// This function is automatically invoked whenever an instance of
21429/// this type is canonicalized.
21430///
21431/// It's an overload of the virtual type_base::on_canonical_type_set.
21432///
21433/// We put here what is thus meant to be executed only at the point of
21434/// type canonicalization.
21435void
21437{
21438 priv_->cached_name_.clear();
21439 priv_->internal_cached_name_.clear();
21440}
21441
21442/// The most straightforward constructor for the function_type class.
21443///
21444/// @param return_type the return type of the function type.
21445///
21446/// @param parms the list of parameters of the function type.
21447/// Stricto sensu, we just need a list of types; we are using a list
21448/// of parameters (where each parameter also carries the name of the
21449/// parameter and its source location) to try and provide better
21450/// diagnostics whenever it makes sense. If it appears that this
21451/// wasts too many resources, we can fall back to taking just a
21452/// vector of types here.
21453///
21454/// @param size_in_bits the size of this type, in bits.
21455///
21456/// @param alignment_in_bits the alignment of this type, in bits.
21457///
21458/// @param size_in_bits the size of this type.
21459function_type::function_type(type_base_sptr return_type,
21460 const parameters& parms,
21461 size_t size_in_bits,
21462 size_t alignment_in_bits)
21463 : type_or_decl_base(return_type->get_environment(),
21464 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21465 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21466 priv_(new priv(parms, return_type))
21467{
21469
21470 for (parameters::size_type i = 0, j = 1;
21471 i < priv_->parms_.size();
21472 ++i, ++j)
21473 {
21474 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21475 // If the first parameter is artificial, then it certainly
21476 // means that this is a member function, and the first
21477 // parameter is the implicit this pointer. In that case, set
21478 // the index of that implicit parameter to zero. Otherwise,
21479 // the index of the first parameter starts at one.
21480 j = 0;
21481 priv_->parms_[i]->set_index(j);
21482 }
21483}
21484
21485/// A constructor for a function_type that takes no parameters.
21486///
21487/// @param return_type the return type of this function_type.
21488///
21489/// @param size_in_bits the size of this type, in bits.
21490///
21491/// @param alignment_in_bits the alignment of this type, in bits.
21492function_type::function_type(type_base_sptr return_type,
21493 size_t size_in_bits, size_t alignment_in_bits)
21494 : type_or_decl_base(return_type->get_environment(),
21495 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21496 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21497 priv_(new priv(return_type))
21498{
21500}
21501
21502/// A constructor for a function_type that takes no parameter and
21503/// that has no return_type yet. These missing parts can (and must)
21504/// be added later.
21505///
21506/// @param env the environment we are operating from.
21507///
21508/// @param size_in_bits the size of this type, in bits.
21509///
21510/// @param alignment_in_bits the alignment of this type, in bits.
21511function_type::function_type(const environment& env,
21512 size_t size_in_bits,
21513 size_t alignment_in_bits)
21514 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21515 type_base(env, size_in_bits, alignment_in_bits),
21516 priv_(new priv)
21517{
21519}
21520
21521/// Return the hash value of the current IR node.
21522///
21523/// Note that upon the first invocation, this member functions
21524/// computes the hash value and returns it. Subsequent invocations
21525/// just return the hash value that was previously calculated.
21526///
21527/// @return the hash value of the current IR node.
21528hash_t
21530{
21532 return h;
21533}
21534
21535/// Getter for the return type of the current instance of @ref
21536/// function_type.
21537///
21538/// @return the return type.
21539type_base_sptr
21541{return priv_->return_type_.lock();}
21542
21543/// Setter of the return type of the current instance of @ref
21544/// function_type.
21545///
21546/// @param t the new return type to set.
21547void
21549{priv_->return_type_ = t;}
21550
21551/// Getter for the set of parameters of the current intance of @ref
21552/// function_type.
21553///
21554/// @return the parameters of the current instance of @ref
21555/// function_type.
21558{return priv_->parms_;}
21559
21560/// Get the Ith parameter of the vector of parameters of the current
21561/// instance of @ref function_type.
21562///
21563/// Note that the first parameter is at index 0. That parameter is
21564/// the first parameter that comes after the possible implicit "this"
21565/// parameter, when the current instance @ref function_type is for a
21566/// member function. Otherwise, if the current instance of @ref
21567/// function_type is for a non-member function, the parameter at index
21568/// 0 is the first parameter of the function.
21569///
21570///
21571/// @param i the index of the parameter to return. If i is greater
21572/// than the index of the last parameter, then this function returns
21573/// an empty parameter (smart) pointer.
21574///
21575/// @return the @p i th parameter that is not implicit.
21578{
21579 parameter_sptr result;
21580 if (dynamic_cast<const method_type*>(this))
21581 {
21582 if (i + 1 < get_parameters().size())
21583 result = get_parameters()[i + 1];
21584 }
21585 else
21586 {
21587 if (i < get_parameters().size())
21588 result = get_parameters()[i];
21589 }
21590 return result;
21591}
21592
21593/// Setter for the parameters of the current instance of @ref
21594/// function_type.
21595///
21596/// @param p the new vector of parameters to set.
21597void
21599{
21600 priv_->parms_ = p;
21601 for (parameters::size_type i = 0, j = 1;
21602 i < priv_->parms_.size();
21603 ++i, ++j)
21604 {
21605 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21606 // If the first parameter is artificial, then it certainly
21607 // means that this is a member function, and the first
21608 // parameter is the implicit this pointer. In that case, set
21609 // the index of that implicit parameter to zero. Otherwise,
21610 // the index of the first parameter starts at one.
21611 j = 0;
21612 priv_->parms_[i]->set_index(j);
21613 }
21614}
21615
21616/// Append a new parameter to the vector of parameters of the current
21617/// instance of @ref function_type.
21618///
21619/// @param parm the parameter to append.
21620void
21622{
21623 parm->set_index(priv_->parms_.size());
21624 priv_->parms_.push_back(parm);
21625}
21626
21627/// Test if the current instance of @ref function_type is for a
21628/// variadic function.
21629///
21630/// A variadic function is a function that takes a variable number of
21631/// arguments.
21632///
21633/// @return true iff the current instance of @ref function_type is for
21634/// a variadic function.
21635bool
21637{
21638 return (!priv_->parms_.empty()
21639 && priv_->parms_.back()->get_variadic_marker());
21640}
21641
21642/// Compare two function types.
21643///
21644/// In case these function types are actually method types, this
21645/// function avoids comparing two parameters (of the function types)
21646/// if the types of the parameters are actually the types of the
21647/// classes of the method types. This prevents infinite recursion
21648/// during the comparison of two classes that are structurally
21649/// identical.
21650///
21651/// This is a subroutine of the equality operator of function_type.
21652///
21653/// @param lhs the first function type to consider
21654///
21655/// @param rhs the second function type to consider
21656///
21657/// @param k a pointer to a bitfield set by the function to give
21658/// information about the kind of changes carried by @p lhs and @p
21659/// rhs. It is set iff @p k is non-null and the function returns
21660/// false.
21661///
21662/// Please note that setting k to a non-null value does have a
21663/// negative performance impact because even if @p l and @p r are not
21664/// equal, the function keeps up the comparison in order to determine
21665/// the different kinds of ways in which they are different.
21666///
21667///@return true if lhs == rhs, false otherwise.
21668bool
21670{
21671#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
21672
21674
21675 {
21676 // First of all, let's see if these two function types haven't
21677 // already been compared. If so, and if the result of the
21678 // comparison has been cached, let's just re-use it, rather than
21679 // comparing them all over again.
21680 bool cached_result = false;
21681 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
21682 cached_result))
21683 ABG_RETURN(cached_result);
21684 }
21685
21687
21688 bool result = true;
21689
21690 if (!l.type_base::operator==(r))
21691 {
21692 result = false;
21693 if (k)
21695 else
21696 RETURN(result);
21697 }
21698
21699 class_or_union* l_class = 0, *r_class = 0;
21700 if (const method_type* m = dynamic_cast<const method_type*>(&l))
21701 l_class = m->get_class_type().get();
21702
21703 if (const method_type* m = dynamic_cast<const method_type*>(&r))
21704 r_class = m->get_class_type().get();
21705
21706 // Compare the names of the class of the method
21707
21708 if (!!l_class != !!r_class)
21709 {
21710 result = false;
21711 if (k)
21713 else
21714 RETURN(result);
21715 }
21716 else if (l_class
21717 && (l_class->get_qualified_name()
21718 != r_class->get_qualified_name()))
21719 {
21720 result = false;
21721 if (k)
21723 else
21724 RETURN(result);
21725 }
21726
21727 // Then compare the return type; Beware if it's t's a class type
21728 // that is the same as the method class name; we can recurse for
21729 // ever in that case.
21730
21731 decl_base* l_return_type_decl =
21733 decl_base* r_return_type_decl =
21735 bool compare_result_types = true;
21736 string l_rt_name = l_return_type_decl
21737 ? l_return_type_decl->get_qualified_name()
21738 : string();
21739 string r_rt_name = r_return_type_decl
21740 ? r_return_type_decl->get_qualified_name()
21741 : string();
21742
21743 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
21744 ||
21745 (r_class && (r_class->get_qualified_name() == r_rt_name)))
21746 compare_result_types = false;
21747
21748 if (compare_result_types)
21749 {
21750 // Let's not consider typedefs when comparing return types to
21751 // avoid spurious changes.
21752 //
21753 // TODO: We should also do this for parameter types, or rather,
21754 // we should teach the equality operators in the IR, at some
21755 // point, to peel typedefs off.
21756 if (l.get_return_type() != r.get_return_type())
21757 {
21758 result = false;
21759 if (k)
21760 {
21762 r.get_return_type()))
21764 else
21765 *k |= SUBTYPE_CHANGE_KIND;
21766 }
21767 else
21768 RETURN(result);
21769 }
21770 }
21771 else
21772 if (l_rt_name != r_rt_name)
21773 {
21774 result = false;
21775 if (k)
21776 *k |= SUBTYPE_CHANGE_KIND;
21777 else
21778 RETURN(result);
21779 }
21780
21781 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
21782 for (i = l.get_first_parm(), j = r.get_first_parm();
21783 i != l.get_parameters().end() && j != r.get_parameters().end();
21784 ++i, ++j)
21785 {
21786 if (**i != **j)
21787 {
21788 result = false;
21789 if (k)
21790 {
21791 if (!types_have_similar_structure((*i)->get_type(),
21792 (*j)->get_type()))
21794 else
21795 *k |= SUBTYPE_CHANGE_KIND;
21796 }
21797 else
21798 RETURN(result);
21799 }
21800 }
21801
21802 if ((i != l.get_parameters().end()
21803 || j != r.get_parameters().end()))
21804 {
21805 result = false;
21806 if (k)
21808 else
21809 RETURN(result);
21810 }
21811
21812 RETURN(result);
21813#undef RETURN
21814}
21815
21816/// Get the first parameter of the function.
21817///
21818/// If the function is a non-static member function, the parameter
21819/// returned is the first one following the implicit 'this' parameter.
21820///
21821/// @return the first non implicit parameter of the function.
21822function_type::parameters::const_iterator
21824{
21825 if (get_parameters().empty())
21826 return get_parameters().end();
21827
21828 bool is_method = dynamic_cast<const method_type*>(this);
21829
21830 parameters::const_iterator i = get_parameters().begin();
21831
21832 if (is_method && (*i)->get_is_artificial())
21833 ++i;
21834
21835 return i;
21836}
21837
21838/// Get the first parameter of the function.
21839///
21840/// Note that if the function is a non-static member function, the
21841/// parameter returned is the implicit 'this' parameter.
21842///
21843/// @return the first parameter of the function.
21844function_type::parameters::const_iterator
21846{return get_parameters().begin();}
21847
21848/// Get the name of the current @ref function_type.
21849///
21850/// The name is retrieved from a cache. If the cache is empty, this
21851/// function computes the name of the type, stores it in the cache and
21852/// returns it. Subsequent invocation of the function are going to
21853/// just hit the cache.
21854///
21855/// Note that if the type is *NOT* canonicalized then function type
21856/// name is never cached.
21857///
21858/// @param internal if true then it means the function type name is
21859/// going to be used for purposes that are internal to libabigail
21860/// itself. If you don't know what this is then you probably should
21861/// set this parameter to 'false'.
21862///
21863/// @return the name of the function type.
21864const interned_string&
21866{
21867 if (internal)
21868 {
21870 {
21871 if (priv_->internal_cached_name_.empty())
21872 priv_->internal_cached_name_ =
21873 get_function_type_name(this, /*internal=*/true);
21874 return priv_->internal_cached_name_;
21875 }
21876 else
21877 {
21878 priv_->temp_internal_cached_name_ =
21879 get_function_type_name(this, /*internal=*/true);
21880 return priv_->temp_internal_cached_name_;
21881 }
21882 }
21883 else
21884 {
21886 {
21887 if (priv_->cached_name_.empty())
21888 priv_->cached_name_ =
21889 get_function_type_name(this, /*internal=*/false);
21890 return priv_->cached_name_;
21891 }
21892 else
21893 {
21894 priv_->cached_name_ =
21895 get_function_type_name(this, /*internal=*/false);
21896 return priv_->cached_name_;
21897 }
21898 }
21899}
21900
21901/// Equality operator for function_type.
21902///
21903/// @param o the other function_type to compare against.
21904///
21905/// @return true iff the two function_type are equal.
21906bool
21908{
21909 const function_type* o = dynamic_cast<const function_type*>(&other);
21910 if (!o)
21911 return false;
21912 return try_canonical_compare(this, o);
21913}
21914
21915/// Return a copy of the pretty representation of the current @ref
21916/// function_type.
21917///
21918/// @param internal set to true if the call is intended to get a
21919/// representation of the decl (or type) for the purpose of canonical
21920/// type comparison. This is mainly used in the function
21921/// type_base::get_canonical_type_for().
21922///
21923/// In other words if the argument for this parameter is true then the
21924/// call is meant for internal use (for technical use inside the
21925/// library itself), false otherwise. If you don't know what this is
21926/// for, then set it to false.
21927///
21928/// @return a copy of the pretty representation of the current @ref
21929/// function_type.
21930string
21932 bool /*qualified_name*/) const
21933{return ir::get_pretty_representation(this, internal);}
21934
21935/// Traverses an instance of @ref function_type, visiting all the
21936/// sub-types and decls that it might contain.
21937///
21938/// @param v the visitor that is used to visit every IR sub-node of
21939/// the current node.
21940///
21941/// @return true if either
21942/// - all the children nodes of the current IR node were traversed
21943/// and the calling code should keep going with the traversing.
21944/// - or the current IR node is already being traversed.
21945/// Otherwise, returning false means that the calling code should not
21946/// keep traversing the tree.
21947bool
21949{
21950 // TODO: should we allow the walker to avoid visiting function type
21951 // twice? I think that if we do, then ir_node_visitor needs an
21952 // option to specifically disallow this feature for function types.
21953
21954 if (visiting())
21955 return true;
21956
21957 if (v.visit_begin(this))
21958 {
21959 visiting(true);
21960 bool keep_going = true;
21961
21962 if (type_base_sptr t = get_return_type())
21963 {
21964 if (!t->traverse(v))
21965 keep_going = false;
21966 }
21967
21968 if (keep_going)
21969 for (parameters::const_iterator i = get_parameters().begin();
21970 i != get_parameters().end();
21971 ++i)
21972 if (type_base_sptr parm_type = (*i)->get_type())
21973 if (!parm_type->traverse(v))
21974 break;
21975
21976 visiting(false);
21977 }
21978 return v.visit_end(this);
21979}
21980
21981function_type::~function_type()
21982{}
21983// </function_type>
21984
21985// <method_type>
21986
21987struct method_type::priv
21988{
21989 class_or_union_wptr class_type_;
21990 bool is_const;
21991
21992 priv()
21993 : is_const()
21994 {}
21995}; // end struct method_type::priv
21996
21997/// Constructor for instances of method_type.
21998///
21999/// Instances of method_decl must be of type method_type.
22000///
22001/// @param return_type the type of the return value of the method.
22002///
22003/// @param class_type the base type of the method type. That is, the
22004/// type of the class the method belongs to.
22005///
22006/// @param p the vector of the parameters of the method.
22007///
22008/// @param is_const whether this method type is for a const method.
22009/// Note that const-ness is a property of the method *type* and of the
22010/// relationship between a method *declaration* and its scope.
22011///
22012/// @param size_in_bits the size of an instance of method_type,
22013/// expressed in bits.
22014///
22015/// @param alignment_in_bits the alignment of an instance of
22016/// method_type, expressed in bits.
22017method_type::method_type (type_base_sptr return_type,
22018 class_or_union_sptr class_type,
22019 const std::vector<function_decl::parameter_sptr>& p,
22020 bool is_const,
22021 size_t size_in_bits,
22022 size_t alignment_in_bits)
22023 : type_or_decl_base(class_type->get_environment(),
22024 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22025 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22026 function_type(return_type, p, size_in_bits, alignment_in_bits),
22027 priv_(new priv)
22028{
22030 set_class_type(class_type);
22031 set_is_const(is_const);
22032}
22033
22034/// Constructor of instances of method_type.
22035///
22036///Instances of method_decl must be of type method_type.
22037///
22038/// @param return_type the type of the return value of the method.
22039///
22040/// @param class_type the type of the class the method belongs to.
22041/// The actual (dynamic) type of class_type must be a pointer
22042/// class_type. We are setting it to pointer to type_base here to
22043/// help client code that is compiled without rtti and thus cannot
22044/// perform dynamic casts.
22045///
22046/// @param p the vector of the parameters of the method type.
22047///
22048/// @param is_const whether this method type is for a const method.
22049/// Note that const-ness is a property of the method *type* and of the
22050/// relationship between a method *declaration* and its scope.
22051///
22052/// @param size_in_bits the size of an instance of method_type,
22053/// expressed in bits.
22054///
22055/// @param alignment_in_bits the alignment of an instance of
22056/// method_type, expressed in bits.
22057method_type::method_type(type_base_sptr return_type,
22058 type_base_sptr class_type,
22059 const std::vector<function_decl::parameter_sptr>& p,
22060 bool is_const,
22061 size_t size_in_bits,
22062 size_t alignment_in_bits)
22063 : type_or_decl_base(class_type->get_environment(),
22064 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22065 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22066 function_type(return_type, p, size_in_bits, alignment_in_bits),
22067 priv_(new priv)
22068{
22070 set_class_type(is_class_type(class_type));
22071 set_is_const(is_const);
22072}
22073
22074/// Constructor of the qualified_type_def
22075///
22076/// @param env the environment we are operating from.
22077///
22078/// @param size_in_bits the size of the type, expressed in bits.
22079///
22080/// @param alignment_in_bits the alignment of the type, expressed in bits
22081method_type::method_type(const environment& env,
22082 size_t size_in_bits,
22083 size_t alignment_in_bits)
22084 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22085 type_base(env, size_in_bits, alignment_in_bits),
22086 function_type(env, size_in_bits, alignment_in_bits),
22087 priv_(new priv)
22088{
22090}
22091
22092/// Constructor of instances of method_type.
22093///
22094/// When constructed with this constructor, and instane of method_type
22095/// must set a return type using method_type::set_return_type
22096///
22097/// @param class_typ the base type of the method type. That is, the
22098/// type of the class (or union) the method belongs to.
22099///
22100/// @param size_in_bits the size of an instance of method_type,
22101/// expressed in bits.
22102///
22103/// @param alignment_in_bits the alignment of an instance of
22104/// method_type, expressed in bits.
22105method_type::method_type(class_or_union_sptr class_type,
22106 bool is_const,
22107 size_t size_in_bits,
22108 size_t alignment_in_bits)
22109 : type_or_decl_base(class_type->get_environment(),
22110 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22111 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22112 function_type(class_type->get_environment(),
22113 size_in_bits,
22114 alignment_in_bits),
22115 priv_(new priv)
22116{
22118 set_class_type(class_type);
22119 set_is_const(is_const);
22120}
22121
22122/// Return the hash value of the current IR node.
22123///
22124/// Note that upon the first invocation, this member functions
22125/// computes the hash value and returns it. Subsequent invocations
22126/// just return the hash value that was previously calculated.
22127///
22128/// @return the hash value of the current IR node.
22129hash_t
22131{
22133 return h;
22134}
22135
22136/// Get the class type this method belongs to.
22137///
22138/// @return the class type.
22139class_or_union_sptr
22141{return class_or_union_sptr(priv_->class_type_);}
22142
22143/// Sets the class type of the current instance of method_type.
22144///
22145/// The class type is the type of the class the method belongs to.
22146///
22147/// @param t the new class type to set.
22148void
22149method_type::set_class_type(const class_or_union_sptr& t)
22150{
22151 if (!t)
22152 return;
22153
22154 priv_->class_type_ = t;
22155}
22156
22157/// Return a copy of the pretty representation of the current @ref
22158/// method_type.
22159///
22160/// @param internal set to true if the call is intended to get a
22161/// representation of the decl (or type) for the purpose of canonical
22162/// type comparison. This is mainly used in the function
22163/// type_base::get_canonical_type_for().
22164///
22165/// In other words if the argument for this parameter is true then the
22166/// call is meant for internal use (for technical use inside the
22167/// library itself), false otherwise. If you don't know what this is
22168/// for, then set it to false.
22169///
22170/// @return a copy of the pretty representation of the current @ref
22171/// method_type.
22172string
22174 bool /*qualified_name*/) const
22175{return ir::get_pretty_representation(*this, internal);}
22176
22177/// Setter of the "is-const" property of @ref method_type.
22178///
22179/// @param the new value of the "is-const" property.
22180void
22182{priv_->is_const = f;}
22183
22184/// Getter of the "is-const" property of @ref method_type.
22185///
22186/// @return true iff the "is-const" property was set.
22187bool
22189{return priv_->is_const;}
22190
22191/// Test if the current method type is for a static method or not.
22192///
22193/// @return true iff the current method_type denotes a the type of a
22194/// static method.
22195bool
22197{
22198 // Let's see if the first parameter is artificial and is a pointer
22199 // to an instance of the same class type as the current class.
22201 if (!get_parameters().empty())
22202 first_parm = get_parameters()[0];
22203 if (!first_parm)
22204 return true;
22205 if (!first_parm->get_is_artificial())
22206 return true;
22207
22208 type_base_sptr this_ptr_type = first_parm->get_type();
22209 // Sometimes, the type of the "this" pointer is "const class_type*
22210 // const". Meaning that the "this pointer" itself is const
22211 // qualified. So let's get the underlying non-qualified pointer.
22212 this_ptr_type = peel_qualified_type(this_ptr_type);
22213 if (!is_pointer_type(this_ptr_type))
22214 return true;
22215
22216 type_base_sptr candidate_class_type =
22217 is_pointer_type(this_ptr_type)->get_pointed_to_type();
22218 candidate_class_type = peel_qualified_type(candidate_class_type);
22219 if (is_class_type(candidate_class_type)
22220 && get_type_name(candidate_class_type) == get_type_name(get_class_type()))
22221 // At this point, we are sure we are looking at a *non-static*
22222 // method.
22223 return false;
22224
22225 return true;
22226}
22227
22228/// The destructor of method_type
22231
22232// </method_type>
22233
22234// <function_decl definitions>
22235
22236struct function_decl::priv
22237{
22238 bool declared_inline_;
22239 decl_base::binding binding_;
22240 function_type_wptr type_;
22241 function_type* naked_type_;
22242 elf_symbol_sptr symbol_;
22243 interned_string id_;
22244
22245 priv()
22246 : declared_inline_(false),
22247 binding_(decl_base::BINDING_GLOBAL),
22248 naked_type_()
22249 {}
22250
22251 priv(function_type_sptr t,
22252 bool declared_inline,
22253 decl_base::binding binding)
22254 : declared_inline_(declared_inline),
22255 binding_(binding),
22256 type_(t),
22257 naked_type_(t.get())
22258 {}
22259
22260 priv(function_type_sptr t,
22261 bool declared_inline,
22262 decl_base::binding binding,
22264 : declared_inline_(declared_inline),
22265 binding_(binding),
22266 type_(t),
22267 naked_type_(t.get()),
22268 symbol_(s)
22269 {}
22270}; // end sruct function_decl::priv
22271
22272/// Constructor of the @ref function_decl.
22273///
22274/// @param name the name of the function.
22275///
22276/// @param function_type the type of the function.
22277///
22278/// @param declared_inline wether the function is declared inline.
22279///
22280/// @param locus the source location of the function.
22281///
22282/// @param mangled_name the linkage name of the function.
22283///
22284/// @param vis the visibility of the function.
22285///
22286/// @param bind the binding of the function.
22289 bool declared_inline,
22290 const location& locus,
22291 const string& mangled_name,
22292 visibility vis,
22293 binding bind)
22294 : type_or_decl_base(function_type->get_environment(),
22295 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22296 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
22297 priv_(new priv(function_type, declared_inline, bind))
22298{
22300}
22301
22302/// Constructor of the function_decl type.
22303///
22304/// This flavour of constructor is for when the pointer to the
22305/// instance of function_type that the client code has is presented as
22306/// a pointer to type_base. In that case, this constructor saves the
22307/// client code from doing a dynamic_cast to get the function_type
22308/// pointer.
22309///
22310/// @param name the name of the function declaration.
22311///
22312/// @param fn_type the type of the function declaration. The dynamic
22313/// type of this parameter should be 'pointer to function_type'
22314///
22315/// @param declared_inline whether this function was declared inline
22316///
22317/// @param locus the source location of the function declaration.
22318///
22319/// @param linkage_name the mangled name of the function declaration.
22320///
22321/// @param vis the visibility of the function declaration.
22322///
22323/// @param bind the kind of the binding of the function
22324/// declaration.
22326 type_base_sptr fn_type,
22327 bool declared_inline,
22328 const location& locus,
22329 const string& linkage_name,
22330 visibility vis,
22331 binding bind)
22332 : type_or_decl_base(fn_type->get_environment(),
22333 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22334 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
22335 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
22336 declared_inline,
22337 bind))
22338{
22340}
22341
22342/// Get the pretty representation of the current instance of @ref function_decl.
22343///
22344/// @param internal set to true if the call is intended to get a
22345/// representation of the decl (or type) for the purpose of canonical
22346/// type comparison. This is mainly used in the function
22347/// type_base::get_canonical_type_for().
22348///
22349/// In other words if the argument for this parameter is true then the
22350/// call is meant for internal use (for technical use inside the
22351/// library itself), false otherwise. If you don't know what this is
22352/// for, then set it to false.
22353///
22354/// @return the pretty representation for a function.
22355string
22357 bool qualified_name) const
22358{
22359 const method_decl* mem_fn =
22360 dynamic_cast<const method_decl*>(this);
22361
22362 string fn_prefix = mem_fn ? "method ": "function ";
22363 string result;
22364
22365 if (mem_fn
22366 && is_member_function(mem_fn)
22368 fn_prefix += "virtual ";
22369
22370 decl_base_sptr return_type;
22371 if ((mem_fn
22372 && is_member_function(mem_fn)
22373 && (get_member_function_is_dtor(*mem_fn)
22374 || get_member_function_is_ctor(*mem_fn))))
22375 /*cdtors do not have return types. */;
22376 else
22377 return_type = mem_fn
22378 ? get_type_declaration(mem_fn->get_type()->get_return_type())
22380
22381 result = get_pretty_representation_of_declarator(internal);
22382 if (return_type)
22383 {
22384 if (is_npaf_type(is_type(return_type))
22385 || !(is_pointer_to_function_type(is_type(return_type))
22386 || is_pointer_to_array_type(is_type(return_type))))
22387 result = get_type_name(is_type(return_type).get(), qualified_name,
22388 internal) + " " + result;
22389 else if (pointer_type_def_sptr p =
22391 result = add_outer_pointer_to_fn_type_expr(p, result,
22392 /*qualified=*/true,
22393 internal);
22394 else if(pointer_type_def_sptr p =
22395 is_pointer_to_array_type(is_type(return_type)))
22396 result = add_outer_pointer_to_array_type_expr(p, result,
22397 qualified_name,
22398 internal);
22399 else
22401 }
22402
22403 return fn_prefix + result;
22404}
22405
22406/// Compute and return the pretty representation for the part of the
22407/// function declaration that starts at the declarator. That is, the
22408/// return type and the other specifiers of the beginning of the
22409/// function's declaration ar omitted.
22410///
22411/// @param internal set to true if the call is intended to get a
22412/// representation of the decl (or type) for the purpose of canonical
22413/// type comparison. This is mainly used in the function
22414/// type_base::get_canonical_type_for().
22415///
22416/// In other words if the argument for this parameter is true then the
22417/// call is meant for internal use (for technical use inside the
22418/// library itself), false otherwise. If you don't know what this is
22419/// for, then set it to false.
22420///
22421/// @return the pretty representation for the part of the function
22422/// declaration that starts at the declarator.
22423string
22425{
22426 const method_decl* mem_fn =
22427 dynamic_cast<const method_decl*>(this);
22428
22429 string result;
22430
22431 if (mem_fn)
22432 {
22433 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
22434 + "::" + mem_fn->get_name();
22435 }
22436 else
22437 result += get_qualified_name();
22438
22439 std::ostringstream fn_parms;
22440 stream_pretty_representation_of_fn_parms(*get_type(),
22441 fn_parms,
22442 /*qualified=*/true,
22443 internal);
22444 result += fn_parms.str();
22445
22446 if (mem_fn
22447 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
22448 || is_method_type(mem_fn->get_type())->get_is_const()))
22449 result += " const";
22450
22451 return result;
22452}
22453
22454/// Getter for the first non-implicit parameter of a function decl.
22455///
22456/// If the function is a non-static member function, the parameter
22457/// returned is the first one following the implicit 'this' parameter.
22458///
22459/// @return the first non implicit parm.
22460function_decl::parameters::const_iterator
22462{
22463 if (get_parameters().empty())
22464 return get_parameters().end();
22465
22466 bool is_method = dynamic_cast<const method_decl*>(this);
22467
22468 parameters::const_iterator i = get_parameters().begin();
22469 if (is_method)
22470 ++i;
22471
22472 return i;
22473}
22474
22475/// Return the type of the current instance of @ref function_decl.
22476///
22477/// It's either a function_type or method_type.
22478/// @return the type of the current instance of @ref function_decl.
22479const shared_ptr<function_type>
22481{return priv_->type_.lock();}
22482
22483/// Fast getter of the type of the current instance of @ref function_decl.
22484///
22485/// Note that this function returns the underlying pointer managed by
22486/// the smart pointer returned by function_decl::get_type(). It's
22487/// faster than function_decl::get_type(). This getter is to be used
22488/// in code paths that are proven to be performance hot spots;
22489/// especially (for instance) when comparing function types. Those
22490/// are compared extremely frequently when libabigail is used to
22491/// handle huge binaries with a lot of functions.
22492///
22493/// @return the type of the current instance of @ref function_decl.
22494const function_type*
22496{return priv_->naked_type_;}
22497
22498void
22499function_decl::set_type(const function_type_sptr& fn_type)
22500{
22501 priv_->type_ = fn_type;
22502 priv_->naked_type_ = fn_type.get();
22503}
22504
22505/// This sets the underlying ELF symbol for the current function decl.
22506///
22507/// And underlyin$g ELF symbol for the current function decl might
22508/// exist only if the corpus that this function decl originates from
22509/// was constructed from an ELF binary file.
22510///
22511/// Note that comparing two function decls that have underlying ELF
22512/// symbols involves comparing their underlying elf symbols. The decl
22513/// name for the function thus becomes irrelevant in the comparison.
22514///
22515/// @param sym the new ELF symbol for this function decl.
22516void
22518{
22519 priv_->symbol_ = sym;
22520 // The function id cache that depends on the symbol must be
22521 // invalidated because the symbol changed.
22522 priv_->id_ = get_environment().intern("");
22523}
22524
22525/// Gets the the underlying ELF symbol for the current variable,
22526/// that was set using function_decl::set_symbol(). Please read the
22527/// documentation for that member function for more information about
22528/// "underlying ELF symbols".
22529///
22530/// @return sym the underlying ELF symbol for this function decl, if
22531/// one exists.
22532const elf_symbol_sptr&
22534{return priv_->symbol_;}
22535
22536/// Test if the function was declared inline.
22537///
22538/// @return true iff the function was declared inline.
22539bool
22541{return priv_->declared_inline_;}
22542
22543/// Set the property of the function being declared inline.
22544///
22545/// @param value true iff the function was declared inline.
22546void
22548{priv_->declared_inline_ = value;}
22549
22551function_decl::get_binding() const
22552{return priv_->binding_;}
22553
22554/// @return the return type of the current instance of function_decl.
22555const shared_ptr<type_base>
22557{return get_type()->get_return_type();}
22558
22559/// @return the parameters of the function.
22560const std::vector<shared_ptr<function_decl::parameter> >&
22562{return get_type()->get_parameters();}
22563
22564/// Append a parameter to the type of this function.
22565///
22566/// @param parm the parameter to append.
22567void
22568function_decl::append_parameter(shared_ptr<parameter> parm)
22569{get_type()->append_parameter(parm);}
22570
22571/// Append a vector of parameters to the type of this function.
22572///
22573/// @param parms the vector of parameters to append.
22574void
22575function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
22576{
22577 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
22578 i != parms.end();
22579 ++i)
22580 get_type()->append_parameter(*i);
22581}
22582
22583/// Create a new instance of function_decl that is a clone of the
22584/// current one.
22585///
22586/// @return the new clone.
22589{
22591 if (is_member_function(*this))
22592 {
22593 method_decl_sptr
22594 m(new method_decl(get_name(),
22595 get_type(),
22597 get_location(),
22600 get_binding()));
22602 ABG_ASSERT(scope);
22606 get_member_is_static(*this),
22610 f = m;
22611 }
22612 else
22613 {
22614 f.reset(new function_decl(get_name(),
22615 get_type(),
22617 get_location(),
22620 get_binding()));
22622 }
22623 f->set_symbol(get_symbol());
22624
22625 return f;
22626}
22627
22628/// Compares two instances of @ref function_decl.
22629///
22630/// If the two intances are different, set a bitfield to give some
22631/// insight about the kind of differences there are.
22632///
22633/// @param l the first artifact of the comparison.
22634///
22635/// @param r the second artifact of the comparison.
22636///
22637/// @param k a pointer to a bitfield that gives information about the
22638/// kind of changes there are between @p l and @p r. This one is set
22639/// iff @p k is non-null and the function returns false.
22640///
22641/// Please note that setting k to a non-null value does have a
22642/// negative performance impact because even if @p l and @p r are not
22643/// equal, the function keeps up the comparison in order to determine
22644/// the different kinds of ways in which they are different.
22645///
22646/// @return true if @p l equals @p r, false otherwise.
22647bool
22649{
22650 bool result = true;
22651
22652 // Compare function types
22653 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
22654 if (t0 == t1 || *t0 == *t1)
22655 ; // the types are equal, let's move on to compare the other
22656 // properties of the functions.
22657 else
22658 {
22659 result = false;
22660 if (k)
22661 {
22662 if (!types_have_similar_structure(t0, t1))
22664 else
22665 *k |= SUBTYPE_CHANGE_KIND;
22666 }
22667 else
22669 }
22670
22671 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
22672 if (!!s0 != !!s1)
22673 {
22674 result = false;
22675 if (k)
22677 else
22679 }
22680 else if (s0 && s0 != s1)
22681 {
22682 if (!elf_symbols_alias(s0, s1))
22683 {
22684 result = false;
22685 if (k)
22687 else
22689 }
22690 }
22691 bool symbols_are_equal = (s0 && s1 && result);
22692
22693 if (symbols_are_equal)
22694 {
22695 // The functions have underlying elf symbols that are equal,
22696 // so now, let's compare the decl_base part of the functions
22697 // w/o considering their decl names.
22698 interned_string n1 = l.get_name(), n2 = r.get_name();
22700 const_cast<function_decl&>(l).set_name("");
22701 const_cast<function_decl&>(l).set_linkage_name("");
22702 const_cast<function_decl&>(r).set_name("");
22703 const_cast<function_decl&>(r).set_linkage_name("");
22704
22705 bool decl_bases_different = !l.decl_base::operator==(r);
22706
22707 const_cast<function_decl&>(l).set_name(n1);
22708 const_cast<function_decl&>(l).set_linkage_name(ln1);
22709 const_cast<function_decl&>(r).set_name(n2);
22710 const_cast<function_decl&>(r).set_linkage_name(ln2);
22711
22712 if (decl_bases_different)
22713 {
22714 result = false;
22715 if (k)
22717 else
22719 }
22720 }
22721 else
22722 if (!l.decl_base::operator==(r))
22723 {
22724 result = false;
22725 if (k)
22727 else
22729 }
22730
22731 // Compare the remaining properties. Note that we don't take into
22732 // account the fact that the function was declared inline or not as
22733 // that doesn't have any impact on the final ABI.
22734 if (l.get_binding() != r.get_binding())
22735 {
22736 result = false;
22737 if (k)
22739 else
22741 }
22742
22744 {
22745 result = false;
22746 if (k)
22748 else
22750 }
22751
22753 {
22766 {
22767 result = false;
22768 if (k)
22770 else
22772 }
22773 }
22774
22775 ABG_RETURN(result);
22776}
22777
22778/// Comparison operator for @ref function_decl.
22779///
22780/// @param other the other instance of @ref function_decl to compare
22781/// against.
22782///
22783/// @return true iff the current instance of @ref function_decl equals
22784/// @p other.
22785bool
22787{
22788 const function_decl* o = dynamic_cast<const function_decl*>(&other);
22789 if (!o)
22790 return false;
22791 return equals(*this, *o, 0);
22792}
22793
22794/// Return true iff the function takes a variable number of
22795/// parameters.
22796///
22797/// @return true if the function taks a variable number
22798/// of parameters.
22799bool
22801{
22802 return (!get_parameters().empty()
22803 && get_parameters().back()->get_variadic_marker());
22804}
22805
22806/// Return an ID that tries to uniquely identify the function inside a
22807/// program or a library.
22808///
22809/// So if the function has an underlying elf symbol, the ID is the
22810/// concatenation of the symbol name and its version. Otherwise, the
22811/// ID is the linkage name if its non-null. Otherwise, it's the
22812/// pretty representation of the function.
22813///
22814/// @return the ID.
22817{
22818 if (priv_->id_.empty())
22819 {
22820 const environment& env = get_type()->get_environment();
22821 if (elf_symbol_sptr s = get_symbol())
22822 {
22823 string virtual_member_suffix;
22824 if (is_member_function(this))
22825 {
22826 method_decl* m = is_method_decl(this);
22827 ABG_ASSERT(m);
22829 {
22831 (m->get_type()->get_class_type(),
22832 /*look_through_decl_only=*/true))
22833 virtual_member_suffix += "/o";
22834 }
22835 }
22836 if (s->has_aliases())
22837 // The symbol has several aliases, so let's use a scheme
22838 // that allows all aliased functions to have different
22839 // IDs.
22840 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
22841 else
22842 // Let's use the full symbol name with its version as ID.
22843 priv_->id_ = env.intern(s->get_id_string());
22844
22845 if (!virtual_member_suffix.empty())
22846 priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
22847 }
22848 else if (!get_linkage_name().empty())
22849 priv_->id_= env.intern(get_linkage_name());
22850 else
22851 priv_->id_ = env.intern(get_pretty_representation());
22852 }
22853 return priv_->id_;
22854}
22855
22856/// Test if two function declarations are aliases.
22857///
22858/// Two functions declarations are aliases if their symbols are
22859/// aliases, in the ELF sense.
22860///
22861/// @param f1 the first function to consider.
22862///
22863/// @param f2 the second function to consider.
22864///
22865/// @return true iff @p f1 is an alias of @p f2
22866bool
22868{
22869 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
22870
22871 if (!s1 || !s2)
22872 return false;
22873
22874 return elf_symbols_alias(s1, s2);
22875}
22876
22877/// This implements the ir_traversable_base::traverse pure virtual
22878/// function.
22879///
22880/// @param v the visitor used on the current instance.
22881///
22882/// @return true if the entire IR node tree got traversed, false
22883/// otherwise.
22884bool
22886{
22887 if (visiting())
22888 return true;
22889
22890 if (v.visit_begin(this))
22891 {
22892 visiting(true);
22893 if (type_base_sptr t = get_type())
22894 t->traverse(v);
22895 visiting(false);
22896 }
22897 return v.visit_end(this);
22898}
22899
22900/// Destructor of the @ref function_decl type.
22902{delete priv_;}
22903
22904/// A deep comparison operator for a shared pointer to @ref function_decl
22905///
22906/// This function compares to shared pointers to @ref function_decl by
22907/// looking at the pointed-to instances of @ref function_dec
22908/// comparing them too. If the two pointed-to objects are equal then
22909/// this function returns true.
22910///
22911/// @param l the left-hand side argument of the equality operator.
22912///
22913/// @param r the right-hand side argument of the equality operator.
22914///
22915/// @return true iff @p l equals @p r.
22916bool
22918{
22919 if (l.get() == r.get())
22920 return true;
22921 if (!!l != !!r)
22922 return false;
22923
22924 return *l == *r;
22925}
22926
22927/// A deep inequality operator for smart pointers to functions.
22928///
22929/// @param l the left-hand side argument of the inequality operator.
22930///
22931/// @pram r the right-hand side argument of the inequality operator.
22932///
22933/// @return true iff @p is not equal to @p r.
22934bool
22936{return !operator==(l, r);}
22937
22938// <function_decl definitions>
22939
22940// <function_decl::parameter definitions>
22941
22942struct function_decl::parameter::priv
22943{
22944 type_base_wptr type_;
22945 unsigned index_;
22946 bool variadic_marker_;
22947
22948 priv()
22949 : index_(),
22950 variadic_marker_()
22951 {}
22952
22953 priv(type_base_sptr type,
22954 unsigned index,
22955 bool variadic_marker)
22956 : type_(type),
22957 index_(index),
22958 variadic_marker_(variadic_marker)
22959 {}
22960};// end struct function_decl::parameter::priv
22961
22962function_decl::parameter::parameter(const type_base_sptr type,
22963 unsigned index,
22964 const string& name,
22965 const location& loc,
22966 bool is_variadic)
22967 : type_or_decl_base(type->get_environment(),
22968 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22969 decl_base(type->get_environment(), name, loc),
22970 priv_(new priv(type, index, is_variadic))
22971{
22972 runtime_type_instance(this);
22973}
22974
22975function_decl::parameter::parameter(const type_base_sptr type,
22976 unsigned index,
22977 const string& name,
22978 const location& loc,
22979 bool is_variadic,
22980 bool is_artificial)
22981 : type_or_decl_base(type->get_environment(),
22982 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22983 decl_base(type->get_environment(), name, loc),
22984 priv_(new priv(type, index, is_variadic))
22985{
22986 runtime_type_instance(this);
22987 set_is_artificial(is_artificial);
22988}
22989
22990function_decl::parameter::parameter(const type_base_sptr type,
22991 const string& name,
22992 const location& loc,
22993 bool is_variadic,
22994 bool is_artificial)
22995 : type_or_decl_base(type->get_environment(),
22996 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22997 decl_base(type->get_environment(), name, loc),
22998 priv_(new priv(type, 0, is_variadic))
22999{
23000 runtime_type_instance(this);
23001 set_is_artificial(is_artificial);
23002}
23003
23004function_decl::parameter::parameter(const type_base_sptr type,
23005 unsigned index,
23006 bool variad)
23007 : type_or_decl_base(type->get_environment(),
23008 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23009 decl_base(type->get_environment(), "", location()),
23010 priv_(new priv(type, index, variad))
23011{
23012 runtime_type_instance(this);
23013}
23014
23015function_decl::parameter::~parameter() = default;
23016
23017const type_base_sptr
23018function_decl::parameter::get_type()const
23019{return priv_->type_.lock();}
23020
23021/// @return a copy of the type name of the parameter.
23022interned_string
23024{
23025 const environment& env = get_environment();
23026
23027 type_base_sptr t = get_type();
23028 string str;
23029 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
23030 str = "...";
23031 else
23032 {
23033 ABG_ASSERT(t);
23035 }
23036 return env.intern(str);
23037}
23038
23039/// @return a copy of the pretty representation of the type of the
23040/// parameter.
23041const string
23043{
23044 type_base_sptr t = get_type();
23045 string str;
23046 if (get_variadic_marker()
23047 || get_environment().is_variadic_parameter_type(t))
23048 str = "...";
23049 else
23050 {
23051 ABG_ASSERT(t);
23053 }
23054 return str;
23055}
23056
23057/// Get a name uniquely identifying the parameter in the function.
23058///
23059///@return the unique parm name id.
23062{
23063 const environment& env = get_environment();
23064
23065
23066 std::ostringstream o;
23067 o << "parameter-" << get_index();
23068
23069 return env.intern(o.str());
23070}
23071
23072unsigned
23073function_decl::parameter::get_index() const
23074{return priv_->index_;}
23075
23076void
23077function_decl::parameter::set_index(unsigned i)
23078{priv_->index_ = i;}
23079
23080
23081bool
23082function_decl::parameter::get_variadic_marker() const
23083{return priv_->variadic_marker_;}
23084
23085/// Compares two instances of @ref function_decl::parameter.
23086///
23087/// If the two intances are different, set a bitfield to give some
23088/// insight about the kind of differences there are.
23089///
23090/// @param l the first artifact of the comparison.
23091///
23092/// @param r the second artifact of the comparison.
23093///
23094/// @param k a pointer to a bitfield that gives information about the
23095/// kind of changes there are between @p l and @p r. This one is set
23096/// iff @p k is non-null and the function returns false.
23097///
23098/// Please note that setting k to a non-null value does have a
23099/// negative performance impact because even if @p l and @p r are not
23100/// equal, the function keeps up the comparison in order to determine
23101/// the different kinds of ways in which they are different.
23102///
23103/// @return true if @p l equals @p r, false otherwise.
23104bool
23106 const function_decl::parameter& r,
23107 change_kind* k)
23108{
23109 bool result = true;
23110
23111 if ((l.get_variadic_marker() != r.get_variadic_marker())
23112 || (l.get_index() != r.get_index())
23113 || (!!l.get_type() != !!r.get_type()))
23114 {
23115 result = false;
23116 if (k)
23117 {
23118 if (l.get_index() != r.get_index())
23120 if (l.get_variadic_marker() != r.get_variadic_marker()
23121 || !!l.get_type() != !!r.get_type())
23123 }
23124 else
23126 }
23127
23128 type_base_sptr l_type = l.get_type();
23129 type_base_sptr r_type = r.get_type();
23130
23131 if (l_type != r_type)
23132 {
23133 result = false;
23134 if (k)
23135 {
23136 if (!types_have_similar_structure(l_type, r_type))
23138 else
23139 *k |= SUBTYPE_CHANGE_KIND;
23140 }
23141 else
23143 }
23144
23145 ABG_RETURN(result);
23146}
23147
23148bool
23149function_decl::parameter::operator==(const parameter& o) const
23150{return equals(*this, o, 0);}
23151
23152bool
23153function_decl::parameter::operator==(const decl_base& o) const
23154{
23155 const function_decl::parameter* p =
23156 dynamic_cast<const function_decl::parameter*>(&o);
23157 if (!p)
23158 return false;
23159 return function_decl::parameter::operator==(*p);
23160}
23161
23162/// Non-member equality operator for @ref function_decl::parameter.
23163///
23164/// @param l the left-hand side of the equality operator
23165///
23166/// @param r the right-hand side of the equality operator
23167///
23168/// @return true iff @p l and @p r equals.
23169bool
23172{
23173 if (!!l != !!r)
23174 return false;
23175 if (!l)
23176 return true;
23177 return *l == *r;
23178}
23179
23180/// Non-member inequality operator for @ref function_decl::parameter.
23181///
23182/// @param l the left-hand side of the equality operator
23183///
23184/// @param r the right-hand side of the equality operator
23185///
23186/// @return true iff @p l and @p r different.
23187bool
23191
23192/// Traverse the diff sub-tree under the current instance
23193/// function_decl.
23194///
23195/// @param v the visitor to invoke on each diff node of the sub-tree.
23196///
23197/// @return true if the traversing has to keep going on, false
23198/// otherwise.
23199bool
23201{
23202 if (visiting())
23203 return true;
23204
23205 if (v.visit_begin(this))
23206 {
23207 visiting(true);
23208 if (type_base_sptr t = get_type())
23209 t->traverse(v);
23210 visiting(false);
23211 }
23212 return v.visit_end(this);
23213}
23214
23215/// Compute the qualified name of the parameter.
23216///
23217/// @param internal set to true if the call is intended for an
23218/// internal use (for technical use inside the library itself), false
23219/// otherwise. If you don't know what this is for, then set it to
23220/// false.
23221///
23222/// @param qn the resulting qualified name.
23223void
23225 bool /*internal*/) const
23226{qualified_name = get_name();}
23227
23228/// Compute and return a copy of the pretty representation of the
23229/// current function parameter.
23230///
23231/// @param internal set to true if the call is intended to get a
23232/// representation of the decl (or type) for the purpose of canonical
23233/// type comparison. This is mainly used in the function
23234/// type_base::get_canonical_type_for().
23235///
23236/// In other words if the argument for this parameter is true then the
23237/// call is meant for internal use (for technical use inside the
23238/// library itself), false otherwise. If you don't know what this is
23239/// for, then set it to false.
23240///
23241/// @return a copy of the textual representation of the current
23242/// function parameter.
23243string
23245 bool qualified_name) const
23246{
23247 const environment& env = get_environment();
23248
23249 string type_repr;
23250 type_base_sptr t = get_type();
23251 if (!t)
23252 type_repr = "void";
23253 else if (env.is_variadic_parameter_type(t))
23254 type_repr = "...";
23255 else
23256 type_repr = ir::get_type_name(t, qualified_name, internal);
23257
23258 string result = type_repr;
23259 string parm_name = get_name_id();
23260
23261 if (!parm_name.empty())
23262 result += " " + parm_name;
23263
23264 return result;
23265}
23266
23267// </function_decl::parameter definitions>
23268
23269// <class_or_union definitions>
23270
23271/// A Constructor for instances of @ref class_or_union
23272///
23273/// @param env the environment we are operating from.
23274///
23275/// @param name the identifier of the class.
23276///
23277/// @param size_in_bits the size of an instance of @ref
23278/// class_or_union, expressed in bits
23279///
23280/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23281/// expressed in bits.
23282///
23283/// @param locus the source location of declaration point this class.
23284///
23285/// @param vis the visibility of instances of @ref class_or_union.
23286///
23287/// @param mem_types the vector of member types of this instance of
23288/// @ref class_or_union.
23289///
23290/// @param data_members the vector of data members of this instance of
23291/// @ref class_or_union.
23292///
23293/// @param member_fns the vector of member functions of this instance
23294/// of @ref class_or_union.
23295class_or_union::class_or_union(const environment& env, const string& name,
23296 size_t size_in_bits, size_t align_in_bits,
23297 const location& locus, visibility vis,
23298 member_types& mem_types,
23300 member_functions& member_fns)
23301 : type_or_decl_base(env,
23302 ABSTRACT_TYPE_BASE
23303 | ABSTRACT_DECL_BASE
23304 | ABSTRACT_SCOPE_TYPE_DECL
23305 | ABSTRACT_SCOPE_DECL),
23306 decl_base(env, name, locus, name, vis),
23307 type_base(env, size_in_bits, align_in_bits),
23308 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23309 priv_(new priv(data_members, member_fns))
23310{
23311 for (member_types::iterator i = mem_types.begin();
23312 i != mem_types.end();
23313 ++i)
23316
23317 for (data_members::iterator i = data_members.begin();
23318 i != data_members.end();
23319 ++i)
23320 if (!has_scope(*i))
23321 add_decl_to_scope(*i, this);
23322
23323 for (member_functions::iterator i = member_fns.begin();
23324 i != member_fns.end();
23325 ++i)
23326 if (!has_scope(static_pointer_cast<decl_base>(*i)))
23327 add_decl_to_scope(*i, this);
23328}
23329
23330/// A constructor for instances of @ref class_or_union.
23331///
23332/// @param env the environment we are operating from.
23333///
23334/// @param name the name of the class.
23335///
23336/// @param size_in_bits the size of an instance of @ref
23337/// class_or_union, expressed in bits
23338///
23339/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23340/// expressed in bits.
23341///
23342/// @param locus the source location of declaration point this class.
23343///
23344/// @param vis the visibility of instances of @ref class_or_union.
23345class_or_union::class_or_union(const environment& env, const string& name,
23346 size_t size_in_bits, size_t align_in_bits,
23347 const location& locus, visibility vis)
23348 : type_or_decl_base(env,
23349 ABSTRACT_TYPE_BASE
23350 | ABSTRACT_DECL_BASE
23351 | ABSTRACT_SCOPE_TYPE_DECL
23352 | ABSTRACT_SCOPE_DECL),
23353 decl_base(env, name, locus, name, vis),
23354 type_base(env, size_in_bits, align_in_bits),
23355 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23356 priv_(new priv)
23357{}
23358
23359/// Constructor of the @ref class_or_union type.
23360///
23361/// @param env the @ref environment we are operating from.
23362///
23363/// @param name the name of the @ref class_or_union.
23364///
23365/// @param is_declaration_only a boolean saying whether the instance
23366/// represents a declaration only, or not.
23367class_or_union::class_or_union(const environment& env, const string& name,
23368 bool is_declaration_only)
23369 : type_or_decl_base(env,
23370 ABSTRACT_TYPE_BASE
23371 | ABSTRACT_DECL_BASE
23372 | ABSTRACT_SCOPE_TYPE_DECL
23373 | ABSTRACT_SCOPE_DECL),
23374 decl_base(env, name, location(), name),
23375 type_base(env, 0, 0),
23376 scope_type_decl(env, name, 0, 0, location()),
23377 priv_(new priv)
23378{
23379 set_is_declaration_only(is_declaration_only);
23380}
23381
23382/// Return the hash value of the current IR node.
23383///
23384/// Note that upon the first invocation, this member functions
23385/// computes the hash value and returns it. Subsequent invocations
23386/// just return the hash value that was previously calculated.
23387///
23388/// @return the hash value of the current IR node.
23389hash_t
23391{
23392 class_or_union::hash do_hash;
23393 hash_t h = do_hash(this);
23394 return h;
23395}
23396
23397/// This implements the ir_traversable_base::traverse pure virtual
23398/// function.
23399///
23400/// @param v the visitor used on the member nodes of the translation
23401/// unit during the traversal.
23402///
23403/// @return true if the entire IR node tree got traversed, false
23404/// otherwise.
23405bool
23407{
23408 if (v.type_node_has_been_visited(this))
23409 return true;
23410
23411 if (visiting())
23412 return true;
23413
23414 if (v.visit_begin(this))
23415 {
23416 visiting(true);
23417 bool stop = false;
23418
23419 if (!stop)
23420 for (data_members::const_iterator i = get_data_members().begin();
23421 i != get_data_members().end();
23422 ++i)
23423 if (!(*i)->traverse(v))
23424 {
23425 stop = true;
23426 break;
23427 }
23428
23429 if (!stop)
23430 for (member_functions::const_iterator i= get_member_functions().begin();
23431 i != get_member_functions().end();
23432 ++i)
23433 if (!(*i)->traverse(v))
23434 {
23435 stop = true;
23436 break;
23437 }
23438
23439 if (!stop)
23440 for (member_types::const_iterator i = get_member_types().begin();
23441 i != get_member_types().end();
23442 ++i)
23443 if (!(*i)->traverse(v))
23444 {
23445 stop = true;
23446 break;
23447 }
23448
23449 if (!stop)
23450 for (member_function_templates::const_iterator i =
23452 i != get_member_function_templates().end();
23453 ++i)
23454 if (!(*i)->traverse(v))
23455 {
23456 stop = true;
23457 break;
23458 }
23459
23460 if (!stop)
23461 for (member_class_templates::const_iterator i =
23463 i != get_member_class_templates().end();
23464 ++i)
23465 if (!(*i)->traverse(v))
23466 {
23467 stop = true;
23468 break;
23469 }
23470 visiting(false);
23471 }
23472
23473 bool result = v.visit_end(this);
23475 return result;
23476}
23477
23478/// Destrcutor of the @ref class_or_union type.
23480{delete priv_;}
23481
23482/// Add a member declaration to the current instance of class_or_union.
23483/// The member declaration can be either a member type, data member,
23484/// member function, or member template.
23485///
23486/// @param d the member declaration to add.
23487decl_base_sptr
23488class_or_union::add_member_decl(const decl_base_sptr& d)
23489{return insert_member_decl(d);}
23490
23491/// Remove a given decl from the current @ref class_or_union scope.
23492///
23493/// Note that only type declarations are supported by this method for
23494/// now. Support for the other kinds of declaration is left as an
23495/// exercise for the interested reader of the code.
23496///
23497/// @param decl the declaration to remove from this @ref
23498/// class_or_union scope.
23499void
23501{
23502 type_base_sptr t = is_type(decl);
23503
23504 // For now we want to support just removing types from classes. For
23505 // other kinds of IR node, we need more work.
23506 ABG_ASSERT(t);
23507
23509}
23510
23511/// Fixup the members of the type of an anonymous data member.
23512///
23513/// Walk all data members of (the type of) a given anonymous data
23514/// member and set a particular property of the relationship between
23515/// each data member and its containing type.
23516///
23517/// That property records the fact that the data member belongs to the
23518/// anonymous data member we consider.
23519///
23520/// In the future, if there are other properties of this relationship
23521/// to set in this manner, they ought to be added here.
23522///
23523/// @param anon_dm the anonymous data member to consider.
23524void
23526{
23527 class_or_union * anon_dm_type =
23529 if (!anon_dm_type)
23530 return;
23531
23532 for (class_or_union::data_members::const_iterator it =
23533 anon_dm_type->get_non_static_data_members().begin();
23534 it != anon_dm_type->get_non_static_data_members().end();
23535 ++it)
23536 {
23537 dm_context_rel *rel =
23538 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
23539 ABG_ASSERT(rel);
23540 rel->set_anonymous_data_member(anon_dm.get());
23541 }
23542}
23543
23544/// Getter of the alignment of the @ref class_or_union type.
23545///
23546/// If this @ref class_or_union is a declaration of a definition that
23547/// is elsewhere, then the size of the definition is returned.
23548///
23549/// @return the alignment of the @ref class_or_union type.
23550size_t
23559
23560/// Setter of the alignment of the class type.
23561///
23562/// If this class is a declaration of a definition that is elsewhere,
23563/// then the new alignment is set to the definition.
23564///
23565/// @param s the new alignment.
23566void
23575
23576/// Setter of the size of the @ref class_or_union type.
23577///
23578/// If this @ref class_or_union is a declaration of a definition that
23579/// is elsewhere, then the new size is set to the definition.
23580///
23581/// @param s the new size.
23582void
23591
23592/// Getter of the size of the @ref class_or_union type.
23593///
23594/// If this @ref class_or_union is a declaration of a definition that
23595/// is elsewhere, then the size of the definition is returned.
23596///
23597/// @return the size of the @ref class_or_union type.
23598size_t
23607
23608/// Get the number of anonymous member classes contained in this
23609/// class.
23610///
23611/// @return the number of anonymous member classes contained in this
23612/// class.
23613size_t
23615{
23616 int result = 0;
23617 for (member_types::const_iterator it = get_member_types().begin();
23618 it != get_member_types().end();
23619 ++it)
23620 if (class_decl_sptr t = is_class_type(*it))
23621 if (t->get_is_anonymous())
23622 ++result;
23623
23624 return result;
23625}
23626
23627/// Get the number of anonymous member unions contained in this class.
23628///
23629/// @return the number of anonymous member unions contained in this
23630/// class.
23631size_t
23633{
23634 int result = 0;
23635 for (member_types::const_iterator it = get_member_types().begin();
23636 it != get_member_types().end();
23637 ++it)
23638 if (union_decl_sptr t = is_union_type(*it))
23639 if (t->get_is_anonymous())
23640 ++result;
23641
23642 return result;
23643}
23644
23645/// Get the number of anonymous member enums contained in this class.
23646///
23647/// @return the number of anonymous member enums contained in this
23648/// class.
23649size_t
23651{
23652 int result = 0;
23653 for (member_types::const_iterator it = get_member_types().begin();
23654 it != get_member_types().end();
23655 ++it)
23656 if (enum_type_decl_sptr t = is_enum_type(*it))
23657 if (t->get_is_anonymous())
23658 ++result;
23659
23660 return result;
23661}
23662
23663/// Add a data member to the current instance of class_or_union.
23664///
23665/// @param v a var_decl to add as a data member. A proper
23666/// class_or_union::data_member is created from @p v and added to the
23667/// class_or_union. This var_decl should not have been already added
23668/// to a scope.
23669///
23670/// @param access the access specifier for the data member.
23671///
23672/// @param is_laid_out whether the data member was laid out. That is,
23673/// if its offset has been computed. In the pattern of a class
23674/// template for instance, this would be set to false.
23675///
23676/// @param is_static whether the data memer is static.
23677///
23678/// @param offset_in_bits if @p is_laid_out is true, this is the
23679/// offset of the data member, expressed (oh, surprise) in bits.
23680void
23682 bool is_laid_out, bool is_static,
23683 size_t offset_in_bits)
23684{
23685 ABG_ASSERT(!has_scope(v));
23686
23687 priv_->data_members_.push_back(v);
23689 set_data_member_is_laid_out(v, is_laid_out);
23690 set_data_member_offset(v, offset_in_bits);
23691 set_member_access_specifier(v, access);
23692 set_member_is_static(v, is_static);
23693
23694 // Add the variable to the set of static or non-static data members,
23695 // if it's not already in there.
23696 bool is_already_in = false;
23697 if (is_static)
23698 {
23699 for (const auto& s_dm: priv_->static_data_members_)
23700 {
23701 if (s_dm == v)
23702 {
23703 is_already_in = true;
23704 break;
23705 }
23706 }
23707 if (!is_already_in)
23708 priv_->static_data_members_.push_back(v);
23709 }
23710 else
23711 {
23712 // If this is a non-static variable, add it to the set of
23713 // non-static variables, if it's not already in there.
23714 for (data_members::const_iterator i =
23715 priv_->non_static_data_members_.begin();
23716 i != priv_->non_static_data_members_.end();
23717 ++i)
23718 if (*i == v)
23719 {
23720 is_already_in = true;
23721 break;
23722 }
23723 if (!is_already_in)
23724 priv_->non_static_data_members_.push_back(v);
23725 }
23726
23727 // If v is an anonymous data member, then fixup its data members.
23728 // For now, the only thing the fixup does is to make the data
23729 // members of the anonymous data member be aware of their containing
23730 // anonymous data member. That is helpful to compute the absolute
23731 // bit offset of each of the members of the anonymous data member.
23733}
23734
23735/// Get the data members of this @ref class_or_union.
23736///
23737/// @return a vector of the data members of this @ref class_or_union.
23740{return priv_->data_members_;}
23741
23742/// Find a data member of a given name in the current @ref class_or_union.
23743///
23744/// @param name the name of the data member to find in the current
23745/// @ref class_or_union.
23746///
23747/// @return a pointer to the @ref var_decl that represents the data
23748/// member to find inside the current @ref class_or_union.
23749const var_decl_sptr
23750class_or_union::find_data_member(const string& name) const
23751{
23752 for (data_members::const_iterator i = get_data_members().begin();
23753 i != get_data_members().end();
23754 ++i)
23755 if ((*i)->get_name() == name)
23756 return *i;
23757
23758 // We haven't found a data member with the name 'name'. Let's look
23759 // closer again, this time in our anonymous data members.
23760 for (data_members::const_iterator i = get_data_members().begin();
23761 i != get_data_members().end();
23762 ++i)
23764 {
23765 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
23766 ABG_ASSERT(type);
23767 if (var_decl_sptr data_member = type->find_data_member(name))
23768 return data_member;
23769 }
23770
23771 return var_decl_sptr();
23772}
23773
23774/// Find an anonymous data member in the class.
23775///
23776/// @param v the anonymous data member to find.
23777///
23778/// @return the anonymous data member found, or nil if none was found.
23779const var_decl_sptr
23781{
23782 if (!v->get_name().empty())
23783 return var_decl_sptr();
23784
23785 for (data_members::const_iterator it = get_non_static_data_members().begin();
23786 it != get_non_static_data_members().end();
23787 ++it)
23788 {
23789 if (is_anonymous_data_member(*it))
23790 if ((*it)->get_pretty_representation(/*internal=*/false, true)
23791 == v->get_pretty_representation(/*internal=*/false, true))
23792 return *it;
23793 }
23794
23795 return var_decl_sptr();
23796}
23797
23798/// Find a given data member.
23799///
23800/// This function takes a @ref var_decl as an argument. If it has a
23801/// non-empty name, then it tries to find a data member which has the
23802/// same name as the argument.
23803///
23804/// If it has an empty name, then the @ref var_decl is considered as
23805/// an anonymous data member. In that case, this function tries to
23806/// find an anonymous data member which type equals that of the @ref
23807/// var_decl argument.
23808///
23809/// @param v this carries either the name of the data member we need
23810/// to look for, or the type of the anonymous data member we are
23811/// looking for.
23812const var_decl_sptr
23814{
23815 if (!v)
23816 return var_decl_sptr();
23817
23818 if (v->get_name().empty())
23820
23821 return find_data_member(v->get_name());
23822}
23823
23824
23825/// Get the non-static data members of this @ref class_or_union.
23826///
23827/// @return a vector of the non-static data members of this @ref
23828/// class_or_union.
23831{return priv_->non_static_data_members_;}
23832
23833/// Get the static data memebers of this @ref class_or_union.
23834///
23835/// @return a vector of the static data members of this @ref
23836/// class_or_union.
23839{return priv_->static_data_members_;}
23840
23841/// Add a member function.
23842///
23843/// @param f the new member function to add.
23844///
23845/// @param a the access specifier to use for the new member function.
23846///
23847/// @param is_static whether the new member function is static.
23848///
23849/// @param is_ctor whether the new member function is a constructor.
23850///
23851/// @param is_dtor whether the new member function is a destructor.
23852///
23853/// @param is_const whether the new member function is const.
23854void
23857 bool is_static, bool is_ctor,
23858 bool is_dtor, bool is_const)
23859{
23860 ABG_ASSERT(!has_scope(f));
23861
23863
23864 set_member_function_is_ctor(f, is_ctor);
23865 set_member_function_is_dtor(f, is_dtor);
23867 set_member_is_static(f, is_static);
23868 set_member_function_is_const(f, is_const);
23869
23870 priv_->member_functions_.push_back(f);
23871
23872 // Update the map of linkage name -> member functions. It's useful,
23873 // so that class_or_union::find_member_function() can function.
23874 if (!f->get_linkage_name().empty())
23875 priv_->mem_fns_map_[f->get_linkage_name()] = f;
23876}
23877
23878/// Get the member functions of this @ref class_or_union.
23879///
23880/// @return a vector of the member functions of this @ref
23881/// class_or_union.
23884{return priv_->member_functions_;}
23885
23886/// Find a method, using its linkage name as a key.
23887///
23888/// @param linkage_name the linkage name of the method to find.
23889///
23890/// @return the method found, or nil if none was found.
23891const method_decl*
23892class_or_union::find_member_function(const string& linkage_name) const
23893{
23894 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
23895}
23896
23897/// Find a method, using its linkage name as a key.
23898///
23899/// @param linkage_name the linkage name of the method to find.
23900///
23901/// @return the method found, or nil if none was found.
23903class_or_union::find_member_function(const string& linkage_name)
23904{
23905 string_mem_fn_sptr_map_type::const_iterator i =
23906 priv_->mem_fns_map_.find(linkage_name);
23907 if (i == priv_->mem_fns_map_.end())
23908 return 0;
23909 return i->second.get();
23910}
23911
23912/// Find a method, using its linkage name as a key.
23913///
23914/// @param linkage_name the linkage name of the method to find.
23915///
23916/// @return the method found, or nil if none was found.
23917method_decl_sptr
23919{
23920 string_mem_fn_sptr_map_type::const_iterator i =
23921 priv_->mem_fns_map_.find(linkage_name);
23922 if (i == priv_->mem_fns_map_.end())
23923 return 0;
23924 return i->second;
23925}
23926
23927/// Find a method (member function) using its signature (pretty
23928/// representation) as a key.
23929///
23930/// @param s the signature of the method.
23931///
23932/// @return the method found, or nil if none was found.
23933const method_decl*
23935{
23936 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
23937}
23938
23939/// Find a method (member function) using its signature (pretty
23940/// representation) as a key.
23941///
23942/// @param s the signature of the method.
23943///
23944/// @return the method found, or nil if none was found.
23947{
23948 string_mem_fn_ptr_map_type::const_iterator i =
23949 priv_->signature_2_mem_fn_map_.find(s);
23950 if (i == priv_->signature_2_mem_fn_map_.end())
23951 return 0;
23952 return i->second;
23953}
23954
23955/// Get the member function templates of this class.
23956///
23957/// @return a vector of the member function templates of this class.
23958const member_function_templates&
23960{return priv_->member_function_templates_;}
23961
23962/// Get the member class templates of this class.
23963///
23964/// @return a vector of the member class templates of this class.
23965const member_class_templates&
23967{return priv_->member_class_templates_;}
23968
23969/// Append a member function template to the @ref class_or_union.
23970///
23971/// @param m the member function template to append.
23972void
23973class_or_union::add_member_function_template(member_function_template_sptr m)
23974{
23975 decl_base* c = m->as_function_tdecl()->get_scope();
23976 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
23977 /// error message or something like a structured error.
23978 priv_->member_function_templates_.push_back(m);
23979 if (!c)
23980 scope_decl::add_member_decl(m->as_function_tdecl());
23981}
23982
23983/// Append a member class template to the @ref class_or_union.
23984///
23985/// @param m the member function template to append.
23986void
23988{
23989 decl_base* c = m->as_class_tdecl()->get_scope();
23990 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
23991 /// error message or something like a structured error.
23992 m->set_scope(this);
23993 priv_->member_class_templates_.push_back(m);
23994 if (!c)
23995 scope_decl::add_member_decl(m->as_class_tdecl());
23996}
23997
23998///@return true iff the current instance has no member.
23999bool
24001{
24002 return (get_member_types().empty()
24003 && priv_->data_members_.empty()
24004 && priv_->member_functions_.empty()
24005 && priv_->member_function_templates_.empty()
24006 && priv_->member_class_templates_.empty());
24007}
24008
24009/// Insert a data member to this @ref class_or_union type.
24010///
24011/// @param d the data member to insert.
24012///
24013/// @return the decl @p that got inserted.
24014decl_base_sptr
24016{
24017 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
24018 {
24019 add_data_member(v, public_access,
24020 /*is_laid_out=*/false,
24021 /*is_static=*/true,
24022 /*offset_in_bits=*/0);
24023 d = v;
24024 }
24025 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24026 add_member_function(f, public_access,
24027 /*is_static=*/false,
24028 /*is_ctor=*/false,
24029 /*is_dtor=*/false,
24030 /*is_const=*/false);
24031 else if (member_function_template_sptr f =
24032 dynamic_pointer_cast<member_function_template>(d))
24034 else if (member_class_template_sptr c =
24035 dynamic_pointer_cast<member_class_template>(d))
24037 else
24039
24040 return d;
24041}
24042
24043/// Equality operator.
24044///
24045/// @param other the other @ref class_or_union to compare against.
24046///
24047/// @return true iff @p other equals the current @ref class_or_union.
24048bool
24050{
24051 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
24052 if (!op)
24053 return false;
24054
24055 // If this is a decl-only type (and thus with no canonical type),
24056 // use the canonical type of the definition, if any.
24057 const class_or_union *l = 0;
24059 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
24060 if (l == 0)
24061 l = this;
24062
24063 // Likewise for the other class.
24064 const class_or_union *r = 0;
24065 if (op->get_is_declaration_only())
24066 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
24067 if (r == 0)
24068 r = op;
24069
24070 return try_canonical_compare(l, r);
24071}
24072
24073/// Equality operator.
24074///
24075/// @param other the other @ref class_or_union to compare against.
24076///
24077/// @return true iff @p other equals the current @ref class_or_union.
24078bool
24080{
24081 const decl_base* o = dynamic_cast<const decl_base*>(&other);
24082 if (!o)
24083 return false;
24084 return *this == *o;
24085}
24086
24087/// Equality operator.
24088///
24089/// @param other the other @ref class_or_union to compare against.
24090///
24091/// @return true iff @p other equals the current @ref class_or_union.
24092bool
24094{
24095 const decl_base& o = other;
24097}
24098
24099/// Compares two instances of @ref class_or_union.
24100///
24101/// If the two intances are different, set a bitfield to give some
24102/// insight about the kind of differences there are.
24103///
24104/// @param l the first artifact of the comparison.
24105///
24106/// @param r the second artifact of the comparison.
24107///
24108/// @param k a pointer to a bitfield that gives information about the
24109/// kind of changes there are between @p l and @p r. This one is set
24110/// iff it's non-null and if the function returns false.
24111///
24112/// Please note that setting k to a non-null value does have a
24113/// negative performance impact because even if @p l and @p r are not
24114/// equal, the function keeps up the comparison in order to determine
24115/// the different kinds of ways in which they are different.
24116///
24117/// @return true if @p l equals @p r, false otherwise.
24118bool
24120{
24121 // if one of the classes is declaration-only, look through it to
24122 // get its definition.
24123 bool l_is_decl_only = l.get_is_declaration_only();
24124 bool r_is_decl_only = r.get_is_declaration_only();
24125 if (l_is_decl_only || r_is_decl_only)
24126 {
24127 const class_or_union* def1 = l_is_decl_only
24129 : &l;
24130
24131 const class_or_union* def2 = r_is_decl_only
24133 : &r;
24134
24135 if (!def1 || !def2)
24136 {
24137 if (!l.get_is_anonymous()
24138 && !r.get_is_anonymous()
24139 && l_is_decl_only && r_is_decl_only
24141 // The two decl-only classes differ from their size. A
24142 // true decl-only class should not have a size property to
24143 // begin with. This comes from a DWARF oddity and can
24144 // results in a false positive, so let's not consider that
24145 // change.
24146 return true;
24147
24151 {
24152 const interned_string& q1 = l.get_scoped_name();
24153 const interned_string& q2 = r.get_scoped_name();
24154 if (q1 == q2)
24155 // Not using RETURN(true) here, because that causes
24156 // performance issues. We don't need to do
24157 // l.priv_->unmark_as_being_compared({l,r}) here because
24158 // we haven't marked l or r as being compared yet, and
24159 // doing so has a peformance cost that shows up on
24160 // performance profiles for *big* libraries.
24161 return true;
24162 else
24163 {
24164 if (k)
24166 // Not using RETURN(true) here, because that causes
24167 // performance issues. We don't need to do
24168 // l.priv_->unmark_as_being_compared({l,r}) here because
24169 // we haven't marked l or r as being compared yet, and
24170 // doing so has a peformance cost that shows up on
24171 // performance profiles for *big* libraries.
24173 }
24174 }
24175 else // A decl-only class is considered different from a
24176 // class definition of the same name.
24177 {
24178 if (!!def1 != !!def2)
24179 {
24180 if (k)
24183 }
24184
24185 // both definitions are empty
24186 if (!(l.decl_base::operator==(r)
24187 && l.type_base::operator==(r)))
24188 {
24189 if (k)
24192 }
24193
24194 return true;
24195 }
24196 }
24197
24198 bool val = *def1 == *def2;
24199 if (!val)
24200 if (k)
24202 ABG_RETURN(val);
24203 }
24204
24205 // No need to go further if the classes have different names or
24206 // different size / alignment.
24207 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
24208 {
24209 if (k)
24212 }
24213
24214 if (types_defined_same_linux_kernel_corpus_public(l, r))
24215 return true;
24216
24217 //TODO: Maybe remove this (cycle detection and canonical type
24218 //propagation handling) from here and have it only in the equal
24219 //overload for class_decl and union_decl because this one ( the
24220 //equal overload for class_or_union) is just a sub-routine of these
24221 //two above.
24222#define RETURN(value) \
24223 return return_comparison_result(l, r, value);
24224
24226
24228
24229 bool result = true;
24230
24231 //compare data_members
24232 {
24233 if (l.get_non_static_data_members().size()
24234 != r.get_non_static_data_members().size())
24235 {
24236 result = false;
24237 if (k)
24239 else
24240 RETURN(result);
24241 }
24242
24243 for (class_or_union::data_members::const_iterator
24244 d0 = l.get_non_static_data_members().begin(),
24245 d1 = r.get_non_static_data_members().begin();
24246 (d0 != l.get_non_static_data_members().end()
24247 && d1 != r.get_non_static_data_members().end());
24248 ++d0, ++d1)
24249 if (**d0 != **d1)
24250 {
24251 result = false;
24252 if (k)
24253 {
24254 // Report any representation change as being local.
24255 if (!types_have_similar_structure((*d0)->get_type(),
24256 (*d1)->get_type())
24257 || (*d0)->get_type() == (*d1)->get_type())
24259 else
24260 *k |= SUBTYPE_CHANGE_KIND;
24261 }
24262 else
24263 RETURN(result);
24264 }
24265 }
24266
24267 // Do not compare member functions. DWARF does not necessarily
24268 // all the member functions, be they virtual or not, in all
24269 // translation units. So we cannot have a clear view of them, per
24270 // class
24271
24272 // compare member function templates
24273 {
24274 if (l.get_member_function_templates().size()
24275 != r.get_member_function_templates().size())
24276 {
24277 result = false;
24278 if (k)
24280 else
24281 RETURN(result);
24282 }
24283
24284 for (member_function_templates::const_iterator
24285 fn_tmpl_it0 = l.get_member_function_templates().begin(),
24286 fn_tmpl_it1 = r.get_member_function_templates().begin();
24287 fn_tmpl_it0 != l.get_member_function_templates().end()
24288 && fn_tmpl_it1 != r.get_member_function_templates().end();
24289 ++fn_tmpl_it0, ++fn_tmpl_it1)
24290 if (**fn_tmpl_it0 != **fn_tmpl_it1)
24291 {
24292 result = false;
24293 if (k)
24294 {
24296 break;
24297 }
24298 else
24299 RETURN(result);
24300 }
24301 }
24302
24303 // compare member class templates
24304 {
24305 if (l.get_member_class_templates().size()
24306 != r.get_member_class_templates().size())
24307 {
24308 result = false;
24309 if (k)
24311 else
24312 RETURN(result);
24313 }
24314
24315 for (member_class_templates::const_iterator
24316 cl_tmpl_it0 = l.get_member_class_templates().begin(),
24317 cl_tmpl_it1 = r.get_member_class_templates().begin();
24318 cl_tmpl_it0 != l.get_member_class_templates().end()
24319 && cl_tmpl_it1 != r.get_member_class_templates().end();
24320 ++cl_tmpl_it0, ++cl_tmpl_it1)
24321 if (**cl_tmpl_it0 != **cl_tmpl_it1)
24322 {
24323 result = false;
24324 if (k)
24325 {
24327 break;
24328 }
24329 else
24330 RETURN(result);
24331 }
24332 }
24333
24334 RETURN(result);
24335#undef RETURN
24336}
24337
24338
24339/// Copy a method of a @ref class_or_union into a new @ref
24340/// class_or_union.
24341///
24342/// @param t the @ref class_or_union into which the method is to be copied.
24343///
24344/// @param method the method to copy into @p t.
24345///
24346/// @return the resulting newly copied method.
24347method_decl_sptr
24348copy_member_function(const class_or_union_sptr& t,
24349 const method_decl_sptr& method)
24350{return copy_member_function(t, method.get());}
24351
24352
24353/// Copy a method of a @ref class_or_union into a new @ref
24354/// class_or_union.
24355///
24356/// @param t the @ref class_or_union into which the method is to be copied.
24357///
24358/// @param method the method to copy into @p t.
24359///
24360/// @return the resulting newly copied method.
24361method_decl_sptr
24362copy_member_function(const class_or_union_sptr& t, const method_decl* method)
24363{
24364 ABG_ASSERT(t);
24365 ABG_ASSERT(method);
24366
24367 method_type_sptr old_type = method->get_type();
24368 ABG_ASSERT(old_type);
24369 method_type_sptr new_type(new method_type(old_type->get_return_type(),
24370 t,
24371 old_type->get_parameters(),
24372 old_type->get_is_const(),
24373 old_type->get_size_in_bits(),
24374 old_type->get_alignment_in_bits()));
24375 t->get_translation_unit()->bind_function_type_life_time(new_type);
24376
24377 method_decl_sptr
24378 new_method(new method_decl(method->get_name(),
24379 new_type,
24380 method->is_declared_inline(),
24381 method->get_location(),
24382 method->get_linkage_name(),
24383 method->get_visibility(),
24384 method->get_binding()));
24385 new_method->set_symbol(method->get_symbol());
24386
24387 if (class_decl_sptr class_type = is_class_type(t))
24388 class_type->add_member_function(new_method,
24392 get_member_is_static(*method),
24396 else
24397 t->add_member_function(new_method,
24399 get_member_is_static(*method),
24403 return new_method;
24404}
24405
24406// </class_or_union definitions>
24407
24408// <class_decl definitions>
24409
24410static void
24411sort_virtual_member_functions(class_decl::member_functions& mem_fns);
24412
24413/// The private data for the class_decl type.
24414struct class_decl::priv
24415{
24416 base_specs bases_;
24417 unordered_map<string, base_spec_sptr> bases_map_;
24418 member_functions virtual_mem_fns_;
24419 virtual_mem_fn_map_type virtual_mem_fns_map_;
24420 bool is_struct_;
24421
24422 priv()
24423 : is_struct_(false)
24424 {}
24425
24426 priv(bool is_struct, class_decl::base_specs& bases)
24427 : bases_(bases),
24428 is_struct_(is_struct)
24429 {
24430 }
24431
24432 priv(bool is_struct)
24433 : is_struct_(is_struct)
24434 {}
24435};// end struct class_decl::priv
24436
24437/// A Constructor for instances of \ref class_decl
24438///
24439/// @param env the environment we are operating from.
24440///
24441/// @param name the identifier of the class.
24442///
24443/// @param size_in_bits the size of an instance of class_decl, expressed
24444/// in bits
24445///
24446/// @param align_in_bits the alignment of an instance of class_decl,
24447/// expressed in bits.
24448///
24449/// @param locus the source location of declaration point this class.
24450///
24451/// @param vis the visibility of instances of class_decl.
24452///
24453/// @param bases the vector of base classes for this instance of class_decl.
24454///
24455/// @param mbrs the vector of member types of this instance of
24456/// class_decl.
24457///
24458/// @param data_mbrs the vector of data members of this instance of
24459/// class_decl.
24460///
24461/// @param mbr_fns the vector of member functions of this instance of
24462/// class_decl.
24463class_decl::class_decl(const environment& env, const string& name,
24464 size_t size_in_bits, size_t align_in_bits,
24465 bool is_struct, const location& locus,
24466 visibility vis, base_specs& bases,
24467 member_types& mbr_types,
24468 data_members& data_mbrs,
24469 member_functions& mbr_fns)
24470 : type_or_decl_base(env,
24471 CLASS_TYPE
24472 | ABSTRACT_TYPE_BASE
24473 | ABSTRACT_DECL_BASE
24474 | ABSTRACT_SCOPE_TYPE_DECL
24475 | ABSTRACT_SCOPE_DECL),
24476 decl_base(env, name, locus, name, vis),
24477 type_base(env, size_in_bits, align_in_bits),
24478 class_or_union(env, name, size_in_bits, align_in_bits,
24479 locus, vis, mbr_types, data_mbrs, mbr_fns),
24480 priv_(new priv(is_struct, bases))
24481{
24483}
24484
24485/// A Constructor for instances of @ref class_decl
24486///
24487/// @param env the environment we are operating from.
24488///
24489/// @param name the identifier of the class.
24490///
24491/// @param size_in_bits the size of an instance of class_decl, expressed
24492/// in bits
24493///
24494/// @param align_in_bits the alignment of an instance of class_decl,
24495/// expressed in bits.
24496///
24497/// @param locus the source location of declaration point this class.
24498///
24499/// @param vis the visibility of instances of class_decl.
24500///
24501/// @param bases the vector of base classes for this instance of class_decl.
24502///
24503/// @param mbrs the vector of member types of this instance of
24504/// class_decl.
24505///
24506/// @param data_mbrs the vector of data members of this instance of
24507/// class_decl.
24508///
24509/// @param mbr_fns the vector of member functions of this instance of
24510/// class_decl.
24511///
24512/// @param is_anonymous whether the newly created instance is
24513/// anonymous.
24514class_decl::class_decl(const environment& env, const string& name,
24515 size_t size_in_bits, size_t align_in_bits,
24516 bool is_struct, const location& locus,
24517 visibility vis, base_specs& bases,
24518 member_types& mbr_types, data_members& data_mbrs,
24519 member_functions& mbr_fns, bool is_anonymous)
24520 : type_or_decl_base(env,
24521 CLASS_TYPE
24522 | ABSTRACT_TYPE_BASE
24523 | ABSTRACT_DECL_BASE
24524 | ABSTRACT_SCOPE_TYPE_DECL
24525 | ABSTRACT_SCOPE_DECL),
24526 decl_base(env, name, locus,
24527 // If the class is anonymous then by default it won't
24528 // have a linkage name. Also, the anonymous class does
24529 // have an internal-only unique name that is generally
24530 // not taken into account when comparing classes; such a
24531 // unique internal-only name, when used as a linkage
24532 // name might introduce spurious comparison false
24533 // negatives.
24534 /*linkage_name=*/is_anonymous ? string() : name,
24535 vis),
24536 type_base(env, size_in_bits, align_in_bits),
24537 class_or_union(env, name, size_in_bits, align_in_bits,
24538 locus, vis, mbr_types, data_mbrs, mbr_fns),
24539 priv_(new priv(is_struct, bases))
24540{
24542 set_is_anonymous(is_anonymous);
24543}
24544
24545/// A constructor for instances of class_decl.
24546///
24547/// @param env the environment we are operating from.
24548///
24549/// @param name the name of the class.
24550///
24551/// @param size_in_bits the size of an instance of class_decl, expressed
24552/// in bits
24553///
24554/// @param align_in_bits the alignment of an instance of class_decl,
24555/// expressed in bits.
24556///
24557/// @param locus the source location of declaration point this class.
24558///
24559/// @param vis the visibility of instances of class_decl.
24560class_decl::class_decl(const environment& env, const string& name,
24561 size_t size_in_bits, size_t align_in_bits,
24562 bool is_struct, const location& locus,
24563 visibility vis)
24564 : type_or_decl_base(env,
24565 CLASS_TYPE
24566 | ABSTRACT_TYPE_BASE
24567 | ABSTRACT_DECL_BASE
24568 | ABSTRACT_SCOPE_TYPE_DECL
24569 | ABSTRACT_SCOPE_DECL),
24570 decl_base(env, name, locus, name, vis),
24571 type_base(env, size_in_bits, align_in_bits),
24572 class_or_union(env, name, size_in_bits, align_in_bits,
24573 locus, vis),
24574 priv_(new priv(is_struct))
24575{
24577}
24578
24579/// A constructor for instances of @ref class_decl.
24580///
24581/// @param env the environment we are operating from.
24582///
24583/// @param name the name of the class.
24584///
24585/// @param size_in_bits the size of an instance of class_decl, expressed
24586/// in bits
24587///
24588/// @param align_in_bits the alignment of an instance of class_decl,
24589/// expressed in bits.
24590///
24591/// @param locus the source location of declaration point this class.
24592///
24593/// @param vis the visibility of instances of class_decl.
24594///
24595/// @param is_anonymous whether the newly created instance is
24596/// anonymous.
24597class_decl:: class_decl(const environment& env, const string& name,
24598 size_t size_in_bits, size_t align_in_bits,
24599 bool is_struct, const location& locus,
24600 visibility vis, bool is_anonymous)
24601 : type_or_decl_base(env,
24602 CLASS_TYPE
24603 | ABSTRACT_TYPE_BASE
24604 | ABSTRACT_DECL_BASE
24605 | ABSTRACT_SCOPE_TYPE_DECL
24606 | ABSTRACT_SCOPE_DECL),
24607 decl_base(env, name, locus,
24608 // If the class is anonymous then by default it won't
24609 // have a linkage name. Also, the anonymous class does
24610 // have an internal-only unique name that is generally
24611 // not taken into account when comparing classes; such a
24612 // unique internal-only name, when used as a linkage
24613 // name might introduce spurious comparison false
24614 // negatives.
24615 /*linkage_name=*/ is_anonymous ? string() : name,
24616 vis),
24617 type_base(env, size_in_bits, align_in_bits),
24618 class_or_union(env, name, size_in_bits, align_in_bits,
24619 locus, vis),
24620 priv_(new priv(is_struct))
24621{
24623 set_is_anonymous(is_anonymous);
24624}
24625
24626/// A constuctor for instances of class_decl that represent a
24627/// declaration without definition.
24628///
24629/// @param env the environment we are operating from.
24630///
24631/// @param name the name of the class.
24632///
24633/// @param is_declaration_only a boolean saying whether the instance
24634/// represents a declaration only, or not.
24635class_decl::class_decl(const environment& env, const string& name,
24636 bool is_struct, bool is_declaration_only)
24637 : type_or_decl_base(env,
24638 CLASS_TYPE
24639 | ABSTRACT_TYPE_BASE
24640 | ABSTRACT_DECL_BASE
24641 | ABSTRACT_SCOPE_TYPE_DECL
24642 | ABSTRACT_SCOPE_DECL),
24643 decl_base(env, name, location(), name),
24644 type_base(env, 0, 0),
24645 class_or_union(env, name, is_declaration_only),
24646 priv_(new priv(is_struct))
24647{
24649}
24650
24651/// This method is invoked automatically right after the current
24652/// instance of @ref class_decl has been canonicalized.
24653///
24654/// Currently, the only thing it does is to sort the virtual member
24655/// functions vector.
24656void
24658{
24660
24661 for (class_decl::virtual_mem_fn_map_type::iterator i =
24662 priv_->virtual_mem_fns_map_.begin();
24663 i != priv_->virtual_mem_fns_map_.end();
24664 ++i)
24665 sort_virtual_member_functions(i->second);
24666}
24667
24668/// Set the "is-struct" flag of the class.
24669///
24670/// @param f the new value of the flag.
24671void
24673{priv_->is_struct_ = f;}
24674
24675/// Test if the class is a struct.
24676///
24677/// @return true iff the class is a struct.
24678bool
24680{return priv_->is_struct_;}
24681
24682/// Add a base specifier to this class.
24683///
24684/// @param b the new base specifier.
24685void
24687{
24688 priv_->bases_.push_back(b);
24689 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
24690}
24691
24692/// Get the base specifiers for this class.
24693///
24694/// @return a vector of the base specifiers.
24697{return priv_->bases_;}
24698
24699/// Find a base class of a given qualified name for the current class.
24700///
24701/// @param qualified_name the qualified name of the base class to look for.
24702///
24703/// @return a pointer to the @ref class_decl that represents the base
24704/// class of name @p qualified_name, if found.
24706class_decl::find_base_class(const string& qualified_name) const
24707{
24708 unordered_map<string, base_spec_sptr>::iterator i =
24709 priv_->bases_map_.find(qualified_name);
24710
24711 if (i != priv_->bases_map_.end())
24712 return i->second->get_base_class();
24713
24714 return class_decl_sptr();
24715}
24716
24717/// Get the virtual member functions of this class.
24718///
24719/// @param return a vector of the virtual member functions of this
24720/// class.
24723{return priv_->virtual_mem_fns_;}
24724
24725/// Get the map that associates a virtual table offset to the virtual
24726/// member functions with that virtual table offset.
24727///
24728/// Usually, there should be a 1:1 mapping between a given vtable
24729/// offset and virtual member functions of that vtable offset. But
24730/// because of some implementation details, there can be several C++
24731/// destructor functions that are *generated* by compilers, for a
24732/// given destructor that is defined in the source code. If the
24733/// destructor is virtual then those generated functions have some
24734/// DWARF attributes in common with the constructor that the user
24735/// actually defined in its source code. Among those attributes are
24736/// the vtable offset of the destructor.
24737///
24738/// @return the map that associates a virtual table offset to the
24739/// virtual member functions with that virtual table offset.
24742{return priv_->virtual_mem_fns_map_;}
24743
24744/// Sort the virtual member functions by their virtual index.
24745void
24747{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
24748
24749/// Getter of the pretty representation of the current instance of
24750/// @ref class_decl.
24751///
24752/// @param internal set to true if the call is intended to get a
24753/// representation of the decl (or type) for the purpose of canonical
24754/// type comparison. This is mainly used in the function
24755/// type_base::get_canonical_type_for().
24756///
24757/// In other words if the argument for this parameter is true then the
24758/// call is meant for internal use (for technical use inside the
24759/// library itself), false otherwise. If you don't know what this is
24760/// for, then set it to false.
24761///
24762/// @param qualified_name if true, names emitted in the pretty
24763/// representation are fully qualified.
24764///
24765/// @return the pretty representaion for a class_decl.
24766string
24768 bool qualified_name) const
24769{
24770 string cl = "class ";
24771 if (!internal && is_struct())
24772 cl = "struct ";
24773
24774 // When computing the pretty representation for internal purposes,
24775 // if an anonymous class is named by a typedef, then consider that
24776 // it has a name, which is the typedef name.
24777 if (get_is_anonymous())
24778 {
24779 if (internal && !get_name().empty())
24780 return cl + get_type_name(this, qualified_name, /*internal=*/true);
24782 /*one_line=*/true,
24783 internal);
24784
24785 }
24786
24787 string result = cl;
24788 if (qualified_name)
24789 result += get_qualified_name(internal);
24790 else
24791 result += get_name();
24792
24793 return result;
24794}
24795
24796decl_base_sptr
24797class_decl::insert_member_decl(decl_base_sptr d)
24798{
24799 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24800 add_member_function(f, public_access,
24801 /*is_virtual=*/false,
24802 /*vtable_offset=*/0,
24803 /*is_static=*/false,
24804 /*is_ctor=*/false,
24805 /*is_dtor=*/false,
24806 /*is_const=*/false);
24807 else
24809
24810 return d;
24811}
24812
24813/// The private data structure of class_decl::base_spec.
24814struct class_decl::base_spec::priv
24815{
24816 class_decl_wptr base_class_;
24817 long offset_in_bits_;
24818 bool is_virtual_;
24819
24820 priv(const class_decl_sptr& cl,
24821 long offset_in_bits,
24822 bool is_virtual)
24823 : base_class_(cl),
24824 offset_in_bits_(offset_in_bits),
24825 is_virtual_(is_virtual)
24826 {}
24827};
24828
24829/// Constructor for base_spec instances.
24830///
24831/// @param base the base class to consider
24832///
24833/// @param a the access specifier of the base class.
24834///
24835/// @param offset_in_bits if positive or null, represents the offset
24836/// of the base in the layout of its containing type.. If negative,
24837/// means that the current base is not laid out in its containing type.
24838///
24839/// @param is_virtual if true, means that the current base class is
24840/// virtual in it's containing type.
24841class_decl::base_spec::base_spec(const class_decl_sptr& base,
24843 long offset_in_bits,
24844 bool is_virtual)
24845 : type_or_decl_base(base->get_environment(),
24846 ABSTRACT_DECL_BASE),
24847 decl_base(base->get_environment(), base->get_name(), base->get_location(),
24848 base->get_linkage_name(), base->get_visibility()),
24849 member_base(a),
24850 priv_(new priv(base, offset_in_bits, is_virtual))
24851{
24853 set_qualified_name(base->get_qualified_name());
24854}
24855
24856/// Return the hash value of the current IR node.
24857///
24858/// Note that upon the first invocation, this member functions
24859/// computes the hash value and returns it. Subsequent invocations
24860/// just return the hash value that was previously calculated.
24861///
24862/// @return the hash value of the current IR node.
24863hash_t
24865{
24867 return h;
24868}
24869
24870/// Get the base class referred to by the current base class
24871/// specifier.
24872///
24873/// @return the base class.
24876{return priv_->base_class_.lock();}
24877
24878/// Getter of the "is-virtual" proprerty of the base class specifier.
24879///
24880/// @return true iff this specifies a virtual base class.
24881bool
24883{return priv_->is_virtual_;}
24884
24885/// Getter of the offset of the base.
24886///
24887/// @return the offset of the base.
24888long
24890{return priv_->offset_in_bits_;}
24891
24892/// Traverses an instance of @ref class_decl::base_spec, visiting all
24893/// the sub-types and decls that it might contain.
24894///
24895/// @param v the visitor that is used to visit every IR sub-node of
24896/// the current node.
24897///
24898/// @return true if either
24899/// - all the children nodes of the current IR node were traversed
24900/// and the calling code should keep going with the traversing.
24901/// - or the current IR node is already being traversed.
24902/// Otherwise, returning false means that the calling code should not
24903/// keep traversing the tree.
24904bool
24906{
24907 if (visiting())
24908 return true;
24909
24910 if (v.visit_begin(this))
24911 {
24912 visiting(true);
24913 get_base_class()->traverse(v);
24914 visiting(false);
24915 }
24916
24917 return v.visit_end(this);
24918}
24919
24920/// Constructor for base_spec instances.
24921///
24922/// Note that this constructor is for clients that don't support RTTI
24923/// and that have a base class of type_base, but of dynamic type
24924/// class_decl.
24925///
24926/// @param base the base class to consider. Must be a pointer to an
24927/// instance of class_decl
24928///
24929/// @param a the access specifier of the base class.
24930///
24931/// @param offset_in_bits if positive or null, represents the offset
24932/// of the base in the layout of its containing type.. If negative,
24933/// means that the current base is not laid out in its containing type.
24934///
24935/// @param is_virtual if true, means that the current base class is
24936/// virtual in it's containing type.
24937class_decl::base_spec::base_spec(const type_base_sptr& base,
24939 long offset_in_bits,
24940 bool is_virtual)
24942 ABSTRACT_DECL_BASE),
24947 member_base(a),
24948 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
24949 offset_in_bits,
24950 is_virtual))
24951{
24953}
24954
24955class_decl::base_spec::~base_spec() = default;
24956
24957/// Compares two instances of @ref class_decl::base_spec.
24958///
24959/// If the two intances are different, set a bitfield to give some
24960/// insight about the kind of differences there are.
24961///
24962/// @param l the first artifact of the comparison.
24963///
24964/// @param r the second artifact of the comparison.
24965///
24966/// @param k a pointer to a bitfield that gives information about the
24967/// kind of changes there are between @p l and @p r. This one is set
24968/// iff @p k is non-null and the function returns false.
24969///
24970/// Please note that setting k to a non-null value does have a
24971/// negative performance impact because even if @p l and @p r are not
24972/// equal, the function keeps up the comparison in order to determine
24973/// the different kinds of ways in which they are different.
24974///
24975/// @return true if @p l equals @p r, false otherwise.
24976bool
24978 const class_decl::base_spec& r,
24979 change_kind* k)
24980{
24981 if (!l.member_base::operator==(r))
24982 {
24983 if (k)
24986 }
24987
24989}
24990
24991/// Comparison operator for @ref class_decl::base_spec.
24992///
24993/// @param other the instance of @ref class_decl::base_spec to compare
24994/// against.
24995///
24996/// @return true if the current instance of @ref class_decl::base_spec
24997/// equals @p other.
24998bool
25000{
25001 const class_decl::base_spec* o =
25002 dynamic_cast<const class_decl::base_spec*>(&other);
25003
25004 if (!o)
25005 return false;
25006
25007 return equals(*this, *o, 0);
25008}
25009
25010/// Comparison operator for @ref class_decl::base_spec.
25011///
25012/// @param other the instance of @ref class_decl::base_spec to compare
25013/// against.
25014///
25015/// @return true if the current instance of @ref class_decl::base_spec
25016/// equals @p other.
25017bool
25019{
25020 const class_decl::base_spec* o =
25021 dynamic_cast<const class_decl::base_spec*>(&other);
25022 if (!o)
25023 return false;
25024
25025 return operator==(static_cast<const decl_base&>(*o));
25026}
25027
25028mem_fn_context_rel::~mem_fn_context_rel()
25029{
25030}
25031
25032/// A constructor for instances of method_decl.
25033///
25034/// @param name the name of the method.
25035///
25036/// @param type the type of the method.
25037///
25038/// @param declared_inline whether the method was
25039/// declared inline or not.
25040///
25041/// @param locus the source location of the method.
25042///
25043/// @param linkage_name the mangled name of the method.
25044///
25045/// @param vis the visibility of the method.
25046///
25047/// @param bind the binding of the method.
25048method_decl::method_decl(const string& name,
25049 method_type_sptr type,
25050 bool declared_inline,
25051 const location& locus,
25052 const string& linkage_name,
25053 visibility vis,
25054 binding bind)
25056 METHOD_DECL
25057 | ABSTRACT_DECL_BASE
25058 |FUNCTION_DECL),
25059 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25060 function_decl(name, static_pointer_cast<function_type>(type),
25061 declared_inline, locus, linkage_name, vis, bind)
25062{
25064 set_context_rel(new mem_fn_context_rel(0));
25065 set_member_function_is_const(*this, type->get_is_const());
25066}
25067
25068/// A constructor for instances of method_decl.
25069///
25070/// @param name the name of the method.
25071///
25072/// @param type the type of the method. Must be an instance of
25073/// method_type.
25074///
25075/// @param declared_inline whether the method was
25076/// declared inline or not.
25077///
25078/// @param locus the source location of the method.
25079///
25080/// @param linkage_name the mangled name of the method.
25081///
25082/// @param vis the visibility of the method.
25083///
25084/// @param bind the binding of the method.
25085method_decl::method_decl(const string& name,
25086 function_type_sptr type,
25087 bool declared_inline,
25088 const location& locus,
25089 const string& linkage_name,
25090 visibility vis,
25091 binding bind)
25092 : type_or_decl_base(type->get_environment(),
25093 METHOD_DECL
25094 | ABSTRACT_DECL_BASE
25095 | FUNCTION_DECL),
25096 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25097 function_decl(name, static_pointer_cast<function_type>
25098 (dynamic_pointer_cast<method_type>(type)),
25099 declared_inline, locus, linkage_name, vis, bind)
25100{
25102 set_context_rel(new mem_fn_context_rel(0));
25103}
25104
25105/// A constructor for instances of method_decl.
25106///
25107/// @param name the name of the method.
25108///
25109/// @param type the type of the method. Must be an instance of
25110/// method_type.
25111///
25112/// @param declared_inline whether the method was
25113/// declared inline or not.
25114///
25115/// @param locus the source location of the method.
25116///
25117/// @param linkage_name the mangled name of the method.
25118///
25119/// @param vis the visibility of the method.
25120///
25121/// @param bind the binding of the method.
25122method_decl::method_decl(const string& name,
25123 type_base_sptr type,
25124 bool declared_inline,
25125 const location& locus,
25126 const string& linkage_name,
25127 visibility vis,
25128 binding bind)
25129 : type_or_decl_base(type->get_environment(),
25130 METHOD_DECL
25131 | ABSTRACT_DECL_BASE
25132 | FUNCTION_DECL),
25133 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25134 function_decl(name, static_pointer_cast<function_type>
25135 (dynamic_pointer_cast<method_type>(type)),
25136 declared_inline, locus, linkage_name, vis, bind)
25137{
25139 set_context_rel(new mem_fn_context_rel(0));
25140}
25141
25142/// Set the linkage name of the method.
25143///
25144/// @param l the new linkage name of the method.
25145void
25147{
25148 string old_lname = get_linkage_name();
25150 // Update the linkage_name -> member function map of the containing
25151 // class declaration.
25152 if (!l.empty())
25153 {
25155 class_or_union_sptr cl = t->get_class_type();
25156 method_decl_sptr m(this, sptr_utils::noop_deleter());
25157 cl->priv_->mem_fns_map_[l] = m;
25158 if (!old_lname.empty() && l != old_lname)
25159 {
25160 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
25161 {
25162 ABG_ASSERT(m.get() == this);
25163 cl->priv_->mem_fns_map_.erase(old_lname);
25164 }
25165 }
25166 }
25167}
25168
25169method_decl::~method_decl()
25170{}
25171
25172const method_type_sptr
25174{
25175 method_type_sptr result;
25177 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
25178 return result;
25179}
25180
25181/// Set the containing class of a method_decl.
25182///
25183/// @param scope the new containing class_decl.
25184void
25185method_decl::set_scope(scope_decl* scope)
25186{
25187 if (!get_context_rel())
25188 set_context_rel(new mem_fn_context_rel(scope));
25189 else
25190 get_context_rel()->set_scope(scope);
25191}
25192
25193/// Equality operator for @ref method_decl_sptr.
25194///
25195/// This is a deep equality operator, as it compares the @ref
25196/// method_decl that is pointed-to by the smart pointer.
25197///
25198/// @param l the left-hand side argument of the equality operator.
25199///
25200/// @param r the righ-hand side argument of the equality operator.
25201///
25202/// @return true iff @p l equals @p r.
25203bool
25204operator==(const method_decl_sptr& l, const method_decl_sptr& r)
25205{
25206 if (l.get() == r.get())
25207 return true;
25208 if (!!l != !!r)
25209 return false;
25210
25211 return *l == *r;
25212}
25213
25214/// Inequality operator for @ref method_decl_sptr.
25215///
25216/// This is a deep equality operator, as it compares the @ref
25217/// method_decl that is pointed-to by the smart pointer.
25218///
25219/// @param l the left-hand side argument of the equality operator.
25220///
25221/// @param r the righ-hand side argument of the equality operator.
25222///
25223/// @return true iff @p l differs from @p r.
25224bool
25225operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
25226{return !operator==(l, r);}
25227
25228/// Test if a function_decl is actually a method_decl.
25229///
25230///@param d the @ref function_decl to consider.
25231///
25232/// @return the method_decl sub-object of @p d if inherits
25233/// a method_decl type.
25236{
25237 return dynamic_cast<method_decl*>
25238 (const_cast<type_or_decl_base*>(d));
25239}
25240
25241/// Test if a function_decl is actually a method_decl.
25242///
25243///@param d the @ref function_decl to consider.
25244///
25245/// @return the method_decl sub-object of @p d if inherits
25246/// a method_decl type.
25250
25251/// Test if a function_decl is actually a method_decl.
25252///
25253///@param d the @ref function_decl to consider.
25254///
25255/// @return the method_decl sub-object of @p d if inherits
25256/// a method_decl type.
25257method_decl_sptr
25259{return dynamic_pointer_cast<method_decl>(d);}
25260
25261/// A "less than" functor to sort a vector of instances of
25262/// method_decl that are virtual.
25263struct virtual_member_function_less_than
25264{
25265 /// The less than operator. First, it sorts the methods by their
25266 /// vtable index. If they have the same vtable index, it sorts them
25267 /// by the name of their ELF symbol. If they don't have elf
25268 /// symbols, it sorts them by considering their pretty
25269 /// representation.
25270 ///
25271 /// Note that this method expects virtual methods.
25272 ///
25273 /// @param f the first method to consider.
25274 ///
25275 /// @param s the second method to consider.
25276 ///
25277 /// @return true if method @p is less than method @s.
25278 bool
25279 operator()(const method_decl& f,
25280 const method_decl& s)
25281 {
25284
25285 ssize_t f_offset = get_member_function_vtable_offset(f);
25286 ssize_t s_offset = get_member_function_vtable_offset(s);
25287 if (f_offset != s_offset) return f_offset < s_offset;
25288
25289 string fn, sn;
25290 // Try the linkage names (important for destructors).
25291 fn = f.get_linkage_name();
25292 sn = s.get_linkage_name();
25293 if (fn != sn) return fn < sn;
25294
25295 // If the functions have symbols, then compare their symbol-id
25296 // string.
25297 elf_symbol_sptr f_sym = f.get_symbol();
25298 elf_symbol_sptr s_sym = s.get_symbol();
25299 if ((!f_sym) != (!s_sym)) return !f_sym;
25300 if (f_sym && s_sym)
25301 {
25302 fn = f_sym->get_id_string();
25303 sn = s_sym->get_id_string();
25304 if (fn != sn) return fn < sn;
25305 }
25306
25307 // None of the functions have symbols or linkage names that
25308 // distinguish them, so compare their pretty representation.
25311 if (fn != sn) return fn < sn;
25312
25313 /// If it's just the file paths that are different then sort them
25314 /// too.
25315 string fn_filepath, sn_filepath;
25316 unsigned line = 0, column = 0;
25317 location fn_loc = f.get_location(), sn_loc = s.get_location();
25318 if (fn_loc)
25319 fn_loc.expand(fn_filepath, line, column);
25320 if (sn_loc)
25321 sn_loc.expand(sn_filepath, line, column);
25322 return fn_filepath < sn_filepath;
25323 }
25324
25325 /// The less than operator. First, it sorts the methods by their
25326 /// vtable index. If they have the same vtable index, it sorts them
25327 /// by the name of their ELF symbol. If they don't have elf
25328 /// symbols, it sorts them by considering their pretty
25329 /// representation.
25330 ///
25331 /// Note that this method expects to take virtual methods.
25332 ///
25333 /// @param f the first method to consider.
25334 ///
25335 /// @param s the second method to consider.
25336 bool
25337 operator()(const method_decl_sptr f,
25338 const method_decl_sptr s)
25339 {return operator()(*f, *s);}
25340}; // end struct virtual_member_function_less_than
25341
25342/// Sort a vector of instances of virtual member functions.
25343///
25344/// @param mem_fns the vector of member functions to sort.
25345static void
25346sort_virtual_member_functions(class_decl::member_functions& mem_fns)
25347{
25348 virtual_member_function_less_than lt;
25349 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25350}
25351
25352/// Add a member function to the current instance of @ref class_or_union.
25353///
25354/// @param f a method_decl to add to the current class. This function
25355/// should not have been already added to a scope.
25356///
25357/// @param access the access specifier for the member function to add.
25358///
25359/// @param is_virtual if this is true then it means the function @p f
25360/// is a virtual function. That also means that the current instance
25361/// of @ref class_or_union is actually an instance of @ref class_decl.
25362///
25363/// @param vtable_offset the offset of the member function in the
25364/// virtual table. This parameter is taken into account only if @p
25365/// is_virtual is true.
25366///
25367/// @param is_static whether the member function is static.
25368///
25369/// @param is_ctor whether the member function is a constructor.
25370///
25371/// @param is_dtor whether the member function is a destructor.
25372///
25373/// @param is_const whether the member function is const.
25374void
25377 bool is_virtual,
25378 size_t vtable_offset,
25379 bool is_static, bool is_ctor,
25380 bool is_dtor, bool is_const)
25381{
25382 add_member_function(f, a, is_static, is_ctor,
25383 is_dtor, is_const);
25384
25385 if (class_decl* klass = is_class_type(this))
25386 {
25387 if (is_virtual)
25388 {
25389 set_member_function_virtuality(f, is_virtual, vtable_offset);
25390 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
25391 }
25392 }
25393}
25394
25395/// When a virtual member function has seen its virtualness set by
25396/// set_member_function_is_virtual(), this function ensures that the
25397/// member function is added to the specific vectors and maps of
25398/// virtual member function of its class.
25399///
25400/// @param method the method to fixup.
25401void
25402fixup_virtual_member_function(method_decl_sptr method)
25403{
25404 if (!method || !get_member_function_is_virtual(method))
25405 return;
25406
25407 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
25408
25409 class_decl::member_functions::const_iterator m;
25410 for (m = klass->priv_->virtual_mem_fns_.begin();
25411 m != klass->priv_->virtual_mem_fns_.end();
25412 ++m)
25413 if (m->get() == method.get()
25414 || (*m)->get_linkage_name() == method->get_linkage_name())
25415 break;
25416 if (m == klass->priv_->virtual_mem_fns_.end())
25417 klass->priv_->virtual_mem_fns_.push_back(method);
25418
25419 // Build or udpate the map that associates a vtable offset to the
25420 // number of virtual member functions that "point" to it.
25421 ssize_t voffset = get_member_function_vtable_offset(method);
25422 if (voffset == -1)
25423 return;
25424
25425 class_decl::virtual_mem_fn_map_type::iterator i =
25426 klass->priv_->virtual_mem_fns_map_.find(voffset);
25427 if (i == klass->priv_->virtual_mem_fns_map_.end())
25428 {
25429 class_decl::member_functions virtual_mem_fns_at_voffset;
25430 virtual_mem_fns_at_voffset.push_back(method);
25431 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
25432 }
25433 else
25434 {
25435 for (m = i->second.begin() ; m != i->second.end(); ++m)
25436 if (m->get() == method.get()
25437 || (*m)->get_linkage_name() == method->get_linkage_name())
25438 break;
25439 if (m == i->second.end())
25440 i->second.push_back(method);
25441 }
25442}
25443
25444/// Return true iff the class has no entity in its scope.
25445bool
25447{return priv_->bases_.empty() && has_no_member();}
25448
25449/// Test if the current instance of @ref class_decl has virtual member
25450/// functions.
25451///
25452/// @return true iff the current instance of @ref class_decl has
25453/// virtual member functions.
25454bool
25457
25458/// Test if the current instance of @ref class_decl has at least one
25459/// virtual base.
25460///
25461/// @return true iff the current instance of @ref class_decl has a
25462/// virtual member function.
25463bool
25465{
25466 for (base_specs::const_iterator b = get_base_specifiers().begin();
25467 b != get_base_specifiers().end();
25468 ++b)
25469 if ((*b)->get_is_virtual()
25470 || (*b)->get_base_class()->has_virtual_bases())
25471 return true;
25472
25473 return false;
25474}
25475
25476/// Test if the current instance has a vtable.
25477///
25478/// This is only valid for a C++ program.
25479///
25480/// Basically this function checks if the class has either virtual
25481/// functions, or virtual bases.
25482bool
25484{
25486 || has_virtual_bases())
25487 return true;
25488 return false;
25489}
25490
25491/// Get the highest vtable offset of all the virtual methods of the
25492/// class.
25493///
25494/// @return the highest vtable offset of all the virtual methods of
25495/// the class.
25496ssize_t
25498{
25499 ssize_t offset = -1;
25500 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
25501 get_virtual_mem_fns_map().begin();
25502 e != get_virtual_mem_fns_map().end();
25503 ++e)
25504 if (e->first > offset)
25505 offset = e->first;
25506
25507 return offset;
25508}
25509
25510/// Return the hash value of the current IR node.
25511///
25512/// Note that upon the first invocation, this member functions
25513/// computes the hash value and returns it. Subsequent invocations
25514/// just return the hash value that was previously calculated.
25515///
25516/// @return the hash value of the current IR node.
25517hash_t
25519{
25521 return h;
25522}
25523
25524/// Test if two methods are equal without taking their symbol or
25525/// linkage name into account.
25526///
25527/// @param f the first method.
25528///
25529/// @param s the second method.
25530///
25531/// @return true iff @p f equals @p s without taking their linkage
25532/// name or symbol into account.
25533static bool
25534methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
25535 const method_decl_sptr& s)
25536{
25537 method_decl_sptr first = f, second = s;
25538 elf_symbol_sptr saved_first_elf_symbol =
25539 first->get_symbol();
25540 elf_symbol_sptr saved_second_elf_symbol =
25541 second->get_symbol();
25542 interned_string saved_first_linkage_name =
25543 first->get_linkage_name();
25544 interned_string saved_second_linkage_name =
25545 second->get_linkage_name();
25546
25547 first->set_symbol(elf_symbol_sptr());
25548 first->set_linkage_name("");
25549 second->set_symbol(elf_symbol_sptr());
25550 second->set_linkage_name("");
25551
25552 bool equal = *first == *second;
25553
25554 first->set_symbol(saved_first_elf_symbol);
25555 first->set_linkage_name(saved_first_linkage_name);
25556 second->set_symbol(saved_second_elf_symbol);
25557 second->set_linkage_name(saved_second_linkage_name);
25558
25559 return equal;
25560}
25561
25562/// Test if a given method is equivalent to at least of other method
25563/// that is in a vector of methods.
25564///
25565/// Note that "equivalent" here means being equal without taking the
25566/// linkage name or the symbol of the methods into account.
25567///
25568/// This is a sub-routine of the 'equals' function that compares @ref
25569/// class_decl.
25570///
25571/// @param method the method to compare.
25572///
25573/// @param fns the vector of functions to compare @p method against.
25574///
25575/// @return true iff @p is equivalent to at least one method in @p
25576/// fns.
25577static bool
25578method_matches_at_least_one_in_vector(const method_decl_sptr& method,
25580{
25581 for (class_decl::member_functions::const_iterator i = fns.begin();
25582 i != fns.end();
25583 ++i)
25584 // Note that the comparison must be done in this order: method ==
25585 // *i This is to keep the consistency of the comparison. It's
25586 // important especially when doing type canonicalization. The
25587 // already canonicalize type is the left operand, and the type
25588 // being canonicalized is the right operand. This comes from the
25589 // code in type_base::get_canonical_type_for().
25590 if (methods_equal_modulo_elf_symbol(method, *i))
25591 return true;
25592
25593 return false;
25594}
25595
25596/// Compares two instances of @ref class_decl.
25597///
25598/// If the two intances are different, set a bitfield to give some
25599/// insight about the kind of differences there are.
25600///
25601/// @param l the first artifact of the comparison.
25602///
25603/// @param r the second artifact of the comparison.
25604///
25605/// @param k a pointer to a bitfield that gives information about the
25606/// kind of changes there are between @p l and @p r. This one is set
25607/// iff @p k is non-null and the function returns false.
25608///
25609/// Please note that setting k to a non-null value does have a
25610/// negative performance impact because even if @p l and @p r are not
25611/// equal, the function keeps up the comparison in order to determine
25612/// the different kinds of ways in which they are different.
25613///
25614/// @return true if @p l equals @p r, false otherwise.
25615bool
25617{
25618 {
25619 // First of all, let's see if these two types haven't already been
25620 // compared. If so, and if the result of the comparison has been
25621 // cached, let's just re-use it, rather than comparing them all
25622 // over again.
25623 bool result = false;
25624 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
25625 ABG_RETURN(result);
25626 }
25627
25628 // if one of the classes is declaration-only then we take a fast
25629 // path here.
25631 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
25632 static_cast<const class_or_union&>(r),
25633 k));
25634
25635 bool result = true;
25636 if (!equals(static_cast<const class_or_union&>(l),
25637 static_cast<const class_or_union&>(r),
25638 k))
25639 {
25640 result = false;
25641 if (!k)
25642 ABG_RETURN(result);
25643 }
25644
25646
25648
25649#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
25650
25651 // Compare bases.
25652 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
25653 {
25654 result = false;
25655 if (k)
25657 else
25658 RETURN(result);
25659 }
25660
25661 for (class_decl::base_specs::const_iterator
25662 b0 = l.get_base_specifiers().begin(),
25663 b1 = r.get_base_specifiers().begin();
25664 (b0 != l.get_base_specifiers().end()
25665 && b1 != r.get_base_specifiers().end());
25666 ++b0, ++b1)
25667 if (*b0 != *b1)
25668 {
25669 result = false;
25670 if (k)
25671 {
25672 if (!types_have_similar_structure((*b0)->get_base_class().get(),
25673 (*b1)->get_base_class().get()))
25675 else
25676 *k |= SUBTYPE_CHANGE_KIND;
25677 break;
25678 }
25679 RETURN(result);
25680 }
25681
25682 // Compare virtual member functions
25683
25684 // We look at the map that associates a given vtable offset to a
25685 // vector of virtual member functions that point to that offset.
25686 //
25687 // This is because there are cases where several functions can
25688 // point to the same virtual table offset.
25689 //
25690 // This is usually the case for virtual destructors. Even though
25691 // there can be only one virtual destructor declared in source
25692 // code, there are actually potentially up to three generated
25693 // functions for that destructor. Some of these generated
25694 // functions can be clones of other functions that are among those
25695 // generated ones. In any cases, they all have the same
25696 // properties, including the vtable offset property.
25697
25698 // So, there should be the same number of different vtable
25699 // offsets, the size of two maps must be equals.
25700 if (l.get_virtual_mem_fns_map().size()
25701 != r.get_virtual_mem_fns_map().size())
25702 {
25703 result = false;
25704 if (k)
25706 else
25707 RETURN(result);
25708 }
25709
25710 // Then, each virtual member function of a given vtable offset in
25711 // the first class type, must match an equivalent virtual member
25712 // function of a the same vtable offset in the second class type.
25713 //
25714 // By "match", I mean that the two virtual member function should
25715 // be equal if we don't take into account their symbol name or
25716 // their linkage name. This is because two destructor functions
25717 // clones (for instance) might have different linkage name, but
25718 // are still equivalent if their other properties are the same.
25719 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
25720 l.get_virtual_mem_fns_map().begin();
25721 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
25722 ++first_v_fn_entry)
25723 {
25724 unsigned voffset = first_v_fn_entry->first;
25725 const class_decl::member_functions& first_vfns =
25726 first_v_fn_entry->second;
25727
25728 const class_decl::virtual_mem_fn_map_type::const_iterator
25729 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
25730
25731 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
25732 {
25733 result = false;
25734 if (k)
25736 RETURN(result);
25737 }
25738
25739 const class_decl::member_functions& second_vfns =
25740 second_v_fn_entry->second;
25741
25742 bool matches = false;
25743 for (class_decl::member_functions::const_iterator i =
25744 first_vfns.begin();
25745 i != first_vfns.end();
25746 ++i)
25747 if (method_matches_at_least_one_in_vector(*i, second_vfns))
25748 {
25749 matches = true;
25750 break;
25751 }
25752
25753 if (!matches)
25754 {
25755 result = false;
25756 if (k)
25757 *k |= SUBTYPE_CHANGE_KIND;
25758 else
25759 RETURN(result);
25760 }
25761 }
25762
25763 RETURN(result);
25764#undef RETURN
25765}
25766
25767/// Copy a method of a class into a new class.
25768///
25769/// @param klass the class into which the method is to be copied.
25770///
25771/// @param method the method to copy into @p klass.
25772///
25773/// @return the resulting newly copied method.
25774method_decl_sptr
25775copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
25776{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
25777
25778/// Copy a method of a class into a new class.
25779///
25780/// @param klass the class into which the method is to be copied.
25781///
25782/// @param method the method to copy into @p klass.
25783///
25784/// @return the resulting newly copied method.
25785method_decl_sptr
25787{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
25788
25789/// Comparison operator for @ref class_decl.
25790///
25791/// @param other the instance of @ref class_decl to compare against.
25792///
25793/// @return true iff the current instance of @ref class_decl equals @p
25794/// other.
25795bool
25797{
25798 const class_decl* op = is_class_type(&other);
25799 if (!op)
25800 {
25801 if (class_or_union* cou = is_class_or_union_type(&other))
25802 return class_or_union::operator==(*cou);
25803 return false;
25804 }
25805
25806 // If this is a decl-only type (and thus with no canonical type),
25807 // use the canonical type of the definition, if any.
25808 const class_decl *l = 0;
25810 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
25811 if (l == 0)
25812 l = this;
25813
25814 ABG_ASSERT(l);
25815
25816 // Likewise for the other type.
25817 const class_decl *r = 0;
25818 if (op->get_is_declaration_only())
25819 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
25820 if (r == 0)
25821 r = op;
25822
25823 ABG_ASSERT(r);
25824
25825 return try_canonical_compare(l, r);
25826}
25827
25828/// Equality operator for class_decl.
25829///
25830/// Re-uses the equality operator that takes a decl_base.
25831///
25832/// @param other the other class_decl to compare against.
25833///
25834/// @return true iff the current instance equals the other one.
25835bool
25837{
25838 const decl_base* o = is_decl(&other);
25839 if (!o)
25840 return false;
25841 return *this == *o;
25842}
25843
25844/// Equality operator for class_decl.
25845///
25846/// Re-uses the equality operator that takes a decl_base.
25847///
25848/// @param other the other class_decl to compare against.
25849///
25850/// @return true iff the current instance equals the other one.
25851bool
25853{
25854 const decl_base& o = other;
25855 return *this == o;
25856}
25857
25858/// Comparison operator for @ref class_decl.
25859///
25860/// @param other the instance of @ref class_decl to compare against.
25861///
25862/// @return true iff the current instance of @ref class_decl equals @p
25863/// other.
25864bool
25866{
25867 const decl_base& o = other;
25868 return *this == o;
25869}
25870
25871/// Turn equality of shared_ptr of class_decl into a deep equality;
25872/// that is, make it compare the pointed to objects too.
25873///
25874/// @param l the shared_ptr of class_decl on left-hand-side of the
25875/// equality.
25876///
25877/// @param r the shared_ptr of class_decl on right-hand-side of the
25878/// equality.
25879///
25880/// @return true if the class_decl pointed to by the shared_ptrs are
25881/// equal, false otherwise.
25882bool
25884{
25885 if (l.get() == r.get())
25886 return true;
25887 if (!!l != !!r)
25888 return false;
25889
25890 return *l == *r;
25891}
25892
25893/// Turn inequality of shared_ptr of class_decl into a deep equality;
25894/// that is, make it compare the pointed to objects too.
25895///
25896/// @param l the shared_ptr of class_decl on left-hand-side of the
25897/// equality.
25898///
25899/// @param r the shared_ptr of class_decl on right-hand-side of the
25900/// equality.
25901///
25902/// @return true if the class_decl pointed to by the shared_ptrs are
25903/// different, false otherwise.
25904bool
25906{return !operator==(l, r);}
25907
25908/// Turn equality of shared_ptr of class_or_union into a deep
25909/// equality; that is, make it compare the pointed to objects too.
25910///
25911/// @param l the left-hand-side operand of the operator
25912///
25913/// @param r the right-hand-side operand of the operator.
25914///
25915/// @return true iff @p l equals @p r.
25916bool
25917operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
25918{
25919 if (l.get() == r.get())
25920 return true;
25921 if (!!l != !!r)
25922 return false;
25923
25924 return *l == *r;
25925}
25926
25927/// Turn inequality of shared_ptr of class_or_union into a deep
25928/// equality; that is, make it compare the pointed to objects too.
25929///
25930/// @param l the left-hand-side operand of the operator
25931///
25932/// @param r the right-hand-side operand of the operator.
25933///
25934/// @return true iff @p l is different from @p r.
25935bool
25936operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
25937{return !operator==(l, r);}
25938
25939/// This implements the ir_traversable_base::traverse pure virtual
25940/// function.
25941///
25942/// @param v the visitor used on the current instance and on its
25943/// members.
25944///
25945/// @return true if the entire IR node tree got traversed, false
25946/// otherwise.
25947bool
25949{
25950 if (v.type_node_has_been_visited(this))
25951 return true;
25952
25953 if (visiting())
25954 return true;
25955
25956 if (v.visit_begin(this))
25957 {
25958 visiting(true);
25959 bool stop = false;
25960
25961 for (base_specs::const_iterator i = get_base_specifiers().begin();
25962 i != get_base_specifiers().end();
25963 ++i)
25964 {
25965 if (!(*i)->traverse(v))
25966 {
25967 stop = true;
25968 break;
25969 }
25970 }
25971
25972 if (!stop)
25973 for (data_members::const_iterator i = get_data_members().begin();
25974 i != get_data_members().end();
25975 ++i)
25976 if (!(*i)->traverse(v))
25977 {
25978 stop = true;
25979 break;
25980 }
25981
25982 if (!stop)
25983 for (member_functions::const_iterator i= get_member_functions().begin();
25984 i != get_member_functions().end();
25985 ++i)
25986 if (!(*i)->traverse(v))
25987 {
25988 stop = true;
25989 break;
25990 }
25991
25992 if (!stop)
25993 for (member_types::const_iterator i = get_member_types().begin();
25994 i != get_member_types().end();
25995 ++i)
25996 if (!(*i)->traverse(v))
25997 {
25998 stop = true;
25999 break;
26000 }
26001
26002 if (!stop)
26003 for (member_function_templates::const_iterator i =
26005 i != get_member_function_templates().end();
26006 ++i)
26007 if (!(*i)->traverse(v))
26008 {
26009 stop = true;
26010 break;
26011 }
26012
26013 if (!stop)
26014 for (member_class_templates::const_iterator i =
26016 i != get_member_class_templates().end();
26017 ++i)
26018 if (!(*i)->traverse(v))
26019 {
26020 stop = true;
26021 break;
26022 }
26023 visiting(false);
26024 }
26025
26026 bool result = v.visit_end(this);
26028 return result;
26029}
26030
26031/// Destructor of the @ref class_decl type.
26033{delete priv_;}
26034
26035context_rel::~context_rel()
26036{}
26037
26038bool
26039member_base::operator==(const member_base& o) const
26040{
26042 && get_is_static() == o.get_is_static());
26043}
26044
26045/// Equality operator for smart pointers to @ref
26046/// class_decl::base_specs.
26047///
26048/// This compares the pointed-to objects.
26049///
26050/// @param l the first instance to consider.
26051///
26052/// @param r the second instance to consider.
26053///
26054/// @return true iff @p l equals @p r.
26055bool
26058{
26059 if (l.get() == r.get())
26060 return true;
26061 if (!!l != !!r)
26062 return false;
26063
26064 return *l == static_cast<const decl_base&>(*r);
26065}
26066
26067/// Inequality operator for smart pointers to @ref
26068/// class_decl::base_specs.
26069///
26070/// This compares the pointed-to objects.
26071///
26072/// @param l the first instance to consider.
26073///
26074/// @param r the second instance to consider.
26075///
26076/// @return true iff @p l is different from @p r.
26077bool
26080{return !operator==(l, r);}
26081
26082/// Test if an ABI artifact is a class base specifier.
26083///
26084/// @param tod the ABI artifact to consider.
26085///
26086/// @return a pointer to the @ref class_decl::base_spec sub-object of
26087/// @p tod iff it's a class base specifier.
26090{
26091 return dynamic_cast<class_decl::base_spec*>
26092 (const_cast<type_or_decl_base*>(tod));
26093}
26094
26095/// Test if an ABI artifact is a class base specifier.
26096///
26097/// @param tod the ABI artifact to consider.
26098///
26099/// @return a pointer to the @ref class_decl::base_spec sub-object of
26100/// @p tod iff it's a class base specifier.
26103{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
26104
26105bool
26106member_function_template::operator==(const member_base& other) const
26107{
26108 try
26109 {
26110 const member_function_template& o =
26111 dynamic_cast<const member_function_template&>(other);
26112
26113 if (!(is_constructor() == o.is_constructor()
26114 && is_const() == o.is_const()
26115 && member_base::operator==(o)))
26116 return false;
26117
26118 if (function_tdecl_sptr ftdecl = as_function_tdecl())
26119 {
26120 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
26121 if (other_ftdecl)
26122 return ftdecl->function_tdecl::operator==(*other_ftdecl);
26123 }
26124 }
26125 catch(...)
26126 {}
26127 return false;
26128}
26129
26130/// Equality operator for smart pointers to @ref
26131/// member_function_template. This is compares the
26132/// pointed-to instances.
26133///
26134/// @param l the first instance to consider.
26135///
26136/// @param r the second instance to consider.
26137///
26138/// @return true iff @p l equals @p r.
26139bool
26140operator==(const member_function_template_sptr& l,
26141 const member_function_template_sptr& r)
26142{
26143 if (l.get() == r.get())
26144 return true;
26145 if (!!l != !!r)
26146 return false;
26147
26148 return *l == *r;
26149}
26150
26151/// Inequality operator for smart pointers to @ref
26152/// member_function_template. This is compares the pointed-to
26153/// instances.
26154///
26155/// @param l the first instance to consider.
26156///
26157/// @param r the second instance to consider.
26158///
26159/// @return true iff @p l equals @p r.
26160bool
26161operator!=(const member_function_template_sptr& l,
26162 const member_function_template_sptr& r)
26163{return !operator==(l, r);}
26164
26165/// This implements the ir_traversable_base::traverse pure virtual
26166/// function.
26167///
26168/// @param v the visitor used on the current instance and on its
26169/// underlying function template.
26170///
26171/// @return true if the entire IR node tree got traversed, false
26172/// otherwise.
26173bool
26175{
26176 if (visiting())
26177 return true;
26178
26179 if (v.visit_begin(this))
26180 {
26181 visiting(true);
26182 if (function_tdecl_sptr f = as_function_tdecl())
26183 f->traverse(v);
26184 visiting(false);
26185 }
26186 return v.visit_end(this);
26187}
26188
26189/// Equality operator of the the @ref member_class_template class.
26190///
26191/// @param other the other @ref member_class_template to compare against.
26192///
26193/// @return true iff the current instance equals @p other.
26194bool
26196{
26197 try
26198 {
26199 const member_class_template& o =
26200 dynamic_cast<const member_class_template&>(other);
26201
26202 if (!member_base::operator==(o))
26203 return false;
26204
26205 return as_class_tdecl()->class_tdecl::operator==(o);
26206 }
26207 catch(...)
26208 {return false;}
26209}
26210
26211/// Equality operator of the the @ref member_class_template class.
26212///
26213/// @param other the other @ref member_class_template to compare against.
26214///
26215/// @return true iff the current instance equals @p other.
26216bool
26218{
26219 if (!decl_base::operator==(other))
26220 return false;
26221 return as_class_tdecl()->class_tdecl::operator==(other);
26222}
26223
26224/// Comparison operator for the @ref member_class_template
26225/// type.
26226///
26227/// @param other the other instance of @ref
26228/// member_class_template to compare against.
26229///
26230/// @return true iff the two instances are equal.
26231bool
26233{
26234 const decl_base* o = dynamic_cast<const decl_base*>(&other);
26235 return *this == *o;
26236}
26237
26238/// Comparison operator for the @ref member_class_template
26239/// type.
26240///
26241/// @param l the first argument of the operator.
26242///
26243/// @param r the second argument of the operator.
26244///
26245/// @return true iff the two instances are equal.
26246bool
26247operator==(const member_class_template_sptr& l,
26248 const member_class_template_sptr& r)
26249{
26250 if (l.get() == r.get())
26251 return true;
26252 if (!!l != !!r)
26253 return false;
26254
26255 return *l == *r;
26256}
26257
26258/// Inequality operator for the @ref member_class_template
26259/// type.
26260///
26261/// @param l the first argument of the operator.
26262///
26263/// @param r the second argument of the operator.
26264///
26265/// @return true iff the two instances are equal.
26266bool
26267operator!=(const member_class_template_sptr& l,
26268 const member_class_template_sptr& r)
26269{return !operator==(l, r);}
26270
26271/// This implements the ir_traversable_base::traverse pure virtual
26272/// function.
26273///
26274/// @param v the visitor used on the current instance and on the class
26275/// pattern of the template.
26276///
26277/// @return true if the entire IR node tree got traversed, false
26278/// otherwise.
26279bool
26281{
26282 if (visiting())
26283 return true;
26284
26285 if (v.visit_begin(this))
26286 {
26287 visiting(true);
26288 if (class_tdecl_sptr t = as_class_tdecl())
26289 t->traverse(v);
26290 visiting(false);
26291 }
26292 return v.visit_end(this);
26293}
26294
26295/// Streaming operator for class_decl::access_specifier.
26296///
26297/// @param o the output stream to serialize the access specifier to.
26298///
26299/// @param a the access specifier to serialize.
26300///
26301/// @return the output stream.
26302std::ostream&
26303operator<<(std::ostream& o, access_specifier a)
26304{
26305 string r;
26306
26307 switch (a)
26308 {
26309 case no_access:
26310 r = "none";
26311 break;
26312 case private_access:
26313 r = "private";
26314 break;
26315 case protected_access:
26316 r = "protected";
26317 break;
26318 case public_access:
26319 r= "public";
26320 break;
26321 };
26322 o << r;
26323 return o;
26324}
26325
26326/// Sets the static-ness property of a class member.
26327///
26328/// @param d the class member to set the static-ness property for.
26329/// Note that this must be a class member otherwise the function
26330/// aborts the current process.
26331///
26332/// @param s this must be true if the member is to be static, false
26333/// otherwise.
26334void
26336{
26338
26340 ABG_ASSERT(c);
26341
26342 c->set_is_static(s);
26343
26344 scope_decl* scope = d.get_scope();
26345
26346 if (class_or_union* cl = is_class_or_union_type(scope))
26347 {
26348 if (var_decl* v = is_var_decl(&d))
26349 {
26350 // First, find v in the set of data members.
26351 var_decl_sptr var;
26352 for (const auto& dm : cl->get_data_members())
26353 if (dm->get_name() == v->get_name())
26354 {
26355 var = dm;
26356 break;
26357 }
26358 if (!var)
26359 return;
26360
26361 if (s)
26362 {
26363 // remove from the non-static data members
26364 for (class_decl::data_members::iterator i =
26365 cl->priv_->non_static_data_members_.begin();
26366 i != cl->priv_->non_static_data_members_.end();
26367 ++i)
26368 {
26369 if ((*i)->get_name() == v->get_name())
26370 {
26371 cl->priv_->non_static_data_members_.erase(i);
26372 break;
26373 }
26374 }
26375
26376 // If it's not in the static data members, then add it
26377 // there.
26378 bool already_in_static_dms = false;
26379 for (const auto& s_dm : cl->priv_->static_data_members_)
26380 if (s_dm->get_name() == v->get_name())
26381 {
26382 already_in_static_dms = true;
26383 break;
26384 }
26385 if (!already_in_static_dms)
26386 cl->priv_->static_data_members_.push_back(var);
26387 }
26388 else // is non-static
26389 {
26390 // Remove from the static data members.
26391 for (class_or_union::data_members::iterator i =
26392 cl->priv_->static_data_members_.begin();
26393 i != cl->priv_->static_data_members_.end();
26394 ++i)
26395 if ((*i)->get_name() == v->get_name())
26396 {
26397 cl->priv_->static_data_members_.erase(i);
26398 break;
26399 }
26400
26401 // If it's not already in the non-static data members
26402 // then add it there.
26403 bool is_already_in_non_static_data_members = false;
26404 for (const auto& ns_dm : cl->priv_->non_static_data_members_)
26405 if (ns_dm->get_name() == v->get_name())
26406 {
26407 is_already_in_non_static_data_members = true;
26408 break;
26409 }
26410 if (!is_already_in_non_static_data_members)
26411 cl->priv_->non_static_data_members_.push_back(var);
26412 }
26413 }
26414 }
26415}
26416
26417/// Sets the static-ness property of a class member.
26418///
26419/// @param d the class member to set the static-ness property for.
26420/// Note that this must be a class member otherwise the function
26421/// aborts the current process.
26422///
26423/// @param s this must be true if the member is to be static, false
26424/// otherwise.
26425void
26426set_member_is_static(const decl_base_sptr& d, bool s)
26427{set_member_is_static(*d, s);}
26428
26429// </class_decl>
26430
26431// <union_decl>
26432
26433/// Constructor for the @ref union_decl type.
26434///
26435/// @param env the @ref environment we are operating from.
26436///
26437/// @param name the name of the union type.
26438///
26439/// @param size_in_bits the size of the union, in bits.
26440///
26441/// @param locus the location of the type.
26442///
26443/// @param vis the visibility of instances of @ref union_decl.
26444///
26445/// @param mbr_types the member types of the union.
26446///
26447/// @param data_mbrs the data members of the union.
26448///
26449/// @param member_fns the member functions of the union.
26450union_decl::union_decl(const environment& env, const string& name,
26451 size_t size_in_bits, const location& locus,
26452 visibility vis, member_types& mbr_types,
26453 data_members& data_mbrs, member_functions& member_fns)
26454 : type_or_decl_base(env,
26455 UNION_TYPE
26456 | ABSTRACT_TYPE_BASE
26457 | ABSTRACT_DECL_BASE),
26458 decl_base(env, name, locus, name, vis),
26459 type_base(env, size_in_bits, 0),
26460 class_or_union(env, name, size_in_bits, 0,
26461 locus, vis, mbr_types, data_mbrs, member_fns)
26462{
26464}
26465
26466/// Constructor for the @ref union_decl type.
26467///
26468/// @param env the @ref environment we are operating from.
26469///
26470/// @param name the name of the union type.
26471///
26472/// @param size_in_bits the size of the union, in bits.
26473///
26474/// @param locus the location of the type.
26475///
26476/// @param vis the visibility of instances of @ref union_decl.
26477///
26478/// @param mbr_types the member types of the union.
26479///
26480/// @param data_mbrs the data members of the union.
26481///
26482/// @param member_fns the member functions of the union.
26483///
26484/// @param is_anonymous whether the newly created instance is
26485/// anonymous.
26486union_decl::union_decl(const environment& env, const string& name,
26487 size_t size_in_bits, const location& locus,
26488 visibility vis, member_types& mbr_types,
26489 data_members& data_mbrs, member_functions& member_fns,
26490 bool is_anonymous)
26491 : type_or_decl_base(env,
26492 UNION_TYPE
26493 | ABSTRACT_TYPE_BASE
26494 | ABSTRACT_DECL_BASE),
26495 decl_base(env, name, locus,
26496 // If the class is anonymous then by default it won't
26497 // have a linkage name. Also, the anonymous class does
26498 // have an internal-only unique name that is generally
26499 // not taken into account when comparing classes; such a
26500 // unique internal-only name, when used as a linkage
26501 // name might introduce spurious comparison false
26502 // negatives.
26503 /*linkage_name=*/is_anonymous ? string() : name,
26504 vis),
26505 type_base(env, size_in_bits, 0),
26506 class_or_union(env, name, size_in_bits, 0,
26507 locus, vis, mbr_types, data_mbrs, member_fns)
26508{
26510 set_is_anonymous(is_anonymous);
26511}
26512
26513/// Constructor for the @ref union_decl type.
26514///
26515/// @param env the @ref environment we are operating from.
26516///
26517/// @param name the name of the union type.
26518///
26519/// @param size_in_bits the size of the union, in bits.
26520///
26521/// @param locus the location of the type.
26522///
26523/// @param vis the visibility of instances of @ref union_decl.
26524union_decl::union_decl(const environment& env, const string& name,
26525 size_t size_in_bits, const location& locus,
26526 visibility vis)
26527 : type_or_decl_base(env,
26528 UNION_TYPE
26529 | ABSTRACT_TYPE_BASE
26530 | ABSTRACT_DECL_BASE
26531 | ABSTRACT_SCOPE_TYPE_DECL
26532 | ABSTRACT_SCOPE_DECL),
26533 decl_base(env, name, locus, name, vis),
26534 type_base(env, size_in_bits, 0),
26535 class_or_union(env, name, size_in_bits,
26536 0, locus, vis)
26537{
26539}
26540
26541/// Constructor for the @ref union_decl type.
26542///
26543/// @param env the @ref environment we are operating from.
26544///
26545/// @param name the name of the union type.
26546///
26547/// @param size_in_bits the size of the union, in bits.
26548///
26549/// @param locus the location of the type.
26550///
26551/// @param vis the visibility of instances of @ref union_decl.
26552///
26553/// @param is_anonymous whether the newly created instance is
26554/// anonymous.
26555union_decl::union_decl(const environment& env, const string& name,
26556 size_t size_in_bits, const location& locus,
26557 visibility vis, bool is_anonymous)
26558 : type_or_decl_base(env,
26559 UNION_TYPE
26560 | ABSTRACT_TYPE_BASE
26561 | ABSTRACT_DECL_BASE
26562 | ABSTRACT_SCOPE_TYPE_DECL
26563 | ABSTRACT_SCOPE_DECL),
26564 decl_base(env, name, locus,
26565 // If the class is anonymous then by default it won't
26566 // have a linkage name. Also, the anonymous class does
26567 // have an internal-only unique name that is generally
26568 // not taken into account when comparing classes; such a
26569 // unique internal-only name, when used as a linkage
26570 // name might introduce spurious comparison false
26571 // negatives.
26572 /*linkage_name=*/is_anonymous ? string() : name,
26573 vis),
26574 type_base(env, size_in_bits, 0),
26575 class_or_union(env, name, size_in_bits,
26576 0, locus, vis)
26577{
26579 set_is_anonymous(is_anonymous);
26580}
26581
26582/// Constructor for the @ref union_decl type.
26583///
26584/// @param env the @ref environment we are operating from.
26585///
26586/// @param name the name of the union type.
26587///
26588/// @param is_declaration_only a boolean saying whether the instance
26589/// represents a declaration only, or not.
26590union_decl::union_decl(const environment& env,
26591 const string& name,
26592 bool is_declaration_only)
26593 : type_or_decl_base(env,
26594 UNION_TYPE
26595 | ABSTRACT_TYPE_BASE
26596 | ABSTRACT_DECL_BASE
26597 | ABSTRACT_SCOPE_TYPE_DECL
26598 | ABSTRACT_SCOPE_DECL),
26599 decl_base(env, name, location(), name),
26600 type_base(env, 0, 0),
26601 class_or_union(env, name, is_declaration_only)
26602{
26604}
26605
26606/// Return the hash value of the current IR node.
26607///
26608/// Note that upon the first invocation, this member functions
26609/// computes the hash value and returns it. Subsequent invocations
26610/// just return the hash value that was previously calculated.
26611///
26612/// @return the hash value of the current IR node.
26613hash_t
26615{
26617 return h;
26618}
26619
26620/// Getter of the pretty representation of the current instance of
26621/// @ref union_decl.
26622///
26623/// @param internal set to true if the call is intended to get a
26624/// representation of the decl (or type) for the purpose of canonical
26625/// type comparison. This is mainly used in the function
26626/// type_base::get_canonical_type_for().
26627///
26628/// In other words if the argument for this parameter is true then the
26629/// call is meant for internal use (for technical use inside the
26630/// library itself), false otherwise. If you don't know what this is
26631/// for, then set it to false.
26632///
26633/// @param qualified_name if true, names emitted in the pretty
26634/// representation are fully qualified.
26635///
26636/// @return the pretty representaion for a union_decl.
26637string
26639 bool qualified_name) const
26640{
26641 string repr;
26642 if (get_is_anonymous())
26643 {
26644 if (internal && !get_name().empty())
26645 repr = string("union ") +
26646 get_type_name(this, qualified_name, /*internal=*/true);
26647 else
26649 /*one_line=*/true,
26650 internal);
26651 }
26652 else
26653 {
26654 repr = "union ";
26655 if (qualified_name)
26656 repr += get_qualified_name(internal);
26657 else
26658 repr += get_name();
26659 }
26660
26661 return repr;
26662}
26663
26664/// Comparison operator for @ref union_decl.
26665///
26666/// @param other the instance of @ref union_decl to compare against.
26667///
26668/// @return true iff the current instance of @ref union_decl equals @p
26669/// other.
26670bool
26672{
26673 const union_decl* op = dynamic_cast<const union_decl*>(&other);
26674 if (!op)
26675 return false;
26676 return try_canonical_compare(this, op);
26677}
26678
26679/// Equality operator for union_decl.
26680///
26681/// Re-uses the equality operator that takes a decl_base.
26682///
26683/// @param other the other union_decl to compare against.
26684///
26685/// @return true iff the current instance equals the other one.
26686bool
26688{
26689 const decl_base *o = dynamic_cast<const decl_base*>(&other);
26690 if (!o)
26691 return false;
26692 return *this == *o;
26693}
26694
26695/// Equality operator for union_decl.
26696///
26697/// Re-uses the equality operator that takes a decl_base.
26698///
26699/// @param other the other union_decl to compare against.
26700///
26701/// @return true iff the current instance equals the other one.
26702bool
26704{
26705 const decl_base *o = dynamic_cast<const decl_base*>(&other);
26706 return *this == *o;
26707}
26708
26709/// Comparison operator for @ref union_decl.
26710///
26711/// @param other the instance of @ref union_decl to compare against.
26712///
26713/// @return true iff the current instance of @ref union_decl equals @p
26714/// other.
26715bool
26717{
26718 const decl_base& o = other;
26719 return *this == o;
26720}
26721
26722/// This implements the ir_traversable_base::traverse pure virtual
26723/// function.
26724///
26725/// @param v the visitor used on the current instance and on its
26726/// members.
26727///
26728/// @return true if the entire IR node tree got traversed, false
26729/// otherwise.
26730bool
26732{
26733 if (v.type_node_has_been_visited(this))
26734 return true;
26735
26736 if (visiting())
26737 return true;
26738
26739 if (v.visit_begin(this))
26740 {
26741 visiting(true);
26742 bool stop = false;
26743
26744 if (!stop)
26745 for (data_members::const_iterator i = get_data_members().begin();
26746 i != get_data_members().end();
26747 ++i)
26748 if (!(*i)->traverse(v))
26749 {
26750 stop = true;
26751 break;
26752 }
26753
26754 if (!stop)
26755 for (member_functions::const_iterator i= get_member_functions().begin();
26756 i != get_member_functions().end();
26757 ++i)
26758 if (!(*i)->traverse(v))
26759 {
26760 stop = true;
26761 break;
26762 }
26763
26764 if (!stop)
26765 for (member_types::const_iterator i = get_member_types().begin();
26766 i != get_member_types().end();
26767 ++i)
26768 if (!(*i)->traverse(v))
26769 {
26770 stop = true;
26771 break;
26772 }
26773
26774 if (!stop)
26775 for (member_function_templates::const_iterator i =
26777 i != get_member_function_templates().end();
26778 ++i)
26779 if (!(*i)->traverse(v))
26780 {
26781 stop = true;
26782 break;
26783 }
26784
26785 if (!stop)
26786 for (member_class_templates::const_iterator i =
26788 i != get_member_class_templates().end();
26789 ++i)
26790 if (!(*i)->traverse(v))
26791 {
26792 stop = true;
26793 break;
26794 }
26795 visiting(false);
26796 }
26797
26798 bool result = v.visit_end(this);
26800 return result;
26801}
26802
26803/// Destructor of the @ref union_decl type.
26806
26807/// Compares two instances of @ref union_decl.
26808///
26809/// If the two intances are different, set a bitfield to give some
26810/// insight about the kind of differences there are.
26811///
26812/// @param l the first artifact of the comparison.
26813///
26814/// @param r the second artifact of the comparison.
26815///
26816/// @param k a pointer to a bitfield that gives information about the
26817/// kind of changes there are between @p l and @p r. This one is set
26818/// iff @p k is non-null and the function returns false.
26819///
26820/// Please note that setting k to a non-null value does have a
26821/// negative performance impact because even if @p l and @p r are not
26822/// equal, the function keeps up the comparison in order to determine
26823/// the different kinds of ways in which they are different.
26824///
26825/// @return true if @p l equals @p r, false otherwise.
26826bool
26828{
26829
26831
26832 {
26833 // First of all, let's see if these two types haven't already been
26834 // compared. If so, and if the result of the comparison has been
26835 // cached, let's just re-use it, rather than comparing them all
26836 // over again.
26837 bool result = false;
26838 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
26839 ABG_RETURN(result);
26840 }
26841
26842 bool result = equals(static_cast<const class_or_union&>(l),
26843 static_cast<const class_or_union&>(r),
26844 k);
26845
26847}
26848
26849/// Copy a method of a @ref union_decl into a new @ref
26850/// union_decl.
26851///
26852/// @param t the @ref union_decl into which the method is to be copied.
26853///
26854/// @param method the method to copy into @p t.
26855///
26856/// @return the resulting newly copied method.
26857method_decl_sptr
26858copy_member_function(const union_decl_sptr& union_type,
26859 const method_decl_sptr& f)
26860{return copy_member_function(union_type, f.get());}
26861
26862/// Copy a method of a @ref union_decl into a new @ref
26863/// union_decl.
26864///
26865/// @param t the @ref union_decl into which the method is to be copied.
26866///
26867/// @param method the method to copy into @p t.
26868///
26869/// @return the resulting newly copied method.
26870method_decl_sptr
26871copy_member_function(const union_decl_sptr& union_type,
26872 const method_decl* f)
26873{
26874 const class_or_union_sptr t = union_type;
26875 return copy_member_function(t, f);
26876}
26877
26878/// Turn equality of shared_ptr of union_decl into a deep equality;
26879/// that is, make it compare the pointed to objects too.
26880///
26881/// @param l the left-hand-side operand of the operator
26882///
26883/// @param r the right-hand-side operand of the operator.
26884///
26885/// @return true iff @p l equals @p r.
26886bool
26887operator==(const union_decl_sptr& l, const union_decl_sptr& r)
26888{
26889 if (l.get() == r.get())
26890 return true;
26891 if (!!l != !!r)
26892 return false;
26893
26894 return *l == *r;
26895}
26896
26897/// Turn inequality of shared_ptr of union_decl into a deep equality;
26898/// that is, make it compare the pointed to objects too.
26899///
26900/// @param l the left-hand-side operand of the operator
26901///
26902/// @param r the right-hand-side operand of the operator.
26903///
26904/// @return true iff @p l is different from @p r.
26905bool
26906operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
26907{return !operator==(l, r);}
26908// </union_decl>
26909
26910// <template_decl stuff>
26911
26912/// Data type of the private data of the @template_decl type.
26913class template_decl::priv
26914{
26915 friend class template_decl;
26916
26917 std::list<template_parameter_sptr> parms_;
26918public:
26919
26920 priv()
26921 {}
26922}; // end class template_decl::priv
26923
26924/// Add a new template parameter to the current instance of @ref
26925/// template_decl.
26926///
26927/// @param p the new template parameter to add.
26928void
26930{priv_->parms_.push_back(p);}
26931
26932/// Get the list of template parameters of the current instance of
26933/// @ref template_decl.
26934///
26935/// @return the list of template parameters.
26936const std::list<template_parameter_sptr>&
26938{return priv_->parms_;}
26939
26940/// Constructor.
26941///
26942/// @param env the environment we are operating from.
26943///
26944/// @param name the name of the template decl.
26945///
26946/// @param locus the source location where the template declaration is
26947/// defined.
26948///
26949/// @param vis the visibility of the template declaration.
26950template_decl::template_decl(const environment& env,
26951 const string& name,
26952 const location& locus,
26953 visibility vis)
26954 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
26955 decl_base(env, name, locus, /*mangled_name=*/"", vis),
26956 priv_(new priv)
26957{
26959}
26960
26961/// Destructor.
26964
26965/// Equality operator.
26966///
26967/// @param o the other instance to compare against.
26968///
26969/// @return true iff @p equals the current instance.
26970bool
26972{
26973 const template_decl* other = dynamic_cast<const template_decl*>(&o);
26974 if (!other)
26975 return false;
26976 return *this == *other;
26977}
26978
26979/// Equality operator.
26980///
26981/// @param o the other instance to compare against.
26982///
26983/// @return true iff @p equals the current instance.
26984bool
26986{
26987 try
26988 {
26989 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
26990 for (t0 = get_template_parameters().begin(),
26991 t1 = o.get_template_parameters().begin();
26992 (t0 != get_template_parameters().end()
26993 && t1 != o.get_template_parameters().end());
26994 ++t0, ++t1)
26995 {
26996 if (**t0 != **t1)
26997 return false;
26998 }
26999
27000 if (t0 != get_template_parameters().end()
27001 || t1 != o.get_template_parameters().end())
27002 return false;
27003
27004 return true;
27005 }
27006 catch(...)
27007 {return false;}
27008}
27009
27010// </template_decl stuff>
27011
27012//<template_parameter>
27013
27014/// The type of the private data of the @ref template_parameter type.
27015class template_parameter::priv
27016{
27017 friend class template_parameter;
27018
27019 unsigned index_;
27020 template_decl_wptr template_decl_;
27021 mutable bool hashing_started_;
27022 mutable bool comparison_started_;
27023
27024 priv();
27025
27026public:
27027
27028 priv(unsigned index, template_decl_sptr enclosing_template_decl)
27029 : index_(index),
27030 template_decl_(enclosing_template_decl),
27031 hashing_started_(),
27032 comparison_started_()
27033 {}
27034}; // end class template_parameter::priv
27035
27036template_parameter::template_parameter(unsigned index,
27037 template_decl_sptr enclosing_template)
27038 : priv_(new priv(index, enclosing_template))
27039 {}
27040
27041unsigned
27042template_parameter::get_index() const
27043{return priv_->index_;}
27044
27046template_parameter::get_enclosing_template_decl() const
27047{return priv_->template_decl_.lock();}
27048
27049
27050bool
27051template_parameter::operator==(const template_parameter& o) const
27052{
27053 if (get_index() != o.get_index())
27054 return false;
27055
27056 if (priv_->comparison_started_)
27057 return true;
27058
27059 bool result = false;
27060
27061 // Avoid inifite loops due to the fact that comparison the enclosing
27062 // template decl might lead to comparing this very same template
27063 // parameter with another one ...
27064 priv_->comparison_started_ = true;
27065
27066 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
27067 ;
27068 else if (get_enclosing_template_decl()
27069 && (*get_enclosing_template_decl()
27070 != *o.get_enclosing_template_decl()))
27071 ;
27072 else
27073 result = true;
27074
27075 priv_->comparison_started_ = false;
27076
27077 return result;
27078}
27079
27080/// Inequality operator.
27081///
27082/// @param other the other instance to compare against.
27083///
27084/// @return true iff the other instance is different from the current
27085/// one.
27086bool
27088{return !operator==(other);}
27089
27090/// Destructor.
27093
27094/// The type of the private data of the @ref type_tparameter type.
27095class type_tparameter::priv
27096{
27097 friend class type_tparameter;
27098}; // end class type_tparameter::priv
27099
27100/// Constructor of the @ref type_tparameter type.
27101///
27102/// @param index the index the type template parameter.
27103///
27104/// @param enclosing_tdecl the enclosing template declaration.
27105///
27106/// @param name the name of the template parameter.
27107///
27108/// @param locus the location of the declaration of this type template
27109/// parameter.
27110type_tparameter::type_tparameter(unsigned index,
27111 template_decl_sptr enclosing_tdecl,
27112 const string& name,
27113 const location& locus)
27114 : type_or_decl_base(enclosing_tdecl->get_environment(),
27115 ABSTRACT_DECL_BASE
27116 | ABSTRACT_TYPE_BASE
27117 | BASIC_TYPE),
27118 decl_base(enclosing_tdecl->get_environment(), name, locus),
27119 type_base(enclosing_tdecl->get_environment(), 0, 0),
27120 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
27121 template_parameter(index, enclosing_tdecl),
27122 priv_(new priv)
27123{
27125}
27126
27127/// Equality operator.
27128///
27129/// @param other the other template type parameter to compare against.
27130///
27131/// @return true iff @p other equals the current instance.
27132bool
27134{
27135 if (!type_decl::operator==(other))
27136 return false;
27137
27138 try
27139 {
27140 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27141 return template_parameter::operator==(o);
27142 }
27143 catch (...)
27144 {return false;}
27145}
27146
27147/// Equality operator.
27148///
27149/// @param other the other template type parameter to compare against.
27150///
27151/// @return true iff @p other equals the current instance.
27152bool
27154{
27155 if (!type_decl::operator==(other))
27156 return false;
27157
27158 try
27159 {
27160 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27161 return template_parameter::operator==(o);
27162 }
27163 catch (...)
27164 {return false;}
27165}
27166
27167/// Equality operator.
27168///
27169/// @param other the other template type parameter to compare against.
27170///
27171/// @return true iff @p other equals the current instance.
27172bool
27174{
27175 if (!decl_base::operator==(other))
27176 return false;
27177
27178 try
27179 {
27180 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27181 return template_parameter::operator==(o);
27182 }
27183 catch (...)
27184 {return false;}
27185}
27186
27187/// Equality operator.
27188///
27189/// @param other the other template type parameter to compare against.
27190///
27191/// @return true iff @p other equals the current instance.
27192bool
27194{
27195 try
27196 {
27197 const type_base& o = dynamic_cast<const type_base&>(other);
27198 return *this == o;
27199 }
27200 catch(...)
27201 {return false;}
27202}
27203
27204/// Equality operator.
27205///
27206/// @param other the other template type parameter to compare against.
27207///
27208/// @return true iff @p other equals the current instance.
27209bool
27211{return *this == static_cast<const type_base&>(other);}
27212
27213type_tparameter::~type_tparameter()
27214{}
27215
27216/// The type of the private data of the @ref non_type_tparameter type.
27217class non_type_tparameter::priv
27218{
27219 friend class non_type_tparameter;
27220
27221 type_base_wptr type_;
27222
27223 priv();
27224
27225public:
27226
27227 priv(type_base_sptr type)
27228 : type_(type)
27229 {}
27230}; // end class non_type_tparameter::priv
27231
27232/// The constructor for the @ref non_type_tparameter type.
27233///
27234/// @param index the index of the template parameter.
27235///
27236/// @param enclosing_tdecl the enclosing template declaration that
27237/// holds this parameter parameter.
27238///
27239/// @param name the name of the template parameter.
27240///
27241/// @param type the type of the template parameter.
27242///
27243/// @param locus the location of the declaration of this template
27244/// parameter.
27245non_type_tparameter::non_type_tparameter(unsigned index,
27246 template_decl_sptr enclosing_tdecl,
27247 const string& name,
27248 type_base_sptr type,
27249 const location& locus)
27250 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
27251 decl_base(type->get_environment(), name, locus, ""),
27252 template_parameter(index, enclosing_tdecl),
27253 priv_(new priv(type))
27254{
27256}
27257
27258/// Getter for the type of the template parameter.
27259///
27260/// @return the type of the template parameter.
27261const type_base_sptr
27263{return priv_->type_.lock();}
27264
27265
27266bool
27268{
27269 if (!decl_base::operator==(other))
27270 return false;
27271
27272 try
27273 {
27274 const non_type_tparameter& o =
27275 dynamic_cast<const non_type_tparameter&>(other);
27276 return (template_parameter::operator==(o)
27277 && get_type() == o.get_type());
27278 }
27279 catch(...)
27280 {return false;}
27281}
27282
27283bool
27285{
27286 try
27287 {
27288 const decl_base& o = dynamic_cast<const decl_base&>(other);
27289 return *this == o;
27290 }
27291 catch(...)
27292 {return false;}
27293}
27294
27295non_type_tparameter::~non_type_tparameter()
27296{}
27297
27298// <template_tparameter stuff>
27299
27300/// Type of the private data of the @ref template_tparameter type.
27301class template_tparameter::priv
27302{
27303}; //end class template_tparameter::priv
27304
27305/// Constructor for the @ref template_tparameter.
27306///
27307/// @param index the index of the template parameter.
27308///
27309/// @param enclosing_tdecl the enclosing template declaration.
27310///
27311/// @param name the name of the template parameter.
27312///
27313/// @param locus the location of the declaration of the template
27314/// parameter.
27315template_tparameter::template_tparameter(unsigned index,
27316 template_decl_sptr enclosing_tdecl,
27317 const string& name,
27318 const location& locus)
27319 : type_or_decl_base(enclosing_tdecl->get_environment(),
27320 ABSTRACT_DECL_BASE
27321 | ABSTRACT_TYPE_BASE
27322 | BASIC_TYPE),
27323 decl_base(enclosing_tdecl->get_environment(), name, locus),
27324 type_base(enclosing_tdecl->get_environment(), 0, 0),
27325 type_decl(enclosing_tdecl->get_environment(), name,
27326 0, 0, locus, name, VISIBILITY_DEFAULT),
27327 type_tparameter(index, enclosing_tdecl, name, locus),
27328 template_decl(enclosing_tdecl->get_environment(), name, locus),
27329 priv_(new priv)
27330{
27332}
27333
27334/// Equality operator.
27335///
27336/// @param other the other template parameter to compare against.
27337///
27338/// @return true iff @p other equals the current instance.
27339bool
27341{
27342 try
27343 {
27344 const template_tparameter& o =
27345 dynamic_cast<const template_tparameter&>(other);
27346 return (type_tparameter::operator==(o)
27347 && template_decl::operator==(o));
27348 }
27349 catch(...)
27350 {return false;}
27351}
27352
27353/// Equality operator.
27354///
27355/// @param other the other template parameter to compare against.
27356///
27357/// @return true iff @p other equals the current instance.
27358bool
27360{
27361 try
27362 {
27363 const template_tparameter& o =
27364 dynamic_cast<const template_tparameter&>(other);
27365 return (type_tparameter::operator==(o)
27366 && template_decl::operator==(o));
27367 }
27368 catch(...)
27369 {return false;}
27370}
27371
27372bool
27374{
27375 try
27376 {
27377 const template_tparameter& other =
27378 dynamic_cast<const template_tparameter&>(o);
27379 return *this == static_cast<const type_base&>(other);
27380 }
27381 catch(...)
27382 {return false;}
27383}
27384
27385bool
27387{
27388 try
27389 {
27390 const template_tparameter& other =
27391 dynamic_cast<const template_tparameter&>(o);
27392 return type_base::operator==(other);
27393 }
27394 catch(...)
27395 {return false;}
27396}
27397
27398template_tparameter::~template_tparameter()
27399{}
27400
27401// </template_tparameter stuff>
27402
27403// <type_composition stuff>
27404
27405/// The type of the private data of the @ref type_composition type.
27406class type_composition::priv
27407{
27408 friend class type_composition;
27409
27410 type_base_wptr type_;
27411
27412 // Forbid this.
27413 priv();
27414
27415public:
27416
27417 priv(type_base_wptr type)
27418 : type_(type)
27419 {}
27420}; //end class type_composition::priv
27421
27422/// Constructor for the @ref type_composition type.
27423///
27424/// @param index the index of the template type composition.
27425///
27426/// @param tdecl the enclosing template parameter that owns the
27427/// composition.
27428///
27429/// @param t the resulting type.
27430type_composition::type_composition(unsigned index,
27431 template_decl_sptr tdecl,
27432 type_base_sptr t)
27433 : type_or_decl_base(tdecl->get_environment(),
27434 ABSTRACT_DECL_BASE),
27435 decl_base(tdecl->get_environment(), "", location()),
27436 template_parameter(index, tdecl),
27437 priv_(new priv(t))
27438{
27440}
27441
27442/// Getter for the resulting composed type.
27443///
27444/// @return the composed type.
27445const type_base_sptr
27447{return priv_->type_.lock();}
27448
27449/// Setter for the resulting composed type.
27450///
27451/// @param t the composed type.
27452void
27454{priv_->type_ = t;}
27455
27456type_composition::~type_composition()
27457{}
27458
27459// </type_composition stuff>
27460
27461//</template_parameter stuff>
27462
27463// <function_template>
27464
27465class function_tdecl::priv
27466{
27467 friend class function_tdecl;
27468
27469 function_decl_sptr pattern_;
27470 binding binding_;
27471
27472 priv();
27473
27474public:
27475
27476 priv(function_decl_sptr pattern, binding bind)
27477 : pattern_(pattern), binding_(bind)
27478 {}
27479
27480 priv(binding bind)
27481 : binding_(bind)
27482 {}
27483}; // end class function_tdecl::priv
27484
27485/// Constructor for a function template declaration.
27486///
27487/// @param env the environment we are operating from.
27488///
27489/// @param locus the location of the declaration.
27490///
27491/// @param vis the visibility of the declaration. This is the
27492/// visibility the functions instantiated from this template are going
27493/// to have.
27494///
27495/// @param bind the binding of the declaration. This is the binding
27496/// the functions instantiated from this template are going to have.
27497function_tdecl::function_tdecl(const environment& env,
27498 const location& locus,
27499 visibility vis,
27500 binding bind)
27501 : type_or_decl_base(env,
27502 ABSTRACT_DECL_BASE
27503 | TEMPLATE_DECL
27504 | ABSTRACT_SCOPE_DECL),
27505 decl_base(env, "", locus, "", vis),
27506 template_decl(env, "", locus, vis),
27507 scope_decl(env, "", locus),
27508 priv_(new priv(bind))
27509{
27511}
27512
27513/// Constructor for a function template declaration.
27514///
27515/// @param pattern the pattern of the template.
27516///
27517/// @param locus the location of the declaration.
27518///
27519/// @param vis the visibility of the declaration. This is the
27520/// visibility the functions instantiated from this template are going
27521/// to have.
27522///
27523/// @param bind the binding of the declaration. This is the binding
27524/// the functions instantiated from this template are going to have.
27525function_tdecl::function_tdecl(function_decl_sptr pattern,
27526 const location& locus,
27527 visibility vis,
27528 binding bind)
27529 : type_or_decl_base(pattern->get_environment(),
27530 ABSTRACT_DECL_BASE
27531 | TEMPLATE_DECL
27532 | ABSTRACT_SCOPE_DECL),
27533 decl_base(pattern->get_environment(), pattern->get_name(), locus,
27534 pattern->get_name(), vis),
27535 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
27536 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
27537 priv_(new priv(pattern, bind))
27538{
27540}
27541
27542/// Set a new pattern to the function template.
27543///
27544/// @param p the new pattern.
27545void
27547{
27548 priv_->pattern_ = p;
27549 add_decl_to_scope(p, this);
27550 set_name(p->get_name());
27551}
27552
27553/// Get the pattern of the function template.
27554///
27555/// @return the pattern.
27558{return priv_->pattern_;}
27559
27560/// Get the binding of the function template.
27561///
27562/// @return the binding
27565{return priv_->binding_;}
27566
27567/// Comparison operator for the @ref function_tdecl type.
27568///
27569/// @param other the other instance of @ref function_tdecl to compare against.
27570///
27571/// @return true iff the two instance are equal.
27572bool
27574{
27575 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
27576 if (o)
27577 return *this == *o;
27578 return false;
27579}
27580
27581/// Comparison operator for the @ref function_tdecl type.
27582///
27583/// @param other the other instance of @ref function_tdecl to compare against.
27584///
27585/// @return true iff the two instance are equal.
27586bool
27588{
27589 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
27590 if (o)
27591 return *this == *o;
27592 return false;
27593}
27594
27595/// Comparison operator for the @ref function_tdecl type.
27596///
27597/// @param o the other instance of @ref function_tdecl to compare against.
27598///
27599/// @return true iff the two instance are equal.
27600bool
27602{
27603 if (!(get_binding() == o.get_binding()
27604 && template_decl::operator==(o)
27605 && scope_decl::operator==(o)
27606 && !!get_pattern() == !!o.get_pattern()))
27607 return false;
27608
27609 if (get_pattern())
27610 return (*get_pattern() == *o.get_pattern());
27611
27612 return true;
27613}
27614
27615/// This implements the ir_traversable_base::traverse pure virtual
27616/// function.
27617///
27618/// @param v the visitor used on the current instance and on the
27619/// function pattern of the template.
27620///
27621/// @return true if the entire IR node tree got traversed, false
27622/// otherwise.
27623bool
27625{
27626 if (visiting())
27627 return true;
27628
27629 if (!v.visit_begin(this))
27630 {
27631 visiting(true);
27632 if (get_pattern())
27633 get_pattern()->traverse(v);
27634 visiting(false);
27635 }
27636 return v.visit_end(this);
27637}
27638
27639function_tdecl::~function_tdecl()
27640{}
27641
27642// </function_template>
27643
27644// <class template>
27645
27646/// Type of the private data of the the @ref class_tdecl type.
27647class class_tdecl::priv
27648{
27649 friend class class_tdecl;
27650 class_decl_sptr pattern_;
27651
27652public:
27653
27654 priv()
27655 {}
27656
27657 priv(class_decl_sptr pattern)
27658 : pattern_(pattern)
27659 {}
27660}; // end class class_tdecl::priv
27661
27662/// Constructor for the @ref class_tdecl type.
27663///
27664/// @param env the environment we are operating from.
27665///
27666/// @param locus the location of the declaration of the class_tdecl
27667/// type.
27668///
27669/// @param vis the visibility of the instance of class instantiated
27670/// from this template.
27671class_tdecl::class_tdecl(const environment& env,
27672 const location& locus,
27673 visibility vis)
27674 : type_or_decl_base(env,
27675 ABSTRACT_DECL_BASE
27676 | TEMPLATE_DECL
27677 | ABSTRACT_SCOPE_DECL),
27678 decl_base(env, "", locus, "", vis),
27679 template_decl(env, "", locus, vis),
27680 scope_decl(env, "", locus),
27681 priv_(new priv)
27682{
27684}
27685
27686/// Constructor for the @ref class_tdecl type.
27687///
27688/// @param pattern The details of the class template. This must NOT be a
27689/// null pointer. If you really this to be null, please use the
27690/// constructor above instead.
27691///
27692/// @param locus the source location of the declaration of the type.
27693///
27694/// @param vis the visibility of the instances of class instantiated
27695/// from this template.
27696class_tdecl::class_tdecl(class_decl_sptr pattern,
27697 const location& locus,
27698 visibility vis)
27699 : type_or_decl_base(pattern->get_environment(),
27700 ABSTRACT_DECL_BASE
27701 | TEMPLATE_DECL
27702 | ABSTRACT_SCOPE_DECL),
27703 decl_base(pattern->get_environment(), pattern->get_name(),
27704 locus, pattern->get_name(), vis),
27705 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
27706 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
27707 priv_(new priv(pattern))
27708{
27710}
27711
27712/// Setter of the pattern of the template.
27713///
27714/// @param p the new template.
27715void
27717{
27718 priv_->pattern_ = p;
27719 add_decl_to_scope(p, this);
27720 set_name(p->get_name());
27721}
27722
27723/// Getter of the pattern of the template.
27724///
27725/// @return p the new template.
27728{return priv_->pattern_;}
27729
27730bool
27732{
27733 try
27734 {
27735 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
27736
27737 if (!(template_decl::operator==(o)
27738 && scope_decl::operator==(o)
27739 && !!get_pattern() == !!o.get_pattern()))
27740 return false;
27741
27742 if (!get_pattern() || !o.get_pattern())
27743 return true;
27744
27745 return get_pattern()->decl_base::operator==(*o.get_pattern());
27746 }
27747 catch(...) {}
27748 return false;
27749}
27750
27751bool
27753{
27754 try
27755 {
27756 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
27757 return *this == static_cast<const decl_base&>(o);
27758 }
27759 catch(...)
27760 {return false;}
27761}
27762
27763bool
27765{return *this == static_cast<const decl_base&>(o);}
27766
27767/// This implements the ir_traversable_base::traverse pure virtual
27768/// function.
27769///
27770/// @param v the visitor used on the current instance and on the class
27771/// pattern of the template.
27772///
27773/// @return true if the entire IR node tree got traversed, false
27774/// otherwise.
27775bool
27777{
27778 if (visiting())
27779 return true;
27780
27781 if (v.visit_begin(this))
27782 {
27783 visiting(true);
27784 if (class_decl_sptr pattern = get_pattern())
27785 pattern->traverse(v);
27786 visiting(false);
27787 }
27788 return v.visit_end(this);
27789}
27790
27791class_tdecl::~class_tdecl()
27792{}
27793
27794/// This visitor checks if a given type as non-canonicalized sub
27795/// types.
27796class non_canonicalized_subtype_detector : public ir::ir_node_visitor
27797{
27798 type_base* type_;
27799 type_base* has_non_canonical_type_;
27800
27801private:
27802 non_canonicalized_subtype_detector();
27803
27804public:
27805 non_canonicalized_subtype_detector(type_base* type)
27806 : type_(type),
27807 has_non_canonical_type_()
27808 {}
27809
27810 /// Return true if the visitor detected that there is a
27811 /// non-canonicalized sub-type.
27812 ///
27813 /// @return true if the visitor detected that there is a
27814 /// non-canonicalized sub-type.
27815 type_base*
27816 has_non_canonical_type() const
27817 {return has_non_canonical_type_;}
27818
27819 /// The intent of this visitor handler is to avoid looking into
27820 /// sub-types of member functions of the type we are traversing.
27821 bool
27822 visit_begin(function_decl* f)
27823 {
27824 // Do not look at sub-types of non-virtual member functions.
27825 if (is_member_function(f)
27827 return false;
27828 return true;
27829 }
27830
27831 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
27832 /// the 'has_non_canonical_type' flag. And in any case, when
27833 /// visiting a sub-type, do not visit its children nodes. So this
27834 /// function only goes to the level below the level of the top-most
27835 /// type.
27836 ///
27837 /// @return true if we are at the same level as the top-most type,
27838 /// otherwise return false.
27839 bool
27840 visit_begin(type_base* t)
27841 {
27842 if (t != type_)
27843 {
27844 if (!t->get_canonical_type())
27845 // We are looking a sub-type of 'type_' which has no
27846 // canonical type. So tada! we found one! Get out right
27847 // now with the trophy.
27848 has_non_canonical_type_ = t;
27849
27850 return false;
27851 }
27852 return true;
27853 }
27854
27855 /// When we are done visiting a sub-type, if it's been flagged as
27856 /// been non-canonicalized, then stop the traversing.
27857 ///
27858 /// Otherwise, keep going.
27859 ///
27860 /// @return false iff the sub-type that has been visited is
27861 /// non-canonicalized.
27862 bool
27863 visit_end(type_base* )
27864 {
27865 if (has_non_canonical_type_)
27866 return false;
27867 return true;
27868 }
27869}; //end class non_canonicalized_subtype_detector
27870
27871/// Test if a type has sub-types that are non-canonicalized.
27872///
27873/// @param t the type which sub-types to consider.
27874///
27875/// @return true if a type has sub-types that are non-canonicalized.
27876type_base*
27878{
27879 if (!t)
27880 return 0;
27881
27882 non_canonicalized_subtype_detector v(t.get());
27883 t->traverse(v);
27884 return v.has_non_canonical_type();
27885}
27886
27887/// Tests if the change of a given type effectively comes from just
27888/// its sub-types. That is, if the type has changed but its type name
27889/// hasn't changed, then the change of the type mostly likely is a
27890/// sub-type change.
27891///
27892/// @param t_v1 the first version of the type.
27893///
27894/// @param t_v2 the second version of the type.
27895///
27896/// @return true iff the type changed and the change is about its
27897/// sub-types.
27898bool
27899type_has_sub_type_changes(const type_base_sptr t_v1,
27900 const type_base_sptr t_v2)
27901{
27902 type_base_sptr t1 = strip_typedef(t_v1);
27903 type_base_sptr t2 = strip_typedef(t_v2);
27904
27905 string repr1 = get_pretty_representation(t1, /*internal=*/false),
27906 repr2 = get_pretty_representation(t2, /*internal=*/false);
27907 return (t1 != t2 && repr1 == repr2);
27908}
27909
27910/// Make sure that the life time of a given (smart pointer to a) type
27911/// is the same as the life time of the libabigail library.
27912///
27913/// @param t the type to consider.
27914void
27915keep_type_alive(type_base_sptr t)
27916{
27917 const environment& env = t->get_environment();
27918 env.priv_->extra_live_types_.push_back(t);
27919}
27920
27921/// Hash an ABI artifact that is either a type or a decl.
27922///
27923/// This function intends to provides the fastest possible hashing for
27924/// types and decls, while being completely correct.
27925///
27926/// Note that if the artifact is a type and if it has a canonical
27927/// type, the hash value is going to be the pointer value of the
27928/// canonical type. Otherwise, this function computes a hash value
27929/// for the type by recursively walking the type members. This last
27930/// code path is possibly *very* slow and should only be used when
27931/// only handful of types are going to be hashed.
27932///
27933/// If the artifact is a decl, then a combination of the hash of its
27934/// type and the hash of the other properties of the decl is computed.
27935///
27936/// @param tod the type or decl to hash.
27937///
27938/// @return the resulting hash value.
27939size_t
27941{
27942 hash_t result = 0;
27943
27944 if (tod == 0)
27945 ;
27946 else if (const type_base* t = is_type(tod))
27947 result = hash_type(t);
27948 else if (const decl_base* d = is_decl(tod))
27949 {
27950 if (const scope_decl* s = is_scope_decl(d))
27951 {
27952 if (const global_scope* g = is_global_scope(s))
27953 result = reinterpret_cast<size_t>(g);
27954 else
27955 result = reinterpret_cast<size_t>(s);
27956 }
27957 else if (var_decl* v = is_var_decl(d))
27958 {
27959 ABG_ASSERT(v->get_type());
27960 hash_t h = hash_type_or_decl(v->get_type());
27961 string repr = v->get_pretty_representation(/*internal=*/true);
27962 std::hash<string> hash_string;
27963 h = hashing::combine_hashes(h, hash_string(repr));
27964 result = h;
27965 }
27966 else if (function_decl* f = is_function_decl(d))
27967 {
27968 ABG_ASSERT(f->get_type());
27969 hash_t h = hash_type_or_decl(f->get_type());
27970 string repr = f->get_pretty_representation(/*internal=*/true);
27971 std::hash<string> hash_string;
27972 h = hashing::combine_hashes(h, hash_string(repr));
27973 result = h;
27974 }
27976 {
27977 type_base_sptr parm_type = p->get_type();
27978 ABG_ASSERT(parm_type);
27979 std::hash<bool> hash_bool;
27980 std::hash<unsigned> hash_unsigned;
27981 hash_t h = hash_type_or_decl(parm_type);
27982 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
27983 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
27984 result = h;
27985 }
27986 else if (class_decl::base_spec *bs = is_class_base_spec(d))
27987 {
27988 member_base::hash hash_member;
27989 std::hash<size_t> hash_size;
27990 std::hash<bool> hash_bool;
27991 type_base_sptr type = bs->get_base_class();
27992 hash_t h = hash_type_or_decl(type);
27993 h = hashing::combine_hashes(h, hash_member(*bs));
27994 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
27995 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
27996 result = h;
27997 }
27998 else
27999 // This is a *really* *SLOW* path. If it shows up in a
28000 // performance profile, I bet it'd be a good idea to try to
28001 // avoid it altogether.
28002 // TODO: recode this function or get rid of it altogethe.
28003 abort();
28004 }
28005 else
28006 // We should never get here.
28007 abort();
28008 return *result;
28009}
28010
28011/// Hash an ABI artifact that is a type.
28012///
28013/// This function intends to provides the fastest possible hashing for
28014/// types while being completely correct.
28015///
28016/// Note that if the type artifact has a canonical type, the hash
28017/// value is going to be the pointer value of the canonical type.
28018/// Otherwise, this function computes a hash value for the type by
28019/// recursively walking the type members. This last code path is
28020/// possibly *very* slow and should only be used when only handful of
28021/// types are going to be hashed.
28022///
28023/// @param t the type or decl to hash.
28024///
28025/// @return the resulting hash value.
28026size_t
28028{return hash_as_canonical_type_or_constant(t);}
28029
28030/// Hash an ABI artifact that is either a type of a decl.
28031///
28032/// @param tod the ABI artifact to hash.
28033///
28034/// @return the hash value of the ABI artifact.
28035size_t
28037{return hash_type_or_decl(tod.get());}
28038
28039/// Get the hash value associated to an IR node.
28040///
28041/// Unlike type_or_decl_base::hash_value(), if the IR has no
28042/// associated hash value, an empty hash value is returned.
28043///
28044/// @param artefact the IR node to consider.
28045///
28046/// @return the hash value stored on the IR node or an empty hash if
28047/// no hash value is stored in the @p artefact.
28048hash_t
28050{
28051 const type_or_decl_base* artefactp = &artefact;
28052 if (decl_base *d = is_decl(artefactp))
28053 {
28055 if (d->type_or_decl_base::priv_->get_hashing_state()
28057 return d->type_or_decl_base::priv_->hash_value_;
28058 }
28059 else if (artefact.priv_->get_hashing_state() == hashing::HASHING_FINISHED_STATE)
28060 return artefact.priv_->hash_value_;
28061
28062 return hash_t();
28063}
28064
28065/// Test if a given type is allowed to be non canonicalized
28066///
28067/// This is a subroutine of hash_as_canonical_type_or_constant.
28068///
28069/// For now, the only types allowed to be non canonicalized in the
28070/// system are (typedefs & pointers to) decl-only class/union, the
28071/// void type and variadic parameter types.
28072///
28073/// @return true iff @p t is a one of the only types allowed to be
28074/// non-canonicalized in the system.
28075bool
28077{
28078 if (!t)
28079 return true;
28080
28081 return (// The IR nodes for the types below are unique across the
28082 // entire ABI corpus. Thus, no need to canonicalize them.
28083 // Maybe we could say otherwise and canonicalize them once
28084 // for all so that they can be removed from here.
28086
28087 // An IR node for the types below can be equal to several
28088 // other types (i.e, a decl-only type t equals a fully
28089 // defined type of the same name in ODR-supported
28090 // languages). Hence, they can't be given a canonical type.
28091 //
28092 // TODO: Maybe add a mode that would detect ODR violations
28093 // that would make a decl-only type co-exists with several
28094 // different definitions of the type in the ABI corpus.
28097 /*look_through_decl_only=*/true)
28099
28100}
28101
28102/// Test if a type is unique in the entire environment.
28103///
28104/// Examples of unique types are void, void* and variadic parameter
28105/// types.
28106///
28107/// @param t the type to test for.
28108///
28109/// @return true iff the type @p t is unique in the entire
28110/// environment.
28111bool
28112is_unique_type(const type_base_sptr& t)
28113{return is_unique_type(t.get());}
28114
28115/// Test if a type is unique in the entire environment.
28116///
28117/// Examples of unique types are void, void* and variadic parameter
28118/// types.
28119///
28120/// @param t the type to test for.
28121///
28122/// @return true iff the type @p t is unique in the entire
28123/// environment.
28124bool
28126{
28127 if (!t)
28128 return false;
28129
28130 const environment& env = t->get_environment();
28131 return (env.is_void_type(t)
28132 || env.is_void_pointer_type(t)
28133 || env.is_variadic_parameter_type(t));
28134}
28135
28136/// For a given type, return its exemplar type.
28137///
28138/// For a given type, its exemplar type is either its canonical type
28139/// or the canonical type of the definition type of a given
28140/// declaration-only type. If the neither of those two types exist,
28141/// then the exemplar type is the given type itself.
28142///
28143/// @param type the input to consider.
28144///
28145/// @return the exemplar type.
28146type_base*
28148{
28149 if (decl_base * decl = is_decl(type))
28150 {
28151 // Make sure we get the real definition of a decl-only type.
28152 decl = look_through_decl_only(decl);
28153 type = is_type(decl);
28154 ABG_ASSERT(type);
28155 }
28156 type_base *exemplar = type->get_naked_canonical_type();
28157 if (!exemplar)
28158 {
28159 // The type has no canonical type. Let's be sure that it's one
28160 // of those rare types that are allowed to be non canonicalized
28161 // in the system.
28162 exemplar = const_cast<type_base*>(type);
28164 }
28165 return exemplar;
28166}
28167
28168/// Test if a given type is allowed to be non canonicalized
28169///
28170/// This is a subroutine of hash_as_canonical_type_or_constant.
28171///
28172/// For now, the only types allowed to be non canonicalized in the
28173/// system are decl-only class/union and the void type.
28174///
28175/// @return true iff @p t is a one of the only types allowed to be
28176/// non-canonicalized in the system.
28177bool
28178is_non_canonicalized_type(const type_base_sptr& t)
28179{return is_non_canonicalized_type(t.get());}
28180
28181/// Hash a type by either returning the pointer value of its canonical
28182/// type or by returning a constant if the type doesn't have a
28183/// canonical type.
28184///
28185/// This is a subroutine of hash_type.
28186///
28187/// @param t the type to consider.
28188///
28189/// @return the hash value.
28190static size_t
28191hash_as_canonical_type_or_constant(const type_base *t)
28192{
28193 type_base *canonical_type = 0;
28194
28195 if (t)
28196 canonical_type = t->get_naked_canonical_type();
28197
28198 if (!canonical_type)
28199 {
28200 // If the type doesn't have a canonical type, maybe it's because
28201 // it's a declaration-only type? If that's the case, let's try
28202 // to get the canonical type of the definition of this
28203 // declaration.
28204 decl_base *decl = is_decl(t);
28205 if (decl
28206 && decl->get_is_declaration_only()
28208 {
28209 type_base *definition =
28211 ABG_ASSERT(definition);
28212 canonical_type = definition->get_naked_canonical_type();
28213 }
28214 }
28215
28216 if (canonical_type)
28217 return reinterpret_cast<size_t>(canonical_type);
28218
28219 // If we reached this point, it means we are seeing a
28220 // non-canonicalized type. It must be a decl-only class or a void
28221 // type, otherwise it means that for some weird reason, the type
28222 // hasn't been canonicalized. It should be!
28224
28225 return 0xDEADBABE;
28226}
28227
28228/// Test if the pretty representation of a given @ref function_decl is
28229/// lexicographically less then the pretty representation of another
28230/// @ref function_decl.
28231///
28232/// @param f the first @ref function_decl to consider for comparison.
28233///
28234/// @param s the second @ref function_decl to consider for comparison.
28235///
28236/// @return true iff the pretty representation of @p f is
28237/// lexicographically less than the pretty representation of @p s.
28238bool
28240{
28243
28244 if (fr != sr)
28245 return fr < sr;
28246
28247 fr = f.get_pretty_representation(/*internal=*/true),
28248 sr = s.get_pretty_representation(/*internal=*/true);
28249
28250 if (fr != sr)
28251 return fr < sr;
28252
28253 if (f.get_symbol())
28254 fr = f.get_symbol()->get_id_string();
28255 else if (!f.get_linkage_name().empty())
28256 fr = f.get_linkage_name();
28257
28258 if (s.get_symbol())
28259 sr = s.get_symbol()->get_id_string();
28260 else if (!s.get_linkage_name().empty())
28261 sr = s.get_linkage_name();
28262
28263 return fr < sr;
28264}
28265
28266/// Test if two types have similar structures, even though they are
28267/// (or can be) different.
28268///
28269/// const and volatile qualifiers are completely ignored.
28270///
28271/// typedef are resolved to their definitions; their names are ignored.
28272///
28273/// Two indirect types (pointers or references) have similar structure
28274/// if their underlying types are of the same kind and have the same
28275/// name. In the indirect types case, the size of the underlying type
28276/// does not matter.
28277///
28278/// Two direct types (i.e, non indirect) have a similar structure if
28279/// they have the same kind, name and size. Two class types have
28280/// similar structure if they have the same name, size, and if the
28281/// types of their data members have similar types.
28282///
28283/// @param first the first type to consider.
28284///
28285/// @param second the second type to consider.
28286///
28287/// @param indirect_type whether to do an indirect comparison
28288///
28289/// @return true iff @p first and @p second have similar structures.
28290bool
28291types_have_similar_structure(const type_base_sptr& first,
28292 const type_base_sptr& second,
28293 bool indirect_type)
28294{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
28295
28296/// Test if two types have similar structures, even though they are
28297/// (or can be) different.
28298///
28299/// const and volatile qualifiers are completely ignored.
28300///
28301/// typedef are resolved to their definitions; their names are ignored.
28302///
28303/// Two indirect types (pointers, references or arrays) have similar
28304/// structure if their underlying types are of the same kind and have
28305/// the same name. In the indirect types case, the size of the
28306/// underlying type does not matter.
28307///
28308/// Two direct types (i.e, non indirect) have a similar structure if
28309/// they have the same kind, name and size. Two class types have
28310/// similar structure if they have the same name, size, and if the
28311/// types of their data members have similar types.
28312///
28313/// @param first the first type to consider.
28314///
28315/// @param second the second type to consider.
28316///
28317/// @param indirect_type if true, then consider @p first and @p
28318/// second as being underlying types of indirect types. Meaning that
28319/// their size does not matter.
28320///
28321/// @return true iff @p first and @p second have similar structures.
28322bool
28324 const type_base* second,
28325 bool indirect_type)
28326{
28327 if (!!first != !!second)
28328 return false;
28329
28330 if (!first)
28331 return false;
28332
28333 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
28334 first = peel_qualified_or_typedef_type(first);
28335 second = peel_qualified_or_typedef_type(second);
28336
28337 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
28338 // various ty2 below cannot be null.
28339 if (typeid(*first) != typeid(*second))
28340 return false;
28341
28342 // Peel off matching pointers.
28343 if (const pointer_type_def* ty1 = is_pointer_type(first))
28344 {
28345 const pointer_type_def* ty2 = is_pointer_type(second);
28346 return types_have_similar_structure(ty1->get_pointed_to_type(),
28347 ty2->get_pointed_to_type(),
28348 /*indirect_type=*/true);
28349 }
28350
28351 // Peel off matching references.
28352 if (const reference_type_def* ty1 = is_reference_type(first))
28353 {
28354 const reference_type_def* ty2 = is_reference_type(second);
28355 if (ty1->is_lvalue() != ty2->is_lvalue())
28356 return false;
28357 return types_have_similar_structure(ty1->get_pointed_to_type(),
28358 ty2->get_pointed_to_type(),
28359 /*indirect_type=*/true);
28360 }
28361
28362 // Peel off matching pointer-to-member types.
28363 if (const ptr_to_mbr_type* ty1 = is_ptr_to_mbr_type(first))
28364 {
28365 const ptr_to_mbr_type* ty2 = is_ptr_to_mbr_type(second);
28366 return (types_have_similar_structure(ty1->get_member_type(),
28367 ty2->get_member_type(),
28368 /*indirect_type=*/true)
28369 && types_have_similar_structure(ty1->get_containing_type(),
28370 ty2->get_containing_type(),
28371 /*indirect_type=*/true));
28372 }
28373
28374 if (const type_decl* ty1 = is_type_decl(first))
28375 {
28376 const type_decl* ty2 = is_type_decl(second);
28377 if (!indirect_type)
28378 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28379 return false;
28380
28381 return ty1->get_name() == ty2->get_name();
28382 }
28383
28384 if (const enum_type_decl* ty1 = is_enum_type(first))
28385 {
28386 const enum_type_decl* ty2 = is_enum_type(second);
28387 if (!indirect_type)
28388 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28389 return false;
28390
28391 return (get_name(ty1->get_underlying_type())
28392 == get_name(ty2->get_underlying_type()));
28393 }
28394
28395 if (const class_decl* ty1 = is_class_type(first))
28396 {
28397 const class_decl* ty2 = is_class_type(second);
28398 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28399 && ty1->get_name() != ty2->get_name())
28400 return false;
28401
28402 if (!indirect_type)
28403 {
28404 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
28405 || (ty1->get_non_static_data_members().size()
28406 != ty2->get_non_static_data_members().size()))
28407 return false;
28408
28409 for (class_or_union::data_members::const_iterator
28410 i = ty1->get_non_static_data_members().begin(),
28411 j = ty2->get_non_static_data_members().begin();
28412 (i != ty1->get_non_static_data_members().end()
28413 && j != ty2->get_non_static_data_members().end());
28414 ++i, ++j)
28415 {
28416 var_decl_sptr dm1 = *i;
28417 var_decl_sptr dm2 = *j;
28418 if (!types_have_similar_structure(dm1->get_type().get(),
28419 dm2->get_type().get(),
28420 indirect_type))
28421 return false;
28422 }
28423 }
28424
28425 return true;
28426 }
28427
28428 if (const union_decl* ty1 = is_union_type(first))
28429 {
28430 const union_decl* ty2 = is_union_type(second);
28431 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28432 && ty1->get_name() != ty2->get_name())
28433 return false;
28434
28435 if (!indirect_type)
28436 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
28437
28438 return true;
28439 }
28440
28441 if (const array_type_def* ty1 = is_array_type(first))
28442 {
28443 const array_type_def* ty2 = is_array_type(second);
28444 // TODO: Handle int[5][2] vs int[2][5] better.
28445 if (!indirect_type)
28446 {
28447 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
28448 || ty1->get_dimension_count() != ty2->get_dimension_count())
28449 return false;
28450 }
28451
28452 if (!types_have_similar_structure(ty1->get_element_type(),
28453 ty2->get_element_type(),
28454 /*indirect_type=*/true))
28455 return false;
28456
28457 return true;
28458 }
28459
28460 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
28461 {
28463 if (ty1->get_upper_bound() != ty2->get_upper_bound()
28464 || ty1->get_lower_bound() != ty2->get_lower_bound()
28465 || ty1->get_language() != ty2->get_language()
28466 || !types_have_similar_structure(ty1->get_underlying_type(),
28467 ty2->get_underlying_type(),
28468 indirect_type))
28469 return false;
28470
28471 return true;
28472 }
28473
28474 if (const function_type* ty1 = is_function_type(first))
28475 {
28476 const function_type* ty2 = is_function_type(second);
28477 if (!types_have_similar_structure(ty1->get_return_type(),
28478 ty2->get_return_type(),
28479 indirect_type))
28480 return false;
28481
28482 if (ty1->get_parameters().size() != ty2->get_parameters().size())
28483 return false;
28484
28485 for (function_type::parameters::const_iterator
28486 i = ty1->get_parameters().begin(),
28487 j = ty2->get_parameters().begin();
28488 (i != ty1->get_parameters().end()
28489 && j != ty2->get_parameters().end());
28490 ++i, ++j)
28491 if (!types_have_similar_structure((*i)->get_type(),
28492 (*j)->get_type(),
28493 indirect_type))
28494 return false;
28495
28496 return true;
28497 }
28498
28499 // All kinds of type should have been handled at this point.
28501
28502 return false;
28503}
28504
28505/// Look for a data member of a given class, struct or union type and
28506/// return it.
28507///
28508/// The data member is designated by its name.
28509///
28510/// @param type the class, struct or union type to consider.
28511///
28512/// @param dm_name the name of the data member to lookup.
28513///
28514/// @return the data member iff it was found in @type or NULL if no
28515/// data member with that name was found.
28516const var_decl*
28518 const char* dm_name)
28519
28520{
28522 if (!cou)
28523 return 0;
28524
28525 return cou->find_data_member(dm_name).get();
28526}
28527
28528/// Look for a data member of a given class, struct or union type and
28529/// return it.
28530///
28531/// The data member is designated by its name.
28532///
28533/// @param type the class, struct or union type to consider.
28534///
28535/// @param dm the data member to lookup.
28536///
28537/// @return the data member iff it was found in @type or NULL if no
28538/// data member with that name was found.
28539const var_decl_sptr
28540lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
28541{
28542 class_or_union_sptr cou = is_class_or_union_type(type);
28543 if (!cou)
28544 return var_decl_sptr();
28545
28546 return cou->find_data_member(dm);
28547}
28548
28549/// Get the function parameter designated by its index.
28550///
28551/// Note that the first function parameter has index 0.
28552///
28553/// @param fun the function to consider.
28554///
28555/// @param parm_index the index of the function parameter to get.
28556///
28557/// @return the function parameter designated by its index, of NULL if
28558/// no function parameter with that index was found.
28561 unsigned parm_index)
28562{
28564 if (!fn)
28565 return 0;
28566
28567 const function_decl::parameters &parms = fn->get_type()->get_parameters();
28568 if (parms.size() <= parm_index)
28569 return 0;
28570
28571 return parms[parm_index].get();
28572}
28573
28574/// Build the internal name of the underlying type of an enum.
28575///
28576/// @param base_name the (unqualified) name of the enum the underlying
28577/// type is destined to.
28578///
28579/// @param is_anonymous true if the underlying type of the enum is to
28580/// be anonymous.
28581string
28583 bool is_anonymous,
28584 uint64_t size)
28585{
28586 std::ostringstream o;
28587
28588 if (is_anonymous)
28589 o << "unnamed-enum";
28590 else
28591 o << "enum-" << base_name;
28592
28593 o << "-underlying-type-" << size;
28594
28595 return o.str();
28596}
28597
28598/// Find the first data member of a class or union which name matches
28599/// a regular expression.
28600///
28601/// @param t the class or union to consider.
28602///
28603/// @param r the regular expression to consider.
28604///
28605/// @return the data member matched by @p r or nil if none was found.
28608 const regex::regex_t_sptr& r)
28609{
28610 for (auto data_member : t.get_data_members())
28611 {
28612 if (regex::match(r, data_member->get_name()))
28613 return data_member;
28614 }
28615
28616 return var_decl_sptr();
28617}
28618
28619/// Find the last data member of a class or union which name matches
28620/// a regular expression.
28621///
28622/// @param t the class or union to consider.
28623///
28624/// @param r the regular expression to consider.
28625///
28626/// @return the data member matched by @p r or nil if none was found.
28629 const regex::regex_t_sptr& regex)
28630{
28631 auto d = t.get_data_members().rbegin();
28632 auto e = t.get_data_members().rend();
28633 for (; d != e; ++d)
28634 {
28635 if (regex::match(regex, (*d)->get_name()))
28636 return *d;
28637 }
28638
28639 return var_decl_sptr();
28640}
28641
28642/// Emit the pretty representation of the parameters of a function
28643/// type.
28644///
28645/// @param fn_type the function type to consider.
28646///
28647/// @param o the output stream to emit the pretty representation to.
28648///
28649/// @param qualified if true, emit fully qualified names.
28650///
28651/// @param internal if true, then the result is to be used for the
28652/// purpose of type canonicalization.
28653static void
28654stream_pretty_representation_of_fn_parms(const function_type& fn_type,
28655 ostream& o, bool qualified,
28656 bool internal)
28657{
28658 o << "(";
28659 if (fn_type.get_parameters().empty())
28660 o << "void";
28661 else
28662 {
28663 type_base_sptr type;
28664 auto end = fn_type.get_parameters().end();
28665 auto first_parm = fn_type.get_first_non_implicit_parm();
28667 const environment& env = fn_type.get_environment();
28668 for (auto i = fn_type.get_first_non_implicit_parm(); i != end; ++i)
28669 {
28670 if (i != first_parm)
28671 o << ", ";
28672 parm = *i;
28673 type = parm->get_type();
28674 // If the type is a decl-only class, union or enum that has a
28675 // definition, use the definition instead. That definition
28676 // is what is going to be serialized out in ABIXML anyway,
28677 // so use that for consistency.
28678 if (decl_base_sptr def = look_through_decl_only(is_decl(type)))
28679 type = is_type(def);
28680 if (env.is_variadic_parameter_type(type))
28681 o << "...";
28682 else
28683 o << get_type_name(type, qualified, internal);
28684 }
28685 }
28686 o << ")";
28687}
28688
28689/// When constructing the name of a pointer to function type, add the
28690/// return type to the left of the existing type identifier, and the
28691/// parameters declarator to the right.
28692///
28693/// This function considers the name of the type as an expression.
28694///
28695/// The resulting type expr is going to be made of three parts:
28696/// left_expr inner_expr right_expr.
28697///
28698/// Suppose we want to build the type expression representing:
28699///
28700/// "an array of pointer to function taking a char parameter and
28701/// returning an int".
28702///
28703/// It's going to look like:
28704///
28705/// int(*a[])(char);
28706///
28707/// Suppose the caller of this function started to emit the inner
28708/// "a[]" part of the expression already. It thus calls this
28709/// function with that input "a[]" part. We consider that "a[]" as
28710/// the "type identifier".
28711///
28712/// So the inner_expr is going to be "(*a[])".
28713///
28714/// The left_expr part is "int". The right_expr part is "(char)".
28715///
28716/// In other words, this function adds the left_expr and right_expr to
28717/// the inner_expr. left_expr and right_expr are called "outer
28718/// pointer to function type expression".
28719///
28720/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28721/// array_declaration_name()
28722///
28723/// @param p the pointer to function type to consider.
28724///
28725/// @param input the type-id to use as the inner expression of the
28726/// overall pointer-to-function type expression
28727///
28728/// @param qualified if true then use qualified names in the resulting
28729/// type name.
28730///
28731/// @param internal if true then the resulting type name is going to
28732/// be used for type canonicalization purposes.
28733///
28734/// @return the name of the pointer to function type.
28735static string
28736add_outer_pointer_to_fn_type_expr(const type_base* p,
28737 const string& input,
28738 bool qualified, bool internal)
28739{
28740 if (!p)
28741 return "";
28742
28743 function_type_sptr pointed_to_fn;
28744 string star_or_ref;
28745
28746 if (const pointer_type_def* ptr = is_pointer_type(p))
28747 {
28748 pointed_to_fn = is_function_type(ptr->get_pointed_to_type());
28749 star_or_ref= "*";
28750 }
28751 else if (const reference_type_def* ref = is_reference_type(p))
28752 {
28753 star_or_ref = "&";
28754 pointed_to_fn = is_function_type(ref->get_pointed_to_type());
28755 }
28756
28757 if (!pointed_to_fn)
28758 return "";
28759
28760 if (pointed_to_fn->priv_->is_pretty_printing())
28761 // We have just detected a cycle while walking the sub-tree of
28762 // this function type for the purpose of printing its
28763 // representation. We need to get out of here pronto or else
28764 // we'll be spinning endlessly.
28765 return "";
28766
28767 // Let's mark thie function type to signify that we started walking
28768 // its subtree. This is to detect potential cycles and avoid
28769 // looping endlessly.
28770 pointed_to_fn->priv_->set_is_pretty_printing();
28771
28772 std::ostringstream left, right, inner;
28773
28774 inner << "(" << star_or_ref << input << ")";
28775
28776 type_base_sptr type;
28777 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
28778 qualified, internal);
28779
28780 type_base_sptr return_type = pointed_to_fn->get_return_type();
28781 string result;
28782
28783 if (is_npaf_type(return_type)
28784 || !(is_pointer_to_function_type(return_type)
28785 || is_pointer_to_array_type(return_type)))
28786 {
28787 if (return_type)
28788 left << get_type_name(return_type, qualified, internal);
28789 result = left.str() + " " + inner.str() + right.str();
28790 }
28791 else if (pointer_type_def_sptr p = is_pointer_to_function_type(return_type))
28792 {
28793 string inner_string = inner.str() + right.str();
28794 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
28795 qualified, internal);
28796 }
28797 else if (pointer_type_def_sptr p = is_pointer_to_array_type(return_type))
28798 {
28799 string inner_string = inner.str() + right.str();
28800 result = add_outer_pointer_to_array_type_expr(p, inner_string,
28801 qualified, internal);
28802 }
28803 else
28805
28806 // Lets unmark this function type to signify that we are done
28807 // walking its subtree. This was to detect potential cycles and
28808 // avoid looping endlessly.
28809 pointed_to_fn->priv_->unset_is_pretty_printing();
28810 return result;
28811}
28812
28813/// When constructing the name of a pointer to function type, add the
28814/// return type to the left of the existing type identifier, and the
28815/// parameters declarator to the right.
28816///
28817/// This function considers the name of the type as an expression.
28818///
28819/// The resulting type expr is going to be made of three parts:
28820/// left_expr inner_expr right_expr.
28821///
28822/// Suppose we want to build the type expression representing:
28823///
28824/// "an array of pointer to function taking a char parameter and
28825/// returning an int".
28826///
28827/// It's going to look like:
28828///
28829/// int(*a[])(char);
28830///
28831/// Suppose the caller of this function started to emit the inner
28832/// "a[]" part of the expression already. It thus calls this
28833/// function with that input "a[]" part. We consider that "a[]" as
28834/// the "type identifier".
28835///
28836/// So the inner_expr is going to be "(*a[])".
28837///
28838/// The left_expr part is "int". The right_expr part is "(char)".
28839///
28840/// In other words, this function adds the left_expr and right_expr to
28841/// the inner_expr. left_expr and right_expr are called "outer
28842/// pointer to function type expression".
28843///
28844/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28845/// array_declaration_name()
28846///
28847/// @param p the pointer to function type to consider.
28848///
28849/// @param input the type-id to use as the inner expression of the
28850/// overall pointer-to-function type expression
28851///
28852/// @param qualified if true then use qualified names in the resulting
28853/// type name.
28854///
28855/// @param internal if true then the resulting type name is going to
28856/// be used for type canonicalization purposes.
28857///
28858/// @return the name of the pointer to function type.
28859static string
28860add_outer_pointer_to_fn_type_expr(const type_base_sptr& p,
28861 const string& input,
28862 bool qualified, bool internal)
28863{return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
28864
28865/// When constructing the name of a pointer to array type, add the
28866/// array element type type to the left of the existing type
28867/// identifier, and the array declarator part to the right.
28868///
28869/// This function considers the name of the type as an expression.
28870///
28871/// The resulting type expr is going to be made of three parts:
28872/// left_expr inner_expr right_expr.
28873///
28874/// Suppose we want to build the type expression representing:
28875///
28876/// "a pointer to an array of int".
28877///
28878/// It's going to look like:
28879///
28880/// int(*foo)[];
28881///
28882/// Suppose the caller of this function started to emit the inner
28883/// "foo" part of the expression already. It thus calls this function
28884/// with that input "foo" part. We consider that "foo" as the "type
28885/// identifier".
28886///
28887/// So we are passed an input string that is "foo" and it's going to
28888/// be turned into the inner_expr part, which is going to be "(*foo)".
28889///
28890/// The left_expr part is "int". The right_expr part is "[]".
28891///
28892/// In other words, this function adds the left_expr and right_expr to
28893/// the inner_expr. left_expr and right_expr are called "outer
28894/// pointer to array type expression".
28895///
28896/// The model of this function was taken from the article "Reading C
28897/// type declaration", from Steve Friedl at
28898/// http://unixwiz.net/techtips/reading-cdecl.html.
28899///
28900/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28901/// array_declaration_name()
28902///
28903/// @param p the pointer to array type to consider.
28904///
28905/// @param input the type-id to start from as the inner part of the
28906/// final type name.
28907///
28908/// @param qualified if true then use qualified names in the resulting
28909/// type name.
28910///
28911/// @param internal if true then the resulting type name is going to
28912/// be used for type canonicalization purposes.
28913///
28914/// @return the name of the pointer to array type.
28915static string
28916add_outer_pointer_to_array_type_expr(const type_base* p,
28917 const string& input, bool qualified,
28918 bool internal)
28919{
28920 if (!p)
28921 return "";
28922
28923 string star_or_ref;
28924 type_base_sptr pointed_to_type;
28925
28926 if (const pointer_type_def *ptr = is_pointer_type(p))
28927 {
28928 pointed_to_type = ptr->get_pointed_to_type();
28929 star_or_ref = "*";
28930 }
28931 else if (const reference_type_def *ref = is_reference_type(p))
28932 {
28933 pointed_to_type = ref->get_pointed_to_type();
28934 star_or_ref = "&";
28935 }
28936
28937 array_type_def_sptr array = is_array_type(pointed_to_type);
28938 if (!array)
28939 return "";
28940
28941 std::ostringstream left, right, inner;
28942 inner << "(" << star_or_ref << input << ")";
28943 right << array->get_subrange_representation();
28944 string result;
28945
28946 type_base_sptr array_element_type = array->get_element_type();
28947
28948 if (is_npaf_type(array_element_type)
28949 || !(is_pointer_to_function_type(array_element_type)
28950 || is_pointer_to_array_type(array_element_type)))
28951 {
28952 left << get_type_name(array_element_type, qualified, internal);
28953 result = left.str() + inner.str() + right.str();
28954 }
28955 else if (pointer_type_def_sptr p =
28956 is_pointer_to_function_type(array_element_type))
28957 {
28958 string r = inner.str() + right.str();
28959 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
28960 }
28961 else if (pointer_type_def_sptr p =
28962 is_pointer_to_array_type(array_element_type))
28963 {
28964 string inner_string = inner.str() + right.str();
28965 result = add_outer_pointer_to_array_type_expr(p, inner_string,
28966 qualified, internal);
28967 }
28968 else
28970
28971 return result;
28972}
28973
28974/// When constructing the name of a pointer to array type, add the
28975/// array element type type to the left of the existing type
28976/// identifier, and the array declarator part to the right.
28977///
28978/// This function considers the name of the type as an expression.
28979///
28980/// The resulting type expr is going to be made of three parts:
28981/// left_expr inner_expr right_expr.
28982///
28983/// Suppose we want to build the type expression representing:
28984///
28985/// "a pointer to an array of int".
28986///
28987/// It's going to look like:
28988///
28989/// int(*foo)[];
28990///
28991/// Suppose the caller of this function started to emit the inner
28992/// "foo" part of the expression already. It thus calls this function
28993/// with that input "foo" part. We consider that "foo" as the "type
28994/// identifier".
28995///
28996/// So we are passed an input string that is "foo" and it's going to
28997/// be turned into the inner_expr part, which is going to be "(*foo)".
28998///
28999/// The left_expr part is "int". The right_expr part is "[]".
29000///
29001/// In other words, this function adds the left_expr and right_expr to
29002/// the inner_expr. left_expr and right_expr are called "outer
29003/// pointer to array type expression".
29004///
29005/// The model of this function was taken from the article "Reading C
29006/// type declaration", from Steve Friedl at
29007/// http://unixwiz.net/techtips/reading-cdecl.html.
29008///
29009/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29010/// array_declaration_name()
29011///
29012/// @param p the pointer to array type to consider.
29013///
29014/// @param input the type-id to start from as the inner part of the
29015/// final type name.
29016///
29017/// @param qualified if true then use qualified names in the resulting
29018/// type name.
29019///
29020/// @param internal if true then the resulting type name is going to
29021/// be used for type canonicalization purposes.
29022///
29023/// @return the name of the pointer to array type.
29024static string
29025add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
29026 const string& input, bool qualified,
29027 bool internal)
29028{return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
29029 input, qualified, internal);}
29030
29031/// When constructing the name of a pointer to mebmer type, add the
29032/// return type to the left of the existing type identifier, and the
29033/// parameters declarator to the right.
29034///
29035/// This function considers the name of the type as an expression.
29036///
29037/// The resulting type expr is going to be made of three parts:
29038/// left_expr inner_expr right_expr.
29039///
29040/// Suppose we want to build the type expression representing:
29041///
29042/// "an array of pointer to member function (of a containing struct
29043/// X) taking a char parameter and returning an int".
29044///
29045/// It's going to look like:
29046///
29047/// int (X::* a[])(char);
29048///
29049/// Suppose the caller of this function started to emit the inner
29050/// "a[]" part of the expression already. It thus calls this
29051/// function with that input "a[]" part. We consider that "a[]" as
29052/// the "type identifier".
29053///
29054/// So the inner_expr is going to be "(X::* a[])".
29055///
29056/// The left_expr part is "int". The right_expr part is "(char)".
29057///
29058/// In other words, this function adds the left_expr and right_expr to
29059/// the inner_expr. left_expr and right_expr are called "outer
29060/// pointer to member type expression".
29061///
29062/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29063///
29064/// @param p the pointer to member type to consider.
29065///
29066/// @param input the type-id to use as the inner expression of the
29067/// overall pointer-to-member type expression
29068///
29069/// @param qualified if true then use qualified names in the resulting
29070/// type name.
29071///
29072/// @param internal if true then the resulting type name is going to
29073/// be used for type canonicalization purposes.
29074///
29075/// @return the name of the pointer to member type.
29076static string
29077add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
29078 const string& input, bool qualified,
29079 bool internal)
29080{
29081 if (!p)
29082 return "";
29083
29084 std::ostringstream left, right, inner;
29085 type_base_sptr void_type = p->get_environment().get_void_type();
29086 string containing_type_name = get_type_name(p->get_containing_type(),
29087 qualified, internal);
29088 type_base_sptr mbr_type = p->get_member_type();
29089 string result;
29090 if (function_type_sptr fn_type = is_function_type(mbr_type))
29091 {
29092 inner << "(" << containing_type_name << "::*" << input << ")";
29093 stream_pretty_representation_of_fn_parms(*fn_type, right,
29094 qualified, internal);
29095 type_base_sptr return_type = fn_type->get_return_type();
29096 if (!return_type)
29097 return_type = void_type;
29098 if (is_npaf_type(return_type)
29099 || !(is_pointer_to_function_type(return_type)
29100 || is_pointer_to_array_type(return_type)
29101 || is_pointer_to_ptr_to_mbr_type(return_type)
29102 || is_ptr_to_mbr_type(return_type)))
29103 {
29104 left << get_type_name(return_type, qualified, internal) << " ";;
29105 result = left.str() + inner.str() + right.str();
29106 }
29107 else if (pointer_type_def_sptr p = is_pointer_type(return_type))
29108 {
29109 string inner_str = inner.str() + right.str();
29110 result = pointer_declaration_name(p, inner_str, qualified, internal);
29111 }
29112 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(return_type))
29113 {
29114 string inner_str = inner.str() + right.str();
29115 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
29116 qualified, internal);
29117 }
29118 else
29120 }
29121 else if (ptr_to_mbr_type_sptr ptr_mbr_type = is_ptr_to_mbr_type(mbr_type))
29122 {
29123 inner << "(" << containing_type_name << "::*" << input << ")";
29124 stream_pretty_representation_of_fn_parms(*fn_type, right,
29125 qualified, internal);
29126 string inner_str = inner.str() + right.str();
29127 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
29128 qualified, internal);
29129 }
29130 else
29131 {
29132 left << get_type_name(p->get_member_type(), qualified, internal) << " ";
29133 inner << containing_type_name << "::*" << input;
29134 result = left.str()+ inner.str();
29135 }
29136
29137 return result;
29138}
29139
29140/// When constructing the name of a pointer to mebmer type, add the
29141/// return type to the left of the existing type identifier, and the
29142/// parameters declarator to the right.
29143///
29144/// This function considers the name of the type as an expression.
29145///
29146/// The resulting type expr is going to be made of three parts:
29147/// left_expr inner_expr right_expr.
29148///
29149/// Suppose we want to build the type expression representing:
29150///
29151/// "an array of pointer to member function (of a containing struct
29152/// X) taking a char parameter and returning an int".
29153///
29154/// It's going to look like:
29155///
29156/// int (X::* a[])(char);
29157///
29158/// Suppose the caller of this function started to emit the inner
29159/// "a[]" part of the expression already. It thus calls this
29160/// function with that input "a[]" part. We consider that "a[]" as
29161/// the "type identifier".
29162///
29163/// So the inner_expr is going to be "(X::* a[])".
29164///
29165/// The left_expr part is "int". The right_expr part is "(char)".
29166///
29167/// In other words, this function adds the left_expr and right_expr to
29168/// the inner_expr. left_expr and right_expr are called "outer
29169/// pointer to member type expression".
29170///
29171/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29172///
29173/// @param p the pointer to member type to consider.
29174///
29175/// @param input the type-id to use as the inner expression of the
29176/// overall pointer-to-member type expression
29177///
29178/// @param qualified if true then use qualified names in the resulting
29179/// type name.
29180///
29181/// @param internal if true then the resulting type name is going to
29182/// be used for type canonicalization purposes.
29183///
29184/// @return the name of the pointer to member type.
29185static string
29186add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
29187 const string& input, bool qualified,
29188 bool internal)
29189{return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
29190
29191/// This adds the outer parts of a pointer to a pointer-to-member
29192/// expression.
29193///
29194/// Please read the comments of @ref add_outer_ptr_to_mbr_type_expr to
29195/// learn more about this function, which is similar.
29196///
29197/// This is a sub-routine of @ref pointer_declaration_name().
29198///
29199/// @param a pointer (or reference) to a pointer-to-member type.
29200///
29201/// @param input the inner type-id to add the outer parts to.
29202///
29203/// @param qualified if true then use qualified names in the resulting
29204/// type name.
29205///
29206/// @param internal if true then the resulting type name is going to
29207/// be used for type canonicalization purposes.
29208static string
29209add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
29210 const string& input, bool qualified,
29211 bool internal)
29212{
29213 if (!p)
29214 return "";
29215
29216 string star_or_ref;
29217 type_base_sptr pointed_to_type;
29218
29219 if (const pointer_type_def* ptr = is_pointer_type(p))
29220 {
29221 pointed_to_type = ptr->get_pointed_to_type();
29222 star_or_ref = "*";
29223 }
29224 else if (const reference_type_def* ref = is_reference_type(p))
29225 {
29226 pointed_to_type= ref->get_pointed_to_type();
29227 star_or_ref = "&";
29228 }
29229
29230 if (!pointed_to_type)
29231 return "";
29232
29233 ptr_to_mbr_type_sptr pointed_to_ptr_to_mbr =
29234 is_ptr_to_mbr_type(pointed_to_type);
29235 if (!pointed_to_ptr_to_mbr)
29236 return "";
29237
29238 std::ostringstream inner;
29239 inner << star_or_ref << input;
29240 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
29241 inner.str(),
29242 qualified, internal);
29243 return result;
29244}
29245
29246/// Emit the name of a pointer declaration.
29247///
29248/// @param the pointer to consider.
29249///
29250/// @param idname the name of the variable that has @p as a type or
29251/// the id of the type. If it's empty then the resulting name is
29252/// going to be the abstract name of the type.
29253///
29254/// @param qualified if true then the type name is going to be
29255/// fully qualified.
29256///
29257/// @param internal if true then the type name is going to be used for
29258/// type canonicalization purposes.
29259static interned_string
29260pointer_declaration_name(const type_base* ptr,
29261 const string& idname,
29262 bool qualified, bool internal)
29263{
29264 if (!ptr)
29265 return interned_string();
29266
29267 type_base_sptr pointed_to_type;
29268 string star_or_ref;
29269 if (const pointer_type_def* p = is_pointer_type(ptr))
29270 {
29271 pointed_to_type = p->get_pointed_to_type();
29272 star_or_ref = "*";
29273 }
29274 else if (const reference_type_def* p = is_reference_type(ptr))
29275 {
29276 pointed_to_type = p->get_pointed_to_type();
29277 star_or_ref = "&";
29278 }
29279
29280 if (!pointed_to_type)
29281 return interned_string();
29282
29283 string result;
29284 if (is_npaf_type(pointed_to_type)
29285 || !(is_function_type(pointed_to_type)
29286 || is_array_type(pointed_to_type)
29287 || is_ptr_to_mbr_type(pointed_to_type)))
29288 {
29289 result = get_type_name(pointed_to_type,
29290 qualified,
29291 internal)
29292 + star_or_ref;
29293
29294 if (!idname.empty())
29295 result += idname;
29296 }
29297 else
29298 {
29299 // derived type
29300 if (is_function_type(pointed_to_type))
29301 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
29302 qualified, internal);
29303 else if (is_array_type(pointed_to_type))
29304 result = add_outer_pointer_to_array_type_expr(ptr, idname,
29305 qualified, internal);
29306 else if (is_ptr_to_mbr_type(pointed_to_type))
29307 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
29308 qualified, internal);
29309 else
29311 }
29312 return ptr->get_environment().intern(result);
29313}
29314
29315
29316/// Emit the name of a pointer declaration.
29317///
29318/// @param the pointer to consider.
29319///
29320/// @param the name of the variable that has @p as a type. If it's
29321/// empty then the resulting name is going to be the abstract name of
29322/// the type.
29323///
29324/// @param qualified if true then the type name is going to be
29325/// fully qualified.
29326///
29327/// @param internal if true then the type name is going to be used for
29328/// type canonicalization purposes.
29329static interned_string
29330pointer_declaration_name(const type_base_sptr& ptr,
29331 const string& variable_name,
29332 bool qualified, bool internal)
29333{return pointer_declaration_name(ptr.get(), variable_name,
29334 qualified, internal);}
29335
29336/// Emit the name of a array declaration.
29337///
29338/// @param the array to consider.
29339///
29340/// @param the name of the variable that has @p as a type. If it's
29341/// empty then the resulting name is going to be the abstract name of
29342/// the type.
29343///
29344/// @param qualified if true then the type name is going to be
29345/// fully qualified.
29346///
29347/// @param internal if true then the type name is going to be used for
29348/// type canonicalization purposes.
29349static interned_string
29350array_declaration_name(const array_type_def* array,
29351 const string& variable_name,
29352 bool qualified, bool internal)
29353{
29354 if (!array)
29355 return interned_string();
29356
29357 type_base_sptr e_type = array->get_element_type();
29358 string e_type_repr =
29359 (e_type
29360 ? get_type_name(e_type, qualified, internal)
29361 : string("void"));
29362
29363 string result;
29364 if (is_ada_language(array->get_language()))
29365 {
29366 std::ostringstream o;
29367 if (!variable_name.empty())
29368 o << variable_name << " is ";
29369 o << "array ("
29370 << array->get_subrange_representation()
29371 << ") of " << e_type_repr;
29372 result = o.str();
29373 }
29374 else
29375 {
29376 if (is_npaf_type(e_type)
29377 || !(is_pointer_to_function_type(e_type)
29378 || is_pointer_to_array_type(e_type)
29379 || is_pointer_to_ptr_to_mbr_type(e_type)
29380 || is_ptr_to_mbr_type(e_type)))
29381 {
29382 result = e_type_repr;
29383 if (!variable_name.empty())
29384 result += variable_name;
29385 result += array->get_subrange_representation();
29386 }
29387 else if (pointer_type_def_sptr p = is_pointer_type(e_type))
29388 {
29389 string s = variable_name + array->get_subrange_representation();
29390 result = pointer_declaration_name(p, s, qualified, internal);
29391 }
29392 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(e_type))
29393 {
29394 string s = variable_name + array->get_subrange_representation();
29395 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
29396 }
29397 else
29399 }
29400 return array->get_environment().intern(result);
29401}
29402
29403/// Emit the name of a array declaration.
29404///
29405/// @param the array to consider.
29406///
29407/// @param the name of the variable that has @p as a type. If it's
29408/// empty then the resulting name is going to be the abstract name of
29409/// the type.
29410///
29411/// @param qualified if true then the type name is going to be
29412/// fully qualified.
29413///
29414/// @param internal if true then the type name is going to be used for
29415/// type canonicalization purposes.
29416static interned_string
29417array_declaration_name(const array_type_def_sptr& array,
29418 const string& variable_name,
29419 bool qualified, bool internal)
29420{return array_declaration_name(array.get(), variable_name,
29421 qualified, internal);}
29422
29423/// Emit the name of a pointer-to-member declaration.
29424///
29425/// @param ptr the pointer-to-member to consider.
29426///
29427/// @param variable_name the name of the variable that has @p as a
29428/// type. If it's empty then the resulting name is going to be the
29429/// abstract name of the type.
29430///
29431/// @param qualified if true then the type name is going to be
29432/// fully qualified.
29433///
29434/// @param internal if true then the type name is going to be used for
29435/// type canonicalization purposes.
29436static interned_string
29437ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
29438 const string& variable_name,
29439 bool qualified, bool internal)
29440{
29441 if (!ptr)
29442 return interned_string();
29443
29444 string input = variable_name;
29445 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
29446 qualified, internal);
29447 return ptr->get_environment().intern(result);
29448}
29449
29450/// Emit the name of a pointer-to-member declaration.
29451///
29452/// @param ptr the pointer-to-member to consider.
29453///
29454/// @param variable_name the name of the variable that has @p as a
29455/// type. If it's empty then the resulting name is going to be the
29456/// abstract name of the type.
29457///
29458/// @param qualified if true then the type name is going to be
29459/// fully qualified.
29460///
29461/// @param internal if true then the type name is going to be used for
29462/// type canonicalization purposes.
29463static interned_string
29464ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
29465 const string& variable_name,
29466 bool qualified, bool internal)
29467{
29468 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
29469 qualified, internal);
29470}
29471
29472/// Sort types right before hashing and canonicalizing them.
29473///
29474/// @param types the vector of types to sort.
29475void
29476sort_types_for_hash_computing_and_c14n(vector<type_base_sptr>& types)
29477{
29478 sort_types_for_hash_computing_and_c14n(types.begin(), types.end());
29479}
29480
29481bool
29484
29485// <ir_node_visitor stuff>
29486
29487/// The private data structure of the ir_node_visitor type.
29488struct ir_node_visitor::priv
29489{
29490 pointer_set visited_ir_nodes;
29491 bool allow_visiting_already_visited_type_node;
29492
29493 priv()
29494 : allow_visiting_already_visited_type_node(true)
29495 {}
29496}; // end struct ir_node_visitory::priv
29497
29498/// Default Constructor of the ir_node_visitor type.
29500 : priv_(new priv)
29501{}
29502
29503ir_node_visitor::~ir_node_visitor() = default;
29504
29505/// Set if the walker using this visitor is allowed to re-visit a type
29506/// node that was previously visited or not.
29507///
29508/// @param f if true, then the walker using this visitor is allowed to
29509/// re-visit a type node that was previously visited.
29510void
29512{priv_->allow_visiting_already_visited_type_node = f;}
29513
29514/// Get if the walker using this visitor is allowed to re-visit a type
29515/// node that was previously visited or not.
29516///
29517/// @return true iff the walker using this visitor is allowed to
29518/// re-visit a type node that was previously visited.
29519bool
29521{return priv_->allow_visiting_already_visited_type_node;}
29522
29523/// Mark a given type node as having been visited.
29524///
29525/// Note that for this function to work, the type node must have been
29526/// canonicalized. Otherwise the process is aborted.
29527///
29528/// @param p the type to mark as having been visited.
29529void
29531{
29533 return;
29534
29535 if (p == 0 || type_node_has_been_visited(p))
29536 return;
29537
29538 type_base* canonical_type = p->get_naked_canonical_type();
29540 {
29541 ABG_ASSERT(!canonical_type);
29542 canonical_type = p;
29543 }
29544 ABG_ASSERT(canonical_type);
29545
29546 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
29547 priv_->visited_ir_nodes.insert(canonical_ptr_value);
29548}
29549
29550/// Un-mark all visited type nodes.
29551///
29552/// That is, no type node is going to be considered as having been
29553/// visited anymore.
29554///
29555/// In other words, after invoking this funciton,
29556/// ir_node_visitor::type_node_has_been_visited() is going to return
29557/// false on all type nodes.
29558void
29560{priv_->visited_ir_nodes.clear();}
29561
29562/// Test if a given type node has been marked as visited.
29563///
29564/// @param p the type node to consider.
29565///
29566/// @return true iff the type node @p p has been marked as visited by
29567/// the function ir_node_visitor::mark_type_node_as_visited.
29568bool
29570{
29572 return false;
29573
29574 if (p == 0)
29575 return false;
29576
29577 type_base *canonical_type = p->get_naked_canonical_type();
29579 {
29580 ABG_ASSERT(!canonical_type);
29581 canonical_type = p;
29582 }
29583 ABG_ASSERT(canonical_type);
29584
29585 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
29586 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
29587 if (it == priv_->visited_ir_nodes.end())
29588 return false;
29589
29590 return true;
29591}
29592
29593bool
29594ir_node_visitor::visit_begin(decl_base*)
29595{return true;}
29596
29597bool
29598ir_node_visitor::visit_end(decl_base*)
29599{return true;}
29600
29601bool
29602ir_node_visitor::visit_begin(scope_decl*)
29603{return true;}
29604
29605bool
29606ir_node_visitor::visit_end(scope_decl*)
29607{return true;}
29608
29609bool
29610ir_node_visitor::visit_begin(type_base*)
29611{return true;}
29612
29613bool
29614ir_node_visitor::visit_end(type_base*)
29615{return true;}
29616
29617bool
29618ir_node_visitor::visit_begin(scope_type_decl* t)
29619{return visit_begin(static_cast<type_base*>(t));}
29620
29621bool
29622ir_node_visitor::visit_end(scope_type_decl* t)
29623{return visit_end(static_cast<type_base*>(t));}
29624
29625bool
29626ir_node_visitor::visit_begin(type_decl* t)
29627{return visit_begin(static_cast<type_base*>(t));}
29628
29629bool
29630ir_node_visitor::visit_end(type_decl* t)
29631{return visit_end(static_cast<type_base*>(t));}
29632
29633bool
29634ir_node_visitor::visit_begin(namespace_decl* d)
29635{return visit_begin(static_cast<decl_base*>(d));}
29636
29637bool
29638ir_node_visitor::visit_end(namespace_decl* d)
29639{return visit_end(static_cast<decl_base*>(d));}
29640
29641bool
29642ir_node_visitor::visit_begin(qualified_type_def* t)
29643{return visit_begin(static_cast<type_base*>(t));}
29644
29645bool
29646ir_node_visitor::visit_end(qualified_type_def* t)
29647{return visit_end(static_cast<type_base*>(t));}
29648
29649bool
29650ir_node_visitor::visit_begin(pointer_type_def* t)
29651{return visit_begin(static_cast<type_base*>(t));}
29652
29653bool
29654ir_node_visitor::visit_end(pointer_type_def* t)
29655{return visit_end(static_cast<type_base*>(t));}
29656
29657bool
29658ir_node_visitor::visit_begin(reference_type_def* t)
29659{return visit_begin(static_cast<type_base*>(t));}
29660
29661bool
29662ir_node_visitor::visit_end(reference_type_def* t)
29663{return visit_end(static_cast<type_base*>(t));}
29664
29665bool
29666ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
29667{return visit_begin(static_cast<type_base*>(t));}
29668
29669bool
29670ir_node_visitor::visit_end(ptr_to_mbr_type* t)
29671{return visit_end(static_cast<type_base*>(t));}
29672
29673bool
29674ir_node_visitor::visit_begin(array_type_def* t)
29675{return visit_begin(static_cast<type_base*>(t));}
29676
29677bool
29678ir_node_visitor::visit_end(array_type_def* t)
29679{return visit_end(static_cast<type_base*>(t));}
29680
29681bool
29682ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
29683{return visit_begin(static_cast<type_base*>(t));}
29684
29685bool
29686ir_node_visitor::visit_end(array_type_def::subrange_type* t)
29687{return visit_end(static_cast<type_base*>(t));}
29688
29689bool
29690ir_node_visitor::visit_begin(enum_type_decl* t)
29691{return visit_begin(static_cast<type_base*>(t));}
29692
29693bool
29694ir_node_visitor::visit_end(enum_type_decl* t)
29695{return visit_end(static_cast<type_base*>(t));}
29696
29697bool
29698ir_node_visitor::visit_begin(typedef_decl* t)
29699{return visit_begin(static_cast<type_base*>(t));}
29700
29701bool
29702ir_node_visitor::visit_end(typedef_decl* t)
29703{return visit_end(static_cast<type_base*>(t));}
29704
29705bool
29706ir_node_visitor::visit_begin(function_type* t)
29707{return visit_begin(static_cast<type_base*>(t));}
29708
29709bool
29710ir_node_visitor::visit_end(function_type* t)
29711{return visit_end(static_cast<type_base*>(t));}
29712
29713bool
29714ir_node_visitor::visit_begin(var_decl* d)
29715{return visit_begin(static_cast<decl_base*>(d));}
29716
29717bool
29718ir_node_visitor::visit_end(var_decl* d)
29719{return visit_end(static_cast<decl_base*>(d));}
29720
29721bool
29722ir_node_visitor::visit_begin(function_decl* d)
29723{return visit_begin(static_cast<decl_base*>(d));}
29724
29725bool
29726ir_node_visitor::visit_end(function_decl* d)
29727{return visit_end(static_cast<decl_base*>(d));}
29728
29729bool
29730ir_node_visitor::visit_begin(function_decl::parameter* d)
29731{return visit_begin(static_cast<decl_base*>(d));}
29732
29733bool
29734ir_node_visitor::visit_end(function_decl::parameter* d)
29735{return visit_end(static_cast<decl_base*>(d));}
29736
29737bool
29738ir_node_visitor::visit_begin(function_tdecl* d)
29739{return visit_begin(static_cast<decl_base*>(d));}
29740
29741bool
29742ir_node_visitor::visit_end(function_tdecl* d)
29743{return visit_end(static_cast<decl_base*>(d));}
29744
29745bool
29746ir_node_visitor::visit_begin(class_tdecl* d)
29747{return visit_begin(static_cast<decl_base*>(d));}
29748
29749bool
29750ir_node_visitor::visit_end(class_tdecl* d)
29751{return visit_end(static_cast<decl_base*>(d));}
29752
29753bool
29754ir_node_visitor::visit_begin(class_or_union* t)
29755{return visit_begin(static_cast<type_base*>(t));}
29756
29757bool
29758ir_node_visitor::visit_end(class_or_union* t)
29759{return visit_end(static_cast<type_base*>(t));}
29760
29761bool
29762ir_node_visitor::visit_begin(class_decl* t)
29763{return visit_begin(static_cast<type_base*>(t));}
29764
29765bool
29766ir_node_visitor::visit_end(class_decl* t)
29767{return visit_end(static_cast<type_base*>(t));}
29768
29769bool
29770ir_node_visitor::visit_begin(union_decl* t)
29771{return visit_begin(static_cast<type_base*>(t));}
29772
29773bool
29774ir_node_visitor::visit_end(union_decl* t)
29775{return visit_end(static_cast<type_base*>(t));}
29776
29777bool
29778ir_node_visitor::visit_begin(class_decl::base_spec* d)
29779{return visit_begin(static_cast<decl_base*>(d));}
29780
29781bool
29782ir_node_visitor::visit_end(class_decl::base_spec* d)
29783{return visit_end(static_cast<decl_base*>(d));}
29784
29785bool
29786ir_node_visitor::visit_begin(member_function_template* d)
29787{return visit_begin(static_cast<decl_base*>(d));}
29788
29789bool
29790ir_node_visitor::visit_end(member_function_template* d)
29791{return visit_end(static_cast<decl_base*>(d));}
29792
29793bool
29794ir_node_visitor::visit_begin(member_class_template* d)
29795{return visit_begin(static_cast<decl_base*>(d));}
29796
29797bool
29798ir_node_visitor::visit_end(member_class_template* d)
29799{return visit_end(static_cast<decl_base*>(d));}
29800
29801// </ir_node_visitor stuff>
29802
29803// <debugging facilities>
29804
29805/// Generate a different string at each invocation.
29806///
29807/// @return the resulting string.
29808static string
29809get_next_string()
29810{
29811 static __thread size_t counter;
29812 ++counter;
29813 std::ostringstream o;
29814 o << counter;
29815 return o.str();
29816}
29817
29818/// A hashing functor for a @ref function_decl
29819struct function_decl_hash
29820{
29821 size_t operator()(const function_decl* f) const
29822 {return reinterpret_cast<size_t>(f);}
29823
29824 size_t operator()(const function_decl_sptr& f) const
29825 {return operator()(f.get());}
29826};
29827
29828/// Convenience typedef for a hash map of pointer to function_decl and
29829/// string.
29830typedef unordered_map<const function_decl*, string,
29831 function_decl_hash,
29833
29834/// Return a string associated to a given function. Two functions
29835/// that compare equal would yield the same string, as far as this
29836/// routine is concerned. And two functions that are different would
29837/// yield different strings.
29838///
29839/// This is used to debug core diffing issues on functions. The
29840/// sequence of strings can be given to the 'testdiff2' program that
29841/// is in the tests/ directory of the source tree, to reproduce core
29842/// diffing issues on string and thus ease the debugging.
29843///
29844/// @param fn the function to generate a string for.
29845///
29846/// @param m the function_decl* <-> string map to be used by this
29847/// function to generate strings associated to a function.
29848///
29849/// @return the resulting string.
29850static const string&
29851fn_to_str(const function_decl* fn,
29853{
29854 fns_to_str_map_type::const_iterator i = m.find(fn);
29855 if (i != m.end())
29856 return i->second;
29857 string s = get_next_string();
29858 return m[fn]= s;
29859}
29860
29861/// Generate a sequence of string that matches a given sequence of
29862/// function. In the resulting sequence, each function is "uniquely
29863/// representated" by a string. For instance, if the same function "foo"
29864/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
29865/// we don't care about the actual string) would appear at index 1 and 3.
29866///
29867/// @param begin the beginning of the sequence of functions to consider.
29868///
29869/// @param end the end of the sequence of functions. This points to
29870/// one-passed-the-end of the actual sequence.
29871///
29872/// @param m the function_decl* <-> string map to be used by this
29873/// function to generate strings associated to a function.
29874///
29875/// @param o the output stream where to emit the generated list of
29876/// strings to.
29877static void
29878fns_to_str(vector<function_decl*>::const_iterator begin,
29879 vector<function_decl*>::const_iterator end,
29881 std::ostream& o)
29882{
29883 vector<function_decl*>::const_iterator i;
29884 for (i = begin; i != end; ++i)
29885 o << "'" << fn_to_str(*i, m) << "' ";
29886}
29887
29888/// For each sequence of functions given in argument, generate a
29889/// sequence of string that matches a given sequence of function. In
29890/// the resulting sequence, each function is "uniquely representated"
29891/// by a string. For instance, if the same function "foo" appears at
29892/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
29893/// care about the actual string) would appear at index 1 and 3.
29894///
29895/// @param a_begin the beginning of the sequence of functions to consider.
29896///
29897/// @param a_end the end of the sequence of functions. This points to
29898/// one-passed-the-end of the actual sequence.
29899///
29900/// @param b_begin the beginning of the second sequence of functions
29901/// to consider.
29902///
29903/// @param b_end the end of the second sequence of functions.
29904///
29905/// @param m the function_decl* <-> string map to be used by this
29906/// function to generate strings associated to a function.
29907///
29908/// @param o the output stream where to emit the generated list of
29909/// strings to.
29910static void
29911fns_to_str(vector<function_decl*>::const_iterator a_begin,
29912 vector<function_decl*>::const_iterator a_end,
29913 vector<function_decl*>::const_iterator b_begin,
29914 vector<function_decl*>::const_iterator b_end,
29916 std::ostream& o)
29917{
29918 fns_to_str(a_begin, a_end, m, o);
29919 o << "->|<- ";
29920 fns_to_str(b_begin, b_end, m, o);
29921 o << "\n";
29922}
29923
29924/// For each sequence of functions given in argument, generate a
29925/// sequence of string that matches a given sequence of function. In
29926/// the resulting sequence, each function is "uniquely representated"
29927/// by a string. For instance, if the same function "foo" appears at
29928/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
29929/// care about the actual string) would appear at index 1 and 3.
29930///
29931/// @param a_begin the beginning of the sequence of functions to consider.
29932///
29933/// @param a_end the end of the sequence of functions. This points to
29934/// one-passed-the-end of the actual sequence.
29935///
29936/// @param b_begin the beginning of the second sequence of functions
29937/// to consider.
29938///
29939/// @param b_end the end of the second sequence of functions.
29940///
29941/// @param o the output stream where to emit the generated list of
29942/// strings to.
29943void
29944fns_to_str(vector<function_decl*>::const_iterator a_begin,
29945 vector<function_decl*>::const_iterator a_end,
29946 vector<function_decl*>::const_iterator b_begin,
29947 vector<function_decl*>::const_iterator b_end,
29948 std::ostream& o)
29949{
29951 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
29952}
29953
29954// </debugging facilities>
29955
29956// </class template>
29957
29958}// end namespace ir
29959}//end namespace abigail
29960
29961namespace
29962{
29963
29964/// Update the qualified parent name, qualified name and scoped name
29965/// of a tree decl node.
29966///
29967/// @return true if the tree walking should continue, false otherwise.
29968///
29969/// @param d the tree node to take in account.
29970bool
29971qualified_name_setter::do_update(abigail::ir::decl_base* d)
29972{
29973 std::string parent_qualified_name;
29974 abigail::ir::scope_decl* parent = d->get_scope();
29975 if (parent)
29976 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
29977 else
29978 d->priv_->qualified_parent_name_ = abigail::interned_string();
29979
29980 const abigail::ir::environment& env = d->get_environment();
29981
29982 if (!d->priv_->qualified_parent_name_.empty())
29983 {
29984 if (d->get_name().empty())
29985 d->priv_->qualified_name_ = abigail::interned_string();
29986 else
29987 {
29988 d->priv_->qualified_name_ =
29989 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
29990 d->priv_->internal_qualified_name_ = env.intern(d->get_name());
29991 }
29992 }
29993 // Make sure the internal qualified name (used for type
29994 // canonicalization puroses) is always the qualified name. For
29995 // integral/real types however, only the non qualified type is used.
29996 if (!is_integral_type(d))
29997 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
29998
29999 if (d->priv_->scoped_name_.empty())
30000 {
30001 if (parent
30002 && !parent->get_is_anonymous()
30003 && !parent->get_name().empty())
30004 d->priv_->scoped_name_ =
30005 env.intern(parent->get_name() + "::" + d->get_name());
30006 else
30007 d->priv_->scoped_name_ =
30008 env.intern(d->get_name());
30009 }
30010
30011 if (!is_scope_decl(d))
30012 return false;
30013
30014 return true;
30015}
30016
30017/// This is called when we start visiting a decl node, during the
30018/// udpate of the qualified name of a given sub-tree.
30019///
30020/// @param d the decl node we are visiting.
30021///
30022/// @return true iff the traversal should keep going.
30023bool
30024qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
30025{return do_update(d);}
30026
30027/// This is called when we start visiting a type node, during the
30028/// udpate of the qualified name of a given sub-tree.
30029///
30030/// @param d the decl node we are visiting.
30031///
30032/// @return true iff the traversal should keep going.
30033bool
30034qualified_name_setter::visit_begin(abigail::ir::type_base* t)
30035{
30037 return do_update(d);
30038 return false;
30039}
30040}// 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:1718
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.
void clear()
Clear the string.
This class is to hold the value of the bound of a subrange. The value can be either signed or unsigne...
Definition abg-ir.h:2560
void set_signed(int64_t v)
Setter of the bound value as signed.
Definition abg-ir.cc:18870
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition abg-ir.cc:18838
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition abg-ir.cc:18831
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition abg-ir.cc:18845
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition abg-ir.cc:18882
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition abg-ir.cc:18853
bound_value()
Default constructor of the array_type_def::subrange_type::bound_value class.
Definition abg-ir.cc:18803
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition abg-ir.cc:18860
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++.
Definition abg-ir.h:2545
void set_lower_bound(int64_t lb)
Setter of the lower bound.
Definition abg-ir.cc:19061
bool is_non_finite() const
Test if the length of the subrange type is infinite.
Definition abg-ir.cc:19088
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition abg-ir.cc:19054
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:19028
string as_string() const
Return a string representation of the sub range.
Definition abg-ir.cc:19110
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:19009
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:19310
bool operator!=(const decl_base &o) const
Equality operator.
Definition abg-ir.cc:19249
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition abg-ir.cc:19040
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:19020
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:19205
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition abg-ir.cc:19047
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:19288
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition abg-ir.cc:19133
uint64_t get_length() const
Getter of the length of the subrange type.
Definition abg-ir.cc:19071
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition abg-ir.cc:19103
The abstraction of an array type.
Definition abg-ir.h:2519
virtual bool is_non_finite() const
Definition abg-ir.cc:19661
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:19691
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
Definition abg-ir.h:2540
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:19417
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition abg-ir.cc:19622
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition abg-ir.cc:19637
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:19754
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition abg-ir.h:2537
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition abg-ir.cc:19781
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:19600
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:19470
translation_unit::language get_language() const
Get the language of the array.
Definition abg-ir.cc:19589
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition abg-ir.cc:19647
Abstraction of a base specifier in a class declaration.
Definition abg-ir.h:4314
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
Definition abg-ir.cc:24875
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition abg-ir.cc:24882
long get_offset_in_bits() const
Getter of the offset of the base.
Definition abg-ir.cc:24889
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:24864
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:24905
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Definition abg-ir.cc:24999
Abstracts a class declaration.
Definition abg-ir.h:4127
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition abg-ir.h:4145
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition abg-ir.cc:25616
void is_struct(bool f)
Set the "is-struct" flag of the class.
Definition abg-ir.cc:24672
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition abg-ir.cc:25455
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:24741
bool is_struct() const
Test if the class is a struct.
Definition abg-ir.cc:24679
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:25518
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition abg-ir.cc:24696
virtual ~class_decl()
Destructor of the class_decl type.
Definition abg-ir.cc:26032
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:24657
bool has_vtable() const
Test if the current instance has a vtable.
Definition abg-ir.cc:25483
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition abg-ir.cc:25497
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition abg-ir.cc:25464
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition abg-ir.h:4146
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:25948
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
Definition abg-ir.cc:24686
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition abg-ir.cc:24722
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition abg-ir.cc:24746
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition abg-ir.cc:25796
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:24706
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition abg-ir.cc:25446
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:24767
The base type of class_decl and union_decl.
Definition abg-ir.h:3929
virtual size_t get_num_anonymous_member_classes() const
Get the number of anonymous member classes contained in this class.
Definition abg-ir.cc:23614
unordered_map< ssize_t, member_functions > virtual_mem_fn_map_type
Convenience typedef.
Definition abg-ir.h:3961
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:23855
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:23780
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition abg-ir.cc:23883
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
Definition abg-ir.cc:23500
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition abg-ir.cc:23959
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition abg-ir.cc:23599
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition abg-ir.cc:23632
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
Definition abg-ir.cc:23973
vector< type_base_sptr > member_types
Convenience typedef.
Definition abg-ir.h:3958
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition abg-ir.h:3960
const data_members & get_data_members() const
Get the data members of this class_or_union.
Definition abg-ir.cc:23739
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:23390
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:23681
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:23934
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:23918
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition abg-ir.cc:23583
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
Definition abg-ir.cc:24015
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:23488
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:23406
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition abg-ir.cc:23987
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
Definition abg-ir.cc:23830
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:23892
const data_members & get_static_data_members() const
Get the static data memebers of this class_or_union.
Definition abg-ir.cc:23838
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:23525
virtual ~class_or_union()
Destrcutor of the class_or_union type.
Definition abg-ir.cc:23479
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:24049
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition abg-ir.cc:26335
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition abg-ir.cc:23551
vector< var_decl_sptr > data_members
Convenience typedef.
Definition abg-ir.h:3959
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition abg-ir.cc:23966
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition abg-ir.cc:23567
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
Definition abg-ir.cc:23650
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:23750
Abstract a class template.
Definition abg-ir.h:3749
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition abg-ir.cc:27727
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
Definition abg-ir.cc:27716
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:27776
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:27731
The abstraction of the relationship between an entity and its containing scope (its context)....
Definition abg-ir.h:1256
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition abg-corpus.h:25
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
origin get_origin() const
Getter for the origin of the corpus.
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
type_maps & get_type_per_loc_map()
Get the maps that associate a location string to a certain kind of type.
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr<exported_decls_builder>.
Definition abg-corpus.h:45
const environment & get_environment() const
Getter of the enviroment of the corpus.
The base type of all declarations.
Definition abg-ir.h:1556
void set_definition_of_declaration(const decl_base_sptr &)
Set the definition of this declaration-only decl_base.
Definition abg-ir.cc:15948
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:4860
virtual bool operator!=(const decl_base &) const
Inequality operator.
Definition abg-ir.cc:5075
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current decl.
Definition abg-ir.cc:4749
scope_decl * get_scope() const
Return the type containing the current decl, if any.
Definition abg-ir.cc:4647
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
Definition abg-ir.cc:4378
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:4440
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:5430
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
Definition abg-ir.cc:4808
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
Definition abg-ir.cc:4622
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:4844
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition abg-ir.cc:4678
void clear_qualified_name()
Clear the qualified name of this decl.
Definition abg-ir.cc:4371
virtual void set_name(const string &n)
Setter for the name of the decl.
Definition abg-ir.cc:4510
const location & get_location() const
Get the location of a given declaration.
Definition abg-ir.cc:4460
binding
ELF binding.
Definition abg-ir.h:1607
typedef_decl_sptr get_naming_typedef() const
Getter for the naming typedef of the current decl.
Definition abg-ir.cc:4570
virtual const interned_string & get_name() const
Getter for the name of the current decl.
Definition abg-ir.cc:4666
virtual void set_scope(scope_decl *)
Setter of the scope of the current decl.
Definition abg-ir.cc:5102
const interned_string & peek_qualified_name() const
Getter for the qualified name.
Definition abg-ir.cc:4362
const context_rel * get_context_rel() const
Getter for the context relationship.
Definition abg-ir.cc:4412
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Definition abg-ir.cc:4523
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:8305
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
Definition abg-ir.cc:4800
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:4828
friend void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition abg-ir.cc:5399
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
Definition abg-ir.cc:4588
void set_location(const location &l)
Set the location for a given declaration.
Definition abg-ir.cc:4498
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
Definition abg-ir.cc:4533
void set_visibility(visibility v)
Setter for the visibility of the decl.
Definition abg-ir.cc:4639
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
Definition abg-ir.cc:4405
friend bool equals(const decl_base &, const decl_base &, change_kind *)
Compares two instances of decl_base.
Definition abg-ir.cc:4993
visibility get_visibility() const
Getter for the visibility of the decl.
Definition abg-ir.cc:4632
visibility
ELF visibility.
Definition abg-ir.h:1597
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Definition abg-ir.cc:4851
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:5091
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition abg-ir.cc:4816
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition abg-ir.cc:4615
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition abg-ir.cc:5370
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition abg-ir.cc:6496
virtual ~decl_base()
Destructor of the decl_base type.
Definition abg-ir.cc:5079
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:5064
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:4659
bool get_is_anonymous_or_has_anonymous_parent() const
Definition abg-ir.cc:4556
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
Definition abg-ir.cc:4545
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:4432
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
Definition abg-ir.cc:4391
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:4701
The abstraction for a data member context relationship. This relates a data member to its parent clas...
Definition abg-ir.h:2966
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:3199
void set_anonymous_data_member(var_decl *)
Set the containing anonymous data member of this data member context relationship....
Definition abg-ir.cc:3209
The abstraction of the version of an ELF symbol.
Definition abg-ir.h:1203
version & operator=(const version &o)
Assign a version to the current one.
Definition abg-ir.cc:3112
bool operator==(const version &o) const
Compares the current version against another one.
Definition abg-ir.cc:3094
bool is_default() const
Getter for the 'is_default' property of the version.
Definition abg-ir.cc:3074
const string & str() const
Getter for the version name.
Definition abg-ir.cc:3060
bool operator!=(const version &o) const
Inequality operator.
Definition abg-ir.cc:3103
Abstraction of an elf symbol.
Definition abg-ir.h:932
const abg_compat::optional< std::string > & get_namespace() const
Getter of the 'namespace' property.
Definition abg-ir.cc:2197
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:2520
elf_symbol_sptr get_next_common_instance() const
Get the next common instance of the current common symbol.
Definition abg-ir.cc:2415
type get_type() const
Getter for the type of the current instance of elf_symbol.
Definition abg-ir.cc:2031
const elf_symbol_sptr get_main_symbol() const
Get the main symbol of an alias chain.
Definition abg-ir.cc:2252
void set_is_in_ksymtab(bool is_in_ksymtab)
Setter of the 'is-in-ksymtab' property.
Definition abg-ir.cc:2176
bool has_aliases() const
Check if the current elf_symbol has an alias.
Definition abg-ir.cc:2281
void set_name(const string &n)
Setter for the name of the current intance of elf_symbol.
Definition abg-ir.cc:2021
bool is_suppressed() const
Getter for the 'is-suppressed' property.
Definition abg-ir.cc:2213
binding
The binding of a symbol.
Definition abg-ir.h:949
int get_number_of_aliases() const
Get the number of aliases to this elf symbol.
Definition abg-ir.cc:2288
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:2541
void set_binding(binding b)
Setter for the binding of the current instance of elf_symbol.
Definition abg-ir.cc:2066
void add_common_instance(const elf_symbol_sptr &)
Add a common instance to the current common elf symbol.
Definition abg-ir.cc:2426
void add_alias(const elf_symbol_sptr &)
Add an alias to the current elf symbol.
Definition abg-ir.cc:2305
void set_is_suppressed(bool is_suppressed)
Setter for the 'is-suppressed' property.
Definition abg-ir.cc:2222
bool is_variable() const
Test if the current instance of elf_symbol is a variable symbol or not.
Definition abg-ir.cc:2154
elf_symbol_sptr update_main_symbol(const std::string &)
Update the main symbol for a group of aliased symbols.
Definition abg-ir.cc:2351
void set_size(size_t)
Setter of the size of the symbol.
Definition abg-ir.cc:2052
const string & get_name() const
Getter for the name of the elf_symbol.
Definition abg-ir.cc:2014
binding get_binding() const
Getter for the binding of the current instance of elf_symbol.
Definition abg-ir.cc:2059
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:2607
bool is_function() const
Test if the current instance of elf_symbol is a function symbol or not.
Definition abg-ir.cc:2145
type
The type of a symbol.
Definition abg-ir.h:936
void set_version(const version &v)
Setter for the version of the current instance of elf_symbol.
Definition abg-ir.cc:2080
const abg_compat::optional< uint32_t > & get_crc() const
Getter of the 'crc' property.
Definition abg-ir.cc:2183
void set_visibility(visibility v)
Setter of the visibility of the current instance of elf_symbol.
Definition abg-ir.cc:2091
bool does_alias(const elf_symbol &) const
Test if the current symbol aliases another one.
Definition abg-ir.cc:2666
bool is_main_symbol() const
Tests whether this symbol is the main symbol.
Definition abg-ir.cc:2266
void set_crc(const abg_compat::optional< uint32_t > &crc)
Setter of the 'crc' property.
Definition abg-ir.cc:2190
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:1937
visibility
The visibility of the symbol.
Definition abg-ir.h:958
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition abg-ir.cc:2073
bool is_common_symbol() const
Return true if the symbol is a common one.
Definition abg-ir.cc:2384
void set_index(size_t)
Setter for the index.
Definition abg-ir.cc:2007
visibility get_visibility() const
Getter of the visibility of the current instance of elf_symbol.
Definition abg-ir.cc:2099
bool has_other_common_instances() const
Return true if this common common symbol has other common instances.
Definition abg-ir.cc:2400
size_t get_index() const
Getter for the index.
Definition abg-ir.cc:2000
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
Definition abg-ir.cc:2471
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:2498
const environment & get_environment() const
Getter of the environment used by the current instance of elf_symbol.
Definition abg-ir.cc:1993
void set_type(type t)
Setter for the type of the current instance of elf_symbol.
Definition abg-ir.cc:2038
bool is_public() const
Test if the current instance of elf_symbol is public or not.
Definition abg-ir.cc:2129
bool is_in_ksymtab() const
Getter of the 'is-in-ksymtab' property.
Definition abg-ir.cc:2168
size_t get_size() const
Getter of the size of the symbol.
Definition abg-ir.cc:2045
bool is_defined() const
Test if the current instance of elf_symbol is defined or not.
Definition abg-ir.cc:2107
void set_namespace(const abg_compat::optional< std::string > &ns)
Setter of the 'namespace' property.
Definition abg-ir.cc:2204
elf_symbol_sptr get_next_alias() const
Get the next alias of the current symbol.
Definition abg-ir.cc:2273
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:2652
The abstraction of an enumerator.
Definition abg-ir.h:2844
enumerator()
Default constructor of the enum_type_decl::enumerator type.
Definition abg-ir.cc:20416
bool operator!=(const enumerator &other) const
Inequality operator.
Definition abg-ir.cc:20476
void set_name(const string &n)
Setter for the name of enum_type_decl::enumerator.
Definition abg-ir.cc:20518
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition abg-ir.cc:20540
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition abg-ir.cc:20485
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition abg-ir.cc:20547
void set_value(int64_t v)
Setter for the value of enum_type_decl::enumerator.
Definition abg-ir.cc:20533
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:20502
int64_t get_value() const
Getter for the value of enum_type_decl::enumerator.
Definition abg-ir.cc:20526
bool operator==(const enumerator &other) const
Equality operator.
Definition abg-ir.cc:20463
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::enumerator type.
Definition abg-ir.cc:20447
Abstracts a declaration for an enum type.
Definition abg-ir.h:2756
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition abg-ir.h:2772
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:19854
virtual ~enum_type_decl()
Destructor for the enum type declaration.
Definition abg-ir.cc:19967
const enumerators & get_enumerators() const
Definition abg-ir.cc:19867
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
Definition abg-ir.cc:19879
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:19945
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition abg-ir.cc:19862
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:20337
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:19920
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:3446
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:3513
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:3593
const vector< type_base_sptr > * get_canonical_types(const char *name) const
Get the vector of canonical types which have a given "stringrepresentation".
Definition abg-ir.cc:3730
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:3323
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:3545
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
Definition abg-ir.cc:3374
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:3342
const config & get_config() const
Getter of the general configuration object.
Definition abg-ir.cc:3583
environment()
Default constructor of the environment type.
Definition abg-ir.cc:3224
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition abg-ir.cc:3386
type_base * get_canonical_type(const char *name, unsigned index)
Get a given canonical type which has a given "stringrepresentation".
Definition abg-ir.cc:3753
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:3361
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:3482
virtual ~environment()
Destructor for the environment type.
Definition abg-ir.cc:3229
bool canonicalization_started() const
Getter of a flag saying if the canonicalization process has started or not.
Definition abg-ir.cc:3413
interned_string intern(const string &) const
Do intern a string.
Definition abg-ir.cc:3576
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 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:3619
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Definition abg-ir.cc:3237
Abstraction of a function parameter.
Definition abg-ir.h:3287
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
Definition abg-ir.cc:23224
interned_string get_type_name() const
Definition abg-ir.cc:23023
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition abg-ir.cc:23061
const string get_type_pretty_representation() const
Definition abg-ir.cc:23042
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition abg-ir.cc:23200
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:23244
Abstraction for a function declaration.
Definition abg-ir.h:3117
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition abg-ir.h:3139
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:22424
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition abg-ir.cc:22495
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition abg-ir.h:3142
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:22885
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition abg-ir.cc:22575
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition abg-ir.cc:22800
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition abg-ir.cc:22461
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition abg-ir.cc:22480
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:22287
const type_base_sptr get_return_type() const
Definition abg-ir.cc:22556
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition abg-ir.cc:22588
const std::vector< parameter_sptr > & get_parameters() const
Definition abg-ir.cc:22561
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition abg-ir.cc:22568
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition abg-ir.cc:22517
virtual ~function_decl()
Destructor of the function_decl type.
Definition abg-ir.cc:22901
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:22533
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition abg-ir.cc:22786
bool is_declared_inline() const
Test if the function was declared inline.
Definition abg-ir.cc:22540
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:22356
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:22816
Abstract a function template declaration.
Definition abg-ir.h:3704
binding get_binding() const
Get the binding of the function template.
Definition abg-ir.cc:27564
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
Definition abg-ir.cc:27546
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition abg-ir.cc:27557
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:27624
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition abg-ir.cc:27573
Abstraction of a function type.
Definition abg-ir.h:3372
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition abg-ir.h:3384
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:21529
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:21948
shared_ptr< function_decl::parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition abg-ir.h:3382
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition abg-ir.cc:21636
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition abg-ir.cc:21845
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:21436
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition abg-ir.cc:21907
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:21621
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition abg-ir.cc:21598
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition abg-ir.cc:21865
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:21577
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition abg-ir.cc:21540
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition abg-ir.cc:21548
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition abg-ir.cc:21823
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition abg-ir.cc:21557
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:21931
This abstracts the global scope of a given translation unit.
Definition abg-ir.h:1953
The base class for the visitor type hierarchy used for traversing a translation unit.
Definition abg-ir.h:4761
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:29520
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition abg-ir.cc:29569
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition abg-ir.cc:29559
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition abg-ir.cc:29499
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition abg-ir.cc:29530
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:4447
bool is_constructor() const
Getter for the 'is-constructor' property.
Definition abg-ir.h:4525
bool is_const() const
Getter for the 'is-const' property.
Definition abg-ir.h:4560
size_t vtable_offset() const
Getter for the vtable offset property.
Definition abg-ir.h:4505
bool is_destructor() const
Getter for the 'is-destructor' property.
Definition abg-ir.h:4542
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition abg-ir.h:3791
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition abg-ir.h:3811
bool get_is_static() const
Definition abg-ir.h:3823
Abstracts a member class template template.
Definition abg-ir.h:4652
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
Definition abg-ir.cc:26195
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26280
Abstract a member function template.
Definition abg-ir.h:4597
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26174
Abstraction of the declaration of a method.
Definition abg-ir.h:3839
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
Definition abg-ir.cc:25146
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
Definition abg-ir.cc:6393
const method_type_sptr get_type() const
Definition abg-ir.cc:25173
Abstracts the type of a class member function.
Definition abg-ir.h:3458
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:22149
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:22130
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition abg-ir.cc:22181
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
Definition abg-ir.cc:22196
virtual ~method_type()
The destructor of method_type.
Definition abg-ir.cc:22229
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:22173
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition abg-ir.cc:22140
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition abg-ir.cc:22188
The abstraction of a namespace declaration.
Definition abg-ir.h:2178
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:17069
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17100
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition abg-ir.cc:17003
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition abg-ir.cc:17055
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:17041
Abstracts non type template parameters.
Definition abg-ir.h:3614
const type_base_sptr get_type() const
Getter for the type of the template parameter.
Definition abg-ir.cc:27262
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:27267
The abstraction of a pointer type.
Definition abg-ir.h:2321
void set_pointed_to_type(const type_base_sptr &)
Set the pointed-to type of the pointer.
Definition abg-ir.cc:17762
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:17888
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:17752
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:17679
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17982
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition abg-ir.cc:17824
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition abg-ir.cc:17868
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition abg-ir.cc:17875
The abstraction of a pointer-to-member type.
Definition abg-ir.h:2456
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:18652
virtual const interned_string & get_name() const
Getter of the name of the current ptr-to-mbr-type.
Definition abg-ir.cc:18562
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18575
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:18595
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
Definition abg-ir.cc:18636
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:18703
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
Definition abg-ir.cc:18586
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
Definition abg-ir.cc:18728
The abstraction of a qualified type.
Definition abg-ir.h:2207
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:17405
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition abg-ir.cc:17530
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition abg-ir.cc:17269
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:17257
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:17518
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition abg-ir.h:2226
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:17195
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition abg-ir.cc:17509
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17478
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition abg-ir.cc:17504
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition abg-ir.cc:17523
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition abg-ir.cc:17349
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition abg-ir.cc:17172
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:16445
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
Definition abg-ir.cc:16468
base_type get_base_type() const
Getter of the base type of the real_type.
Definition abg-ir.cc:16431
bool operator==(const real_type &) const
Equality operator for the real_type.
Definition abg-ir.cc:16455
real_type()
Default constructor of the real_type.
Definition abg-ir.cc:16401
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:16438
Abstracts a reference type.
Definition abg-ir.h:2387
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:18311
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18174
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:18076
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:18433
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:18184
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition abg-ir.cc:18253
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:18412
A declaration that introduces a scope.
Definition abg-ir.h:1824
virtual size_t get_num_anonymous_member_classes() const
Getter for the number of anonymous classes contained in this scope.
Definition abg-ir.cc:7776
void remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
Definition abg-ir.cc:7985
void insert_member_type(type_base_sptr t, declarations::iterator before)
Insert a member type.
Definition abg-ir.cc:7943
std::vector< scope_decl_sptr > scopes
Convenience typedef for a vector of scope_decl_sptr.
Definition abg-ir.h:1835
void add_member_type(type_base_sptr t)
Add a member type to the current instance of class_or_union.
Definition abg-ir.cc:7960
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
Definition abg-ir.cc:7794
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
Definition abg-ir.cc:7829
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
Definition abg-ir.h:1831
bool is_empty() const
Test if the current scope is empty.
Definition abg-ir.cc:7843
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:8275
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
Definition abg-ir.cc:7918
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:8053
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:7712
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:8227
virtual void remove_member_decl(decl_base_sptr member)
Remove a declaration from the current scope.
Definition abg-ir.cc:8078
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:7889
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:7929
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition abg-ir.cc:7736
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:7700
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
Definition abg-ir.cc:8004
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:8305
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:8181
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
Definition abg-ir.cc:7754
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
Definition abg-ir.cc:7812
A type that introduces a scope.
Definition abg-ir.h:2155
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:16962
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition abg-ir.cc:16924
The base class of templates.
Definition abg-ir.h:3519
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:26937
virtual ~template_decl()
Destructor.
Definition abg-ir.cc:26962
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:26929
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition abg-ir.cc:26971
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition abg-ir.h:3551
virtual ~template_parameter()
Destructor.
Definition abg-ir.cc:27091
bool operator!=(const template_parameter &) const
Inequality operator.
Definition abg-ir.cc:27087
Abstracts a template template parameter.
Definition abg-ir.h:3647
virtual bool operator==(const type_base &) const
Equality operator.
Definition abg-ir.cc:27340
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
Definition abg-ir.h:695
void set_address_size(char)
Setter of the address size in this translation unit.
Definition abg-ir.cc:1426
const std::string & get_absolute_path() const
Get the concatenation of the build directory and the relative path of the translation unit.
Definition abg-ir.cc:1341
void set_is_constructed(bool)
Setter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
Definition abg-ir.cc:1458
bool operator==(const translation_unit &) const
Compare the current translation unit against another one.
Definition abg-ir.cc:1468
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
Definition abg-ir.cc:1384
char get_address_size() const
Getter of the address size in this translation unit.
Definition abg-ir.cc:1419
const std::string & get_compilation_dir_path() const
Get the path of the directory that was 'current' when the translation unit was compiled.
Definition abg-ir.cc:1322
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
Definition abg-ir.cc:1368
void set_language(language l)
Setter of the language of the source code of the translation unit.
Definition abg-ir.cc:1285
void bind_function_type_life_time(function_type_sptr) const
Ensure that the life time of a function type is bound to the life time of the current translation uni...
Definition abg-ir.cc:1494
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
Definition abg-ir.cc:1221
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
Definition abg-ir.cc:1408
bool is_constructed() const
Getter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
Definition abg-ir.cc:1442
const std::string & get_path() const
Get the path of the current translation unit.
Definition abg-ir.cc:1298
void set_compilation_dir_path(const std::string &)
Set the path of the directory that was 'current' when the translation unit was compiled.
Definition abg-ir.cc:1333
location_manager & get_loc_mgr()
Getter of the location manager for the current translation unit.
Definition abg-ir.cc:1392
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
Definition abg-ir.cc:1309
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse virtual function.
Definition abg-ir.cc:1528
language
The language of the translation unit.
Definition abg-ir.h:708
bool operator!=(const translation_unit &) const
Inequality operator.
Definition abg-ir.cc:1483
const vector< function_type_sptr > & get_live_fn_types() const
Get the vector of function types that are used in the current translation unit.
Definition abg-ir.cc:1264
const environment & get_environment() const
Getter of the environment of the current translation_unit.
Definition abg-ir.cc:1271
const type_maps & get_types() const
Getter of the types of the current translation_unit.
Definition abg-ir.cc:1248
language get_language() const
Getter of the language of the source code of the translation unit.
Definition abg-ir.cc:1278
bool visiting() const
This should returns false before and after the node has been visiting. During the visiting of the nod...
An abstraction helper for type declarations.
Definition abg-ir.h:1974
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
Definition abg-ir.cc:16031
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition abg-ir.cc:16007
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition abg-ir.cc:16110
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:15977
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:16136
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:15710
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition abg-ir.cc:16103
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition abg-ir.cc:16096
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition abg-ir.cc:16086
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition abg-ir.cc:16124
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition abg-ir.cc:16117
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition abg-ir.cc:15991
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition abg-ir.h:3682
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition abg-ir.cc:27446
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition abg-ir.cc:27453
A basic type declaration that introduces no scope.
Definition abg-ir.h:2089
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:16756
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:16596
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:16835
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition abg-ir.cc:16694
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition abg-ir.cc:16650
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:16815
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:1377
void set_translation_unit(translation_unit *)
Set the translation_unit this ABI artifact belongs to.
Definition abg-ir.cc:4133
friend hash_t peek_hash_value(const type_or_decl_base &)
Get the hash value associated to an IR node.
Definition abg-ir.cc:28049
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
Definition abg-ir.cc:3946
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
Definition abg-ir.cc:3935
location & get_artificial_location() const
Getter of the artificial location of the artifact.
Definition abg-ir.cc:4093
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
Definition abg-ir.cc:4100
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Definition abg-ir.cc:4125
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.
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition abg-ir.cc:10800
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:4046
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
Definition abg-ir.cc:3969
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition abg-ir.cc:3958
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
Definition abg-ir.cc:4158
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
Definition abg-ir.cc:3989
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:4024
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10405
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
Definition abg-ir.cc:4075
type_or_decl_kind
This is a bitmap type which instance is meant to contain the runtime type of a given ABI artifact....
Definition abg-ir.h:1389
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition abg-ir.cc:4057
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
Definition abg-ir.cc:10478
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Definition abg-ir.cc:4150
Abstracts a type template parameter.
Definition abg-ir.h:3580
virtual bool operator==(const type_base &) const
Equality operator.
Definition abg-ir.cc:27133
The abstraction of a typedef declaration.
Definition abg-ir.h:2898
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:20802
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition abg-ir.cc:20787
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition abg-ir.cc:20642
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:20629
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:20834
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition abg-ir.cc:20780
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:20722
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition abg-ir.cc:20659
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:20763
Abstracts a union type declaration.
Definition abg-ir.h:4372
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:26614
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26731
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition abg-ir.cc:26671
virtual ~union_decl()
Destructor of the union_decl type.
Definition abg-ir.cc:26804
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:26638
Abstracts a variable declaration.
Definition abg-ir.h:3020
binding get_binding() const
Getter of the binding of the variable.
Definition abg-ir.cc:20948
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition abg-ir.cc:20930
void set_binding(binding b)
Setter of the binding of the variable.
Definition abg-ir.cc:20955
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
Definition abg-ir.cc:6054
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
Definition abg-ir.cc:20993
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:21246
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition abg-ir.cc:20941
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition abg-ir.cc:6199
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition abg-ir.cc:20923
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:21408
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:21385
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition abg-ir.cc:20970
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:20986
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition abg-ir.cc:21181
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:21276
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:21200
A type used to time various part of the libabigail system.
bool stop()
Stop the timer.
bool start()
Start the timer.
bool is_decl_only_class_with_size_change(const class_or_union &first, const class_or_union &second)
Test if two classes that are decl-only (have the decl-only flag and carry no data members) but are di...
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
ostream & operator<<(ostream &o, diff_category c)
Serialize an instance of diff_category to an output stream.
hash_t combine_hashes(hash_t val1, hash_t val2)
Combine two hash values to produce a third hash value.
Definition abg-hash.cc:172
@ HASHING_FINISHED_STATE
Hashing of given IR node started and is now done. If an ABI artifact is in this state,...
Definition abg-hash.h:61
real_type::modifiers_type operator~(real_type::modifiers_type l)
Bitwise one's complement operator for real_type::modifiers_type.
Definition abg-ir.cc:16193
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 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:19979
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:12584
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition abg-ir.cc:28076
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Definition abg-ir.cc:6309
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
Definition abg-ir.cc:7119
hash_t peek_hash_value(const type_or_decl_base &artefact)
Get the hash value associated to an IR node.
Definition abg-ir.cc:28049
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
Definition abg-ir.cc:12071
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:28027
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:11935
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:5636
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:6009
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:11722
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:5430
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:11180
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:9991
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:888
size_t get_canonical_type_index(const type_base &t)
Getter of the canonical type index of a given type.
Definition abg-ir.cc:345
const type_base_wptrs_type * lookup_enum_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the enum type*s* that have a given qualified name.
Definition abg-ir.cc:13652
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition abg-ir.cc:22867
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:11162
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:15451
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:14324
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:13814
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition abg-ir.cc:6433
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
Definition abg-fwd.h:142
scope_decl * get_type_scope(type_base *t)
Get the scope of a given type.
Definition abg-ir.cc:8655
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:25402
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 variables are equals modulo CV qualifiers.
Definition abg-ir.cc:19550
const scope_decl * is_scope_decl(const decl_base *d)
Test if a declaration is a scope_decl.
Definition abg-ir.cc:5300
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
Definition abg-ir.cc:7470
const type_base * is_void_pointer_type(const type_base *t)
Test if a type is a pointer to void type.
Definition abg-ir.cc:11413
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition abg-ir.cc:10465
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition abg-ir.cc:5727
bool is_template_parameter(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter.
Definition abg-ir.cc:10339
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
Definition abg-ir.cc:1540
weak_ptr< type_base > type_base_wptr
Convenience typedef for a weak pointer on a type_base.
Definition abg-fwd.h:128
type_base_sptr peel_reference_type(const type_base_sptr &type)
Return the leaf pointed-to type node of a reference_type_def node.
Definition abg-ir.cc:7028
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:26089
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
Definition abg-ir.cc:5254
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:11841
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:897
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:13211
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
Definition abg-ir.cc:28147
class_decl_sptr is_compatible_with_class_type(const type_base_sptr &t)
Test if a type is a class. This function looks through typedefs.
Definition abg-ir.cc:10759
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:16386
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
Definition abg-ir.cc:8330
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:10056
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
Definition abg-ir.cc:7403
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
Definition abg-ir.h:1332
@ LOCAL_TYPE_CHANGE_KIND
This means that a given IR artifact has a local type change.
Definition abg-ir.h:1336
@ SUBTYPE_CHANGE_KIND
This means that a given IR artifact has changes in some of its sub-types, with respect to the other a...
Definition abg-ir.h:1352
@ LOCAL_NON_TYPE_CHANGE_KIND
This means that a given IR artifact has a local non-type change. That is a change that is carried by ...
Definition abg-ir.h:1341
var_decl_sptr find_last_data_member_matching_regexp(const class_or_union &t, const regex::regex_t_sptr &regex)
Find the last data member of a class or union which name matches a regular expression.
Definition abg-ir.cc:28628
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:11337
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:5573
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:12946
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:9533
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
Definition abg-ir.cc:5334
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:1723
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:11961
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:10041
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:5670
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition abg-ir.cc:10791
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:14897
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:6570
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition abg-fwd.h:244
function_type_sptr lookup_or_synthesize_fn_type(const function_type_sptr &fn_t, const corpus &corpus)
Look into an ABI corpus for a function type.
Definition abg-ir.cc:13236
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:10975
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:9135
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
Definition abg-ir.cc:10516
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:13839
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:7188
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:5913
type_decl * is_integral_type(const type_or_decl_base *t)
Test if a type is an integral type.
Definition abg-ir.cc:10625
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:5969
class_decl_sptr lookup_class_type_per_location(const interned_string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
Definition abg-ir.cc:13515
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition abg-ir.cc:6337
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
Definition abg-ir.cc:7077
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
Definition abg-ir.cc:12402
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:28291
corpus_group_sptr is_corpus_group(const corpus_sptr &corpus)
Test if a corpus is a corpus_group.
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
Definition abg-fwd.h:314
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
Definition abg-ir.cc:11022
var_decl_sptr get_data_member(class_or_union *clazz, const char *member_name)
Get a given data member, referred to by its name, of a class type.
Definition abg-ir.cc:9873
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:11653
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:5597
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:7264
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:6393
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:6770
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:2919
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
Definition abg-ir.cc:11704
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:10567
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10445
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:11593
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:11484
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:8541
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition abg-ir.cc:5399
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition abg-ir.cc:10669
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
Definition abg-ir.h:105
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
Definition abg-ir.cc:6171
enum_type_decl_sptr lookup_enum_type_per_location(const interned_string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
Definition abg-ir.cc:13682
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
Definition abg-ir.cc:9682
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:14980
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:2791
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:6972
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:21054
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
Definition abg-ir.cc:12111
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:13186
qualified_type_def_sptr is_array_of_qualified_element(const array_type_def_sptr &array)
Tests if the element of a given array is a qualified type.
Definition abg-ir.cc:11782
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:3303
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
Definition abg-ir.cc:11240
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:7366
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:11277
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
bool elf_symbol_is_function(elf_symbol::type t)
Test if the type of an ELF symbol denotes a function symbol.
Definition abg-ir.cc:3000
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
Definition abg-ir.cc:1686
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:13439
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:6422
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:8349
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:3220
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:10741
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:28239
bool elf_symbols_alias(const elf_symbol &s1, const elf_symbol &s2)
Test if two symbols alias.
Definition abg-ir.cc:2722
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:10308
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
Definition abg-ir.cc:8398
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:9901
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:27940
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
bool is_template_decl(const decl_base_sptr &decl)
Tests whether a decl is a template.
Definition abg-ir.cc:11864
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
Definition abg-fwd.h:264
bool string_to_elf_symbol_binding(const string &s, elf_symbol::binding &b)
Convert a string representing a an elf symbol binding into an elf_symbol::binding.
Definition abg-ir.cc:2952
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
Definition abg-fwd.h:120
pointer_type_def_sptr lookup_pointer_type(const interned_string &type_name, const translation_unit &tu)
Lookup a pointer type from a translation unit.
Definition abg-ir.cc:12340
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:5845
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:11376
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:29832
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition abg-ir.cc:11870
bool try_canonical_compare(const T *l, const T *r)
Compare two types by comparing their canonical types if present.
Definition abg-ir.cc:914
const decl_base_sptr lookup_var_decl_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a var_decl in a scope.
Definition abg-ir.cc:12601
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:27877
unordered_map< string, decl_base_sptr > string_decl_base_sptr_map
Convenience typedef for a map which key is a string and which value is a decl_base_sptr.
Definition abg-fwd.h:157
qualified_type_def_sptr lookup_qualified_type(const interned_string &type_name, const translation_unit &tu)
Lookup a qualified type from a translation unit.
Definition abg-ir.cc:12294
void push_composite_type_comparison_operands(const type_base &left, const type_base &right)
Push a pair of operands on the stack of operands of the current type comparison, during type canonica...
Definition abg-ir.cc:311
const type_base_sptr lookup_type(const interned_string &fqn, const translation_unit &tu)
Lookup a type in a translation unit.
Definition abg-ir.cc:12517
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
Definition abg-ir.cc:1700
function_decl::parameter * is_function_parameter(const type_or_decl_base *tod)
Test whether a declaration is a function_decl.
Definition abg-ir.cc:10382
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
Definition abg-ir.cc:4993
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition abg-ir.cc:6199
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
Definition abg-ir.cc:12148
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:2977
weak_ptr< elf_symbol > elf_symbol_wptr
A convenience typedef for a weak pointer to elf_symbol.
Definition abg-ir.h:900
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition abg-ir.cc:6365
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:8890
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:14354
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:20060
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
Definition abg-ir.cc:7156
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:1610
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:14144
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:6084
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
Definition abg-ir.cc:6128
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:6223
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:28560
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition abg-ir.cc:11685
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
Definition abg-ir.cc:1672
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10405
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:27915
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:25235
array_type_def_sptr lookup_array_type(const interned_string &type_name, const translation_unit &tu)
Lookup an array type from a translation unit.
Definition abg-ir.cc:12446
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition abg-ir.cc:5319
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:9357
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:8305
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:28582
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:10552
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition abg-ir.cc:5370
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:6022
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:6635
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition abg-ir.cc:6039
unordered_set< uintptr_t > pointer_set
A convenience typedef for an unordered set of pointer values.
Definition abg-ir.h:99
void sort_types_for_hash_computing_and_c14n(IteratorType begin, IteratorType end)
Sort types before hashing (and then canonicalizing) them.
class_or_union * is_at_class_scope(const decl_base_sptr decl)
Tests whether a given decl is at class scope.
Definition abg-ir.cc:10265
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition abg-ir.cc:6496
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:11105
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:9654
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:5885
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
Definition abg-ir.cc:8621
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:11145
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
Definition abg-ir.cc:10161
weak_ptr< decl_base > decl_base_wptr
Convenience typedef for a weak pointer to a decl_base.
Definition abg-fwd.h:181
var_decl_sptr has_fake_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with one element.
Definition abg-ir.cc:10902
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:8967
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:11736
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:11544
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition abg-ir.cc:11071
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition abg-ir.cc:9920
enum_type_decl_sptr lookup_enum_type(const interned_string &type_name, const translation_unit &tu)
Lookup an enum type from a translation unit.
Definition abg-ir.cc:12216
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:6918
const type_base_wptrs_type * lookup_union_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the union type*s* that have a given qualified name.
Definition abg-ir.cc:13470
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:8920
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:11820
function_type_sptr lookup_function_type(const interned_string &type_name, const translation_unit &tu)
Lookup a function type from a translation unit.
Definition abg-ir.cc:12466
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
Definition abg-ir.cc:10210
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:8511
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:6185
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:11197
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition abg-ir.cc:5468
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:28607
const type_base_wptrs_type * lookup_class_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the class type*s* that have a given qualified name.
Definition abg-ir.cc:13419
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition abg-ir.cc:10078
var_decl_sptr has_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with non-finite data member.
Definition abg-ir.cc:10832
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition abg-ir.cc:26335
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:15869
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:11749
interned_string get_method_type_name(const method_type_sptr fn_type, bool internal)
Get the name of a given method type and return a copy of it.
Definition abg-ir.cc:9057
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:28517
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:9029
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition abg-fwd.h:161
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
Definition abg-ir.cc:7445
type_decl_sptr lookup_basic_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a type_decl type from a given corpus, by its location.
Definition abg-ir.cc:13307
bool compare_using_locations(const decl_base *f, const decl_base *s)
Compare decls using their locations.
Definition abg-ir.cc:3268
const type_base_sptr lookup_type_through_scopes(const type_base_sptr type, const translation_unit &tu)
Lookup a type from a translation unit by walking the scopes of the translation unit in sequence and l...
Definition abg-ir.cc:12878
type_or_decl_base * debug(const type_or_decl_base *artifact)
Emit a textual representation of an artifact to std error stream for debugging purposes.
Definition abg-ir.cc:9940
unordered_set< type_base_sptr, canonical_type_hash > canonical_type_sptr_set_type
Helper typedef for an unordered set of type_base_sptr which uses pointer value to tell its members ap...
Definition abg-ir.h:121
bool return_comparison_result(T &l, T &r, bool value)
Return the result of the comparison of two (sub) types.
Definition abg-ir.cc:1127
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
Definition abg-fwd.h:284
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
Definition abg-ir.cc:1709
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
Definition abg-ir.cc:15054
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition abg-ir.cc:28112
bool types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
Test if two types are equal modulo a typedef.
Definition abg-ir.cc:10112
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:8690
const scope_decl * get_top_most_scope_under(const decl_base *decl, const scope_decl *scope)
Return the a scope S containing a given declaration and that is right under a given scope P.
Definition abg-ir.cc:8442
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
Definition abg-ir.cc:7523
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:1742
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:8868
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
Definition abg-ir.cc:10330
typedef_decl_sptr lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a typedef_decl from a corpus, by its location.
Definition abg-ir.cc:13777
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition abg-ir.cc:10353
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:3010
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:27899
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:14262
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:11514
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:11464
typedef_decl_sptr lookup_typedef_type(const interned_string &type_name, const translation_unit &tu)
Lookup a typedef type from a translation unit.
Definition abg-ir.cc:12254
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:11217
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:918
union_decl_sptr lookup_union_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
Definition abg-ir.cc:12181
bool class_or_union_types_of_same_kind(const class_or_union *first, const class_or_union *second)
Test if two class or union types are of the same kind.
Definition abg-ir.cc:11043
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:8587
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:3251
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:24348
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
Definition abg-ir.cc:11574
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
Definition abg-fwd.h:294
enum_type_decl_sptr is_compatible_with_enum_type(const type_base_sptr &t)
Test if a type is an enum. This function looks through typedefs.
Definition abg-ir.cc:10708
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:7213
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:15084
bool is_at_global_scope(const decl_base &decl)
Tests whether a given declaration is at global scope.
Definition abg-ir.cc:10238
type_decl * is_real_type(const type_or_decl_base *t)
Test if a type is a real type.
Definition abg-ir.cc:10585
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition abg-ir.cc:5272
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:4924
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition abg-ir.cc:6250
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:6280
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:11011
bool match(const regex_t_sptr &r, const std::string &str)
See if a string matches a regex.
Definition abg-regex.cc:127
std::shared_ptr< regex_t > regex_t_sptr
A convenience typedef for a shared pointer of regex_t.
Definition abg-fwd.h:87
const char * get_anonymous_subrange_internal_name_prefix()
Getter of the prefix for the name of anonymous range.
const char * get_anonymous_enum_internal_name_prefix()
Getter of the prefix for the name of anonymous enums.
const char * get_anonymous_struct_internal_name_prefix()
Getter of the prefix for the name of anonymous structs.
const char * get_anonymous_union_internal_name_prefix()
Getter of the prefix for the name of anonymous unions.
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
Definition abg-ir.cc:151
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
Definition abg-ir.cc:185
unordered_map< string, string * > pool_map_type
Convenience typedef for a map of string -> string*.
Definition abg-ir.cc:73
A functor to hash instances of interned_string.
size_t operator()(const type_base_sptr &l) const
Hash a type by returning the pointer value of its canonical type.
Definition abg-ir.cc:7638
Hasher for the class_or_union type.
Definition abg-hash.h:250
bool is_printing_flat_representation() const
Getter of the 'is_printing_flat_representation_' boolean.
void unset_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to false.
void set_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to true.
A functor to sort decls somewhat topologically. That is, types are sorted in a way that makes the one...
The private data of the environment type.
Equality functor for instances of function_decl.
Definition abg-ir.h:4722
The hashing functor for function_type.
Definition abg-hash.h:217
The type of the private data of the function_type type.
virtual bool traverse(ir_node_visitor &v)
Traverse a given IR node and its children, calling an visitor on each node.
Definition abg-ir.cc:29482
The hashing functor for member_base.
Definition abg-hash.h:243
Private type to hold private members of translation_unit.
Hash functor for instances of type_base.
Definition abg-hash.h:111
Definition of the private data of type_base.
The private data of type_or_decl_base.
A predicate for deep equality of instances of shared_ptr<type_base>
Definition abg-ir.h:2067
A functor to sort types somewhat topologically. That is, types are sorted in a way that makes the one...
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.