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-2025 Red Hat, Inc.
6//
7//Author: Dodji Seketeli
8
9/// @file
10///
11/// Definitions for the Internal Representation artifacts of libabigail.
12
13#include <cxxabi.h>
14#include <cstdint>
15#include <functional>
16#include <iterator>
17#include <memory>
18#include <sstream>
19#include <typeinfo>
20#include <unordered_map>
21#include <utility>
22#include <vector>
23
24#include "abg-internal.h"
25// <headers defining libabigail's API go under here>
26ABG_BEGIN_EXPORT_DECLARATIONS
27
28#include "abg-interned-str.h"
29#include "abg-ir.h"
30#include "abg-corpus.h"
31#include "abg-regex.h"
32
33ABG_END_EXPORT_DECLARATIONS
34// </headers defining libabigail's API>
35
36#include "abg-corpus-priv.h"
37#include "abg-comp-filter.h"
38#include "abg-ir-priv.h"
39
40namespace
41{
42/// This internal type is a tree walking that is used to set the
43/// qualified name of a tree of decls and types. It used by the
44/// function update_qualified_name().
45class qualified_name_setter : public abigail::ir::ir_node_visitor
46{
47
48public:
49 bool
50 do_update(abigail::ir::decl_base* d);
51
52 bool
53 visit_begin(abigail::ir::decl_base* d);
54
55 bool
56 visit_begin(abigail::ir::type_base* d);
57}; // end class qualified_name_setter
58
59}// end anon namespace
60
61namespace abigail
62{
63
64// Inject.
65using std::string;
66using std::list;
67using std::vector;
68using std::unordered_map;
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
71
72/// Convenience typedef for a map of string -> string*.
73typedef unordered_map<string, string*> pool_map_type;
74
75/// The type of the private data structure of type @ref
76/// intered_string_pool.
77struct interned_string_pool::priv
78{
79 pool_map_type map;
80}; //end struc struct interned_string_pool::priv
81
82/// Default constructor.
84 : priv_(new priv)
85{
86 priv_->map[""] = 0;
87}
88
89/// Test if the interned string pool already contains a string with a
90/// given value.
91///
92/// @param s the string to test for.
93///
94/// @return true if the pool contains a string with the value @p s.
95bool
97{return priv_->map.find(s) != priv_->map.end();}
98
99/// Get a pointer to the interned string which has a given value.
100///
101/// @param s the value of the interned string to look for.
102///
103/// @return a pointer to the raw string of characters which has the
104/// value of @p s. Or null if no string with value @p s was interned.
105const char*
107{
108 unordered_map<string, string*>::const_iterator i =
109 priv_->map.find(s);
110 if (i == priv_->map.end())
111 return 0;
112 if (i->second)
113 return i->second->c_str();
114 return "";
115}
116
117/// Create an interned string with a given value.
118///
119/// @param str_value the value of the interned string to create.
120///
121/// @return the new created instance of @ref interned_string created.
123interned_string_pool::create_string(const std::string& str_value)
124{
125 string*& result = priv_->map[str_value];
126 if (!result && !str_value.empty())
127 result = new string(str_value);
128 return interned_string(result);
129}
130
131/// Destructor.
133{
134 for (pool_map_type::iterator i = priv_->map.begin();
135 i != priv_->map.end();
136 ++i)
137 if (i->second)
138 delete i->second;
139}
140
141/// Equality operator.
142///
143/// @param l the instance of std::string on the left-hand-side of the
144/// equality operator.
145///
146/// @param r the instance of @ref interned_string on the
147/// right-hand-side of the equality operator.
148///
149/// @return true iff the two string are equal.
150bool
151operator==(const std::string& l, const interned_string& r)
152{return r.operator==(l);}
153
154bool
155operator!=(const std::string& l, const interned_string& r)
156{return !(l == r);}
157
158/// Streaming operator.
159///
160/// Streams an instance of @ref interned_string to an output stream.
161///
162/// @param o the destination output stream.
163///
164/// @param s the instance of @ref interned_string to stream out.
165///
166/// @return the output stream this function just streamed to.
167std::ostream&
168operator<<(std::ostream& o, const interned_string& s)
169{
170 o << static_cast<std::string>(s);
171 return o;
172}
173
174/// Concatenation operator.
175///
176/// Concatenate two instances of @ref interned_string, builds an
177/// instance of std::string with the resulting string and return it.
178///
179/// @param s1 the first string to consider.
180///
181/// @param s2 the second string to consider.
182///
183/// @return the resuting concatenated string.
184std::string
185operator+(const interned_string& s1,const std::string& s2)
186{return static_cast<std::string>(s1) + s2;}
187
188/// Concatenation operator.
189///
190/// Concatenate two instances of @ref interned_string, builds an
191/// instance of std::string with the resulting string and return it.
192///
193/// @param s1 the first string to consider.
194///
195/// @param s2 the second string to consider.
196///
197/// @return the resuting concatenated string.
198std::string
199operator+(const std::string& s1, const interned_string& s2)
200{return s1 + static_cast<std::string>(s2);}
201
202namespace ir
203{
204
205static size_t
206hash_as_canonical_type_or_constant(const type_base *t);
207
208static bool
209has_generic_anonymous_internal_type_name(const decl_base *d);
210
211static interned_string
212get_generic_anonymous_internal_type_name(const decl_base *d);
213
214static string
215get_internal_real_type_name(const type_base*);
216
217static void
218update_qualified_name(decl_base * d);
219
220static void
221update_qualified_name(decl_base_sptr d);
222
223static interned_string
224pointer_declaration_name(const type_base* ptr,
225 const string& variable_name,
226 bool qualified, bool internal);
227
228static interned_string
229pointer_declaration_name(const type_base_sptr& ptr,
230 const string& variable_name,
231 bool qualified, bool internal);
232
233static interned_string
234ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
235 const string& variable_name,
236 bool qualified, bool internal);
237
238static interned_string
239ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
240 const string& variable_name,
241 bool qualified, bool internal);
242
243static interned_string
244array_declaration_name(const array_type_def* array,
245 const string& variable_name,
246 bool qualified, bool internal);
247
248static interned_string
249array_declaration_name(const array_type_def_sptr& array,
250 const string& variable_name,
251 bool qualified, bool internal);
252
253static void
254stream_pretty_representation_of_fn_parms(const function_type& fn_type,
255 ostream& o, bool qualified,
256 bool internal);
257static string
258add_outer_pointer_to_fn_type_expr(const type_base* pointer_to_fn,
259 const string& input, bool qualified,
260 bool internal);
261
262static string
263add_outer_pointer_to_fn_type_expr(const type_base_sptr& pointer_to_fn,
264 const string& input, bool qualified,
265 bool internal);
266
267static string
268add_outer_pointer_to_array_type_expr(const type_base* pointer_to_ar,
269 const string& input, bool qualified,
270 bool internal);
271
272static string
273add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
274 const string& input, bool qualified,
275 bool internal);
276
277static string
278add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
279 const string& input, bool qualified,
280 bool internal);
281
282static string
283add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
284 const string& input, bool qualified,
285 bool internal);
286
287static string
288add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
289 const string& input,
290 bool qualified, bool internal);
291
292void
293push_composite_type_comparison_operands(const type_base& left,
294 const type_base& right);
295
296void
297pop_composite_type_comparison_operands(const type_base& left,
298 const type_base& right);
299
300
301/// Push a pair of operands on the stack of operands of the current
302/// type comparison, during type canonicalization.
303///
304/// For more information on this, please look at the description of
305/// the environment::priv::right_type_comp_operands_ data member.
306///
307/// @param left the left-hand-side comparison operand to push.
308///
309/// @param right the right-hand-side comparison operand to push.
310void
312 const type_base& right)
313{
314 const environment& env = left.get_environment();
315 env.priv_->push_composite_type_comparison_operands(&left, &right);
316}
317
318/// Pop a pair of operands from the stack of operands to the current
319/// type comparison.
320///
321/// For more information on this, please look at the description of
322/// the environment::privright_type_comp_operands_ data member.
323///
324/// @param left the left-hand-side comparison operand we expect to
325/// pop from the top of the stack. If this doesn't match the
326/// operand found on the top of the stack, the function aborts.
327///
328/// @param right the right-hand-side comparison operand we expect to
329/// pop from the bottom of the stack. If this doesn't match the
330/// operand found on the top of the stack, the function aborts.
331void
333 const type_base& right)
334{
335 const environment& env = left.get_environment();
336 env.priv_->pop_composite_type_comparison_operands(&left, &right);
337}
338
339/// Getter of the canonical type index of a given type.
340///
341/// @param t the type to consider.
342///
343/// @return the CTI of the type.
344size_t
346{return t.priv_->canonical_type_index;}
347
348/// Getter of the canonical type index of a given type.
349///
350/// @param t the type to consider.
351///
352/// @return the CTI of the type.
353size_t
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_C17:
1557 return "LANG_C17";
1558 case translation_unit::LANG_C23:
1559 return "LANG_C23";
1560 case translation_unit::LANG_C:
1561 return "LANG_C";
1562 case translation_unit::LANG_C_plus_plus_03:
1563 return "LANG_C_plus_plus_03";
1564 case translation_unit::LANG_C_plus_plus_11:
1565 return "LANG_C_plus_plus_11";
1566 case translation_unit::LANG_C_plus_plus_14:
1567 return "LANG_C_plus_plus_14";
1568 case translation_unit::LANG_C_plus_plus_17:
1569 return "LANG_C_plus_plus_17";
1570 case translation_unit::LANG_C_plus_plus_20:
1571 return "LANG_C_plus_plus_20";
1572 case translation_unit::LANG_C_plus_plus_23:
1573 return "LANG_C_plus_plus_23";
1574 case translation_unit::LANG_C_plus_plus:
1575 return "LANG_C_plus_plus";
1576 case translation_unit::LANG_OCaml:
1577 return "LANG_OCaml";
1578 case translation_unit::LANG_Zig:
1579 return "LANG_Zig";
1580 case translation_unit::LANG_ObjC:
1581 return "LANG_ObjC";
1582 case translation_unit::LANG_ObjC_plus_plus:
1583 return "LANG_ObjC_plus_plus";
1584 case translation_unit::LANG_D:
1585 return "LANG_D";
1586 case translation_unit::LANG_Go:
1587 return "LANG_Go";
1588 case translation_unit::LANG_Rust:
1589 return "LANG_Rust";
1590 case translation_unit::LANG_Fortran77:
1591 return "LANG_Fortran77";
1592 case translation_unit::LANG_Fortran90:
1593 return "LANG_Fortran90";
1594 case translation_unit::LANG_Fortran95:
1595 return "LANG_Fortran95";
1596 case translation_unit::LANG_Fortran18:
1597 return "LANG_Fortran18";
1598 case translation_unit::LANG_Fortran23:
1599 return "LANG_Fortran23";
1600 case translation_unit::LANG_Ada83:
1601 return "LANG_Ada83";
1602 case translation_unit::LANG_Ada95:
1603 return "LANG_Ada95";
1604 case translation_unit::LANG_Ada2005:
1605 return "LANG_Ada2005";
1606 case translation_unit::LANG_Ada2012:
1607 return "LANG_Ada2012";
1608 case translation_unit::LANG_Pascal83:
1609 return "LANG_Pascal83";
1610 case translation_unit::LANG_Modula2:
1611 return "LANG_Modula2";
1612 case translation_unit::LANG_Java:
1613 return "LANG_Java";
1614 case translation_unit::LANG_Kotlin:
1615 return "LANG_Kotlin";
1616 case translation_unit::LANG_C_sharp:
1617 return "LANG_C_sharp";
1618 case translation_unit::LANG_Python:
1619 return "LANG_Python";
1620 case translation_unit::LANG_Ruby:
1621 return "LANG_Ruby";
1622 case translation_unit::LANG_PLI:
1623 return "LANG_PLI";
1624 case translation_unit::LANG_UPC:
1625 return "LANG_UPC";
1626 case translation_unit::LANG_Mips_Assembler:
1627 return "LANG_Mips_Assembler";
1628 case translation_unit::LANG_Assembly:
1629 return "LANG_Assembly";
1630 case translation_unit::LANG_Crystal:
1631 return "LANG_Crystal";
1632 case translation_unit::LANG_HIP:
1633 return "LANG_HIP";
1634 case translation_unit::LANG_Mojo:
1635 return "LANG_Mojo";
1636 case translation_unit::LANG_GLSL:
1637 return "LANG_GLSL";
1638 case translation_unit::LANG_GLSL_ES:
1639 return "LANG_GLSL_ES";
1640 case translation_unit::LANG_HLSL:
1641 return "LANG_HLSL";
1642 case translation_unit::LANG_OpenCL_CPP:
1643 return "LANG_OpenCL_CPP";
1644 case translation_unit::LANG_CPP_for_OpenCL:
1645 return "LANG_CPP_for_OpenCL";
1646 case translation_unit::LANG_SYCL:
1647 return "LANG_SYCL";
1648 case translation_unit::LANG_Odin:
1649 return "LANG_Odin";
1650 case translation_unit::LANG_P4:
1651 return "LANG_P4";
1652 case translation_unit::LANG_Metal:
1653 return "LANG_Metal";
1654 case translation_unit::LANG_Move:
1655 return "LANG_Move";
1656 case translation_unit::LANG_Hylo:
1657 return "LANG_Hylo";
1658 }
1659
1660 return "LANG_UNKNOWN";
1661}
1662
1663/// Parse a string representing a language into a
1664/// translation_unit::language enumerator into a string.
1665///
1666/// @param l the string representing the language.
1667///
1668/// @return the resulting translation_unit::language enumerator.
1671{
1672 if (l == "LANG_Cobol74")
1673 return translation_unit::LANG_Cobol74;
1674 else if (l == "LANG_Cobol85")
1675 return translation_unit::LANG_Cobol85;
1676 else if (l == "LANG_C89")
1677 return translation_unit::LANG_C89;
1678 else if (l == "LANG_C99")
1679 return translation_unit::LANG_C99;
1680 else if (l == "LANG_C11")
1681 return translation_unit::LANG_C11;
1682 else if (l == "LANG_C17")
1683 return translation_unit::LANG_C17;
1684 else if (l == "LANG_C23")
1685 return translation_unit::LANG_C23;
1686 else if (l == "LANG_C")
1687 return translation_unit::LANG_C;
1688 else if (l == "LANG_C_plus_plus_03")
1689 return translation_unit::LANG_C_plus_plus_03;
1690 else if (l == "LANG_C_plus_plus_11")
1691 return translation_unit::LANG_C_plus_plus_11;
1692 else if (l == "LANG_C_plus_plus_14")
1693 return translation_unit::LANG_C_plus_plus_14;
1694 else if (l == "LANG_C_plus_plus_17")
1695 return translation_unit::LANG_C_plus_plus_17;
1696 else if (l == "LANG_C_plus_plus_20")
1697 return translation_unit::LANG_C_plus_plus_20;
1698 else if (l == "LANG_C_plus_plus_23")
1699 return translation_unit::LANG_C_plus_plus_23;
1700 else if (l == "LANG_C_plus_plus")
1701 return translation_unit::LANG_C_plus_plus;
1702 else if (l == "LANG_OCaml")
1703 return translation_unit::LANG_OCaml;
1704 else if (l == "LANG_ObjC")
1705 return translation_unit::LANG_ObjC;
1706 else if (l == "LANG_ObjC_plus_plus")
1707 return translation_unit::LANG_ObjC_plus_plus;
1708 else if (l == "LANG_Zig")
1709 return translation_unit::LANG_Zig;
1710 else if (l == "LANG_Metal")
1711 return translation_unit::LANG_Metal;
1712 else if (l == "LANG_Fortran77")
1713 return translation_unit::LANG_Fortran77;
1714 else if (l == "LANG_Fortran90")
1715 return translation_unit::LANG_Fortran90;
1716 else if (l == "LANG_Fortran95")
1717 return translation_unit::LANG_Fortran95;
1718 else if (l == "LANG_Fortran18")
1719 return translation_unit::LANG_Fortran23;
1720 else if (l == "LANG_Ada83")
1721 return translation_unit::LANG_Ada83;
1722 else if (l == "LANG_Ada95")
1723 return translation_unit::LANG_Ada95;
1724 else if (l == "LANG_Ada2005")
1725 return translation_unit::LANG_Ada2005;
1726 else if (l == "LANG_Ada2012")
1727 return translation_unit::LANG_Ada2012;
1728 else if (l == "LANG_Pascal83")
1729 return translation_unit::LANG_Pascal83;
1730 else if (l == "LANG_Modula2")
1731 return translation_unit::LANG_Modula2;
1732 else if (l == "LANG_Java")
1733 return translation_unit::LANG_Java;
1734 else if (l == "LANG_Kotlin")
1735 return translation_unit::LANG_Kotlin;
1736 else if (l == "LANG_PLI")
1737 return translation_unit::LANG_PLI;
1738 else if (l == "LANG_UPC")
1739 return translation_unit::LANG_UPC;
1740 else if (l == "LANG_D")
1741 return translation_unit::LANG_D;
1742 else if (l == "LANG_Go")
1743 return translation_unit::LANG_Go;
1744 else if (l == "LANG_Rust")
1745 return translation_unit::LANG_Rust;
1746 else if (l == "LANG_Python")
1747 return translation_unit::LANG_Python;
1748 else if (l == "LANG_Ruby")
1749 return translation_unit::LANG_Ruby;
1750 else if (l == "LANG_Mips_Assembler")
1751 return translation_unit::LANG_Mips_Assembler;
1752 else if (l == "LANG_Assembly")
1753 return translation_unit::LANG_Assembly;
1754 else if (l == "LANG_Crystal")
1755 return translation_unit::LANG_Crystal;
1756 else if (l == "LANG_HIP")
1757 return translation_unit::LANG_HIP;
1758 else if (l == "LANG_C_sharp")
1759 return translation_unit::LANG_C_sharp;
1760 else if (l == "LANG_Mojo")
1761 return translation_unit::LANG_Mojo;
1762 else if (l == "LANG_GLSL")
1763 return translation_unit::LANG_GLSL;
1764 else if (l == "LANG_GLSL_ES")
1765 return translation_unit::LANG_GLSL_ES;
1766 else if (l == "LANG_HLSL")
1767 return translation_unit::LANG_HLSL;
1768 else if (l == "LANG_OpenCL_CPP")
1769 return translation_unit::LANG_OpenCL_CPP;
1770 else if (l == "LANG_CPP_for_OpenCL")
1771 return translation_unit::LANG_CPP_for_OpenCL;
1772 else if (l == "LANG_SYCL")
1773 return translation_unit::LANG_SYCL;
1774 else if (l == "LANG_Odin")
1775 return translation_unit::LANG_Odin;
1776 else if (l == "LANG_P4")
1777 return translation_unit::LANG_P4;
1778 else if (l == "LANG_Move")
1779 return translation_unit::LANG_Move;
1780 else if (l == "LANG_Hylo")
1781 return translation_unit::LANG_Hylo;
1782
1783 return translation_unit::LANG_UNKNOWN;
1784}
1785
1786/// Test if a language enumerator designates the C language.
1787///
1788/// @param l the language enumerator to consider.
1789///
1790/// @return true iff @p l designates the C language.
1791bool
1793{
1794 return (l == translation_unit::LANG_C89
1795 || l == translation_unit::LANG_C99
1796 || l == translation_unit::LANG_C11
1797 || l == translation_unit::LANG_C17
1798 || l == translation_unit::LANG_C23
1799 || l == translation_unit::LANG_C);
1800}
1801
1802/// Test if a language enumerator designates the C++ language.
1803///
1804/// @param l the language enumerator to consider.
1805///
1806/// @return true iff @p l designates the C++ language.
1807bool
1809{
1810 return (l == translation_unit::LANG_C_plus_plus_03
1811 || l == translation_unit::LANG_C_plus_plus_11
1812 || l == translation_unit::LANG_C_plus_plus_14
1813 || l == translation_unit::LANG_C_plus_plus_20
1814 || l == translation_unit::LANG_C_plus_plus_23
1815 || l == translation_unit::LANG_C_plus_plus);
1816}
1817
1818/// Test if a language enumerator designates the Java language.
1819///
1820/// @param l the language enumerator to consider.
1821///
1822/// @return true iff @p l designates the Java language.
1823bool
1825{return l == translation_unit::LANG_Java;}
1826
1827/// Test if a language enumerator designates the Ada language.
1828///
1829/// @param l the language enumerator to consider.
1830///
1831/// @return true iff @p l designates the Ada language.
1832bool
1834{
1835 return (l == translation_unit::LANG_Ada83
1836 || l == translation_unit::LANG_Ada95
1837 || l == translation_unit::LANG_Ada2005
1838 || l == translation_unit::LANG_Ada2012);
1839}
1840
1841/// A deep comparison operator for pointers to translation units.
1842///
1843/// @param l the first translation unit to consider for the comparison.
1844///
1845/// @param r the second translation unit to consider for the comparison.
1846///
1847/// @return true if the two translation units are equal, false otherwise.
1848bool
1850{
1851 if (l.get() == r.get())
1852 return true;
1853
1854 if (!!l != !!r)
1855 return false;
1856
1857 return *l == *r;
1858}
1859
1860/// A deep inequality operator for pointers to translation units.
1861///
1862/// @param l the first translation unit to consider for the comparison.
1863///
1864/// @param r the second translation unit to consider for the comparison.
1865///
1866/// @return true iff the two translation units are different.
1867bool
1869{return !operator==(l, r);}
1870
1871// </translation_unit stuff>
1872
1873// <elf_symbol stuff>
1874struct elf_symbol::priv
1875{
1876 const environment& env_;
1877 size_t index_;
1878 size_t size_;
1879 string name_;
1880 elf_symbol::type type_;
1881 elf_symbol::binding binding_;
1882 elf_symbol::version version_;
1883 elf_symbol::visibility visibility_;
1884 bool is_defined_;
1885 // This flag below says if the symbol is a common elf symbol. In
1886 // relocatable files, a common symbol is a symbol defined in a
1887 // section of kind SHN_COMMON.
1888 //
1889 // Note that a symbol of kind STT_COMMON is also considered a common
1890 // symbol. Here is what the gABI says about STT_COMMON and
1891 // SHN_COMMON:
1892 //
1893 // Symbols with type STT_COMMON label uninitialized common
1894 // blocks. In relocatable objects, these symbols are not
1895 // allocated and must have the special section index SHN_COMMON
1896 // (see below). In shared objects and executables these symbols
1897 // must be allocated to some section in the defining object.
1898 //
1899 // In relocatable objects, symbols with type STT_COMMON are
1900 // treated just as other symbols with index SHN_COMMON. If the
1901 // link-editor allocates space for the SHN_COMMON symbol in an
1902 // output section of the object it is producing, it must
1903 // preserve the type of the output symbol as STT_COMMON.
1904 //
1905 // When the dynamic linker encounters a reference to a symbol
1906 // that resolves to a definition of type STT_COMMON, it may (but
1907 // is not required to) change its symbol resolution rules as
1908 // follows: instead of binding the reference to the first symbol
1909 // found with the given name, the dynamic linker searches for
1910 // the first symbol with that name with type other than
1911 // STT_COMMON. If no such symbol is found, it looks for the
1912 // STT_COMMON definition of that name that has the largest size.
1913 bool is_common_;
1914 bool is_in_ksymtab_;
1917 bool is_suppressed_;
1918 elf_symbol_wptr main_symbol_;
1919 elf_symbol_wptr next_alias_;
1920 elf_symbol_wptr next_common_instance_;
1921 string id_string_;
1922
1923 priv(const environment& e)
1924 : env_(e),
1925 index_(),
1926 size_(),
1927 type_(elf_symbol::NOTYPE_TYPE),
1928 binding_(elf_symbol::GLOBAL_BINDING),
1929 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1930 is_defined_(false),
1931 is_common_(false),
1932 is_in_ksymtab_(false),
1933 crc_(),
1934 namespace_(),
1935 is_suppressed_(false)
1936 {}
1937
1938 priv(const environment& e,
1939 size_t i,
1940 size_t s,
1941 const string& n,
1944 bool d,
1945 bool c,
1946 const elf_symbol::version& ve,
1948 bool is_in_ksymtab,
1951 bool is_suppressed)
1952 : env_(e),
1953 index_(i),
1954 size_(s),
1955 name_(n),
1956 type_(t),
1957 binding_(b),
1958 version_(ve),
1959 visibility_(vi),
1960 is_defined_(d),
1961 is_common_(c),
1962 is_in_ksymtab_(is_in_ksymtab),
1963 crc_(crc),
1964 namespace_(ns),
1965 is_suppressed_(is_suppressed)
1966 {
1967 if (!is_common_)
1968 is_common_ = type_ == COMMON_TYPE;
1969 }
1970}; // end struct elf_symbol::priv
1971
1972/// Constructor of the @ref elf_symbol type.
1973///
1974/// Note that this constructor is private, so client code cannot use
1975/// it to create instances of @ref elf_symbol. Rather, client code
1976/// should use the @ref elf_symbol::create() function to create
1977/// instances of @ref elf_symbol instead.
1978///
1979/// @param e the environment we are operating from.
1980///
1981/// @param i the index of the symbol in the (ELF) symbol table.
1982///
1983/// @param s the size of the symbol.
1984///
1985/// @param n the name of the symbol.
1986///
1987/// @param t the type of the symbol.
1988///
1989/// @param b the binding of the symbol.
1990///
1991/// @param d true if the symbol is defined, false otherwise.
1992///
1993/// @param c true if the symbol is a common symbol, false otherwise.
1994///
1995/// @param ve the version of the symbol.
1996///
1997/// @param vi the visibility of the symbol.
1998///
1999/// @param crc the CRC (modversions) value of Linux Kernel symbols
2000///
2001/// @param ns the namespace of Linux Kernel symbols, if any
2002elf_symbol::elf_symbol(const environment& e,
2003 size_t i,
2004 size_t s,
2005 const string& n,
2006 type t,
2007 binding b,
2008 bool d,
2009 bool c,
2010 const version& ve,
2011 visibility vi,
2012 bool is_in_ksymtab,
2015 bool is_suppressed)
2016 : priv_(new priv(e,
2017 i,
2018 s,
2019 n,
2020 t,
2021 b,
2022 d,
2023 c,
2024 ve,
2025 vi,
2026 is_in_ksymtab,
2027 crc,
2028 ns,
2029 is_suppressed))
2030{}
2031
2032/// Factory of instances of @ref elf_symbol.
2033///
2034/// This is the function to use to create instances of @ref elf_symbol.
2035///
2036/// @param e the environment we are operating from.
2037///
2038/// @param i the index of the symbol in the (ELF) symbol table.
2039///
2040/// @param s the size of the symbol.
2041///
2042/// @param n the name of the symbol.
2043///
2044/// @param t the type of the symbol.
2045///
2046/// @param b the binding of the symbol.
2047///
2048/// @param d true if the symbol is defined, false otherwise.
2049///
2050/// @param c true if the symbol is a common symbol.
2051///
2052/// @param ve the version of the symbol.
2053///
2054/// @param vi the visibility of the symbol.
2055///
2056/// @param crc the CRC (modversions) value of Linux Kernel symbols
2057///
2058/// @param ns the namespace of Linux Kernel symbols, if any
2059///
2060/// @return a (smart) pointer to a newly created instance of @ref
2061/// elf_symbol.
2064 size_t i,
2065 size_t s,
2066 const string& n,
2067 type t,
2068 binding b,
2069 bool d,
2070 bool c,
2071 const version& ve,
2072 visibility vi,
2073 bool is_in_ksymtab,
2076 bool is_suppressed)
2077{
2078 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
2079 is_in_ksymtab, crc, ns, is_suppressed));
2080 sym->priv_->main_symbol_ = sym;
2081 return sym;
2082}
2083
2084/// Test textual equality between two symbols.
2085///
2086/// Textual equality means that the aliases of the compared symbols
2087/// are not taken into account. Only the name, type, and version of
2088/// the symbols are compared.
2089///
2090/// @parm l the first ELF symbol to take into consideration in the
2091/// comparison.
2092///
2093/// @param r the second ELF symbol to take into consideration in the
2094/// comparison.
2095///
2096/// @param k a pointer to a bitfield that gives information about the
2097/// kind of changes there are between @p l and @p r. This one is set
2098/// iff it's non-null and if the function returns false.
2099///
2100/// @return true iff the two symbols are textually equal.
2101static bool
2102textually_equals(const elf_symbol&l, const elf_symbol&r,
2103 change_kind* k = nullptr)
2104{
2105 bool equals = (l.get_name() == r.get_name()
2106 && l.get_type() == r.get_type()
2107 && l.is_public() == r.is_public()
2108 && l.is_defined() == r.is_defined()
2110 && l.get_version() == r.get_version()
2111 && l.get_crc() == r.get_crc()
2112 && l.get_namespace() == r.get_namespace());
2113
2114 if (!equals)
2115 if (k)
2117
2118 if (equals && l.is_variable())
2119 // These are variable symbols. Let's compare their symbol size.
2120 // The symbol size in this case is the size taken by the storage
2121 // of the variable. If that size changes, then it's an ABI
2122 // change.
2123 if (l.get_size() != r.get_size())
2124 {
2125 equals = false;
2126 if (k)
2128 }
2129
2130 return equals;
2131}
2132
2133/// Getter of the environment used by the current instance of @ref
2134/// elf_symbol.
2135///
2136/// @return the enviroment used by the current instance of @ref elf_symbol.
2137const environment&
2139{return priv_->env_;}
2140
2141/// Getter for the index
2142///
2143/// @return the index of the symbol.
2144size_t
2146{return priv_->index_;}
2147
2148/// Setter for the index.
2149///
2150/// @param s the new index.
2151void
2153{priv_->index_ = s;}
2154
2155/// Getter for the name of the @ref elf_symbol.
2156///
2157/// @return a reference to the name of the @ref symbol.
2158const string&
2160{return priv_->name_;}
2161
2162/// Setter for the name of the current intance of @ref elf_symbol.
2163///
2164/// @param n the new name.
2165void
2166elf_symbol::set_name(const string& n)
2167{
2168 priv_->name_ = n;
2169 priv_->id_string_.clear();
2170}
2171
2172/// Getter for the type of the current instance of @ref elf_symbol.
2173///
2174/// @return the type of the elf symbol.
2177{return priv_->type_;}
2178
2179/// Setter for the type of the current instance of @ref elf_symbol.
2180///
2181/// @param t the new symbol type.
2182void
2184{priv_->type_ = t;}
2185
2186/// Getter of the size of the symbol.
2187///
2188/// @return the size of the symbol, in bytes.
2189size_t
2191{return priv_->size_;}
2192
2193/// Setter of the size of the symbol.
2194///
2195/// @param size the new size of the symbol, in bytes.
2196void
2198{priv_->size_ = size;}
2199
2200/// Getter for the binding of the current instance of @ref elf_symbol.
2201///
2202/// @return the binding of the symbol.
2205{return priv_->binding_;}
2206
2207/// Setter for the binding of the current instance of @ref elf_symbol.
2208///
2209/// @param b the new binding.
2210void
2212{priv_->binding_ = b;}
2213
2214/// Getter for the version of the current instanc of @ref elf_symbol.
2215///
2216/// @return the version of the elf symbol.
2219{return priv_->version_;}
2220
2221/// Setter for the version of the current instance of @ref elf_symbol.
2222///
2223/// @param v the new version of the elf symbol.
2224void
2226{
2227 priv_->version_ = v;
2228 priv_->id_string_.clear();
2229}
2230
2231/// Setter of the visibility of the current instance of @ref
2232/// elf_symbol.
2233///
2234/// @param v the new visibility of the elf symbol.
2235void
2237{priv_->visibility_ = v;}
2238
2239/// Getter of the visibility of the current instance of @ref
2240/// elf_symbol.
2241///
2242/// @return the visibility of the elf symbol.
2245{return priv_->visibility_;}
2246
2247/// Test if the current instance of @ref elf_symbol is defined or not.
2248///
2249/// @return true if the current instance of @ref elf_symbol is
2250/// defined, false otherwise.
2251bool
2253{return priv_->is_defined_;}
2254
2255/// Sets a flag saying if the current instance of @ref elf_symbol is
2256/// defined
2257///
2258/// @param b the new value of the flag.
2259void
2261{priv_->is_defined_ = d;}
2262
2263/// Test if the current instance of @ref elf_symbol is public or not.
2264///
2265/// This tests if the symbol is defined, has default or protected
2266///visibility, and either:
2267/// - has global binding
2268/// - has weak binding
2269/// - or has a GNU_UNIQUE binding.
2270///
2271/// return true if the current instance of @ref elf_symbol is public,
2272/// false otherwise.
2273bool
2275{
2276 return (is_defined()
2277 && (get_binding() == GLOBAL_BINDING
2278 || get_binding() == WEAK_BINDING
2279 || get_binding() == GNU_UNIQUE_BINDING)
2280 && (get_visibility() == DEFAULT_VISIBILITY
2281 || get_visibility() == PROTECTED_VISIBILITY));
2282}
2283
2284/// Test if the current instance of @ref elf_symbol is a function
2285/// symbol or not.
2286///
2287/// @return true if the current instance of @ref elf_symbol is a
2288/// function symbol, false otherwise.
2289bool
2291{return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2292
2293/// Test if the current instance of @ref elf_symbol is a variable
2294/// symbol or not.
2295///
2296/// @return true if the current instance of @ref elf_symbol is a
2297/// variable symbol, false otherwise.
2298bool
2300{
2301 return (get_type() == OBJECT_TYPE
2302 || get_type() == TLS_TYPE
2303 // It appears that undefined variables have NOTYPE type.
2304 || (get_type() == NOTYPE_TYPE
2305 && !is_defined()));
2306}
2307
2308/// Getter of the 'is-in-ksymtab' property.
2309///
2310/// @return true iff the current symbol is in the Linux Kernel
2311/// specific 'ksymtab' symbol table.
2312bool
2314{return priv_->is_in_ksymtab_;}
2315
2316/// Setter of the 'is-in-ksymtab' property.
2317///
2318/// @param is_in_ksymtab this is true iff the current symbol is in the
2319/// Linux Kernel specific 'ksymtab' symbol table.
2320void
2322{priv_->is_in_ksymtab_ = is_in_ksymtab;}
2323
2324/// Getter of the 'crc' property.
2325///
2326/// @return the CRC (modversions) value for Linux Kernel symbols, if any
2329{return priv_->crc_;}
2330
2331/// Setter of the 'crc' property.
2332///
2333/// @param crc the new CRC (modversions) value for Linux Kernel symbols
2334void
2336{priv_->crc_ = crc;}
2337
2338/// Getter of the 'namespace' property.
2339///
2340/// @return the namespace for Linux Kernel symbols, if any
2343{return priv_->namespace_;}
2344
2345/// Setter of the 'namespace' property.
2346///
2347/// @param ns the new namespace for Linux Kernel symbols, if any
2348void
2350{priv_->namespace_ = ns;}
2351
2352/// Getter for the 'is-suppressed' property.
2353///
2354/// @return true iff the current symbol has been suppressed by a
2355/// suppression specification that was provided in the context that
2356/// led to the creation of the corpus this ELF symbol belongs to.
2357bool
2359{return priv_->is_suppressed_;}
2360
2361/// Setter for the 'is-suppressed' property.
2362///
2363/// @param true iff the current symbol has been suppressed by a
2364/// suppression specification that was provided in the context that
2365/// led to the creation of the corpus this ELF symbol belongs to.
2366void
2368{priv_->is_suppressed_ = is_suppressed;}
2369
2370/// @name Elf symbol aliases
2371///
2372/// An alias A for an elf symbol S is a symbol that is defined at the
2373/// same address as S. S is chained to A through the
2374/// elf_symbol::get_next_alias() method.
2375///
2376/// When there are several aliases to a symbol, the main symbol is the
2377/// the first symbol found in the symbol table for a given address.
2378///
2379/// The alias chain is circular. That means if S is the main symbol
2380/// and A is the alias, S is chained to A and A
2381/// is chained back to the main symbol S. The last alias in an alias
2382///chain is always chained to the main symbol.
2383///
2384/// Thus, when looping over the aliases of an elf_symbol A, detecting
2385/// an alias that is equal to the main symbol should logically be a
2386/// loop exit condition.
2387///
2388/// Accessing and adding aliases for instances of elf_symbol is done
2389/// through the member functions below.
2390
2391/// @{
2392
2393/// Get the main symbol of an alias chain.
2394///
2395///@return the main symbol.
2396const elf_symbol_sptr
2398{return priv_->main_symbol_.lock();}
2399
2400/// Get the main symbol of an alias chain.
2401///
2402///@return the main symbol.
2405{return priv_->main_symbol_.lock();}
2406
2407/// Tests whether this symbol is the main symbol.
2408///
2409/// @return true iff this symbol is the main symbol.
2410bool
2412{return get_main_symbol().get() == this;}
2413
2414/// Get the next alias of the current symbol.
2415///
2416///@return the alias, or NULL if there is no alias.
2419{return priv_->next_alias_.lock();}
2420
2421
2422/// Check if the current elf_symbol has an alias.
2423///
2424///@return true iff the current elf_symbol has an alias.
2425bool
2427{return bool(get_next_alias());}
2428
2429/// Get the number of aliases to this elf symbol
2430///
2431/// @return the number of aliases to this elf symbol.
2432int
2434{
2435 int result = 0;
2436
2438 a && a.get() != get_main_symbol().get();
2439 a = a->get_next_alias())
2440 ++result;
2441
2442 return result;
2443}
2444
2445/// Add an alias to the current elf symbol.
2446///
2447/// @param alias the new alias. Note that this elf_symbol should *NOT*
2448/// have aliases prior to the invocation of this function.
2449void
2451{
2452 if (!alias)
2453 return;
2454
2455 ABG_ASSERT(!alias->has_aliases());
2457
2458 if (has_aliases())
2459 {
2460 elf_symbol_sptr last_alias;
2462 a && !a->is_main_symbol();
2463 a = a->get_next_alias())
2464 {
2465 if (a->get_next_alias()->is_main_symbol())
2466 {
2467 ABG_ASSERT(last_alias == 0);
2468 last_alias = a;
2469 }
2470 }
2471 ABG_ASSERT(last_alias);
2472
2473 last_alias->priv_->next_alias_ = alias;
2474 }
2475 else
2476 priv_->next_alias_ = alias;
2477
2478 alias->priv_->next_alias_ = get_main_symbol();
2479 alias->priv_->main_symbol_ = get_main_symbol();
2480}
2481
2482/// Update the main symbol for a group of aliased symbols
2483///
2484/// If after the construction of the symbols (in order of discovery), the
2485/// actual main symbol can be identified (e.g. as the symbol that actually is
2486/// defined in the code), this method offers a way of updating the main symbol
2487/// through one of the aliased symbols.
2488///
2489/// For that, locate the new main symbol by name and update all references to
2490/// the main symbol among the group of aliased symbols.
2491///
2492/// @param name the name of the main symbol
2493///
2494/// @return the new main elf_symbol
2496elf_symbol::update_main_symbol(const std::string& name)
2497{
2499 if (!has_aliases() || get_name() == name)
2500 return get_main_symbol();
2501
2502 // find the new main symbol
2503 elf_symbol_sptr new_main;
2504 // we've already checked this; check the rest of the aliases
2505 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2506 a = a->get_next_alias())
2507 if (a->get_name() == name)
2508 {
2509 new_main = a;
2510 break;
2511 }
2512
2513 if (!new_main)
2514 return get_main_symbol();
2515
2516 // now update all main symbol references
2517 priv_->main_symbol_ = new_main;
2518 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2519 a = a->get_next_alias())
2520 a->priv_->main_symbol_ = new_main;
2521
2522 return new_main;
2523}
2524
2525/// Return true if the symbol is a common one.
2526///
2527/// @return true iff the symbol is common.
2528bool
2530{return priv_->is_common_;}
2531
2532/// Return true if this common common symbol has other common instances.
2533///
2534/// A common instance of a given common symbol is another common
2535/// symbol with the same name. Those exist in relocatable files. The
2536/// linker normally allocates all the instances into a common block in
2537/// the final output file.
2538///
2539/// Note that the current object must be a common symbol, otherwise,
2540/// this function aborts.
2541///
2542/// @return true iff the current common symbol has other common
2543/// instances.
2544bool
2550
2551/// Get the next common instance of the current common symbol.
2552///
2553/// A common instance of a given common symbol is another common
2554/// symbol with the same name. Those exist in relocatable files. The
2555/// linker normally allocates all the instances into a common block in
2556/// the final output file.
2557///
2558/// @return the next common instance, or nil if there is not any.
2561{return priv_->next_common_instance_.lock();}
2562
2563/// Add a common instance to the current common elf symbol.
2564///
2565/// Note that this symbol must be the main symbol. Being the main
2566/// symbol means being the first common symbol to appear in the symbol
2567/// table.
2568///
2569/// @param common the other common instance to add.
2570void
2572{
2573 if (!common)
2574 return;
2575
2576 ABG_ASSERT(!common->has_other_common_instances());
2579
2581 {
2582 elf_symbol_sptr last_common_instance;
2584 c && (c.get() != get_main_symbol().get());
2585 c = c->get_next_common_instance())
2586 {
2587 if (c->get_next_common_instance().get() == get_main_symbol().get())
2588 {
2589 ABG_ASSERT(last_common_instance == 0);
2590 last_common_instance = c;
2591 }
2592 }
2593 ABG_ASSERT(last_common_instance);
2594
2595 last_common_instance->priv_->next_common_instance_ = common;
2596 }
2597 else
2598 priv_->next_common_instance_ = common;
2599
2600 common->priv_->next_common_instance_ = get_main_symbol();
2601 common->priv_->main_symbol_ = get_main_symbol();
2602}
2603
2604/// Get a string that is representative of a given elf_symbol.
2605///
2606/// If the symbol has a version, then the ID string is the
2607/// concatenation of the name of the symbol, the '@' character, and
2608/// the version of the symbol. If the version is the default version
2609/// of the symbol then the '@' character is replaced by a "@@" string.
2610///
2611/// Otherwise, if the symbol does not have any version, this function
2612/// returns the name of the symbol.
2613///
2614/// @return a the ID string.
2615const string&
2617{
2618 if (priv_->id_string_.empty())
2619 {
2620 string s = get_name ();
2621
2622 if (!get_version().is_empty())
2623 {
2624 if (get_version().is_default())
2625 s += "@@";
2626 else
2627 s += "@";
2628 s += get_version().str();
2629 }
2630 priv_->id_string_ = s;
2631 }
2632
2633 return priv_->id_string_;
2634}
2635
2636/// From the aliases of the current symbol, lookup one with a given name.
2637///
2638/// @param name the name of symbol alias we are looking for.
2639///
2640/// @return the symbol alias that has the name @p name, or nil if none
2641/// has been found.
2643elf_symbol::get_alias_from_name(const string& name) const
2644{
2645 if (name == get_name())
2646 return elf_symbol_sptr(priv_->main_symbol_);
2647
2649 a && a.get() != get_main_symbol().get();
2650 a = a->get_next_alias())
2651 if (a->get_name() == name)
2652 return a;
2653
2654 return elf_symbol_sptr();
2655}
2656
2657/// In the list of aliases of a given elf symbol, get the alias that
2658/// equals this current symbol.
2659///
2660/// @param other the elf symbol to get the potential aliases from.
2661///
2662/// @return the alias of @p other that texually equals the current
2663/// symbol, or nil if no alias textually equals the current symbol.
2666{
2667 for (elf_symbol_sptr a = other.get_next_alias();
2668 a && a.get() != a->get_main_symbol().get();
2669 a = a->get_next_alias())
2670 if (textually_equals(*this, *a))
2671 return a;
2672 return elf_symbol_sptr();
2673}
2674
2675/// Return a comma separated list of the id of the current symbol as
2676/// well as the id string of its aliases.
2677///
2678/// @param syms a map of all the symbols of the corpus the current
2679/// symbol belongs to.
2680///
2681/// @param include_symbol_itself if set to true, then the name of the
2682/// current symbol is included in the list of alias names that is emitted.
2683///
2684/// @return the string.
2685string
2687 bool include_symbol_itself) const
2688{
2689 string result;
2690
2691 if (include_symbol_itself)
2692 result = get_id_string();
2693
2694 vector<elf_symbol_sptr> aliases;
2695 compute_aliases_for_elf_symbol(*this, syms, aliases);
2696 if (!aliases.empty() && include_symbol_itself)
2697 result += ", ";
2698
2699 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2700 i != aliases.end();
2701 ++i)
2702 {
2703 if (i != aliases.begin())
2704 result += ", ";
2705 result += (*i)->get_id_string();
2706 }
2707 return result;
2708}
2709
2710/// Return a comma separated list of the id of the current symbol as
2711/// well as the id string of its aliases.
2712///
2713/// @param include_symbol_itself if set to true, then the name of the
2714/// current symbol is included in the list of alias names that is emitted.
2715///
2716/// @return the string.
2717string
2718elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2719{
2720 vector<elf_symbol_sptr> aliases;
2721 if (include_symbol_itself)
2722 aliases.push_back(get_main_symbol());
2723
2725 a && a.get() != get_main_symbol().get();
2726 a = a->get_next_alias())
2727 aliases.push_back(a);
2728
2729 string result;
2730 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2731 i != aliases.end();
2732 ++i)
2733 {
2734 if (i != aliases.begin())
2735 result += ", ";
2736 result += (*i)->get_id_string();
2737 }
2738
2739 return result;
2740}
2741
2742/// Given the ID of a symbol, get the name and the version of said
2743/// symbol.
2744///
2745/// @param id the symbol ID to consider.
2746///
2747/// @param name the symbol name extracted from the ID. This is set
2748/// only if the function returned true.
2749///
2750/// @param ver the symbol version extracted from the ID.
2751bool
2753 string& name,
2754 string& ver)
2755{
2756 name.clear(), ver.clear();
2757
2758 string::size_type i = id.find('@');
2759 if (i == string::npos)
2760 {
2761 name = id;
2762 return true;
2763 }
2764
2765 name = id.substr(0, i);
2766 ++i;
2767
2768 if (i >= id.size())
2769 return true;
2770
2771 string::size_type j = id.find('@', i);
2772 if (j == string::npos)
2773 j = i;
2774 else
2775 ++j;
2776
2777 if (j >= id.size())
2778 {
2779 ver = "";
2780 return true;
2781 }
2782
2783 ver = id.substr(j);
2784 return true;
2785}
2786
2787///@}
2788
2789/// Test if two main symbols are textually equal, or, if they have
2790/// aliases that are textually equal.
2791///
2792/// @param other the symbol to compare against.
2793///
2794/// @return true iff the current instance of elf symbol equals the @p
2795/// other.
2796bool
2798{
2799 bool are_equal = textually_equals(*this, other);
2800 if (!are_equal)
2801 are_equal = bool(get_alias_which_equals(other));
2802 return are_equal;
2803}
2804
2805/// Test if the current symbol aliases another one.
2806///
2807/// @param o the other symbol to test against.
2808///
2809/// @return true iff the current symbol aliases @p o.
2810bool
2812{
2813 if (*this == o)
2814 return true;
2815
2816 if (get_main_symbol() == o.get_main_symbol())
2817 return true;
2818
2820 a && !a->is_main_symbol();
2821 a = a->get_next_alias())
2822 {
2823 if (o == *a)
2824 return true;
2825 }
2826 return false;
2827}
2828
2829/// Equality operator for smart pointers to elf_symbol.
2830///
2831/// @param lhs the first elf symbol to consider.
2832///
2833/// @param rhs the second elf symbol to consider.
2834///
2835/// @return true iff @p lhs equals @p rhs.
2836bool
2838{
2839 if (!!lhs != !!rhs)
2840 return false;
2841
2842 if (!lhs)
2843 return true;
2844
2845 return *lhs == *rhs;
2846}
2847
2848/// Inequality operator for smart pointers to elf_symbol.
2849///
2850/// @param lhs the first elf symbol to consider.
2851///
2852/// @param rhs the second elf symbol to consider.
2853///
2854/// @return true iff @p lhs is different from @p rhs.
2855bool
2857{return !operator==(lhs, rhs);}
2858
2859/// Test if two symbols alias.
2860///
2861/// @param s1 the first symbol to consider.
2862///
2863/// @param s2 the second symbol to consider.
2864///
2865/// @return true if @p s1 aliases @p s2.
2866bool
2868{return s1.does_alias(s2) || s2.does_alias(s1);}
2869
2870void
2871compute_aliases_for_elf_symbol(const elf_symbol& sym,
2872 const string_elf_symbols_map_type& symtab,
2873 vector<elf_symbol_sptr>& aliases)
2874{
2875
2876 if (elf_symbol_sptr a = sym.get_next_alias())
2877 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2878 aliases.push_back(a);
2879 else
2880 {
2881 // No pre-linked alias chain (e.g. symbols loaded from abixml).
2882 // Look up by name in the symtab (O(1) hash lookup) instead of
2883 // scanning the entire table (which was O(N) per call).
2884 string_elf_symbols_map_type::const_iterator i =
2885 symtab.find(sym.get_name());
2886 if (i == symtab.end())
2887 return;
2888
2889 for (elf_symbols::const_iterator j = i->second.begin();
2890 j != i->second.end();
2891 ++j)
2892 {
2893 if (**j == sym)
2894 for (elf_symbol_sptr s = (*j)->get_next_alias();
2895 s && !s->is_main_symbol();
2896 s = s->get_next_alias())
2897 aliases.push_back(s);
2898 else
2899 for (elf_symbol_sptr s = (*j)->get_next_alias();
2900 s && !s->is_main_symbol();
2901 s = s->get_next_alias())
2902 if (*s == sym)
2903 aliases.push_back(*j);
2904 }
2905 }
2906}
2907
2908/// Test if two symbols alias.
2909///
2910/// @param s1 the first symbol to consider.
2911///
2912/// @param s2 the second symbol to consider.
2913///
2914/// @return true if @p s1 aliases @p s2.
2915bool
2917{
2918 if (!!s1 != !!s2)
2919 return false;
2920 if (s1 == s2)
2921 return true;
2922 return elf_symbols_alias(*s1, *s2);
2923}
2924
2925/// Test if two symbols alias.
2926///
2927/// @param s1 the first symbol to consider.
2928///
2929/// @param s2 the second symbol to consider.
2930///
2931/// @return true if @p s1 aliases @p s2.
2932bool
2934{return elf_symbols_alias(s1.get(), s2.get());}
2935
2936/// Serialize an instance of @ref symbol_type and stream it to a given
2937/// output stream.
2938///
2939/// @param o the output stream to serialize the symbole type to.
2940///
2941/// @param t the symbol type to serialize.
2942std::ostream&
2943operator<<(std::ostream& o, elf_symbol::type t)
2944{
2945 string repr;
2946
2947 switch (t)
2948 {
2949 case elf_symbol::NOTYPE_TYPE:
2950 repr = "unspecified symbol type";
2951 break;
2952 case elf_symbol::OBJECT_TYPE:
2953 repr = "variable symbol type";
2954 break;
2955 case elf_symbol::FUNC_TYPE:
2956 repr = "function symbol type";
2957 break;
2958 case elf_symbol::SECTION_TYPE:
2959 repr = "section symbol type";
2960 break;
2961 case elf_symbol::FILE_TYPE:
2962 repr = "file symbol type";
2963 break;
2964 case elf_symbol::COMMON_TYPE:
2965 repr = "common data object symbol type";
2966 break;
2967 case elf_symbol::TLS_TYPE:
2968 repr = "thread local data object symbol type";
2969 break;
2970 case elf_symbol::GNU_IFUNC_TYPE:
2971 repr = "indirect function symbol type";
2972 break;
2973 default:
2974 {
2975 std::ostringstream s;
2976 s << "unknown symbol type (" << (char)t << ')';
2977 repr = s.str();
2978 }
2979 break;
2980 }
2981
2982 o << repr;
2983 return o;
2984}
2985
2986/// Serialize an instance of @ref symbol_binding and stream it to a
2987/// given output stream.
2988///
2989/// @param o the output stream to serialize the symbole type to.
2990///
2991/// @param b the symbol binding to serialize.
2992std::ostream&
2993operator<<(std::ostream& o, elf_symbol::binding b)
2994{
2995 string repr;
2996
2997 switch (b)
2998 {
2999 case elf_symbol::LOCAL_BINDING:
3000 repr = "local binding";
3001 break;
3002 case elf_symbol::GLOBAL_BINDING:
3003 repr = "global binding";
3004 break;
3005 case elf_symbol::WEAK_BINDING:
3006 repr = "weak binding";
3007 break;
3008 case elf_symbol::GNU_UNIQUE_BINDING:
3009 repr = "GNU unique binding";
3010 break;
3011 default:
3012 {
3013 std::ostringstream s;
3014 s << "unknown binding (" << (unsigned char) b << ")";
3015 repr = s.str();
3016 }
3017 break;
3018 }
3019
3020 o << repr;
3021 return o;
3022}
3023
3024/// Serialize an instance of @ref elf_symbol::visibility and stream it
3025/// to a given output stream.
3026///
3027/// @param o the output stream to serialize the symbole type to.
3028///
3029/// @param v the symbol visibility to serialize.
3030std::ostream&
3031operator<<(std::ostream& o, elf_symbol::visibility v)
3032{
3033 string repr;
3034
3035 switch (v)
3036 {
3037 case elf_symbol::DEFAULT_VISIBILITY:
3038 repr = "default visibility";
3039 break;
3040 case elf_symbol::PROTECTED_VISIBILITY:
3041 repr = "protected visibility";
3042 break;
3043 case elf_symbol::HIDDEN_VISIBILITY:
3044 repr = "hidden visibility";
3045 break;
3046 case elf_symbol::INTERNAL_VISIBILITY:
3047 repr = "internal visibility";
3048 break;
3049 default:
3050 {
3051 std::ostringstream s;
3052 s << "unknown visibility (" << (unsigned char) v << ")";
3053 repr = s.str();
3054 }
3055 break;
3056 }
3057
3058 o << repr;
3059 return o;
3060}
3061
3062/// Convert a string representing a symbol type into an
3063/// elf_symbol::type.
3064///
3065///@param s the string to convert.
3066///
3067///@param t the resulting elf_symbol::type.
3068///
3069/// @return true iff the conversion completed successfully.
3070bool
3072{
3073 if (s == "no-type")
3074 t = elf_symbol::NOTYPE_TYPE;
3075 else if (s == "object-type")
3076 t = elf_symbol::OBJECT_TYPE;
3077 else if (s == "func-type")
3078 t = elf_symbol::FUNC_TYPE;
3079 else if (s == "section-type")
3080 t = elf_symbol::SECTION_TYPE;
3081 else if (s == "file-type")
3082 t = elf_symbol::FILE_TYPE;
3083 else if (s == "common-type")
3084 t = elf_symbol::COMMON_TYPE;
3085 else if (s == "tls-type")
3086 t = elf_symbol::TLS_TYPE;
3087 else if (s == "gnu-ifunc-type")
3088 t = elf_symbol::GNU_IFUNC_TYPE;
3089 else
3090 return false;
3091
3092 return true;
3093}
3094
3095/// Convert a string representing a an elf symbol binding into an
3096/// elf_symbol::binding.
3097///
3098/// @param s the string to convert.
3099///
3100/// @param b the resulting elf_symbol::binding.
3101///
3102/// @return true iff the conversion completed successfully.
3103bool
3105{
3106 if (s == "local-binding")
3107 b = elf_symbol::LOCAL_BINDING;
3108 else if (s == "global-binding")
3109 b = elf_symbol::GLOBAL_BINDING;
3110 else if (s == "weak-binding")
3111 b = elf_symbol::WEAK_BINDING;
3112 else if (s == "gnu-unique-binding")
3113 b = elf_symbol::GNU_UNIQUE_BINDING;
3114 else
3115 return false;
3116
3117 return true;
3118}
3119
3120/// Convert a string representing a an elf symbol visibility into an
3121/// elf_symbol::visibility.
3122///
3123/// @param s the string to convert.
3124///
3125/// @param b the resulting elf_symbol::visibility.
3126///
3127/// @return true iff the conversion completed successfully.
3128bool
3130{
3131 if (s == "default-visibility")
3132 v = elf_symbol::DEFAULT_VISIBILITY;
3133 else if (s == "protected-visibility")
3134 v = elf_symbol::PROTECTED_VISIBILITY;
3135 else if (s == "hidden-visibility")
3136 v = elf_symbol::HIDDEN_VISIBILITY;
3137 else if (s == "internal-visibility")
3138 v = elf_symbol::INTERNAL_VISIBILITY;
3139 else
3140 return false;
3141
3142 return true;
3143}
3144
3145/// Test if the type of an ELF symbol denotes a function symbol.
3146///
3147/// @param t the type of the ELF symbol.
3148///
3149/// @return true iff elf symbol type @p t denotes a function symbol
3150/// type.
3151bool
3153{return t == elf_symbol::FUNC_TYPE;}
3154
3155/// Test if the type of an ELF symbol denotes a function symbol.
3156///
3157/// @param t the type of the ELF symbol.
3158///
3159/// @return true iff elf symbol type @p t denotes a function symbol
3160/// type.
3161bool
3163{return t == elf_symbol::OBJECT_TYPE;}
3164
3165// <elf_symbol::version stuff>
3166
3167struct elf_symbol::version::priv
3168{
3169 string version_;
3170 bool is_default_;
3171
3172 priv()
3173 : is_default_(false)
3174 {}
3175
3176 priv(const string& v,
3177 bool d)
3178 : version_(v),
3179 is_default_(d)
3180 {}
3181}; // end struct elf_symbol::version::priv
3182
3183elf_symbol::version::version()
3184 : priv_(new priv)
3185{}
3186
3187/// @param v the name of the version.
3188///
3189/// @param is_default true if this is a default version.
3190elf_symbol::version::version(const string& v,
3191 bool is_default)
3192 : priv_(new priv(v, is_default))
3193{}
3194
3195elf_symbol::version::version(const elf_symbol::version& v)
3196 : priv_(new priv(v.str(), v.is_default()))
3197{
3198}
3199
3200elf_symbol::version::~version() = default;
3201
3202/// Cast the version_type into a string that is its name.
3203///
3204/// @return the name of the version.
3205elf_symbol::version::operator const string&() const
3206{return priv_->version_;}
3207
3208/// Getter for the version name.
3209///
3210/// @return the version name.
3211const string&
3213{return priv_->version_;}
3214
3215/// Setter for the version name.
3216///
3217/// @param s the version name.
3218void
3220{priv_->version_ = s;}
3221
3222/// Getter for the 'is_default' property of the version.
3223///
3224/// @return true iff this is a default version.
3225bool
3227{return priv_->is_default_;}
3228
3229/// Setter for the 'is_default' property of the version.
3230///
3231/// @param f true if this is the default version.
3232void
3234{priv_->is_default_ = f;}
3235
3236bool
3237elf_symbol::version::is_empty() const
3238{return str().empty();}
3239
3240/// Compares the current version against another one.
3241///
3242/// @param o the other version to compare the current one to.
3243///
3244/// @return true iff the current version equals @p o.
3245bool
3247{return str() == o.str();}
3248
3249/// Inequality operator.
3250///
3251/// @param o the version to compare against the current one.
3252///
3253/// @return true iff both versions are different.
3254bool
3256{return !operator==(o);}
3257
3258/// Assign a version to the current one.
3259///
3260/// @param o the other version to assign to this one.
3261///
3262/// @return a reference to the assigned version.
3265{
3266 str(o.str());
3267 is_default(o.is_default());
3268 return *this;
3269}
3270
3271// </elf_symbol::version stuff>
3272
3273// </elf_symbol stuff>
3274
3275// <class dm_context_rel stuff>
3276struct dm_context_rel::priv
3277{
3278 bool is_laid_out_;
3279 size_t offset_in_bits_;
3280 var_decl* anonymous_data_member_;
3281
3282 priv(bool is_static = false)
3283 : is_laid_out_(!is_static),
3284 offset_in_bits_(0),
3285 anonymous_data_member_()
3286 {}
3287
3288 priv(bool is_laid_out, size_t offset_in_bits)
3289 : is_laid_out_(is_laid_out),
3290 offset_in_bits_(offset_in_bits),
3291 anonymous_data_member_()
3292 {}
3293}; //end struct dm_context_rel::priv
3294
3295dm_context_rel::dm_context_rel()
3296 : context_rel(),
3297 priv_(new priv)
3298{}
3299
3300dm_context_rel::dm_context_rel(scope_decl* s,
3301 bool is_laid_out,
3302 size_t offset_in_bits,
3304 bool is_static)
3305 : context_rel(s, a, is_static),
3306 priv_(new priv(is_laid_out, offset_in_bits))
3307{}
3308
3309dm_context_rel::dm_context_rel(scope_decl* s)
3310 : context_rel(s),
3311 priv_(new priv())
3312{}
3313
3314bool
3315dm_context_rel::get_is_laid_out() const
3316{return priv_->is_laid_out_;}
3317
3318void
3319dm_context_rel::set_is_laid_out(bool f)
3320{priv_->is_laid_out_ = f;}
3321
3322size_t
3323dm_context_rel::get_offset_in_bits() const
3324{return priv_->offset_in_bits_;}
3325
3326void
3327dm_context_rel::set_offset_in_bits(size_t o)
3328{priv_->offset_in_bits_ = o;}
3329
3330bool
3331dm_context_rel::operator==(const dm_context_rel& o) const
3332{
3333 if (!context_rel::operator==(o))
3334 return false;
3335
3336 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3337 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3338}
3339
3340bool
3341dm_context_rel::operator!=(const dm_context_rel& o) const
3342{return !operator==(o);}
3343
3344/// Return a non-nil value if this data member context relationship
3345/// has an anonymous data member. That means, if the data member this
3346/// relation belongs to is part of an anonymous data member.
3347///
3348/// @return the containing anonymous data member of this data member
3349/// relationship. Nil if there is none.
3350const var_decl*
3352{return priv_->anonymous_data_member_;}
3353
3354/// Set the containing anonymous data member of this data member
3355/// context relationship. That means that the data member this
3356/// relation belongs to is part of an anonymous data member.
3357///
3358/// @param anon_dm the containing anonymous data member of this data
3359/// member relationship. Nil if there is none.
3360void
3362{priv_->anonymous_data_member_ = anon_dm;}
3363
3364dm_context_rel::~dm_context_rel()
3365{}
3366// </class dm_context_rel stuff>
3367
3368// <environment stuff>
3369
3370/// Convenience typedef for a map of interned_string -> bool.
3371typedef unordered_map<interned_string,
3373
3374
3375/// Default constructor of the @ref environment type.
3377 :priv_(new priv)
3378{}
3379
3380/// Destructor for the @ref environment type.
3383
3384/// Getter the map of canonical types.
3385///
3386/// @return the map of canonical types. The key of the map is the
3387/// hash of the canonical type and its value if the canonical type.
3390{return priv_->canonical_types_;}
3391
3392/// Getter the map of canonical types.
3393///
3394/// @return the map of canonical types. The key of the map is the
3395/// hash of the canonical type and its value if the canonical type.
3399
3400/// Helper to detect if a type is either a reference, a pointer, or a
3401/// qualified type.
3402bool
3404{
3405 if (is_pointer_type(t)
3406 || is_reference_type(t)
3407 || is_qualified_type(t))
3408 return true;
3409 return false;
3410}
3411
3412/// Compare decls using their locations.
3413///
3414/// @param f the first decl to compare.
3415///
3416/// @param s the second decl to compare.
3417///
3418/// @return true if @p f compares less than @p s.
3419bool
3421 const decl_base *s)
3422{
3423 // If a decl has artificial location, then use that one over the
3424 // natural one.
3427
3428 ABG_ASSERT(fl.get_value() && sl.get_value());
3429 if (fl.get_is_artificial() == sl.get_is_artificial())
3430 {
3431 // The locations of the two artfifacts have the same
3432 // artificial-ness so they can be compared.
3433 string p1, p2;
3434 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3435 fl.expand(p1, l1, c1);
3436 sl.expand(p2, l2, c2);
3437 if (p1 != p2)
3438 return p1 < p2;
3439 if (l1 != l2)
3440 return l1 < l2;
3441 if (c1 != c2)
3442 return c1 < c2;
3443 }
3444
3445 return (get_pretty_representation(f, /*internal=*/false)
3446 < get_pretty_representation(s, /*internal=*/false));
3447}
3448
3449/// Sort types in a hopefully stable manner.
3450///
3451/// @param types a set of types with canonical types to sort.
3452///
3453/// @param result the resulting sorted vector.
3454void
3456 vector<type_base_sptr>& result)
3457{
3458 for (auto t: types)
3459 result.push_back(t);
3460
3461 type_topo_comp comp;
3462 std::stable_sort(result.begin(), result.end(), comp);
3463}
3464
3465/// Get the unique @ref type_decl that represents a "void" type for
3466/// the current environment. This node must be the only one
3467/// representing a void type in the system.
3468///
3469/// Note that upon first use of this IR node (by the relevant
3470/// front-end, for instance) it must be added to a scope using e.g,
3471/// the @ref add_decl_to_scope() function.
3472///
3473/// @return the @ref type_decl that represents a "void" type.
3474const type_base_sptr&
3476{
3477 if (!priv_->void_type_)
3478 priv_->void_type_.reset(new type_decl(*this,
3479 intern("void"),
3480 0, 0, location()));
3481 return priv_->void_type_;
3482}
3483
3484/// Getter of the "pointer-to-void" IR node that is shared across the
3485/// ABI corpus. This node must be the only one representing a void
3486/// pointer type in the system.
3487///
3488/// Note that upon first use of this IR node (by the relevant
3489/// front-end, for instance) it must be added to a scope using e.g,
3490/// the @ref add_decl_to_scope() function.
3491///
3492/// @return the "pointer-to-void" IR node.
3493const type_base_sptr&
3495{
3496 if (!priv_->void_pointer_type_)
3497 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3498 0, 0, location()));
3499 return priv_->void_pointer_type_;
3500}
3501
3502/// Get a @ref type_decl instance that represents a the type of a
3503/// variadic function parameter. This node must be the only one
3504/// representing a variadic parameter type in the system.
3505///
3506/// Note that upon first use of this IR node (by the relevant
3507/// front-end, for instance) it must be added to a scope using e.g,
3508/// the @ref add_decl_to_scope() function.
3509///
3510/// @return the Get a @ref type_decl instance that represents a the
3511/// type of a variadic function parameter.
3512const type_base_sptr&
3514{
3515 if (!priv_->variadic_marker_type_)
3516 priv_->variadic_marker_type_.
3518 0, 0, location()));
3519 return priv_->variadic_marker_type_;
3520}
3521
3522/// Getter of the name of the variadic parameter type.
3523///
3524/// @return the name of the variadic parameter type.
3525string&
3527{
3528 static string variadic_parameter_type_name = "variadic parameter type";
3529 return variadic_parameter_type_name;
3530}
3531
3532/// Test if the canonicalization of types created out of the current
3533/// environment is done.
3534///
3535/// @return true iff the canonicalization of types created out of the current
3536/// environment is done.
3537bool
3539{return priv_->canonicalization_is_done_;}
3540
3541/// Set a flag saying if the canonicalization of types created out of
3542/// the current environment is done or not.
3543///
3544/// Note that this function must only be called by internal code of
3545/// the library that creates ABI artifacts (e.g, read an abi corpus
3546/// from elf or from our own xml format and creates representations of
3547/// types out of it) and thus needs to canonicalize types to speed-up
3548/// further type comparison.
3549///
3550/// @param f the new value of the flag.
3551void
3553{
3554 priv_->canonicalization_is_done_ = f;
3555 if (priv_->canonicalization_is_done_)
3557}
3558
3559/// Getter of a flag saying if the canonicalization process has
3560/// started or not.
3561///
3562/// @return the flag saying if the canonicalization process has
3563/// started or not.
3564bool
3566{return priv_->canonicalization_started_;}
3567
3568/// Setter of a flag saying if the canonicalization process has
3569/// started or not.
3570///
3571/// @param f the new value of the flag saying if the canonicalization
3572/// process has started or not.
3573void
3575{priv_->canonicalization_started_ = f;}
3576
3577/// Getter of the "decl-only-class-equals-definition" flag.
3578///
3579/// Usually, a declaration-only class named 'struct foo' compares
3580/// equal to any class definition named "struct foo'. This is at
3581/// least true for C++.
3582///
3583/// In C, though, because there can be multiple definitions of 'struct
3584/// foo' in the binary, a declaration-only "struct foo" might be
3585/// considered to *NOT* resolve to any of the struct foo defined. In
3586/// that case, the declaration-only "struct foo" is considered
3587/// different from the definitions.
3588///
3589/// This flag controls the behaviour of the comparison of an
3590/// unresolved decl-only class against a definition of the same name.
3591///
3592/// If set to false, the the declaration equals the definition. If
3593/// set to false, then the decalration is considered different from
3594/// the declaration.
3595///
3596/// @return the value of the "decl-only-class-equals-definition" flag.
3597bool
3599{return priv_->decl_only_class_equals_definition_;}
3600
3601/// Setter of the "decl-only-class-equals-definition" flag.
3602///
3603/// Usually, a declaration-only class named 'struct foo' compares
3604/// equal to any class definition named "struct foo'. This is at
3605/// least true for C++.
3606///
3607/// In C, though, because there can be multiple definitions of 'struct
3608/// foo' in the binary, a declaration-only "struct foo" might be
3609/// considered to *NOT* resolve to any of the struct foo defined. In
3610/// that case, the declaration-only "struct foo" is considered
3611/// different from the definitions.
3612///
3613/// This flag controls the behaviour of the comparison of an
3614/// unresolved decl-only class against a definition of the same name.
3615///
3616/// If set to false, the the declaration equals the definition. If
3617/// set to false, then the decalration is considered different from
3618/// the declaration.
3619///
3620/// @param the new value of the "decl-only-class-equals-definition"
3621/// flag.
3622void
3624{priv_->decl_only_class_equals_definition_ = f;}
3625
3626/// Test if a given type is a void type as defined in the current
3627/// environment.
3628///
3629/// @param t the type to consider.
3630///
3631/// @return true iff @p t is a void type as defined in the current
3632/// environment.
3633bool
3634environment::is_void_type(const type_base_sptr& t) const
3635{
3636 if (!t)
3637 return false;
3638 return is_void_type(t.get());
3639}
3640
3641/// Test if a given type is a void type as defined in the current
3642/// environment.
3643///
3644/// @param t the type to consider.
3645///
3646/// @return true iff @p t is a void type as defined in the current
3647/// environment.
3648bool
3650{
3651 if (!t)
3652 return false;
3653 return (t == get_void_type().get()
3654 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3655}
3656
3657/// Test if a given type is the same as the void pointer type of the
3658/// environment.
3659///
3660/// @param t the IR type to test.
3661///
3662/// @return true iff @p t is the void pointer returned by
3663/// environment::get_void_pointer_type().
3664bool
3665environment::is_void_pointer_type(const type_base_sptr& t) const
3666{
3667 if (!t)
3668 return false;
3669
3670 return t.get() == get_void_pointer_type().get();
3671}
3672
3673/// Test if a given type is the same as the void pointer type of the
3674/// environment.
3675///
3676/// @param t the IR type to test.
3677///
3678/// @return true iff @p t is the void pointer returned by
3679/// environment::get_void_pointer_type().
3680bool
3682{
3683 if (!t)
3684 return false;
3685
3686 return t == get_void_pointer_type().get();
3687}
3688
3689/// Test if a type is a variadic parameter type as defined in the
3690/// current environment.
3691///
3692/// @param t the type to consider.
3693///
3694/// @return true iff @p t is a variadic parameter type as defined in
3695/// the current environment.
3696bool
3698{
3699 if (!t)
3700 return false;
3701 return t == get_variadic_parameter_type().get();
3702}
3703
3704/// Test if a type is a variadic parameter type as defined in the
3705/// current environment.
3706///
3707/// @param t the type to consider.
3708///
3709/// @return true iff @p t is a variadic parameter type as defined in
3710/// the current environment.
3711bool
3712environment::is_variadic_parameter_type(const type_base_sptr& t) const
3713{return is_variadic_parameter_type(t.get());}
3714
3715/// Do intern a string.
3716///
3717/// If a value of this string already exists in the interned string
3718/// pool of the current environment, then this function returns a new
3719/// interned_string pointing to that already existing string.
3720/// Otherwise, a new string is created, stored in the interned string
3721/// pool and a new interned_string instance is created to point to
3722/// that new intrerned string, and it's return.
3723///
3724/// @param s the value of the string to intern.
3725///
3726/// @return the interned string.
3728environment::intern(const string& s) const
3729{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3730
3731/// Getter of the general configuration object.
3732///
3733/// @return the configuration object.
3734const config&
3736{return priv_->config_;}
3737
3738/// Getter for a property that says if the user actually did set the
3739/// analyze_exported_interfaces_only() property. If not, it means
3740/// the default behaviour prevails.
3741///
3742/// @return tru iff the user did set the
3743/// analyze_exported_interfaces_only() property.
3744bool
3746{return priv_->analyze_exported_interfaces_only_.has_value();}
3747
3748/// Setter for the property that controls if we are to restrict the
3749/// analysis to the types that are only reachable from the exported
3750/// interfaces only, or if the set of types should be more broad than
3751/// that. Typically, we'd restrict the analysis to types reachable
3752/// from exported interfaces only (stricto sensu, that would really be
3753/// only the types that are part of the ABI of well designed
3754/// libraries) for performance reasons.
3755///
3756/// @param f the value of the flag.
3757void
3759{priv_->analyze_exported_interfaces_only_ = f;}
3760
3761/// Getter for the property that controls if we are to restrict the
3762/// analysis to the types that are only reachable from the exported
3763/// interfaces only, or if the set of types should be more broad than
3764/// that. Typically, we'd restrict the analysis to types reachable
3765/// from exported interfaces only (stricto sensu, that would really be
3766/// only the types that are part of the ABI of well designed
3767/// libraries) for performance reasons.
3768///
3769/// @param f the value of the flag.
3770bool
3772{return priv_->analyze_exported_interfaces_only_.value_or(false);}
3773
3774#ifdef WITH_DEBUG_SELF_COMPARISON
3775/// Setter of the corpus of the input corpus of the self comparison
3776/// that takes place when doing "abidw --debug-abidiff <binary>".
3777///
3778/// The first invocation of this function sets the first corpus of the
3779/// self comparison. The second invocation of this very same function
3780/// sets the second corpus of the self comparison. That second corpus
3781/// is supposed to come from the abixml serialization of the first
3782/// corpus.
3783///
3784/// @param c the corpus of the input binary or the corpus of the
3785/// abixml serialization of the initial binary input.
3786void
3787environment::set_self_comparison_debug_input(const corpus_sptr& c)
3788{
3789 self_comparison_debug_is_on(true);
3790 if (priv_->first_self_comparison_corpus_.expired())
3791 priv_->first_self_comparison_corpus_ = c;
3792 else if (priv_->second_self_comparison_corpus_.expired()
3793 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3794 priv_->second_self_comparison_corpus_ = c;
3795}
3796
3797/// Getter for the corpora of the input binary and the intermediate
3798/// abixml of the self comparison that takes place when doing
3799/// 'abidw --debug-abidiff <binary>'.
3800///
3801/// @param first_corpus output parameter that is set to the corpus of
3802/// the input corpus.
3803///
3804/// @param second_corpus output parameter that is set to the corpus of
3805/// the second corpus.
3806void
3807environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3808 corpus_sptr& second_corpus)
3809{
3810 first_corpus = priv_->first_self_comparison_corpus_.lock();
3811 second_corpus = priv_->second_self_comparison_corpus_.lock();
3812}
3813
3814/// Turn on/off the self comparison debug mode.
3815///
3816/// @param f true iff the self comparison debug mode is turned on.
3817void
3818environment::self_comparison_debug_is_on(bool f)
3819{priv_->self_comparison_debug_on_ = f;}
3820
3821/// Test if we are in the process of the 'self-comparison
3822/// debugging' as triggered by 'abidw --debug-abidiff' command.
3823///
3824/// @return true if self comparison debug is on.
3825bool
3826environment::self_comparison_debug_is_on() const
3827{return priv_->self_comparison_debug_on_;}
3828#endif
3829
3830#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3831/// Set the "type canonicalization debugging" mode, triggered by using
3832/// the command: "abidw --debug-tc".
3833///
3834/// @param flag if true then the type canonicalization debugging mode
3835/// is enabled.
3836void
3837environment::debug_type_canonicalization_is_on(bool flag)
3838{priv_->debug_type_canonicalization_ = flag;}
3839
3840/// Getter of the "type canonicalization debugging" mode, triggered by
3841/// using the command: "abidw --debug-tc".
3842///
3843/// @return true iff the type canonicalization debugging mode is
3844/// enabled.
3845bool
3846environment::debug_type_canonicalization_is_on() const
3847{return priv_->debug_type_canonicalization_;}
3848
3849/// Setter of the "DIE canonicalization debugging" mode, triggered by
3850/// using the command: "abidw --debug-dc".
3851///
3852/// @param flag true iff the DIE canonicalization debugging mode is
3853/// enabled.
3854void
3855environment::debug_die_canonicalization_is_on(bool flag)
3856{priv_->debug_die_canonicalization_ = flag;}
3857
3858/// Getter of the "DIE canonicalization debugging" mode, triggered by
3859/// using the command: "abidw --debug-dc".
3860///
3861/// @return true iff the DIE canonicalization debugging mode is
3862/// enabled.
3863bool
3864environment::debug_die_canonicalization_is_on() const
3865{return priv_->debug_die_canonicalization_;}
3866#endif // WITH_DEBUG_TYPE_CANONICALIZATION
3867
3868/// Get the vector of canonical types which have a given "string
3869/// representation".
3870///
3871/// @param 'name', the textual representation of the type as returned
3872/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3873/// /*qualified=*/true)
3874///
3875/// This is useful to for debugging purposes as it's handy to use from
3876/// inside a debugger like GDB.
3877///
3878/// @return a pointer to the vector of canonical types having the
3879/// representation @p name, or nullptr if no type with that
3880/// representation exists.
3881const vector<type_base_sptr>*
3883{
3884 auto ti = get_canonical_types_map().find(name);
3885 if (ti == get_canonical_types_map().end())
3886 return nullptr;
3887 return &ti->second;
3888}
3889
3890/// Get a given canonical type which has a given "string
3891/// representation".
3892///
3893/// @param 'name', the textual representation of the type as returned
3894/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3895/// /*qualified=*/true).
3896///
3897/// @param index, the index of the type in the vector of types that
3898/// all have the same textual representation @p 'name'. That vector
3899/// is returned by the function environment::get_canonical_types().
3900///
3901/// @return the canonical type which has the representation @p name,
3902/// and which is at index @p index in the vector of canonical types
3903/// having that same textual representation.
3904type_base*
3905environment::get_canonical_type(const char* name, unsigned index)
3906{
3907 const vector<type_base_sptr> *types = get_canonical_types(name);
3908 if (!types ||index >= types->size())
3909 return nullptr;
3910 return (*types)[index].get();
3911}
3912
3913#ifdef WITH_DEBUG_SELF_COMPARISON
3914/// Get the set of abixml type-id and the pointer value of the
3915/// (canonical) type it's associated to.
3916///
3917/// This is useful for debugging purposes, especially in the context
3918/// of the use of the command:
3919/// 'abidw --debug-abidiff <binary>'.
3920///
3921/// @return the set of abixml type-id and the pointer value of the
3922/// (canonical) type it's associated to.
3923const unordered_map<string, uintptr_t>&
3924environment::get_type_id_canonical_type_map() const
3925{return priv_->get_type_id_canonical_type_map();}
3926
3927/// Get the set of abixml type-id and the pointer value of the
3928/// (canonical) type it's associated to.
3929///
3930/// This is useful for debugging purposes, especially in the context
3931/// of the use of the command:
3932/// 'abidw --debug-abidiff <binary>'.
3933///
3934/// @return the set of abixml type-id and the pointer value of the
3935/// (canonical) type it's associated to.
3936unordered_map<string, uintptr_t>&
3937environment::get_type_id_canonical_type_map()
3938{return priv_->get_type_id_canonical_type_map();}
3939
3940/// Getter of the map that associates the values of type pointers to
3941/// their type-id strings.
3942///
3943/// Note that this map is populated at abixml reading time, (by
3944/// build_type()) when a given XML element representing a type is
3945/// read into a corresponding abigail::ir::type_base.
3946///
3947/// This is used only for the purpose of debugging the
3948/// self-comparison process. That is, when invoking "abidw
3949/// --debug-abidiff".
3950///
3951/// @return the map that associates the values of type pointers to
3952/// their type-id strings.
3953const unordered_map<uintptr_t, string>&
3954environment::get_pointer_type_id_map() const
3955{return priv_->get_pointer_type_id_map();}
3956
3957/// Getter of the map that associates the values of type pointers to
3958/// their type-id strings.
3959///
3960/// Note that this map is populated at abixml reading time, (by
3961/// build_type()) when a given XML element representing a type is
3962/// read into a corresponding abigail::ir::type_base.
3963///
3964/// This is used only for the purpose of debugging the
3965/// self-comparison process. That is, when invoking "abidw
3966/// --debug-abidiff".
3967///
3968/// @return the map that associates the values of type pointers to
3969/// their type-id strings.
3970unordered_map<uintptr_t, string>&
3971environment::get_pointer_type_id_map()
3972{return priv_->get_pointer_type_id_map();}
3973
3974/// Getter of the type-id that corresponds to the value of a pointer
3975/// to abigail::ir::type_base that was created from the abixml reader.
3976///
3977/// That value is retrieved from the map returned from
3978/// environment::get_pointer_type_id_map().
3979///
3980/// That map is populated at abixml reading time, (by build_type())
3981/// when a given XML element representing a type is read into a
3982/// corresponding abigail::ir::type_base.
3983///
3984/// This is used only for the purpose of debugging the
3985/// self-comparison process. That is, when invoking "abidw
3986/// --debug-abidiff".
3987///
3988/// @return the type-id strings that corresponds
3989string
3990environment::get_type_id_from_pointer(uintptr_t ptr) const
3991{return priv_->get_type_id_from_pointer(ptr);}
3992
3993/// Getter of the type-id that corresponds to the value of an
3994/// abigail::ir::type_base that was created from the abixml reader.
3995///
3996/// That value is retrieved from the map returned from
3997/// environment::get_pointer_type_id_map().
3998///
3999/// That map is populated at abixml reading time, (by build_type())
4000/// when a given XML element representing a type is read into a
4001/// corresponding abigail::ir::type_base.
4002///
4003/// This is used only for the purpose of debugging the
4004/// self-comparison process. That is, when invoking "abidw
4005/// --debug-abidiff".
4006///
4007/// @return the type-id strings that corresponds
4008string
4009environment::get_type_id_from_type(const type_base *t) const
4010{return priv_->get_type_id_from_type(t);}
4011
4012/// Getter of the canonical type of the artifact designated by a
4013/// type-id.
4014///
4015/// That type-id was generated by the abixml writer at the emitting
4016/// time of the abixml file. The corresponding canonical type was
4017/// stored in the map returned by
4018/// environment::get_type_id_canonical_type_map().
4019///
4020/// This is useful for debugging purposes, especially in the context
4021/// of the use of the command:
4022/// 'abidw --debug-abidiff <binary>'.
4023///
4024/// @return the set of abixml type-id and the pointer value of the
4025/// (canonical) type it's associated to.
4026uintptr_t
4027environment::get_canonical_type_from_type_id(const char* type_id) const
4028{return priv_->get_canonical_type_from_type_id(type_id);}
4029#endif
4030
4031// </environment stuff>
4032
4033// <type_or_decl_base stuff>
4034
4035/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
4036/// bitmap type.
4040{
4041 return static_cast<type_or_decl_base::type_or_decl_kind>
4042 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4043}
4044
4045/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4046/// bitmap type.
4050{
4051 l = l | r;
4052 return l;
4053}
4054
4055/// bitwise "AND" operator for the
4056/// type_or_decl_base::type_or_decl_kind bitmap type.
4060{
4061 return static_cast<type_or_decl_base::type_or_decl_kind>
4062 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4063}
4064
4065/// bitwise "A&=" operator for the
4066/// type_or_decl_base::type_or_decl_kind bitmap type.
4070{
4071 l = l & r;
4072 return l;
4073}
4074
4075/// Constructor of @ref type_or_decl_base.
4076///
4077/// @param the environment the current ABI artifact is constructed
4078/// from.
4079///
4080/// @param k the runtime identifier bitmap of the type being built.
4081type_or_decl_base::type_or_decl_base(const environment& e,
4082 enum type_or_decl_kind k)
4083 :priv_(new priv(e, k))
4084{}
4085
4086/// The destructor of the @ref type_or_decl_base type.
4089
4090/// Getter of the flag that says if the artefact is artificial.
4091///
4092/// Being artificial means it was not explicitely mentionned in the
4093/// source code, but was rather artificially created by the compiler
4094/// or libabigail.
4095///
4096/// @return true iff the declaration is artificial.
4097bool
4099{return priv_->is_artificial_;}
4100
4101/// Setter of the flag that says if the artefact is artificial.
4102///
4103/// Being artificial means the artefact was not explicitely
4104/// mentionned in the source code, but was rather artificially created
4105/// by the compiler or by libabigail.
4106///
4107/// @param f the new value of the flag that says if the artefact is
4108/// artificial.
4109void
4111{priv_->is_artificial_ = f;}
4112
4113/// Getter for the "kind" property of @ref type_or_decl_base type.
4114///
4115/// This property holds the identifier bitmap of the runtime type of
4116/// an ABI artifact.
4117///
4118/// @return the runtime type identifier bitmap of the current ABI
4119/// artifact.
4122{return priv_->kind();}
4123
4124/// Setter for the "kind" property of @ref type_or_decl_base type.
4125///
4126/// This property holds the identifier bitmap of the runtime type of
4127/// an ABI artifact.
4128///
4129/// @param the runtime type identifier bitmap of the current ABI
4130/// artifact.
4131void
4133{priv_->kind(k);}
4134
4135/// Getter of the pointer to the runtime type sub-object of the
4136/// current instance.
4137///
4138/// @return the pointer to the runtime type sub-object of the current
4139/// instance.
4140const void*
4142{return priv_->rtti_;}
4143
4144/// Getter of the pointer to the runtime type sub-object of the
4145/// current instance.
4146///
4147/// @return the pointer to the runtime type sub-object of the current
4148/// instance.
4149void*
4151{return priv_->rtti_;}
4152
4153/// Setter of the pointer to the runtime type sub-object of the
4154/// current instance.
4155///
4156/// @param i the new pointer to the runtime type sub-object of the
4157/// current instance.
4158void
4160{
4161 priv_->rtti_ = i;
4162 if (type_base* t = dynamic_cast<type_base*>(this))
4163 priv_->type_or_decl_ptr_ = t;
4164 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4165 priv_->type_or_decl_ptr_ = d;
4166}
4167
4168/// Getter of the pointer to either the type_base sub-object of the
4169/// current instance if it's a type, or to the decl_base sub-object of
4170/// the current instance if it's a decl.
4171///
4172/// @return the pointer to either the type_base sub-object of the
4173/// current instance if it's a type, or to the decl_base sub-object of
4174/// the current instance if it's a decl.
4175const void*
4178
4179/// Getter of the pointer to either the type_base sub-object of the
4180/// current instance if it's a type, or to the decl_base sub-object of
4181/// the current instance if it's a decl.
4182///
4183/// @return the pointer to either the type_base sub-object of the
4184/// current instance if it's a type, or to the decl_base sub-object of
4185/// the current instance if it's a decl.
4186void*
4188{return priv_->type_or_decl_ptr_;}
4189
4190/// Return the hash value of the current IR node.
4191///
4192/// Note that upon the first invocation, this member functions
4193/// computes the hash value and returns it. Subsequent invocations
4194/// just return the hash value that was previously calculated.
4195///
4196/// @return the hash value of the current IR node.
4197hash_t
4199{return priv_->hash_value_;}
4200
4201void
4202type_or_decl_base::set_hash_value(hash_t h) const
4203{priv_->set_hash_value(h);}
4204
4205/// Getter of the environment of the current ABI artifact.
4206///
4207/// @return the environment of the artifact.
4208const environment&
4210{return priv_->env_;}
4211
4212/// Setter of the artificial location of the artificat.
4213///
4214/// The artificial location is a location that was artificially
4215/// generated by libabigail, not generated by the original emitter of
4216/// the ABI meta-data. For instance, when reading an XML element from
4217/// an abixml file, the artificial location is the source location of
4218/// the XML element within the file, not the value of the
4219/// 'location'property that might be carried by the element.
4220///
4221/// Artificial locations might be useful to ensure that abixml emitted
4222/// by the abixml writer are sorted the same way as the input abixml
4223/// read by the reader.
4224///
4225/// @param l the new artificial location.
4226void
4228{priv_->artificial_location_ = l;}
4229
4230/// Getter of the artificial location of the artifact.
4231///
4232/// The artificial location is a location that was artificially
4233/// generated by libabigail, not generated by the original emitter of
4234/// the ABI meta-data. For instance, when reading an XML element from
4235/// an abixml file, the artificial location is the source location of
4236/// the XML element within the file, not the value of the
4237/// 'location'property that might be carried by the element.
4238///
4239/// Artificial locations might be useful to ensure that the abixml
4240/// emitted by the abixml writer is sorted the same way as the input
4241/// abixml read by the reader.
4242///
4243/// @return the new artificial location.
4244location&
4246{return priv_->artificial_location_;}
4247
4248/// Test if the current ABI artifact carries an artificial location.
4249///
4250/// @return true iff the current ABI artifact carries an artificial location.
4251bool
4253{
4254 return (priv_->artificial_location_
4255 && priv_->artificial_location_.get_is_artificial());
4256}
4257
4258/// Get the @ref corpus this ABI artifact belongs to.
4259///
4260/// @return the corpus this ABI artifact belongs to, or nil if it
4261/// belongs to none for now.
4262corpus*
4264{
4266 if (!tu)
4267 return 0;
4268 return tu->get_corpus();
4269}
4270
4271
4272/// Get the @ref corpus this ABI artifact belongs to.
4273///
4274/// @return the corpus this ABI artifact belongs to, or nil if it
4275/// belongs to none for now.
4276const corpus*
4278{return const_cast<type_or_decl_base*>(this)->get_corpus();}
4279
4280/// Set the @ref translation_unit this ABI artifact belongs to.
4281///
4282/// Note that adding an ABI artifact to a containining on should
4283/// invoke this member function.
4284void
4286{priv_->translation_unit_ = tu;}
4287
4288
4289/// Get the @ref translation_unit this ABI artifact belongs to.
4290///
4291/// @return the translation unit this ABI artifact belongs to, or nil
4292/// if belongs to none for now.
4295{return priv_->translation_unit_;}
4296
4297/// Get the @ref translation_unit this ABI artifact belongs to.
4298///
4299/// @return the translation unit this ABI artifact belongs to, or nil
4300/// if belongs to none for now.
4301const translation_unit*
4304
4305/// Traverse the the ABI artifact.
4306///
4307/// @param v the visitor used to traverse the sub-tree nodes of the
4308/// artifact.
4309bool
4312
4313/// Non-member equality operator for the @type_or_decl_base type.
4314///
4315/// @param lr the left-hand operand of the equality.
4316///
4317/// @param rr the right-hand operatnr of the equality.
4318///
4319/// @return true iff @p lr equals @p rr.
4320bool
4322{
4323 const type_or_decl_base* l = &lr;
4324 const type_or_decl_base* r = &rr;
4325
4326 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4327 *dr = dynamic_cast<const decl_base*>(r);
4328
4329 if (!!dl != !!dr)
4330 return false;
4331
4332 if (dl && dr)
4333 return *dl == *dr;
4334
4335 const type_base* tl = dynamic_cast<const type_base*>(l),
4336 *tr = dynamic_cast<const type_base*>(r);
4337
4338 if (!!tl != !!tr)
4339 return false;
4340
4341 if (tl && tr)
4342 return *tl == *tr;
4343
4344 return false;
4345}
4346
4347/// Non-member equality operator for the @type_or_decl_base type.
4348///
4349/// @param l the left-hand operand of the equality.
4350///
4351/// @param r the right-hand operatnr of the equality.
4352///
4353/// @return true iff @p l equals @p r.
4354bool
4356{
4357 if (!! l != !!r)
4358 return false;
4359
4360 if (!l)
4361 return true;
4362
4363 return *r == *l;
4364}
4365
4366/// Non-member inequality operator for the @type_or_decl_base type.
4367///
4368/// @param l the left-hand operand of the equality.
4369///
4370/// @param r the right-hand operator of the equality.
4371///
4372/// @return true iff @p l is different from @p r.
4373bool
4376
4377// </type_or_decl_base stuff>
4378
4379// <Decl definition>
4380
4381struct decl_base::priv
4382{
4383 bool in_pub_sym_tab_;
4384 bool is_anonymous_;
4385 location location_;
4386 context_rel *context_;
4387 interned_string name_;
4388 interned_string qualified_parent_name_;
4389 // This temporary qualified name is the cache used for the qualified
4390 // name before the type associated to this decl (if applicable) is
4391 // canonicalized. Once the type is canonicalized, the cached use is
4392 // the data member qualified_parent_name_ above.
4393 interned_string temporary_qualified_name_;
4394 // This is the fully qualified name of the decl. It contains the
4395 // name of the decl and the qualified name of its scope. So if in
4396 // the parent scopes of the decl, there is one anonymous struct,
4397 // somewhere in the name, there is going to by an
4398 // __anonymous_struct__ string, even if the anonymous struct is not
4399 // the direct containing scope of this decl.
4400 interned_string qualified_name_;
4401 interned_string temporary_internal_qualified_name_;
4402 interned_string internal_qualified_name_;
4403 interned_string internal_cached_repr_;
4404 interned_string cached_repr_;
4405 // Unline qualified_name_, scoped_name_ contains the name of the
4406 // decl and the name of its scope; not the qualified name of the
4407 // scope.
4408 interned_string scoped_name_;
4409 interned_string linkage_name_;
4410 visibility visibility_;
4411 decl_base_sptr declaration_;
4412 decl_base_wptr definition_of_declaration_;
4413 decl_base* naked_definition_of_declaration_;
4414 bool is_declaration_only_;
4415 typedef_decl_sptr naming_typedef_;
4416
4417 priv()
4418 : in_pub_sym_tab_(false),
4419 is_anonymous_(true),
4420 context_(),
4421 visibility_(VISIBILITY_DEFAULT),
4422 naked_definition_of_declaration_(),
4423 is_declaration_only_(false)
4424 {}
4425
4426 priv(interned_string name, interned_string linkage_name, visibility vis)
4427 : in_pub_sym_tab_(false),
4428 context_(),
4429 name_(name),
4430 qualified_name_(name),
4431 linkage_name_(linkage_name),
4432 visibility_(vis),
4433 naked_definition_of_declaration_(),
4434 is_declaration_only_(false)
4435 {
4436 is_anonymous_ = name_.empty();
4437 }
4438
4439 ~priv()
4440 {
4441 delete context_;
4442 }
4443};// end struct decl_base::priv
4444
4445/// Constructor for the @ref decl_base type.
4446///
4447/// @param e the environment the current @ref decl_base is being
4448/// created in.
4449///
4450/// @param name the name of the declaration.
4451///
4452/// @param locus the location where to find the declaration in the
4453/// source code.
4454///
4455/// @param linkage_name the linkage name of the declaration.
4456///
4457/// @param vis the visibility of the declaration.
4458decl_base::decl_base(const environment& e,
4459 const string& name,
4460 const location& locus,
4461 const string& linkage_name,
4462 visibility vis)
4463 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4464 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4465{
4466 set_location(locus);
4467}
4468
4469/// Constructor.
4470///
4471/// @param e the environment this instance of @ref decl_base is
4472/// created in.
4473///
4474/// @param name the name of the declaration being constructed.
4475///
4476/// @param locus the source location of the declaration being constructed.
4477///
4478/// @param linkage_name the linkage name of the declaration being
4479/// constructed.
4480///
4481/// @param vis the visibility of the declaration being constructed.
4482decl_base::decl_base(const environment& e,
4483 const interned_string& name,
4484 const location& locus,
4485 const interned_string& linkage_name,
4486 visibility vis)
4487 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4488 priv_(new priv(name, linkage_name, vis))
4489{
4490 set_location(locus);
4491}
4492
4493/// Constructor for the @ref decl_base type.
4494///
4495///@param environment the environment this instance of @ref decl_base
4496/// is being constructed in.
4497///
4498/// @param l the location where to find the declaration in the source
4499/// code.
4500decl_base::decl_base(const environment& e, const location& l)
4501 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4502 priv_(new priv())
4503{
4504 set_location(l);
4505}
4506
4507/// Getter for the qualified name.
4508///
4509/// Unlike decl_base::get_qualified_name() this doesn't try to update
4510/// the qualified name.
4511///
4512/// @return the qualified name.
4513const interned_string&
4515{return priv_->qualified_name_;}
4516
4517/// Clear the qualified name of this decl.
4518///
4519/// This is useful to ensure that the cache for the qualified name of
4520/// the decl is refreshed right after type canonicalization, for
4521/// instance.
4522void
4524{priv_->qualified_name_.clear();}
4525
4526/// Setter for the qualified name.
4527///
4528/// @param n the new qualified name.
4529void
4531{priv_->qualified_name_ = n;}
4532
4533/// Getter of the temporary qualified name of the current declaration.
4534///
4535/// This temporary qualified name is used as a qualified name cache by
4536/// the type for which this is the declaration (when applicable)
4537/// before the type is canonicalized. Once the type is canonicalized,
4538/// it's the result of decl_base::peek_qualified_name() that becomes
4539/// the qualified name cached.
4540///
4541/// @return the temporary qualified name.
4542const interned_string&
4544{return priv_->temporary_qualified_name_;}
4545
4546/// Setter for the temporary qualified name of the current
4547/// declaration.
4548///
4549///@param n the new temporary qualified name.
4550///
4551/// This temporary qualified name is used as a qualified name cache by
4552/// the type for which this is the declaration (when applicable)
4553/// before the type is canonicalized. Once the type is canonicalized,
4554/// it's the result of decl_base::peek_qualified_name() that becomes
4555/// the qualified name cached.
4556void
4558{priv_->temporary_qualified_name_ = n;}
4559
4560///Getter for the context relationship.
4561///
4562///@return the context relationship for the current decl_base.
4563const context_rel*
4565{return priv_->context_;}
4566
4567///Getter for the context relationship.
4568///
4569///@return the context relationship for the current decl_base.
4572{return priv_->context_;}
4573
4574void
4575decl_base::set_context_rel(context_rel *c)
4576{priv_->context_ = c;}
4577
4578/// Test if the decl is defined in a ELF symbol table as a public
4579/// symbol.
4580///
4581/// @return true iff the decl is defined in a ELF symbol table as a
4582/// public symbol.
4583bool
4585{return priv_->in_pub_sym_tab_;}
4586
4587/// Set the flag saying if this decl is from a symbol that is in
4588/// a public symbols table, defined as public (global or weak).
4589///
4590/// @param f the new flag value.
4591void
4593{priv_->in_pub_sym_tab_ = f;}
4594
4595/// Get the location of a given declaration.
4596///
4597/// The location is an abstraction for the tripplet {file path,
4598/// line, column} that defines where the declaration appeared in the
4599/// source code.
4600///
4601/// To get the value of the tripplet {file path, line, column} from
4602/// the @ref location, you need to use the
4603/// location_manager::expand_location() method.
4604///
4605/// The instance of @ref location_manager that you want is
4606/// accessible from the instance of @ref translation_unit that the
4607/// current instance of @ref decl_base belongs to, via a call to
4608/// translation_unit::get_loc_mgr().
4609///
4610/// @return the location of the current instance of @ref decl_base.
4611const location&
4613{return priv_->location_;}
4614
4615/// Set the location for a given declaration.
4616///
4617/// The location is an abstraction for the tripplet {file path,
4618/// line, column} that defines where the declaration appeared in the
4619/// source code.
4620///
4621/// To create a location from a tripplet {file path, line, column},
4622/// you need to use the method @ref
4623/// location_manager::create_new_location().
4624///
4625/// Note that there can be two kinds of location. An artificial
4626/// location and a non-artificial one. The non-artificial location is
4627/// the one emitted by the original emitter of the ABI artifact, for
4628/// instance, if the ABI artifact comes from debug info, then the
4629/// source location that is present in the debug info represent a
4630/// non-artificial location. When looking at an abixml file on the
4631/// other hand, the value of the 'location' attribute of an XML
4632/// element describing an artifact is the non-artificial location.
4633/// The artificial location is the location (line number from the
4634/// beginning of the file) of the XML element within the abixml file.
4635///
4636/// So, if the location that is being set is artificial, note that the
4637/// type_or_decl_base::has_artificial_location() method of this decl will
4638/// subsequently return true and that artificial location will have to
4639/// be retrieved using type_or_decl_base::get_artificial_location().
4640/// If the location is non-artificial however,
4641/// type_or_decl_base::has_artificial_location() will subsequently
4642/// return false and the non-artificial location will have to be
4643/// retrieved using decl_base::get_location().
4644///
4645/// The instance of @ref location_manager that you want is
4646/// accessible from the instance of @ref translation_unit that the
4647/// current instance of @ref decl_base belongs to, via a call to
4648/// translation_unit::get_loc_mgr().
4649void
4651{
4652 if (l.get_is_artificial())
4654 else
4655 priv_->location_ = l;
4656}
4657
4658/// Setter for the name of the decl.
4659///
4660/// @param n the new name to set.
4661void
4662decl_base::set_name(const string& n)
4663{
4664 priv_->name_ = get_environment().intern(n);
4665 priv_->is_anonymous_ = n.empty();
4666}
4667
4668/// Test if the current declaration is anonymous.
4669///
4670/// Being anonymous means that the declaration was created without a
4671/// name. This can usually happen for enum or struct types.
4672///
4673/// @return true iff the type is anonymous.
4674bool
4676{return priv_->is_anonymous_;}
4677
4678/// Set the "is_anonymous" flag of the current declaration.
4679///
4680/// Being anonymous means that the declaration was created without a
4681/// name. This can usually happen for enum or struct types.
4682///
4683/// @param f the new value of the flag.
4684void
4686{priv_->is_anonymous_ = f;}
4687
4688
4689/// Get the "has_anonymous_parent" flag of the current declaration.
4690///
4691/// Having an anoymous parent means having a anonymous parent scope
4692/// (containing type or namespace) which is either direct or indirect.
4693///
4694/// @return true iff the current decl has a direct or indirect scope
4695/// which is anonymous.
4696bool
4698{
4699 scope_decl *scope = get_scope();
4700 if (!scope)
4701 return false;
4702 return scope->get_is_anonymous();
4703}
4704
4705/// @return the logical "OR" of decl_base::get_is_anonymous() and
4706/// decl_base::get_has_anonymous_parent().
4707bool
4710
4711/// Getter for the naming typedef of the current decl.
4712///
4713/// Consider the C idiom:
4714///
4715/// typedef struct {int member;} foo_type;
4716///
4717/// In that idiom, foo_type is the naming typedef of the anonymous
4718/// struct that is declared.
4719///
4720/// @return the naming typedef, if any. Otherwise, returns nil.
4723{return priv_->naming_typedef_;}
4724
4725/// Set the naming typedef of the current instance of @ref decl_base.
4726///
4727/// Consider the C idiom:
4728///
4729/// typedef struct {int member;} foo_type;
4730///
4731/// In that idiom, foo_type is the naming typedef of the anonymous
4732/// struct that is declared.
4733///
4734/// After completion of this function, the decl will not be considered
4735/// anonymous anymore. It's name is going to be the name of the
4736/// naming typedef.
4737///
4738/// @param typedef_type the new naming typedef.
4739void
4741{
4742 // A naming typedef is usually for an anonymous type.
4744 // Whe the typedef-named decl is saved into abixml, it's
4745 // not anonymous anymore. Its name is the typedef name.
4746 // So when we read it back, we must still be able to
4747 // apply the naming typedef to the decl.
4748 || t->get_name() == get_name());
4749 // Only non canonicalized types can be edited this way.
4750 ABG_ASSERT(is_type(this)
4751 && is_type(this)->get_naked_canonical_type() == nullptr);
4752
4753 priv_->naming_typedef_ = t;
4754 set_name(t->get_name());
4755 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4756 set_qualified_name(get_environment().intern(qualified_name));
4757 set_is_anonymous(false);
4758 // Now that the qualified type of the decl has changed, let's update
4759 // the qualified names of the member types of this decls.
4760 update_qualified_name(this);
4761}
4762
4763/// Getter for the mangled name.
4764///
4765/// @return the new mangled name.
4766const interned_string&
4768{return priv_->linkage_name_;}
4769
4770/// Setter for the linkage name.
4771///
4772/// @param m the new linkage name.
4773void
4775{
4776 const environment& env = get_environment();
4777 priv_->linkage_name_ = env.intern(m);
4778}
4779
4780/// Getter for the visibility of the decl.
4781///
4782/// @return the new visibility.
4785{return priv_->visibility_;}
4786
4787/// Setter for the visibility of the decl.
4788///
4789/// @param v the new visibility.
4790void
4792{priv_->visibility_ = v;}
4793
4794/// Return the type containing the current decl, if any.
4795///
4796/// @return the type that contains the current decl, or NULL if there
4797/// is none.
4800{
4801 if (priv_->context_)
4802 return priv_->context_->get_scope();
4803 return 0;
4804}
4805
4806/// Return a copy of the qualified name of the parent of the current
4807/// decl.
4808///
4809/// @return the newly-built qualified name of the of the current decl.
4810const interned_string&
4812{return priv_->qualified_parent_name_;}
4813
4814/// Getter for the name of the current decl.
4815///
4816/// @return the name of the current decl.
4817const interned_string&
4819{return priv_->name_;}
4820
4821/// Compute the qualified name of the decl.
4822///
4823/// @param qn the resulting qualified name.
4824///
4825/// @param internal set to true if the call is intended for an
4826/// internal use (for technical use inside the library itself), false
4827/// otherwise. If you don't know what this is for, then set it to
4828/// false.
4829void
4831{qn = get_qualified_name(internal);}
4832
4833/// Get the pretty representatin of the current declaration.
4834///
4835///
4836/// @param internal set to true if the call is intended to get a
4837/// representation of the decl (or type) for the purpose of canonical
4838/// type comparison. This is mainly used in the function
4839/// type_base::get_canonical_type_for().
4840///
4841/// In other words if the argument for this parameter is true then the
4842/// call is meant for internal use (for technical use inside the
4843/// library itself), false otherwise. If you don't know what this is
4844/// for, then set it to false.
4845///
4846/// @param qualified_name if true, names emitted in the pretty
4847/// representation are fully qualified.
4848///
4849/// @return the default pretty representation for a decl. This is
4850/// basically the fully qualified name of the decl optionally prefixed
4851/// with a meaningful string to add context for the user.
4852string
4854 bool qualified_name) const
4855{
4856 if (internal
4857 && get_is_anonymous()
4858 && has_generic_anonymous_internal_type_name(this))
4859 {
4860 // We are looking at an anonymous enum, union or class and we
4861 // want an *internal* pretty representation for it. All
4862 // anonymous types of this kind in the same namespace must have
4863 // the same internal representation for type canonicalization to
4864 // work properly.
4865 //
4866 // OK, in practise, we are certainly looking at an enum because
4867 // classes and unions should have their own overloaded virtual
4868 // member function for this.
4869 string name = get_generic_anonymous_internal_type_name(this);
4870 if (qualified_name && !get_qualified_parent_name().empty())
4871 name = get_qualified_parent_name() + "::" + name;
4872 return name;
4873 }
4874
4875 if (qualified_name)
4876 return get_qualified_name(internal);
4877 return get_name();
4878}
4879
4880/// Get the pretty representation of the current decl.
4881///
4882/// The pretty representation is retrieved from a cache. If the cache
4883/// is empty, this function computes the pretty representation, put it
4884/// in the cache and returns it.
4885///
4886/// Please note that if this function is called too early in the life
4887/// cycle of the decl (before it is fully constructed), then the
4888/// pretty representation that is cached is going to represent a
4889/// non-complete (and thus wrong) representation of the decl. Thus
4890/// this function must be called only once the decl is fully
4891/// constructed.
4892///
4893/// @param internal if true, then the pretty representation is to be
4894/// used for purpuses that are internal to the libabigail library
4895/// itself. If you don't know what this means, then you probably
4896/// should set this parameter to "false".
4897///
4898/// @return a reference to a cached @ref interned_string holding the
4899/// pretty representation of the current decl.
4900const interned_string&
4902{
4903 if (internal)
4904 {
4905 if (priv_->internal_cached_repr_.empty())
4906 {
4907 string r = ir::get_pretty_representation(this, internal);
4908 priv_->internal_cached_repr_ = get_environment().intern(r);
4909 }
4910 return priv_->internal_cached_repr_;
4911 }
4912
4913 if (priv_->cached_repr_.empty())
4914 {
4915 string r = ir::get_pretty_representation(this, internal);
4916 priv_->cached_repr_ = get_environment().intern(r);
4917 }
4918
4919 return priv_->cached_repr_;
4920}
4921
4922/// Return the qualified name of the decl.
4923///
4924/// This is the fully qualified name of the decl. It's made of the
4925/// concatenation of the name of the decl with the qualified name of
4926/// its scope.
4927///
4928/// Note that the value returned by this function is computed by @ref
4929/// update_qualified_name when the decl is added to its scope.
4930///
4931/// @param internal set to true if the call is intended for an
4932/// internal use (for technical use inside the library itself), false
4933/// otherwise. If you don't know what this is for, then set it to
4934/// false.
4935///
4936/// @return the resulting qualified name.
4937const interned_string&
4938decl_base::get_qualified_name(bool /*internal*/) const
4939{return priv_->qualified_name_;}
4940
4941/// Return the scoped name of the decl.
4942///
4943/// This is made of the concatenation of the name of the decl with the
4944/// name of its scope. It doesn't contain the qualified name of its
4945/// scope, unlike what is returned by decl_base::get_qualified_name.
4946///
4947/// Note that the value returned by this function is computed by @ref
4948/// update_qualified_name when the decl is added to its scope.
4949///
4950/// @return the scoped name of the decl.
4951const interned_string&
4953{return priv_->scoped_name_;}
4954
4955/// If this @ref decl_base is a definition, get its earlier
4956/// declaration.
4957///
4958/// @return the earlier declaration of the class, if any.
4959const decl_base_sptr
4961{return priv_->declaration_;}
4962
4963/// set the earlier declaration of this @ref decl_base definition.
4964///
4965/// @param d the earlier declaration to set. Note that it's set only
4966/// if it's a pure declaration.
4967void
4969{
4970 if (d && d->get_is_declaration_only())
4971 priv_->declaration_ = d;
4972}
4973
4974
4975/// If this @ref decl_base is declaration-only, get its definition, if
4976/// any.
4977///
4978/// @return the definition of this decl-only @ref decl_base.
4979const decl_base_sptr
4981{return priv_->definition_of_declaration_.lock();}
4982
4983/// If this @ref decl_base is declaration-only, get its definition,
4984/// if any.
4985///
4986/// Note that this function doesn't return a smart pointer, but rather
4987/// the underlying pointer managed by the smart pointer. So it's as
4988/// fast as possible. This getter is to be used in code paths that
4989/// are proven to be performance hot spots; especially, when comparing
4990/// sensitive types like enums, classes or unions. Those are compared
4991/// extremely frequently and thus, their access to the definition of
4992/// declaration must be fast.
4993///
4994/// @return the definition of the declaration.
4995const decl_base*
4997{return priv_->naked_definition_of_declaration_;}
4998
4999/// Test if a @ref decl_base is a declaration-only decl.
5000///
5001/// @return true iff the current @ref decl_base is declaration-only.
5002bool
5004{return priv_->is_declaration_only_;}
5005
5006/// Set a flag saying if the @ref enum_type_decl is a declaration-only
5007/// @ref enum_type_decl.
5008///
5009/// @param f true if the @ref enum_type_decl is a declaration-only
5010/// @ref enum_type_decl.
5011void
5013{
5014 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
5015
5016 priv_->is_declaration_only_ = f;
5017
5018 if (update_types_lookup_map)
5019 if (scope_decl* s = get_scope())
5020 {
5021 scope_decl::declarations::iterator i;
5022 if (s->find_iterator_for_member(this, i))
5024 else
5026 }
5027}
5028
5031{
5032 return static_cast<change_kind>(static_cast<unsigned>(l)
5033 | static_cast<unsigned>(r));
5034}
5035
5038{
5039 return static_cast<change_kind>(static_cast<unsigned>(l)
5040 & static_cast<unsigned>(r));
5041}
5042
5045{
5046 l = l | r;
5047 return l;
5048}
5049
5052{
5053 l = l & r;
5054 return l;
5055}
5056
5057/// Compare the properties that belong to the "is-a-member-relation"
5058/// of a decl.
5059///
5060/// For instance, access specifiers are part of the
5061/// "is-a-member-relation" of a decl.
5062///
5063/// This comparison however doesn't take decl names into account. So
5064/// typedefs for instance are decls that we want to compare with this
5065/// function.
5066///
5067/// This function is a sub-routine of the more general 'equals'
5068/// overload for instances of decl_base.
5069///
5070/// @param l the left-hand side operand of the comparison.
5071///
5072/// @param r the right-hand side operand of the comparison.
5073///
5074/// @return true iff @p l compare equals, as a member decl, to @p r.
5075bool
5077 const decl_base& r,
5078 change_kind* k)
5079{
5080 bool result = true;
5081 if (is_member_decl(l) && is_member_decl(r))
5082 {
5083 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
5084 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
5085
5086 access_specifier la = no_access, ra = no_access;
5087 bool member_types_or_functions =
5088 ((is_type(l) && is_type(r))
5089 || (is_function_decl(l) && is_function_decl(r)));
5090
5091 if (member_types_or_functions)
5092 {
5093 // Access specifiers on member types in DWARF is not
5094 // reliable; in the same DSO, the same struct can be either
5095 // a class or a struct, and the access specifiers of its
5096 // member types are not necessarily given, so they
5097 // effectively can be considered differently, again, in the
5098 // same DSO. So, here, let's avoid considering those!
5099 // during comparison.
5100 la = r1->get_access_specifier();
5101 ra = r2->get_access_specifier();
5102 r1->set_access_specifier(no_access);
5103 r2->set_access_specifier(no_access);
5104 }
5105
5106 bool rels_are_different = *r1 != *r2;
5107
5108 if (member_types_or_functions)
5109 {
5110 // restore the access specifiers.
5111 r1->set_access_specifier(la);
5112 r2->set_access_specifier(ra);
5113 }
5114
5115 if (rels_are_different)
5116 {
5117 result = false;
5118 if (k)
5120 }
5121 }
5122 ABG_RETURN(result);
5123}
5124
5125/// Compares two instances of @ref decl_base.
5126///
5127/// If the two intances are different, set a bitfield to give some
5128/// insight about the kind of differences there are.
5129///
5130/// @param l the first artifact of the comparison.
5131///
5132/// @param r the second artifact of the comparison.
5133///
5134/// @param k a pointer to a bitfield that gives information about the
5135/// kind of changes there are between @p l and @p r. This one is set
5136/// iff it's non-null and if the function returns false.
5137///
5138/// Please note that setting k to a non-null value does have a
5139/// negative performance impact because even if @p l and @p r are not
5140/// equal, the function keeps up the comparison in order to determine
5141/// the different kinds of ways in which they are different.
5142///
5143/// @return true if @p l equals @p r, false otherwise.
5144bool
5145equals(const decl_base& l, const decl_base& r, change_kind* k)
5146{
5147 bool result = true;
5148 const interned_string &l_linkage_name = l.get_linkage_name();
5149 const interned_string &r_linkage_name = r.get_linkage_name();
5150 if (!l_linkage_name.empty() && !r_linkage_name.empty())
5151 {
5152 if (l_linkage_name != r_linkage_name)
5153 {
5154 // Linkage names are different. That usually means the two
5155 // decls are different, unless we are looking at two
5156 // function declarations which have two different symbols
5157 // that are aliases of each other.
5158 const function_decl *f1 = is_function_decl(&l),
5159 *f2 = is_function_decl(&r);
5160 if (f1 && f2 && function_decls_alias(*f1, *f2))
5161 ;// The two functions are aliases, so they are not
5162 // different.
5163 else
5164 {
5165 result = false;
5166 if (k)
5168 else
5170 }
5171 }
5172 }
5173
5174 if (r.get_is_anonymous() && l.get_is_anonymous())
5175 // We are looking at too anonymous types (or two members of
5176 // anonymous types) with one not yet been added to the IR. That
5177 // means we want to compare just the object part of the
5178 // anonymous type and not their qualified names. This is used
5179 // when looking up an anonymous type inside a class type.
5180 ABG_RETURN(result);
5181
5182 // This is the name of the decls that we want to compare.
5183 interned_string ln = l.get_name(), rn = r.get_name();
5184
5185 /// If both of the current decls have an anonymous scope then let's
5186 /// compare their name component by component by properly handling
5187 /// anonymous scopes. That's the slow path.
5188 ///
5189 /// Otherwise, let's just compare their name, the obvious way.
5190 /// That's the fast path because in that case the names are
5191 /// interned_string and comparing them is much faster.
5192 bool decls_are_same = (ln == rn);
5193
5194 if (!decls_are_same)
5195 {
5196 result = false;
5197 if (k)
5199 else
5201 }
5202
5203 result &= maybe_compare_as_member_decls(l, r, k);
5204
5205 ABG_RETURN(result);
5206}
5207
5208/// Return true iff the two decls have the same name.
5209///
5210/// This function doesn't test if the scopes of the the two decls are
5211/// equal.
5212///
5213/// Note that this virtual function is to be implemented by classes
5214/// that extend the \p decl_base class.
5215bool
5217{return equals(*this, other, 0);}
5218
5219/// Inequality operator.
5220///
5221/// @param other to other instance of @ref decl_base to compare the
5222/// current instance to.
5223///
5224/// @return true iff the current instance of @ref decl_base is
5225/// different from @p other.
5226bool
5228{return !operator==(other);}
5229
5230/// Destructor of the @ref decl_base type.
5232{delete priv_;}
5233
5234/// This implements the ir_traversable_base::traverse pure virtual
5235/// function.
5236///
5237/// @param v the visitor used on the member nodes of the translation
5238/// unit during the traversal.
5239///
5240/// @return true if the entire IR node tree got traversed, false
5241/// otherwise.
5242bool
5244{
5245 // Do nothing in the base class.
5246 return true;
5247}
5248
5249/// Setter of the scope of the current decl.
5250///
5251/// Note that the decl won't hold a reference on the scope. It's
5252/// rather the scope that holds a reference on its members.
5253void
5255{
5256 if (!priv_->context_)
5257 priv_->context_ = new context_rel(scope);
5258 else
5259 priv_->context_->set_scope(scope);
5260}
5261
5262// </decl_base definition>
5263
5264/// Streaming operator for the decl_base::visibility.
5265///
5266/// @param o the output stream to serialize the visibility to.
5267///
5268/// @param v the visibility to serialize.
5269///
5270/// @return the output stream.
5271std::ostream&
5272operator<<(std::ostream& o, decl_base::visibility v)
5273{
5274 string r;
5275 switch (v)
5276 {
5277 case decl_base::VISIBILITY_NONE:
5278 r = "none";
5279 break;
5280 case decl_base::VISIBILITY_DEFAULT:
5281 r = "default";
5282 break;
5283 case decl_base::VISIBILITY_PROTECTED:
5284 r = "protected";
5285 break;
5286 case decl_base::VISIBILITY_HIDDEN:
5287 r = "hidden";
5288 break;
5289 case decl_base::VISIBILITY_INTERNAL:
5290 r = "internal";
5291 break;
5292 }
5293 return o;
5294}
5295
5296/// Streaming operator for decl_base::binding.
5297///
5298/// @param o the output stream to serialize the visibility to.
5299///
5300/// @param b the binding to serialize.
5301///
5302/// @return the output stream.
5303std::ostream&
5304operator<<(std::ostream& o, decl_base::binding b)
5305{
5306 string r;
5307 switch (b)
5308 {
5309 case decl_base::BINDING_NONE:
5310 r = "none";
5311 break;
5312 case decl_base::BINDING_LOCAL:
5313 r = "local";
5314 break;
5315 case decl_base::BINDING_GLOBAL:
5316 r = "global";
5317 break;
5318 case decl_base::BINDING_WEAK:
5319 r = "weak";
5320 break;
5321 }
5322 o << r;
5323 return o;
5324}
5325
5326/// Turn equality of shared_ptr of decl_base into a deep equality;
5327/// that is, make it compare the pointed to objects, not just the
5328/// pointers.
5329///
5330/// @param l the shared_ptr of decl_base on left-hand-side of the
5331/// equality.
5332///
5333/// @param r the shared_ptr of decl_base on right-hand-side of the
5334/// equality.
5335///
5336/// @return true if the decl_base pointed to by the shared_ptrs are
5337/// equal, false otherwise.
5338bool
5339operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5340{
5341 if (l.get() == r.get())
5342 return true;
5343 if (!!l != !!r)
5344 return false;
5345
5346 return *l == *r;
5347}
5348
5349/// Inequality operator of shared_ptr of @ref decl_base.
5350///
5351/// This is a deep equality operator, that is, it compares the
5352/// pointed-to objects, rather than just the pointers.
5353///
5354/// @param l the left-hand-side operand.
5355///
5356/// @param r the right-hand-side operand.
5357///
5358/// @return true iff @p l is different from @p r.
5359bool
5360operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5361{return !operator==(l, r);}
5362
5363/// Turn equality of shared_ptr of type_base into a deep equality;
5364/// that is, make it compare the pointed to objects too.
5365///
5366/// @param l the shared_ptr of type_base on left-hand-side of the
5367/// equality.
5368///
5369/// @param r the shared_ptr of type_base on right-hand-side of the
5370/// equality.
5371///
5372/// @return true if the type_base pointed to by the shared_ptrs are
5373/// equal, false otherwise.
5374bool
5375operator==(const type_base_sptr& l, const type_base_sptr& r)
5376{
5377 if (l.get() == r.get())
5378 return true;
5379 if (!!l != !!r)
5380 return false;
5381
5382 return *l == *r;
5383}
5384
5385/// Turn inequality of shared_ptr of type_base into a deep equality;
5386/// that is, make it compare the pointed to objects..
5387///
5388/// @param l the shared_ptr of type_base on left-hand-side of the
5389/// equality.
5390///
5391/// @param r the shared_ptr of type_base on right-hand-side of the
5392/// equality.
5393///
5394/// @return true iff the type_base pointed to by the shared_ptrs are
5395/// different.
5396bool
5397operator!=(const type_base_sptr& l, const type_base_sptr& r)
5398{return !operator==(l, r);}
5399
5400/// Tests if a declaration has got a scope.
5401///
5402/// @param d the declaration to consider.
5403///
5404/// @return true if the declaration has got a scope, false otherwise.
5405bool
5407{return (d.get_scope());}
5408
5409/// Tests if a declaration has got a scope.
5410///
5411/// @param d the declaration to consider.
5412///
5413/// @return true if the declaration has got a scope, false otherwise.
5414bool
5415has_scope(const decl_base_sptr d)
5416{return has_scope(*d.get());}
5417
5418/// Tests if a declaration is a class member.
5419///
5420/// @param d the declaration to consider.
5421///
5422/// @return true if @p d is a class member, false otherwise.
5423bool
5424is_member_decl(const decl_base_sptr d)
5425{return is_at_class_scope(d) || is_method_decl(d);}
5426
5427/// Tests if a declaration is a class member.
5428///
5429/// @param d the declaration to consider.
5430///
5431/// @return true if @p d is a class member, false otherwise.
5432bool
5435
5436/// Tests if a declaration is a class member.
5437///
5438/// @param d the declaration to consider.
5439///
5440/// @return true if @p d is a class member, false otherwise.
5441bool
5444
5445/// Test if a declaration is a @ref scope_decl.
5446///
5447/// @param d the declaration to take in account.
5448///
5449/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5450/// if d is a @ref scope_decl.
5451const scope_decl*
5453{return dynamic_cast<const scope_decl*>(d);}
5454
5455/// Test if a declaration is a @ref scope_decl.
5456///
5457/// @param d the declaration to take in account.
5458///
5459/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5460/// if d is a @ref scope_decl.
5462is_scope_decl(const decl_base_sptr& d)
5463{return dynamic_pointer_cast<scope_decl>(d);}
5464
5465/// Tests if a type is a class member.
5466///
5467/// @param t the type to consider.
5468///
5469/// @return true if @p t is a class member type, false otherwise.
5470bool
5471is_member_type(const type_base_sptr& t)
5472{
5473 decl_base_sptr d = get_type_declaration(t);
5474 return is_member_decl(d);
5475}
5476
5477/// Test if a type is user-defined.
5478///
5479/// A type is considered user-defined if it's a
5480/// struct/class/union/enum that is *NOT* artificial.
5481///
5482/// @param t the type to consider.
5483///
5484/// @return true iff the type @p t is user-defined.
5485bool
5487{
5488 if (t == 0)
5489 return false;
5490
5492 decl_base *d = is_decl(t);
5493
5495 && d && !d->get_is_artificial())
5496 return true;
5497
5498 return false;
5499}
5500
5501/// Test if a type is user-defined.
5502///
5503/// A type is considered user-defined if it's a
5504/// struct/class/union/enum.
5505///
5506///
5507/// @param t the type to consider.
5508///
5509/// @return true iff the type @p t is user-defined.
5510bool
5511is_user_defined_type(const type_base_sptr& t)
5512{return is_user_defined_type(t.get());}
5513
5514/// Gets the access specifier for a class member.
5515///
5516/// @param d the declaration of the class member to consider. Note
5517/// that this must be a class member otherwise the function aborts the
5518/// current process.
5519///
5520/// @return the access specifier for the class member @p d.
5523{
5525
5526 const context_rel* c = d.get_context_rel();
5527 ABG_ASSERT(c);
5528
5529 return c->get_access_specifier();
5530}
5531
5532/// Gets the access specifier for a class member.
5533///
5534/// @param d the declaration of the class member to consider. Note
5535/// that this must be a class member otherwise the function aborts the
5536/// current process.
5537///
5538/// @return the access specifier for the class member @p d.
5540get_member_access_specifier(const decl_base_sptr& d)
5541{return get_member_access_specifier(*d);}
5542
5543/// Sets the access specifier for a class member.
5544///
5545/// @param d the class member to set the access specifier for. Note
5546/// that this must be a class member otherwise the function aborts the
5547/// current process.
5548///
5549/// @param a the new access specifier to set the class member to.
5550void
5553{
5555
5557 ABG_ASSERT(c);
5558
5559 c->set_access_specifier(a);
5560}
5561
5562/// Sets the access specifier for a class member.
5563///
5564/// @param d the class member to set the access specifier for. Note
5565/// that this must be a class member otherwise the function aborts the
5566/// current process.
5567///
5568/// @param a the new access specifier to set the class member to.
5569void
5570set_member_access_specifier(const decl_base_sptr& d,
5573
5574/// Gets a flag saying if a class member is static or not.
5575///
5576/// @param d the declaration for the class member to consider. Note
5577/// that this must be a class member otherwise the function aborts the
5578/// current process.
5579///
5580/// @return true if the class member @p d is static, false otherwise.
5581bool
5583{
5585
5586 const context_rel* c = d.get_context_rel();
5587 ABG_ASSERT(c);
5588
5589 return c->get_is_static();
5590}
5591
5592/// Gets a flag saying if a class member is static or not.
5593///
5594/// @param d the declaration for the class member to consider. Note
5595/// that this must be a class member otherwise the function aborts the
5596/// current process.
5597///
5598/// @return true if the class member @p d is static, false otherwise.
5599bool
5602
5603/// Gets a flag saying if a class member is static or not.
5604///
5605/// @param d the declaration for the class member to consider. Note
5606/// that this must be a class member otherwise the function aborts the
5607/// current process.
5608///
5609/// @return true if the class member @p d is static, false otherwise.
5610bool
5611get_member_is_static(const decl_base_sptr& d)
5612{return get_member_is_static(*d);}
5613
5614/// Test if a var_decl is a data member.
5615///
5616/// @param v the var_decl to consider.
5617///
5618/// @return true if @p v is data member, false otherwise.
5619bool
5621{return is_at_class_scope(v);}
5622
5623/// Test if a var_decl is a data member.
5624///
5625/// @param v the var_decl to consider.
5626///
5627/// @return true if @p v is data member, false otherwise.
5628bool
5630{return is_data_member(*v);}
5631
5632/// Test if a var_decl is a data member.
5633///
5634/// @param v the var_decl to consider.
5635///
5636/// @return true if @p v is data member, false otherwise.
5637bool
5640
5641/// Test if a decl is a data member.
5642///
5643/// @param d the decl to consider.
5644///
5645/// @return a pointer to the data member iff @p d is a data member, or
5646/// a null pointer.
5648is_data_member(const decl_base_sptr& d)
5649{
5650 if (var_decl_sptr v = is_var_decl(d))
5651 {
5652 if (is_data_member(v))
5653 return v;
5654 }
5655 return var_decl_sptr();
5656}
5657
5658/// Test if a decl is a data member.
5659///
5660/// @param d the decl to consider.
5661///
5662/// @return a pointer to the data member iff @p d is a data member, or
5663/// a null pointer.
5666{
5667 if (var_decl_sptr v = is_var_decl(d))
5668 {
5669 if (is_data_member(v))
5670 return v;
5671 }
5672 return var_decl_sptr();
5673}
5674
5675/// Test if a decl is a data member.
5676///
5677/// @param d the decl to consider.
5678///
5679/// @return a pointer to the data member iff @p d is a data member, or
5680/// a null pointer.
5681var_decl*
5683{
5684 if (var_decl *v = is_var_decl(d))
5685 if (is_data_member(v))
5686 return v;
5687 return 0;
5688}
5689
5690/// Test if a decl is a data member.
5691///
5692/// @param d the decl to consider.
5693///
5694/// @return a pointer to the data member iff @p d is a data member, or
5695/// a null pointer.
5696var_decl*
5698{
5699 if (var_decl *v = is_var_decl(d))
5700 if (is_data_member(v))
5701 return v;
5702 return 0;
5703}
5704
5705/// Get the first non-anonymous data member of a given anonymous data
5706/// member.
5707///
5708/// E.g:
5709///
5710/// struct S
5711/// {
5712/// union // <-- for this anonymous data member, the function
5713/// // returns a.
5714/// {
5715/// int a;
5716/// charb;
5717/// };
5718/// };
5719///
5720/// @return anon_dm the anonymous data member to consider.
5721///
5722/// @return the first non-anonymous data member of @p anon_dm. If no
5723/// data member was found then this function returns @p anon_dm.
5724const var_decl_sptr
5726{
5727 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5728 return anon_dm;
5729
5730 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5731 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5732
5733 if (is_anonymous_data_member(first))
5735
5736 return first;
5737}
5738
5739/// In the context of a given class or union, this function returns
5740/// the data member that is located after a given data member.
5741///
5742/// @param klass the class or union to consider.
5743///
5744/// @param the data member to consider.
5745///
5746/// @return the data member that is located right after @p
5747/// data_member.
5748const var_decl_sptr
5750 const var_decl_sptr &data_member)
5751{
5752 if (!klass ||!data_member)
5753 return var_decl_sptr();
5754
5755 for (class_or_union::data_members::const_iterator it =
5756 klass->get_non_static_data_members().begin();
5757 it != klass->get_non_static_data_members().end();
5758 ++it)
5759 if (**it == *data_member)
5760 {
5761 ++it;
5762 if (it != klass->get_non_static_data_members().end())
5764 break;
5765 }
5766
5767 return var_decl_sptr();
5768}
5769
5770/// In the context of a given class or union, this function returns
5771/// the data member that is located after a given data member.
5772///
5773/// @param klass the class or union to consider.
5774///
5775/// @param the data member to consider.
5776///
5777/// @return the data member that is located right after @p
5778/// data_member.
5779const var_decl_sptr
5780get_next_data_member(const class_or_union_sptr& klass,
5781 const var_decl_sptr &data_member)
5782{return get_next_data_member(klass.get(), data_member);}
5783
5784/// Get the last data member of a class type.
5785///
5786/// @param klass the class type to consider.
5789{return klass.get_non_static_data_members().back();}
5790
5791/// Get the last data member of a class type.
5792///
5793/// @param klass the class type to consider.
5797
5798/// Get the last data member of a class type.
5799///
5800/// @param klass the class type to consider.
5802get_last_data_member(const class_or_union_sptr &klass)
5803{return get_last_data_member(klass.get());}
5804
5805/// Collect all the non-anonymous data members of a class or union type.
5806///
5807/// If the class contains any anonymous data member, this function
5808/// looks through it to collect the non-anonymous data members that it
5809/// contains. The function also looks through the base classes of the
5810/// current type.
5811///
5812/// @param cou the class or union type to consider.
5813///
5814/// @param dms output parameter. This is populated by the function
5815/// with a map containing the non-anonymous data members that were
5816/// collected. The key of the map is the name of the data member.
5817/// This is set iff the function returns true.
5818///
5819/// @return true iff at least one non-anonymous data member was
5820/// collected.
5821bool
5824{
5825 if (!cou)
5826 return false;
5827
5828 bool result = false;
5829 class_decl* klass = is_class_type(cou);
5830 if (klass)
5831 // First look into base classes for data members.
5833 result |= collect_non_anonymous_data_members(base->get_base_class().get(), dms);
5834
5835 // Then look into our data members
5836 for (var_decl_sptr member : cou->get_non_static_data_members())
5837 {
5838 if (is_anonymous_data_member(member))
5839 {
5840 class_or_union_sptr cl = anonymous_data_member_to_class_or_union(member);
5841 ABG_ASSERT(cl);
5842 result |= collect_non_anonymous_data_members(cl.get(), dms);
5843 }
5844 else
5845 {
5846 dms[member->get_name()] = member;
5847 result = true;
5848 }
5849 }
5850 return result;
5851}
5852
5853/// Collect all the non-anonymous data members of a class or union type.
5854///
5855/// If the class contains any anonymous data member, this function
5856/// looks through it to collect the non-anonymous data members that it
5857/// contains. The function also also looks through the base classes
5858/// of the current type.
5859///
5860/// @param cou the class or union type to consider.
5861///
5862/// @param dms output parameter. This is populated by the function
5863/// with a map containing the non-anonymous data members that were
5864/// collected. The key of the map is the name of the data member.
5865/// This is set iff the function returns true.
5866///
5867/// @return true iff at least one non-anonymous data member was
5868/// collected.
5869bool
5871{return collect_non_anonymous_data_members(cou.get(), dms);}
5872
5873/// Test if a decl is an anonymous data member.
5874///
5875/// @param d the decl to consider.
5876///
5877/// @return true iff @p d is an anonymous data member.
5878bool
5881
5882/// Test if a decl is an anonymous data member.
5883///
5884/// @param d the decl to consider.
5885///
5886/// @return the var_decl representing the data member iff @p d is an
5887/// anonymous data member.
5888const var_decl*
5890{
5891 if (const var_decl* v = is_data_member(d))
5892 {
5894 return v;
5895 }
5896 return 0;
5897}
5898
5899/// Test if a decl is an anonymous data member.
5900///
5901/// @param d the decl to consider.
5902///
5903/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5904/// it's an anonymous data member. Otherwise returns a nil pointer.
5905const var_decl*
5907{
5908 if (const var_decl* v = is_data_member(d))
5909 {
5911 return v;
5912 }
5913 return 0;
5914}
5915
5916/// Test if a decl is an anonymous data member.
5917///
5918/// @param d the decl to consider.
5919///
5920/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5921/// it's an anonymous data member. Otherwise returns a nil pointer.
5924{
5925 if (var_decl_sptr v = is_data_member(d))
5926 {
5928 return v;
5929 }
5930 return var_decl_sptr();
5931}
5932
5933/// Test if a decl is an anonymous data member.
5934///
5935/// @param d the decl to consider.
5936///
5937/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5938/// it's an anonymous data member. Otherwise returns a nil pointer.
5940is_anonymous_data_member(const decl_base_sptr& d)
5941{
5942 if (var_decl_sptr v = is_data_member(d))
5943 return is_anonymous_data_member(v);
5944 return var_decl_sptr();
5945}
5946
5947/// Test if a @ref var_decl is an anonymous data member.
5948///
5949/// @param d the @ref var_decl to consider.
5950///
5951/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5952/// it's an anonymous data member. Otherwise returns a nil pointer.
5955{
5956 if (is_anonymous_data_member(d.get()))
5957 return d;
5958 return var_decl_sptr();
5959}
5960
5961/// Test if a @ref var_decl is an anonymous data member.
5962///
5963/// @param d the @ref var_decl to consider.
5964///
5965/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5966/// it's an anonymous data member. Otherwise returns a nil pointer.
5967const var_decl*
5969{
5970 if (d && is_anonymous_data_member(*d))
5971 return d;
5972 return 0;
5973}
5974
5975/// Test if a @ref var_decl is an anonymous data member.
5976///
5977/// @param d the @ref var_decl to consider.
5978///
5979/// @return true iff @p d is an anonymous data member.
5980bool
5982{
5983 return (is_data_member(d)
5984 && d.get_is_anonymous()
5985 && d.get_name().empty()
5987}
5988
5989/// Test if a @ref var_decl is a data member belonging to an anonymous
5990/// type.
5991///
5992/// @param d the @ref var_decl to consider.
5993///
5994/// @return true iff @p d is a data member belonging to an anonymous
5995/// type.
5996bool
5998{
5999 if (is_data_member(d))
6000 {
6001 scope_decl* scope = d.get_scope();
6002 if (scope && scope->get_is_anonymous())
6003 return true;
6004 }
6005 return false;
6006}
6007
6008/// Test if a @ref var_decl is a data member belonging to an anonymous
6009/// type.
6010///
6011/// @param d the @ref var_decl to consider.
6012///
6013/// @return true iff @p d is a data member belonging to an anonymous
6014/// type.
6015bool
6018
6019/// Test if a @ref var_decl is a data member belonging to an anonymous
6020/// type.
6021///
6022/// @param d the @ref var_decl to consider.
6023///
6024/// @return true iff @p d is a data member belonging to an anonymous
6025/// type.
6026bool
6029
6030/// Get the @ref class_or_union type of a given anonymous data member.
6031///
6032/// @param d the anonymous data member to consider.
6033///
6034/// @return the @ref class_or_union type of the anonymous data member
6035/// @p d.
6038{
6039 if ((d = is_anonymous_data_member(d)))
6040 return is_class_or_union_type(d->get_type().get());
6041 return 0;
6042}
6043
6044/// Get the @ref class_or_union type of a given anonymous data member.
6045///
6046/// @param d the anonymous data member to consider.
6047///
6048/// @return the @ref class_or_union type of the anonymous data member
6049/// @p d.
6050class_or_union_sptr
6052{
6054 return is_class_or_union_type(d.get_type());
6055 return class_or_union_sptr();
6056}
6057
6058/// Test if a data member has annonymous type or not.
6059///
6060/// @param d the data member to consider.
6061///
6062/// @return the anonymous class or union type iff @p turns out to have
6063/// an anonymous type. Otherwise, returns nil.
6064const class_or_union_sptr
6066{
6067 if (is_data_member(d))
6068 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
6069 if (cou->get_is_anonymous())
6070 return cou;
6071
6072 return class_or_union_sptr();
6073}
6074
6075/// Test if a data member has annonymous type or not.
6076///
6077/// @param d the data member to consider.
6078///
6079/// @return the anonymous class or union type iff @p turns out to have
6080/// an anonymous type. Otherwise, returns nil.
6081const class_or_union_sptr
6083{
6084 if (d)
6086 return class_or_union_sptr();
6087}
6088
6089/// Test if a data member has annonymous type or not.
6090///
6091/// @param d the data member to consider.
6092///
6093/// @return the anonymous class or union type iff @p turns out to have
6094/// an anonymous type. Otherwise, returns nil.
6095const class_or_union_sptr
6098
6099/// Get the @ref class_or_union type of a given anonymous data member.
6100///
6101/// @param d the anonymous data member to consider.
6102///
6103/// @return the @ref class_or_union type of the anonymous data member
6104/// @p d.
6105class_or_union_sptr
6107{
6109 return is_class_or_union_type(v->get_type());
6110 return class_or_union_sptr();
6111}
6112
6113/// Test if a given anonymous data member exists in a class or union.
6114///
6115/// @param anon_dm the anonymous data member to consider.
6116///
6117/// @param clazz the class to consider.
6118///
6119/// @return true iff @p anon_dm exists in the @clazz.
6120bool
6122 const class_or_union& clazz)
6123{
6124 if (!anon_dm.get_is_anonymous()
6125 || !is_class_or_union_type(anon_dm.get_type()))
6126 return false;
6127
6128 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
6129 ABG_ASSERT(cl);
6130
6131 // Look for the presence of each data member of anon_dm in clazz.
6132 //
6133 // If one data member of anon_dm is not present in clazz, then the
6134 // data member anon_dm is considered to not exist in clazz.
6135 for (auto anon_dm_m : cl->get_non_static_data_members())
6136 {
6137 // If the data member anon_dm_m is not an anonymous data member,
6138 // it's easy to look for it.
6139 if (!is_anonymous_data_member(anon_dm_m))
6140 {
6141 if (!clazz.find_data_member(anon_dm_m->get_name()))
6142 return false;
6143 }
6144 // If anon_dm_m is itself an anonymous data member then recurse
6145 else
6146 {
6147 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
6148 return false;
6149 }
6150 }
6151
6152 return true;
6153}
6154
6155/// Test if a given decl is anonymous or has a naming typedef.
6156///
6157/// @param d the decl to consider.
6158///
6159/// @return true iff @p d is anonymous or has a naming typedef.
6160bool
6162{
6163 if (d.get_is_anonymous() || d.get_naming_typedef())
6164 return true;
6165 return false;
6166}
6167
6168/// Set the offset of a data member into its containing class.
6169///
6170/// @param m the data member to consider.
6171///
6172/// @param o the offset, in bits.
6173void
6175{
6177
6178 dm_context_rel* ctxt_rel =
6179 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6180 ABG_ASSERT(ctxt_rel);
6181
6182 ctxt_rel->set_offset_in_bits(o);
6183}
6184
6185/// Get the offset of a data member.
6186///
6187/// @param m the data member to consider.
6188///
6189/// @return the offset (in bits) of @p m in its containing class.
6190uint64_t
6192{
6194 const dm_context_rel* ctxt_rel =
6195 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6196 ABG_ASSERT(ctxt_rel);
6197 return ctxt_rel->get_offset_in_bits();
6198}
6199
6200/// Get the offset of a data member.
6201///
6202/// @param m the data member to consider.
6203///
6204/// @return the offset (in bits) of @p m in its containing class.
6205uint64_t
6208
6209/// Get the offset of a data member.
6210///
6211/// @param m the data member to consider.
6212///
6213/// @return the offset (in bits) of @p m in its containing class.
6214uint64_t
6215get_data_member_offset(const decl_base_sptr d)
6216{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6217
6218/// Get the offset of the non-static data member that comes after a
6219/// given one.
6220///
6221/// If there is no data member after after the one given to this
6222/// function (maybe because the given one is the last data member of
6223/// the class type) then the function return false.
6224///
6225/// @param klass the class to consider.
6226///
6227/// @param dm the data member before the one we want to retrieve.
6228///
6229/// @param offset out parameter. This parameter is set by the
6230/// function to the offset of the data member that comes right after
6231/// the data member @p dm, iff the function returns true.
6232///
6233/// @return true iff the data member coming right after @p dm was
6234/// found.
6235bool
6237 const var_decl_sptr& dm,
6238 uint64_t& offset)
6239{
6240 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6241 if (!next_dm)
6242 return false;
6243 offset = get_data_member_offset(next_dm);
6244 return true;
6245}
6246
6247/// Get the offset of the non-static data member that comes after a
6248/// given one.
6249///
6250/// If there is no data member after after the one given to this
6251/// function (maybe because the given one is the last data member of
6252/// the class type) then the function return false.
6253///
6254/// @param klass the class to consider.
6255///
6256/// @param dm the data member before the one we want to retrieve.
6257///
6258/// @param offset out parameter. This parameter is set by the
6259/// function to the offset of the data member that comes right after
6260/// the data member @p dm, iff the function returns true.
6261///
6262/// @return true iff the data member coming right after @p dm was
6263/// found.
6264bool
6265get_next_data_member_offset(const class_or_union_sptr& klass,
6266 const var_decl_sptr& dm,
6267 uint64_t& offset)
6268{return get_next_data_member_offset(klass.get(), dm, offset);}
6269
6270/// Get the absolute offset of a data member.
6271///
6272/// If the data member is part of an anonymous data member then this
6273/// returns the absolute offset -- relative to the beginning of the
6274/// containing class of the anonymous data member.
6275///
6276/// @param m the data member to consider.
6277///
6278/// @return the aboslute offset of the data member @p m.
6279uint64_t
6281{
6283 const dm_context_rel* ctxt_rel =
6284 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6285 ABG_ASSERT(ctxt_rel);
6286
6287 const var_decl *containing_anonymous_data_member =
6288 ctxt_rel->get_anonymous_data_member();
6289
6290 uint64_t containing_anonymous_data_member_offset = 0;
6291 if (containing_anonymous_data_member)
6292 containing_anonymous_data_member_offset =
6293 get_absolute_data_member_offset(*containing_anonymous_data_member);
6294
6295 return (ctxt_rel->get_offset_in_bits()
6296 +
6297 containing_anonymous_data_member_offset);
6298}
6299
6300/// Get the absolute offset of a data member.
6301///
6302/// If the data member is part of an anonymous data member then this
6303/// returns the absolute offset -- relative to the beginning of the
6304/// containing class of the anonymous data member.
6305///
6306/// @param m the data member to consider.
6307///
6308/// @return the aboslute offset of the data member @p m.
6309uint64_t
6311{
6312 if (!m)
6313 return 0;
6315}
6316
6317/// Get the size of a given variable.
6318///
6319/// @param v the variable to consider.
6320///
6321/// @return the size of variable @p v.
6322uint64_t
6324{
6325 type_base_sptr t = v->get_type();
6326 ABG_ASSERT(t);
6327
6328 return t->get_size_in_bits();
6329}
6330
6331/// Set a flag saying if a data member is laid out.
6332///
6333/// @param m the data member to consider.
6334///
6335/// @param l true if @p m is to be considered as laid out.
6336void
6338{
6340 dm_context_rel* ctxt_rel =
6341 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6342 ctxt_rel->set_is_laid_out(l);
6343}
6344
6345/// Test whether a data member is laid out.
6346///
6347/// @param m the data member to consider.
6348///
6349/// @return true if @p m is laid out, false otherwise.
6350bool
6352{
6354 const dm_context_rel* ctxt_rel =
6355 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6356
6357 return ctxt_rel->get_is_laid_out();
6358}
6359
6360/// Test whether a data member is laid out.
6361///
6362/// @param m the data member to consider.
6363///
6364/// @return true if @p m is laid out, false otherwise.
6365bool
6368
6369/// Test whether a function_decl is a member function.
6370///
6371/// @param f the function_decl to test.
6372///
6373/// @return true if @p f is a member function, false otherwise.
6374bool
6377
6378/// Test whether a function_decl is a member function.
6379///
6380/// @param f the function_decl to test.
6381///
6382/// @return true if @p f is a member function, false otherwise.
6383bool
6386
6387/// Test whether a function_decl is a member function.
6388///
6389/// @param f the function_decl to test.
6390///
6391/// @return true if @p f is a member function, false otherwise.
6392bool
6395
6396/// Test whether a member function is a constructor.
6397///
6398/// @param f the member function to test.
6399///
6400/// @return true if @p f is a constructor, false otherwise.
6401bool
6403{
6405
6406 const method_decl* m = is_method_decl(&f);
6407 ABG_ASSERT(m);
6408
6409 const mem_fn_context_rel* ctxt =
6410 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6411
6412 return ctxt->is_constructor();
6413}
6414
6415/// Test whether a member function is a constructor.
6416///
6417/// @param f the member function to test.
6418///
6419/// @return true if @p f is a constructor, false otherwise.
6420bool
6423
6424
6425/// Setter for the is_ctor property of the member function.
6426///
6427/// @param f the member function to set.
6428///
6429/// @param f the new boolean value of the is_ctor property. Is true
6430/// if @p f is a constructor, false otherwise.
6431void
6433{
6435
6436 method_decl* m = is_method_decl(&f);
6437 ABG_ASSERT(m);
6438
6439 mem_fn_context_rel* ctxt =
6440 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6441
6442 ctxt->is_constructor(c);
6443}
6444
6445/// Setter for the is_ctor property of the member function.
6446///
6447/// @param f the member function to set.
6448///
6449/// @param f the new boolean value of the is_ctor property. Is true
6450/// if @p f is a constructor, false otherwise.
6451void
6454
6455/// Test whether a member function is a destructor.
6456///
6457/// @param f the function to test.
6458///
6459/// @return true if @p f is a destructor, false otherwise.
6460bool
6462{
6464
6465 const method_decl* m = is_method_decl(&f);
6466 ABG_ASSERT(m);
6467
6468 const mem_fn_context_rel* ctxt =
6469 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6470
6471 return ctxt->is_destructor();
6472}
6473
6474/// Test whether a member function is a destructor.
6475///
6476/// @param f the function to test.
6477///
6478/// @return true if @p f is a destructor, false otherwise.
6479bool
6482
6483/// Set the destructor-ness property of a member function.
6484///
6485/// @param f the function to set.
6486///
6487/// @param d true if @p f is a destructor, false otherwise.
6488void
6490{
6492
6493 method_decl* m = is_method_decl(&f);
6494 ABG_ASSERT(m);
6495
6496 mem_fn_context_rel* ctxt =
6497 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6498
6499 ctxt->is_destructor(d);
6500}
6501
6502/// Set the destructor-ness property of a member function.
6503///
6504/// @param f the function to set.
6505///
6506/// @param d true if @p f is a destructor, false otherwise.
6507void
6510
6511/// Test whether a member function is const.
6512///
6513/// @param f the function to test.
6514///
6515/// @return true if @p f is const, false otherwise.
6516bool
6518{
6520
6521 const method_decl* m = is_method_decl(&f);
6522 ABG_ASSERT(m);
6523
6524 const mem_fn_context_rel* ctxt =
6525 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6526
6527 return ctxt->is_const();
6528}
6529
6530/// Test whether a member function is const.
6531///
6532/// @param f the function to test.
6533///
6534/// @return true if @p f is const, false otherwise.
6535bool
6538
6539/// set the const-ness property of a member function.
6540///
6541/// @param f the function to set.
6542///
6543/// @param is_const the new value of the const-ness property of @p f
6544void
6546{
6548
6549 method_decl* m = is_method_decl(&f);
6550 ABG_ASSERT(m);
6551
6552 mem_fn_context_rel* ctxt =
6553 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6554
6555 ctxt->is_const(is_const);
6556}
6557
6558/// set the const-ness property of a member function.
6559///
6560/// @param f the function to set.
6561///
6562/// @param is_const the new value of the const-ness property of @p f
6563void
6566
6567/// Test if a virtual member function has a vtable offset set.
6568///
6569/// @param f the virtual member function to consider.
6570///
6571/// @return true iff the virtual member function has its vtable offset
6572/// set, i.e, if the vtable offset of @p is different from -1.
6573bool
6576
6577/// Get the vtable offset of a member function.
6578///
6579/// @param f the member function to consider.
6580///
6581/// @return the vtable offset of @p f. Note that a vtable offset of
6582/// value -1 means that the member function does *NOT* yet have a
6583/// vtable offset associated to it.
6584ssize_t
6586{
6588
6589 const method_decl* m =
6590 dynamic_cast<const method_decl*>(&f);
6591 ABG_ASSERT(m);
6592
6593 const mem_fn_context_rel* ctxt =
6594 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6595
6596 return ctxt->vtable_offset();
6597}
6598
6599/// Get the vtable offset of a member function.
6600///
6601/// @param f the member function to consider.
6602///
6603/// @return the vtable offset of @p f. Note that a vtable offset of
6604/// value -1 means that the member function does *NOT* yet have a
6605/// vtable offset associated to it.
6606ssize_t
6609
6610/// Set the vtable offset of a member function.
6611///
6612/// @param f the member function to consider.
6613///
6614/// @param s the new vtable offset. Please note that a vtable offset
6615/// of value -1 means that the virtual member function does not (yet)
6616/// have any vtable offset associated to it.
6617static void
6618set_member_function_vtable_offset(function_decl& f, ssize_t s)
6619{
6621
6622 method_decl* m = is_method_decl(&f);
6623 ABG_ASSERT(m);
6624
6625 mem_fn_context_rel* ctxt =
6626 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6627
6628 ctxt->vtable_offset(s);
6629}
6630
6631/// Get the vtable offset of a member function.
6632///
6633/// @param f the member function to consider.
6634///
6635/// @param s the new vtable offset. Please note that a vtable offset
6636/// of value -1 means that the virtual member function does not (yet)
6637/// have any vtable offset associated to it.
6638static void
6639set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
6640{return set_member_function_vtable_offset(*f, s);}
6641
6642/// Test if a given member function is virtual.
6643///
6644/// @param mem_fn the member function to consider.
6645///
6646/// @return true iff a @p mem_fn is virtual.
6647bool
6649{
6651
6652 const method_decl* m =
6653 dynamic_cast<const method_decl*>(&f);
6654 ABG_ASSERT(m);
6655
6656 const mem_fn_context_rel* ctxt =
6657 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6658
6659 return ctxt->is_virtual();
6660}
6661
6662/// Test if a given member function is virtual.
6663///
6664/// @param mem_fn the member function to consider.
6665///
6666/// @return true iff a @p mem_fn is virtual.
6667bool
6669{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6670
6671/// Test if a given member function is virtual.
6672///
6673/// @param mem_fn the member function to consider.
6674///
6675/// @return true iff a @p mem_fn is virtual.
6676bool
6678{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6679
6680/// Set the virtual-ness of a member function.
6681///
6682/// @param f the member function to consider.
6683///
6684/// @param is_virtual set to true if the function is virtual.
6685static void
6686set_member_function_is_virtual(function_decl& f, bool is_virtual)
6687{
6689
6690 method_decl* m = is_method_decl(&f);
6691 ABG_ASSERT(m);
6692
6693 mem_fn_context_rel* ctxt =
6694 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6695
6696 ctxt->is_virtual(is_virtual);
6697}
6698
6699/// Set the virtual-ness of a member function.
6700///
6701/// @param f the member function to consider.
6702///
6703/// @param is_virtual set to true if the function is virtual.
6704static void
6705set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
6706{
6707 if (fn)
6708 {
6709 set_member_function_is_virtual(*fn, is_virtual);
6711 }
6712}
6713
6714/// Set the virtual-ness of a member fcuntion
6715///
6716/// @param fn the member function to consider.
6717///
6718/// @param is_virtual whether the function is virtual.
6719///
6720/// @param voffset the virtual offset of the virtual function.
6721void
6723 bool is_virtual,
6724 ssize_t voffset)
6725{
6726 // Setting the offset must come first because the second function
6727 // does assume the voffset is set, in case of virtuality
6728 set_member_function_vtable_offset(fn, voffset);
6729 set_member_function_is_virtual(fn, is_virtual);
6730}
6731
6732/// Set the virtual-ness of a member fcuntion
6733///
6734/// @param fn the member function to consider.
6735///
6736/// @param is_virtual whether the function is virtual.
6737///
6738/// @param voffset the virtual offset of the virtual function.
6739void
6741 bool is_virtual,
6742 ssize_t voffset)
6743{
6744 if (fn)
6745 set_member_function_virtuality(*fn, is_virtual, voffset);
6746}
6747
6748/// Set the virtual-ness of a member fcuntion
6749///
6750/// @param fn the member function to consider.
6751///
6752/// @param is_virtual whether the function is virtual.
6753///
6754/// @param voffset the virtual offset of the virtual function.
6755void
6757 bool is_virtual,
6758 ssize_t voffset)
6759{
6760 set_member_function_vtable_offset(fn, voffset);
6761 set_member_function_is_virtual(fn, is_virtual);
6762}
6763
6764/// Recursively returns the the underlying type of a typedef. The
6765/// return type should not be a typedef of anything anymore.
6766///
6767///
6768/// Also recursively strip typedefs from the sub-types of the type
6769/// given in arguments.
6770///
6771/// Note that this function builds types in which typedefs are
6772/// stripped off. Usually, types are held by their scope, so their
6773/// life time is bound to the life time of their scope. But as this
6774/// function cannot really insert the built type into it's scope, it
6775/// must ensure that the newly built type stays live long enough.
6776///
6777/// So, if the newly built type has a canonical type, this function
6778/// returns the canonical type. Otherwise, this function ensure that
6779/// the newly built type has a life time that is the same as the life
6780/// time of the entire libabigail library.
6781///
6782/// @param type the type to strip the typedefs from.
6783///
6784/// @return the resulting type stripped from its typedefs, or just
6785/// return @p type if it has no typedef in any of its sub-types.
6786type_base_sptr
6787strip_typedef(const type_base_sptr type)
6788{
6789 if (!type)
6790 return type;
6791
6792 // If type is a class type then do not try to strip typedefs from it.
6793 // And if it has no canonical type (which can mean that it's a
6794 // declaration-only class), then, make sure its live for ever and
6795 // return it.
6796 if (class_decl_sptr cl = is_class_type(type))
6797 {
6798 if (!cl->get_canonical_type())
6799 keep_type_alive(type);
6800 return type;
6801 }
6802
6803 const environment& env = type->get_environment();
6804 type_base_sptr t = type;
6805
6806 if (const typedef_decl_sptr ty = is_typedef(t))
6807 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6808 else if (const reference_type_def_sptr ty = is_reference_type(t))
6809 {
6810 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6811 env));
6812 ABG_ASSERT(p);
6813 t.reset(new reference_type_def(p,
6814 ty->is_lvalue(),
6815 ty->get_size_in_bits(),
6816 ty->get_alignment_in_bits(),
6817 ty->get_location()));
6818 }
6819 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6820 {
6821 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6822 env));
6823 ABG_ASSERT(p);
6824 t.reset(new pointer_type_def(p,
6825 ty->get_size_in_bits(),
6826 ty->get_alignment_in_bits(),
6827 ty->get_location()));
6828 }
6829 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6830 {
6831 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6832 env));
6833 ABG_ASSERT(p);
6834 t.reset(new qualified_type_def(p,
6835 ty->get_cv_quals(),
6836 ty->get_location()));
6837 }
6838 else if (const array_type_def_sptr ty = is_array_type(t))
6839 {
6840 type_base_sptr p = strip_typedef(ty->get_element_type());
6841 ABG_ASSERT(p);
6842 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6843 }
6844 else if (const method_type_sptr ty = is_method_type(t))
6845 {
6847 for (function_decl::parameters::const_iterator i =
6848 ty->get_parameters().begin();
6849 i != ty->get_parameters().end();
6850 ++i)
6851 {
6853 type_base_sptr typ = strip_typedef(p->get_type());
6854 ABG_ASSERT(typ);
6856 (new function_decl::parameter(typ,
6857 p->get_index(),
6858 p->get_name(),
6859 p->get_location(),
6860 p->get_variadic_marker(),
6861 p->get_is_artificial()));
6862 parm.push_back(stripped);
6863 }
6864 type_base_sptr p = strip_typedef(ty->get_return_type());
6865 ABG_ASSERT(!!p == !!ty->get_return_type());
6866 t.reset(new method_type(p, ty->get_class_type(),
6867 parm, ty->get_is_const(),
6868 ty->get_size_in_bits(),
6869 ty->get_alignment_in_bits()));
6870 }
6871 else if (const function_type_sptr ty = is_function_type(t))
6872 {
6874 for (function_decl::parameters::const_iterator i =
6875 ty->get_parameters().begin();
6876 i != ty->get_parameters().end();
6877 ++i)
6878 {
6880 type_base_sptr typ = strip_typedef(p->get_type());
6881 ABG_ASSERT(typ);
6883 (new function_decl::parameter(typ,
6884 p->get_index(),
6885 p->get_name(),
6886 p->get_location(),
6887 p->get_variadic_marker(),
6888 p->get_is_artificial()));
6889 parm.push_back(stripped);
6890 }
6891 type_base_sptr p = strip_typedef(ty->get_return_type());
6892 ABG_ASSERT(!!p == !!ty->get_return_type());
6893 t.reset(new function_type(p, parm,
6894 ty->get_size_in_bits(),
6895 ty->get_alignment_in_bits()));
6896 }
6897
6898 if (!t->get_translation_unit())
6899 t->set_translation_unit(type->get_translation_unit());
6900
6901 if (!(type->get_canonical_type() && canonicalize(t)))
6902 keep_type_alive(t);
6903
6904 return t->get_canonical_type() ? t->get_canonical_type() : t;
6905}
6906
6907/// Strip qualification from a qualified type, when it makes sense.
6908///
6909/// DWARF constructs "const reference". This is redundant because a
6910/// reference is always const. It also constructs the useless "const
6911/// void" type. The issue is these redundant types then leak into the
6912/// IR and make for bad diagnostics.
6913///
6914/// This function thus strips the const qualifier from the type in
6915/// that case. It might contain code to strip other cases like this
6916/// in the future.
6917///
6918/// @param t the type to strip const qualification from.
6919///
6920/// @return the stripped type or just return @p t.
6921decl_base_sptr
6922strip_useless_const_qualification(const qualified_type_def_sptr t)
6923{
6924 if (!t)
6925 return t;
6926
6927 decl_base_sptr result = t;
6928 type_base_sptr u = t->get_underlying_type();
6929 const environment& env = t->get_environment();
6930
6931 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6932 && (is_reference_type(u)))
6933 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6934 && env.is_void_type(u))
6935 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6936 // Let's strip the const qualifier because a reference is always
6937 // 'const' and a const void doesn't make sense. They will just
6938 // lead to spurious changes later down the pipeline, that we'll
6939 // have to deal with by doing painful and error-prone editing of
6940 // the diff IR. Dropping that useless and inconsistent artefact
6941 // right here seems to be a good way to go.
6942 result = is_decl(u);
6943
6944 return result;
6945}
6946
6947/// Merge redundant qualifiers from a tree of qualified types.
6948///
6949/// Suppose a tree of qualified types leads to:
6950///
6951/// const virtual const restrict const int;
6952///
6953/// Suppose the IR tree of qualified types ressembles (with C meaning
6954/// const, V meaning virtual and R meaning restrict):
6955///
6956/// [C|V]-->[C|R] -->[C] --> [int].
6957///
6958/// This function walks the IR and remove the redundant CV qualifiers
6959/// so the IR becomes:
6960///
6961/// [C|V] --> [R] --> [] -->[int].
6962///
6963/// Note that the empty qualified type (noted []) represents a
6964/// qualified type with no qualifier. It's rare, but it can exist.
6965/// I've put it here just for the sake of example.
6966///
6967/// The resulting IR thus represents the (merged) type:
6968///
6969/// const virtual restrict int.
6970///
6971/// This function is a sub-routine of the overload @ref
6972/// strip_useless_const_qualification which doesn't return any value.
6973///
6974/// @param t the qualified type to consider.
6975///
6976/// @param redundant_quals the (redundant) qualifiers to be removed
6977/// from the qualifiers of the underlying types of @p t.
6978///
6979/// @return the underlying type of @p t which might have had its
6980/// redundant qualifiers removed.
6981static qualified_type_def_sptr
6982strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
6983 qualified_type_def::CV redundant_quals)
6984{
6985 if (!t)
6986 return t;
6987
6988 // We must NOT edit canonicalized types.
6989 ABG_ASSERT(!t->get_canonical_type());
6990
6991 qualified_type_def_sptr underlying_qualified_type =
6992 is_qualified_type(t->get_underlying_type());
6993
6994 // Let's build 'currated qualifiers' that are the qualifiers of the
6995 // current type from which redundant qualifiers are removed.
6996 qualified_type_def::CV currated_quals = t->get_cv_quals();
6997
6998 // Remove the redundant qualifiers from these currated qualifiers
6999 currated_quals &= ~redundant_quals;
7000 t->set_cv_quals(currated_quals);
7001
7002 // The redundant qualifiers, moving forward, is now the union of the
7003 // previous set of redundant qualifiers and the currated qualifiers.
7004 redundant_quals |= currated_quals;
7005
7006 qualified_type_def_sptr result = t;
7007 if (underlying_qualified_type)
7008 // Now remove the redundant qualifiers from the qualified types
7009 // potentially carried by the underlying type.
7010 result =
7011 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
7012 redundant_quals);
7013
7014 return result;
7015}
7016
7017/// Merge redundant qualifiers from a tree of qualified types.
7018///
7019/// Suppose a tree of qualified types leads to:
7020///
7021/// const virtual const restrict const int;
7022///
7023/// Suppose the IR tree of qualified types ressembles (with C meaning
7024/// const, V meaning virtual and R meaning restrict):
7025///
7026/// [C|V]-->[C|R] -->[C] --> [int].
7027///
7028/// This function walks the IR and remove the redundant CV qualifiers
7029/// so the IR becomes:
7030///
7031/// [C|V] --> [R] --> [] -->[int].
7032///
7033/// Note that the empty qualified type (noted []) represents a
7034/// qualified type with no qualifier. It's rare, but it can exist.
7035/// I've put it here just for the sake of example.
7036///
7037/// The resulting IR thus represents the (merged) type:
7038///
7039/// const virtual restrict int.
7040///
7041/// @param t the qualified type to consider. The IR below the
7042/// argument to this parameter will be edited to remove redundant
7043/// qualifiers where applicable.
7044void
7045strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
7046{
7047 if (!t)
7048 return;
7049
7050 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
7051 strip_redundant_quals_from_underyling_types(t, redundant_quals);
7052}
7053
7054/// Return the leaf underlying type node of a @ref typedef_decl node.
7055///
7056/// If the underlying type of a @ref typedef_decl node is itself a
7057/// @ref typedef_decl node, then recursively look at the underlying
7058/// type nodes to get the first one that is not a a @ref typedef_decl
7059/// node. This is what a leaf underlying type node means.
7060///
7061/// Otherwise, if the underlying type node of @ref typedef_decl is
7062/// *NOT* a @ref typedef_decl node, then just return the underlying
7063/// type node.
7064///
7065/// And if the type node considered is not a @ref typedef_decl node,
7066/// then just return it.
7067///
7068/// @return the leaf underlying type node of a @p type.
7069type_base_sptr
7070peel_typedef_type(const type_base_sptr& type)
7071{
7072 typedef_decl_sptr t = is_typedef(type);
7073 if (!t)
7074 return type;
7075
7076 if (is_typedef(t->get_underlying_type()))
7077 return peel_typedef_type(t->get_underlying_type());
7078 return t->get_underlying_type();
7079}
7080
7081/// Return the leaf underlying type node of a @ref typedef_decl node.
7082///
7083/// If the underlying type of a @ref typedef_decl node is itself a
7084/// @ref typedef_decl node, then recursively look at the underlying
7085/// type nodes to get the first one that is not a a @ref typedef_decl
7086/// node. This is what a leaf underlying type node means.
7087///
7088/// Otherwise, if the underlying type node of @ref typedef_decl is
7089/// *NOT* a @ref typedef_decl node, then just return the underlying
7090/// type node.
7091///
7092/// And if the type node considered is not a @ref typedef_decl node,
7093/// then just return it.
7094///
7095/// @return the leaf underlying type node of a @p type.
7096const type_base*
7098{
7099 const typedef_decl* t = is_typedef(type);
7100 if (!t)
7101 return type;
7102
7103 return peel_typedef_type(t->get_underlying_type()).get();
7104}
7105
7106/// Return the leaf pointed-to type node of a @ref pointer_type_def
7107/// node.
7108///
7109/// If the pointed-to type of a @ref pointer_type_def node is itself a
7110/// @ref pointer_type_def node, then recursively look at the
7111/// pointed-to type nodes to get the first one that is not a a @ref
7112/// pointer_type_def node. This is what a leaf pointed-to type node
7113/// means.
7114///
7115/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7116/// *NOT* a @ref pointer_type_def node, then just return the
7117/// pointed-to type node.
7118///
7119/// And if the type node considered is not a @ref pointer_type_def
7120/// node, then just return it.
7121///
7122/// @return the leaf pointed-to type node of a @p type.
7123type_base_sptr
7124peel_pointer_type(const type_base_sptr& type)
7125{
7127 if (!t)
7128 return type;
7129
7130 if (is_pointer_type(t->get_pointed_to_type()))
7131 return peel_pointer_type(t->get_pointed_to_type());
7132 return t->get_pointed_to_type();
7133}
7134
7135/// Return the leaf pointed-to type node of a @ref pointer_type_def
7136/// node.
7137///
7138/// If the pointed-to type of a @ref pointer_type_def node is itself a
7139/// @ref pointer_type_def node, then recursively look at the
7140/// pointed-to type nodes to get the first one that is not a a @ref
7141/// pointer_type_def node. This is what a leaf pointed-to type node
7142/// means.
7143///
7144/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7145/// *NOT* a @ref pointer_type_def node, then just return the
7146/// pointed-to type node.
7147///
7148/// And if the type node considered is not a @ref pointer_type_def
7149/// node, then just return it.
7150///
7151/// @return the leaf pointed-to type node of a @p type.
7152const type_base*
7154{
7155 const pointer_type_def* t = is_pointer_type(type);
7156 if (!t)
7157 return type;
7158
7159 return peel_pointer_type(t->get_pointed_to_type()).get();
7160}
7161
7162/// Return the leaf pointed-to type node of a @ref reference_type_def
7163/// node.
7164///
7165/// If the pointed-to type of a @ref reference_type_def node is itself
7166/// a @ref reference_type_def node, then recursively look at the
7167/// pointed-to type nodes to get the first one that is not a a @ref
7168/// reference_type_def node. This is what a leaf pointed-to type node
7169/// means.
7170///
7171/// Otherwise, if the pointed-to type node of @ref reference_type_def
7172/// is *NOT* a @ref reference_type_def node, then just return the
7173/// pointed-to type node.
7174///
7175/// And if the type node considered is not a @ref reference_type_def
7176/// node, then just return it.
7177///
7178/// @return the leaf pointed-to type node of a @p type.
7179type_base_sptr
7180peel_reference_type(const type_base_sptr& type)
7181{
7183 if (!t)
7184 return type;
7185
7186 if (is_reference_type(t->get_pointed_to_type()))
7187 return peel_reference_type(t->get_pointed_to_type());
7188 return t->get_pointed_to_type();
7189}
7190
7191/// Return the leaf pointed-to type node of a @ref reference_type_def
7192/// node.
7193///
7194/// If the pointed-to type of a @ref reference_type_def node is itself
7195/// a @ref reference_type_def node, then recursively look at the
7196/// pointed-to type nodes to get the first one that is not a a @ref
7197/// reference_type_def node. This is what a leaf pointed-to type node
7198/// means.
7199///
7200/// Otherwise, if the pointed-to type node of @ref reference_type_def
7201/// is *NOT* a @ref reference_type_def node, then just return the
7202/// pointed-to type node.
7203///
7204/// And if the type node considered is not a @ref reference_type_def
7205/// node, then just return it.
7206///
7207/// @return the leaf pointed-to type node of a @p type.
7208const type_base*
7210{
7211 const reference_type_def* t = is_reference_type(type);
7212 if (!t)
7213 return type;
7214
7215 return peel_reference_type(t->get_pointed_to_type()).get();
7216}
7217
7218/// Return the leaf element type of an array.
7219///
7220/// If the element type is itself an array, then recursively return
7221/// the element type of that array itself.
7222///
7223/// @param type the array type to consider. If this is not an array
7224/// type, this type is returned by the function.
7225///
7226/// @return the leaf element type of the array @p type, or, if it's
7227/// not an array type, then just return @p.
7228const type_base_sptr
7229peel_array_type(const type_base_sptr& type)
7230{
7231 const array_type_def_sptr t = is_array_type(type);
7232 if (!t)
7233 return type;
7234
7235 return peel_array_type(t->get_element_type());
7236}
7237
7238/// Return the leaf element type of an array.
7239///
7240/// If the element type is itself an array, then recursively return
7241/// the element type of that array itself.
7242///
7243/// @param type the array type to consider. If this is not an array
7244/// type, this type is returned by the function.
7245///
7246/// @return the leaf element type of the array @p type, or, if it's
7247/// not an array type, then just return @p.
7248const type_base*
7250{
7251 const array_type_def* t = is_array_type(type);
7252 if (!t)
7253 return type;
7254
7255 return peel_array_type(t->get_element_type()).get();
7256}
7257
7258/// Return the leaf underlying type of a qualified type.
7259///
7260/// If the underlying type is itself a qualified type, then
7261/// recursively return the first underlying type of that qualified
7262/// type to return the first underlying type that is not a qualified type.
7263///
7264/// If the underlying type is NOT a qualified type, then just return
7265/// that underlying type.
7266///
7267/// @param type the qualified type to consider.
7268///
7269/// @return the leaf underlying type.
7270const type_base*
7272{
7273 const qualified_type_def* t = is_qualified_type(type);
7274 if (!t)
7275 return type;
7276
7277 return peel_qualified_type(t->get_underlying_type().get());
7278}
7279
7280/// Return the leaf underlying type of a qualified type.
7281///
7282/// If the underlying type is itself a qualified type, then
7283/// recursively return the first underlying type of that qualified
7284/// type to return the first underlying type that is not a qualified type.
7285///
7286/// If the underlying type is NOT a qualified type, then just return
7287/// that underlying type.
7288///
7289/// @param type the qualified type to consider.
7290///
7291/// @return the leaf underlying type.
7292const type_base_sptr
7293peel_qualified_type(const type_base_sptr& type)
7294{
7295 const qualified_type_def_sptr t = is_qualified_type(type);
7296 if (!t)
7297 return type;
7298
7299 return peel_qualified_type(t->get_underlying_type());
7300}
7301
7302/// Test if a given qualified type is const.
7303///
7304/// @pram t the qualified type to consider.
7305///
7306/// @return true iff @p t is a const qualified type.
7307bool
7308is_const_qualified_type(const qualified_type_def_sptr& t)
7309{
7310 if (!t)
7311 return false;
7312
7313 if (t->get_cv_quals() == qualified_type_def::CV_CONST)
7314 return true;
7315
7316 return false;
7317}
7318
7319/// Test if a given type is const-qualified.
7320///
7321/// @pram t the type to consider.
7322///
7323/// @return true iff @p t is a const qualified type.
7324bool
7325is_const_qualified_type(const type_base_sptr& t)
7326{
7327 qualified_type_def_sptr q = is_qualified_type(t);
7328 if (!q)
7329 return false;
7330 return is_const_qualified_type(q);
7331}
7332
7333/// If a qualified type is const, then return its underlying type.
7334///
7335/// @param q the qualified type to consider.
7336///
7337/// @return the underlying type of @p q if it's a const-qualified
7338/// type, otherwise, return @p q itself.
7339type_base_sptr
7340peel_const_qualified_type(const qualified_type_def_sptr& q)
7341{
7342 if (!q)
7343 return q;
7344
7346 return q->get_underlying_type();
7347
7348 return q;
7349}
7350
7351/// Return the leaf underlying type of a qualified or typedef type.
7352///
7353/// If the underlying type is itself a qualified or typedef type, then
7354/// recursively return the first underlying type of that qualified or
7355/// typedef type to return the first underlying type that is not a
7356/// qualified or typedef type.
7357///
7358/// If the underlying type is NOT a qualified nor a typedef type, then
7359/// just return that underlying type.
7360///
7361/// @param type the qualified or typedef type to consider.
7362///
7363/// @return the leaf underlying type.
7364type_base*
7366{
7367 while (is_typedef(type) || is_qualified_type(type))
7368 {
7369 if (const typedef_decl* t = is_typedef(type))
7370 type = peel_typedef_type(t);
7371
7372 if (const qualified_type_def* t = is_qualified_type(type))
7373 type = peel_qualified_type(t);
7374 }
7375
7376 return const_cast<type_base*>(type);
7377}
7378
7379/// Return the leaf underlying type of a qualified or typedef type.
7380///
7381/// If the underlying type is itself a qualified or typedef type, then
7382/// recursively return the first underlying type of that qualified or
7383/// typedef type to return the first underlying type that is not a
7384/// qualified or typedef type.
7385///
7386/// If the underlying type is NOT a qualified nor a typedef type, then
7387/// just return that underlying type.
7388///
7389/// @param type the qualified or typedef type to consider.
7390///
7391/// @return the leaf underlying type.
7392type_base_sptr
7393peel_qualified_or_typedef_type(const type_base_sptr &t)
7394{
7395 type_base_sptr type = t;
7396 while (is_typedef(type) || is_qualified_type(type))
7397 {
7398 if (typedef_decl_sptr t = is_typedef(type))
7399 type = peel_typedef_type(t);
7400
7401 if (qualified_type_def_sptr t = is_qualified_type(type))
7402 type = peel_qualified_type(t);
7403 }
7404
7405 return type;
7406}
7407
7408/// Return the leaf underlying or pointed-to type node of a @ref
7409/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7410/// or @ref array_type_def node.
7411///
7412/// @param type the type to peel.
7413///
7414/// @return the leaf underlying or pointed-to type node of @p type.
7415type_base_sptr
7417{
7418 type_base_sptr typ = type;
7419 while (is_typedef(typ)
7420 || is_pointer_type(typ)
7421 || is_reference_type(typ)
7422 || is_array_type(typ))
7423 {
7424 if (typedef_decl_sptr t = is_typedef(typ))
7425 typ = peel_typedef_type(t);
7426
7428 typ = peel_pointer_type(t);
7429
7431 typ = peel_reference_type(t);
7432
7433 if (const array_type_def_sptr t = is_array_type(typ))
7434 typ = peel_array_type(t);
7435 }
7436
7437 return typ;
7438}
7439
7440/// Return the leaf underlying or pointed-to type node of a @ref
7441/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7442/// node.
7443///
7444/// @param type the type to peel.
7445///
7446/// @return the leaf underlying or pointed-to type node of @p type.
7447type_base*
7449{
7450 while (is_typedef(type)
7451 || is_pointer_type(type)
7452 || is_reference_type(type)
7453 || is_array_type(type))
7454 {
7455 if (const typedef_decl* t = is_typedef(type))
7456 type = peel_typedef_type(t);
7457
7458 if (const pointer_type_def* t = is_pointer_type(type))
7459 type = peel_pointer_type(t);
7460
7461 if (const reference_type_def* t = is_reference_type(type))
7462 type = peel_reference_type(t);
7463
7464 if (const array_type_def* t = is_array_type(type))
7465 type = peel_array_type(t);
7466 }
7467
7468 return const_cast<type_base*>(type);
7469}
7470
7471/// Return the leaf underlying or pointed-to type node of a @ref
7472/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7473/// node.
7474///
7475/// @param type the type to peel.
7476///
7477/// @return the leaf underlying or pointed-to type node of @p type.
7478type_base*
7480 bool peel_qual_type)
7481{
7482 while (is_typedef(type)
7483 || is_pointer_type(type)
7484 || is_reference_type(type)
7485 || is_array_type(type)
7486 || (peel_qual_type && is_qualified_type(type)))
7487 {
7488 if (const typedef_decl* t = is_typedef(type))
7489 type = peel_typedef_type(t);
7490
7491 if (const pointer_type_def* t = is_pointer_type(type))
7492 type = peel_pointer_type(t);
7493
7494 if (const reference_type_def* t = is_reference_type(type))
7495 type = peel_reference_type(t);
7496
7497 if (const array_type_def* t = is_array_type(type))
7498 type = peel_array_type(t);
7499
7500 if (peel_qual_type)
7501 if (const qualified_type_def* t = is_qualified_type(type))
7502 type = peel_qualified_type(t);
7503 }
7504
7505 return const_cast<type_base*>(type);
7506}
7507
7508/// Return the leaf underlying or pointed-to type node of a, @ref
7509/// pointer_type_def, @ref reference_type_def or @ref
7510/// qualified_type_def type node.
7511///
7512/// @param type the type to peel.
7513///
7514/// @param peel_qualified_type if true, also peel qualified types.
7515///
7516/// @return the leaf underlying or pointed-to type node of @p type.
7517type_base*
7519 bool peel_qual_type)
7520{
7521 while (is_pointer_type(type)
7522 || is_reference_type(type)
7523 || is_array_type(type)
7524 || (peel_qual_type && is_qualified_type(type)))
7525 {
7526 if (const pointer_type_def* t = is_pointer_type(type))
7527 type = peel_pointer_type(t);
7528
7529 if (const reference_type_def* t = is_reference_type(type))
7530 type = peel_reference_type(t);
7531
7532 if (const array_type_def* t = is_array_type(type))
7533 type = peel_array_type(t);
7534
7535 if (peel_qual_type)
7536 if (const qualified_type_def* t = is_qualified_type(type))
7537 type = peel_qualified_type(t);
7538 }
7539
7540 return const_cast<type_base*>(type);
7541}
7542
7543/// Clone an array type.
7544///
7545/// Note that the element type of the new array is shared witht the
7546/// old one.
7547///
7548/// @param array the array type to clone.
7549///
7550/// @return a newly built array type. Note that it needs to be added
7551/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7552/// bound to the one of that scope. Otherwise, its lifetime is bound
7553/// to the lifetime of its containing shared pointer.
7556{
7557 vector<array_type_def::subrange_sptr> subranges;
7558
7559 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7560 array->get_subranges().begin();
7561 i != array->get_subranges().end();
7562 ++i)
7563 {
7565 (new array_type_def::subrange_type(array->get_environment(),
7566 (*i)->get_name(),
7567 (*i)->get_lower_bound(),
7568 (*i)->get_upper_bound(),
7569 (*i)->get_underlying_type(),
7570 (*i)->get_location(),
7571 (*i)->get_language()));
7572 subrange->is_non_finite((*i)->is_non_finite());
7573 if (scope_decl *scope = (*i)->get_scope())
7574 add_decl_to_scope(subrange, scope);
7575 subranges.push_back(subrange);
7576 }
7577
7578 array_type_def_sptr result
7579 (new array_type_def(array->get_element_type(),
7580 subranges, array->get_location()));
7581
7582 return result;
7583}
7584
7585/// Clone a typedef type.
7586///
7587/// Note that the underlying type of the newly constructed typedef is
7588/// shared with the old one.
7589///
7590/// @param t the typedef to clone.
7591///
7592/// @return the newly constructed typedef. Note that it needs to be
7593/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7594/// to be bound to the one of that scope. Otherwise, its lifetime is
7595/// bound to the lifetime of its containing shared pointer.
7598{
7599 if (!t)
7600 return t;
7601
7602 typedef_decl_sptr result
7603 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7604 t->get_location(), t->get_linkage_name(),
7605 t->get_visibility()));
7606 return result;
7607}
7608
7609/// Clone a qualifiend type.
7610///
7611/// Note that underlying type of the newly constructed qualified type
7612/// is shared with the old one.
7613///
7614/// @param t the qualified type to clone.
7615///
7616/// @return the newly constructed qualified type. Note that it needs
7617/// to be added to a scope (e.g, using add_decl_to_scope) for its
7618/// lifetime to be bound to the one of that scope. Otherwise, its
7619/// lifetime is bound to the lifetime of its containing shared
7620/// pointer.
7621qualified_type_def_sptr
7622clone_qualified_type(const qualified_type_def_sptr& t)
7623{
7624 if (!t)
7625 return t;
7626
7627 qualified_type_def_sptr result
7628 (new qualified_type_def(t->get_underlying_type(),
7629 t->get_cv_quals(), t->get_location()));
7630
7631 return result;
7632}
7633
7634/// Clone a typedef, an array or a qualified tree.
7635///
7636/// @param type the typedef, array or qualified tree to clone. any
7637/// order.
7638///
7639/// @return the cloned type, or NULL if @type was neither a typedef,
7640/// array nor a qualified type.
7641static type_base_sptr
7642clone_typedef_array_qualified_type(type_base_sptr type)
7643{
7644 if (!type)
7645 return type;
7646
7647 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7648 type_base_sptr result;
7649
7650 if (typedef_decl_sptr t = is_typedef(type))
7651 result = clone_typedef(is_typedef(t));
7652 else if (qualified_type_def_sptr t = is_qualified_type(type))
7653 result = clone_qualified_type(t);
7654 else if (array_type_def_sptr t = is_array_type(type))
7655 result = clone_array(t);
7656 else
7657 return type_base_sptr();
7658
7659 if (scope)
7660 add_decl_to_scope(is_decl(result), scope);
7661
7662 return result;
7663}
7664
7665/// Clone a type tree made of an array or a typedef of array.
7666///
7667/// Note that this can be a tree which root node is a typedef an which
7668/// sub-tree can be any arbitrary combination of typedef, qualified
7669/// type and arrays.
7670///
7671/// @param t the array or typedef of qualified array to consider.
7672///
7673/// @return a clone of @p t.
7674type_base_sptr
7675clone_array_tree(const type_base_sptr t)
7676{
7678
7679 scope_decl* scope = is_decl(t)->get_scope();
7680 type_base_sptr result = clone_typedef_array_qualified_type(t);
7681 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7682
7683 type_base_sptr subtree;
7684 if (typedef_decl_sptr type = is_typedef(result))
7685 {
7686 type_base_sptr s =
7687 clone_typedef_array_qualified_type(type->get_underlying_type());
7688 if (s)
7689 {
7690 subtree = s;
7691 type->set_underlying_type(subtree);
7692 }
7693 }
7694 else if (array_type_def_sptr type = is_array_type(result))
7695 {
7696 type_base_sptr s =
7697 clone_typedef_array_qualified_type(type->get_element_type());
7698 if (s)
7699 {
7700 subtree = s;
7701 type->set_element_type(subtree);
7702 }
7703 }
7704 add_decl_to_scope(is_decl(subtree), scope);
7705
7706 for (;;)
7707 {
7708 if (typedef_decl_sptr t = is_typedef(subtree))
7709 {
7710 type_base_sptr s =
7711 clone_typedef_array_qualified_type(t->get_underlying_type());
7712 if (s)
7713 {
7714 scope_decl* scope =
7715 is_decl(t->get_underlying_type())->get_scope();
7716 ABG_ASSERT(scope);
7717 add_decl_to_scope(is_decl(s), scope);
7718 t->set_underlying_type (s);
7719 subtree = s;
7720 }
7721 else
7722 break;
7723 }
7724 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7725 {
7726 type_base_sptr s =
7727 clone_typedef_array_qualified_type(t->get_underlying_type());
7728 if (s)
7729 {
7730 scope_decl* scope =
7731 is_decl(t->get_underlying_type())->get_scope();
7732 ABG_ASSERT(scope);
7733 add_decl_to_scope(is_decl(s), scope);
7734 t->set_underlying_type(s);
7735 subtree = s;
7736 }
7737 else
7738 break;
7739 }
7740 else if (array_type_def_sptr t = is_array_type(subtree))
7741 {
7742 type_base_sptr e = t->get_element_type();
7743 if (is_typedef(e) || is_qualified_type(e))
7744 {
7745 type_base_sptr s =
7746 clone_typedef_array_qualified_type(e);
7747 if (s)
7748 {
7749 scope_decl* scope = is_decl(e)->get_scope();
7750 ABG_ASSERT(scope);
7751 add_decl_to_scope(is_decl(s), scope);
7752 t->set_element_type(s);
7753 }
7754 else
7755 break;
7756 }
7757 break;
7758 }
7759 else
7760 break;
7761 }
7762 return result;
7763}
7764
7765/// Update the qualified name of a given sub-tree.
7766///
7767/// @param d the sub-tree for which to update the qualified name.
7768static void
7769update_qualified_name(decl_base * d)
7770{
7771 ::qualified_name_setter setter;
7772 d->traverse(setter);
7773}
7774
7775/// Update the qualified name of a given sub-tree.
7776///
7777/// @param d the sub-tree for which to update the qualified name.
7778static void
7779update_qualified_name(decl_base_sptr d)
7780{return update_qualified_name(d.get());}
7781
7782// <scope_decl stuff>
7783
7784/// Hash a type by returning the pointer value of its canonical type.
7785///
7786/// @param l the type to hash.
7787///
7788/// @return the the pointer value of the canonical type of @p l.
7789size_t
7790canonical_type_hash::operator()(const type_base_sptr& l) const
7791{return operator()(l.get());}
7792
7793/// Hash a (canonical) type by returning its pointer value
7794///
7795/// @param l the canonical type to hash.
7796///
7797/// @return the pointer value of the canonical type of @p l.
7798size_t
7800{return reinterpret_cast<size_t>(l);}
7801
7802struct scope_decl::priv
7803{
7804 declarations members_;
7805 declarations sorted_members_;
7806 type_base_sptrs_type member_types_;
7807 type_base_sptrs_type sorted_member_types_;
7808 scopes member_scopes_;
7809 canonical_type_sptr_set_type canonical_types_;
7810 type_base_sptrs_type sorted_canonical_types_;
7811 bool clear_sorted_member_types_cache_ = false;
7812}; // end struct scope_decl::priv
7813
7814/// Constructor of the @ref scope_decl type.
7815///
7816/// @param the environment to use for the new instance.
7817///
7818/// @param the name of the scope decl.
7819///
7820/// @param locus the source location where the scope_decl is defined.
7821///
7822/// @param vis the visibility of the declaration.
7823scope_decl::scope_decl(const environment& env,
7824 const string& name,
7825 const location& locus,
7826 visibility vis)
7827 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7828 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7829 priv_(new priv)
7830{}
7831
7832/// Constructor of the @ref scope_decl type.
7833///
7834/// @param the environment to use for the new instance.
7835///
7836/// @param l the source location where the scope_decl is defined.
7837///
7838/// @param vis the visibility of the declaration.
7839scope_decl::scope_decl(const environment& env, location& l)
7840 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7841 decl_base(env, "", l),
7842 priv_(new priv)
7843{}
7844
7845/// @eturn the set of canonical types of the the current scope.
7848{return priv_->canonical_types_;}
7849
7850/// @eturn the set of canonical types of the the current scope.
7853{return const_cast<scope_decl*>(this)->get_canonical_types();}
7854
7855/// Return a vector of sorted canonical types of the current scope.
7856///
7857/// The types are sorted "almost topologically". That means, they are
7858/// sorted using the lexicographic order of the string representing
7859/// the location their definition point. If a type doesn't have a
7860/// location, then its pretty representation is used.
7861///
7862/// @return a vector of sorted canonical types of the current scope.
7865{
7866 if (priv_->sorted_canonical_types_.empty())
7867 {
7868 for (canonical_type_sptr_set_type::const_iterator e =
7869 get_canonical_types().begin();
7870 e != get_canonical_types().end();
7871 ++e)
7872 priv_->sorted_canonical_types_.push_back(*e);
7873
7874 type_topo_comp comp;
7875 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7876 priv_->sorted_canonical_types_.end(),
7877 comp);
7878 }
7879 return priv_->sorted_canonical_types_;
7880}
7881
7882/// Getter for the member declarations carried by the current @ref
7883/// scope_decl.
7884///
7885/// @return the member declarations carried by the current @ref
7886/// scope_decl.
7889{return priv_->members_;}
7890
7891/// Getter for the member declarations carried by the current @ref
7892/// scope_decl.
7893///
7894/// @return the member declarations carried by the current @ref
7895/// scope_decl.
7898{return priv_->members_;}
7899
7900/// Getter for the sorted member declarations carried by the current
7901/// @ref scope_decl.
7902///
7903/// @return the sorted member declarations carried by the current @ref
7904/// scope_decl. The declarations are sorted topologically.
7907{
7908 decl_topo_comp comp;
7909 if (priv_->sorted_members_.empty())
7910 {
7911 for (declarations::const_iterator i = get_member_decls().begin();
7912 i != get_member_decls().end();
7913 ++i)
7914 priv_->sorted_members_.push_back(*i);
7915
7916 std::stable_sort(priv_->sorted_members_.begin(),
7917 priv_->sorted_members_.end(),
7918 comp);
7919 }
7920 return priv_->sorted_members_;
7921}
7922
7923/// Getter for the number of anonymous classes contained in this
7924/// scope.
7925///
7926/// @return the number of anonymous classes contained in this scope.
7927size_t
7929{
7930 int result = 0;
7931 for (declarations::const_iterator it = get_member_decls().begin();
7932 it != get_member_decls().end();
7933 ++it)
7934 if (class_decl_sptr t = is_class_type(*it))
7935 if (t->get_is_anonymous())
7936 ++result;
7937
7938 return result;
7939}
7940
7941/// Getter for the number of anonymous unions contained in this
7942/// scope.
7943///
7944/// @return the number of anonymous unions contained in this scope.
7945size_t
7947{
7948 int result = 0;
7949 for (declarations::const_iterator it = get_member_decls().begin();
7950 it != get_member_decls().end();
7951 ++it)
7952 if (union_decl_sptr t = is_union_type(*it))
7953 if (t->get_is_anonymous())
7954 ++result;
7955
7956 return result;
7957}
7958
7959/// Getter for the number of anonymous enums contained in this
7960/// scope.
7961///
7962/// @return the number of anonymous enums contained in this scope.
7963size_t
7965{
7966 int result = 0;
7967 for (declarations::const_iterator it = get_member_decls().begin();
7968 it != get_member_decls().end();
7969 ++it)
7970 if (enum_type_decl_sptr t = is_enum_type(*it))
7971 if (t->get_is_anonymous())
7972 ++result;
7973
7974 return result;
7975}
7976
7977/// Getter for the scopes carried by the current scope.
7978///
7979/// @return the scopes carried by the current scope.
7982{return priv_->member_scopes_;}
7983
7984/// Getter for the scopes carried by the current scope.
7985///
7986/// @return the scopes carried by the current scope.
7987const scope_decl::scopes&
7989{return priv_->member_scopes_;}
7990
7991/// Test if the current scope is empty.
7992///
7993/// @return true iff the current scope is empty.
7994bool
7996{
7997 return (get_member_decls().empty()
7998 && get_canonical_types().empty());
7999}
8000
8001/// Set the translation unit of a decl
8002///
8003/// It also perform some IR integrity checks.
8004///
8005/// This is a sub-routine of scope_decl::{insert,add}_member_decl.
8006///
8007/// @param decl the decl to set the translation unit for.
8008///
8009/// @param tu the translation unit to set.
8010static void
8011maybe_set_translation_unit(const decl_base_sptr& decl,
8012 translation_unit* tu)
8013{
8014 ABG_ASSERT(tu);
8015
8016 if (translation_unit* existing_tu = decl->get_translation_unit())
8017 // The decl already belongs to a translation unit.
8018 // Either:
8019 //
8020 // 1/ it's a unique type, in which case we should not add it to
8021 // any translation unique since unique types are "logically"
8022 // supposed to belong to no translation unit in particular, as
8023 // they are unique.
8024 //
8025 // 2/ or the decl was already added to this translation unit.
8026 ABG_ASSERT(tu == existing_tu || is_unique_type(is_type(decl)));
8027 else
8028 decl->set_translation_unit(tu);
8029}
8030
8031/// Add a member decl to this scope. Note that user code should not
8032/// use this, but rather use add_decl_to_scope.
8033///
8034/// Note that this function updates the qualified name of the member
8035/// decl that is added. It also sets the scope of the member. Thus,
8036/// it ABG_ASSERTs that member should not have its scope set, prior to
8037/// calling this function.
8038///
8039/// @param member the new member decl to add to this scope.
8040decl_base_sptr
8041scope_decl::add_member_decl(const decl_base_sptr& member)
8042{
8043 ABG_ASSERT(!has_scope(member));
8044
8045 member->set_scope(this);
8046 priv_->members_.push_back(member);
8047 if (is_type(member))
8048 {
8049 priv_->member_types_.push_back(is_type(member));
8050 priv_->clear_sorted_member_types_cache_ = true;
8051 }
8052
8053 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8054 priv_->member_scopes_.push_back(m);
8055
8056 update_qualified_name(member);
8057
8059 maybe_set_translation_unit(member, tu);
8060
8062
8063 return member;
8064}
8065
8066/// Get the member types of this @ref scope_decl.
8067///
8068/// @return a vector of the member types of this ref class_or_union.
8071{return priv_->member_types_;}
8072
8073/// Find a member type of a given name, inside the current @ref
8074/// scope_decl.
8075///
8076/// @param name the name of the member type to look for.
8077///
8078/// @return a pointer to the @ref type_base that represents the member
8079/// type of name @p name, for the current scope.
8080type_base_sptr
8081scope_decl::find_member_type(const string& name) const
8082{
8083 for (auto t : get_member_types())
8084 if (get_type_name(t, /*qualified*/false) == name)
8085 return t;
8086 return type_base_sptr();
8087}
8088
8089/// Insert a member type.
8090///
8091/// @param t the type to insert in the @ref scope_decl type.
8092///
8093/// @param an iterator right before which @p t has to be inserted.
8094void
8096 declarations::iterator before)
8097{
8098 decl_base_sptr d = get_type_declaration(t);
8099 ABG_ASSERT(d);
8100 ABG_ASSERT(!has_scope(d));
8101
8102 priv_->member_types_.push_back(t);
8103 priv_->clear_sorted_member_types_cache_= true;
8104 insert_member_decl(d, before);
8105}
8106
8107/// Add a member type to the current instance of class_or_union.
8108///
8109/// @param t the member type to add. It must not have been added to a
8110/// scope, otherwise this will violate an ABG_ASSERTion.
8111void
8114
8115/// Add a member type to the current instance of class_or_union.
8116///
8117/// @param t the type to be added as a member type to the current
8118/// instance of class_or_union. An instance of class_or_union::member_type
8119/// will be created out of @p t and and added to the the class.
8120///
8121/// @param a the access specifier for the member type to be created.
8122type_base_sptr
8124{
8125 decl_base_sptr d = get_type_declaration(t);
8126 ABG_ASSERT(d);
8128 add_member_type(t);
8130 return t;
8131}
8132
8133/// Remove a member type from the current @ref class_or_union scope.
8134///
8135/// @param t the type to remove.
8136void
8138{
8139 for (auto i = priv_->member_types_.begin();
8140 i != priv_->member_types_.end();
8141 ++i)
8142 {
8143 if (*((*i)) == *t)
8144 {
8145 priv_->member_types_.erase(i);
8146 return;
8147 }
8148 }
8149}
8150
8151/// Get the sorted member types of this @ref scope_decl
8152///
8153/// @return a vector of the sorted member types of this ref
8154/// class_or_union.
8157{
8158 if (priv_->clear_sorted_member_types_cache_)
8159 {
8160 priv_->sorted_member_types_.clear();
8161 priv_->clear_sorted_member_types_cache_ = false;
8162 }
8163
8164 if (priv_->sorted_member_types_.empty())
8165 {
8166 unordered_set<type_base_sptr> canonical_pointer_types;
8167 for (auto t : get_member_types())
8168 {
8170 priv_->sorted_member_types_.push_back(t);
8171 else if (auto c = t->get_canonical_type())
8172 canonical_pointer_types.insert(c);
8173 else
8174 canonical_pointer_types.insert(t);
8175 }
8176
8177 for (auto t : canonical_pointer_types)
8178 priv_->sorted_member_types_.push_back(t);
8179
8180 type_topo_comp comp;
8181 std::stable_sort(priv_->sorted_member_types_.begin(),
8182 priv_->sorted_member_types_.end(),
8183 comp);
8184 }
8185
8186 const ir::environment& env = get_environment();
8188 priv_->clear_sorted_member_types_cache_ = true;
8189
8190 return priv_->sorted_member_types_;
8191}
8192
8193/// Insert a member decl to this scope, right before an element
8194/// pointed to by a given iterator. Note that user code should not
8195/// use this, but rather use insert_decl_into_scope.
8196///
8197/// Note that this function updates the qualified name of the inserted
8198/// member.
8199///
8200/// @param member the new member decl to add to this scope.
8201///
8202/// @param before an interator pointing to the element before which
8203/// the new member should be inserted.
8204decl_base_sptr
8206 declarations::iterator before)
8207{
8208 ABG_ASSERT(!member->get_scope());
8209
8210 member->set_scope(this);
8211 priv_->members_.insert(before, member);
8212
8213 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8214 priv_-> member_scopes_.push_back(m);
8215
8216 update_qualified_name(member);
8217
8219 maybe_set_translation_unit(member, tu);
8220
8222
8223 return member;
8224}
8225
8226/// Remove a declaration from the current scope.
8227///
8228/// @param member the declaration to remove from the scope.
8229void
8231{
8232 for (declarations::iterator i = priv_->members_.begin();
8233 i != priv_->members_.end();
8234 ++i)
8235 {
8236 if (**i == *member)
8237 {
8238 priv_->members_.erase(i);
8239 // Do not access i after this point as it's invalided by the
8240 // erase call.
8241 break;
8242 }
8243 }
8244
8245 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8246 if (scope)
8247 {
8248 for (scopes::iterator i = priv_->member_scopes_.begin();
8249 i != priv_->member_scopes_.end();
8250 ++i)
8251 {
8252 if (**i == *member)
8253 {
8254 priv_->member_scopes_.erase(i);
8255 break;
8256 }
8257 }
8258 }
8259
8260 member->set_scope(nullptr);
8261 member->set_translation_unit(nullptr);
8262}
8263
8264/// Compares two instances of @ref scope_decl.
8265///
8266/// If the two intances are different, set a bitfield to give some
8267/// insight about the kind of differences there are.
8268///
8269/// @param l the first artifact of the comparison.
8270///
8271/// @param r the second artifact of the comparison.
8272///
8273/// @param k a pointer to a bitfield that gives information about the
8274/// kind of changes there are between @p l and @p r. This one is set
8275/// iff @p k is non-null and the function returns false.
8276///
8277/// Please note that setting k to a non-null value does have a
8278/// negative performance impact because even if @p l and @p r are not
8279/// equal, the function keeps up the comparison in order to determine
8280/// the different kinds of ways in which they are different.
8281///
8282/// @return true if @p l equals @p r, false otherwise.
8283bool
8285{
8286 bool result = true;
8287
8288 if (!l.decl_base::operator==(r))
8289 {
8290 result = false;
8291 if (k)
8293 else
8295 }
8296
8297 scope_decl::declarations::const_iterator i, j;
8298 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8299 i != l.get_member_decls().end() && j != r.get_member_decls().end();
8300 ++i, ++j)
8301 {
8302 if (**i != **j)
8303 {
8304 result = false;
8305 if (k)
8306 {
8307 *k |= SUBTYPE_CHANGE_KIND;
8308 break;
8309 }
8310 else
8312 }
8313 }
8314
8315 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8316 {
8317 result = false;
8318 if (k)
8320 else
8322 }
8323
8324 ABG_RETURN(result);
8325}
8326
8327/// Return true iff both scopes have the same names and have the same
8328/// member decls.
8329///
8330/// This function doesn't check for equality of the scopes of its
8331/// arguments.
8332bool
8334{
8335 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8336 if (!other)
8337 return false;
8338
8339 return equals(*this, *other, 0);
8340}
8341
8342/// Equality operator for @ref scope_decl_sptr.
8343///
8344/// @param l the left hand side operand of the equality operator.
8345///
8346/// @pram r the right hand side operand of the equalify operator.
8347///
8348/// @return true iff @p l equals @p r.
8349bool
8351{
8352 if (!!l != !!r)
8353 return false;
8354 if (l.get() == r.get())
8355 return true;
8356 return *l == *r;
8357}
8358
8359/// Inequality operator for @ref scope_decl_sptr.
8360///
8361/// @param l the left hand side operand of the equality operator.
8362///
8363/// @pram r the right hand side operand of the equalify operator.
8364///
8365/// @return true iff @p l equals @p r.
8366bool
8368{return !operator==(l, r);}
8369
8370/// Find a member of the current scope and return an iterator on it.
8371///
8372/// @param decl the scope member to find.
8373///
8374/// @param i the iterator to set to the member @p decl. This is set
8375/// iff the function returns true.
8376///
8377/// @return true if the member decl was found, false otherwise.
8378bool
8380 declarations::iterator& i)
8381{
8382 if (!decl)
8383 return false;
8384
8385 if (get_member_decls().empty())
8386 {
8387 i = get_member_decls().end();
8388 return false;
8389 }
8390
8391 for (declarations::iterator it = get_member_decls().begin();
8392 it != get_member_decls().end();
8393 ++it)
8394 {
8395 if ((*it).get() == decl)
8396 {
8397 i = it;
8398 return true;
8399 }
8400 }
8401
8402 return false;
8403}
8404
8405/// Find a member of the current scope and return an iterator on it.
8406///
8407/// @param decl the scope member to find.
8408///
8409/// @param i the iterator to set to the member @p decl. This is set
8410/// iff the function returns true.
8411///
8412/// @return true if the member decl was found, false otherwise.
8413bool
8415 declarations::iterator& i)
8416{return find_iterator_for_member(decl.get(), i);}
8417
8418/// This implements the ir_traversable_base::traverse pure virtual
8419/// function.
8420///
8421/// @param v the visitor used on the current instance of scope_decl
8422/// and on its member nodes.
8423///
8424/// @return true if the traversal of the tree should continue, false
8425/// otherwise.
8426bool
8428{
8429 if (visiting())
8430 return true;
8431
8432 if (v.visit_begin(this))
8433 {
8434 visiting(true);
8435 for (scope_decl::declarations::const_iterator i =
8436 get_member_decls().begin();
8437 i != get_member_decls ().end();
8438 ++i)
8439 if (!(*i)->traverse(v))
8440 break;
8441 visiting(false);
8442 }
8443 return v.visit_end(this);
8444}
8445
8446scope_decl::~scope_decl()
8447{}
8448
8449/// Appends a declaration to a given scope, if the declaration
8450/// doesn't already belong to one and if the declaration is not for a
8451/// type that is supposed to be unique.
8452///
8453/// @param decl the declaration to add to the scope
8454///
8455/// @param scope the scope to append the declaration to
8456decl_base_sptr
8457add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8458{
8459 if (!scope)
8460 return decl;
8461
8462 if (scope && decl && !decl->get_scope())
8463 decl = scope->add_member_decl(decl);
8464
8465 return decl;
8466}
8467
8468/// Appends a declaration to a given scope, if the declaration doesn't
8469/// already belong to a scope.
8470///
8471/// @param decl the declaration to add append to the scope
8472///
8473/// @param scope the scope to append the decl to
8474decl_base_sptr
8475add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8476{return add_decl_to_scope(decl, scope.get());}
8477
8478/// Remove a given decl from its scope
8479///
8480/// @param decl the decl to remove from its scope.
8481void
8482remove_decl_from_scope(decl_base_sptr decl)
8483{
8484 if (!decl)
8485 return;
8486
8487 scope_decl* scope = decl->get_scope();
8488 scope->remove_member_decl(decl);
8489}
8490
8491/// Inserts a declaration into a given scope, before a given IR child
8492/// node of the scope.
8493///
8494/// @param decl the declaration to insert into the scope.
8495///
8496/// @param before an iterator pointing to the child IR node before
8497/// which to insert the declaration.
8498///
8499/// @param scope the scope into which to insert the declaration.
8500decl_base_sptr
8501insert_decl_into_scope(decl_base_sptr decl,
8502 scope_decl::declarations::iterator before,
8503 scope_decl* scope)
8504{
8505 if (scope && decl && !decl->get_scope())
8506 {
8507 decl_base_sptr d = scope->insert_member_decl(decl, before);
8508 decl = d;
8509 }
8510 return decl;
8511}
8512
8513/// Inserts a declaration into a given scope, before a given IR child
8514/// node of the scope.
8515///
8516/// @param decl the declaration to insert into the scope.
8517///
8518/// @param before an iterator pointing to the child IR node before
8519/// which to insert the declaration.
8520///
8521/// @param scope the scope into which to insert the declaration.
8522decl_base_sptr
8523insert_decl_into_scope(decl_base_sptr decl,
8524 scope_decl::declarations::iterator before,
8525 scope_decl_sptr scope)
8526{return insert_decl_into_scope(decl, before, scope.get());}
8527
8528/// Constructor of the @ref global_scope type.
8529///
8530/// @param tu the translation unit the scope belongs to.
8531global_scope::global_scope(translation_unit *tu)
8532 : type_or_decl_base(tu->get_environment(),
8533 GLOBAL_SCOPE_DECL
8534 | ABSTRACT_DECL_BASE
8535 | ABSTRACT_SCOPE_DECL),
8536 decl_base(tu->get_environment(), "", location()),
8537 scope_decl(tu->get_environment(), "", location()),
8538 translation_unit_(tu)
8539{
8540 runtime_type_instance(this);
8541}
8542
8543/// return the global scope as seen by a given declaration.
8544///
8545/// @param decl the declaration to consider.
8546///
8547/// @return the global scope of the decl, or a null pointer if the
8548/// decl is not yet added to a translation_unit.
8549const global_scope*
8551{
8552 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8553 return s;
8554
8555 scope_decl* scope = decl.get_scope();
8556 while (scope && !dynamic_cast<global_scope*>(scope))
8557 scope = scope->get_scope();
8558
8559 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8560}
8561
8562/// return the global scope as seen by a given declaration.
8563///
8564/// @param decl the declaration to consider.
8565///
8566/// @return the global scope of the decl, or a null pointer if the
8567/// decl is not yet added to a translation_unit.
8568const global_scope*
8570{return get_global_scope(*decl);}
8571
8572/// Return the global scope as seen by a given declaration.
8573///
8574/// @param decl the declaration to consider.
8575///
8576/// @return the global scope of the decl, or a null pointer if the
8577/// decl is not yet added to a translation_unit.
8578const global_scope*
8579get_global_scope(const shared_ptr<decl_base> decl)
8580{return get_global_scope(decl.get());}
8581
8582/// Return the a scope S containing a given declaration and that is
8583/// right under a given scope P.
8584///
8585/// Note that @p scope must come before @p decl in topological
8586/// order.
8587///
8588/// @param decl the decl for which to find a scope.
8589///
8590/// @param scope the scope under which the resulting scope must be.
8591///
8592/// @return the resulting scope.
8593const scope_decl*
8595 const scope_decl* scope)
8596{
8597 if (!decl)
8598 return 0;
8599
8600 if (scope == 0)
8601 return get_global_scope(decl);
8602
8603 // Handle the case where decl is a scope itself.
8604 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8605 if (!s)
8606 s = decl->get_scope();
8607
8608 if (is_global_scope(s))
8609 return scope;
8610
8611 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8612 // same. The caller needs to be prepared to deal with this case.
8613 if (s == scope)
8614 return s;
8615
8616 while (s && !is_global_scope(s) && s->get_scope() != scope)
8617 s = s->get_scope();
8618
8619 if (!s || is_global_scope(s))
8620 // SCOPE must come before decl in topological order, but I don't
8621 // know how to ensure that ...
8622 return scope;
8623 ABG_ASSERT(s);
8624
8625 return s;
8626}
8627
8628/// Return the a scope S containing a given declaration and that is
8629/// right under a given scope P.
8630///
8631/// @param decl the decl for which to find a scope.
8632///
8633/// @param scope the scope under which the resulting scope must be.
8634///
8635/// @return the resulting scope.
8636const scope_decl*
8637get_top_most_scope_under(const decl_base_sptr decl,
8638 const scope_decl* scope)
8639{return get_top_most_scope_under(decl.get(), scope);}
8640
8641/// Return the a scope S containing a given declaration and that is
8642/// right under a given scope P.
8643///
8644/// @param decl the decl for which to find a scope.
8645///
8646/// @param scope the scope under which the resulting scope must be.
8647///
8648/// @return the resulting scope.
8649const scope_decl*
8650get_top_most_scope_under(const decl_base_sptr decl,
8651 const scope_decl_sptr scope)
8652{return get_top_most_scope_under(decl, scope.get());}
8653
8654// </scope_decl stuff>
8655
8656
8657/// Get the string representation of a CV qualifier bitmap.
8658///
8659/// @param cv_quals the bitmap of CV qualifiers to consider.
8660///
8661/// @return the string representation.
8662string
8664{
8665 string repr;
8666 if (cv_quals & qualified_type_def::CV_RESTRICT)
8667 repr = "restrict";
8668 if (cv_quals & qualified_type_def::CV_CONST)
8669 {
8670 if (!repr.empty())
8671 repr += ' ';
8672 repr += "const";
8673 }
8674 if (cv_quals & qualified_type_def::CV_VOLATILE)
8675 {
8676 if (!repr.empty())
8677 repr += ' ';
8678 repr += "volatile";
8679 }
8680 return repr;
8681}
8682
8683/// Build and return a copy of the name of an ABI artifact that is
8684/// either a type or a decl.
8685///
8686/// @param tod the ABI artifact to get the name for.
8687///
8688/// @param qualified if yes, return the qualified name of @p tod;
8689/// otherwise, return the non-qualified name;
8690///
8691/// @return the name of @p tod.
8692string
8693get_name(const type_or_decl_base *tod, bool qualified)
8694{
8695 string result;
8696
8697 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8698
8699 if (type_base* t = dynamic_cast<type_base*>(a))
8700 result = get_type_name(t, qualified);
8701 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8702 {
8703 if (qualified)
8704 result = d->get_qualified_name();
8705 else
8706 result = d->get_name();
8707 }
8708 else
8709 // We should never reach this point.
8710 abort();
8711
8712 return result;
8713}
8714
8715/// Build and return a copy of the name of an ABI artifact that is
8716/// either a type of a decl.
8717///
8718/// @param tod the ABI artifact to get the name for.
8719///
8720/// @param qualified if yes, return the qualified name of @p tod;
8721/// otherwise, return the non-qualified name;
8722///
8723/// @return the name of @p tod.
8724string
8725get_name(const type_or_decl_base_sptr& tod, bool qualified)
8726{return get_name(tod.get(), qualified);}
8727
8728/// Build and return a qualified name from a name and its scope.
8729///
8730/// The name is supposed to be for an entity that is part of the
8731/// scope.
8732///
8733/// @param the scope to consider.
8734///
8735/// @param name of the name to consider.
8736///
8737/// @return a copy of the string that represents the qualified name.
8738string
8739build_qualified_name(const scope_decl* scope, const string& name)
8740{
8741 if (name.empty())
8742 return "";
8743
8744 string qualified_name;
8745 if (scope)
8746 qualified_name = scope->get_qualified_name();
8747
8748 if (qualified_name.empty())
8749 qualified_name = name;
8750 else
8751 qualified_name = qualified_name + "::" + name;
8752
8753 return qualified_name;
8754}
8755
8756/// Build and return the qualified name of a type in its scope.
8757///
8758/// @param scope the scope of the type to consider.
8759///
8760/// @param type the type to consider.
8761string
8762build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8763{return build_qualified_name(scope, get_name((type)));}
8764
8765// </scope_decl stuff>
8766
8767/// Get the location of the declaration of a given type.
8768///
8769/// @param type the type to consider.
8770///
8771/// @return the location of the declaration of type @p type.
8773get_location(const type_base_sptr& type)
8774{
8775 if (decl_base_sptr decl = get_type_declaration(type))
8776 return get_location(decl);
8777 return location();
8778}
8779
8780/// Get the location of a given declaration.
8781///
8782/// @param decl the declaration to consider.
8783///
8784/// @return the location of the declaration @p decl.
8786get_location(const decl_base_sptr& decl)
8787{
8788 location loc = decl->get_location();
8789 if (!loc)
8790 {
8791 if (class_or_union_sptr c = is_class_or_union_type(decl))
8792 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8793 {
8794 c = is_class_or_union_type(c->get_definition_of_declaration());
8795 loc = c->get_location();
8796 }
8797 }
8798 return loc;
8799}
8800
8801/// Get the scope of a given type.
8802///
8803/// @param t the type to consider.
8804///
8805/// @return the scope of type @p t or 0 if the type has no scope yet.
8808{
8809 if (!t)
8810 return 0;
8811
8813 if (d)
8814 return d->get_scope();
8815 return 0;
8816}
8817
8818/// Get the scope of a given type.
8819///
8820/// @param t the type to consider.
8821///
8822/// @return the scope of type @p t or 0 if the type has no scope yet.
8824get_type_scope(const type_base_sptr& t)
8825{return get_type_scope(t.get());}
8826
8827/// Get the name of a given type and return a copy of it.
8828///
8829/// @param t the type to consider.
8830///
8831/// @param qualified if true then return the qualified name of the
8832/// type.
8833///
8834/// @param internal set to true if the call is intended for an
8835/// internal use (for technical use inside the library itself), false
8836/// otherwise. If you don't know what this is for, then set it to
8837/// false.
8838///
8839/// @return a copy of the type name if the type has a name, or the
8840/// empty string if it does not.
8842get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8843{return get_type_name(t.get(), qualified, internal);}
8844
8845/// Return true iff a decl is for a type type that has a generic
8846/// anonymous internal type name.
8847///
8848/// @param d the decl to considier.
8849///
8850/// @return true iff @p d is for a type type that has a generic
8851/// anonymous internal type name.
8852static bool
8853has_generic_anonymous_internal_type_name(const decl_base *d)
8854{
8855 return (is_class_or_union_type(d)
8856 || is_enum_type(d)
8857 || is_subrange_type(d));
8858}
8859
8860/// Return the generic internal name of an anonymous type.
8861///
8862/// For internal purposes, we want to define a generic name for all
8863/// anonymous types of a certain kind. For instance, all anonymous
8864/// structs will be have a generic name of "__anonymous_struct__", all
8865/// anonymous unions will have a generic name of
8866/// "__anonymous_union__", etc.
8867///
8868/// That generic name can be used as a hash to put all anonymous types
8869/// of a certain kind in the same hash table bucket, for instance.
8870static interned_string
8871get_generic_anonymous_internal_type_name(const decl_base *d)
8872{
8873 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8874
8875 const environment&env = d->get_environment();
8876
8877 interned_string result;
8878 if (is_class_type(d))
8879 result =
8881 else if (is_union_type(d))
8882 result =
8884 else if (is_enum_type(d))
8885 result =
8887 else if (is_subrange_type(d))
8888 result =
8890 else
8892
8893 return result;
8894}
8895
8896/// Get the internal name for a given real type.
8897///
8898/// All real types that have the modifiers 'short, long or long
8899/// long' have the same internal name. This is so that they can all
8900/// have the same canonical type if they are of the same size.
8901/// Otherwise, 'long int' and 'long long int' would have different
8902/// canonical types even though they are equivalent from an ABI point
8903/// of view.
8904///
8905/// @param t the real type to consider
8906///
8907/// @return the internal name for @p t if it's an integral type, or
8908/// the empty string if @p t is not a real type.
8909static string
8910get_internal_real_type_name(const type_base* t)
8911{
8912 string name;
8913 type_decl *type = is_real_type(t);
8914
8915 if (!type)
8916 return name;
8917
8918 real_type int_type;
8919 if (parse_real_type(type->get_name(), int_type))
8920 name = int_type.to_string(/*internal=*/true);
8921
8922 return name;
8923}
8924
8925/// Get the name of a given type and return a copy of it.
8926///
8927/// @param t the type to consider.
8928///
8929/// @param qualified if true then return the qualified name of the
8930/// type.
8931///
8932/// @param internal set to true if the call is intended for an
8933/// internal use (for technical use inside the library itself), false
8934/// otherwise. If you don't know what this is for, then set it to
8935/// false.
8936///
8937/// @return a copy of the type name if the type has a name, or the
8938/// empty string if it does not.
8939interned_string
8940get_type_name(const type_base* t, bool qualified, bool internal)
8941{
8942 interned_string empty_string;
8943
8944 if (!t)
8945 return empty_string;
8946
8947 const decl_base* d = dynamic_cast<const decl_base*>(t);
8948 if (!d)
8949 {
8950 const function_type* fn_type = is_function_type(t);
8951 if (!fn_type)
8952 return empty_string;
8953 return fn_type->get_cached_name(internal);
8954 }
8955
8956 const environment&env = d->get_environment();
8957
8958 // All anonymous types of a given kind get to have the same internal
8959 // name for internal purpose. This to allow them to be compared
8960 // among themselves during type canonicalization.
8961 if (internal)
8962 {
8963 if (d->get_is_anonymous() && !is_type_decl(t))
8964 {
8965 // Note that anonymous type_decl that are used for
8966 // enumerators are not handled here because they don't have
8967 // generic internal type names.
8968 string r;
8969 r += get_generic_anonymous_internal_type_name(d);
8970 return t->get_environment().intern(r);
8971 }
8972
8973 if (is_typedef(t))
8974 return d->get_name();
8975
8976 if (qualified)
8977 return d->get_qualified_name(internal);
8978
8979 return env.intern(get_internal_real_type_name(t));
8980 }
8981
8982 if (d->get_is_anonymous())
8983 {
8985 return env.intern
8987 /*one_line=*/true,
8988 internal, qualified));
8989 }
8990
8991 if (qualified)
8992 return d->get_qualified_name(internal);
8993 return d->get_name();
8994}
8995
8996/// Get the name of a given type and return a copy of it.
8997///
8998/// @param t the type to consider.
8999///
9000/// @param qualified if true then return the qualified name of the
9001/// type.
9002///
9003/// @param internal set to true if the call is intended for an
9004/// internal use (for technical use inside the library itself), false
9005/// otherwise. If you don't know what this is for, then set it to
9006/// false.
9007///
9008/// @return a copy of the type name if the type has a name, or the
9009/// empty string if it does not.
9011get_type_name(const type_base& t, bool qualified, bool internal)
9012{return get_type_name(&t, qualified, internal);}
9013
9014/// Get the name of the pointer to a given type.
9015///
9016/// @param pointed_to_type the pointed-to-type to consider.
9017///
9018/// @param qualified this is true if the resulting name should be of a
9019/// pointer to a *fully-qualified* pointed-to-type.
9020///
9021/// @param internal true if the name is for libabigail-internal
9022/// purposes.
9023///
9024/// @return the name (string representation) of the pointer.
9027 bool qualified, bool internal)
9028{
9029 const environment& env = pointed_to_type.get_environment();
9030 string tn = get_type_name(pointed_to_type, qualified, internal);
9031 tn = tn + "*";
9032
9033 return env.intern(tn);
9034}
9035
9036/// Get the name of the reference to a given type.
9037///
9038/// @param pointed_to_type the pointed-to-type to consider.
9039///
9040/// @param qualified this is true if the resulting name should be of a
9041/// reference to a *fully-qualified* pointed-to-type.
9042///
9043/// @param internal true if the name is for libabigail-internal
9044/// purposes.
9045///
9046/// @return the name (string representation) of the reference.
9049 bool lvalue_reference,
9050 bool qualified, bool internal)
9051{
9052 const environment& env = pointed_to_type.get_environment();
9053
9054 string name = get_type_name(pointed_to_type, qualified, internal);
9055 if (lvalue_reference)
9056 name = name + "&";
9057 else
9058 name = name + "&&";
9059
9060 return env.intern(name);
9061}
9062
9063/// Get the name of a qualified type, given the underlying type and
9064/// its qualifiers.
9065///
9066/// @param underlying_type the underlying type to consider.
9067///
9068/// @param quals the CV qualifiers of the name.
9069///
9070/// @param qualified true if we should consider the fully qualified
9071/// name of @p underlying_type.
9072///
9073/// @param internal true if the result is to be used for
9074/// libabigail-internal purposes.
9075///
9076/// @return the name (string representation) of the qualified type.
9078get_name_of_qualified_type(const type_base_sptr& underlying_type,
9080 bool qualified, bool internal)
9081{
9082 const environment& env = underlying_type->get_environment();
9083
9084 string quals_repr = get_string_representation_of_cv_quals(quals);
9085 string name = get_type_name(underlying_type, qualified, internal);
9086
9087 if (quals_repr.empty() && internal)
9088 // We are asked to return the internal name, that might be used
9089 // for type canonicalization. For that canonicalization, we need
9090 // to make a difference between a no-op qualified type which
9091 // underlying type is foo (the qualified type is named "none
9092 // foo"), and the name of foo, which is just "foo".
9093 //
9094 // Please remember that this has to be kept in sync with what is
9095 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
9096 // change this code here, please change that code there too.
9097 quals_repr = "";
9098
9099 if (!quals_repr.empty())
9100 {
9101 if (is_pointer_type(peel_qualified_type(underlying_type))
9102 || is_reference_type(peel_qualified_type(underlying_type)))
9103 {
9104 name += " ";
9105 name += quals_repr;
9106 }
9107 else
9108 name = quals_repr + " " + name;
9109 }
9110
9111 return env.intern(name);
9112}
9113
9114/// Get the name of a given function type and return a copy of it.
9115///
9116/// @param fn_type the function type to consider.
9117///
9118/// @param internal set to true if the call is intended for an
9119/// internal use (for technical use inside the library itself), false
9120/// otherwise. If you don't know what this is for, then set it to
9121/// false.
9122///
9123/// @return a copy of the function type name
9126 bool internal)
9127{return get_function_type_name(fn_type.get(), internal);}
9128
9129/// Get the name of a given function type and return a copy of it.
9130///
9131/// @param fn_type the function type to consider.
9132///
9133/// @param internal set to true if the call is intended for an
9134/// internal use (for technical use inside the library itself), false
9135/// otherwise. If you don't know what this is for, then set it to
9136/// false.
9137///
9138/// @return a copy of the function type name
9141 bool internal)
9142{
9143 ABG_ASSERT(fn_type);
9144
9145 if (const method_type* method = is_method_type(fn_type))
9146 return get_method_type_name(method, internal);
9147
9148 return get_function_type_name(*fn_type, internal);
9149}
9150
9151/// Get the name of a given function type and return a copy of it.
9152///
9153/// @param fn_type the function type to consider.
9154///
9155/// @param internal set to true if the call is intended for an
9156/// internal use (for technical use inside the library itself), false
9157/// otherwise. If you don't know what this is for, then set it to
9158/// false.
9159///
9160/// @return a copy of the function type name
9163 bool internal)
9164{
9165 std::ostringstream o;
9166 // When the function name is used for internal purposes (e.g, for
9167 // canonicalization), we want its representation to stay the same,
9168 // regardless of typedefs. So let's strip typedefs from the return
9169 // type.
9170 type_base_sptr return_type = fn_type.get_return_type();
9171 const environment& env = fn_type.get_environment();
9172
9173 o << get_type_name(return_type, /*qualified=*/true, internal) << " ";
9174 stream_pretty_representation_of_fn_parms(fn_type, o,
9175 /*qualified=*/true,
9176 internal);
9177 return env.intern(o.str());
9178}
9179
9180/// Get the ID of a function, or, if the ID can designate several
9181/// different functions, get its pretty representation.
9182///
9183/// @param fn the function to consider
9184///
9185/// @return the function ID of pretty representation of @p fn.
9188{
9189 ABG_ASSERT(fn);
9190
9191 interned_string result = fn->get_environment().intern(fn->get_id());
9192
9193 if (const corpus *c = fn->get_corpus())
9194 {
9196 c->get_exported_decls_builder();
9197 if (b->fn_id_maps_to_several_fns(fn))
9198 result = fn->get_environment().intern(fn->get_pretty_representation());
9199 }
9200
9201 return result;
9202}
9203
9204/// Get the name of a given method type and return a copy of it.
9205///
9206/// @param fn_type the function type to consider.
9207///
9208/// @param internal set to true if the call is intended for an
9209/// internal use (for technical use inside the library itself), false
9210/// otherwise. If you don't know what this is for, then set it to
9211/// false.
9212///
9213/// @return a copy of the function type name
9216 bool internal)
9217{return get_method_type_name(fn_type.get(), internal);}
9218
9219/// Get the name of a given method type and return a copy of it.
9220///
9221/// @param fn_type the function type to consider.
9222///
9223/// @param internal set to true if the call is intended for an
9224/// internal use (for technical use inside the library itself), false
9225/// otherwise. If you don't know what this is for, then set it to
9226/// false.
9227///
9228/// @return a copy of the function type name
9231 bool internal)
9232{
9233 if (fn_type)
9234 return get_method_type_name(*fn_type, internal);
9235
9236 return interned_string();
9237}
9238
9239/// Get the name of a given method type and return a copy of it.
9240///
9241/// @param fn_type the function type to consider.
9242///
9243/// @param internal set to true if the call is intended for an
9244/// internal use (for technical use inside the library itself), false
9245/// otherwise. If you don't know what this is for, then set it to
9246/// false.
9247///
9248/// @return a copy of the function type name
9251 bool internal)
9252{
9253 std::ostringstream o;
9254 // When the function name is used for internal purposes (e.g, for
9255 // canonicalization), we want its representation to stay the same,
9256 // regardless of typedefs. So let's strip typedefs from the return
9257 // type.
9258 type_base_sptr return_type = fn_type.get_return_type();
9259
9260 const environment& env = fn_type.get_environment();
9261
9262 if (return_type)
9263 o << get_type_name(return_type, /*qualified=*/true, internal);
9264 else
9265 // There are still some abixml files out there in which "void"
9266 // can be expressed as an empty type.
9267 o << "void";
9268
9269 class_or_union_sptr class_type = fn_type.get_class_type();
9270 ABG_ASSERT(class_type);
9271
9272 o << " (" << class_type->get_qualified_name(internal) << "::*) ";
9273 stream_pretty_representation_of_fn_parms(fn_type, o,
9274 /*qualified=*/true,
9275 internal);
9276
9277 return env.intern(o.str());
9278}
9279
9280/// Build and return a copy of the pretty representation of an ABI
9281/// artifact that could be either a type of a decl.
9282///
9283/// param tod the ABI artifact to consider.
9284///
9285/// @param internal set to true if the call is intended for an
9286/// internal use (for technical use inside the library itself), false
9287/// otherwise. If you don't know what this is for, then set it to
9288/// false.
9289///
9290/// @return a copy of the pretty representation of an ABI artifact
9291/// that could be either a type of a decl.
9292string
9294{
9295 string result;
9296
9297 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9298 result = get_pretty_representation(t, internal);
9299 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9300 result = get_pretty_representation(d, internal);
9301 else
9302 // We should never reach this point
9303 abort();
9304
9305 return result;
9306}
9307
9308/// Build and return a copy of the pretty representation of an ABI
9309/// artifact that could be either a type of a decl.
9310///
9311/// param tod the ABI artifact to consider.
9312///
9313/// @param internal set to true if the call is intended for an
9314/// internal use (for technical use inside the library itself), false
9315/// otherwise. If you don't know what this is for, then set it to
9316/// false.
9317///
9318/// @return a copy of the pretty representation of an ABI artifact
9319/// that could be either a type of a decl.
9320string
9322{return get_pretty_representation(tod.get(), internal);}
9323
9324/// Get a copy of the pretty representation of a decl.
9325///
9326/// @param d the decl to consider.
9327///
9328/// @param internal set to true if the call is intended for an
9329/// internal use (for technical use inside the library itself), false
9330/// otherwise. If you don't know what this is for, then set it to
9331/// false.
9332///
9333/// @return the pretty representation of the decl.
9334string
9335get_pretty_representation(const decl_base* d, bool internal)
9336{
9337 if (!d)
9338 return "";
9339 return d->get_pretty_representation(internal);
9340}
9341
9342/// Get a copy of the pretty representation of a type.
9343///
9344/// @param d the type to consider.
9345///
9346/// @param internal set to true if the call is intended for an
9347/// internal use (for technical use inside the library itself), false
9348/// otherwise. If you don't know what this is for, then set it to
9349/// false.
9350///
9351/// @return the pretty representation of the type.
9352string
9353get_pretty_representation(const type_base* t, bool internal)
9354{
9355 if (!t)
9356 return "void";
9357 if (const function_type* fn_type = is_function_type(t))
9358 return get_pretty_representation(fn_type, internal);
9359
9360 const decl_base* d = get_type_declaration(t);
9361 ABG_ASSERT(d);
9362 return get_pretty_representation(d, internal);
9363}
9364
9365/// Get a copy of the pretty representation of a decl.
9366///
9367/// @param d the decl to consider.
9368///
9369/// @param internal set to true if the call is intended for an
9370/// internal use (for technical use inside the library itself), false
9371/// otherwise. If you don't know what this is for, then set it to
9372/// false.
9373///
9374/// @return the pretty representation of the decl.
9375string
9376get_pretty_representation(const decl_base_sptr& d, bool internal)
9377{return get_pretty_representation(d.get(), internal);}
9378
9379/// Get a copy of the pretty representation of a type.
9380///
9381/// @param d the type to consider.
9382///
9383/// @param internal set to true if the call is intended for an
9384/// internal use (for technical use inside the library itself), false
9385/// otherwise. If you don't know what this is for, then set it to
9386/// false.
9387///
9388/// @return the pretty representation of the type.
9389string
9390get_pretty_representation(const type_base_sptr& t, bool internal)
9391{return get_pretty_representation(t.get(), internal);}
9392
9393/// Get the pretty representation of a function type.
9394///
9395/// @param fn_type the function type to consider.
9396///
9397/// @param internal set to true if the call is intended for an
9398/// internal use (for technical use inside the library itself), false
9399/// otherwise. If you don't know what this is for, then set it to
9400/// false.
9401///
9402/// @return the string represenation of the function type.
9403string
9405 bool internal)
9406{return get_pretty_representation(fn_type.get(), internal);}
9407
9408/// Get the pretty representation of a function type.
9409///
9410/// @param fn_type the function type to consider.
9411///
9412/// @param internal set to true if the call is intended for an
9413/// internal use (for technical use inside the library itself), false
9414/// otherwise. If you don't know what this is for, then set it to
9415/// false.
9416///
9417/// @return the string represenation of the function type.
9418string
9419get_pretty_representation(const function_type* fn_type, bool internal)
9420{
9421 if (!fn_type)
9422 return "void";
9423
9424 if (const method_type* method = is_method_type(fn_type))
9425 return get_pretty_representation(method, internal);
9426
9427 return get_pretty_representation(*fn_type, internal);
9428}
9429
9430/// Get the pretty representation of a function type.
9431///
9432/// @param fn_type the function type to consider.
9433///
9434/// @param internal set to true if the call is intended for an
9435/// internal use (for technical use inside the library itself), false
9436/// otherwise. If you don't know what this is for, then set it to
9437/// false.
9438///
9439/// @return the string represenation of the function type.
9440string
9441get_pretty_representation(const function_type& fn_type, bool internal)
9442{
9443 std::ostringstream o;
9444 o << "function type " << get_function_type_name(fn_type, internal);
9445 return o.str();
9446}
9447
9448/// Get the pretty representation of a method type.
9449///
9450/// @param method the method type to consider.
9451///
9452/// @param internal set to true if the call is intended for an
9453/// internal use (for technical use inside the library itself), false
9454/// otherwise. If you don't know what this is for, then set it to
9455/// false.
9456///
9457/// @return the string represenation of the method type.
9458string
9459get_pretty_representation(const method_type& method, bool internal)
9460{
9461 std::ostringstream o;
9462 o << "method type " << get_method_type_name(method, internal);
9463 return o.str();
9464}
9465
9466/// Get the pretty representation of a method type.
9467///
9468/// @param method the method type to consider.
9469///
9470/// @param internal set to true if the call is intended for an
9471/// internal use (for technical use inside the library itself), false
9472/// otherwise. If you don't know what this is for, then set it to
9473/// false.
9474///
9475/// @return the string represenation of the method type.
9476string
9477get_pretty_representation(const method_type* method, bool internal)
9478{
9479 if (!method)
9480 return "void";
9481 return get_pretty_representation(*method, internal);
9482}
9483
9484/// Get the pretty representation of a method type.
9485///
9486/// @param method the method type to consider.
9487///
9488/// @param internal set to true if the call is intended for an
9489/// internal use (for technical use inside the library itself), false
9490/// otherwise. If you don't know what this is for, then set it to
9491/// false.
9492///
9493/// @return the string represenation of the method type.
9494string
9496{return get_pretty_representation(method.get(), internal);}
9497
9498/// Get the flat representation of an instance of @ref class_or_union
9499/// type.
9500///
9501/// The flat representation of a given @ref class_or_union type is the
9502/// actual definition of the type, for instance:
9503///
9504/// struct foo {int a; char b;}
9505///
9506///@param cou the instance of @ref class_or_union to consider.
9507///
9508///@param indent the identation spaces to use in the representation.
9509///
9510///@param one_line if true, then the flat representation stands on one
9511///line. Otherwise, it stands on multiple lines.
9512///
9513///@return the resulting flat representation.
9514string
9516 const string& indent,
9517 bool one_line,
9518 bool internal,
9519 bool qualified_names)
9520{
9521 string repr;
9522 string local_indent = " ";
9523
9524 if (class_decl* clazz = is_class_type(&cou))
9525 {
9526 repr = indent;
9527 if (!internal && clazz->is_struct())
9528 repr += "struct";
9529 else
9530 repr += "class";
9531 }
9532 else if (is_union_type(cou))
9533 repr = indent + "union";
9534 else
9535 return "";
9536
9537 repr += " ";
9538
9539 string name = cou.get_qualified_name();
9540
9541 if (!cou.get_is_anonymous())
9542 repr += name;
9543
9544 if (cou.priv_->is_printing_flat_representation())
9545 {
9546 // We have just detected a cycle while walking the sub-tree
9547 // of this class or union type for the purpose of printing
9548 // its flat representation. We need to get out of here
9549 // pronto or else we'll be spinning endlessly.
9550 repr += "{}";
9551 return repr;
9552 }
9553
9554 // Let's mark this class or union type to signify that we started
9555 // walking its sub-tree. This is to detect potential cycles and
9556 // avoid looping endlessly.
9558
9559 repr += "{";
9560
9561 if (!one_line)
9562 repr += "\n";
9563
9564 string real_indent;
9566 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9567 dm != dmems.end();
9568 ++dm)
9569 {
9570 if (dm != dmems.begin())
9571 {
9572 if (one_line)
9573 real_indent = " ";
9574 else
9575 real_indent = "\n" + indent + local_indent;
9576 }
9577
9579 repr +=
9582 real_indent, one_line, internal, qualified_names);
9583 else
9584 {
9585 if (one_line)
9586 {
9587 if (dm != dmems.begin())
9588 repr += real_indent;
9589 repr += (*dm)->get_pretty_representation(internal,
9590 qualified_names);
9591 }
9592 else
9593 repr +=
9594 real_indent+ (*dm)->get_pretty_representation(internal,
9595 qualified_names);
9596 }
9597 repr += ";";
9598 }
9599
9600 if (one_line)
9601 repr += "}";
9602 else
9603 repr += indent + "}";
9604
9605 // Let's unmark this class or union type to signify that we are done
9606 // walking its sub-tree. This was to detect potential cycles and
9607 // avoid looping endlessly.
9609
9610 return repr;
9611}
9612
9613/// Get the flat representation of an instance of @ref class_or_union
9614/// type.
9615///
9616/// The flat representation of a given @ref class_or_union type is the
9617/// actual definition of the type, for instance:
9618///
9619/// struct foo {int a; char b;}
9620///
9621///@param cou the instance of @ref class_or_union to consider.
9622///
9623///@param indent the identation spaces to use in the representation.
9624///
9625///@param one_line if true, then the flat representation stands on one
9626///line. Otherwise, it stands on multiple lines.
9627///
9628///@return the resulting flat representation.
9629string
9631 const string& indent,
9632 bool one_line,
9633 bool internal,
9634 bool qualified_names)
9635{
9636 if (cou)
9637 return get_class_or_union_flat_representation(*cou, indent, one_line,
9638 internal, qualified_names);
9639 return "";
9640}
9641
9642/// Get the flat representation of an instance of @ref class_or_union
9643/// type.
9644///
9645/// The flat representation of a given @ref class_or_union type is the
9646/// actual definition of the type, for instance:
9647///
9648/// struct foo {int a; char b;}
9649///
9650///@param cou the instance of @ref class_or_union to consider.
9651///
9652///@param indent the identation spaces to use in the representation.
9653///
9654///@param one_line if true, then the flat representation stands on one
9655///line. Otherwise, it stands on multiple lines.
9656///
9657///@return the resulting flat representation.
9658string
9659get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9660 const string& indent,
9661 bool one_line,
9662 bool internal,
9663 bool qualified_names)
9665 indent,
9666 one_line,
9667 internal,
9668 qualified_names);}
9669
9670/// Get the flat representation of an instance of @ref enum_type_decl
9671/// type.
9672///
9673/// The flat representation of a given @ref enum_type_decl type is the
9674/// actual definition of the type, for instance:
9675///
9676/// enum {E_0 =0, E_1 = 1}
9677///
9678///@param enum_type the enum type to consider.
9679///
9680///@param indent the identation spaces to use in the representation.
9681///
9682///@param one_line if true, then the flat representation stands on one
9683///line. Otherwise, it stands on multiple lines.
9684///
9685///@param qualified_names use qualified names when applicable.
9686///Typically, if this is true, the name of the enum is going to be
9687///qualified.
9688///
9689///@return the resulting flat representation.
9690string
9692 const string& indent, bool one_line,
9693 bool qualified_names)
9694{
9695 string repr;
9696 std::ostringstream o;
9697 string local_indent = " ";
9698
9699 repr = indent + "enum ";
9700
9701 if (!enum_type.get_is_anonymous())
9702 o << (qualified_names
9703 ? enum_type.get_qualified_name()
9704 : enum_type.get_name()) + " ";
9705
9706 o << "{";
9707
9708 if (!one_line)
9709 o << "\n";
9710
9711 for (const auto &enumerator : enum_type.get_sorted_enumerators())
9712 {
9713 if (!one_line)
9714 o << "\n" + indent;
9715
9716 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
9717 }
9718
9719 if (!one_line)
9720 o << "\n" + indent << "}";
9721 else
9722 o << "}";
9723
9724 repr =o.str();
9725
9726 return repr;
9727}
9728
9729/// Get the flat representation of an instance of @ref enum_type_decl
9730/// type.
9731///
9732/// The flat representation of a given @ref enum_type_decl type is the
9733/// actual definition of the type, for instance:
9734///
9735/// enum {E_0 =0, E_1 = 1}
9736///
9737///@param enum_type the enum type to consider.
9738///
9739///@param indent the identation spaces to use in the representation.
9740///
9741///@param one_line if true, then the flat representation stands on one
9742///line. Otherwise, it stands on multiple lines.
9743///
9744///@param qualified_names use qualified names when applicable.
9745///Typically, if this is true, the name of the enum is going to be
9746///qualified.
9747///
9748///@return the resulting flat representation.
9749string
9751 const string& indent, bool one_line,
9752 bool qualified_names)
9753{
9754 if (!enum_type)
9755 return "";
9756
9757 return get_enum_flat_representation(*enum_type, indent,
9758 one_line, qualified_names);
9759}
9760
9761/// Get the flat representation of an instance of @ref enum_type_decl
9762/// type.
9763///
9764/// The flat representation of a given @ref enum_type_decl type is the
9765/// actual definition of the type, for instance:
9766///
9767/// enum {E_0 =0, E_1 = 1}
9768///
9769///@param enum_type the enum type to consider.
9770///
9771///@param indent the identation spaces to use in the representation.
9772///
9773///@param one_line if true, then the flat representation stands on one
9774///line. Otherwise, it stands on multiple lines.
9775///
9776///@param qualified_names use qualified names when applicable.
9777///Typically, if this is true, the name of the enum is going to be
9778///qualified.
9779///
9780///@return the resulting flat representation.
9781string
9783 const string& indent, bool one_line,
9784 bool qualified_names)
9785{
9786 return get_enum_flat_representation(enum_type.get(),
9787 indent, one_line,
9788 qualified_names);
9789}
9790
9791/// Get the flat representation of an instance of @ref enum_type_decl
9792/// type.
9793///
9794/// The flat representation of a given @ref enum_type_decl type is the
9795/// actual definition of the type, for instance:
9796///
9797/// enum {E_0 =0, E_1 = 1}
9798///
9799///@param enum_type the enum type to consider.
9800///
9801///@param indent the identation spaces to use in the representation.
9802///
9803///@param one_line if true, then the flat representation stands on one
9804///line. Otherwise, it stands on multiple lines.
9805///
9806///@param qualified_names use qualified names when applicable.
9807///Typically, if this is true, the name of the enum is going to be
9808///qualified.
9809///
9810///@return the resulting flat representation.
9811string
9813 const string& indent,
9814 bool one_line,
9815 bool internal,
9816 bool qualified_name)
9817
9818{
9819 string repr;
9820 if (const class_or_union* cou = is_class_or_union_type(&coe))
9821 repr = get_class_or_union_flat_representation(cou, indent, one_line,
9822 internal, qualified_name);
9823 else if (const enum_type_decl* enom = is_enum_type(&coe))
9824 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9825
9826 return repr;
9827}
9828
9829/// Get the textual representation of a type for debugging purposes.
9830///
9831/// If the type is a class/union, this shows the data members, virtual
9832/// member functions, size, pointer value of its canonical type, etc.
9833/// Otherwise, this just shows the name of the artifact as returned by
9834/// type_or_decl_base:get_pretty_representation().
9835///
9836/// @param artifact the artifact to show a debugging representation of.
9837///
9838/// @return a debugging string representation of @p artifact.
9839string
9841{
9842 string nil_str;
9843 if (!artifact)
9844 return nil_str;
9845
9846 class_or_union * c = is_class_or_union_type(artifact);
9847 if (c)
9848 {
9849 class_decl *clazz = is_class_type(c);
9850 string name = c->get_qualified_name();
9851 std::ostringstream o;
9852 if (clazz)
9853 {
9854 if (clazz->is_struct())
9855 o << "struct ";
9856 else
9857 o << "class ";
9858 }
9859 else if (is_union_type(c))
9860 o << "union ";
9861 o << name;
9862
9863 if (clazz)
9864 {
9865 if (!clazz->get_base_specifiers().empty())
9866 o << " :" << std::endl;
9867 for (auto &b : clazz->get_base_specifiers())
9868 {
9869 o << " ";
9870 if (b->get_is_virtual())
9871 o << "virtual ";
9872 o << b->get_base_class()->get_qualified_name()
9873 << " // hash: ";
9874 hash_t h = peek_hash_value(*b->get_base_class());
9875 if (h)
9876 o << std::hex << *h << std::dec;
9877 else
9878 o << "none";
9879 o << std::endl;
9880 }
9881 }
9882 o << std::endl
9883 << "{"
9884 << " // size in bits: " << c->get_size_in_bits() << "\n"
9885 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9886 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9887 << " // translation unit: "
9888 << (c->get_translation_unit()
9890 : nil_str)
9891 << std::endl
9892 << " // @: " << std::hex << is_type(c)
9893 << ", @canonical: " << c->get_canonical_type().get() << std::dec << "\n"
9894 << " // hash: " ;
9895
9896 hash_t h = peek_hash_value(*c);
9897 if (h)
9898 o << std::hex << *h << std::dec;
9899 else
9900 o << "none";
9901 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*c);
9902 o << "\n\n";
9903
9904
9905 for (auto member_type : c->get_sorted_member_types())
9906 {
9907 o << " "
9908 << member_type->get_pretty_representation(/*internal=*/false,
9909 /*qualified=*/false)
9910 << ";";
9911 if (member_type->get_canonical_type())
9912 {
9913 o << " // uses canonical type: '@"
9914 << std::hex << member_type->get_canonical_type().get() << "'";
9915 o << " / h:";
9916 hash_t h = peek_hash_value(*member_type);
9917 o << std::hex << *h << std::dec;
9918 if (get_canonical_type_index(*member_type))
9919 o << "#" << get_canonical_type_index(*member_type);
9920 }
9921 o << "\n";
9922 }
9923
9924 if (!c->get_sorted_member_types().empty())
9925 o << std::endl;
9926
9927 for (auto m : c->get_data_members())
9928 {
9929 type_base_sptr t = m->get_type();
9931
9932 o << " "
9933 << m->get_pretty_representation(/*internal=*/false,
9934 /*qualified=*/false)
9935 << ";";
9936
9937 if (t && t->get_canonical_type())
9938 o << " // uses canonical type '@"
9939 << std::hex << t->get_canonical_type().get() << "'";
9940
9941 o << "/ h:";
9942 hash_t h = peek_hash_value(*m->get_type());
9943 if (h)
9944 o << std::hex << *h << std::dec;
9945 else
9946 o << "none";
9947 o << std::endl;
9948 }
9949
9950 if (!c->get_data_members().empty())
9951 o << std::endl;
9952
9953 if (clazz && clazz->has_vtable())
9954 {
9955 o << " // virtual member functions\n\n";
9956 for (auto f : clazz->get_virtual_mem_fns())
9957 {
9958 o << " " << f->get_pretty_representation(/*internal=*/false,
9959 /*qualified=*/false)
9960 << " // voffset: " << get_member_function_vtable_offset(f)
9961 << ", h: ";
9962 hash_t h = peek_hash_value(*f->get_type());
9963 if (h)
9964 o << std::hex << *h << std::dec;
9965 else
9966 o << "none";
9967 o << ";" << std::endl;
9968 }
9969 }
9970
9971 o << "};" << std::endl;
9972
9973 return o.str();
9974 }
9975 else if (const enum_type_decl* e = is_enum_type(artifact))
9976 {
9977 string name = e->get_qualified_name();
9978 std::ostringstream o;
9979 o << "enum " << name
9980 << " : "
9981 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9982 true)
9983 << "\n"
9984 << "{\n"
9985 << " // size in bits: " << e->get_size_in_bits() << "\n"
9986 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9987 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9988 << " // translation unit: "
9989 << e->get_translation_unit()->get_absolute_path() << "\n"
9990 << " // @: " << std::hex << is_type(e)
9991 << ", @canonical: " << e->get_canonical_type().get() << std::dec << "\n"
9992 << " // hash: ";
9993
9994 hash_t h = peek_hash_value(*e);
9995 if (h)
9996 o << std::hex << *h << std::dec;
9997 else
9998 o << "none";
9999 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*e);
10000 o << "\n\n";
10001
10002 for (const auto &enom : e->get_enumerators())
10003 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
10004
10005 o << "};\n";
10006
10007 return o.str();
10008 }
10009 else if (type_base *t = is_type(artifact))
10010 {
10011 std::ostringstream o;
10012 o << t->get_pretty_representation(/*internal=*/true,
10013 /*qualified=*/true)
10014 << " // cti: " << get_canonical_type_index(*t)
10015 << "\n";
10016 return o.str();
10017 }
10018
10019 return artifact->get_pretty_representation(/*internal=*/true,
10020 /*qualified=*/true);
10021}
10022
10023/// Get a given data member, referred to by its name, of a class type.
10024///
10025/// @param clazz the class to consider.
10026///
10027/// @param member_name name of the data member to get.
10028///
10029/// @return the resulting data member or nullptr if none was found.
10031get_data_member(class_or_union *clazz, const char* member_name)
10032{
10033 if (!clazz)
10034 return var_decl_sptr();
10035 return clazz->find_data_member(member_name);
10036}
10037
10038/// Get a given data member, referred to by its name, of a class type.
10039///
10040/// @param clazz the class to consider.
10041///
10042/// @param member_name name of the data member to get.
10043///
10044/// @return the resulting data member or nullptr if none was found.
10046get_data_member(type_base *clazz, const char* member_name)
10047{return get_data_member(is_class_or_union_type(clazz), member_name);}
10048
10049/// Get the non-artificial (natural) location of a decl.
10050///
10051/// If the decl doesn't have a natural location then return its
10052/// artificial one.
10053///
10054/// @param decl the decl to consider.
10055///
10056/// @return the natural location @p decl if it has one; otherwise,
10057/// return its artificial one.
10058const location&
10060{
10061 ABG_ASSERT(decl);
10062
10063 if (decl->get_location())
10064 return decl->get_location();
10065 return decl->get_artificial_location();
10066}
10067
10068/// Get the artificial location of a decl.
10069///
10070/// If the decl doesn't have an artificial location then return its
10071/// natural one.
10072///
10073/// @param decl the decl to consider.
10074///
10075/// @return the artificial location @p decl if it has one; otherwise,
10076/// return its natural one.
10077const location&
10079{
10080 ABG_ASSERT(decl);
10081
10082 if (decl->has_artificial_location())
10083 return decl->get_artificial_location();
10084 return decl->get_location();
10085}
10086
10087/// Emit a textual representation of an artifact to std error stream
10088/// for debugging purposes.
10089///
10090/// This is useful to invoke from within a command line debugger like
10091/// GDB to help make sense of a given ABI artifact.
10092///
10093/// @param artifact the ABI artifact to emit the debugging
10094/// representation for.
10095///
10096/// @return the artifact @p artifact.
10098debug(const type_or_decl_base* artifact)
10099{
10100 std::cerr << get_debug_representation(artifact) << std::endl;
10101 return const_cast<type_or_decl_base*>(artifact);
10102}
10103
10104/// Emit a textual representation of an artifact to std error stream
10105/// for debugging purposes.
10106///
10107/// This is useful to invoke from within a command line debugger like
10108/// GDB to help make sense of a given ABI artifact.
10109///
10110/// @param artifact the ABI artifact to emit the debugging
10111/// representation for.
10112///
10113/// @return the artifact @p artifact.
10114type_base*
10115debug(const type_base* artifact)
10116{
10117 debug(static_cast<const type_or_decl_base*>(artifact));
10118 return const_cast<type_base*>(artifact);
10119}
10120
10121/// Emit a textual representation of an artifact to std error stream
10122/// for debugging purposes.
10123///
10124/// This is useful to invoke from within a command line debugger like
10125/// GDB to help make sense of a given ABI artifact.
10126///
10127/// @param artifact the ABI artifact to emit the debugging
10128/// representation for.
10129///
10130/// @return the artifact @p artifact.
10131decl_base*
10132debug(const decl_base* artifact)
10133{
10134 debug(static_cast<const type_or_decl_base*>(artifact));
10135 return const_cast<decl_base*>(artifact);
10136}
10137
10138/// Test if two ABI artifacts are equal.
10139///
10140/// This can be useful when used from the command line of a debugger
10141/// like GDB.
10142///
10143/// @param l the first ABI artifact to consider in the comparison.
10144///
10145/// @param r the second ABI artifact to consider in the comparison.
10146///
10147/// @return true iff @p l equals @p r.
10148bool
10150{
10151 if (!!l != !!r)
10152 return false;
10153 if (!l && !r)
10154 return true;
10155
10156 return (*l == *r);
10157}
10158
10159/// Emit a trace of a comparison operand stack.
10160///
10161/// @param vect the operand stack to emit the trace for.
10162///
10163/// @param o the output stream to emit the trace to.
10164static void
10165debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
10166{
10167 for (auto t : vect)
10168 {
10169 o << "|" << t->get_pretty_representation()
10170 << "@" << std::hex << t << std::dec;
10171 }
10172 if (!vect.empty())
10173 o << "|";
10174}
10175
10176/// Construct a trace of the two comparison operand stacks.
10177///
10178/// @param the environment in which the comparison operand stacks are.
10179///
10180/// @return a string representing the trace.
10181static string
10182print_comp_stack(const environment& env)
10183{
10184 std::ostringstream o;
10185 o << "left-operands: ";
10186 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
10187 o << "\n" << "right-operands: ";
10188 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10189 o << "\n";
10190 return o.str();
10191}
10192
10193/// Emit a trace of the two comparison operands stack on the standard
10194/// error stream.
10195///
10196/// @param env the environment the comparison operands stack belong
10197/// to.
10198void
10200{
10201 std::cerr << print_comp_stack(env);
10202 std::cerr << std::endl;
10203}
10204
10205/// By looking at the language of the TU a given ABI artifact belongs
10206/// to, test if the ONE Definition Rule should apply.
10207///
10208/// To date, it applies to c++, java and ada.
10209///
10210/// @param artifact the ABI artifact to consider.
10211///
10212/// @return true iff the One Definition Rule should apply.
10213bool
10215{
10216 if (!artifact.get_translation_unit())
10217 return false;
10218
10220 artifact.get_translation_unit()->get_language();
10221
10223 || is_java_language(l)
10224 || is_ada_language(l))
10225 return true;
10226
10227 return false;
10228}
10229
10230/// Get the declaration for a given type.
10231///
10232/// @param t the type to consider.
10233///
10234/// @return the declaration for the type to return.
10235const decl_base*
10237{return dynamic_cast<const decl_base*>(t);}
10238
10239/// Get the declaration for a given type.
10240///
10241/// @param t the type to consider.
10242///
10243/// @return the declaration for the type to return.
10244decl_base*
10246{return dynamic_cast<decl_base*>(t);}
10247
10248/// Get the declaration for a given type.
10249///
10250/// @param t the type to consider.
10251///
10252/// @return the declaration for the type to return.
10253decl_base_sptr
10254get_type_declaration(const type_base_sptr t)
10255{return dynamic_pointer_cast<decl_base>(t);}
10256
10257/// Test if two classes have the same layout.
10258///
10259/// Test if all the types and offsets of the members are equal,
10260/// regardless of their access modifiers.
10261///
10262/// @param f the first class to take into account.
10263///
10264/// @param s the second class to take into account.
10265///
10266/// @return true iff @p s and @p f are class types with the same
10267/// layout.
10268bool
10269classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
10270{
10271#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10272#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10273#endif
10274
10275#ifdef ENSURE_NO_ENDLESS_LOOP
10276#undef ENSURE_NO_ENDLESS_LOOP
10277#endif
10278
10279#define RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(VALUE) \
10280 do \
10281 { \
10282 auto t1 = is_class_or_union_type(f); \
10283 auto t2 = is_class_or_union_type(s); \
10284 t1->priv_->comparing_class_layouts_.erase(t2.get()); \
10285 t2->priv_->comparing_class_layouts_.erase(t1.get()); \
10286 return VALUE; \
10287 } while (false)
10288
10289#define ENSURE_NO_ENDLESS_LOOP \
10290 do \
10291 { \
10292 auto t1 = is_class_or_union_type(f); \
10293 auto t2 = is_class_or_union_type(s); \
10294 const auto& END = t1->priv_->comparing_class_layouts_.end(); \
10295 if (t1->priv_->comparing_class_layouts_.find(t2.get()) != END \
10296 || t2->priv_->comparing_class_layouts_.find(t1.get()) != END) \
10297 return true; \
10298 t1->priv_->comparing_class_layouts_.insert(t2.get()); \
10299 t2->priv_->comparing_class_layouts_.insert(t1.get()); \
10300 } while (false)
10301
10304
10305 if (!fc
10306 || !sc
10307 || (fc->get_qualified_name() != sc->get_qualified_name())
10308 || (fc->get_size_in_bits() != sc->get_size_in_bits())
10309 || (fc->get_data_members().size() != sc->get_data_members().size()))
10310 return false;
10311
10312 if (*fc == *sc)
10313 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
10314
10315 // Compare the types and offsets of data members one by one.
10316 for (auto f_decl_it = fc->get_data_members().begin(),
10317 s_decl_it = sc->get_data_members().begin();
10318 (f_decl_it != fc->get_data_members().end()
10319 && s_decl_it != sc->get_data_members().end());
10320 ++f_decl_it, ++s_decl_it)
10321 {
10322 var_decl_sptr dm1 = *f_decl_it, dm2 = *s_decl_it;
10323 type_base_sptr dm1_type = dm1->get_type(), dm2_type = dm2->get_type();
10324
10325 if (*dm1_type != *dm2_type
10327 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10328 }
10329
10330 // Compare the layout of base types
10331 for (auto f_bs_it = fc->get_base_specifiers().begin(),
10332 s_bs_it = sc->get_base_specifiers().end();
10333 (f_bs_it != fc->get_base_specifiers().end()
10334 && s_bs_it != sc->get_base_specifiers().end());
10335 ++f_bs_it, ++s_bs_it)
10336 {
10337 class_decl::base_spec_sptr f_bs = *f_bs_it, s_bs = *s_bs_it;
10338 if ((f_bs->get_is_virtual() != s_bs->get_is_virtual())
10339 || (f_bs->get_offset_in_bits() != s_bs->get_offset_in_bits()))
10340 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10341
10342 class_decl_sptr fb = f_bs->get_base_class(), sb = s_bs->get_base_class();
10343 if (!classes_have_same_layout(fb, sb))
10344 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10345 }
10346
10347 if (fc->has_vtable() != sc->has_vtable())
10348 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10349
10350 // Compare virtual function types
10351 ENSURE_NO_ENDLESS_LOOP;
10352 if (fc->has_vtable())
10353 {
10354 if (fc->get_virtual_mem_fns().size() > sc->get_virtual_mem_fns().size())
10355 // Some virtual member function got removed. Bad.
10356 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10357
10358 for (auto it1 = fc->get_virtual_mem_fns().begin(),
10359 it2 = sc->get_virtual_mem_fns().begin();
10360 (it1 != fc->get_virtual_mem_fns().end()
10361 && it2 != sc->get_virtual_mem_fns().end());
10362 ++it1, ++it2)
10363 {
10364 method_decl_sptr method1 = *it1;
10365 method_decl_sptr method2 = *it2;
10366
10369 || !types_are_compatible(method1->get_type(),
10370 method2->get_type()))
10371 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10372 }
10373 }
10374
10375 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
10376
10377#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10378#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10379#endif
10380
10381#ifdef ENSURE_NO_ENDLESS_LOOP
10382#undef ENSURE_NO_ENDLESS_LOOP
10383#endif
10384}
10385
10386/// Test if two types are equal modulo a typedef or CV qualifiers.
10387///
10388/// Type A and B are compatible if
10389///
10390/// - A and B are equal
10391/// - or A and B are integral types with harmless name change
10392/// - or if one type is a typedef of the other one.
10393/// - or if one type is the CV qualified version of the other
10394/// - or if A and B are classes with the same layout.
10395/// - or if A and B are pointers, references or arrays of
10396/// compatible types
10397///
10398/// @param type1 the first type to consider.
10399///
10400/// @param type2 the second type to consider.
10401///
10402/// @return true iff @p type1 and @p type2 are compatible.
10403bool
10404types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
10405{
10406 if (!type1 || !type2)
10407 return false;
10408
10409 if (type1 == type2 || *type1 == *type2)
10410 return true;
10411
10412 type_base_sptr t1 = peel_qualified_or_typedef_type(type1);
10413 type_base_sptr t2 = peel_qualified_or_typedef_type(type2);
10414
10415 if (t1 && t2 && *t1 == *t2)
10416 return true;
10417
10419 return true;
10420
10421 if (is_pointer_type(t1) && is_pointer_type(t2))
10422 {
10425 return types_are_compatible(t1, t2);
10426 }
10427
10428 if (is_reference_type(t1) && is_reference_type(t2))
10429 {
10430 t1 = is_reference_type(t1)->get_pointed_to_type();
10431 t2 = is_reference_type(t2)->get_pointed_to_type();
10432 return types_are_compatible(t1, t2);
10433 }
10434
10435 if (is_array_type(t1) && is_array_type(t2))
10436 {
10439 type_base_sptr e1 = a1->get_element_type();
10440 type_base_sptr e2 = a2->get_element_type();
10443
10444 if ((a1->get_size_in_bits() != a2->get_size_in_bits())
10445 || (a1->get_dimension_count() != a2->get_dimension_count())
10446 || !types_are_compatible(e1, e2))
10447 return false;
10448
10449 return true;
10450 }
10451
10452 if (function_type_sptr fn_type1 = is_function_type(t1))
10453 if (function_type_sptr fn_type2 = is_function_type(t2))
10454 {
10455 // Compare return types
10456 if (!types_are_compatible(fn_type1->get_return_type(),
10457 fn_type2->get_return_type()))
10458 return false;
10459
10460 // Compare parameter types, omitting the implicit parameter to
10461 // avoid infinite recursion when we are being called from
10462 // classes_have_same_layout on classes with virtual member
10463 // functions.
10464 if (fn_type1->get_parameters().size()
10465 != fn_type2->get_parameters().size())
10466 return false;
10467
10468 for (auto p1 = fn_type1->get_first_non_implicit_parm(),
10469 p2 = fn_type2->get_first_non_implicit_parm();
10470 (p1 != fn_type1->get_parameters().end()
10471 && p2 != fn_type2->get_parameters().end());
10472 ++p1, ++p2)
10473 if (!types_are_compatible((*p1)->get_type(),
10474 (*p2)->get_type()))
10475 return false;
10476
10477 return true;
10478 }
10479
10480 if (classes_have_same_layout(t1, t2))
10481 return true;
10482
10483 return false;
10484}
10485
10486/// Test if two types are equal modulo a typedef.
10487///
10488/// Type A and B are compatible if
10489///
10490/// - A and B are equal
10491/// - or if one type is a typedef of the other one.
10492///
10493/// @param type1 the declaration of the first type to consider.
10494///
10495/// @param type2 the declaration of the second type to consider.
10496///
10497/// @return true iff @p type1 and @p type2 are compatible.
10498bool
10499types_are_compatible(const decl_base_sptr d1,
10500 const decl_base_sptr d2)
10501{return types_are_compatible(is_type(d1), is_type(d2));}
10502
10503/// Return the translation unit a declaration belongs to.
10504///
10505/// @param decl the declaration to consider.
10506///
10507/// @return the resulting translation unit, or null if the decl is not
10508/// yet added to a translation unit.
10511{
10512 translation_unit* result =
10513 const_cast<translation_unit*>(t.get_translation_unit());
10514
10515 if (result)
10516 return result;
10517
10518 if (decl_base* decl = is_decl(&t))
10519 {
10520 scope_decl* scope = decl->get_scope();
10521 while (scope)
10522 {
10523 result = scope->get_translation_unit();
10524 if (result)
10525 break;
10526 scope = scope->get_scope();
10527 }
10528 }
10529
10530 return result;
10531}
10532
10533/// Return the translation unit a declaration belongs to.
10534///
10535/// @param decl the declaration to consider.
10536///
10537/// @return the resulting translation unit, or null if the decl is not
10538/// yet added to a translation unit.
10541{return decl ? get_translation_unit(*decl) : nullptr;}
10542
10543/// Return the translation unit a declaration belongs to.
10544///
10545/// @param decl the declaration to consider.
10546///
10547/// @return the resulting translation unit, or null if the decl is not
10548/// yet added to a translation unit.
10552
10553/// Tests whether if a given scope is the global scope.
10554///
10555/// @param scope the scope to consider.
10556///
10557/// @return true iff the current scope is the global one.
10558bool
10560{return !!dynamic_cast<const global_scope*>(&scope);}
10561
10562/// Tests whether if a given scope is the global scope.
10563///
10564/// @param scope the scope to consider.
10565///
10566/// @return the @ref global_scope* representing the scope @p scope or
10567/// 0 if @p scope is not a global scope.
10568const global_scope*
10570{return dynamic_cast<const global_scope*>(scope);}
10571
10572/// Tests whether if a given scope is the global scope.
10573///
10574/// @param scope the scope to consider.
10575///
10576/// @return true iff the current scope is the global one.
10577bool
10578is_global_scope(const shared_ptr<scope_decl>scope)
10579{return is_global_scope(scope.get());}
10580
10581/// Tests whether a given declaration is at global scope.
10582///
10583/// @param decl the decl to consider.
10584///
10585/// @return true iff decl is at global scope.
10586bool
10588{return (is_global_scope(decl.get_scope()));}
10589
10590/// Tests whether a given declaration is at global scope.
10591///
10592/// @param decl the decl to consider.
10593///
10594/// @return true iff decl is at global scope.
10595bool
10596is_at_global_scope(const decl_base_sptr decl)
10597{return (decl && is_global_scope(decl->get_scope()));}
10598
10599/// Tests whether a given declaration is at global scope.
10600///
10601/// @param decl the decl to consider.
10602///
10603/// @return true iff decl is at global scope.
10604bool
10606{return is_at_global_scope(*decl);}
10607
10608/// Tests whether a given decl is at class scope.
10609///
10610/// @param decl the decl to consider.
10611///
10612/// @return true iff decl is at class scope.
10614is_at_class_scope(const decl_base_sptr decl)
10615{return is_at_class_scope(decl.get());}
10616
10617/// Tests whether a given decl is at class scope.
10618///
10619/// @param decl the decl to consider.
10620///
10621/// @return true iff decl is at class scope.
10624{
10625 if (!decl)
10626 return 0;
10627
10628 return is_at_class_scope(*decl);
10629}
10630
10631/// Tests whether a given decl is at class scope.
10632///
10633/// @param decl the decl to consider.
10634///
10635/// @return true iff decl is at class scope.
10638{
10639 scope_decl* scope = decl.get_scope();
10640 if (class_or_union* cl = is_class_type(scope))
10641 return cl;
10642 if (class_or_union* cl = is_union_type(scope))
10643 return cl;
10644 return 0;
10645}
10646
10647/// Find a data member inside an anonymous data member.
10648///
10649/// An anonymous data member has a type which is a class or union.
10650/// This function looks for a data member inside the type of that
10651/// anonymous data member.
10652///
10653/// @param anon_dm the anonymous data member to consider.
10654///
10655/// @param name the name of the data member to look for.
10658 const string& name)
10659{
10660 const class_or_union* containing_class_or_union =
10662
10663 if (!containing_class_or_union)
10664 return var_decl_sptr();
10665
10666 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10667 return result;
10668}
10669
10670/// Tests whether a given decl is at template scope.
10671///
10672/// Note that only template parameters , types that are compositions,
10673/// and template patterns (function or class) can be at template scope.
10674///
10675/// @param decl the decl to consider.
10676///
10677/// @return true iff the decl is at template scope.
10678bool
10679is_at_template_scope(const shared_ptr<decl_base> decl)
10680{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10681
10682/// Tests whether a decl is a template parameter.
10683///
10684/// @param decl the decl to consider.
10685///
10686/// @return true iff decl is a template parameter.
10687bool
10688is_template_parameter(const shared_ptr<decl_base> decl)
10689{
10690 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10691 || dynamic_pointer_cast<non_type_tparameter>(decl)
10692 || dynamic_pointer_cast<template_tparameter>(decl)));
10693}
10694
10695/// Test whether a declaration is a @ref function_decl.
10696///
10697/// @param d the declaration to test for.
10698///
10699/// @return a shared pointer to @ref function_decl if @p d is a @ref
10700/// function_decl. Otherwise, a nil shared pointer.
10703{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10704
10705/// Test whether a declaration is a @ref function_decl.
10706///
10707/// @param d the declaration to test for.
10708///
10709/// @return true if @p d is a function_decl.
10710bool
10713
10714/// Test whether a declaration is a @ref function_decl.
10715///
10716/// @param d the declaration to test for.
10717///
10718/// @return a shared pointer to @ref function_decl if @p d is a @ref
10719/// function_decl. Otherwise, a nil shared pointer.
10722{return dynamic_pointer_cast<function_decl>(d);}
10723
10724/// Test whether a declaration is a @ref function_decl.
10725///
10726/// @param d the declaration to test for.
10727///
10728/// @return a pointer to @ref function_decl if @p d is a @ref
10729/// function_decl. Otherwise, a nil shared pointer.
10732{
10733 return dynamic_cast<function_decl::parameter*>
10734 (const_cast<type_or_decl_base*>(tod));
10735}
10736
10737/// Test whether an ABI artifact is a @ref function_decl.
10738///
10739/// @param tod the declaration to test for.
10740///
10741/// @return a pointer to @ref function_decl if @p d is a @ref
10742/// function_decl. Otherwise, a nil shared pointer.
10745{return dynamic_pointer_cast<function_decl::parameter>(tod);}
10746
10747/// Test if an ABI artifact is a declaration.
10748///
10749/// @param d the artifact to consider.
10750///
10751/// @param return the declaration sub-object of @p d if it's a
10752/// declaration, or NULL if it is not.
10753decl_base*
10755{
10756 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10757 {
10758 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10759 // The artifact is a decl-only (like a function or a
10760 // variable). That is, it's not a type that also has a
10761 // declaration. In this case, we are in the fast path and we
10762 // have a pointer to the decl sub-object handy. Just return
10763 // it ...
10764 return reinterpret_cast<decl_base*>
10765 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10766
10767 // ... Otherwise, we are in the slow path, which is that the
10768 // artifact is a type which has a declaration. In that case,
10769 // let's use the slow dynamic_cast because we don't have the
10770 // pointer to the decl sub-object handily present.
10771 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10772 }
10773 return 0;
10774}
10775
10776/// Test if an ABI artifact is a declaration.
10777///
10778/// @param d the artifact to consider.
10779///
10780/// @param return the declaration sub-object of @p d if it's a
10781/// declaration, or NULL if it is not.
10782decl_base_sptr
10784{return dynamic_pointer_cast<decl_base>(d);}
10785
10786/// Test if an ABI artifact is a declaration.
10787///
10788/// This is done using a slow path that uses dynamic_cast.
10789///
10790/// @param d the artifact to consider.
10791///
10792/// @param return the declaration sub-object of @p d if it's a
10793decl_base*
10795{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10796
10797/// Test if an ABI artifact is a declaration.
10798///
10799/// This is done using a slow path that uses dynamic_cast.
10800///
10801/// @param d the artifact to consider.
10802///
10803/// @param return the declaration sub-object of @p d if it's a
10804decl_base_sptr
10806{return dynamic_pointer_cast<decl_base>(t);}
10807
10808/// Test whether a declaration is a type.
10809///
10810/// @param d the IR artefact to test for.
10811///
10812/// @return true if the artifact is a type, false otherwise.
10813bool
10815{
10816 if (dynamic_cast<const type_base*>(&tod))
10817 return true;
10818 return false;
10819}
10820
10821/// Test whether a declaration is a type.
10822///
10823/// @param d the IR artefact to test for.
10824///
10825/// @return true if the artifact is a type, false otherwise.
10826type_base*
10828{
10829 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10830 return reinterpret_cast<type_base*>
10831 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10832
10833 return 0;
10834}
10835
10836/// Test whether a declaration is a type.
10837///
10838/// @param d the IR artefact to test for.
10839///
10840/// @return true if the artifact is a type, false otherwise.
10841type_base_sptr
10843{return dynamic_pointer_cast<type_base>(tod);}
10844
10845/// Test whether a declaration is a type.
10846///
10847/// @param d the declaration to test for.
10848///
10849/// @return true if the declaration is a type, false otherwise.
10850
10851/// Test if a given type is anonymous.
10852///
10853/// Note that this function considers that an anonymous class that is
10854/// named by a typedef is not anonymous anymore. This is the C idiom:
10855///
10856/// typedef struct {int member;} s_type;
10857///
10858/// The typedef s_type becomes the name of the originally anonymous
10859/// struct.
10860///
10861/// @param t the type to consider.
10862///
10863/// @return true iff @p t is anonymous.
10864bool
10866{
10867 const decl_base* d = get_type_declaration(t);
10868 if (d)
10869 if (d->get_is_anonymous())
10870 {
10872 {
10873 // An anonymous class that is named by a typedef is not
10874 // considered anonymous anymore.
10875 if (!cou->get_naming_typedef())
10876 return true;
10877 }
10878 else
10879 return true;
10880 }
10881 return false;
10882}
10883
10884/// Test if a given type is anonymous.
10885///
10886/// @param t the type to consider.
10887///
10888/// @return true iff @p t is anonymous.
10889bool
10890is_anonymous_type(const type_base_sptr& t)
10891{return is_anonymous_type(t.get());}
10892
10893/// Test if a type is a neither a pointer, an array nor a function
10894/// type.
10895///
10896/// @param t the type to consider.
10897///
10898/// @return true if the @p t is NOT a pointer, an array nor a
10899/// function.
10900bool
10901is_npaf_type(const type_base_sptr& t)
10902{
10903 if (!(is_pointer_type(t)
10904 || is_array_type(t)
10905 || is_function_type(t)
10906 || is_ptr_to_mbr_type(t)))
10907 return true;
10908 return false;
10909}
10910
10911/// Test whether a type is a type_decl (a builtin type).
10912///
10913/// @return the type_decl* for @t if it's type_decl, otherwise, return
10914/// nil.
10915const type_decl*
10917{return dynamic_cast<const type_decl*>(t);}
10918
10919/// Test whether a type is a type_decl (a builtin type).
10920///
10921/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10922/// return nil.
10925{return dynamic_pointer_cast<type_decl>(t);}
10926
10927/// Test if a type is a real type.
10928///
10929/// @param t the type to test.
10930///
10931/// @return the real type @p t can be converted to, or nil if @p
10932/// is not a real type.
10933type_decl*
10935{
10936 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10937 if (!type)
10938 return nullptr;
10939
10940 real_type int_type;
10941 if (!parse_real_type(type->get_name(), int_type))
10942 return nullptr;
10943
10944 return type;
10945}
10946
10947/// Test if a type is a real type.
10948///
10949/// @param t the type to test.
10950///
10951/// @return the real type @p t can be converted to, or nil if @p is
10952/// not a real type.
10955{
10956 const type_decl_sptr type = is_type_decl(t);
10957 if (!type)
10958 return type_decl_sptr();
10959
10960 real_type int_type;
10961 if (!parse_real_type(type->get_name(), int_type))
10962 return type_decl_sptr();
10963
10964 return type;
10965}
10966
10967/// Test if a type is an integral type.
10968///
10969/// @param t the type to test.
10970///
10971/// @return the integral type @p t can be converted to, or nil if @p
10972/// is not an integral type.
10973type_decl*
10975{
10976 type_decl* type = is_real_type(t);
10977 if (!type)
10978 return nullptr;
10979
10980 real_type rt;
10981 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10984 return nullptr;
10985
10986 return type;
10987}
10988
10989/// Test if a type is an integral type.
10990///
10991/// @param t the type to test.
10992///
10993/// @return the integral type @p t can be converted to, or nil if @p
10994/// is not an integral type.
10997{
10998 type_decl_sptr type = is_real_type(t);
10999 if (!type)
11000 return type;
11001
11002 real_type rt;
11003 ABG_ASSERT(parse_real_type(type->get_name(), rt));
11006 return type_decl_sptr();
11007
11008 return type;
11009}
11010
11011/// Test whether a type is a typedef.
11012///
11013/// @param t the type to test for.
11014///
11015/// @return the typedef declaration of the @p t, or NULL if it's not a
11016/// typedef.
11019{return dynamic_pointer_cast<typedef_decl>(t);}
11020
11021/// Test whether a type is a typedef.
11022///
11023/// @param t the declaration of the type to test for.
11024///
11025/// @return the typedef declaration of the @p t, or NULL if it's not a
11026/// typedef.
11027const typedef_decl*
11029{return dynamic_cast<const typedef_decl*>(t);}
11030
11031/// Test whether a type is a typedef.
11032///
11033/// @param t the declaration of the type to test for.
11034///
11035/// @return the typedef declaration of the @p t, or NULL if it's not a
11036/// typedef.
11039{return dynamic_cast<typedef_decl*>(t);}
11040
11041/// Test whether a type is a typedef.
11042///
11043/// @param t the declaration of the type to test for.
11044///
11045/// @return the typedef declaration of the @p t, or NULL if it's not a
11046/// typedef.
11047const typedef_decl*
11049{return dynamic_cast<const typedef_decl*>(t);}
11050
11051/// Test if a type is an enum. This function looks through typedefs.
11052///
11053/// @parm t the type to consider.
11054///
11055/// @return the enum_decl if @p t is an @ref enum_decl or null
11056/// otherwise.
11057const enum_type_decl*
11059{
11060 if (!t)
11061 return nullptr;
11062
11063 type_base* ty = const_cast<type_base*>(peel_typedef_type(t));
11064 return is_enum_type(ty);
11065}
11066
11067/// Test if a type is an enum. This function looks through typedefs.
11068///
11069/// @parm t the type to consider.
11070///
11071/// @return the enum_decl if @p t is an @ref enum_decl or null
11072/// otherwise.
11074is_compatible_with_enum_type(const type_base_sptr& t)
11075{
11076 if (!t)
11077 return enum_type_decl_sptr();
11078
11079 // Normally we should strip typedefs entirely, but this is
11080 // potentially costly, especially on binaries with huge changesets
11081 // like the Linux Kernel. So we just get the leaf types for now.
11082 //
11083 // Maybe there should be an option by which users accepts to pay the
11084 // CPU usage toll in exchange for finer filtering?
11085
11086 // type_base_sptr ty = strip_typedef(t);
11087 type_base_sptr ty = peel_typedef_type(t);;
11088 return is_enum_type(ty);
11089}
11090
11091/// Test if a type is an enum. This function looks through typedefs.
11092///
11093/// @parm t the type to consider.
11094///
11095/// @return the enum_decl if @p t is an @ref enum_decl or null
11096/// otherwise.
11098is_compatible_with_enum_type(const decl_base_sptr& t)
11100
11101/// Test if a decl is an enum_type_decl
11102///
11103/// @param d the decl to test for.
11104///
11105/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
11106const enum_type_decl*
11108{return dynamic_cast<const enum_type_decl*>(d);}
11109
11110/// Test if a decl is an enum_type_decl
11111///
11112/// @param d the decl to test for.
11113///
11114/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
11117{return dynamic_pointer_cast<enum_type_decl>(d);}
11118
11119/// Test if a type is a class. This function looks through typedefs.
11120///
11121/// @parm t the type to consider.
11122///
11123/// @return the class_decl if @p t is a class_decl or null otherwise.
11124const class_decl*
11126{
11127 if(!t)
11128 return nullptr;
11129
11130 const type_base* ty = peel_typedef_type(t);
11131 return is_class_type(ty);
11132}
11133
11134/// Test if a type is a class. This function looks through typedefs.
11135///
11136/// @parm t the type to consider.
11137///
11138/// @return the class_decl if @p t is a class_decl or null otherwise.
11140is_compatible_with_class_type(const type_base_sptr& t)
11141{
11142 if (!t)
11143 return class_decl_sptr();
11144
11145 // Normally we should strip typedefs entirely, but this is
11146 // potentially costly, especially on binaries with huge changesets
11147 // like the Linux Kernel. So we just get the leaf types for now.
11148 //
11149 // Maybe there should be an option by which users accepts to pay the
11150 // CPU usage toll in exchange for finer filtering?
11151
11152 // type_base_sptr ty = strip_typedef(t);
11153 type_base_sptr ty = peel_typedef_type(t);
11154 return is_class_type(ty);
11155}
11156
11157/// Test if a type is a class. This function looks through typedefs.
11158///
11159/// @parm t the type to consider.
11160///
11161/// @return the class_decl if @p t is a class_decl or null otherwise.
11163is_compatible_with_class_type(const decl_base_sptr& t)
11165
11166/// Test whether a type is a class.
11167///
11168/// @parm t the type to consider.
11169///
11170/// @return true iff @p t is a class_decl.
11171bool
11173{return is_class_type(&t);}
11174
11175/// Test whether a type is a class.
11176///
11177/// @parm t the type to consider.
11178///
11179/// @return the class_decl if @p t is a class_decl or null otherwise.
11182{
11183 if (!t)
11184 return 0;
11185
11186 if (t->kind() & type_or_decl_base::CLASS_TYPE)
11187 return reinterpret_cast<class_decl*>
11188 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
11189
11190 return 0;
11191}
11192
11193/// Test whether a type is a class.
11194///
11195/// @parm t the type to consider.
11196///
11197/// @return the class_decl if @p t is a class_decl or null otherwise.
11200{return dynamic_pointer_cast<class_decl>(d);}
11201
11202/// Test if the last data member of a class is an array with
11203/// non-finite data member.
11204///
11205/// The flexible data member idiom is a well known C idiom:
11206/// https://en.wikipedia.org/wiki/Flexible_array_member.
11207///
11208/// @param klass the class to consider.
11209///
11210/// @return the data member which type is a flexible array, if any, or
11211/// nil.
11214{
11215 var_decl_sptr nil;
11217 if (dms.empty())
11218 return nil;
11219
11220 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11221 {// The type of the last data member is an array.
11222 if (array->is_non_finite())
11223 // The array has a non-finite size. We are thus looking at a
11224 // flexible array data member. Let's return it.
11225 return dms.back();
11226 }
11227
11228 return nil;
11229}
11230
11231/// Test if the last data member of a class is an array with
11232/// non-finite data member.
11233///
11234/// The flexible data member idiom is a well known C idiom:
11235/// https://en.wikipedia.org/wiki/Flexible_array_member.
11236///
11237/// @param klass the class to consider.
11238///
11239/// @return the data member which type is a flexible array, if any, or
11240/// nil.
11243{
11244 if (!klass)
11245 return var_decl_sptr();
11246
11247 return has_flexible_array_data_member(*klass);
11248}
11249
11250/// Test if the last data member of a class is an array with
11251/// non-finite data member.
11252///
11253/// The flexible data member idiom is a well known C idiom:
11254/// https://en.wikipedia.org/wiki/Flexible_array_member.
11255///
11256/// @param klass the class to consider.
11257///
11258/// @return the data member which type is a flexible array, if any, or
11259/// nil.
11263
11264/// Test if the last data member of a class is an array with
11265/// one element.
11266///
11267/// An array with one element is a way to mimic the flexible data
11268/// member idiom that was later standardized in C99.
11269///
11270/// To learn more about the flexible data member idiom, please
11271/// consider reading :
11272/// https://en.wikipedia.org/wiki/Flexible_array_member.
11273///
11274/// The various ways of representing that idiom pre-standardization
11275/// are presented in this article:
11276/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11277///
11278/// @param klass the class to consider.
11279///
11280/// @return the data member which type is a fake flexible array, if
11281/// any, or nil.
11284{
11285 var_decl_sptr nil;
11287 if (dms.empty())
11288 return nil;
11289
11290 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11291 {// The type of the last data member is an array.
11292 if (array->get_subranges().size() == 1
11293 && array->get_subranges()[0]->get_length() == 1)
11294 // The array has a size of one. We are thus looking at a
11295 // "fake" flexible array data member. Let's return it.
11296 return dms.back();
11297 }
11298
11299 return nil;
11300}
11301
11302/// Test if the last data member of a class is an array with
11303/// one element.
11304///
11305/// An array with one element is a way to mimic the flexible data
11306/// member idiom that was later standardized in C99.
11307///
11308/// To learn more about the flexible data member idiom, please
11309/// consider reading :
11310/// https://en.wikipedia.org/wiki/Flexible_array_member.
11311///
11312/// The various ways of representing that idiom pre-standardization
11313/// are presented in this article:
11314/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11315///
11316/// @param klass the class to consider.
11317///
11318/// @return the data member which type is a fake flexible array, if
11319/// any, or nil.
11323
11324/// Test if the last data member of a class is an array with
11325/// one element.
11326///
11327/// An array with one element is a way to mimic the flexible data
11328/// member idiom that was later standardized in C99.
11329///
11330/// To learn more about the flexible data member idiom, please
11331/// consider reading :
11332/// https://en.wikipedia.org/wiki/Flexible_array_member.
11333///
11334/// The various ways of representing that idiom pre-standardization
11335/// are presented in this article:
11336/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11337///
11338/// @param klass the class to consider.
11339///
11340/// @return the data member which type is a fake flexible array, if
11341/// any, or nil.
11345
11346/// Test wheter a type is a declaration-only class.
11347///
11348/// @param t the type to considier.
11349///
11350/// @param look_through_decl_only if true, then look through the
11351/// decl-only class to see if it actually has a class definition in
11352/// the same ABI corpus.
11353///
11354/// @return true iff @p t is a declaration-only class.
11355bool
11358{
11359 if (class_or_union *klass = is_class_or_union_type(t))
11360 {
11362 klass = look_through_decl_only_class(klass);
11363 return klass->get_is_declaration_only();
11364 }
11365 return false;
11366}
11367
11368/// Test wheter a type is a declaration-only class.
11369///
11370/// @param t the type to considier.
11371///
11372/// @param look_through_decl_only if true, then look through the
11373/// decl-only class to see if it actually has a class definition in
11374/// the same ABI corpus.
11375///
11376/// @return true iff @p t is a declaration-only class.
11377bool
11381
11382/// Test wheter a type is a declaration-only class.
11383///
11384/// @param t the type to considier.
11385///
11386/// @param look_through_decl_only if true, then look through the
11387/// decl-only class to see if it actually has a class definition in
11388/// the same ABI corpus.
11389///
11390/// @return true iff @p t is a declaration-only class.
11391bool
11395
11396/// Test if a type is a @ref class_or_union.
11397///
11398/// @param t the type to consider.
11399///
11400/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11401/// nil otherwise.
11404{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
11405
11406/// Test if a type is a @ref class_or_union.
11407///
11408/// @param t the type to consider.
11409///
11410/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11411/// nil otherwise.
11412shared_ptr<class_or_union>
11413is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
11414{return dynamic_pointer_cast<class_or_union>(t);}
11415
11416/// Test if two class or union types are of the same kind.
11417///
11418/// @param first the first type to consider.
11419///
11420/// @param second the second type to consider.
11421///
11422/// @return true iff @p first is of the same kind as @p second.
11423bool
11425 const class_or_union* second)
11426{
11427 if ((is_class_type(first) && is_class_type(second))
11428 || (is_union_type(first) && is_union_type(second)))
11429 return true;
11430
11431 return false;
11432}
11433
11434/// Test if two class or union types are of the same kind.
11435///
11436/// @param first the first type to consider.
11437///
11438/// @param second the second type to consider.
11439///
11440/// @return true iff @p first is of the same kind as @p second.
11441bool
11442class_or_union_types_of_same_kind(const class_or_union_sptr& first,
11443 const class_or_union_sptr& second)
11444{return class_or_union_types_of_same_kind(first.get(), second.get());}
11445
11446/// Test if a type is a @ref union_decl.
11447///
11448/// @param t the type to consider.
11449///
11450/// @return true iff @p t is a union_decl.
11451bool
11453{return is_union_type(&t);}
11454
11455/// Test if a type is a @ref union_decl.
11456///
11457/// @param t the type to consider.
11458///
11459/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11460/// otherwise.
11463{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
11464
11465/// Test if a type is a @ref union_decl.
11466///
11467/// @param t the type to consider.
11468///
11469/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11470/// otherwise.
11471union_decl_sptr
11472is_union_type(const shared_ptr<type_or_decl_base>& t)
11473{return dynamic_pointer_cast<union_decl>(t);}
11474
11475/// Test whether a type is a pointer_type_def.
11476///
11477/// @param t the type to test.
11478///
11479/// @param look_through_decl_only if this is true, then look through
11480/// qualified types to see if the underlying type is a
11481/// pointer_type_def.
11482///
11483/// @return the @ref pointer_type_def_sptr if @p t is a
11484/// pointer_type_def, null otherwise.
11485const pointer_type_def*
11487 bool look_through_qualifiers)
11488{
11489 if (!t)
11490 return 0;
11491
11492 const type_base* type = is_type(t);
11493 if (look_through_qualifiers)
11494 type = peel_qualified_type(is_type(t));
11495
11496 return dynamic_cast<pointer_type_def*>(const_cast<type_base*>(type));
11497}
11498
11499/// Test whether a type is a pointer_type_def.
11500///
11501/// @param t the type to test.
11502///
11503/// @param look_through_decl_only if this is true, then look through
11504/// qualified types to see if the underlying type is a
11505/// pointer_type_def.
11506///
11507/// @return the @ref pointer_type_def_sptr if @p t is a
11508/// pointer_type_def, null otherwise.
11511 bool look_through_qualifiers)
11512{
11513 type_base_sptr type = is_type(t);
11514 if (look_through_qualifiers)
11515 type = peel_qualified_type(type);
11516 return dynamic_pointer_cast<pointer_type_def>(type);
11517}
11518
11519/// Test if a type is a pointer to function type.
11520///
11521/// @param t the type to consider.
11522///
11523/// @return the @ref pointer_type_def_sptr iff @p t is a pointer to
11524/// function type.
11526is_pointer_to_function_type(const type_base_sptr& t)
11527{
11529 {
11530 if (is_function_type(p->get_pointed_to_type()))
11531 return p;
11532 }
11533 return pointer_type_def_sptr();
11534}
11535
11536/// Test if a type is a pointer to array type.
11537///
11538/// @param t the type to consider.
11539///
11540/// @return the pointer_type_def_sptr iff @p t is a pointer to array
11541/// type.
11543is_pointer_to_array_type(const type_base_sptr& t)
11544{
11546 {
11547 if (is_array_type(p->get_pointed_to_type()))
11548 return p;
11549 }
11550 return pointer_type_def_sptr();
11551}
11552
11553/// Test if we are looking at a pointer to a
11554/// neither-a-pointer-to-an-array-nor-a-function type.
11555///
11556/// @param t the type to consider.
11557///
11558/// @return the @ref pointer_type_def_sptr type iff @p t is a
11559/// neither-a-pointer-an-array-nor-a-function type.
11561is_pointer_to_npaf_type(const type_base_sptr& t)
11562{
11564 {
11565 if (is_npaf_type(p->get_pointed_to_type()))
11566 return p;
11567 }
11568 return pointer_type_def_sptr();
11569}
11570
11571/// Test if we are looking at a pointer to pointer to member type.
11572///
11573/// @param t the type to consider.
11574///
11575/// @return the @ref pointer_type_def_sptr type iff @p t is a pointer
11576/// to pointer to member type.
11578is_pointer_to_ptr_to_mbr_type(const type_base_sptr& t)
11579{
11581 {
11582 if (is_ptr_to_mbr_type(p->get_pointed_to_type()))
11583 return p;
11584 }
11585 return pointer_type_def_sptr();
11586}
11587
11588/// Test if a type is a typedef, pointer or reference to a decl-only
11589/// class/union.
11590///
11591/// This looks into qualified types too.
11592///
11593/// @param t the type to consider.
11594///
11595/// @return true iff @p t is a type is a typedef, pointer or reference
11596/// to a decl-only class/union.
11597bool
11599{
11600 const type_base * type =
11601 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11602
11604 /*look_through_decl_only=*/true))
11605 return true;
11606
11607 return false;
11608}
11609
11610/// Test if a type is a typedef of a class or union type, or a typedef
11611/// of a qualified class or union type.
11612///
11613/// Note that if the type is directly a class or union type, the
11614/// function returns true as well.
11615///
11616/// @param t the type to consider.
11617///
11618/// @return true iff @p t is a typedef of a class or union type, or a
11619/// typedef of a qualified class or union type.
11620bool
11622{
11623 if (!t)
11624 return false;
11625
11628 return true;
11629
11630return false;
11631}
11632
11633/// Test if a type is a typedef of a class or union type, or a typedef
11634/// of a qualified class or union type.
11635///
11636/// Note that if the type is directly a class or union type, the
11637/// function returns true as well.
11638///
11639/// @param t the type to consider.
11640///
11641/// @return true iff @p t is a typedef of a class or union type, or a
11642/// typedef of a qualified class or union type.
11643bool
11646
11647/// Test whether a type is a reference_type_def.
11648///
11649/// @param t the type to test.
11650///
11651/// @param look_through_decl_only if this is true, then look through
11652/// qualified types to see if the underlying type is a
11653/// reference_type_def.
11654///
11655/// @return the @ref reference_type_def_sptr if @p t is a
11656/// reference_type_def, null otherwise.
11659 bool look_through_qualifiers)
11660{
11661 const type_base* type = is_type(t);
11662 if (!type)
11663 return nullptr;
11664
11665 if (look_through_qualifiers)
11666 type = peel_qualified_type(type);
11667 return dynamic_cast<reference_type_def*>(const_cast<type_base*>(type));
11668}
11669
11670/// Test whether a type is a reference_type_def.
11671///
11672/// @param t the type to test.
11673///
11674/// @param look_through_decl_only if this is true, then look through
11675/// qualified types to see if the underlying type is a
11676/// reference_type_def.
11677///
11678/// @return the @ref reference_type_def_sptr if @p t is a
11679/// reference_type_def, null otherwise.
11680const reference_type_def*
11682 bool look_through_qualifiers)
11683{
11684 const type_base* type = is_type(t);
11685
11686 if (look_through_qualifiers)
11687 type = peel_qualified_type(type);
11688 return dynamic_cast<const reference_type_def*>(type);
11689}
11690
11691/// Test whether a type is a reference_type_def.
11692///
11693/// @param t the type to test.
11694///
11695/// @param look_through_decl_only if this is true, then look through
11696/// qualified types to see if the underlying type is a
11697/// reference_type_def.
11698///
11699/// @return the @ref reference_type_def_sptr if @p t is a
11700/// reference_type_def, null otherwise.
11703 bool look_through_qualifiers)
11704{
11705 type_base_sptr type = is_type(t);
11706 if (look_through_qualifiers)
11707 type = peel_qualified_type(type);
11708 return dynamic_pointer_cast<reference_type_def>(type);
11709}
11710
11711/// Test whether a type is a @ref ptr_to_mbr_type.
11712///
11713/// @param t the type to test.
11714///
11715/// @return the @ref ptr_to_mbr_type* if @p t is a @ref
11716/// ptr_to_mbr_type type, null otherwise.
11717const ptr_to_mbr_type*
11719 bool look_through_qualifiers)
11720{
11721 const type_base* type = is_type(t);
11722 if (look_through_qualifiers)
11723 type = peel_qualified_type(type);
11724 return dynamic_cast<const ptr_to_mbr_type*>(type);
11725}
11726
11727/// Test whether a type is a @ref ptr_to_mbr_type_sptr.
11728///
11729/// @param t the type to test.
11730///
11731/// @param look_through_decl_only if this is true, then look through
11732/// qualified types to see if the underlying type is a
11733/// ptr_to_mbr_type..
11734///
11735/// @return the @ref ptr_to_mbr_type_sptr if @p t is a @ref
11736/// ptr_to_mbr_type type, null otherwise.
11739 bool look_through_qualifiers)
11740{
11741 type_base_sptr type = is_type(t);
11742 if (look_through_qualifiers)
11743 type = peel_qualified_type(type);
11744 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
11745}
11746
11747/// Test if a type is equivalent to a pointer to void type.
11748///
11749/// Note that this looks trough typedefs or CV qualifiers to look for
11750/// the void pointer.
11751///
11752/// @param type the type to consider.
11753///
11754/// @return the actual void pointer if @p is eqivalent to a void
11755/// pointer or NULL if it's not.
11756const type_base*
11758{
11759 type = peel_qualified_or_typedef_type(type);
11760
11761 const pointer_type_def * t = is_pointer_type(type);
11762 if (!t)
11763 return 0;
11764
11765 // Look through typedefs in the pointed-to type as well.
11766 type_base * ty = t->get_pointed_to_type().get();
11768 if (ty && ty->get_environment().is_void_type(ty))
11769 return ty;
11770
11771 return 0;
11772}
11773
11774/// Test if a type is equivalent to a pointer to void type.
11775///
11776/// Note that this looks trough typedefs or CV qualifiers to look for
11777/// the void pointer.
11778///
11779/// @param type the type to consider.
11780///
11781/// @return the actual void pointer if @p is eqivalent to a void
11782/// pointer or NULL if it's not.
11783const type_base*
11786
11787/// Test if a type is a pointer to void type.
11788///
11789/// @param type the type to consider.
11790///
11791/// @return the actual void pointer if @p is a void pointer or NULL if
11792/// it's not.
11793const type_base*
11795{
11796 if (!t)
11797 return nullptr;
11798
11799 if (t->get_environment().get_void_pointer_type().get() == t)
11800 return t;
11801
11802 const pointer_type_def* ptr = is_pointer_type(t);
11803 if (!ptr)
11804 return nullptr;
11805
11807 return t;
11808
11809 return nullptr;
11810}
11811
11812/// Test if a type is a pointer to void type.
11813///
11814/// @param type the type to consider.
11815///
11816/// @return the actual void pointer if @p is a void pointer or NULL if
11817/// it's not.
11818const type_base_sptr
11819is_void_pointer_type(const type_base_sptr& t)
11820{
11821 type_base_sptr nil;
11822 if (!t)
11823 return nil;
11824
11825 if (t->get_environment().get_void_pointer_type().get() == t.get())
11826 return t;
11827
11828 const pointer_type_def* ptr = is_pointer_type(t.get());
11829 if (!ptr)
11830 return nil;
11831
11832 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11833 return t;
11834
11835 return nil;
11836}
11837
11838/// Test whether a type is a reference_type_def.
11839///
11840/// @param t the type to test.
11841///
11842/// @return the @ref reference_type_def_sptr if @p t is a
11843/// reference_type_def, null otherwise.
11846{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11847
11848/// Test whether a type is a qualified_type_def.
11849///
11850/// @param t the type to test.
11851///
11852/// @return the @ref qualified_type_def_sptr if @p t is a
11853/// qualified_type_def, null otherwise.
11854qualified_type_def_sptr
11856{return dynamic_pointer_cast<qualified_type_def>(t);}
11857
11858/// Test whether a type is a function_type.
11859///
11860/// @param t the type to test.
11861///
11862/// @return the @ref function_type_sptr if @p t is a
11863/// function_type, null otherwise.
11866{return dynamic_pointer_cast<function_type>(t);}
11867
11868/// Test whether a type is a function_type.
11869///
11870/// @param t the type to test.
11871///
11872/// @return the @ref function_type_sptr if @p t is a
11873/// function_type, null otherwise.
11876{return dynamic_cast<function_type*>(t);}
11877
11878/// Test whether a type is a function_type.
11879///
11880/// @param t the type to test.
11881///
11882/// @return the @ref function_type_sptr if @p t is a
11883/// function_type, null otherwise.
11884const function_type*
11886{return dynamic_cast<const function_type*>(t);}
11887
11888/// Test whether a type is a method_type.
11889///
11890/// @param t the type to test.
11891///
11892/// @return the @ref method_type_sptr if @p t is a
11893/// method_type, null otherwise.
11896{return dynamic_pointer_cast<method_type>(t);}
11897
11898/// Test whether a type is a method_type.
11899///
11900/// @param t the type to test.
11901///
11902/// @return the @ref method_type_sptr if @p t is a
11903/// method_type, null otherwise.
11904const method_type*
11906{return dynamic_cast<const method_type*>(t);}
11907
11908/// Test whether a type is a method_type.
11909///
11910/// @param t the type to test.
11911///
11912/// @return the @ref method_type_sptr if @p t is a
11913/// method_type, null otherwise.
11916{return dynamic_cast<method_type*>(t);}
11917
11918/// If a class (or union) is a decl-only class, get its definition.
11919/// Otherwise, just return the initial class.
11920///
11921/// @param the_class the class (or union) to consider.
11922///
11923/// @return either the definition of the class, or the class itself.
11927
11928/// If a class (or union) is a decl-only class, get its definition.
11929/// Otherwise, just return the initial class.
11930///
11931/// @param the_class the class (or union) to consider.
11932///
11933/// @return either the definition of the class, or the class itself.
11934class_or_union_sptr
11937
11938/// If a class (or union) is a decl-only class, get its definition.
11939/// Otherwise, just return the initial class.
11940///
11941/// @param klass the class (or union) to consider.
11942///
11943/// @return either the definition of the class, or the class itself.
11944class_or_union_sptr
11945look_through_decl_only_class(class_or_union_sptr klass)
11947
11948/// If an enum is a decl-only enum, get its definition.
11949/// Otherwise, just return the initial enum.
11950///
11951/// @param the_enum the enum to consider.
11952///
11953/// @return either the definition of the enum, or the enum itself.
11957
11958/// If an enum is a decl-only enum, get its definition.
11959/// Otherwise, just return the initial enum.
11960///
11961/// @param enom the enum to consider.
11962///
11963/// @return either the definition of the enum, or the enum itself.
11967
11968/// If a decl is decl-only get its definition. Otherwise, just return nil.
11969///
11970/// @param d the decl to consider.
11971///
11972/// @return either the definition of the decl, or nil.
11973decl_base_sptr
11975{
11976 decl_base_sptr decl;
11979
11980 if (!decl)
11981 return decl;
11982
11983 while (decl->get_is_declaration_only()
11984 && decl->get_definition_of_declaration())
11985 decl = decl->get_definition_of_declaration();
11986
11987 return decl;
11988}
11989
11990/// If a decl is decl-only enum, get its definition. Otherwise, just
11991/// return the initial decl.
11992///
11993/// @param d the decl to consider.
11994///
11995/// @return either the definition of the enum, or the decl itself.
11996decl_base*
11998{
11999 if (!d)
12000 return d;
12001
12002 decl_base* result = look_through_decl_only(*d).get();
12003 if (!result)
12004 result = d;
12005
12006 return result;
12007}
12008
12009/// If a decl is decl-only get its definition. Otherwise, just return nil.
12010///
12011/// @param d the decl to consider.
12012///
12013/// @return either the definition of the decl, or nil.
12014decl_base_sptr
12015look_through_decl_only(const decl_base_sptr& d)
12016{
12017 if (!d)
12018 return d;
12019
12020 decl_base_sptr result = look_through_decl_only(*d);
12021 if (!result)
12022 result = d;
12023
12024 return result;
12025}
12026
12027/// If a type is is decl-only, then get its definition. Otherwise,
12028/// just return the initial type.
12029///
12030/// @param d the decl to consider.
12031///
12032/// @return either the definition of the decl, or the initial type.
12033type_base*
12035{
12036 decl_base* d = is_decl(t);
12037 if (!d)
12038 return t;
12040 return is_type(d);
12041}
12042
12043/// If a type is is decl-only, then get its definition. Otherwise,
12044/// just return the initial type.
12045///
12046/// @param d the decl to consider.
12047///
12048/// @return either the definition of the decl, or the initial type.
12049type_base_sptr
12050look_through_decl_only_type(const type_base_sptr& t)
12051{
12052 decl_base_sptr d = is_decl(t);
12053 if (!d)
12054 return t;
12056 return is_type(d);
12057}
12058
12059/// Tests if a declaration is a variable declaration.
12060///
12061/// @param decl the decl to test.
12062///
12063/// @return the var_decl_sptr iff decl is a variable declaration; nil
12064/// otherwise.
12065var_decl*
12067{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
12068
12069/// Tests if a declaration is a variable declaration.
12070///
12071/// @param decl the decl to test.
12072///
12073/// @return the var_decl_sptr iff decl is a variable declaration; nil
12074/// otherwise.
12077{return dynamic_pointer_cast<var_decl>(decl);}
12078
12079/// Tests if a declaration is a namespace declaration.
12080///
12081/// @param d the decalration to consider.
12082///
12083/// @return the namespace declaration if @p d is a namespace.
12085is_namespace(const decl_base_sptr& d)
12086{return dynamic_pointer_cast<namespace_decl>(d);}
12087
12088/// Tests if a declaration is a namespace declaration.
12089///
12090/// @param d the decalration to consider.
12091///
12092/// @return the namespace declaration if @p d is a namespace.
12095{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
12096
12097/// Tests whether a decl is a template parameter composition type.
12098///
12099/// @param decl the declaration to consider.
12100///
12101/// @return true iff decl is a template parameter composition type.
12102bool
12103is_template_parm_composition_type(const shared_ptr<decl_base> decl)
12104{
12105 return (decl
12106 && is_at_template_scope(decl)
12107 && is_type(decl)
12108 && !is_template_parameter(decl));
12109}
12110
12111/// Test whether a decl is the pattern of a function template.
12112///
12113/// @param decl the decl to consider.
12114///
12115/// @return true iff decl is the pattern of a function template.
12116bool
12117is_function_template_pattern(const shared_ptr<decl_base> decl)
12118{
12119 return (decl
12120 && dynamic_pointer_cast<function_decl>(decl)
12121 && dynamic_cast<template_decl*>(decl->get_scope()));
12122}
12123
12124/// Test if a type is an array_type_def.
12125///
12126/// @param type the type to consider.
12127///
12128/// @return true iff @p type is an array_type_def.
12131 bool look_through_qualifiers)
12132{
12133 const type_base* t = is_type(type);
12134
12135 if (look_through_qualifiers)
12136 t = peel_qualified_type(t);
12137 return dynamic_cast<array_type_def*>(const_cast<type_base*>(t));
12138}
12139
12140/// Test if a type is an array_type_def.
12141///
12142/// @param type the type to consider.
12143///
12144/// @return true iff @p type is an array_type_def.
12147 bool look_through_qualifiers)
12148{
12149 type_base_sptr t = is_type(type);
12150
12151 if (look_through_qualifiers)
12152 t = peel_qualified_type(t);
12153 return dynamic_pointer_cast<array_type_def>(t);
12154}
12155
12156/// Tests if the element of a given array is a qualified type.
12157///
12158/// @param array the array type to consider.
12159///
12160/// @return the qualified element of the array iff it's a qualified
12161/// type. Otherwise, return a nil object.
12162qualified_type_def_sptr
12164{
12165 if (!array)
12166 return qualified_type_def_sptr();
12167
12168 return is_qualified_type(array->get_element_type());
12169}
12170
12171/// Test if an array type is an array to a qualified element type.
12172///
12173/// @param type the array type to consider.
12174///
12175/// @return true the array @p type iff it's an array to a qualified
12176/// element type.
12178is_array_of_qualified_element(const type_base_sptr& type)
12179{
12180 if (array_type_def_sptr array = is_array_type(type))
12182 return array;
12183
12184 return array_type_def_sptr();
12185}
12186
12187/// Test if a type is a typedef of an array.
12188///
12189/// Note that the function looks through qualified and typedefs types
12190/// of the underlying type of the current typedef. In other words, if
12191/// we are looking at a typedef of a CV-qualified array, or at a
12192/// typedef of a CV-qualified typedef of an array, this function will
12193/// still return TRUE.
12194///
12195/// @param t the type to consider.
12196///
12197/// @return true if t is a typedef which underlying type is an array.
12198/// That array might be either cv-qualified array or a typedef'ed
12199/// array, or a combination of both.
12201is_typedef_of_array(const type_base_sptr& t)
12202{
12203 array_type_def_sptr result;
12204
12205 if (typedef_decl_sptr typdef = is_typedef(t))
12206 {
12207 type_base_sptr u =
12208 peel_qualified_or_typedef_type(typdef->get_underlying_type());
12209 result = is_array_type(u);
12210 }
12211
12212 return result;
12213}
12214
12215/// Test if a type is an array_type_def::subrange_type.
12216///
12217/// @param type the type to consider.
12218///
12219/// @return the array_type_def::subrange_type which @p type is a type
12220/// of, or nil if it's not of that type.
12223{
12224 return dynamic_cast<array_type_def::subrange_type*>
12225 (const_cast<type_or_decl_base*>(type));
12226}
12227
12228/// Test if a type is an array_type_def::subrange_type.
12229///
12230/// @param type the type to consider.
12231///
12232/// @return the array_type_def::subrange_type which @p type is a type
12233/// of, or nil if it's not of that type.
12236{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
12237
12238/// Tests whether a decl is a template.
12239///
12240/// @param decl the decl to consider.
12241///
12242/// @return true iff decl is a function template, class template, or
12243/// template template parameter.
12244bool
12245is_template_decl(const decl_base_sptr& decl)
12246{return decl && dynamic_pointer_cast<template_decl>(decl);}
12247
12248/// This enum describe the kind of entity to lookup, while using the
12249/// lookup API.
12251{
12252 LOOKUP_ENTITY_TYPE,
12253 LOOKUP_ENTITY_VAR,
12254};
12255
12256/// Find the first relevant delimiter (the "::" string) in a fully
12257/// qualified C++ type name, starting from a given position. The
12258/// delimiter returned separates a type name from the name of its
12259/// context.
12260///
12261/// This is supposed to work correctly on names in cases like this:
12262///
12263/// foo<ns1::name1, ns2::name2>
12264///
12265/// In that case when called with with parameter @p begin set to 0, no
12266/// delimiter is returned, because the type name in this case is:
12267/// 'foo<ns1::name1, ns2::name2>'.
12268///
12269/// But in this case:
12270///
12271/// foo<p1, bar::name>::some_type
12272///
12273/// The "::" returned is the one right before 'some_type'.
12274///
12275/// @param fqn the fully qualified name of the type to consider.
12276///
12277/// @param begin the position from which to look for the delimiter.
12278///
12279/// @param delim_pos out parameter. Is set to the position of the
12280/// delimiter iff the function returned true.
12281///
12282/// @return true iff the function found and returned the delimiter.
12283static bool
12284find_next_delim_in_cplus_type(const string& fqn,
12285 size_t begin,
12286 size_t& delim_pos)
12287{
12288 int angle_count = 0;
12289 bool found = false;
12290 size_t i = begin;
12291 for (; i < fqn.size(); ++i)
12292 {
12293 if (fqn[i] == '<')
12294 ++angle_count;
12295 else if (fqn[i] == '>')
12296 --angle_count;
12297 else if (i + 1 < fqn.size()
12298 && !angle_count
12299 && fqn[i] == ':'
12300 && fqn[i+1] == ':')
12301 {
12302 delim_pos = i;
12303 found = true;
12304 break;
12305 }
12306 }
12307 return found;
12308}
12309
12310/// Decompose a fully qualified name into the list of its components.
12311///
12312/// @param fqn the fully qualified name to decompose.
12313///
12314/// @param comps the resulting list of component to fill.
12315void
12316fqn_to_components(const string& fqn,
12317 list<string>& comps)
12318{
12319 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
12320 do
12321 {
12322 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
12323 comp_end = fqn_size;
12324
12325 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
12326 comps.push_back(comp);
12327
12328 comp_begin = comp_end + 2;
12329 if (comp_begin >= fqn_size)
12330 break;
12331 } while (true);
12332}
12333
12334/// Turn a set of qualified name components (that name a type) into a
12335/// qualified name string.
12336///
12337/// @param comps the name components
12338///
12339/// @return the resulting string, which would be the qualified name of
12340/// a type.
12341string
12342components_to_type_name(const list<string>& comps)
12343{
12344 string result;
12345 for (list<string>::const_iterator c = comps.begin();
12346 c != comps.end();
12347 ++c)
12348 if (c == comps.begin())
12349 result = *c;
12350 else
12351 result += "::" + *c;
12352 return result;
12353}
12354
12355/// This predicate returns true if a given container iterator points
12356/// to the last element of the container, false otherwise.
12357///
12358/// @tparam T the type of the container of the iterator.
12359///
12360/// @param container the container the iterator points into.
12361///
12362/// @param i the iterator to consider.
12363///
12364/// @return true iff the iterator points to the last element of @p
12365/// container.
12366template<typename T>
12367static bool
12368iterator_is_last(T& container,
12369 typename T::const_iterator i)
12370{
12371 typename T::const_iterator next = i;
12372 ++next;
12373 return (next == container.end());
12374}
12375
12376//--------------------------------
12377// <type and decls lookup stuff>
12378// ------------------------------
12379
12380/// Lookup all the type*s* that have a given fully qualified name.
12381///
12382/// @param type_name the fully qualified name of the type to
12383/// lookup.
12384///
12385/// @param type_map the map to look into.
12386///
12387/// @return the vector containing the types named @p type_name. If
12388/// the lookup didn't yield any type, then this function returns nil.
12389static const type_base_wptrs_type*
12390lookup_types_in_map(const interned_string& type_name,
12391 const istring_type_base_wptrs_map_type& type_map)
12392{
12393 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12394 if (i != type_map.end())
12395 return &i->second;
12396 return 0;
12397}
12398
12399/// Lookup a type (with a given name) in a map that associates a type
12400/// name to a type. If there are several types with a given name,
12401/// then try to return the first one that is not decl-only.
12402/// Otherwise, return the last of such types, that is, the last one
12403/// that got registered.
12404///
12405/// @tparam TypeKind the type of the type this function is supposed to
12406/// return.
12407///
12408/// @param type_name the name of the type to lookup.
12409///
12410/// @param type_map the map in which to look.
12411///
12412/// @return a shared_ptr to the type found. If no type was found or
12413/// if the type found was not of type @p TypeKind then the function
12414/// returns nil.
12415template <class TypeKind>
12416static shared_ptr<TypeKind>
12417lookup_type_in_map(const interned_string& type_name,
12418 const istring_type_base_wptrs_map_type& type_map)
12419{
12420 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12421 if (i != type_map.end())
12422 {
12423 // Walk the types that have the name "type_name" and return the
12424 // first one that is not declaration-only ...
12425 for (auto j : i->second)
12426 {
12427 type_base_sptr t(j);
12428 decl_base_sptr d = is_decl(t);
12429 if (d && !d->get_is_declaration_only())
12430 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
12431 }
12432 // ... or return the last type with the name "type_name" that
12433 // was recorded. It's likely to be declaration-only if we
12434 // reached this point.
12435 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
12436 }
12437 return shared_ptr<TypeKind>();
12438}
12439
12440/// Lookup a basic type from a translation unit.
12441///
12442/// This is done by looking the type up in the type map that is
12443/// maintained in the translation unit. So this is as fast as
12444/// possible.
12445///
12446/// @param type_name the name of the basic type to look for.
12447///
12448/// @param tu the translation unit to look into.
12449///
12450/// @return the basic type found or nil if no basic type was found.
12453{
12454 return lookup_type_in_map<type_decl>(type_name,
12455 tu.get_types().basic_types());
12456}
12457
12458/// Lookup a basic type from a translation unit.
12459///
12460/// This is done by looking the type up in the type map that is
12461/// maintained in the translation unit. So this is as fast as
12462/// possible.
12463///
12464/// @param type_name the name of the basic type to look for.
12465///
12466/// @param tu the translation unit to look into.
12467///
12468/// @return the basic type found or nil if no basic type was found.
12470lookup_basic_type(const string& type_name, const translation_unit& tu)
12471{
12472 const environment& env = tu.get_environment();
12473
12474 interned_string s = env.intern(type_name);
12475 return lookup_basic_type(s, tu);
12476}
12477
12478/// Lookup a class type from a translation unit.
12479///
12480/// This is done by looking the type up in the type map that is
12481/// maintained in the translation unit. So this is as fast as
12482/// possible.
12483///
12484/// @param fqn the fully qualified name of the class type node to look
12485/// up.
12486///
12487/// @param tu the translation unit to perform lookup from.
12488///
12489/// @return the declaration of the class type IR node found, NULL
12490/// otherwise.
12492lookup_class_type(const string& fqn, const translation_unit& tu)
12493{
12494 const environment& env = tu.get_environment();
12495 interned_string s = env.intern(fqn);
12496 return lookup_class_type(s, tu);
12497}
12498
12499/// Lookup a class type from a translation unit.
12500///
12501/// This is done by looking the type up in the type map that is
12502/// maintained in the translation unit. So this is as fast as
12503/// possible.
12504///
12505/// @param type_name the name of the class type to look for.
12506///
12507/// @param tu the translation unit to look into.
12508///
12509/// @return the class type found or nil if no class type was found.
12512{
12513 return lookup_type_in_map<class_decl>(type_name,
12514 tu.get_types().class_types());
12515}
12516
12517/// Lookup a union type from a translation unit.
12518///
12519/// This is done by looking the type up in the type map that is
12520/// maintained in the translation unit. So this is as fast as
12521/// possible.
12522///
12523/// @param type_name the name of the union type to look for.
12524///
12525/// @param tu the translation unit to look into.
12526///
12527/// @return the union type found or nil if no union type was found.
12528union_decl_sptr
12530{
12531 return lookup_type_in_map<union_decl>(type_name,
12532 tu.get_types().union_types());
12533}
12534
12535/// Lookup a union type from a translation unit.
12536///
12537/// This is done by looking the type up in the type map that is
12538/// maintained in the translation unit. So this is as fast as
12539/// possible.
12540///
12541/// @param fqn the fully qualified name of the type to lookup.
12542///
12543/// @param tu the translation unit to look into.
12544///
12545/// @return the union type found or nil if no union type was found.
12546union_decl_sptr
12547lookup_union_type(const string& fqn, const translation_unit& tu)
12548{
12549 const environment& env = tu.get_environment();
12550 interned_string s = env.intern(fqn);
12551 return lookup_union_type(s, tu);
12552}
12553
12554/// Lookup a union type in a given corpus, from its location.
12555///
12556/// @param loc the location of the union type to look for.
12557///
12558/// @param corp the corpus to look it from.
12559///
12560/// @return the resulting union_decl.
12561union_decl_sptr
12563{
12566 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
12567
12568 return result;
12569}
12570
12571/// Lookup a union type in a given corpus, from its location.
12572///
12573/// @param loc the location of the union type to look for.
12574///
12575/// @param corp the corpus to look it from.
12576///
12577/// @return the resulting union_decl.
12578union_decl_sptr
12579lookup_union_type_per_location(const string& loc, const corpus& corp)
12580{
12581 const environment& env = corp.get_environment();
12582 return lookup_union_type_per_location(env.intern(loc), corp);
12583}
12584
12585/// Lookup an enum type from a translation unit.
12586///
12587/// This is done by looking the type up in the type map that is
12588/// maintained in the translation unit. So this is as fast as
12589/// possible.
12590///
12591/// @param type_name the name of the enum type to look for.
12592///
12593/// @param tu the translation unit to look into.
12594///
12595/// @return the enum type found or nil if no enum type was found.
12598{
12599 return lookup_type_in_map<enum_type_decl>(type_name,
12600 tu.get_types().enum_types());
12601}
12602
12603/// Lookup an enum type from a translation unit.
12604///
12605/// This is done by looking the type up in the type map that is
12606/// maintained in the translation unit. So this is as fast as
12607/// possible.
12608///
12609/// @param type_name the name of the enum type to look for.
12610///
12611/// @param tu the translation unit to look into.
12612///
12613/// @return the enum type found or nil if no enum type was found.
12615lookup_enum_type(const string& type_name, const translation_unit& tu)
12616{
12617 const environment& env = tu.get_environment();
12618 interned_string s = env.intern(type_name);
12619 return lookup_enum_type(s, tu);
12620}
12621
12622/// Lookup a typedef type from a translation unit.
12623///
12624/// This is done by looking the type up in the type map that is
12625/// maintained in the translation unit. So this is as fast as
12626/// possible.
12627///
12628/// @param type_name the name of the typedef type to look for.
12629///
12630/// @param tu the translation unit to look into.
12631///
12632/// @return the typedef type found or nil if no typedef type was
12633/// found.
12636 const translation_unit& tu)
12637{
12638 return lookup_type_in_map<typedef_decl>(type_name,
12639 tu.get_types().typedef_types());
12640}
12641
12642/// Lookup a typedef type from a translation unit.
12643///
12644/// This is done by looking the type up in the type map that is
12645/// maintained in the translation unit. So this is as fast as
12646/// possible.
12647///
12648/// @param type_name the name of the typedef type to look for.
12649///
12650/// @param tu the translation unit to look into.
12651///
12652/// @return the typedef type found or nil if no typedef type was
12653/// found.
12655lookup_typedef_type(const string& type_name, const translation_unit& tu)
12656{
12657 const environment& env = tu.get_environment();
12658 interned_string s = env.intern(type_name);
12659 return lookup_typedef_type(s, tu);
12660}
12661
12662/// Lookup a qualified type from a translation unit.
12663///
12664/// This is done by looking the type up in the type map that is
12665/// maintained in the translation unit. So this is as fast as
12666/// possible.
12667///
12668/// @param type_name the name of the qualified type to look for.
12669///
12670/// @param tu the translation unit to look into.
12671///
12672/// @return the qualified type found or nil if no qualified type was
12673/// found.
12674qualified_type_def_sptr
12676 const translation_unit& tu)
12677{
12678 const type_maps& m = tu.get_types();
12679 return lookup_type_in_map<qualified_type_def>(type_name,
12680 m.qualified_types());
12681}
12682
12683/// Lookup a qualified type from a translation unit.
12684///
12685/// This is done by looking the type up in the type map that is
12686/// maintained in the translation unit. So this is as fast as
12687/// possible.
12688///
12689/// @param underlying_type the underying type of the qualified type to
12690/// look up.
12691///
12692/// @param quals the CV-qualifiers of the qualified type to look for.
12693///
12694/// @param tu the translation unit to look into.
12695///
12696/// @return the qualified type found or nil if no qualified type was
12697/// found.
12698qualified_type_def_sptr
12699lookup_qualified_type(const type_base_sptr& underlying_type,
12701 const translation_unit& tu)
12702{
12703 interned_string type_name = get_name_of_qualified_type(underlying_type,
12704 quals);
12705 return lookup_qualified_type(type_name, tu);
12706}
12707
12708/// Lookup a pointer type from a translation unit.
12709///
12710/// This is done by looking the type up in the type map that is
12711/// maintained in the translation unit. So this is as fast as
12712/// possible.
12713///
12714/// @param type_name the name of the pointer type to look for.
12715///
12716/// @param tu the translation unit to look into.
12717///
12718/// @return the pointer type found or nil if no pointer type was
12719/// found.
12722 const translation_unit& tu)
12723{
12724 const type_maps& m = tu.get_types();
12725 return lookup_type_in_map<pointer_type_def>(type_name,
12726 m.pointer_types());
12727}
12728
12729/// Lookup a pointer type from a translation unit.
12730///
12731/// This is done by looking the type up in the type map that is
12732/// maintained in the translation unit. So this is as fast as
12733/// possible.
12734///
12735/// @param type_name the name of the pointer type to look for.
12736///
12737/// @param tu the translation unit to look into.
12738///
12739/// @return the pointer type found or nil if no pointer type was
12740/// found.
12742lookup_pointer_type(const string& type_name, const translation_unit& tu)
12743{
12744 const environment& env = tu.get_environment();
12745 interned_string s = env.intern(type_name);
12746 return lookup_pointer_type(s, tu);
12747}
12748
12749/// Lookup a pointer type from a translation unit.
12750///
12751/// This is done by looking the type up in the type map that is
12752/// maintained in the translation unit. So this is as fast as
12753/// possible.
12754///
12755/// @param pointed_to_type the pointed-to-type of the pointer to look for.
12756///
12757/// @param tu the translation unit to look into.
12758///
12759/// @return the pointer type found or nil if no pointer type was
12760/// found.
12762lookup_pointer_type(const type_base_sptr& pointed_to_type,
12763 const translation_unit& tu)
12764{
12765 type_base_sptr t = look_through_decl_only_type(pointed_to_type);
12767 return lookup_pointer_type(type_name, tu);
12768}
12769
12770/// Lookup a reference type from a translation unit.
12771///
12772/// This is done by looking the type up in the type map that is
12773/// maintained in the translation unit. So this is as fast as
12774/// possible.
12775///
12776/// @param type_name the name of the reference type to look for.
12777///
12778/// @param tu the translation unit to look into.
12779///
12780/// @return the reference type found or nil if no reference type was
12781/// found.
12784 const translation_unit& tu)
12785{
12786 const type_maps& m = tu.get_types();
12787 return lookup_type_in_map<reference_type_def>(type_name,
12788 m.reference_types());
12789}
12790
12791/// Lookup a reference type from a translation unit.
12792///
12793/// This is done by looking the type up in the type map that is
12794/// maintained in the translation unit. So this is as fast as
12795/// possible.
12796///
12797/// @param pointed_to_type the pointed-to-type of the reference to
12798/// look up.
12799///
12800/// @param tu the translation unit to look into.
12801///
12802/// @return the reference type found or nil if no reference type was
12803/// found.
12805lookup_reference_type(const type_base_sptr& pointed_to_type,
12806 bool lvalue_reference,
12807 const translation_unit& tu)
12808{
12809 interned_string type_name =
12811 lvalue_reference);
12812 return lookup_reference_type(type_name, tu);
12813}
12814
12815/// Lookup an array type from a translation unit.
12816///
12817/// This is done by looking the type up in the type map that is
12818/// maintained in the translation unit. So this is as fast as
12819/// possible.
12820///
12821/// @param type_name the name of the array type to look for.
12822///
12823/// @param tu the translation unit to look into.
12824///
12825/// @return the array type found or nil if no array type was found.
12828 const translation_unit& tu)
12829{
12830 const type_maps& m = tu.get_types();
12831 return lookup_type_in_map<array_type_def>(type_name,
12832 m.array_types());
12833}
12834
12835/// Lookup a function type from a translation unit.
12836///
12837/// This is done by looking the type up in the type map that is
12838/// maintained in the translation unit. So this is as fast as
12839/// possible.
12840///
12841/// @param type_name the name of the type to lookup.
12842///
12843/// @param tu the translation unit to look into.
12844///
12845/// @return the function type found, or NULL of none was found.
12848 const translation_unit& tu)
12849{
12850 const type_maps& m = tu.get_types();
12851 return lookup_type_in_map<function_type>(type_name,
12852 m.function_types());
12853}
12854
12855/// Lookup a function type from a translation unit.
12856///
12857/// This walks all the function types held by the translation unit and
12858/// compare their sub-type *names*. If the names match then return
12859/// the function type found in the translation unit.
12860///
12861/// @param t the function type to look for.
12862///
12863/// @param tu the translation unit to look into.
12864///
12865/// @return the function type found, or NULL of none was found.
12868 const translation_unit& tu)
12869{
12870 interned_string type_name = get_type_name(t);
12871 return lookup_function_type(type_name, tu);
12872}
12873
12874/// Lookup a function type from a translation unit.
12875///
12876/// This is done by looking the type up in the type map that is
12877/// maintained in the translation unit. So this is as fast as
12878/// possible.
12879///
12880/// @param t the function type to look for.
12881///
12882/// @param tu the translation unit to look into.
12883///
12884/// @return the function type found, or NULL of none was found.
12887 const translation_unit& tu)
12888{return lookup_function_type(*t, tu);}
12889
12890/// Lookup a type in a translation unit.
12891///
12892/// @param fqn the fully qualified name of the type to lookup.
12893///
12894/// @param tu the translation unit to consider.
12895///
12896/// @return the declaration of the type if found, NULL otherwise.
12897const type_base_sptr
12899 const translation_unit& tu)
12900{
12901 type_base_sptr result;
12902 ((result = lookup_typedef_type(fqn, tu))
12903 || (result = lookup_class_type(fqn, tu))
12904 || (result = lookup_union_type(fqn, tu))
12905 || (result = lookup_enum_type(fqn, tu))
12906 || (result = lookup_qualified_type(fqn, tu))
12907 || (result = lookup_pointer_type(fqn, tu))
12908 || (result = lookup_reference_type(fqn, tu))
12909 || (result = lookup_array_type(fqn, tu))
12910 || (result = lookup_function_type(fqn, tu))
12911 || (result = lookup_basic_type(fqn, tu)));
12912
12913 return result;
12914}
12915
12916/// Lookup a type in a translation unit, starting from the global
12917/// namespace.
12918///
12919/// @param fqn the fully qualified name of the type to lookup.
12920///
12921/// @param tu the translation unit to consider.
12922///
12923/// @return the declaration of the type if found, NULL otherwise.
12924type_base_sptr
12925lookup_type(const string& fqn, const translation_unit& tu)
12926{
12927 const environment&env = tu.get_environment();
12928 interned_string ifqn = env.intern(fqn);
12929 return lookup_type(ifqn, tu);
12930}
12931
12932/// Lookup a type from a translation unit.
12933///
12934/// @param fqn the components of the fully qualified name of the node
12935/// to look up.
12936///
12937/// @param tu the translation unit to perform lookup from.
12938///
12939/// @return the declaration of the IR node found, NULL otherwise.
12940const type_base_sptr
12941lookup_type(const type_base_sptr type,
12942 const translation_unit& tu)
12943{
12944 interned_string type_name = get_type_name(type);
12945 return lookup_type(type_name, tu);
12946}
12947
12948/// Lookup a type in a scope.
12949///
12950/// This is really slow as it walks the member types of the scope in
12951/// sequence to find the type with a given name.
12952///
12953/// If possible, users should prefer looking up types from the
12954/// enclosing translation unit or even ABI corpus because both the
12955/// translation unit and the corpus have a map of type, indexed by
12956/// their name. Looking up a type from those maps is thus much
12957/// faster.
12958///
12959/// @param fqn the fully qualified name of the type to lookup.
12960///
12961/// @param skope the scope to look into.
12962///
12963/// @return the declaration of the type if found, NULL otherwise.
12964const type_base_sptr
12965lookup_type_in_scope(const string& fqn,
12966 const scope_decl_sptr& skope)
12967{
12968 list<string> comps;
12969 fqn_to_components(fqn, comps);
12970 return lookup_type_in_scope(comps, skope);
12971}
12972
12973/// Lookup a @ref var_decl in a scope.
12974///
12975/// @param fqn the fuly qualified name of the @var_decl to lookup.
12976///
12977/// @param skope the scope to look into.
12978///
12979/// @return the declaration of the @ref var_decl if found, NULL
12980/// otherwise.
12981const decl_base_sptr
12983 const scope_decl_sptr& skope)
12984{
12985 list<string> comps;
12986 fqn_to_components(fqn, comps);
12987 return lookup_var_decl_in_scope(comps, skope);
12988}
12989
12990/// A generic function (template) to get the name of a node, whatever
12991/// node it is. This has to be specialized for the kind of node we
12992/// want.
12993///
12994/// Note that a node is a member of a scope.
12995///
12996/// @tparam NodeKind the kind of node to consider.
12997///
12998/// @param node the node to get the name from.
12999///
13000/// @return the name of the node.
13001template<typename NodeKind>
13002static const interned_string&
13003get_node_name(shared_ptr<NodeKind> node);
13004
13005/// Gets the name of a class_decl node.
13006///
13007/// @param node the decl_base node to get the name from.
13008///
13009/// @return the name of the node.
13010template<>
13011const interned_string&
13012get_node_name(class_decl_sptr node)
13013{return node->get_name();}
13014
13015/// Gets the name of a type_base node.
13016///
13017/// @param node the type_base node to get the name from.
13018///
13019/// @return the name of the node.
13020template<>
13021const interned_string&
13022get_node_name(type_base_sptr node)
13023{return get_type_declaration(node)->get_name();}
13024
13025/// Gets the name of a var_decl node.
13026///
13027/// @param node the var_decl node to get the name from.
13028///
13029/// @return the name of the node.
13030template<>
13031const interned_string&
13032get_node_name(var_decl_sptr node)
13033{return node->get_name();}
13034
13035/// Generic function to get the declaration of a given node, whatever
13036/// it is. There has to be specializations for the kind of the nodes
13037/// we want to support.
13038///
13039/// @tparam NodeKind the type of the node we are looking at.
13040///
13041/// @return the declaration.
13042template<typename NodeKind>
13043static decl_base_sptr
13044convert_node_to_decl(shared_ptr<NodeKind> node);
13045
13046/// Lookup a node in a given scope.
13047///
13048/// @tparam the type of the node to lookup.
13049///
13050/// @param fqn the components of the fully qualified name of the node
13051/// to lookup.
13052///
13053/// @param skope the scope to look into.
13054///
13055/// @return the declaration of the looked up node, or NULL if it
13056/// wasn't found.
13057template<typename NodeKind>
13058static const type_or_decl_base_sptr
13059lookup_node_in_scope(const list<string>& fqn,
13060 const scope_decl_sptr& skope)
13061{
13062 type_or_decl_base_sptr resulting_decl;
13063 shared_ptr<NodeKind> node;
13064 bool it_is_last = false;
13065 scope_decl_sptr cur_scope = skope, new_scope, scope;
13066
13067 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
13068 {
13069 new_scope.reset();
13070 it_is_last = iterator_is_last(fqn, c);
13071 for (scope_decl::declarations::const_iterator m =
13072 cur_scope->get_member_decls().begin();
13073 m != cur_scope->get_member_decls().end();
13074 ++m)
13075 {
13076 if (!it_is_last)
13077 {
13078 // looking for a scope
13079 scope = dynamic_pointer_cast<scope_decl>(*m);
13080 if (scope && scope->get_name() == *c)
13081 {
13082 new_scope = scope;
13083 break;
13084 }
13085 }
13086 else
13087 {
13088 //looking for a final type.
13089 node = dynamic_pointer_cast<NodeKind>(*m);
13090 if (node && get_node_name(node) == *c)
13091 {
13092 if (class_decl_sptr cl =
13093 dynamic_pointer_cast<class_decl>(node))
13094 if (cl->get_is_declaration_only()
13095 && !cl->get_definition_of_declaration())
13096 continue;
13097 resulting_decl = node;
13098 break;
13099 }
13100 }
13101 }
13102 if (!new_scope && !resulting_decl)
13103 return decl_base_sptr();
13104 cur_scope = new_scope;
13105 }
13106 ABG_ASSERT(resulting_decl);
13107 return resulting_decl;
13108}
13109
13110/// lookup a type in a scope.
13111///
13112///
13113/// This is really slow as it walks the member types of the scope in
13114/// sequence to find the type with a given name.
13115///
13116/// If possible, users should prefer looking up types from the
13117/// enclosing translation unit or even ABI corpus because both the
13118/// translation unit and the corpus have a map of type, indexed by
13119/// their name. Looking up a type from those maps is thus much
13120/// faster.
13121///
13122/// @param comps the components of the fully qualified name of the
13123/// type to lookup.
13124///
13125/// @param skope the scope to look into.
13126///
13127/// @return the declaration of the type found.
13128const type_base_sptr
13129lookup_type_in_scope(const list<string>& comps,
13130 const scope_decl_sptr& scope)
13131{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
13132
13133/// lookup a type in a scope.
13134///
13135/// This is really slow as it walks the member types of the scope in
13136/// sequence to find the type with a given name.
13137///
13138/// If possible, users should prefer looking up types from the
13139/// enclosing translation unit or even ABI corpus because both the
13140/// translation unit and the corpus have a map of type, indexed by
13141/// their name. Looking up a type from those maps is thus much
13142/// faster.
13143///
13144/// @param type the type to look for.
13145///
13146/// @param access_path a vector of scopes the path of scopes to follow
13147/// before reaching the scope into which to look for @p type. Note
13148/// that the deepest scope (the one immediately containing @p type) is
13149/// at index 0 of this vector, and the top-most scope is the last
13150/// element of the vector.
13151///
13152/// @param scope the top-most scope into which to look for @p type.
13153///
13154/// @return the scope found in @p scope, or NULL if it wasn't found.
13155static const type_base_sptr
13157 const vector<scope_decl*>& access_path,
13158 const scope_decl* scope)
13159{
13160 vector<scope_decl*> a = access_path;
13161 type_base_sptr result;
13162
13163 scope_decl* first_scope = 0;
13164 if (!a.empty())
13165 {
13166 first_scope = a.back();
13167 ABG_ASSERT(first_scope->get_name() == scope->get_name());
13168 a.pop_back();
13169 }
13170
13171 if (a.empty())
13172 {
13173 interned_string n = get_type_name(type, false);
13174 for (scope_decl::declarations::const_iterator i =
13175 scope->get_member_decls().begin();
13176 i != scope->get_member_decls().end();
13177 ++i)
13178 if (is_type(*i) && (*i)->get_name() == n)
13179 {
13180 result = is_type(*i);
13181 break;
13182 }
13183 }
13184 else
13185 {
13186 first_scope = a.back();
13187 interned_string scope_name, cur_scope_name = first_scope->get_name();
13188 for (scope_decl::scopes::const_iterator i =
13189 scope->get_member_scopes().begin();
13190 i != scope->get_member_scopes().end();
13191 ++i)
13192 {
13193 scope_name = (*i)->get_name();
13194 if (scope_name == cur_scope_name)
13195 {
13196 result = lookup_type_in_scope(type, a, (*i).get());
13197 break;
13198 }
13199 }
13200 }
13201 return result;
13202}
13203
13204/// lookup a type in a scope.
13205///
13206/// This is really slow as it walks the member types of the scope in
13207/// sequence to find the type with a given name.
13208///
13209/// If possible, users should prefer looking up types from the
13210/// enclosing translation unit or even ABI corpus because both the
13211/// translation unit and the corpus have a map of type, indexed by
13212/// their name. Looking up a type from those maps is thus much
13213/// faster.
13214///
13215/// @param type the type to look for.
13216///
13217/// @param scope the top-most scope into which to look for @p type.
13218///
13219/// @return the scope found in @p scope, or NULL if it wasn't found.
13220static const type_base_sptr
13221lookup_type_in_scope(const type_base_sptr type,
13222 const scope_decl* scope)
13223{
13224 if (!type || is_function_type(type))
13225 return type_base_sptr();
13226
13227 decl_base_sptr type_decl = get_type_declaration(type);
13228 ABG_ASSERT(type_decl);
13229 vector<scope_decl*> access_path;
13230 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
13231 {
13232 access_path.push_back(s);
13233 if (is_global_scope(s))
13234 break;
13235 }
13236 return lookup_type_in_scope(*type, access_path, scope);
13237}
13238
13239/// Lookup a type from a translation unit by walking the scopes of the
13240/// translation unit in sequence and looking into them.
13241///
13242/// This is really slow as it walks the member types of the scopes in
13243/// sequence to find the type with a given name.
13244///
13245/// If possible, users should prefer looking up types from the
13246/// translation unit or even ABI corpus in a more direct way, by using
13247/// the lookup_type() functins.
13248///
13249///
13250/// This is because both the translation unit and the corpus have a
13251/// map of types, indexed by their name. Looking up a type from those
13252/// maps is thus much faster. @param fqn the components of the fully
13253/// qualified name of the node to look up.
13254///
13255/// @param tu the translation unit to perform lookup from.
13256///
13257/// @return the declaration of the IR node found, NULL otherwise.
13258const type_base_sptr
13259lookup_type_through_scopes(const type_base_sptr type,
13260 const translation_unit& tu)
13261{
13262 if (function_type_sptr fn_type = is_function_type(type))
13263 return lookup_function_type(fn_type, tu);
13264 return lookup_type_in_scope(type, tu.get_global_scope().get());
13265}
13266
13267/// lookup a var_decl in a scope.
13268///
13269/// @param comps the components of the fully qualified name of the
13270/// var_decl to lookup.
13271///
13272/// @param skope the scope to look into.
13273const decl_base_sptr
13274lookup_var_decl_in_scope(const std::list<string>& comps,
13275 const scope_decl_sptr& skope)
13276{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
13277
13278/// Lookup an IR node from a translation unit.
13279///
13280/// @tparam NodeKind the type of the IR node to lookup from the
13281/// translation unit.
13282///
13283/// @param fqn the components of the fully qualified name of the node
13284/// to look up.
13285///
13286/// @param tu the translation unit to perform lookup from.
13287///
13288/// @return the declaration of the IR node found, NULL otherwise.
13289template<typename NodeKind>
13290static const type_or_decl_base_sptr
13291lookup_node_in_translation_unit(const list<string>& fqn,
13292 const translation_unit& tu)
13293{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
13294
13295/// Lookup a type from a translation unit by walking its scopes in
13296/// sequence and by looking into them.
13297///
13298/// This is much slower than using the lookup_type() function.
13299///
13300/// @param fqn the components of the fully qualified name of the node
13301/// to look up.
13302///
13303/// @param tu the translation unit to perform lookup from.
13304///
13305/// @return the declaration of the IR node found, NULL otherwise.
13306type_base_sptr
13307lookup_type_through_scopes(const list<string>& fqn,
13308 const translation_unit& tu)
13309{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
13310
13311
13312/// Lookup a class type from a translation unit by walking its scopes
13313/// in sequence and by looking into them.
13314///
13315/// This is much slower than using the lookup_class_type() function
13316/// because it walks all the scopes of the translation unit in
13317/// sequence and lookup the types to find one that has a given name.
13318///
13319/// @param fqn the components of the fully qualified name of the class
13320/// type node to look up.
13321///
13322/// @param tu the translation unit to perform lookup from.
13323///
13324/// @return the declaration of the class type IR node found, NULL
13325/// otherwise.
13327lookup_class_type_through_scopes(const list<string>& fqn,
13328 const translation_unit& tu)
13329{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
13330
13331/// Lookup a basic type from all the translation units of a given
13332/// corpus.
13333///
13334/// @param fqn the components of the fully qualified name of the basic
13335/// type node to look up.
13336///
13337/// @param tu the translation unit to perform lookup from.
13338///
13339/// @return the declaration of the basic type IR node found, NULL
13340/// otherwise.
13341static type_decl_sptr
13342lookup_basic_type_through_translation_units(const interned_string& type_name,
13343 const corpus& abi_corpus)
13344{
13345 type_decl_sptr result;
13346
13347 for (translation_units::const_iterator tu =
13348 abi_corpus.get_translation_units().begin();
13349 tu != abi_corpus.get_translation_units().end();
13350 ++tu)
13351 if ((result = lookup_basic_type(type_name, **tu)))
13352 break;
13353
13354 return result;
13355}
13356
13357/// Lookup a union type from all the translation units of a given
13358/// corpus.
13359///
13360/// @param fqn the components of the fully qualified name of the union
13361/// type node to look up.
13362///
13363/// @param tu the translation unit to perform lookup from.
13364///
13365/// @return the declaration of the union type IR node found, NULL
13366/// otherwise.
13367static union_decl_sptr
13368lookup_union_type_through_translation_units(const interned_string& type_name,
13369 const corpus & abi_corpus)
13370{
13371 union_decl_sptr result;
13372
13373 for (translation_units::const_iterator tu =
13374 abi_corpus.get_translation_units().begin();
13375 tu != abi_corpus.get_translation_units().end();
13376 ++tu)
13377 if ((result = lookup_union_type(type_name, **tu)))
13378 break;
13379
13380 return result;
13381}
13382
13383/// Lookup an enum type from all the translation units of a given
13384/// corpus.
13385///
13386/// @param fqn the components of the fully qualified name of the enum
13387/// type node to look up.
13388///
13389/// @param tu the translation unit to perform lookup from.
13390///
13391/// @return the declaration of the enum type IR node found, NULL
13392/// otherwise.
13394lookup_enum_type_through_translation_units(const interned_string& type_name,
13395 const corpus & abi_corpus)
13396{
13397 enum_type_decl_sptr result;
13398
13399 for (translation_units::const_iterator tu =
13400 abi_corpus.get_translation_units().begin();
13401 tu != abi_corpus.get_translation_units().end();
13402 ++tu)
13403 if ((result = lookup_enum_type(type_name, **tu)))
13404 break;
13405
13406 return result;
13407}
13408
13409/// Lookup a typedef type definition in all the translation units of a
13410/// given ABI corpus.
13411///
13412/// @param @param qn the fully qualified name of the typedef type to lookup.
13413///
13414/// @param abi_corpus the ABI corpus which to look the type up in.
13415///
13416/// @return the type definition if any was found, or a NULL pointer.
13417static typedef_decl_sptr
13418lookup_typedef_type_through_translation_units(const interned_string& type_name,
13419 const corpus & abi_corpus)
13420{
13421 typedef_decl_sptr result;
13422
13423 for (translation_units::const_iterator tu =
13424 abi_corpus.get_translation_units().begin();
13425 tu != abi_corpus.get_translation_units().end();
13426 ++tu)
13427 if ((result = lookup_typedef_type(type_name, **tu)))
13428 break;
13429
13430 return result;
13431}
13432
13433/// Lookup a qualified type definition in all the translation units of a
13434/// given ABI corpus.
13435///
13436/// @param @param qn the fully qualified name of the qualified type to
13437/// lookup.
13438///
13439/// @param abi_corpus the ABI corpus which to look the type up in.
13440///
13441/// @return the type definition if any was found, or a NULL pointer.
13442static qualified_type_def_sptr
13443lookup_qualified_type_through_translation_units(const interned_string& t_name,
13444 const corpus & abi_corpus)
13445{
13446 qualified_type_def_sptr result;
13447
13448 for (translation_units::const_iterator tu =
13449 abi_corpus.get_translation_units().begin();
13450 tu != abi_corpus.get_translation_units().end();
13451 ++tu)
13452 if ((result = lookup_qualified_type(t_name, **tu)))
13453 break;
13454
13455 return result;
13456}
13457
13458/// Lookup a pointer type definition in all the translation units of a
13459/// given ABI corpus.
13460///
13461/// @param @param qn the fully qualified name of the pointer type to
13462/// lookup.
13463///
13464/// @param abi_corpus the ABI corpus which to look the type up in.
13465///
13466/// @return the type definition if any was found, or a NULL pointer.
13468lookup_pointer_type_through_translation_units(const interned_string& type_name,
13469 const corpus & abi_corpus)
13470{
13471 pointer_type_def_sptr result;
13472
13473 for (translation_units::const_iterator tu =
13474 abi_corpus.get_translation_units().begin();
13475 tu != abi_corpus.get_translation_units().end();
13476 ++tu)
13477 if ((result = lookup_pointer_type(type_name, **tu)))
13478 break;
13479
13480 return result;
13481}
13482
13483/// Lookup a reference type definition in all the translation units of a
13484/// given ABI corpus.
13485///
13486/// @param @param qn the fully qualified name of the reference type to
13487/// lookup.
13488///
13489/// @param abi_corpus the ABI corpus which to look the type up in.
13490///
13491/// @return the type definition if any was found, or a NULL pointer.
13493lookup_reference_type_through_translation_units(const interned_string& t_name,
13494 const corpus & abi_corpus)
13495{
13497
13498 for (translation_units::const_iterator tu =
13499 abi_corpus.get_translation_units().begin();
13500 tu != abi_corpus.get_translation_units().end();
13501 ++tu)
13502 if ((result = lookup_reference_type(t_name, **tu)))
13503 break;
13504
13505 return result;
13506}
13507
13508/// Lookup a array type definition in all the translation units of a
13509/// given ABI corpus.
13510///
13511/// @param @param qn the fully qualified name of the array type to
13512/// lookup.
13513///
13514/// @param abi_corpus the ABI corpus which to look the type up in.
13515///
13516/// @return the type definition if any was found, or a NULL pointer.
13518lookup_array_type_through_translation_units(const interned_string& type_name,
13519 const corpus & abi_corpus)
13520{
13521 array_type_def_sptr result;
13522
13523 for (translation_units::const_iterator tu =
13524 abi_corpus.get_translation_units().begin();
13525 tu != abi_corpus.get_translation_units().end();
13526 ++tu)
13527 if ((result = lookup_array_type(type_name, **tu)))
13528 break;
13529
13530 return result;
13531}
13532
13533/// Lookup a function type definition in all the translation units of
13534/// a given ABI corpus.
13535///
13536/// @param @param qn the fully qualified name of the function type to
13537/// lookup.
13538///
13539/// @param abi_corpus the ABI corpus which to look the type up in.
13540///
13541/// @return the type definition if any was found, or a NULL pointer.
13542static function_type_sptr
13543lookup_function_type_through_translation_units(const interned_string& type_name,
13544 const corpus & abi_corpus)
13545{
13546 function_type_sptr result;
13547
13548 for (translation_units::const_iterator tu =
13549 abi_corpus.get_translation_units().begin();
13550 tu != abi_corpus.get_translation_units().end();
13551 ++tu)
13552 if ((result = lookup_function_type(type_name, **tu)))
13553 break;
13554
13555 return result;
13556}
13557
13558/// Lookup a type definition in all the translation units of a given
13559/// ABI corpus.
13560///
13561/// @param @param qn the fully qualified name of the type to lookup.
13562///
13563/// @param abi_corpus the ABI corpus which to look the type up in.
13564///
13565/// @return the type definition if any was found, or a NULL pointer.
13566type_base_sptr
13568 const corpus& abi_corpus)
13569{
13570 type_base_sptr result;
13571
13572 for (translation_units::const_iterator tu =
13573 abi_corpus.get_translation_units().begin();
13574 tu != abi_corpus.get_translation_units().end();
13575 ++tu)
13576 if ((result = lookup_type(qn, **tu)))
13577 break;
13578
13579 return result;
13580}
13581
13582/// Lookup a type from a given translation unit present in a give corpus.
13583///
13584/// @param type_name the name of the type to look for.
13585///
13586/// @parm tu_path the path of the translation unit to consider.
13587///
13588/// @param corp the corpus to consider.
13589///
13590/// @return the resulting type, if any.
13591type_base_sptr
13593 const string& tu_path,
13594 const corpus& corp)
13595{
13596 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
13597 if (i == corp.priv_->path_tu_map.end())
13598 return type_base_sptr();
13599
13600 translation_unit_sptr tu = i->second;
13601 ABG_ASSERT(tu);
13602
13603 type_base_sptr t = lookup_type(type_name, *tu);
13604 return t;
13605}
13606
13607/// Look into an ABI corpus for a function type.
13608///
13609/// @param fn_type the function type to be looked for in the ABI
13610/// corpus.
13611///
13612/// @param corpus the ABI corpus into which to look for the function
13613/// type.
13614///
13615/// @return the function type found in the corpus.
13618 const corpus& corpus)
13619{
13620 ABG_ASSERT(fn_t);
13621
13622 function_type_sptr result;
13623
13624 if ((result = lookup_function_type(fn_t, corpus)))
13625 return result;
13626
13627 for (translation_units::const_iterator i =
13628 corpus.get_translation_units().begin();
13629 i != corpus.get_translation_units().end();
13630 ++i)
13632 **i)))
13633 return result;
13634
13635 return result;
13636}
13637
13638/// Look into a given corpus to find a type which has the same
13639/// qualified name as a giventype.
13640///
13641/// If the per-corpus type map is non-empty (because the corpus allows
13642/// the One Definition Rule) then the type islooked up in that
13643/// per-corpus type map. Otherwise, the type is looked-up in each
13644/// translation unit.
13645///
13646/// @param t the type which has the same qualified name as the type we
13647/// are looking for.
13648///
13649/// @param corp the ABI corpus to look into for the type.
13651lookup_basic_type(const type_decl& t, const corpus& corp)
13652{return lookup_basic_type(t.get_name(), corp);}
13653
13654/// Look into a given corpus to find a basic type which has a given
13655/// qualified name.
13656///
13657/// If the per-corpus type map is non-empty (because the corpus allows
13658/// the One Definition Rule) then the type islooked up in that
13659/// per-corpus type map. Otherwise, the type is looked-up in each
13660/// translation unit.
13661///
13662/// @param qualified_name the qualified name of the basic type to look
13663/// for.
13664///
13665/// @param corp the corpus to look into.
13667lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
13668{
13670 type_decl_sptr result;
13671
13672 if (!m.empty())
13673 result = lookup_type_in_map<type_decl>(qualified_name, m);
13674 else
13675 result = lookup_basic_type_through_translation_units(qualified_name, corp);
13676
13677 return result;
13678}
13679
13680/// Lookup a @ref type_decl type from a given corpus, by its location.
13681///
13682/// @param loc the location to consider.
13683///
13684/// @param corp the corpus to consider.
13685///
13686/// @return the resulting basic type, if any.
13689 const corpus &corp)
13690{
13693 type_decl_sptr result;
13694
13695 result = lookup_type_in_map<type_decl>(loc, m);
13696
13697 return result;
13698}
13699
13700/// Lookup a @ref type_decl type from a given corpus, by its location.
13701///
13702/// @param loc the location to consider.
13703///
13704/// @param corp the corpus to consider.
13705///
13706/// @return the resulting basic type, if any.
13708lookup_basic_type_per_location(const string &loc, const corpus &corp)
13709{
13710 const environment& env = corp.get_environment();
13711 return lookup_basic_type_per_location(env.intern(loc), corp);
13712}
13713
13714/// Look into a given corpus to find a basic type which has a given
13715/// qualified name.
13716///
13717/// If the per-corpus type map is non-empty (because the corpus allows
13718/// the One Definition Rule) then the type islooked up in that
13719/// per-corpus type map. Otherwise, the type is looked-up in each
13720/// translation unit.
13721///
13722/// @param qualified_name the qualified name of the basic type to look
13723/// for.
13724///
13725/// @param corp the corpus to look into.
13727lookup_basic_type(const string& qualified_name, const corpus& corp)
13728{
13729 return lookup_basic_type(corp.get_environment().intern(qualified_name),
13730 corp);
13731}
13732
13733/// Look into a given corpus to find a class type which has the same
13734/// qualified name as a given type.
13735///
13736/// If the per-corpus type map is non-empty (because the corpus allows
13737/// the One Definition Rule) then the type islooked up in that
13738/// per-corpus type map. Otherwise, the type is looked-up in each
13739/// translation unit.
13740///
13741/// @param t the class decl type which has the same qualified name as
13742/// the type we are looking for.
13743///
13744/// @param corp the corpus to look into.
13747{
13749 return lookup_class_type(s, corp);
13750}
13751
13752/// Look into a given corpus to find a class type which has a given
13753/// qualified name.
13754///
13755/// If the per-corpus type map is non-empty (because the corpus allows
13756/// the One Definition Rule) then the type islooked up in that
13757/// per-corpus type map. Otherwise, the type is looked-up in each
13758/// translation unit.
13759///
13760/// @param qualified_name the qualified name of the type to look for.
13761///
13762/// @param corp the corpus to look into.
13764lookup_class_type(const string& qualified_name, const corpus& corp)
13765{
13766 interned_string s = corp.get_environment().intern(qualified_name);
13767 return lookup_class_type(s, corp);
13768}
13769
13770/// Look into a given corpus to find a class type which has a given
13771/// qualified name.
13772///
13773/// If the per-corpus type map is non-empty (because the corpus allows
13774/// the One Definition Rule) then the type islooked up in that
13775/// per-corpus type map. Otherwise, the type is looked-up in each
13776/// translation unit.
13777///
13778/// @param qualified_name the qualified name of the type to look for.
13779///
13780/// @param corp the corpus to look into.
13782lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13783{
13785
13786 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13787
13788 return result;
13789}
13790
13791/// Look into a given corpus to find the class type*s* that have a
13792/// given qualified name.
13793///
13794/// @param qualified_name the qualified name of the type to look for.
13795///
13796/// @param corp the corpus to look into.
13797///
13798/// @return the vector of class types named @p qualified_name.
13800lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13801{
13803
13804 return lookup_types_in_map(qualified_name, m);
13805}
13806
13807/// Look into a given corpus to find the class type*s* that have a
13808/// given qualified name and that are declaration-only.
13809///
13810/// @param qualified_name the qualified name of the type to look for.
13811///
13812/// @param corp the corpus to look into.
13813///
13814/// @param result the vector of decl-only class types named @p
13815/// qualified_name. This is populated iff the function returns true.
13816///
13817/// @return true iff @p result was populated with the decl-only
13818/// classes named @p qualified_name.
13819bool
13821 const corpus& corp,
13822 type_base_wptrs_type& result)
13823{
13825
13826 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13827 if (!v)
13828 return false;
13829
13830 for (auto type : *v)
13831 {
13832 type_base_sptr t(type);
13834 if (c->get_is_declaration_only()
13835 && !c->get_definition_of_declaration())
13836 result.push_back(type);
13837 }
13838
13839 return !result.empty();
13840}
13841
13842/// Look into a given corpus to find the union type*s* that have a
13843/// given qualified name.
13844///
13845/// @param qualified_name the qualified name of the type to look for.
13846///
13847/// @param corp the corpus to look into.
13848///
13849/// @return the vector of union types named @p qualified_name.
13851lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13852{
13854
13855 return lookup_types_in_map(qualified_name, m);
13856}
13857
13858/// Look into a given corpus to find the class type*s* that have a
13859/// given qualified name.
13860///
13861/// @param qualified_name the qualified name of the type to look for.
13862///
13863/// @param corp the corpus to look into.
13864///
13865/// @return the vector of class types which name is @p qualified_name.
13867lookup_class_types(const string& qualified_name, const corpus& corp)
13868{
13869 interned_string s = corp.get_environment().intern(qualified_name);
13870 return lookup_class_types(s, corp);
13871}
13872
13873/// Look into a given corpus to find the union types that have a given
13874/// qualified name.
13875///
13876/// @param qualified_name the qualified name of the type to look for.
13877///
13878/// @param corp the corpus to look into.
13879///
13880/// @return the vector of union types which name is @p qualified_name.
13882lookup_union_types(const string& qualified_name, const corpus& corp)
13883{
13884 interned_string s = corp.get_environment().intern(qualified_name);
13885 return lookup_union_types(s, corp);
13886}
13887
13888/// Look up a @ref class_decl from a given corpus by its location.
13889///
13890/// @param loc the location to consider.
13891///
13892/// @param corp the corpus to consider.
13893///
13894/// @return the resulting class decl, if any.
13897 const corpus& corp)
13898{
13901 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13902
13903 return result;
13904}
13905
13906/// Look up a @ref class_decl from a given corpus by its location.
13907///
13908/// @param loc the location to consider.
13909///
13910/// @param corp the corpus to consider.
13911///
13912/// @return the resulting class decl, if any.
13914lookup_class_type_per_location(const string &loc, const corpus &corp)
13915{
13916 const environment& env = corp.get_environment();
13917 return lookup_class_type_per_location(env.intern(loc), corp);
13918}
13919
13920/// Look into a given corpus to find a union type which has a given
13921/// qualified name.
13922///
13923/// If the per-corpus type map is non-empty (because the corpus allows
13924/// the One Definition Rule) then the type islooked up in that
13925/// per-corpus type map. Otherwise, the type is looked-up in each
13926/// translation unit.
13927///
13928/// @param qualified_name the qualified name of the type to look for.
13929///
13930/// @param corp the corpus to look into.
13931union_decl_sptr
13932lookup_union_type(const interned_string& type_name, const corpus& corp)
13933{
13935
13936 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13937 if (!result)
13938 result = lookup_union_type_through_translation_units(type_name, corp);
13939
13940 return result;
13941}
13942
13943/// Look into a given corpus to find a union type which has a given
13944/// qualified name.
13945///
13946/// If the per-corpus type map is non-empty (because the corpus allows
13947/// the One Definition Rule) then the type islooked up in that
13948/// per-corpus type map. Otherwise, the type is looked-up in each
13949/// translation unit.
13950///
13951/// @param qualified_name the qualified name of the type to look for.
13952///
13953/// @param corp the corpus to look into.
13954union_decl_sptr
13955lookup_union_type(const string& type_name, const corpus& corp)
13956{
13957 interned_string s = corp.get_environment().intern(type_name);
13958 return lookup_union_type(s, corp);
13959}
13960
13961/// Look into a given corpus to find an enum type which has the same
13962/// qualified name as a given enum type.
13963///
13964/// If the per-corpus type map is non-empty (because the corpus allows
13965/// the One Definition Rule) then the type islooked up in that
13966/// per-corpus type map. Otherwise, the type is looked-up in each
13967/// translation unit.
13968///
13969/// @param t the enum type which has the same qualified name as the
13970/// type we are looking for.
13971///
13972/// @param corp the corpus to look into.
13975{
13977 return lookup_enum_type(s, corp);
13978}
13979
13980/// Look into a given corpus to find an enum type which has a given
13981/// qualified name.
13982///
13983/// If the per-corpus type map is non-empty (because the corpus allows
13984/// the One Definition Rule) then the type islooked up in that
13985/// per-corpus type map. Otherwise, the type is looked-up in each
13986/// translation unit.
13987///
13988/// @param qualified_name the qualified name of the enum type to look
13989/// for.
13990///
13991/// @param corp the corpus to look into.
13993lookup_enum_type(const string& qualified_name, const corpus& corp)
13994{
13995 interned_string s = corp.get_environment().intern(qualified_name);
13996 return lookup_enum_type(s, corp);
13997}
13998
13999/// Look into a given corpus to find an enum type which has a given
14000/// qualified name.
14001///
14002/// If the per-corpus type map is non-empty (because the corpus allows
14003/// the One Definition Rule) then the type islooked up in that
14004/// per-corpus type map. Otherwise, the type is looked-up in each
14005/// translation unit.
14006///
14007/// @param qualified_name the qualified name of the enum type to look
14008/// for.
14009///
14010/// @param corp the corpus to look into.
14012lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
14013{
14015
14016 enum_type_decl_sptr result =
14017 lookup_type_in_map<enum_type_decl>(qualified_name, m);
14018 if (!result)
14019 result = lookup_enum_type_through_translation_units(qualified_name, corp);
14020
14021 return result;
14022}
14023
14024/// Look into a given corpus to find the enum type*s* that have a
14025/// given qualified name.
14026///
14027/// @param qualified_name the qualified name of the type to look for.
14028///
14029/// @param corp the corpus to look into.
14030///
14031/// @return the vector of enum types that which name is @p qualified_name.
14033lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
14034{
14036
14037 return lookup_types_in_map(qualified_name, m);
14038}
14039
14040/// Look into a given corpus to find the enum type*s* that have a
14041/// given qualified name.
14042///
14043/// @param qualified_name the qualified name of the type to look for.
14044///
14045/// @param corp the corpus to look into.
14046///
14047/// @return the vector of enum types that which name is @p qualified_name.
14049lookup_enum_types(const string& qualified_name, const corpus& corp)
14050{
14051 interned_string s = corp.get_environment().intern(qualified_name);
14052 return lookup_enum_types(s, corp);
14053}
14054
14055/// Look up an @ref enum_type_decl from a given corpus, by its location.
14056///
14057/// @param loc the location to consider.
14058///
14059/// @param corp the corpus to look the type from.
14060///
14061/// @return the resulting enum type, if any.
14064{
14067 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
14068
14069 return result;
14070}
14071
14072/// Look up an @ref enum_type_decl from a given corpus, by its location.
14073///
14074/// @param loc the location to consider.
14075///
14076/// @param corp the corpus to look the type from.
14077///
14078/// @return the resulting enum type, if any.
14080lookup_enum_type_per_location(const string &loc, const corpus &corp)
14081{
14082 const environment& env = corp.get_environment();
14083 return lookup_enum_type_per_location(env.intern(loc), corp);
14084}
14085
14086/// Look into a given corpus to find a typedef type which has the
14087/// same qualified name as a given typedef type.
14088///
14089/// If the per-corpus type map is non-empty (because the corpus allows
14090/// the One Definition Rule) then the type islooked up in that
14091/// per-corpus type map. Otherwise, the type is looked-up in each
14092/// translation unit.
14093///
14094/// @param t the typedef type which has the same qualified name as the
14095/// typedef type we are looking for.
14096///
14097/// @param corp the corpus to look into.
14100{
14102 return lookup_typedef_type(s, corp);
14103}
14104
14105/// Look into a given corpus to find a typedef type which has the
14106/// same qualified name as a given typedef type.
14107///
14108/// If the per-corpus type map is non-empty (because the corpus allows
14109/// the One Definition Rule) then the type islooked up in that
14110/// per-corpus type map. Otherwise, the type is looked-up in each
14111/// translation unit.
14112///
14113/// @param t the typedef type which has the same qualified name as the
14114/// typedef type we are looking for.
14115///
14116/// @param corp the corpus to look into.
14118lookup_typedef_type(const string& qualified_name, const corpus& corp)
14119{
14120 interned_string s = corp.get_environment().intern(qualified_name);
14121 return lookup_typedef_type(s, corp);
14122}
14123
14124/// Look into a given corpus to find a typedef type which has a
14125/// given qualified name.
14126///
14127/// If the per-corpus type map is non-empty (because the corpus allows
14128/// the One Definition Rule) then the type islooked up in that
14129/// per-corpus type map. Otherwise, the type is looked-up in each
14130/// translation unit.
14131///
14132/// @param qualified_name the qualified name of the typedef type to
14133/// look for.
14134///
14135/// @param corp the corpus to look into.
14137lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
14138{
14140
14141 typedef_decl_sptr result =
14142 lookup_type_in_map<typedef_decl>(qualified_name, m);
14143 if (!result)
14144 result = lookup_typedef_type_through_translation_units(qualified_name,
14145 corp);
14146
14147 return result;
14148}
14149
14150/// Lookup a @ref typedef_decl from a corpus, by its location.
14151///
14152/// @param loc the location to consider.
14153///
14154/// @param corp the corpus to consider.
14155///
14156/// @return the typedef_decl found, if any.
14159{
14162 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
14163
14164 return result;
14165}
14166
14167/// Lookup a @ref typedef_decl from a corpus, by its location.
14168///
14169/// @param loc the location to consider.
14170///
14171/// @param corp the corpus to consider.
14172///
14173/// @return the typedef_decl found, if any.
14175lookup_typedef_type_per_location(const string &loc, const corpus &corp)
14176{
14177 const environment& env = corp.get_environment();
14178 return lookup_typedef_type_per_location(env.intern(loc), corp);
14179}
14180
14181/// Look into a corpus to find a class, union or typedef type which
14182/// has a given qualified name.
14183///
14184/// If the per-corpus type map is non-empty (because the corpus allows
14185/// the One Definition Rule) then the type islooked up in that
14186/// per-corpus type map. Otherwise, the type is looked-up in each
14187/// translation unit.
14188///
14189/// @param qualified_name the name of the type to find.
14190///
14191/// @param corp the corpus to look into.
14192///
14193/// @return the typedef or class type found.
14194type_base_sptr
14195lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
14196{
14197 type_base_sptr result = lookup_class_type(qualified_name, corp);
14198 if (!result)
14199 result = lookup_union_type(qualified_name, corp);
14200
14201 if (!result)
14202 result = lookup_typedef_type(qualified_name, corp);
14203 return result;
14204}
14205
14206/// Look into a corpus to find a class, typedef or enum type which has
14207/// a given qualified name.
14208///
14209/// If the per-corpus type map is non-empty (because the corpus allows
14210/// the One Definition Rule) then the type islooked up in that
14211/// per-corpus type map. Otherwise, the type is looked-up in each
14212/// translation unit.
14213///
14214/// @param qualified_name the qualified name of the type to look for.
14215///
14216/// @param corp the corpus to look into.
14217///
14218/// @return the typedef, class or enum type found.
14219type_base_sptr
14220lookup_class_typedef_or_enum_type(const string& qualified_name,
14221 const corpus& corp)
14222{
14223 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
14224 if (!result)
14225 result = lookup_enum_type(qualified_name, corp);
14226
14227 return result;
14228}
14229
14230/// Look into a given corpus to find a qualified type which has the
14231/// same qualified name as a given type.
14232///
14233/// @param t the type which has the same qualified name as the
14234/// qualified type we are looking for.
14235///
14236/// @param corp the corpus to look into.
14237///
14238/// @return the qualified type found.
14239qualified_type_def_sptr
14241{
14243 return lookup_qualified_type(s, corp);
14244}
14245
14246/// Look into a given corpus to find a qualified type which has a
14247/// given qualified name.
14248///
14249/// @param qualified_name the qualified name of the type to look for.
14250///
14251/// @param corp the corpus to look into.
14252///
14253/// @return the type found.
14254qualified_type_def_sptr
14255lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
14256{
14258 corp.get_types().qualified_types();
14259
14260 qualified_type_def_sptr result =
14261 lookup_type_in_map<qualified_type_def>(qualified_name, m);
14262
14263 if (!result)
14264 result = lookup_qualified_type_through_translation_units(qualified_name,
14265 corp);
14266
14267 return result;
14268}
14269
14270/// Look into a given corpus to find a pointer type which has the same
14271/// qualified name as a given pointer type.
14272///
14273/// @param t the pointer type which has the same qualified name as the
14274/// type we are looking for.
14275///
14276/// @param corp the corpus to look into.
14277///
14278/// @return the pointer type found.
14281{
14283 return lookup_pointer_type(s, corp);
14284}
14285
14286/// Look into a given corpus to find a pointer type which has a given
14287/// qualified name.
14288///
14289/// If the per-corpus type map is non-empty (because the corpus allows
14290/// the One Definition Rule) then the type islooked up in that
14291/// per-corpus type map. Otherwise, the type is looked-up in each
14292/// translation unit.
14293///
14294/// @param qualified_name the qualified name of the pointer type to
14295/// look for.
14296///
14297/// @param corp the corpus to look into.
14298///
14299/// @return the pointer type found.
14301lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
14302{
14304
14305 pointer_type_def_sptr result =
14306 lookup_type_in_map<pointer_type_def>(qualified_name, m);
14307 if (!result)
14308 result = lookup_pointer_type_through_translation_units(qualified_name,
14309 corp);
14310
14311 return result;
14312}
14313
14314/// Look into a given corpus to find a reference type which has the
14315/// same qualified name as a given reference type.
14316///
14317/// If the per-corpus type map is non-empty (because the corpus allows
14318/// the One Definition Rule) then the type islooked up in that
14319/// per-corpus type map. Otherwise, the type is looked-up in each
14320/// translation unit.
14321///
14322/// @param t the reference type which has the same qualified name as
14323/// the reference type we are looking for.
14324///
14325/// @param corp the corpus to look into.
14326///
14327/// @return the reference type found.
14330{
14332 return lookup_reference_type(s, corp);
14333}
14334
14335/// Look into a given corpus to find a reference type which has a
14336/// given qualified name.
14337///
14338/// If the per-corpus type map is non-empty (because the corpus allows
14339/// the One Definition Rule) then the type islooked up in that
14340/// per-corpus type map. Otherwise, the type is looked-up in each
14341/// translation unit.
14342///
14343/// @param qualified_name the qualified name of the reference type to
14344/// look for.
14345///
14346/// @param corp the corpus to look into.
14347///
14348/// @return the reference type found.
14350lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
14351{
14353 corp.get_types().reference_types();
14354
14356 lookup_type_in_map<reference_type_def>(qualified_name, m);
14357 if (!result)
14358 result = lookup_reference_type_through_translation_units(qualified_name,
14359 corp);
14360
14361 return result;
14362}
14363
14364/// Look into a given corpus to find an array type which has a given
14365/// qualified name.
14366///
14367/// If the per-corpus type map is non-empty (because the corpus allows
14368/// the One Definition Rule) then the type islooked up in that
14369/// per-corpus type map. Otherwise, the type is looked-up in each
14370/// translation unit.
14371///
14372/// @param qualified_name the qualified name of the array type to look
14373/// for.
14374///
14375/// @param corp the corpus to look into.
14376///
14377/// @return the array type found.
14380{
14382 return lookup_array_type(s, corp);
14383}
14384
14385/// Look into a given corpus to find an array type which has the same
14386/// qualified name as a given array type.
14387///
14388/// If the per-corpus type map is non-empty (because the corpus allows
14389/// the One Definition Rule) then the type islooked up in that
14390/// per-corpus type map. Otherwise, the type is looked-up in each
14391/// translation unit.
14392///
14393/// @param t the type which has the same qualified name as the type we
14394/// are looking for.
14395///
14396/// @param corp the corpus to look into.
14397///
14398/// @return the type found.
14400lookup_array_type(const interned_string& qualified_name, const corpus& corp)
14401{
14403
14404 array_type_def_sptr result =
14405 lookup_type_in_map<array_type_def>(qualified_name, m);
14406 if (!result)
14407 result = lookup_array_type_through_translation_units(qualified_name, corp);
14408
14409 return result;
14410}
14411
14412/// Look into a given corpus to find a function type which has the same
14413/// qualified name as a given function type.
14414///
14415/// If the per-corpus type map is non-empty (because the corpus allows
14416/// the One Definition Rule) then the type islooked up in that
14417/// per-corpus type map. Otherwise, the type is looked-up in each
14418/// translation unit.
14419///
14420/// @param t the function type which has the same qualified name as
14421/// the function type we are looking for.
14422///
14423/// @param corp the corpus to look into.
14424///
14425/// @return the function type found.
14428{
14429 interned_string type_name = get_type_name(t);
14430 return lookup_function_type(type_name, corp);
14431}
14432
14433/// Look into a given corpus to find a function type which has the same
14434/// qualified name as a given function type.
14435///
14436/// If the per-corpus type map is non-empty (because the corpus allows
14437/// the One Definition Rule) then the type islooked up in that
14438/// per-corpus type map. Otherwise, the type is looked-up in each
14439/// translation unit.
14440///
14441/// @param t the function type which has the same qualified name as
14442/// the function type we are looking for.
14443///
14444/// @param corp the corpus to look into.
14445///
14446/// @return the function type found.
14449 const corpus& corpus)
14450{
14451 if (fn_t)
14452 return lookup_function_type(*fn_t, corpus);
14453 return function_type_sptr();
14454}
14455
14456/// Look into a given corpus to find a function type which has a given
14457/// qualified name.
14458///
14459/// If the per-corpus type map is non-empty (because the corpus allows
14460/// the One Definition Rule) then the type islooked up in that
14461/// per-corpus type map. Otherwise, the type is looked-up in each
14462/// translation unit.
14463///
14464/// @param qualified_name the qualified name of the function type to
14465/// look for.
14466///
14467/// @param corp the corpus to look into.
14468///
14469/// @return the function type found.
14471lookup_function_type(const interned_string& qualified_name, const corpus& corp)
14472{
14474
14475 function_type_sptr result =
14476 lookup_type_in_map<function_type>(qualified_name, m);
14477 if (!result)
14478 result = lookup_function_type_through_translation_units(qualified_name,
14479 corp);
14480
14481 return result;
14482}
14483
14484/// Look into a given corpus to find a type which has a given
14485/// qualified name.
14486///
14487/// If the per-corpus type map is non-empty (because the corpus allows
14488/// the One Definition Rule) then the type islooked up in that
14489/// per-corpus type map. Otherwise, the type is looked-up in each
14490/// translation unit.
14491///
14492/// @param qualified_name the qualified name of the function type to
14493/// look for.
14494///
14495/// @param corp the corpus to look into.
14496///
14497/// @return the function type found.
14498type_base_sptr
14499lookup_type(const interned_string& n, const corpus& corp)
14500{
14501 type_base_sptr result;
14502
14503 ((result = lookup_basic_type(n, corp))
14504 || (result = lookup_class_type(n, corp))
14505 || (result = lookup_union_type(n, corp))
14506 || (result = lookup_enum_type(n, corp))
14507 || (result = lookup_typedef_type(n, corp))
14508 || (result = lookup_qualified_type(n, corp))
14509 || (result = lookup_pointer_type(n, corp))
14510 || (result = lookup_reference_type(n, corp))
14511 || (result = lookup_array_type(n, corp))
14512 || (result= lookup_function_type(n, corp)));
14513
14514 return result;
14515}
14516
14517/// Lookup a type from a corpus, by its location.
14518///
14519/// @param loc the location to consider.
14520///
14521/// @param corp the corpus to look the type from.
14522///
14523/// @return the resulting type, if any found.
14524type_base_sptr
14526{
14527 // TODO: finish this.
14528
14529 //TODO: when we fully support types indexed by their location, this
14530 //function should return a vector of types because at each location,
14531 //there can be several types that are defined (yay, C and C++,
14532 //*sigh*).
14533
14534 type_base_sptr result;
14535 ((result = lookup_basic_type_per_location(loc, corp))
14536 || (result = lookup_class_type_per_location(loc, corp))
14537 || (result = lookup_union_type_per_location(loc, corp))
14538 || (result = lookup_enum_type_per_location(loc, corp))
14539 || (result = lookup_typedef_type_per_location(loc, corp)));
14540
14541 return result;
14542}
14543
14544/// Look into a given corpus to find a type
14545///
14546/// If the per-corpus type map is non-empty (because the corpus allows
14547/// the One Definition Rule) then the type islooked up in that
14548/// per-corpus type map. Otherwise, the type is looked-up in each
14549/// translation unit.
14550///
14551/// @param qualified_name the qualified name of the function type to
14552/// look for.
14553///
14554/// @param corp the corpus to look into.
14555///
14556/// @return the function type found.
14557type_base_sptr
14558lookup_type(const type_base&t, const corpus& corp)
14559{
14561 return lookup_type(n, corp);
14562}
14563
14564/// Look into a given corpus to find a type
14565///
14566/// If the per-corpus type map is non-empty (because the corpus allows
14567/// the One Definition Rule) then the type islooked up in that
14568/// per-corpus type map. Otherwise, the type is looked-up in each
14569/// translation unit.
14570///
14571/// @param qualified_name the qualified name of the function type to
14572/// look for.
14573///
14574/// @param corp the corpus to look into.
14575///
14576/// @return the function type found.
14577type_base_sptr
14578lookup_type(const type_base_sptr&t, const corpus& corp)
14579{
14580 if (t)
14581 return lookup_type(*t, corp);
14582 return type_base_sptr();
14583}
14584
14585/// Update the map that associates a fully qualified name of a given
14586/// type to that type.
14587///
14588///
14589/// @param type the type we are considering.
14590///
14591/// @param types_map the map to update. It's a map that assciates a
14592/// fully qualified name of a type to the type itself.
14593///
14594/// @param use_type_name_as_key if true, use the name of the type as
14595/// the key to look it up later. If false, then use the location of
14596/// the type as a key to look it up later.
14597///
14598/// @return true iff the type was added to the map.
14599template<typename TypeKind>
14600bool
14601maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
14603 bool use_type_name_as_key = true)
14604{
14606
14607 if (use_type_name_as_key)
14608 s = get_type_name(type);
14609 else if (location l = type->get_location())
14610 {
14611 string str = l.expand();
14612 s = type->get_environment().intern(str);
14613 }
14614
14615 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14616 bool result = false;
14617
14618 if (i == types_map.end())
14619 {
14620 types_map[s].push_back(type);
14621 result = true;
14622 }
14623 else
14624 i->second.push_back(type);
14625
14626 return result;
14627}
14628
14629/// This is the specialization for type @ref class_decl of the
14630/// function template:
14631///
14632/// maybe_update_types_lookup_map<T>(scope_decl*,
14633/// const shared_ptr<T>&,
14634/// istring_type_base_wptrs_map_type&)
14635///
14636/// @param class_type the type to consider.
14637///
14638/// @param types_map the type map to update.
14639///
14640/// @return true iff the type was added to the map.
14641template<>
14642bool
14645 bool use_type_name_as_key)
14646{
14647 class_decl_sptr type = class_type;
14648
14649 bool update_qname_map = true;
14650 if (type->get_is_declaration_only())
14651 {
14652 // Let's try to look through decl-only classes to get their
14653 // definition. But if the class doesn't have a definition then
14654 // we'll keep it.
14655 if (class_decl_sptr def =
14656 is_class_type(class_type->get_definition_of_declaration()))
14657 type = def;
14658 }
14659
14660 if (!update_qname_map)
14661 return false;
14662
14664 if (use_type_name_as_key)
14665 {
14666 string qname = type->get_qualified_name();
14667 s = type->get_environment().intern(qname);
14668 }
14669 else if (location l = type->get_location())
14670 {
14671 string str = l.expand();
14672 s = type->get_environment().intern(str);
14673 }
14674
14675 bool result = false;
14676 istring_type_base_wptrs_map_type::iterator i = map.find(s);
14677 if (i == map.end())
14678 {
14679 map[s].push_back(type);
14680 result = true;
14681 }
14682 else
14683 i->second.push_back(type);
14684
14685 return result;
14686}
14687
14688/// This is the specialization for type @ref function_type of the
14689/// function template:
14690///
14691/// maybe_update_types_lookup_map<T>(scope_decl*,
14692/// const shared_ptr<T>&,
14693/// istring_type_base_wptrs_map_type&)
14694///
14695/// @param scope the scope of the type to consider.
14696///
14697/// @param class_type the type to consider.
14698///
14699/// @param types_map the type map to update.
14700///
14701/// @return true iff the type was added to the map.
14702template<>
14703bool
14705(const function_type_sptr& type,
14707 bool /*use_type_name_as_key*/)
14708{
14709 bool result = false;
14711 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14712 if (i == types_map.end())
14713 {
14714 types_map[s].push_back(type);
14715 result = true;
14716 }
14717 else
14718 i->second.push_back(type);
14719
14720 return result;
14721}
14722
14723/// Update the map that associates the fully qualified name of a basic
14724/// type with the type itself.
14725///
14726/// The per-translation unit type map is updated if no type with this
14727/// name was already existing in that map.
14728///
14729/// If no type with this name did already exist in the per-corpus type
14730/// map, then that per-corpus type map is updated. Otherwise, that
14731/// type is erased from that per-corpus map.
14732///
14733/// @param basic_type the basic type to consider.
14734void
14736{
14737 if (translation_unit *tu = basic_type->get_translation_unit())
14738 maybe_update_types_lookup_map<type_decl>
14739 (basic_type, tu->get_types().basic_types());
14740
14741 if (corpus *type_corpus = basic_type->get_corpus())
14742 {
14743 maybe_update_types_lookup_map<type_decl>
14744 (basic_type,
14745 type_corpus->priv_->get_types().basic_types());
14746
14747 maybe_update_types_lookup_map<type_decl>
14748 (basic_type,
14749 type_corpus->get_type_per_loc_map().basic_types(),
14750 /*use_type_name_as_key*/false);
14751
14752 if (corpus *group = type_corpus->get_group())
14753 {
14754 maybe_update_types_lookup_map<type_decl>
14755 (basic_type,
14756 group->priv_->get_types().basic_types());
14757
14758 maybe_update_types_lookup_map<type_decl>
14759 (basic_type,
14760 group->get_type_per_loc_map().basic_types(),
14761 /*use_type_name_as_key*/false);
14762 }
14763 }
14764
14765}
14766
14767/// Update the map that associates the fully qualified name of a class
14768/// type with the type itself.
14769///
14770/// The per-translation unit type map is updated if no type with this
14771/// name was already existing in that map.
14772///
14773/// If no type with this name did already exist in the per-corpus type
14774/// map, then that per-corpus type map is updated. Otherwise, that
14775/// type is erased from that per-corpus map.
14776///
14777/// @param class_type the class type to consider.
14778void
14780{
14781 if (translation_unit *tu = class_type->get_translation_unit())
14783 (class_type, tu->get_types().class_types());
14784
14785 if (corpus *type_corpus = class_type->get_corpus())
14786 {
14788 (class_type,
14789 type_corpus->priv_->get_types().class_types());
14790
14792 (class_type,
14793 type_corpus->get_type_per_loc_map().class_types(),
14794 /*use_type_name_as_key*/false);
14795
14796 if (corpus *group = type_corpus->get_group())
14797 {
14799 (class_type,
14800 group->priv_->get_types().class_types());
14801
14803 (class_type,
14804 group->get_type_per_loc_map().class_types(),
14805 /*use_type_name_as_key*/false);
14806 }
14807 }
14808}
14809
14810/// Update the map that associates the fully qualified name of a union
14811/// type with the type itself.
14812///
14813/// The per-translation unit type map is updated if no type with this
14814/// name was already existing in that map.
14815///
14816/// If no type with this name did already exist in the per-corpus type
14817/// map, then that per-corpus type map is updated. Otherwise, that
14818/// type is erased from that per-corpus map.
14819///
14820/// @param union_type the union type to consider.
14821void
14822maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14823{
14824 if (translation_unit *tu = union_type->get_translation_unit())
14825 maybe_update_types_lookup_map<union_decl>
14826 (union_type, tu->get_types().union_types());
14827
14828 if (corpus *type_corpus = union_type->get_corpus())
14829 {
14830 maybe_update_types_lookup_map<union_decl>
14831 (union_type,
14832 type_corpus->priv_->get_types().union_types());
14833
14834 maybe_update_types_lookup_map<union_decl>
14835 (union_type,
14836 type_corpus->get_type_per_loc_map().union_types(),
14837 /*use_type_name_as_key*/false);
14838
14839 if (corpus *group = type_corpus->get_group())
14840 {
14841 maybe_update_types_lookup_map<union_decl>
14842 (union_type,
14843 group->priv_->get_types().union_types());
14844
14845 maybe_update_types_lookup_map<union_decl>
14846 (union_type,
14847 group->get_type_per_loc_map().union_types(),
14848 /*use_type_name_as_key*/false);
14849 }
14850 }
14851}
14852
14853/// Update the map that associates the fully qualified name of an enum
14854/// type with the type itself.
14855///
14856/// The per-translation unit type map is updated if no type with this
14857/// name was already existing in that map.
14858///
14859/// If no type with this name did already exist in the per-corpus type
14860/// map, then that per-corpus type map is updated. Otherwise, that
14861/// type is erased from that per-corpus map.
14862///
14863/// @param enum_type the type to consider.
14864void
14866{
14867 if (translation_unit *tu = enum_type->get_translation_unit())
14868 maybe_update_types_lookup_map<enum_type_decl>
14869 (enum_type, tu->get_types().enum_types());
14870
14871 if (corpus *type_corpus = enum_type->get_corpus())
14872 {
14873 maybe_update_types_lookup_map<enum_type_decl>
14874 (enum_type,
14875 type_corpus->priv_->get_types().enum_types());
14876
14877 maybe_update_types_lookup_map<enum_type_decl>
14878 (enum_type,
14879 type_corpus->get_type_per_loc_map().enum_types(),
14880 /*use_type_name_as_key*/false);
14881
14882 if (corpus *group = type_corpus->get_group())
14883 {
14884 maybe_update_types_lookup_map<enum_type_decl>
14885 (enum_type,
14886 group->priv_->get_types().enum_types());
14887
14888 maybe_update_types_lookup_map<enum_type_decl>
14889 (enum_type,
14890 group->get_type_per_loc_map().enum_types(),
14891 /*use_type_name_as_key*/false);
14892 }
14893 }
14894
14895}
14896
14897/// Update the map that associates the fully qualified name of a
14898/// typedef type with the type itself.
14899///
14900/// The per-translation unit type map is updated if no type with this
14901/// name was already existing in that map.
14902///
14903/// If no type with this name did already exist in the per-corpus type
14904/// map, then that per-corpus type map is updated. Otherwise, that
14905/// type is erased from that per-corpus map.
14906///
14907/// @param typedef_type the type to consider.
14908void
14910{
14911 if (translation_unit *tu = typedef_type->get_translation_unit())
14912 maybe_update_types_lookup_map<typedef_decl>
14913 (typedef_type, tu->get_types().typedef_types());
14914
14915 if (corpus *type_corpus = typedef_type->get_corpus())
14916 {
14917 maybe_update_types_lookup_map<typedef_decl>
14918 (typedef_type,
14919 type_corpus->priv_->get_types().typedef_types());
14920
14921 maybe_update_types_lookup_map<typedef_decl>
14922 (typedef_type,
14923 type_corpus->get_type_per_loc_map().typedef_types(),
14924 /*use_type_name_as_key*/false);
14925
14926 if (corpus *group = type_corpus->get_group())
14927 {
14928 maybe_update_types_lookup_map<typedef_decl>
14929 (typedef_type,
14930 group->priv_->get_types().typedef_types());
14931
14932 maybe_update_types_lookup_map<typedef_decl>
14933 (typedef_type,
14934 group->get_type_per_loc_map().typedef_types(),
14935 /*use_type_name_as_key*/false);
14936 }
14937 }
14938}
14939
14940/// Update the map that associates the fully qualified name of a
14941/// qualified type with the type itself.
14942///
14943/// The per-translation unit type map is updated if no type with this
14944/// name was already existing in that map.
14945///
14946/// If no type with this name did already exist in the per-corpus type
14947/// map, then that per-corpus type map is updated. Otherwise, that
14948/// type is erased from that per-corpus map.
14949///
14950/// @param qualified_type the type to consider.
14951void
14952maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14953{
14954 if (translation_unit *tu = qualified_type->get_translation_unit())
14955 maybe_update_types_lookup_map<qualified_type_def>
14956 (qualified_type, tu->get_types().qualified_types());
14957
14958 if (corpus *type_corpus = qualified_type->get_corpus())
14959 {
14960 maybe_update_types_lookup_map<qualified_type_def>
14961 (qualified_type,
14962 type_corpus->priv_->get_types().qualified_types());
14963
14964 if (corpus *group = type_corpus->get_group())
14965 {
14966 maybe_update_types_lookup_map<qualified_type_def>
14967 (qualified_type,
14968 group->priv_->get_types().qualified_types());
14969 }
14970 }
14971}
14972
14973/// Update the map that associates the fully qualified name of a
14974/// pointer type with the type itself.
14975///
14976/// The per-translation unit type map is updated if no type with this
14977/// name was already existing in that map.
14978///
14979/// If no type with this name did already exist in the per-corpus type
14980/// map, then that per-corpus type map is updated. Otherwise, that
14981/// type is erased from that per-corpus map.
14982///
14983/// @param pointer_type the type to consider.
14984void
14986{
14987 if (translation_unit *tu = pointer_type->get_translation_unit())
14988 maybe_update_types_lookup_map<pointer_type_def>
14989 (pointer_type, tu->get_types().pointer_types());
14990
14991 if (corpus *type_corpus = pointer_type->get_corpus())
14992 {
14993 maybe_update_types_lookup_map<pointer_type_def>
14994 (pointer_type,
14995 type_corpus->priv_->get_types().pointer_types());
14996
14997 if (corpus *group = type_corpus->get_group())
14998 {
14999 maybe_update_types_lookup_map<pointer_type_def>
15000 (pointer_type,
15001 group->priv_->get_types().pointer_types());
15002 }
15003 }
15004}
15005
15006/// Update the map that associates the fully qualified name of a
15007/// pointer-to-member type with the type itself.
15008///
15009/// The per-translation unit type map is updated if no type with this
15010/// name was already existing in that map.
15011///
15012/// If no type with this name did already exist in the per-corpus type
15013/// map, then that per-corpus type map is updated. Otherwise, that
15014/// type is erased from that per-corpus map.
15015///
15016/// @param ptr_to_mbr_type the type to consider.
15017void
15019{
15020 if (translation_unit *tu = ptr_to_member->get_translation_unit())
15021 maybe_update_types_lookup_map<ptr_to_mbr_type>
15022 (ptr_to_member, tu->get_types().ptr_to_mbr_types());
15023
15024 if (corpus *type_corpus = ptr_to_member->get_corpus())
15025 {
15026 maybe_update_types_lookup_map<ptr_to_mbr_type>
15027 (ptr_to_member,
15028 type_corpus->priv_->get_types().ptr_to_mbr_types());
15029
15030 if (corpus *group = type_corpus->get_group())
15031 {
15032 maybe_update_types_lookup_map<ptr_to_mbr_type>
15033 (ptr_to_member,
15034 group->priv_->get_types().ptr_to_mbr_types());
15035 }
15036 }
15037}
15038
15039/// Update the map that associates the fully qualified name of a
15040/// reference type with the type itself.
15041///
15042/// The per-translation unit type map is updated if no type with this
15043/// name was already existing in that map.
15044///
15045/// If no type with this name did already exist in the per-corpus type
15046/// map, then that per-corpus type map is updated. Otherwise, that
15047/// type is erased from that per-corpus map.
15048///
15049/// @param reference_type the type to consider.
15050void
15052{
15053 if (translation_unit *tu = reference_type->get_translation_unit())
15054 maybe_update_types_lookup_map<reference_type_def>
15055 (reference_type, tu->get_types().reference_types());
15056
15057 if (corpus *type_corpus = reference_type->get_corpus())
15058 {
15059 maybe_update_types_lookup_map<reference_type_def>
15060 (reference_type,
15061 type_corpus->priv_->get_types().reference_types());
15062
15063 if (corpus *group = type_corpus->get_group())
15064 {
15065 maybe_update_types_lookup_map<reference_type_def>
15066 (reference_type,
15067 group->priv_->get_types().reference_types());
15068 }
15069 }
15070}
15071
15072/// Update the map that associates the fully qualified name of a type
15073/// with the type itself.
15074///
15075/// The per-translation unit type map is updated if no type with this
15076/// name was already existing in that map.
15077///
15078/// If no type with this name did already exist in the per-corpus type
15079/// map, then that per-corpus type map is updated. Otherwise, that
15080/// type is erased from that per-corpus map.
15081///
15082/// @param array_type the type to consider.
15083void
15085{
15086 if (translation_unit *tu = array_type->get_translation_unit())
15087 maybe_update_types_lookup_map<array_type_def>
15088 (array_type, tu->get_types().array_types());
15089
15090 if (corpus *type_corpus = array_type->get_corpus())
15091 {
15092 maybe_update_types_lookup_map<array_type_def>
15093 (array_type,
15094 type_corpus->priv_->get_types().array_types());
15095
15096 maybe_update_types_lookup_map<array_type_def>
15097 (array_type,
15098 type_corpus->get_type_per_loc_map().array_types(),
15099 /*use_type_name_as_key*/false);
15100
15101 if (corpus *group = type_corpus->get_group())
15102 {
15103 maybe_update_types_lookup_map<array_type_def>
15104 (array_type,
15105 group->priv_->get_types().array_types());
15106
15107 maybe_update_types_lookup_map<array_type_def>
15108 (array_type,
15109 group->get_type_per_loc_map().array_types(),
15110 /*use_type_name_as_key*/false);
15111 }
15112 }
15113}
15114
15115/// Update the map that associates the fully qualified name of a type
15116/// with the type itself.
15117///
15118/// The per-translation unit type map is updated if no type with this
15119/// name was already existing in that map.
15120///
15121/// If no type with this name did already exist in the per-corpus type
15122/// map, then that per-corpus type map is updated. Otherwise, that
15123/// type is erased from that per-corpus map.
15124///
15125/// @param subrange_type the type to consider.
15126void
15128(const array_type_def::subrange_sptr& subrange_type)
15129{
15130 if (translation_unit *tu = subrange_type->get_translation_unit())
15131 maybe_update_types_lookup_map<array_type_def::subrange_type>
15132 (subrange_type, tu->get_types().subrange_types());
15133
15134 if (corpus *type_corpus = subrange_type->get_corpus())
15135 {
15136 maybe_update_types_lookup_map<array_type_def::subrange_type>
15137 (subrange_type,
15138 type_corpus->priv_->get_types().subrange_types());
15139
15140 maybe_update_types_lookup_map<array_type_def::subrange_type>
15141 (subrange_type,
15142 type_corpus->get_type_per_loc_map().subrange_types(),
15143 /*use_type_name_as_key*/false);
15144
15145 if (corpus *group = subrange_type->get_corpus())
15146 {
15147 maybe_update_types_lookup_map<array_type_def::subrange_type>
15148 (subrange_type,
15149 group->priv_->get_types().subrange_types());
15150
15151 maybe_update_types_lookup_map<array_type_def::subrange_type>
15152 (subrange_type,
15153 group->get_type_per_loc_map().subrange_types(),
15154 /*use_type_name_as_key*/false);
15155 }
15156 }
15157}
15158
15159/// Update the map that associates the fully qualified name of a
15160/// function type with the type itself.
15161///
15162/// The per-translation unit type map is updated if no type with this
15163/// name was already existing in that map.
15164///
15165/// If no type with this name did already exist in the per-corpus type
15166/// map, then that per-corpus type map is updated. Otherwise, that
15167/// type is erased from that per-corpus map.
15168///
15169/// @param scope the scope of the function type.
15170/// @param fn_type the type to consider.
15171void
15173{
15174 if (translation_unit *tu = fn_type->get_translation_unit())
15176 (fn_type, tu->get_types().function_types());
15177
15178 if (corpus *type_corpus = fn_type->get_corpus())
15179 {
15181 (fn_type,
15182 type_corpus->priv_->get_types().function_types());
15183
15184 if (corpus *group = fn_type->get_corpus())
15185 {
15187 (fn_type,
15188 group->priv_->get_types().function_types());
15189 }
15190 }
15191}
15192
15193/// Update the map that associates the fully qualified name of a type
15194/// declaration with the type itself.
15195///
15196/// The per-translation unit type map is updated if no type with this
15197/// name was already existing in that map.
15198///
15199/// If no type with this name did already exist in the per-corpus type
15200/// map, then that per-corpus type map is updated. Otherwise, that
15201/// type is erased from that per-corpus map.
15202///
15203/// @param decl the declaration of the type to consider.
15204void
15205maybe_update_types_lookup_map(const decl_base_sptr& decl)
15206{
15207 if (!is_type(decl))
15208 return;
15209
15210 if (type_decl_sptr basic_type = is_type_decl(decl))
15212 else if (class_decl_sptr class_type = is_class_type(decl))
15214 else if (union_decl_sptr union_type = is_union_type(decl))
15216 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
15218 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
15219 maybe_update_types_lookup_map(typedef_type);
15220 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
15221 maybe_update_types_lookup_map(qualified_type);
15222 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
15223 maybe_update_types_lookup_map(pointer_type);
15224 else if (ptr_to_mbr_type_sptr ptr_to_member = is_ptr_to_mbr_type(decl))
15225 maybe_update_types_lookup_map(ptr_to_member);
15226 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
15227 maybe_update_types_lookup_map(reference_type);
15228 else if (array_type_def_sptr array_type = is_array_type(decl))
15230 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
15231 maybe_update_types_lookup_map(subrange_type);
15232 else if (function_type_sptr fn_type = is_function_type(decl))
15234 else
15236}
15237
15238/// Update the map that associates the fully qualified name of a type
15239/// with the type itself.
15240///
15241/// The per-translation unit type map is updated if no type with this
15242/// name was already existing in that map.
15243///
15244/// If no type with this name did already exist in the per-corpus type
15245/// map, then that per-corpus type map is updated. Otherwise, that
15246/// type is erased from that per-corpus map.
15247///
15248/// @param type the type to consider.
15249void
15250maybe_update_types_lookup_map(const type_base_sptr& type)
15251{
15252 if (decl_base_sptr decl = get_type_declaration(type))
15254 else if (function_type_sptr fn_type = is_function_type(type))
15256 else
15258}
15259
15260//--------------------------------
15261// </type and decls lookup stuff>
15262// ------------------------------
15263
15264/// In a translation unit, lookup a given type or synthesize it if
15265/// it's a qualified type.
15266///
15267/// So this function first looks the type up in the translation unit.
15268/// If it's found, then OK, it's returned. Otherwise, if it's a
15269/// qualified, reference or pointer or function type (a composite
15270/// type), lookup the underlying type, synthesize the type we want
15271/// from it and return it.
15272///
15273/// If the underlying types is not not found, then give up and return
15274/// nil.
15275///
15276/// @return the type that was found or the synthesized type.
15277type_base_sptr
15278synthesize_type_from_translation_unit(const type_base_sptr& type,
15279 translation_unit& tu)
15280{
15281 type_base_sptr result;
15282
15283 result = lookup_type(type, tu);
15284
15285 if (!result)
15286 {
15287 if (qualified_type_def_sptr qual = is_qualified_type(type))
15288 {
15289 type_base_sptr underlying_type =
15290 synthesize_type_from_translation_unit(qual->get_underlying_type(),
15291 tu);
15292 if (underlying_type)
15293 {
15294 result.reset(new qualified_type_def(underlying_type,
15295 qual->get_cv_quals(),
15296 qual->get_location()));
15297 }
15298 }
15299 else if (pointer_type_def_sptr p = is_pointer_type(type))
15300 {
15301 type_base_sptr pointed_to_type =
15302 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
15303 tu);
15304 if (pointed_to_type)
15305 {
15306 result.reset(new pointer_type_def(pointed_to_type,
15307 p->get_size_in_bits(),
15308 p->get_alignment_in_bits(),
15309 p->get_location()));
15310 }
15311 }
15312 else if (reference_type_def_sptr r = is_reference_type(type))
15313 {
15314 type_base_sptr pointed_to_type =
15315 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
15316 if (pointed_to_type)
15317 {
15318 result.reset(new reference_type_def(pointed_to_type,
15319 r->is_lvalue(),
15320 r->get_size_in_bits(),
15321 r->get_alignment_in_bits(),
15322 r->get_location()));
15323 }
15324 }
15325 else if (function_type_sptr f = is_function_type(type))
15327
15328 if (result)
15329 {
15331 canonicalize(result);
15332 }
15333 }
15334
15335 if (result)
15336 tu.priv_->synthesized_types_.push_back(result);
15337
15338 return result;
15339}
15340
15341/// In a translation unit, lookup the sub-types that make up a given
15342/// function type and if the sub-types are all found, synthesize and
15343/// return a function_type with them.
15344///
15345/// This function is like lookup_function_type_in_translation_unit()
15346/// execept that it constructs the function type from the sub-types
15347/// found in the translation, rather than just looking for the
15348/// function types held by the translation unit. This can be useful
15349/// if the translation unit doesnt hold the function type we are
15350/// looking for (i.e, lookup_function_type_in_translation_unit()
15351/// returned NULL) but we still want to see if the sub-types of the
15352/// function types are present in the translation unit.
15353///
15354/// @param fn_type the function type to consider.
15355///
15356/// @param tu the translation unit to look into.
15357///
15358/// @return the resulting synthesized function type if all its
15359/// sub-types have been found, NULL otherwise.
15362 translation_unit& tu)
15363{
15365
15366 const environment& env = tu.get_environment();
15367
15368 type_base_sptr return_type = fn_type.get_return_type();
15369 type_base_sptr result_return_type;
15370 if (!return_type || env.is_void_type(return_type))
15371 result_return_type = env.get_void_type();
15372 else
15373 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
15374 if (!result_return_type)
15375 return nil;
15376
15378 type_base_sptr parm_type;
15380 for (function_type::parameters::const_iterator i =
15381 fn_type.get_parameters().begin();
15382 i != fn_type.get_parameters().end();
15383 ++i)
15384 {
15385 type_base_sptr t = (*i)->get_type();
15386 parm_type = synthesize_type_from_translation_unit(t, tu);
15387 if (!parm_type)
15388 return nil;
15389 parm.reset(new function_decl::parameter(parm_type,
15390 (*i)->get_index(),
15391 (*i)->get_name(),
15392 (*i)->get_location(),
15393 (*i)->get_variadic_marker(),
15394 (*i)->get_is_artificial()));
15395 parms.push_back(parm);
15396 }
15397
15398 class_or_union_sptr class_type;
15399 const method_type* method = is_method_type(&fn_type);
15400 if (method)
15401 {
15402 class_type = is_class_or_union_type
15404 ABG_ASSERT(class_type);
15405 }
15406
15407 function_type_sptr result_fn_type;
15408
15409 if (class_type)
15410 result_fn_type.reset(new method_type(result_return_type,
15411 class_type,
15412 parms,
15413 method->get_is_const(),
15414 fn_type.get_size_in_bits(),
15415 fn_type.get_alignment_in_bits()));
15416 else
15417 result_fn_type.reset(new function_type(result_return_type,
15418 parms,
15419 fn_type.get_size_in_bits(),
15420 fn_type.get_alignment_in_bits()));
15421
15422 tu.priv_->synthesized_types_.push_back(result_fn_type);
15423 tu.bind_function_type_life_time(result_fn_type);
15424
15425 canonicalize(result_fn_type);
15426 return result_fn_type;
15427}
15428
15429/// Demangle a C++ mangled name and return the resulting string
15430///
15431/// @param mangled_name the C++ mangled name to demangle.
15432///
15433/// @return the resulting mangled name.
15434string
15435demangle_cplus_mangled_name(const string& mangled_name)
15436{
15437 if (mangled_name.empty())
15438 return "";
15439
15440 size_t l = 0;
15441 int status = 0;
15442 char * str = abi::__cxa_demangle(mangled_name.c_str(),
15443 NULL, &l, &status);
15444 string demangled_name = mangled_name;
15445 if (str)
15446 {
15447 ABG_ASSERT(status == 0);
15448 demangled_name = str;
15449 free(str);
15450 str = 0;
15451 }
15452 return demangled_name;
15453}
15454
15455/// Return either the type given in parameter if it's non-null, or the
15456/// void type.
15457///
15458/// @param t the type to consider.
15459///
15460/// @param env the environment to use. If NULL, just abort the
15461/// process.
15462///
15463/// @return either @p t if it is non-null, or the void type.
15464type_base_sptr
15465type_or_void(const type_base_sptr t, const environment& env)
15466{
15467 type_base_sptr r;
15468
15469 if (t)
15470 r = t;
15471 else
15472 r = type_base_sptr(env.get_void_type());
15473
15474 return r;
15475}
15476
15477global_scope::~global_scope()
15478{
15479}
15480
15481/// Test if two types are eligible to the "Linux Kernel Fast Type
15482/// Comparison Optimization", a.k.a LKFTCO.
15483///
15484/// Two types T1 and T2 (who are presumably of the same name and kind)
15485/// are eligible to the LKFTCO if they fulfill the following criteria/
15486///
15487/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
15488/// either class, union or enums.
15489///
15490/// 2/ They are defined in the same translation unit.
15491///
15492/// @param t1 the first type to consider.
15493///
15494/// @param t2 the second type to consider.
15495///
15496/// @return true iff t1 and t2 are eligible to the LKFTCO.
15497static bool
15498types_defined_same_linux_kernel_corpus_public(const type_base& t1,
15499 const type_base& t2)
15500{
15501 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
15502 string t1_file_path, t2_file_path;
15503
15504 /// If the t1 (and t2) are classes/unions/enums from the same linux
15505 /// kernel corpus, let's move on. Otherwise bail out.
15506 if (!(t1_corpus && t2_corpus
15507 && t1_corpus == t2_corpus
15508 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
15509 && (is_class_or_union_type(&t1)
15510 || is_enum_type(&t1))))
15511 return false;
15512
15513 class_or_union *c1 = 0, *c2 = 0;
15514 c1 = is_class_or_union_type(&t1);
15515 c2 = is_class_or_union_type(&t2);
15516
15517 // Two anonymous class types with no naming typedefs cannot be
15518 // eligible to this optimization.
15519 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
15520 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
15521 return false;
15522
15523 // Two anonymous classes with naming typedefs should have the same
15524 // typedef name.
15525 if (c1
15526 && c2
15527 && c1->get_is_anonymous() && c1->get_naming_typedef()
15528 && c2->get_is_anonymous() && c2->get_naming_typedef())
15529 if (c1->get_naming_typedef()->get_name()
15530 != c2->get_naming_typedef()->get_name())
15531 return false;
15532
15533 // Two anonymous enum types cannot be eligible to this optimization.
15534 if (const enum_type_decl *e1 = is_enum_type(&t1))
15535 if (const enum_type_decl *e2 = is_enum_type(&t2))
15536 if (e1->get_is_anonymous() || e2->get_is_anonymous())
15537 return false;
15538
15539 // Look through declaration-only types. That is, get the associated
15540 // definition type.
15543
15544 if (c1 && c2)
15545 {
15546 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
15547 {
15548 if (c1->get_environment().decl_only_class_equals_definition())
15549 // At least one of classes/union is declaration-only.
15550 // Because we are in a context in which a declaration-only
15551 // class/union is equal to all definitions of that
15552 // class/union, we can assume that the two types are
15553 // equal.
15554 return true;
15555 }
15556 }
15557
15558 if (t1.get_size_in_bits() != t2.get_size_in_bits())
15559 return false;
15560
15561 // Look at the file names of the locations of t1 and t2. If they
15562 // are equal, then t1 and t2 are defined in the same file.
15563 {
15564 location l;
15565
15566 if (c1)
15567 l = c1->get_location();
15568 else
15569 l = dynamic_cast<const decl_base&>(t1).get_location();
15570
15571 unsigned line = 0, col = 0;
15572 if (l)
15573 l.expand(t1_file_path, line, col);
15574 if (c2)
15575 l = c2->get_location();
15576 else
15577 l = dynamic_cast<const decl_base&>(t2).get_location();
15578 if (l)
15579 l.expand(t2_file_path, line, col);
15580 }
15581
15582 if (t1_file_path.empty() || t2_file_path.empty())
15583 return false;
15584
15585 if (t1_file_path == t2_file_path)
15586 return true;
15587
15588 return false;
15589}
15590
15591
15592/// Compare a type T against a canonical type.
15593///
15594/// This function is called during the canonicalization process of the
15595/// type T. T is called the "candidate type" because it's in the
15596/// process of being canonicalized. Meaning, it's going to be
15597/// compared to a canonical type C. If T equals C, then the canonical
15598/// type of T is C.
15599///
15600/// The purpose of this function is to allow the debugging of the
15601/// canonicalization of T, if that debugging is activated by
15602/// configuring the libabigail package with
15603/// --enable-debug-type-canonicalization and by running "abidw
15604/// --debug-tc". In that case, T is going to be compared to C twice:
15605/// once with canonical equality and once with structural equality.
15606/// The two comparisons must be equal. Otherwise, the
15607/// canonicalization process is said to be faulty and this function
15608/// aborts.
15609///
15610/// This is a sub-routine of type_base::get_canonical_type_for.
15611///
15612/// @param canonical_type the canonical type to compare the candidate
15613/// type against.
15614///
15615/// @param candidate_type the candidate type to compare against the
15616/// canonical type.
15617///
15618/// @return true iff @p canonical_type equals @p candidate_type.
15619///
15620static bool
15621compare_types_during_canonicalization(const type_base& canonical_type,
15622 const type_base& candidate_type)
15623{
15624#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
15625 const environment& env = canonical_type.get_environment();
15626 if (env.debug_type_canonicalization_is_on())
15627 {
15628 bool canonical_equality = false, structural_equality = false;
15629 env.priv_->allow_type_comparison_results_caching(false);
15630 env.priv_->use_canonical_type_comparison_ = false;
15631 structural_equality = canonical_type == candidate_type;
15632 env.priv_->use_canonical_type_comparison_ = true;
15633 canonical_equality = canonical_type == candidate_type;
15634 env.priv_->allow_type_comparison_results_caching(true);
15635 if (canonical_equality != structural_equality)
15636 {
15637 std::cerr << "structural & canonical equality different for type: "
15638 << canonical_type.get_pretty_representation(true, true)
15639 << std::endl;
15641 }
15642 return structural_equality;
15643 }
15644#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
15645 return canonical_type == candidate_type;
15646}
15647
15648/// Compare a canonical type against a candidate canonical type.
15649///
15650/// This is ultimately a sub-routine of the
15651/// type_base::get_canonical_type_for().
15652///
15653/// The goal of this function is to ease debugging because it can be
15654/// called from within type_base::get_canonical_type_for() from the
15655/// prompt of the debugger (with some breakpoint appropriately set) to
15656/// debug the comparison that happens during type canonicalization,
15657/// between a candidate type being canonicalized, and an existing
15658/// canonical type that is registered in the system, in as returned by
15659/// environment::get_canonical_types()
15660///
15661/// @param canonical_type the canonical type to consider.
15662///
15663/// @param candidate_type the candidate type that is being
15664/// canonicalized, and thus compared to @p canonical_type.
15665///
15666/// @return true iff @p canonical_type compares equal to @p
15667/// candidate_type.
15668static bool
15669compare_canonical_type_against_candidate(const type_base& canonical_type,
15670 const type_base& candidate_type)
15671{
15672 environment& env = const_cast<environment&>(canonical_type.get_environment());
15673
15674 // Before the "*it == it" comparison below is done, let's
15675 // perform on-the-fly-canonicalization. For C types, let's
15676 // consider that an unresolved struct declaration 'struct S'
15677 // is different from a definition 'struct S'. This is
15678 // because normally, at this point all the declarations of
15679 // struct S that are compatible with the definition of
15680 // struct S have already been resolved to that definition,
15681 // during the DWARF parsing. The remaining unresolved
15682 // declaration are thus considered different. With this
15683 // setup we can properly handle cases of two *different*
15684 // struct S being defined in the same binary (in different
15685 // translation units), and a third struct S being only
15686 // declared as an opaque type in a third translation unit of
15687 // its own, with no definition in there. In that case, the
15688 // declaration-only struct S should be left alone and not
15689 // resolved to any of the two definitions of struct S.
15690 bool saved_decl_only_class_equals_definition =
15691 env.decl_only_class_equals_definition();
15692
15693 // Compare types by considering that decl-only classes don't
15694 // equal their definition.
15695 env.decl_only_class_equals_definition(false);
15696 env.priv_->allow_type_comparison_results_caching(true);
15697 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
15698 candidate_type)
15699 || compare_types_during_canonicalization(canonical_type,
15700 candidate_type));
15701 // Restore the state of the on-the-fly-canonicalization and
15702 // the decl-only-class-being-equal-to-a-matching-definition
15703 // flags.
15704 env.priv_->clear_type_comparison_results_cache();
15705 env.priv_->allow_type_comparison_results_caching(false);
15706 env.decl_only_class_equals_definition
15707 (saved_decl_only_class_equals_definition);
15708 return equal;
15709}
15710
15711/// Compare a canonical type against a candidate canonical type.
15712///
15713/// This is ultimately a sub-routine of the
15714/// type_base::get_canonical_type_for().
15715///
15716/// The goal of this function is to ease debugging because it can be
15717/// called from within type_base::get_canonical_type_for() from the
15718/// prompt of the debugger (with some breakpoint appropriately set) to
15719/// debug the comparison that happens during type canonicalization,
15720/// between a candidate type being canonicalized, and an existing
15721/// canonical type that is registered in the system, in as returned by
15722/// environment::get_canonical_types()
15723///
15724/// @param canonical_type the canonical type to consider.
15725///
15726/// @param candidate_type the candidate type that is being
15727/// canonicalized, and thus compared to @p canonical_type.
15728///
15729/// @return true iff @p canonical_type compares equal to @p
15730/// candidate_type.
15731static bool
15732compare_canonical_type_against_candidate(const type_base* canonical_type,
15733 const type_base* candidate_type)
15734{
15735 return compare_canonical_type_against_candidate(*canonical_type,
15736 *candidate_type);
15737}
15738
15739/// Compare a canonical type against a candidate canonical type.
15740///
15741/// This is ultimately a sub-routine of the
15742/// type_base::get_canonical_type_for().
15743///
15744/// The goal of this function is to ease debugging because it can be
15745/// called from within type_base::get_canonical_type_for() from the
15746/// prompt of the debugger (with some breakpoint appropriately set) to
15747/// debug the comparison that happens during type canonicalization,
15748/// between a candidate type being canonicalized, and an existing
15749/// canonical type that is registered in the system, in as returned by
15750/// environment::get_canonical_types()
15751///
15752/// @param canonical_type the canonical type to consider.
15753///
15754/// @param candidate_type the candidate type that is being
15755/// canonicalized, and thus compared to @p canonical_type.
15756///
15757/// @return true iff @p canonical_type compares equal to @p
15758/// candidate_type.
15759static bool
15760compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15761 const type_base_sptr& candidate_type)
15762{
15763 return compare_canonical_type_against_candidate(canonical_type.get(),
15764 candidate_type.get());
15765}
15766
15767/// Test if a candidate for type canonicalization coming from ABIXML
15768/// matches a canonical type by first looking at their hash values.
15769///
15770/// If the two hash values are equal then the candidate is
15771/// structurally compared to the canonical type. If the two hashes
15772/// are different then the two types are considered different and the
15773/// function returns nullptr.
15774///
15775/// If the candidate doesn't come from ABIXML then the function
15776/// returns nullptr.
15777///
15778/// @param cncls the vector of canonical types to consider.
15779///
15780/// @param type the candidate to consider for canonicalization.
15781///
15782/// @return the canonical type from @p cncls that matches the
15783/// candidate @p type.
15784static type_base_sptr
15785candidate_matches_a_canonical_type_hash(const vector<type_base_sptr>& cncls,
15786 type_base& type)
15787{
15788 if (type.get_corpus()
15789 && type.get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
15790 && peek_hash_value(type))
15791 {
15792 // The candidate type comes from ABIXML and does have a stashed
15793 // hash value coming from the ABIXML.
15794
15795 // Let's see if we find a potential canonical type whose hash
15796 // matches the stashed hash and whose canonical type index
15797 // matches it too.
15798 for (const auto& c : cncls)
15799 if (peek_hash_value(type) == peek_hash_value(*c))
15801 // We found a potential canonical type which hash matches the
15802 // stashed hash of the candidate type. Let's compare them to
15803 // see if they match.
15804 if (compare_canonical_type_against_candidate(*c, type))
15805 return c;
15806
15807 // Let's do the same things, but just consideing hash values.
15808 for (const auto& c : cncls)
15809 if (peek_hash_value(type) == peek_hash_value(*c))
15810 // We found a potential canonical type which hash matches the
15811 // stashed hash of the candidate type. Let's compare them to
15812 // see if they match.
15813 if (compare_canonical_type_against_candidate(*c, type))
15814 return c;
15815 }
15816
15817 return nullptr;
15818}
15819
15820/// Test if we should attempt to compute a hash value for a given
15821/// type.
15822///
15823/// For now this function returns true only for types originating from
15824/// ELF. For types originating from ABIXML, for instance, the
15825/// function return false, meaning that types originating from ABIXML
15826/// should NOT be hashed.
15827///
15828/// @param t the type to consider.
15829///
15830/// @return true iff @p type should be considered for hashing.
15831bool
15833{
15834 if (t.get_corpus()
15835 && (t.get_corpus()->get_origin() & corpus::ELF_ORIGIN))
15836 return true;
15837 return false;
15838}
15839
15840/// Compute the canonical type for a given instance of @ref type_base.
15841///
15842/// Consider two types T and T'. The canonical type of T, denoted
15843/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
15844/// otherwise, to compare two types, one just needs to compare their
15845/// canonical types using pointer equality. That makes type
15846/// comparison faster than the structural comparison performed by the
15847/// abigail::ir::equals() overloads.
15848///
15849/// If there is not yet any canonical type for @p t, then @p t is its
15850/// own canonical type. Otherwise, this function returns the
15851/// canonical type of @p t which is the canonical type that has the
15852/// same hash value as @p t and that structurally equals @p t. Note
15853/// that after invoking this function, the life time of the returned
15854/// canonical time is then equals to the life time of the current
15855/// process.
15856///
15857/// @param t a smart pointer to instance of @ref type_base we want to
15858/// compute a canonical type for.
15859///
15860/// @return the canonical type for the current instance of @ref
15861/// type_base.
15862type_base_sptr
15863type_base::get_canonical_type_for(type_base_sptr t)
15864{
15865 if (!t)
15866 return t;
15867
15868 environment& env = const_cast<environment&>(t->get_environment());
15869
15871 // This type should not be canonicalized!
15872 return type_base_sptr();
15873
15874 if (is_decl(t))
15876
15877 // Look through decl-only types (classes, unions and enums)
15878 bool decl_only_class_equals_definition =
15880
15881 class_or_union_sptr class_or_union = is_class_or_union_type(t);
15882
15883 // In the context of types from C++ or languages where we assume the
15884 // "One Definition Rule", we assume that a declaration-only
15885 // non-anonymous class equals all fully defined classes of the same
15886 // name.
15887 //
15888 // Otherwise, all classes, including declaration-only classes are
15889 // canonicalized and only canonical comparison is going to be used
15890 // in the system.
15891 if (decl_only_class_equals_definition)
15892 if (class_or_union)
15894 return type_base_sptr();
15895
15896 class_decl_sptr is_class = is_class_type(t);
15897 if (t->get_canonical_type())
15898 return t->get_canonical_type();
15899
15900 // For classes and union, ensure that an anonymous class doesn't
15901 // have a linkage name. If it does in the future, then me must be
15902 // mindful that the linkage name respects the type identity
15903 // constraints which states that "if two linkage names are different
15904 // then the two types are different".
15908
15909 // We want the pretty representation of the type, but for an
15910 // internal use, not for a user-facing purpose.
15911 //
15912 // If two classe types Foo are declared, one as a class and the
15913 // other as a struct, but are otherwise equivalent, we want their
15914 // pretty representation to be the same. Hence the 'internal'
15915 // argument of ir::get_pretty_representation() is set to true here.
15916 // So in this case, the pretty representation of Foo is going to be
15917 // "class Foo", regardless of its struct-ness. This also applies to
15918 // composite types which would have "class Foo" as a sub-type.
15919 string repr = t->get_cached_pretty_representation(/*internal=*/true);
15920
15921 // If 't' already has a canonical type 'inside' its corpus
15922 // (t_corpus), then this variable is going to contain that canonical
15923 // type.
15924 type_base_sptr canonical_type_present_in_corpus;
15927
15928 type_base_sptr result;
15929 environment::canonical_types_map_type::iterator i = types.find(repr);
15930
15931 if (i == types.end())
15932 {
15933 vector<type_base_sptr> v;
15934 v.push_back(t);
15935 types[repr] = v;
15936 result = t;
15937 }
15938 else
15939 {
15940 vector<type_base_sptr> &v = i->second;
15941 // Look at the canonical types and if the current candidate type
15942 // coming from abixml has the same hash as one of the canonical
15943 // types, then compare the current candidate with the one with a
15944 // matching hash.
15945 result = candidate_matches_a_canonical_type_hash(v, *t);
15946
15947 // Let's compare 't' structurally (i.e, compare its sub-types
15948 // recursively) against the canonical types of the system. If it
15949 // equals a given canonical type C, then it means C is the
15950 // canonical type of 't'. Otherwise, if 't' is different from
15951 // all the canonical types of the system, then it means 't' is a
15952 // canonical type itself.
15953 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15954 !result && it != v.rend();
15955 ++it)
15956 {
15957 bool equal = compare_canonical_type_against_candidate(*it, t);
15958 if (equal)
15959 {
15960 result = *it;
15961 break;
15962 }
15963 }
15964#ifdef WITH_DEBUG_SELF_COMPARISON
15965 if (env.self_comparison_debug_is_on())
15966 {
15967 // So we are debugging the canonicalization process,
15968 // possibly via the use of 'abidw --debug-abidiff <binary>'.
15969 corpus_sptr corp1, corp2;
15970 env.get_self_comparison_debug_inputs(corp1, corp2);
15971 if (corp1 && corp2 && type_originates_from_corpus(t, corp2)
15972 && corp1->get_origin() != corp2->get_origin()
15973 && corp2->get_origin() & corpus::NATIVE_XML_ORIGIN)
15974 {
15975 // If 't' comes from the second corpus, then it *must*
15976 // be equal to its matching canonical type coming from
15977 // the first corpus because the second corpus is the
15978 // abixml representation of the first corpus. In other
15979 // words, all types coming from the second corpus must
15980 // have canonical types coming from the first corpus.
15981 if (result)
15982 {
15983 if (!env.priv_->
15984 check_canonical_type_from_abixml_during_self_comp(t,
15985 result))
15986 {
15987 // The canonical type of the type re-read from abixml
15988 // type doesn't match the canonical type that was
15989 // initially serialized down.
15990 uintptr_t should_have_canonical_type = 0;
15991 string type_id = env.get_type_id_from_type(t.get());
15992 if (type_id.empty())
15993 type_id = "type-id-<not-found>";
15994 else
15995 should_have_canonical_type =
15996 env.get_canonical_type_from_type_id(type_id.c_str());
15997 std::cerr << "error: wrong canonical type for '"
15998 << repr
15999 << "' / type: @"
16000 << std::hex
16001 << t.get()
16002 << "/ canon: @"
16003 << result.get()
16004 << ", type-id: '"
16005 << type_id
16006 << "'. Should have had canonical type: "
16007 << std::hex
16008 << should_have_canonical_type
16009 << std::dec
16010 << std::endl;
16011 }
16012 }
16013 else //!result
16014 {
16015 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
16016 string type_id = env.get_type_id_from_pointer(ptr_val);
16017 if (type_id.empty())
16018 type_id = "type-id-<not-found>";
16019 // We are in the case where 't' is different from all
16020 // the canonical types of the same name that come from
16021 // the first corpus.
16022 //
16023 // If 't' indeed comes from the second corpus then this
16024 // clearly is a canonicalization failure.
16025 //
16026 // There was a problem either during the serialization
16027 // of 't' into abixml, or during the de-serialization
16028 // from abixml into abigail::ir. Further debugging is
16029 // needed to determine what that root cause problem is.
16030 //
16031 // Note that the first canonicalization problem of this
16032 // kind must be fixed before looking at the subsequent
16033 // ones, because the later might well just be
16034 // consequences of the former.
16035 std::cerr << "error: wrong induced canonical type for '"
16036 << repr
16037 << "' from second corpus"
16038 << ", ptr: " << std::hex << t.get()
16039 << " type-id: " << type_id
16040 << " /hash="
16041 << *t->hash_value()
16042 << std::dec
16043 << std::endl;
16044 }
16045 }
16046 if (result)
16047 {
16048 if (!is_type_decl(t))
16049 if (hash_t t_hash = peek_hash_value(*t))
16050 if (hash_t result_hash = peek_hash_value(*result))
16051 if (t_hash != result_hash)
16052 {
16053 std::cerr << "error: type hash mismatch"
16054 << " between type: '"
16055 << repr
16056 << "' @ "
16057 << std::hex
16058 << t.get()
16059 << "/hash="
16060 << *t->hash_value()
16061 << " and its computed canonical type @"
16062 << std::hex
16063 << result.get()
16064 << "/hash="
16065 << std::hex
16066 << *result->hash_value()
16067 << std::dec
16068 << std::endl;
16069 }
16070 }
16071 }
16072#endif //WITH_DEBUG_SELF_COMPARISON
16073
16074 if (!result)
16075 {
16076 v.push_back(t);
16077 result = t;
16078 // we need to generate a canonical type index to sort these
16079 // types that have the same representation and potentially
16080 // same hash value but are canonically different.
16081 t->priv_->canonical_type_index = v.size();
16082 }
16083 }
16084
16085 return result;
16086}
16087
16088/// This method is invoked automatically right after the current
16089/// instance of @ref class_decl has been canonicalized.
16090void
16093
16094/// This is a subroutine of the canonicalize() function.
16095///
16096/// When the canonical type C of type T has just been computed, there
16097/// can be cases where T has member functions that C doesn't have.
16098///
16099/// This is possible because non virtual member functions are not
16100/// taken in account when comparing two types.
16101///
16102/// In that case, this function updates C so that it contains the
16103/// member functions.
16104///
16105/// There can also be cases where C has a method M which is not linked
16106/// to any underlying symbol, whereas in T, M is to link to an
16107/// underlying symbol. In that case, this function updates M in C so
16108/// that it's linked to the same underlying symbol as for M in T.
16109static void
16110maybe_adjust_canonical_type(const type_base_sptr& canonical,
16111 const type_base_sptr& type)
16112{
16113 if (type->get_naked_canonical_type())
16114 return;
16115
16116 class_decl_sptr canonical_class = is_class_type(canonical);
16117
16118 if (class_decl_sptr cl = is_class_type(type))
16119 {
16121 if (canonical_class
16122 && canonical_class.get() != cl.get())
16123 {
16124 // Set symbols of member functions that might be missing
16125 // theirs.
16126 for (class_decl::member_functions::const_iterator i =
16127 cl->get_member_functions().begin();
16128 i != cl->get_member_functions().end();
16129 ++i)
16130 if ((*i)->get_symbol())
16131 {
16132 if (method_decl *m = canonical_class->
16133 find_member_function((*i)->get_linkage_name()))
16134 {
16135 elf_symbol_sptr s1 = (*i)->get_symbol();
16136 if (s1 && !m->get_symbol())
16137 // Method 'm' in the canonical type is not
16138 // linked to the underlying symbol of '*i'.
16139 // Let's link it now. have th
16140 m->set_symbol(s1);
16141 }
16142 else
16143 if (!is_anonymous_type(cl)
16144 && canonical_class->get_corpus()
16145 && cl->get_corpus()
16146 && (cl->get_corpus() == canonical_class->get_corpus()))
16147 // There is a member function defined and publicly
16148 // exported in the other class and the canonical
16149 // class doesn't have that member function. This
16150 // should not have happened! For instance, the
16151 // DWARF reader does merge the member functions of
16152 // classes having the same name so that all of them
16153 // end-up having the same member functions. What's
16154 // going on here?
16156 }
16157
16158 // Set symbols of static data members that might be missing
16159 // theirs.
16160 for (const auto& data_member : cl->get_data_members())
16161 {
16162 if (!get_member_is_static(data_member))
16163 continue;
16164 elf_symbol_sptr sym = data_member->get_symbol();
16165 if (!sym)
16166 continue;
16167 const auto& canonical_data_member =
16168 canonical_class->find_data_member(data_member->get_name());
16169 if (!canonical_data_member)
16170 {
16171 // Two classes my be equivalent (same name, non-static
16172 // sub-objects) and yet not have the same number of
16173 // static data members, if they are coming from
16174 // different corpora. If they are in the same corpus,
16175 // however then that means there is a problem!
16176 if (!is_anonymous_type(cl)
16177 && canonical_class->get_corpus()
16178 && cl->get_corpus()
16179 && canonical_class->get_corpus() == cl->get_corpus())
16181
16182 continue;
16183 }
16184
16185 if (!canonical_data_member->get_symbol())
16186 canonical_data_member->set_symbol(sym);
16187 }
16188 }
16189 }
16190
16191 // Make sure the virtual member functions with exported symbols are
16192 // all added to the set of exported functions of the corpus.
16193
16194 // If we are looking at a non-canonicalized class (for instance, a
16195 // decl-only class that has virtual member functions), let's pretend
16196 // it does have a canonical class so that we can perform the
16197 // necessary virtual member function adjustments
16198 if (class_decl_sptr cl = is_class_type(type))
16200 {
16201 ABG_ASSERT(!canonical_class);
16202 canonical_class = cl;
16203 }
16204
16205 if (canonical_class)
16206 {
16207 if (auto abi_corpus = canonical_class->get_corpus())
16208 {
16209 for (auto& fn : canonical_class->get_member_functions())
16210 {
16211 if (elf_symbol_sptr sym = fn->get_symbol())
16212 {
16213 if (sym->is_defined() && sym->is_public())
16214 {
16215 fn->set_is_in_public_symbol_table(true);
16216 auto b = abi_corpus->get_exported_decls_builder();
16217 b->maybe_add_fn_to_exported_fns(fn.get());
16218 }
16219 else if (!sym->is_defined())
16220 abi_corpus->get_undefined_functions().insert(fn.get());
16221 }
16222 }
16223 }
16224 }
16225
16226 // If an artificial function type equals a non-artfificial one in
16227 // the system, then the canonical type of both should be deemed
16228 // non-artificial. This is important because only non-artificial
16229 // canonical function types are emitted out into abixml, so if don't
16230 // do this we risk missing to emit some function types.
16231 if (is_function_type(type))
16232 if (type->get_is_artificial() != canonical->get_is_artificial())
16233 canonical->set_is_artificial(false);
16234}
16235
16236/// Compute the canonical type of a given type.
16237///
16238/// It means that after invoking this function, comparing the intance
16239/// instance @ref type_base and another one (on which
16240/// type_base::enable_canonical_equality() would have been invoked as
16241/// well) is performed by just comparing the pointer values of the
16242/// canonical types of both types. That equality comparison is
16243/// supposedly faster than structural comparison of the types.
16244///
16245/// @param t a smart pointer to the instance of @ref type_base for
16246/// which to compute the canonical type. After this call,
16247/// t->get_canonical_type() will return the newly computed canonical
16248/// type.
16249///
16250/// @param do_log if true then logs are emitted about canonicalization
16251/// progress.
16252///
16253/// @param show_stats if true and if @p do_log is true as well, then
16254/// more detailed logs are emitted about canonicalization.
16255///
16256/// @return the canonical type computed for @p t.
16257type_base_sptr
16258canonicalize(type_base_sptr t, bool do_log, bool show_stats)
16259{
16260 if (!t)
16261 return t;
16262
16263 if (t->get_canonical_type())
16264 return t->get_canonical_type();
16265
16266 if (do_log && show_stats)
16267 std::cerr << "Canonicalization of type '"
16268 << t->get_pretty_representation(true, true)
16269 << "/@#" << std::hex << t.get() << ": ";
16270
16272
16273 if (do_log && show_stats)
16274 tmr.start();
16275 type_base_sptr canonical = type_base::get_canonical_type_for(t);
16276
16277 if (do_log && show_stats)
16278 tmr.stop();
16279
16280 if (do_log && show_stats)
16281 std::cerr << tmr << "\n";
16282
16283 maybe_adjust_canonical_type(canonical, t);
16284
16285 t->priv_->canonical_type = canonical;
16286 t->priv_->naked_canonical_type = canonical.get();
16287
16288 if (canonical)
16289 if (!t->priv_->canonical_type_index)
16290 t->priv_->canonical_type_index = canonical->priv_->canonical_type_index;
16291
16292 if (class_decl_sptr cl = is_class_type(t))
16293 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
16294 if ((canonical = d->get_canonical_type()))
16295 {
16296 d->priv_->canonical_type = canonical;
16297 d->priv_->naked_canonical_type = canonical.get();
16298 }
16299
16300 if (canonical)
16301 {
16302 if (decl_base_sptr d = is_decl_slow(canonical))
16303 {
16304 scope_decl *scope = d->get_scope();
16305 // Add the canonical type to the set of canonical types
16306 // belonging to its scope.
16307 if (scope)
16308 {
16309 if (is_type(scope))
16310 // The scope in question is itself a type (e.g, a class
16311 // or union). Let's call that type ST. We want to add
16312 // 'canonical' to the set of canonical types belonging
16313 // to ST.
16314 if (type_base_sptr c = is_type(scope)->get_canonical_type())
16315 // We want to add 'canonical' to the set of
16316 // canonical types belonging to the canonical type
16317 // of ST. That way, just looking at the canonical
16318 // type of ST is enough to get the types that belong
16319 // to the scope of the class of equivalence of ST.
16320 scope = is_scope_decl(is_decl(c)).get();
16321 scope->get_canonical_types().insert(canonical);
16322 }
16323 // else, if the type doesn't have a scope, it's not meant to be
16324 // emitted. This can be the case for the result of the
16325 // function strip_typedef, for instance.
16326 }
16327 }
16328
16329 t->on_canonical_type_set();
16330 return canonical;
16331}
16332
16333/// Set the definition of this declaration-only @ref decl_base.
16334///
16335/// @param d the new definition to set.
16336void
16338{
16340 priv_->definition_of_declaration_ = d;
16341 if (type_base *t = is_type(this))
16342 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
16343 t->priv_->canonical_type = canonical_type;
16344
16345 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
16346}
16347
16348/// The constructor of @ref type_base.
16349///
16350/// @param s the size of the type, in bits.
16351///
16352/// @param a the alignment of the type, in bits.
16353type_base::type_base(const environment& e, size_t s, size_t a)
16354 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
16355 priv_(new priv(s, a))
16356{}
16357
16358/// Return the hash value of the current IR node.
16359///
16360/// Note that upon the first invocation, this member functions
16361/// computes the hash value and returns it. Subsequent invocations
16362/// just return the hash value that was previously calculated.
16363///
16364/// @return the hash value of the current IR node.
16365hash_t
16367{
16368 type_base::hash do_hash;
16369 return do_hash(this);
16370}
16371
16372/// Getter of the canonical type of the current instance of @ref
16373/// type_base.
16374///
16375/// @return a smart pointer to the canonical type of the current
16376/// intance of @ref type_base, or an empty smart pointer if the
16377/// current instance of @ref type_base doesn't have any canonical
16378/// type.
16379type_base_sptr
16381{return priv_->canonical_type.lock();}
16382
16383/// Getter of the canonical type pointer.
16384///
16385/// Note that this function doesn't return a smart pointer, but rather
16386/// the underlying pointer managed by the smart pointer. So it's as
16387/// fast as possible. This getter is to be used in code paths that
16388/// are proven to be performance hot spots; especially, when comparing
16389/// sensitive types like class, function, pointers and reference
16390/// types. Those are compared extremely frequently and thus, their
16391/// accessing the canonical type must be fast.
16392///
16393/// @return the canonical type pointer, not managed by a smart
16394/// pointer.
16395type_base*
16397{return priv_->naked_canonical_type;}
16398
16399/// Get the pretty representation of the current type.
16400///
16401/// The pretty representation is retrieved from a cache. If the cache
16402/// is empty, this function computes the pretty representation, put it
16403/// in the cache and returns it.
16404///
16405/// Please note that if this function is called too early in the life
16406/// cycle of the type (before the type is fully constructed), then the
16407/// pretty representation that is cached is going to represent a
16408/// non-complete (and thus wrong) representation of the type. Thus
16409/// this function must be called only once the type is fully
16410/// constructed.
16411///
16412/// @param internal if true, then the pretty representation is to be
16413/// used for purpuses that are internal to the libabigail library
16414/// itself. If you don't know what this means, then you probably
16415/// should set this parameter to "false".
16416///
16417/// @return a reference to a cached @ref interned_string holding the
16418/// pretty representation of the current type.
16419const interned_string&
16421{
16422 if (internal)
16423 {
16424 if (priv_->internal_cached_repr_.empty())
16425 {
16426 string r = ir::get_pretty_representation(this, internal);
16427 priv_->internal_cached_repr_ = get_environment().intern(r);
16428 }
16429 return priv_->internal_cached_repr_;
16430 }
16431
16432 if (priv_->cached_repr_.empty())
16433 {
16434 string r = ir::get_pretty_representation(this, internal);
16435 priv_->cached_repr_ = get_environment().intern(r);
16436 }
16437
16438 return priv_->cached_repr_;
16439}
16440
16441/// Compares two instances of @ref type_base.
16442///
16443/// If the two intances are different, set a bitfield to give some
16444/// insight about the kind of differences there are.
16445///
16446/// @param l the first artifact of the comparison.
16447///
16448/// @param r the second artifact of the comparison.
16449///
16450/// @param k a pointer to a bitfield that gives information about the
16451/// kind of changes there are between @p l and @p r. This one is set
16452/// iff @p is non-null and if the function returns false.
16453///
16454/// Please note that setting k to a non-null value does have a
16455/// negative performance impact because even if @p l and @p r are not
16456/// equal, the function keeps up the comparison in order to determine
16457/// the different kinds of ways in which they are different.
16458///
16459/// @return true if @p l equals @p r, false otherwise.
16460bool
16461equals(const type_base& l, const type_base& r, change_kind* k)
16462{
16463 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
16465 if (!result)
16466 if (k)
16468 ABG_RETURN(result);
16469}
16470
16471/// Return true iff both type declarations are equal.
16472///
16473/// Note that this doesn't test if the scopes of both types are equal.
16474bool
16476{return equals(*this, other, 0);}
16477
16478/// Inequality operator.
16479///
16480///@param other the instance of @ref type_base to compare the current
16481/// instance against.
16482///
16483/// @return true iff the current instance is different from @p other.
16484bool
16486{return !operator==(other);}
16487
16488/// Setter for the size of the type.
16489///
16490/// @param s the new size -- in bits.
16491void
16493{priv_->size_in_bits = s;}
16494
16495/// Getter for the size of the type.
16496///
16497/// @return the size in bits of the type.
16498size_t
16500{return priv_->size_in_bits;}
16501
16502/// Setter for the alignment of the type.
16503///
16504/// @param a the new alignment -- in bits.
16505void
16507{priv_->alignment_in_bits = a;}
16508
16509/// Getter for the alignment of the type.
16510///
16511/// @return the alignment of the type in bits.
16512size_t
16514{return priv_->alignment_in_bits;}
16515
16516/// Default implementation of traversal for types. This function does
16517/// nothing. It must be implemented by every single new type that is
16518/// written.
16519///
16520/// Please look at e.g, class_decl::traverse() for an example of how
16521/// to implement this.
16522///
16523/// @param v the visitor used to visit the type.
16524bool
16526{
16527 if (v.type_node_has_been_visited(this))
16528 return true;
16529
16530 v.visit_begin(this);
16531 bool result = v.visit_end(this);
16533
16534 return result;
16535}
16536
16537type_base::~type_base()
16538{delete priv_;}
16539
16540// </type_base definitions>
16541
16542// <real_type definitions>
16543
16544/// Bitwise OR operator for real_type::modifiers_type.
16545///
16546/// @param l the left-hand side operand.
16547///
16548/// @param r the right-hand side operand.
16549///
16550/// @return the result of the bitwise OR.
16553{
16554 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16555 |
16556 static_cast<unsigned>(r));
16557}
16558
16559/// Bitwise AND operator for real_type::modifiers_type.
16560///
16561/// @param l the left-hand side operand.
16562///
16563/// @param r the right-hand side operand.
16564///
16565/// @return the result of the bitwise AND.
16568{
16569 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16570 &
16571 static_cast<unsigned>(r));
16572}
16573
16574/// Bitwise one's complement operator for real_type::modifiers_type.
16575///
16576/// @param l the left-hand side operand.
16577///
16578/// @param r the right-hand side operand.
16579///
16580/// @return the result of the bitwise one's complement operator.
16583{
16584 return static_cast<real_type::modifiers_type>(~static_cast<unsigned>(l));
16585}
16586
16587/// Bitwise |= operator for real_type::modifiers_type.
16588///
16589/// @param l the left-hand side operand.
16590///
16591/// @param r the right-hand side operand.
16592///
16593/// @return the result of the bitwise |=.
16596{
16597 l = l | r;
16598 return l;
16599}
16600
16601/// Bitwise &= operator for real_type::modifiers_type.
16602///
16603/// @param l the left-hand side operand.
16604///
16605/// @param r the right-hand side operand.
16606///
16607/// @return the result of the bitwise &=.
16610{
16611 l = l & r;
16612 return l;
16613}
16614
16615/// Parse a word containing one real type modifier.
16616///
16617/// A word is considered to be a string of characters that doesn't
16618/// contain any white space.
16619///
16620/// @param word the word to parse. It is considered to be a string of
16621/// characters that doesn't contain any white space.
16622///
16623/// @param modifiers out parameter. It's set by this function to the
16624/// parsed modifier iff the function returned true.
16625///
16626/// @return true iff @word was successfully parsed.
16627static bool
16628parse_real_type_modifier(const string& word,
16629 real_type::modifiers_type &modifiers)
16630{
16631 if (word == "signed")
16632 modifiers |= real_type::SIGNED_MODIFIER;
16633 else if (word == "unsigned")
16634 modifiers |= real_type::UNSIGNED_MODIFIER;
16635 else if (word == "short")
16636 modifiers |= real_type::SHORT_MODIFIER;
16637 else if (word == "long")
16638 modifiers |= real_type::LONG_MODIFIER;
16639 else if (word == "long long")
16640 modifiers |= real_type::LONG_LONG_MODIFIER;
16641 else
16642 return false;
16643
16644 return true;
16645}
16646
16647/// Parse a base type of a real type from a string.
16648///
16649/// @param type_name the type name to parse.
16650///
16651/// @param base out parameter. This is set to the resulting base type
16652/// parsed, iff the function returned true.
16653///
16654/// @return true iff the function could successfully parse the base
16655/// type.
16656static bool
16657parse_base_real_type(const string& type_name,
16659{
16660 if (type_name == "int")
16662 else if (type_name == "char")
16664 else if (type_name == "bool" || type_name == "_Bool")
16666 else if (type_name == "double")
16668 else if (type_name =="float")
16670 else if (type_name == "char16_t")
16672 else if (type_name == "char32_t")
16674 else if (type_name == "wchar_t")
16676 else if (type_name == "__ARRAY_SIZE_TYPE__")
16678 else if (type_name == "sizetype")
16679 base = real_type::SIZE_BASE_TYPE;
16680 else if (type_name == "ssizetype")
16681 base = real_type::SSIZE_BASE_TYPE;
16682 else if (type_name == "bitsizetype")
16683 base = real_type::BIT_SIZE_BASE_TYPE;
16684 else if (type_name == "sbitsizetype")
16685 base = real_type::SBIT_SIZE_BASE_TYPE;
16686 else
16687 return false;
16688
16689 return true;
16690}
16691
16692/// Parse a real type from a string.
16693///
16694/// @param type_name the string containing the real type to parse.
16695///
16696/// @param base out parameter. Is set by this function to the base
16697/// type of the real type, iff the function returned true.
16698///
16699/// @param modifiers out parameter If set by this function to the
16700/// modifier of the real type, iff the function returned true.
16701///
16702/// @return true iff the function could parse a real type from @p
16703/// type_name.
16704static bool
16705parse_real_type(const string& type_name,
16707 real_type::modifiers_type& modifiers)
16708{
16709 string input = type_name;
16710 string::size_type len = input.length();
16711 string::size_type cur_pos = 0, prev_pos = 0;
16712 string cur_word, prev_word;
16713 bool ok = false;
16714
16715 while (cur_pos < len)
16716 {
16717 if (cur_pos < len && isspace(input[cur_pos]))
16718 do
16719 ++cur_pos;
16720 while (cur_pos < len && isspace(input[cur_pos]));
16721
16722 prev_pos = cur_pos;
16723 cur_pos = input.find(' ', prev_pos);
16724 prev_word = cur_word;
16725 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16726
16727 if (cur_pos < len
16728 && cur_word == "long"
16729 && prev_word != "long")
16730 {
16731 if (cur_pos < len && isspace(input[cur_pos]))
16732 do
16733 ++cur_pos;
16734 while (cur_pos < len && isspace(input[cur_pos]));
16735 prev_pos = cur_pos;
16736
16737 cur_pos = input.find(' ', prev_pos);
16738 string saved_prev_word = prev_word;
16739 prev_word = cur_word;
16740 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16741 if (cur_word == "long")
16742 cur_word = "long long";
16743 else
16744 {
16745 cur_pos = prev_pos;
16746 cur_word = prev_word;
16747 prev_word = saved_prev_word;
16748 }
16749 }
16750
16751 if (!parse_real_type_modifier(cur_word, modifiers))
16752 {
16753 if (!parse_base_real_type(cur_word, base))
16754 return false;
16755 else
16756 ok = true;
16757 }
16758 else
16759 ok = true;
16760 }
16761
16762 return ok;
16763}
16764
16765/// Parse a real type from a string.
16766///
16767/// @param str the string containing the real type to parse.
16768///
16769///@param type the resulting @ref real_type. Is set to the result
16770///of the parse, iff the function returns true.
16771///
16772/// @return true iff the function could parse a real type from @p
16773/// str.
16774bool
16775parse_real_type(const string& str, real_type& type)
16776{
16778 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16779
16780 if (!parse_real_type(str, base_type, modifiers))
16781 return false;
16782
16783 // So this is a real type.
16784 real_type int_type(base_type, modifiers);
16785 type = int_type;
16786 return true;
16787}
16788
16789/// Default constructor of the @ref real_type.
16791 : base_(INT_BASE_TYPE),
16792 modifiers_(NO_MODIFIER)
16793{}
16794
16795/// Constructor of the @ref real_type.
16796///
16797/// @param b the base type of the real type.
16798///
16799/// @param m the modifiers of the real type.
16801 : base_(b), modifiers_(m)
16802{}
16803
16804/// Constructor of the @ref real_type.
16805///
16806/// @param the name of the real type to parse to initialize the
16807/// current instance of @ref real_type.
16808real_type::real_type(const string& type_name)
16809 : base_(INT_BASE_TYPE),
16810 modifiers_(NO_MODIFIER)
16811{
16812 bool could_parse = parse_real_type(type_name, base_, modifiers_);
16813 ABG_ASSERT(could_parse);
16814}
16815
16816/// Getter of the base type of the @ref real_type.
16817///
16818/// @return the base type of the @ref real_type.
16821{return base_;}
16822
16823/// Getter of the modifiers bitmap of the @ref real_type.
16824///
16825/// @return the modifiers bitmap of the @ref real_type.
16828{return modifiers_;}
16829
16830/// Setter of the modifiers bitmap of the @ref real_type.
16831///
16832/// @param m the new modifiers.
16833void
16835{modifiers_ = m;}
16836
16837/// Equality operator for the @ref real_type.
16838///
16839/// @param other the other real type to compare against.
16840///
16841/// @return true iff @p other equals the current instance of @ref
16842/// real_type.
16843bool
16845{return base_ == other.base_ && modifiers_ == other.modifiers_;}
16846
16847/// Return the string representation of the current instance of @ref
16848/// real_type.
16849///
16850/// @param internal if true the string representation is to be used
16851/// for internal purposes. In general, it means it's for type
16852/// canonicalization purposes.
16853///
16854/// @return the string representation of the current instance of @ref
16855/// real_type.
16856string
16857real_type::to_string(bool internal) const
16858{
16859 string result;
16860
16861 // Look at modifiers ...
16862 if (modifiers_ & SIGNED_MODIFIER)
16863 result += "signed ";
16864 if (modifiers_ & UNSIGNED_MODIFIER)
16865 result += "unsigned ";
16866 if (!internal)
16867 {
16868 // For canonicalization purposes, we won't emit the "short, long, or
16869 // long long" modifiers. This is because on some platforms, "long
16870 // int" and "long long int" might have the same size. In those
16871 // cases, we want the two types to be equivalent if they have the
16872 // same size. If they don't have the same internal string
16873 // representation, they'd automatically have different canonical
16874 // types and thus be canonically different.
16875 if (modifiers_ & SHORT_MODIFIER)
16876 result += "short ";
16877 if (modifiers_ & LONG_MODIFIER)
16878 result += "long ";
16879 if (modifiers_ & LONG_LONG_MODIFIER)
16880 result += "long long ";
16881 }
16882
16883 // ... and look at base types.
16884 if (base_ == INT_BASE_TYPE)
16885 result += "int";
16886 else if (base_ == CHAR_BASE_TYPE)
16887 result += "char";
16888 else if (base_ == BOOL_BASE_TYPE)
16889 result += "bool";
16890 else if (base_ == DOUBLE_BASE_TYPE)
16891 result += "double";
16892 else if (base_ == FLOAT_BASE_TYPE)
16893 result += "float";
16894 else if (base_ == CHAR16_T_BASE_TYPE)
16895 result += "char16_t";
16896 else if (base_ == CHAR32_T_BASE_TYPE)
16897 result += "char32_t";
16898 else if (base_ == WCHAR_T_BASE_TYPE)
16899 result += "wchar_t";
16900 else if (base_ == ARRAY_SIZE_BASE_TYPE)
16901 result += "__ARRAY_SIZE_TYPE__";
16902 else if (base_ == SIZE_BASE_TYPE)
16903 result += "sizetype";
16904 else if (base_ == SSIZE_BASE_TYPE)
16905 result += "ssizetype";
16906 else if (base_ == BIT_SIZE_BASE_TYPE)
16907 result += "bitsizetype";
16908 else if (base_ == SBIT_SIZE_BASE_TYPE)
16909 result += "sbitsizetype";
16910 return result;
16911}
16912
16913/// Convert the current instance of @ref real_type into its string
16914/// representation.
16915///
16916/// @return the string representation of the current instance of @ref
16917/// real_type.
16918real_type::operator string() const
16919{return to_string();}
16920
16921// </real_type definitions>
16922
16923//<type_decl definitions>
16924
16925/// Constructor.
16926///
16927/// @param env the environment we are operating from.
16928///
16929/// @param name the name of the type declaration.
16930///
16931/// @param size_in_bits the size of the current type_decl, in bits.
16932///
16933/// @param alignment_in_bits the alignment of the current typ, in
16934/// bits.
16935///
16936/// @param locus the source location of the current type declaration.
16937///
16938/// @param linkage_name the linkage_name of the current type declaration.
16939///
16940/// @param vis the visibility of the type declaration.
16941type_decl::type_decl(const environment& env,
16942 const string& name,
16943 size_t size_in_bits,
16944 size_t alignment_in_bits,
16945 const location& locus,
16946 const string& linkage_name,
16947 visibility vis)
16948
16949 : type_or_decl_base(env,
16950 BASIC_TYPE
16951 | ABSTRACT_TYPE_BASE
16952 | ABSTRACT_DECL_BASE),
16953 decl_base(env, name, locus, linkage_name, vis),
16954 type_base(env, size_in_bits, alignment_in_bits)
16955{
16957
16959 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16960 real_type int_type(base_type, modifiers);
16961 if (parse_real_type(name, int_type))
16962 {
16963 // Convert the real_type into its canonical string
16964 // representation.
16965 string real_type_name = int_type;
16966
16967 // Set the name of this type_decl to the canonical string
16968 // representation above
16969 set_name(real_type_name);
16971
16972 if (!get_linkage_name().empty())
16973 set_linkage_name(real_type_name);
16974 }
16975}
16976
16977/// Return the hash value of the current IR node.
16978///
16979/// Note that upon the first invocation, this member functions
16980/// computes the hash value and returns it. Subsequent invocations
16981/// just return the hash value that was previously calculated.
16982///
16983/// @return the hash value of the current IR node.
16984hash_t
16986{
16988 return h;
16989}
16990
16991/// Compares two instances of @ref type_decl.
16992///
16993/// If the two intances are different, set a bitfield to give some
16994/// insight about the kind of differences there are.
16995///
16996/// @param l the first artifact of the comparison.
16997///
16998/// @param r the second artifact of the comparison.
16999///
17000/// @param k a pointer to a bitfield that gives information about the
17001/// kind of changes there are between @p l and @p r. This one is set
17002/// iff @p k is non-null and the function returns false.
17003///
17004/// Please note that setting k to a non-null value does have a
17005/// negative performance impact because even if @p l and @p r are not
17006/// equal, the function keeps up the comparison in order to determine
17007/// the different kinds of ways in which they are different.
17008///
17009/// @return true if @p l equals @p r, false otherwise.
17010bool
17011equals(const type_decl& l, const type_decl& r, change_kind* k)
17012{
17013 bool result = false;
17014
17015 // Consider the types as decls to compare their decls-related
17016 // properties.
17017 result = equals(static_cast<const decl_base&>(l),
17018 static_cast<const decl_base&>(r),
17019 k);
17020 if (!k && !result)
17022
17023 // Now consider the types a "types' to compare their size-related
17024 // properties.
17025 result &= equals(static_cast<const type_base&>(l),
17026 static_cast<const type_base&>(r),
17027 k);
17028 ABG_RETURN(result);
17029}
17030
17031/// Return true if both types equals.
17032///
17033/// This operator re-uses the overload that takes a decl_base.
17034///
17035/// Note that this does not check the scopes of any of the types.
17036///
17037/// @param o the other type_decl to check agains.
17038bool
17040{
17041 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17042 if (!other)
17043 return false;
17044 return *this == *other;
17045}
17046
17047/// Return true if both types equals.
17048///
17049/// Note that this does not check the scopes of any of the types.
17050///
17051/// @param o the other type_decl to check against.
17052bool
17054{
17055 const type_decl* other = dynamic_cast<const type_decl*>(&o);
17056 if (!other)
17057 return false;
17058 return try_canonical_compare(this, other);
17059}
17060
17061/// Return true if both types equals.
17062///
17063/// Note that this does not check the scopes of any of the types.
17064///
17065/// @param o the other type_decl to check against.
17066///
17067/// @return true iff the current isntance equals @p o
17068bool
17070{
17071 const decl_base& other = o;
17072 return *this == other;
17073}
17074
17075/// Return true if both types equals.
17076///
17077/// Note that this does not check the scopes of any of the types.
17078///
17079/// @param o the other type_decl to check against.
17080///
17081/// @return true iff the current isntance equals @p o
17082bool
17084{return !operator==(o);}
17085
17086/// Return true if both types equals.
17087///
17088/// Note that this does not check the scopes of any of the types.
17089///
17090/// @param o the other type_decl to check against.
17091///
17092/// @return true iff the current isntance equals @p o
17093bool
17095{return !operator==(o);}
17096
17097/// Inequality operator.
17098///
17099/// @param o the other type to compare against.
17100///
17101/// @return true iff the current instance is different from @p o.
17102bool
17104{return !operator==(o);}
17105
17106/// Equality operator for @ref type_decl_sptr.
17107///
17108/// @param l the first operand to compare.
17109///
17110/// @param r the second operand to compare.
17111///
17112/// @return true iff @p l equals @p r.
17113bool
17115{
17116 if (!!l != !!r)
17117 return false;
17118 if (l.get() == r.get())
17119 return true;
17120 return *l == *r;
17121}
17122
17123/// Inequality operator for @ref type_decl_sptr.
17124///
17125/// @param l the first operand to compare.
17126///
17127/// @param r the second operand to compare.
17128///
17129/// @return true iff @p l is different from @p r.
17130bool
17132{return !operator==(l, r);}
17133
17134/// Implementation for the virtual qualified name builder for @ref
17135/// type_decl.
17136///
17137/// @param qualified_name the output parameter to hold the resulting
17138/// qualified name.
17139///
17140/// @param internal set to true if the call is intended for an
17141/// internal use (for technical use inside the library itself), false
17142/// otherwise. If you don't know what this is for, then set it to
17143/// false.
17144void
17146 bool internal) const
17147{qualified_name = get_qualified_name(internal);}
17148
17149/// Implementation for the virtual qualified name builder for @ref
17150/// type_decl.
17151///
17152/// @param qualified_name the output parameter to hold the resulting
17153/// qualified name.
17154///
17155/// @param internal set to true if the call is intended for an
17156/// internal use (for technical use inside the library itself), false
17157/// otherwise. If you don't know what this is for, then set it to
17158/// false.
17159const interned_string&
17161{
17162 const environment& env = get_environment();
17163
17164
17165 if (internal)
17166 if (is_real_type(this))
17167 {
17169 {
17170 if (decl_base::priv_->internal_qualified_name_.empty())
17171 decl_base::priv_->internal_qualified_name_ =
17172 env.intern(get_internal_real_type_name(this));
17173 return decl_base::priv_->internal_qualified_name_;
17174 }
17175 else
17176 {
17177 decl_base::priv_->temporary_internal_qualified_name_ =
17178 env.intern(get_internal_real_type_name(this));
17179 return decl_base::priv_->temporary_internal_qualified_name_;
17180 }
17181 }
17182
17183 return decl_base::get_qualified_name(/*internal=*/false);
17184}
17185
17186/// Get the pretty representation of the current instance of @ref
17187/// type_decl.
17188///
17189/// @param internal set to true if the call is intended to get a
17190/// representation of the decl (or type) for the purpose of canonical
17191/// type comparison. This is mainly used in the function
17192/// type_base::get_canonical_type_for().
17193///
17194/// In other words if the argument for this parameter is true then the
17195/// call is meant for internal use (for technical use inside the
17196/// library itself), false otherwise. If you don't know what this is
17197/// for, then set it to false.
17198///
17199/// @param qualified_name if true, names emitted in the pretty
17200/// representation are fully qualified.
17201///
17202/// @return the pretty representatin of the @ref type_decl.
17203string
17205 bool qualified_name) const
17206{
17207 if (internal)
17208 if (is_real_type(this))
17209 return get_internal_real_type_name(this);
17210
17211 if (qualified_name)
17212 return get_qualified_name(internal);
17213 return get_name();
17214}
17215
17216/// This implements the ir_traversable_base::traverse pure virtual
17217/// function.
17218///
17219/// @param v the visitor used on the current instance.
17220///
17221/// @return true if the entire IR node tree got traversed, false
17222/// otherwise.
17223bool
17225{
17226 if (v.type_node_has_been_visited(this))
17227 return true;
17228
17229 v.visit_begin(this);
17230 bool result = v.visit_end(this);
17232
17233 return result;
17234}
17235
17236type_decl::~type_decl()
17237{}
17238//</type_decl definitions>
17239
17240// <scope_type_decl definitions>
17241
17242/// Constructor.
17243///
17244/// @param env the environment we are operating from.
17245///
17246/// @param name the name of the type.
17247///
17248/// @param size_in_bits the size of the type, in bits.
17249///
17250/// @param alignment_in_bits the alignment of the type, in bits.
17251///
17252/// @param locus the source location where the type is defined.
17253///
17254/// @param vis the visibility of the type.
17255scope_type_decl::scope_type_decl(const environment& env,
17256 const string& name,
17257 size_t size_in_bits,
17258 size_t alignment_in_bits,
17259 const location& locus,
17260 visibility vis)
17261 : type_or_decl_base(env,
17262 ABSTRACT_SCOPE_TYPE_DECL
17263 | ABSTRACT_TYPE_BASE
17264 | ABSTRACT_DECL_BASE),
17265 decl_base(env, name, locus, "", vis),
17266 type_base(env, size_in_bits, alignment_in_bits),
17267 scope_decl(env, name, locus)
17268{}
17269
17270/// Compares two instances of @ref scope_type_decl.
17271///
17272/// If the two intances are different, set a bitfield to give some
17273/// insight about the kind of differences there are.
17274///
17275/// @param l the first artifact of the comparison.
17276///
17277/// @param r the second artifact of the comparison.
17278///
17279/// @param k a pointer to a bitfield that gives information about the
17280/// kind of changes there are between @p l and @p r. This one is set
17281/// iff @p k is non-null and the function returns false.
17282///
17283/// Please note that setting k to a non-null value does have a
17284/// negative performance impact because even if @p l and @p r are not
17285/// equal, the function keeps up the comparison in order to determine
17286/// the different kinds of ways in which they are different.
17287///
17288/// @return true if @p l equals @p r, false otherwise.
17289bool
17291{
17292 bool result = equals(static_cast<const scope_decl&>(l),
17293 static_cast<const scope_decl&>(r),
17294 k);
17295
17296 if (!k && !result)
17298
17299 result &= equals(static_cast<const type_base&>(l),
17300 static_cast<const type_base&>(r),
17301 k);
17302
17303 ABG_RETURN(result);
17304}
17305
17306/// Equality operator between two scope_type_decl.
17307///
17308/// Note that this function does not consider the scope of the scope
17309/// types themselves.
17310///
17311/// @return true iff both scope types are equal.
17312bool
17314{
17315 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
17316 if (!other)
17317 return false;
17318 return try_canonical_compare(this, other);
17319}
17320
17321/// Equality operator between two scope_type_decl.
17322///
17323/// This re-uses the equality operator that takes a decl_base.
17324///
17325/// @param o the other scope_type_decl to compare against.
17326///
17327/// @return true iff both scope types are equal.
17328bool
17330{
17331 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17332 if (!other)
17333 return false;
17334
17335 return *this == *other;
17336}
17337
17338/// Traverses an instance of @ref scope_type_decl, visiting all the
17339/// sub-types and decls that it might contain.
17340///
17341/// @param v the visitor that is used to visit every IR sub-node of
17342/// the current node.
17343///
17344/// @return true if either
17345/// - all the children nodes of the current IR node were traversed
17346/// and the calling code should keep going with the traversing.
17347/// - or the current IR node is already being traversed.
17348/// Otherwise, returning false means that the calling code should not
17349/// keep traversing the tree.
17350bool
17352{
17353 if (visiting())
17354 return true;
17355
17356 if (v.type_node_has_been_visited(this))
17357 return true;
17358
17359 if (v.visit_begin(this))
17360 {
17361 visiting(true);
17362 for (scope_decl::declarations::const_iterator i =
17363 get_member_decls().begin();
17364 i != get_member_decls ().end();
17365 ++i)
17366 if (!(*i)->traverse(v))
17367 break;
17368 visiting(false);
17369 }
17370
17371 bool result = v.visit_end(this);
17373
17374 return result;
17375}
17376
17377scope_type_decl::~scope_type_decl()
17378{}
17379// </scope_type_decl definitions>
17380
17381// <namespace_decl>
17382
17383/// Constructor.
17384///
17385/// @param the environment we are operatin from.
17386///
17387/// @param name the name of the namespace.
17388///
17389/// @param locus the source location where the namespace is defined.
17390///
17391/// @param vis the visibility of the namespace.
17393 const string& name,
17394 const location& locus,
17395 visibility vis)
17396 // We need to call the constructor of decl_base directly here
17397 // because it is virtually inherited by scope_decl. Note that we
17398 // just implicitely call the default constructor for scope_decl
17399 // here, as what we really want is to initialize the decl_base
17400 // subobject. Wow, virtual inheritance is useful, but setting it
17401 // up is ugly.
17402 : type_or_decl_base(env,
17403 NAMESPACE_DECL
17404 | ABSTRACT_DECL_BASE
17405 | ABSTRACT_SCOPE_DECL),
17406 decl_base(env, name, locus, "", vis),
17407 scope_decl(env, name, locus)
17408{
17410}
17411
17412/// Build and return a copy of the pretty representation of the
17413/// namespace.
17414///
17415/// @param internal set to true if the call is intended to get a
17416/// representation of the decl (or type) for the purpose of canonical
17417/// type comparison. This is mainly used in the function
17418/// type_base::get_canonical_type_for().
17419///
17420/// In other words if the argument for this parameter is true then the
17421/// call is meant for internal use (for technical use inside the
17422/// library itself), false otherwise. If you don't know what this is
17423/// for, then set it to false.
17424///
17425/// @param qualified_name if true, names emitted in the pretty
17426/// representation are fully qualified.
17427///
17428/// @return a copy of the pretty representation of the namespace.
17429string
17431 bool qualified_name) const
17432{
17433 string r =
17434 "namespace " + scope_decl::get_pretty_representation(internal,
17435 qualified_name);
17436 return r;
17437}
17438
17439/// Return true iff both namespaces and their members are equal.
17440///
17441/// Note that this function does not check if the scope of these
17442/// namespaces are equal.
17443bool
17445{
17446 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
17447 if (!other)
17448 return false;
17449 return scope_decl::operator==(*other);
17450}
17451
17452/// Test if the current namespace_decl is empty or contains empty
17453/// namespaces itself.
17454///
17455/// @return true iff the current namespace_decl is empty or contains
17456/// empty itself.
17457bool
17459{
17460 if (is_empty())
17461 return true;
17462
17463 for (declarations::const_iterator i = get_member_decls().begin();
17464 i != get_member_decls().end();
17465 ++i)
17466 {
17467 if (!is_namespace(*i))
17468 return false;
17469
17471 ABG_ASSERT(ns);
17472
17473 if (!ns->is_empty_or_has_empty_sub_namespaces())
17474 return false;
17475 }
17476
17477 return true;
17478}
17479
17480/// This implements the ir_traversable_base::traverse pure virtual
17481/// function.
17482///
17483/// @param v the visitor used on the current instance and on its
17484/// member nodes.
17485///
17486/// @return true if the entire IR node tree got traversed, false
17487/// otherwise.
17488bool
17490{
17491 if (visiting())
17492 return true;
17493
17494 if (v.visit_begin(this))
17495 {
17496 visiting(true);
17497 scope_decl::declarations::const_iterator i;
17498 for (i = get_member_decls().begin();
17499 i != get_member_decls ().end();
17500 ++i)
17501 {
17503 dynamic_pointer_cast<ir_traversable_base>(*i);
17504 if (t)
17505 if (!t->traverse (v))
17506 break;
17507 }
17508 visiting(false);
17509 }
17510 return v.visit_end(this);
17511}
17512
17513namespace_decl::~namespace_decl()
17514{
17515}
17516
17517// </namespace_decl>
17518
17519// <qualified_type_def>
17520
17521/// Type of the private data of qualified_type_def.
17522class qualified_type_def::priv
17523{
17524 friend class qualified_type_def;
17525
17526 qualified_type_def::CV cv_quals_;
17527 // Before the type is canonicalized, this is used as a temporary
17528 // internal name.
17529 interned_string temporary_internal_name_;
17530 // Once the type is canonicalized, this is used as the internal
17531 // name.
17532 interned_string internal_name_;
17533 weak_ptr<type_base> underlying_type_;
17534
17535 priv()
17536 : cv_quals_(CV_NONE)
17537 {}
17538
17539 priv(qualified_type_def::CV quals,
17540 type_base_sptr t)
17541 : cv_quals_(quals),
17542 underlying_type_(t)
17543 {}
17544
17545 priv(qualified_type_def::CV quals)
17546 : cv_quals_(quals)
17547 {}
17548};// end class qualified_type_def::priv
17549
17550/// Build the name of the current instance of qualified type.
17551///
17552/// @param fully_qualified if true, build a fully qualified name.
17553///
17554/// @param internal set to true if the call is intended for an
17555/// internal use (for technical use inside the library itself), false
17556/// otherwise. If you don't know what this is for, then set it to
17557/// false.
17558///
17559/// @return a copy of the newly-built name.
17560string
17561qualified_type_def::build_name(bool fully_qualified, bool internal) const
17562{
17563 type_base_sptr t = get_underlying_type();
17564 if (!t)
17565 // The qualified type might temporarily have no underlying type,
17566 // especially during the construction of the type, while the
17567 // underlying type is not yet constructed. In that case, let's do
17568 // like if the underlying type is the 'void' type.
17570
17572 fully_qualified,
17573 internal);
17574}
17575
17576/// This function is automatically invoked whenever an instance of
17577/// this type is canonicalized.
17578///
17579/// It's an overload of the virtual type_base::on_canonical_type_set.
17580///
17581/// We put here what is thus meant to be executed only at the point of
17582/// type canonicalization.
17583void
17586
17587/// Constructor of the qualified_type_def
17588///
17589/// @param type the underlying type
17590///
17591/// @param quals a bitfield representing the const/volatile qualifiers
17592///
17593/// @param locus the location of the qualified type definition
17594qualified_type_def::qualified_type_def(type_base_sptr type,
17595 CV quals,
17596 const location& locus)
17597 : type_or_decl_base(type->get_environment(),
17598 QUALIFIED_TYPE
17599 | ABSTRACT_TYPE_BASE
17600 | ABSTRACT_DECL_BASE),
17601 type_base(type->get_environment(), type->get_size_in_bits(),
17602 type->get_alignment_in_bits()),
17603 decl_base(type->get_environment(), "", locus, "",
17604 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
17605 priv_(new priv(quals, type))
17606{
17608 interned_string name = type->get_environment().intern(build_name(false));
17609 set_name(name);
17610}
17611
17612/// Constructor of the qualified_type_def
17613///
17614/// @param env the environment of the type.
17615///
17616/// @param quals a bitfield representing the const/volatile qualifiers
17617///
17618/// @param locus the location of the qualified type definition
17619qualified_type_def::qualified_type_def(const environment& env,
17620 CV quals,
17621 const location& locus)
17622 : type_or_decl_base(env,
17623 QUALIFIED_TYPE
17624 | ABSTRACT_TYPE_BASE
17625 | ABSTRACT_DECL_BASE),
17626 type_base(env, /*size_in_bits=*/0,
17627 /*alignment_in_bits=*/0),
17628 decl_base(env, "", locus, ""),
17629 priv_(new priv(quals))
17630{
17632 // We don't yet have an underlying type. So for naming purpose,
17633 // let's temporarily pretend the underlying type is 'void'.
17634 interned_string name = env.intern("void");
17635 set_name(name);
17636}
17637
17638/// Return the hash value of the current IR node.
17639///
17640/// Note that upon the first invocation, this member functions
17641/// computes the hash value and returns it. Subsequent invocations
17642/// just return the hash value that was previously calculated.
17643///
17644/// @return the hash value of the current IR node.
17645hash_t
17647{
17649 return h;
17650}
17651
17652/// Get the size of the qualified type def.
17653///
17654/// This is an overload for type_base::get_size_in_bits().
17655///
17656/// @return the size of the qualified type.
17657size_t
17659{
17660 size_t s = 0;
17661 if (type_base_sptr ut = get_underlying_type())
17662 {
17663 // We do have the underlying type properly set, so let's make
17664 // the size of the qualified type match the size of its
17665 // underlying type.
17666 s = ut->get_size_in_bits();
17667 if (s != type_base::get_size_in_bits())
17668 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
17669 }
17671}
17672
17673/// Compares two instances of @ref qualified_type_def.
17674///
17675/// If the two intances are different, set a bitfield to give some
17676/// insight about the kind of differences there are.
17677///
17678/// @param l the first artifact of the comparison.
17679///
17680/// @param r the second artifact of the comparison.
17681///
17682/// @param k a pointer to a bitfield that gives information about the
17683/// kind of changes there are between @p l and @p r. This one is set
17684/// iff @p k is non-null and the function returns false.
17685///
17686/// Please note that setting k to a non-null value does have a
17687/// negative performance impact because even if @p l and @p r are not
17688/// equal, the function keeps up the comparison in order to determine
17689/// the different kinds of ways in which they are different.
17690///
17691/// @return true if @p l equals @p r, false otherwise.
17692bool
17694{
17695 bool result = true;
17696 if (l.get_cv_quals() != r.get_cv_quals())
17697 {
17698 result = false;
17699 if (k)
17701 else
17703 }
17704
17706 {
17707 result = false;
17708 if (k)
17709 {
17711 r.get_underlying_type().get()))
17712 // Underlying type changes in which the structure of the
17713 // type changed are considered local changes to the
17714 // qualified type.
17716 else
17717 *k |= SUBTYPE_CHANGE_KIND;
17718 }
17719 else
17720 // okay strictly speaking this is not necessary, but I am
17721 // putting it here to maintenance; that is, so that adding
17722 // subsequent clauses needed to compare two qualified types
17723 // later still works.
17725 }
17726
17727 ABG_RETURN(result);
17728}
17729
17730/// Equality operator for qualified types.
17731///
17732/// Note that this function does not check for equality of the scopes.
17733///
17734///@param o the other qualified type to compare against.
17735///
17736/// @return true iff both qualified types are equal.
17737bool
17739{
17740 const qualified_type_def* other =
17741 dynamic_cast<const qualified_type_def*>(&o);
17742 if (!other)
17743 return false;
17744 return try_canonical_compare(this, other);
17745}
17746
17747/// Equality operator for qualified types.
17748///
17749/// Note that this function does not check for equality of the scopes.
17750/// Also, this re-uses the equality operator above that takes a
17751/// decl_base.
17752///
17753///@param o the other qualified type to compare against.
17754///
17755/// @return true iff both qualified types are equal.
17756bool
17758{
17759 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17760 if (!other)
17761 return false;
17762 return *this == *other;
17763}
17764
17765/// Equality operator for qualified types.
17766///
17767/// Note that this function does not check for equality of the scopes.
17768/// Also, this re-uses the equality operator above that takes a
17769/// decl_base.
17770///
17771///@param o the other qualified type to compare against.
17772///
17773/// @return true iff both qualified types are equal.
17774bool
17776{
17777 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17778 if (!other)
17779 return false;
17780 return *this == *other;
17781}
17782
17783/// Implementation for the virtual qualified name builder for @ref
17784/// qualified_type_def.
17785///
17786/// @param qualified_name the output parameter to hold the resulting
17787/// qualified name.
17788///
17789/// @param internal set to true if the call is intended for an
17790/// internal use (for technical use inside the library itself), false
17791/// otherwise. If you don't know what this is for, then set it to
17792/// false.
17793void
17795 bool internal) const
17796{qualified_name = get_qualified_name(internal);}
17797
17798/// Implementation of the virtual qualified name builder/getter.
17799///
17800/// @param internal set to true if the call is intended for an
17801/// internal use (for technical use inside the library itself), false
17802/// otherwise. If you don't know what this is for, then set it to
17803/// false.
17804///
17805/// @return the resulting qualified name.
17806const interned_string&
17808{
17809 const environment& env = get_environment();
17810
17811
17812 if (!get_canonical_type())
17813 {
17814 // The type hasn't been canonicalized yet. We want to return a
17815 // temporary name that is not cached because the structure of
17816 // this type (and so its name) can change until its
17817 // canonicalized.
17818 if (internal)
17819 {
17820 // We are asked to return a temporary *internal* name.
17821 // Lets compute it and return a reference to where it's
17822 // stored.
17823 if (priv_->temporary_internal_name_.empty())
17824 priv_->temporary_internal_name_ =
17825 env.intern(build_name(true, /*internal=*/true));
17826 return priv_->temporary_internal_name_;
17827 }
17828 else
17829 {
17830 // We are asked to return a temporary non-internal name.
17832 (env.intern(build_name(true, /*internal=*/false)));
17834 }
17835 }
17836 else
17837 {
17838 // The type has already been canonicalized. We want to return
17839 // the definitive name and cache it.
17840 if (internal)
17841 {
17842 if (priv_->internal_name_.empty())
17843 priv_->internal_name_ =
17844 env.intern(build_name(/*qualified=*/true,
17845 /*internal=*/true));
17846 return priv_->internal_name_;
17847 }
17848 else
17849 {
17850 if (peek_qualified_name().empty())
17852 (env.intern(build_name(/*qualified=*/true,
17853 /*internal=*/false)));
17854 return peek_qualified_name();
17855 }
17856 }
17857}
17858
17859/// This implements the ir_traversable_base::traverse pure virtual
17860/// function.
17861///
17862/// @param v the visitor used on the current instance.
17863///
17864/// @return true if the entire IR node tree got traversed, false
17865/// otherwise.
17866bool
17868{
17869 if (v.type_node_has_been_visited(this))
17870 return true;
17871
17872 if (visiting())
17873 return true;
17874
17875 if (v.visit_begin(this))
17876 {
17877 visiting(true);
17878 if (type_base_sptr t = get_underlying_type())
17879 t->traverse(v);
17880 visiting(false);
17881 }
17882 bool result = v.visit_end(this);
17884 return result;
17885}
17886
17887qualified_type_def::~qualified_type_def()
17888{
17889}
17890
17891/// Getter of the const/volatile qualifier bit field
17894{return priv_->cv_quals_;}
17895
17896/// Setter of the const/value qualifiers bit field
17897void
17899{priv_->cv_quals_ = cv_quals;}
17900
17901/// Compute and return the string prefix or suffix representing the
17902/// qualifiers hold by the current instance of @ref
17903/// qualified_type_def.
17904///
17905/// @return the newly-built cv string.
17906string
17909
17910/// Getter of the underlying type
17911type_base_sptr
17913{return priv_->underlying_type_.lock();}
17914
17915/// Setter of the underlying type.
17916///
17917/// @param t the new underlying type.
17918void
17920{
17921 ABG_ASSERT(t);
17922 priv_->underlying_type_ = t;
17923 // Now we need to update other properties that depend on the new underlying type.
17924 set_size_in_bits(t->get_size_in_bits());
17925 set_alignment_in_bits(t->get_alignment_in_bits());
17927 set_name(name);
17928 if (scope_decl* s = get_scope())
17929 {
17930 // Now that the name has been updated, we need to update the
17931 // lookup maps accordingly.
17932 scope_decl::declarations::iterator i;
17933 if (s->find_iterator_for_member(this, i))
17935 else
17937 }
17938}
17939
17940/// Non-member equality operator for @ref qualified_type_def
17941///
17942/// @param l the left-hand side of the equality operator
17943///
17944/// @param r the right-hand side of the equality operator
17945///
17946/// @return true iff @p l and @p r equals.
17947bool
17948operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17949{
17950 if (l.get() == r.get())
17951 return true;
17952 if (!!l != !!r)
17953 return false;
17954
17955 return *l == *r;
17956}
17957
17958/// Non-member inequality operator for @ref qualified_type_def
17959///
17960/// @param l the left-hand side of the equality operator
17961///
17962/// @param r the right-hand side of the equality operator
17963///
17964/// @return true iff @p l and @p r equals.
17965bool
17966operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17967{return ! operator==(l, r);}
17968
17969/// Overloaded bitwise OR operator for cv qualifiers.
17972{
17973 return static_cast<qualified_type_def::CV>
17974 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
17975}
17976
17977/// Overloaded bitwise |= operator for cv qualifiers.
17980{
17981 l = l | r;
17982 return l;
17983}
17984
17985/// Overloaded bitwise &= operator for cv qualifiers.
17988{
17989 l = l & r;
17990 return l;
17991}
17992
17993/// Overloaded bitwise AND operator for CV qualifiers.
17996{
17997 return static_cast<qualified_type_def::CV>
17998 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
17999}
18000
18001/// Overloaded bitwise inverting operator for CV qualifiers.
18004{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
18005
18006/// Streaming operator for qualified_type_decl::CV
18007///
18008/// @param o the output stream to serialize the cv qualifier to.
18009///
18010/// @param cv the cv qualifier to serialize.
18011///
18012/// @return the output stream used.
18013std::ostream&
18014operator<<(std::ostream& o, qualified_type_def::CV cv)
18015{
18016 string str;
18017
18018 switch (cv)
18019 {
18020 case qualified_type_def::CV_NONE:
18021 str = "none";
18022 break;
18023 case qualified_type_def::CV_CONST:
18024 str = "const";
18025 break;
18026 case qualified_type_def::CV_VOLATILE:
18027 str = "volatile";
18028 break;
18029 case qualified_type_def::CV_RESTRICT:
18030 str = "restrict";
18031 break;
18032 }
18033
18034 o << str;
18035 return o;
18036}
18037
18038// </qualified_type_def>
18039
18040//<pointer_type_def definitions>
18041
18042/// Private data structure of the @ref pointer_type_def.
18043struct pointer_type_def::priv
18044{
18045 type_base_wptr pointed_to_type_;
18046 type_base* naked_pointed_to_type_;
18047 interned_string internal_qualified_name_;
18048 interned_string temp_internal_qualified_name_;
18049
18050 priv(const type_base_sptr& t)
18051 : pointed_to_type_(type_or_void(t, t->get_environment())),
18052 naked_pointed_to_type_(t.get())
18053 {}
18054
18055 priv()
18056 : naked_pointed_to_type_()
18057 {}
18058}; //end struct pointer_type_def
18059
18060/// This function is automatically invoked whenever an instance of
18061/// this type is canonicalized.
18062///
18063/// It's an overload of the virtual type_base::on_canonical_type_set.
18064///
18065/// We put here what is thus meant to be executed only at the point of
18066/// type canonicalization.
18067void
18070
18071
18072///Constructor of @ref pointer_type_def.
18073///
18074/// @param pointed_to the pointed-to type.
18075///
18076/// @param size_in_bits the size of the type, in bits.
18077///
18078/// @param align_in_bits the alignment of the type, in bits.
18079///
18080/// @param locus the source location where the type was defined.
18081pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
18082 size_t size_in_bits,
18083 size_t align_in_bits,
18084 const location& locus)
18085 : type_or_decl_base(pointed_to->get_environment(),
18086 POINTER_TYPE
18087 | ABSTRACT_TYPE_BASE
18088 | ABSTRACT_DECL_BASE),
18089 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18090 decl_base(pointed_to->get_environment(), "", locus, ""),
18091 priv_(new priv(pointed_to))
18092{
18094 try
18095 {
18096 ABG_ASSERT(pointed_to);
18097 const environment& env = pointed_to->get_environment();
18098 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18099 string name = (pto ? pto->get_name() : string("void")) + "*";
18100 set_name(env.intern(name));
18101 if (pto)
18102 set_visibility(pto->get_visibility());
18103 }
18104 catch (...)
18105 {}
18106}
18107
18108///Constructor of @ref pointer_type_def.
18109///
18110/// @param env the environment of the type.
18111///
18112/// @param size_in_bits the size of the type, in bits.
18113///
18114/// @param align_in_bits the alignment of the type, in bits.
18115///
18116/// @param locus the source location where the type was defined.
18117pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
18118 size_t alignment_in_bits,
18119 const location& locus)
18120 : type_or_decl_base(env,
18121 POINTER_TYPE
18122 | ABSTRACT_TYPE_BASE
18123 | ABSTRACT_DECL_BASE),
18124 type_base(env, size_in_bits, alignment_in_bits),
18125 decl_base(env, "", locus, ""),
18126 priv_(new priv())
18127{
18129 string name = string("void") + "*";
18130 set_name(env.intern(name));
18131}
18132
18133/// Return the hash value of the current IR node.
18134///
18135/// Note that upon the first invocation, this member functions
18136/// computes the hash value and returns it. Subsequent invocations
18137/// just return the hash value that was previously calculated.
18138///
18139/// @return the hash value of the current IR node.
18140hash_t
18142{
18144 return h;
18145}
18146
18147/// Set the pointed-to type of the pointer.
18148///
18149/// @param t the new pointed-to type.
18150void
18152{
18153 ABG_ASSERT(t);
18154 priv_->pointed_to_type_ = t;
18155 priv_->naked_pointed_to_type_ = t.get();
18156
18157 try
18158 {
18159 const environment& env = t->get_environment();
18160 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
18161 string name = (pto ? pto->get_name() : string("void")) + "*";
18162 set_name(env.intern(name));
18163 if (pto)
18164 set_visibility(pto->get_visibility());
18165 }
18166 catch (...)
18167 {}
18168}
18169
18170/// Compares two instances of @ref pointer_type_def.
18171///
18172/// If the two intances are different, set a bitfield to give some
18173/// insight about the kind of differences there are.
18174///
18175/// @param l the first artifact of the comparison.
18176///
18177/// @param r the second artifact of the comparison.
18178///
18179/// @param k a pointer to a bitfield that gives information about the
18180/// kind of changes there are between @p l and @p r. This one is set
18181/// iff @p k is non-null and the function returns false.
18182///
18183/// Please note that setting k to a non-null value does have a
18184/// negative performance impact because even if @p l and @p r are not
18185/// equal, the function keeps up the comparison in order to determine
18186/// the different kinds of ways in which they are different.
18187///
18188/// @return true if @p l equals @p r, false otherwise.
18189bool
18191{
18192 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18193 bool result = p1 == p2;
18194 if (!result)
18195 if (k)
18196 {
18197 if (!types_have_similar_structure(&l, &r))
18198 // pointed-to type changes in which the structure of the
18199 // type changed are considered local changes to the pointer
18200 // type.
18202 *k |= SUBTYPE_CHANGE_KIND;
18203 }
18204
18205 ABG_RETURN(result);
18206}
18207
18208/// Return true iff both instances of pointer_type_def are equal.
18209///
18210/// Note that this function does not check for the scopes of the this
18211/// types.
18212bool
18214{
18215 const pointer_type_def* other = is_pointer_type(&o);
18216 if (!other)
18217 return false;
18218 return try_canonical_compare(this, other);
18219}
18220
18221/// Return true iff both instances of pointer_type_def are equal.
18222///
18223/// Note that this function does not check for the scopes of the
18224/// types.
18225///
18226/// @param other the other type to compare against.
18227///
18228/// @return true iff @p other equals the current instance.
18229bool
18231{
18232 const decl_base* o = is_decl(&other);
18233 if (!o)
18234 return false;
18235 return *this == *o;
18236}
18237
18238/// Return true iff both instances of pointer_type_def are equal.
18239///
18240/// Note that this function does not check for the scopes of the
18241/// types.
18242///
18243/// @param other the other type to compare against.
18244///
18245/// @return true iff @p other equals the current instance.
18246bool
18248{
18249 const decl_base& o = other;
18250 return *this == o;
18251}
18252
18253/// Getter of the pointed-to type.
18254///
18255/// @return the pointed-to type.
18256const type_base_sptr
18258{return priv_->pointed_to_type_.lock();}
18259
18260/// Getter of a naked pointer to the pointed-to type.
18261///
18262/// @return a naked pointed to the pointed-to type.
18263type_base*
18265{return priv_->naked_pointed_to_type_;}
18266
18267/// Build and return the qualified name of the current instance of
18268/// @ref pointer_type_def.
18269///
18270/// @param qn output parameter. The resulting qualified name.
18271///
18272/// @param internal set to true if the call is intended for an
18273/// internal use (for technical use inside the library itself), false
18274/// otherwise. If you don't know what this is for, then set it to
18275/// false.
18276void
18278{qn = get_qualified_name(internal);}
18279
18280/// Build, cache and return the qualified name of the current instance
18281/// of @ref pointer_type_def. Subsequent invocations of this function
18282/// return the cached value.
18283///
18284/// Note that this function should work even if the underlying type is
18285/// momentarily empty.
18286///
18287/// @param internal set to true if the call is intended for an
18288/// internal use (for technical use inside the library itself), false
18289/// otherwise. If you don't know what this is for, then set it to
18290/// false.
18291///
18292/// @return the resulting qualified name.
18293const interned_string&
18295{
18296 type_base* pointed_to_type = get_naked_pointed_to_type();
18297 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18298
18299 if (internal)
18300 {
18301 if (get_canonical_type())
18302 {
18303 if (priv_->internal_qualified_name_.empty())
18304 if (pointed_to_type)
18305 priv_->internal_qualified_name_ =
18306 pointer_declaration_name(this,
18307 /*variable_name=*/"",
18308 /*qualified_name=*/
18309 is_typedef(pointed_to_type)
18310 ? false
18311 : true,
18312 /*internal=*/true);
18313 return priv_->internal_qualified_name_;
18314 }
18315 else
18316 {
18317 // As the type hasn't yet been canonicalized, its structure
18318 // (and so its name) can change. So let's invalidate the
18319 // cache where we store its name at each invocation of this
18320 // function.
18321 if (pointed_to_type)
18322 if (priv_->temp_internal_qualified_name_.empty())
18323 priv_->temp_internal_qualified_name_ =
18324 pointer_declaration_name(this,
18325 /*variable_name=*/"",
18326 /*qualified_name=*/
18327 is_typedef(pointed_to_type)
18328 ? false
18329 : true,
18330 /*internal=*/true);
18331 return priv_->temp_internal_qualified_name_;
18332 }
18333 }
18334 else
18335 {
18337 {
18340 (pointer_declaration_name(this,
18341 /*variable_name=*/"",
18342 /*qualified_name=*/true,
18343 /*internal=*/false));
18345 }
18346 else
18347 {
18348 // As the type hasn't yet been canonicalized, its structure
18349 // (and so its name) can change. So let's invalidate the
18350 // cache where we store its name at each invocation of this
18351 // function.
18352 if (pointed_to_type)
18354 (pointer_declaration_name(this,
18355 /*variable_name=*/"",
18356 /*qualified_name=*/true,
18357 /*internal=*/false));
18359 }
18360 }
18361}
18362
18363/// This implements the ir_traversable_base::traverse pure virtual
18364/// function.
18365///
18366/// @param v the visitor used on the current instance.
18367///
18368/// @return true if the entire IR node tree got traversed, false
18369/// otherwise.
18370bool
18372{
18373 if (v.type_node_has_been_visited(this))
18374 return true;
18375
18376 if (visiting())
18377 return true;
18378
18379 if (v.visit_begin(this))
18380 {
18381 visiting(true);
18382 if (type_base_sptr t = get_pointed_to_type())
18383 t->traverse(v);
18384 visiting(false);
18385 }
18386
18387 bool result = v.visit_end(this);
18389 return result;
18390}
18391
18392pointer_type_def::~pointer_type_def()
18393{}
18394
18395/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
18396/// equality; that is, make it compare the pointed to objects too.
18397///
18398/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18399/// of the equality.
18400///
18401/// @param r the shared_ptr of @ref pointer_type_def on
18402/// right-hand-side of the equality.
18403///
18404/// @return true if the @ref pointer_type_def pointed to by the
18405/// shared_ptrs are equal, false otherwise.
18406bool
18408{
18409 if (l.get() == r.get())
18410 return true;
18411 if (!!l != !!r)
18412 return false;
18413
18414 return *l == *r;
18415}
18416
18417/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
18418/// equality; that is, make it compare the pointed to objects too.
18419///
18420/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18421/// of the equality.
18422///
18423/// @param r the shared_ptr of @ref pointer_type_def on
18424/// right-hand-side of the equality.
18425///
18426/// @return true iff the @ref pointer_type_def pointed to by the
18427/// shared_ptrs are different.
18428bool
18430{return !operator==(l, r);}
18431
18432// </pointer_type_def definitions>
18433
18434// <reference_type_def definitions>
18435
18436/// Private data structure of the @ref reference_type_def type.
18437struct reference_type_def::priv
18438{
18439
18440 type_base_wptr pointed_to_type_;
18441 bool is_lvalue_;
18442 interned_string internal_qualified_name_;
18443 interned_string temp_internal_qualified_name_;
18444
18445 priv(const type_base_sptr& t, bool is_lvalue)
18446 : pointed_to_type_(type_or_void(t, t->get_environment())),
18447 is_lvalue_(is_lvalue)
18448 {}
18449
18450 priv(bool is_lvalue)
18451 : is_lvalue_(is_lvalue)
18452 {}
18453
18454 priv() = delete;
18455};
18456
18457/// This function is automatically invoked whenever an instance of
18458/// this type is canonicalized.
18459///
18460/// It's an overload of the virtual type_base::on_canonical_type_set.
18461///
18462/// We put here what is thus meant to be executed only at the point of
18463/// type canonicalization.
18464void
18467
18468/// Constructor of the reference_type_def type.
18469///
18470/// @param pointed_to the pointed to type.
18471///
18472/// @param lvalue wether the reference is an lvalue reference. If
18473/// false, the reference is an rvalue one.
18474///
18475/// @param size_in_bits the size of the type, in bits.
18476///
18477/// @param align_in_bits the alignment of the type, in bits.
18478///
18479/// @param locus the source location of the type.
18480reference_type_def::reference_type_def(const type_base_sptr pointed_to,
18481 bool lvalue,
18482 size_t size_in_bits,
18483 size_t align_in_bits,
18484 const location& locus)
18485 : type_or_decl_base(pointed_to->get_environment(),
18486 REFERENCE_TYPE
18487 | ABSTRACT_TYPE_BASE
18488 | ABSTRACT_DECL_BASE),
18489 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18490 decl_base(pointed_to->get_environment(), "", locus, ""),
18491 priv_(new priv(pointed_to, lvalue))
18492{
18494
18495 try
18496 {
18497 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18498 string name;
18499 if (pto)
18500 {
18501 set_visibility(pto->get_visibility());
18502 name = string(pto->get_name()) + "&";
18503 }
18504 else
18505 name = string(get_type_name(is_function_type(pointed_to),
18506 /*qualified_name=*/true)) + "&";
18507
18508 if (!is_lvalue())
18509 name += "&";
18510 const environment& env = pointed_to->get_environment();
18511 set_name(env.intern(name));
18512 }
18513 catch (...)
18514 {}
18515}
18516
18517/// Constructor of the reference_type_def type.
18518///
18519/// This one creates a type that has no pointed-to type, temporarily.
18520/// This is useful for cases where the underlying type is not yet
18521/// available. It can be set later using
18522/// reference_type_def::set_pointed_to_type().
18523///
18524/// @param env the environment of the type.
18525///
18526/// @param lvalue wether the reference is an lvalue reference. If
18527/// false, the reference is an rvalue one.
18528///
18529/// @param size_in_bits the size of the type, in bits.
18530///
18531/// @param align_in_bits the alignment of the type, in bits.
18532///
18533/// @param locus the source location of the type.
18534reference_type_def::reference_type_def(const environment& env, bool lvalue,
18535 size_t size_in_bits,
18536 size_t alignment_in_bits,
18537 const location& locus)
18538 : type_or_decl_base(env,
18539 REFERENCE_TYPE
18540 | ABSTRACT_TYPE_BASE
18541 | ABSTRACT_DECL_BASE),
18542 type_base(env, size_in_bits, alignment_in_bits),
18543 decl_base(env, "", locus, ""),
18544 priv_(new priv(lvalue))
18545{
18547 string name = "void&";
18548 if (!is_lvalue())
18549 name += "&";
18550
18551 set_name(env.intern(name));
18552 priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
18553}
18554
18555/// Return the hash value of the current IR node.
18556///
18557/// Note that upon the first invocation, this member functions
18558/// computes the hash value and returns it. Subsequent invocations
18559/// just return the hash value that was previously calculated.
18560///
18561/// @return the hash value of the current IR node.
18562hash_t
18564{
18566 return h;
18567}
18568
18569/// Setter of the pointed_to type of the current reference type.
18570///
18571/// @param pointed_to the new pointed to type.
18572void
18573reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
18574{
18575 ABG_ASSERT(pointed_to_type);
18576 priv_->pointed_to_type_ = pointed_to_type;
18577
18578 decl_base_sptr pto;
18579 try
18580 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
18581 catch (...)
18582 {}
18583
18584 if (pto)
18585 {
18586 set_visibility(pto->get_visibility());
18587 string name = string(pto->get_name()) + "&";
18588 if (!is_lvalue())
18589 name += "&";
18590 const environment& env = pto->get_environment();
18591 set_name(env.intern(name));
18592 }
18593}
18594
18595/// Compares two instances of @ref reference_type_def.
18596///
18597/// If the two intances are different, set a bitfield to give some
18598/// insight about the kind of differences there are.
18599///
18600/// @param l the first artifact of the comparison.
18601///
18602/// @param r the second artifact of the comparison.
18603///
18604/// @param k a pointer to a bitfield that gives information about the
18605/// kind of changes there are between @p l and @p r. This one is set
18606/// iff @p k is non-null and the function returns false.
18607///
18608/// Please note that setting k to a non-null value does have a
18609/// negative performance impact because even if @p l and @p r are not
18610/// equal, the function keeps up the comparison in order to determine
18611/// the different kinds of ways in which they are different.
18612///
18613/// @return true if @p l equals @p r, false otherwise.
18614bool
18616{
18617 if (l.is_lvalue() != r.is_lvalue())
18618 {
18619 if (k)
18622 }
18623 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18624 bool result = p1 == p2;
18625 if (!result)
18626 if (k)
18627 {
18628 if (!types_have_similar_structure(&l, &r))
18630 *k |= SUBTYPE_CHANGE_KIND;
18631 }
18632 ABG_RETURN(result);
18633}
18634
18635/// Equality operator of the @ref reference_type_def type.
18636///
18637/// @param o the other instance of @ref reference_type_def to compare
18638/// against.
18639///
18640/// @return true iff the two instances are equal.
18641bool
18643{
18644 const reference_type_def* other =
18645 dynamic_cast<const reference_type_def*>(&o);
18646 if (!other)
18647 return false;
18648 return try_canonical_compare(this, other);
18649}
18650
18651/// Equality operator of the @ref reference_type_def type.
18652///
18653/// @param o the other instance of @ref reference_type_def to compare
18654/// against.
18655///
18656/// @return true iff the two instances are equal.
18657bool
18659{
18660 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18661 if (!other)
18662 return false;
18663 return *this == *other;
18664}
18665
18666/// Equality operator of the @ref reference_type_def type.
18667///
18668/// @param o the other instance of @ref reference_type_def to compare
18669/// against.
18670///
18671/// @return true iff the two instances are equal.
18672bool
18674{
18675 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18676 if (!other)
18677 return false;
18678 return *this == *other;
18679}
18680
18681type_base_sptr
18682reference_type_def::get_pointed_to_type() const
18683{return priv_->pointed_to_type_.lock();}
18684
18685bool
18686reference_type_def::is_lvalue() const
18687{return priv_->is_lvalue_;}
18688
18689/// Build and return the qualified name of the current instance of the
18690/// @ref reference_type_def.
18691///
18692/// @param qn output parameter. Is set to the newly-built qualified
18693/// name of the current instance of @ref reference_type_def.
18694///
18695/// @param internal set to true if the call is intended for an
18696/// internal use (for technical use inside the library itself), false
18697/// otherwise. If you don't know what this is for, then set it to
18698/// false.
18699void
18701{qn = get_qualified_name(internal);}
18702
18703/// Build, cache and return the qualified name of the current instance
18704/// of the @ref reference_type_def. Subsequent invocations of this
18705/// function return the cached value.
18706///
18707/// @param internal set to true if the call is intended for an
18708/// internal use (for technical use inside the library itself), false
18709/// otherwise. If you don't know what this is for, then set it to
18710/// false.
18711///
18712/// @return the newly-built qualified name of the current instance of
18713/// @ref reference_type_def.
18714const interned_string&
18716{
18717 type_base_sptr pointed_to_type = get_pointed_to_type();
18718 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18719
18720 if (internal)
18721 {
18722 if (get_canonical_type())
18723 {
18724 if (priv_->internal_qualified_name_.empty())
18725 if (pointed_to_type)
18726 priv_->internal_qualified_name_ =
18727 get_name_of_reference_to_type(*pointed_to_type,
18728 is_lvalue(),
18729 /*qualified_name=*/
18730 is_typedef(pointed_to_type)
18731 ? false
18732 : true,
18733 /*internal=*/true);
18734 return priv_->internal_qualified_name_;
18735 }
18736 else
18737 {
18738 // As the type hasn't yet been canonicalized, its structure
18739 // (and so its name) can change. So let's invalidate the
18740 // cache where we store its name at each invocation of this
18741 // function.
18742 if (pointed_to_type)
18743 if (priv_->temp_internal_qualified_name_.empty())
18744 priv_->temp_internal_qualified_name_ =
18745 get_name_of_reference_to_type(*pointed_to_type,
18746 is_lvalue(),
18747 /*qualified_name=*/
18748 is_typedef(pointed_to_type)
18749 ? false
18750 : true,
18751 /*internal=*/true);
18752 return priv_->temp_internal_qualified_name_;
18753 }
18754 }
18755 else
18756 {
18758 {
18760 (get_name_of_reference_to_type(*pointed_to_type,
18761 is_lvalue(),
18762 /*qualified_name=*/true,
18763 /*internal=*/false));
18765 }
18766 else
18767 {
18768 // As the type hasn't yet been canonicalized, its structure
18769 // (and so its name) can change. So let's invalidate the
18770 // cache where we store its name at each invocation of this
18771 // function.
18772 if (pointed_to_type)
18774 (get_name_of_reference_to_type(*pointed_to_type,
18775 is_lvalue(),
18776 /*qualified_name=*/true,
18777 /*internal=*/false));
18779 }
18780 }
18781}
18782
18783/// Get the pretty representation of the current instance of @ref
18784/// reference_type_def.
18785///
18786/// @param internal set to true if the call is intended to get a
18787/// representation of the decl (or type) for the purpose of canonical
18788/// type comparison. This is mainly used in the function
18789/// type_base::get_canonical_type_for().
18790///
18791/// In other words if the argument for this parameter is true then the
18792/// call is meant for internal use (for technical use inside the
18793/// library itself), false otherwise. If you don't know what this is
18794/// for, then set it to false.
18795///
18796/// @param qualified_name if true, names emitted in the pretty
18797/// representation are fully qualified.
18798///
18799/// @return the pretty representatin of the @ref reference_type_def.
18800string
18802 bool qualified_name) const
18803{
18804 string result =
18806 (get_pointed_to_type()),
18807 is_lvalue(),
18808 qualified_name,
18809 internal);
18810
18811 return result;
18812}
18813
18814/// This implements the ir_traversable_base::traverse pure virtual
18815/// function.
18816///
18817/// @param v the visitor used on the current instance.
18818///
18819/// @return true if the entire IR node tree got traversed, false
18820/// otherwise.
18821bool
18823{
18824 if (v.type_node_has_been_visited(this))
18825 return true;
18826
18827 if (visiting())
18828 return true;
18829
18830 if (v.visit_begin(this))
18831 {
18832 visiting(true);
18833 if (type_base_sptr t = get_pointed_to_type())
18834 t->traverse(v);
18835 visiting(false);
18836 }
18837
18838 bool result = v.visit_end(this);
18840 return result;
18841}
18842
18843reference_type_def::~reference_type_def()
18844{}
18845
18846/// Turn equality of shared_ptr of @ref reference_type_def into a deep
18847/// equality; that is, make it compare the pointed to objects too.
18848///
18849/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18850/// of the equality.
18851///
18852/// @param r the shared_ptr of @ref reference_type_def on
18853/// right-hand-side of the equality.
18854///
18855/// @return true if the @ref reference_type_def pointed to by the
18856/// shared_ptrs are equal, false otherwise.
18857bool
18859{
18860 if (l.get() == r.get())
18861 return true;
18862 if (!!l != !!r)
18863 return false;
18864
18865 return *l == *r;
18866}
18867
18868/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
18869/// equality; that is, make it compare the pointed to objects too.
18870///
18871/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18872/// of the equality.
18873///
18874/// @param r the shared_ptr of @ref reference_type_def on
18875/// right-hand-side of the equality.
18876///
18877/// @return true iff the @ref reference_type_def pointed to by the
18878/// shared_ptrs are different.
18879bool
18882
18883// </reference_type_def definitions>
18884
18885// <ptr_to_mbr_type definitions>
18886
18887/// The private data type of @ref ptr_to_mbr_type.
18888struct ptr_to_mbr_type::priv
18889{
18890 // The type of the data member this pointer-to-member-type
18891 // designates.
18892 type_base_sptr dm_type_;
18893 // The class (or typedef to potentially qualified class) containing
18894 // the data member this pointer-to-member-type designates.
18895 type_base_sptr containing_type_;
18896 interned_string internal_qualified_name_;
18897 interned_string temp_internal_qualified_name_;
18898
18899 priv()
18900 {}
18901
18902 priv(const type_base_sptr& dm_type, const type_base_sptr& containing_type)
18903 : dm_type_(dm_type),
18904 containing_type_(containing_type)
18905 {}
18906};// end struct ptr_to_mbr_type::priv
18907
18908/// A constructor for a @ref ptr_to_mbr_type type.
18909///
18910/// @param env the environment to construct the @ref ptr_to_mbr_type in.
18911///
18912/// @param member_type the member type of the of the @ref
18913/// ptr_to_mbr_type to construct.
18914///
18915/// @param containing_type the containing type of the @ref
18916/// ptr_to_mbr_type to construct.
18917///
18918/// @param size_in_bits the size (in bits) of the resulting type.
18919///
18920/// @param alignment_in_bits the alignment (in bits) of the resulting
18921/// type.
18922///
18923/// @param locus the source location of the definition of the
18924/// resulting type.
18925ptr_to_mbr_type::ptr_to_mbr_type(const environment& env,
18926 const type_base_sptr& member_type,
18927 const type_base_sptr& containing_type,
18928 size_t size_in_bits,
18929 size_t alignment_in_bits,
18930 const location& locus)
18931 : type_or_decl_base(env,
18932 POINTER_TO_MEMBER_TYPE
18933 | ABSTRACT_TYPE_BASE
18934 | ABSTRACT_DECL_BASE),
18935 type_base(env, size_in_bits, alignment_in_bits),
18936 decl_base(env, "", locus, ""),
18937 priv_(new priv(member_type, containing_type))
18938{
18940 ABG_ASSERT(member_type);
18941 ABG_ASSERT(containing_type);
18942 set_is_anonymous(false);
18943}
18944
18945/// Getter of the name of the current ptr-to-mbr-type.
18946///
18947/// This just returns the qualified name.
18948///
18949/// @return the (qualified) name of the the type.
18950const interned_string&
18952{
18953 return get_qualified_name(/*internal=*/false);
18954}
18955
18956/// Return the hash value of the current IR node.
18957///
18958/// Note that upon the first invocation, this member functions
18959/// computes the hash value and returns it. Subsequent invocations
18960/// just return the hash value that was previously calculated.
18961///
18962/// @return the hash value of the current IR node.
18963hash_t
18965{
18967 return h;
18968}
18969
18970/// Getter of the member type of the current @ref ptr_to_mbr_type.
18971///
18972/// @return the type of the member referred to by the current
18973/// @ptr_to_mbr_type.
18974const type_base_sptr&
18976{return priv_->dm_type_;}
18977
18978/// Getter of the type containing the member pointed-to by the current
18979/// @ref ptr_to_mbr_type.
18980///
18981/// @return the type containing the member pointed-to by the current
18982/// @ref ptr_to_mbr_type.
18983const type_base_sptr&
18985{return priv_->containing_type_;}
18986
18987/// Equality operator for the current @ref ptr_to_mbr_type.
18988///
18989///@param o the other instance of @ref ptr_to_mbr_type to compare the
18990///current instance to.
18991///
18992/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18993bool
18995{
18996 const ptr_to_mbr_type* other =
18997 dynamic_cast<const ptr_to_mbr_type*>(&o);
18998 if (!other)
18999 return false;
19000 return try_canonical_compare(this, other);
19001}
19002
19003/// Equality operator for the current @ref ptr_to_mbr_type.
19004///
19005///@param o the other instance of @ref ptr_to_mbr_type to compare the
19006///current instance to.
19007///
19008/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
19009bool
19011{
19012 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19013 if (!other)
19014 return false;
19015 return *this == *other;
19016}
19017
19018/// Equality operator for the current @ref ptr_to_mbr_type.
19019///
19020///@param o the other instance of @ref ptr_to_mbr_type to compare the
19021///current instance to.
19022///
19023/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
19024bool
19026{
19027 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19028 if (!other)
19029 return false;
19030 return *this == *other;
19031}
19032
19033/// Get the qualified name for the current @ref ptr_to_mbr_type.
19034///
19035/// @param qualified_name out parameter. This is set to the name of
19036/// the current @ref ptr_to_mbr_type.
19037///
19038/// @param internal if this is true, then the qualified name is for
19039/// the purpose of type canoicalization.
19040void
19042 bool internal) const
19043{qualified_name = get_qualified_name(internal);}
19044
19045/// Get the qualified name for the current @ref ptr_to_mbr_type.
19046///
19047/// @param internal if this is true, then the qualified name is for
19048/// the purpose of type canoicalization.
19049///
19050/// @return the qualified name for the current @ref ptr_to_mbr_type.
19051const interned_string&
19053{
19054 type_base_sptr member_type = get_member_type();
19055 type_base_sptr containing_type = get_containing_type();
19056
19057 if (internal)
19058 {
19059 if (get_canonical_type())
19060 {
19061 if (priv_->internal_qualified_name_.empty())
19062 priv_->internal_qualified_name_ =
19063 ptr_to_mbr_declaration_name(this, "",
19064 /*qualified=*/true,
19065 internal);
19066 return priv_->internal_qualified_name_;
19067 }
19068 else
19069 {
19070 priv_->temp_internal_qualified_name_ =
19071 ptr_to_mbr_declaration_name(this, "", /*qualified=*/true, internal);
19072 return priv_->temp_internal_qualified_name_;
19073 }
19074 }
19075 else
19076 {
19078 (ptr_to_mbr_declaration_name(this, "", /*qualified=*/true,
19079 /*internal=*/false));
19081 }
19082}
19083
19084/// This implements the ir_traversable_base::traverse pure virtual
19085/// function for @ref ptr_to_mbr_type.
19086///
19087/// @param v the visitor used on the current instance.
19088///
19089/// @return true if the entire IR node tree got traversed, false
19090/// otherwise.
19091bool
19093{
19094 if (v.type_node_has_been_visited(this))
19095 return true;
19096
19097 if (visiting())
19098 return true;
19099
19100 if (v.visit_begin(this))
19101 {
19102 visiting(true);
19103 if (type_base_sptr t = get_member_type())
19104 t->traverse(v);
19105
19106 if (type_base_sptr t = get_containing_type())
19107 t->traverse(v);
19108 visiting(false);
19109 }
19110
19111 bool result = v.visit_end(this);
19113 return result;
19114}
19115
19116/// Desctructor for @ref ptr_to_mbr_type.
19119
19120
19121/// Compares two instances of @ref ptr_to_mbr_type.
19122///
19123/// If the two intances are different, set a bitfield to give some
19124/// insight about the kind of differences there are.
19125///
19126/// @param l the first artifact of the comparison.
19127///
19128/// @param r the second artifact of the comparison.
19129///
19130/// @param k a pointer to a bitfield that gives information about the
19131/// kind of changes there are between @p l and @p r. This one is set
19132/// iff @p k is non-null and the function returns false.
19133///
19134/// Please note that setting k to a non-null value does have a
19135/// negative performance impact because even if @p l and @p r are not
19136/// equal, the function keeps up the comparison in order to determine
19137/// the different kinds of ways in which they are different.
19138///
19139/// @return true if @p l equals @p r, false otherwise.
19140bool
19142{
19143 bool result = true;
19144
19145 if (!(l.decl_base::operator==(r)))
19146 {
19147 result = false;
19148 if (k)
19150 else
19151 result = false;
19152 }
19153
19154 if (l.get_member_type() != r.get_member_type())
19155 {
19156 if (k)
19157 {
19158 if (!types_have_similar_structure(&l, &r))
19160 *k |= SUBTYPE_CHANGE_KIND;
19161 }
19162 result = false;
19163 }
19164
19166 {
19167 if (k)
19168 {
19169 if (!types_have_similar_structure(&l, &r))
19171 *k |= SUBTYPE_CHANGE_KIND;
19172 }
19173 result = false;
19174 }
19175
19176 ABG_RETURN(result);
19177}
19178
19179// </ptr_to_mbr_type definitions>
19180
19181// <array_type_def definitions>
19182
19183// <array_type_def::subrange_type>
19184array_type_def::subrange_type::~subrange_type() = default;
19185
19186// <array_type_def::subrante_type::bound_value>
19187
19188/// Default constructor of the @ref
19189/// array_type_def::subrange_type::bound_value class.
19190///
19191/// Constructs an unsigned bound_value of value zero.
19193 : s_(UNSIGNED_SIGNEDNESS)
19194{
19195 v_.unsigned_ = 0;
19196}
19197
19198/// Initialize an unsigned bound_value with a given value.
19199///
19200/// @param v the initial bound value.
19202 : s_(UNSIGNED_SIGNEDNESS)
19203{
19204 v_.unsigned_ = v;
19205}
19206
19207/// Initialize a signed bound_value with a given value.
19208///
19209/// @param v the initial bound value.
19211 : s_(SIGNED_SIGNEDNESS)
19212{
19213 v_.signed_ = v;
19214}
19215
19216/// Getter of the signedness (unsigned VS signed) of the bound value.
19217///
19218/// @return the signedness of the bound value.
19219enum array_type_def::subrange_type::bound_value::signedness
19222
19223/// Setter of the signedness (unsigned VS signed) of the bound value.
19224///
19225/// @param s the new signedness of the bound value.
19226void
19229
19230/// Getter of the bound value as a signed value.
19231///
19232/// @return the bound value as signed.
19233int64_t
19237
19238/// Getter of the bound value as an unsigned value.
19239///
19240/// @return the bound value as unsigned.
19241uint64_t
19244
19245/// Setter of the bound value as unsigned.
19246///
19247/// @param v the new unsigned value.
19248void
19250{
19251 s_ = UNSIGNED_SIGNEDNESS;
19252 v_.unsigned_ = v;
19253}
19254
19255/// Setter of the bound value as signed.
19256///
19257/// @param v the new signed value.
19258void
19260{
19261 s_ = SIGNED_SIGNEDNESS;
19262 v_.signed_ = v;
19263}
19264
19265/// Equality operator of the bound value.
19266///
19267/// @param v the other bound value to compare with.
19268///
19269/// @return true iff the current bound value equals @p v.
19270bool
19272{
19273 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
19274}
19275
19276// </array_type_def::subrante_type::bound_value>
19277
19278struct array_type_def::subrange_type::priv
19279{
19280 bound_value lower_bound_;
19281 bound_value upper_bound_;
19282 type_base_wptr underlying_type_;
19284 bool infinite_;
19285
19286 priv(bound_value ub,
19287 translation_unit::language l = translation_unit::LANG_C11)
19288 : upper_bound_(ub), language_(l), infinite_(false)
19289 {}
19290
19291 priv(bound_value lb, bound_value ub,
19292 translation_unit::language l = translation_unit::LANG_C11)
19293 : lower_bound_(lb), upper_bound_(ub),
19294 language_(l), infinite_(false)
19295 {}
19296
19297 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
19298 translation_unit::language l = translation_unit::LANG_C11)
19299 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
19300 language_(l), infinite_(false)
19301 {}
19302};
19303
19304/// Constructor of an array_type_def::subrange_type type.
19305///
19306/// @param env the environment this type was created from.
19307///
19308/// @param name the name of the subrange type.
19309///
19310/// @param lower_bound the lower bound of the array. This is
19311/// generally zero (at least for C and C++).
19312///
19313/// @param upper_bound the upper bound of the array.
19314///
19315/// @param underlying_type the underlying type of the subrange type.
19316///
19317/// @param loc the source location where the type is defined.
19318array_type_def::subrange_type::subrange_type(const environment& env,
19319 const string& name,
19320 bound_value lower_bound,
19321 bound_value upper_bound,
19322 const type_base_sptr& utype,
19323 const location& loc,
19325 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19326 type_base(env,
19327 utype
19328 ? utype->get_size_in_bits()
19329 : 0,
19330 0),
19331 decl_base(env, name, loc, ""),
19332 priv_(new priv(lower_bound, upper_bound, utype, l))
19333{
19335}
19336
19337/// Constructor of the array_type_def::subrange_type type.
19338///
19339/// @param env the environment this type is being created in.
19340///
19341/// @param name the name of the subrange type.
19342///
19343/// @param lower_bound the lower bound of the array. This is
19344/// generally zero (at least for C and C++).
19345///
19346/// @param upper_bound the upper bound of the array.
19347///
19348/// @param loc the source location where the type is defined.
19349///
19350/// @param l the language that generated this subrange.
19351array_type_def::subrange_type::subrange_type(const environment& env,
19352 const string& name,
19353 bound_value lower_bound,
19354 bound_value upper_bound,
19355 const location& loc,
19357 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19358 type_base(env, /*size-in-bits=*/0, /*alignment=*/0),
19359 decl_base(env, name, loc, ""),
19360 priv_(new priv(lower_bound, upper_bound, l))
19361{
19363}
19364
19365/// Constructor of the array_type_def::subrange_type type.
19366///
19367/// @param env the environment this type is being created from.
19368///
19369/// @param name of the name of type.
19370///
19371/// @param upper_bound the upper bound of the array. The lower bound
19372/// is considered to be zero.
19373///
19374/// @param loc the source location of the type.
19375///
19376/// @param the language that generated this type.
19377array_type_def::subrange_type::subrange_type(const environment& env,
19378 const string& name,
19379 bound_value upper_bound,
19380 const location& loc,
19382 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19383 type_base(env, upper_bound.get_unsigned_value(), 0),
19384 decl_base(env, name, loc, ""),
19385 priv_(new priv(upper_bound, l))
19386{
19388}
19389
19390/// Return the hash value of the current IR node.
19391///
19392/// Note that upon the first invocation, this member functions
19393/// computes the hash value and returns it. Subsequent invocations
19394/// just return the hash value that was previously calculated.
19395///
19396/// @return the hash value of the current IR node.
19397hash_t
19399{
19401 return h;
19402}
19403
19404/// Getter of the underlying type of the subrange, that is, the type
19405/// that defines the range.
19406///
19407/// @return the underlying type.
19408type_base_sptr
19410{return priv_->underlying_type_.lock();}
19411
19412/// Setter of the underlying type of the subrange, that is, the type
19413/// that defines the range.
19414///
19415/// @param u the new underlying type.
19416void
19418{
19419 ABG_ASSERT(priv_->underlying_type_.expired());
19420 priv_->underlying_type_ = u;
19421 if (u)
19422 set_size_in_bits(u->get_size_in_bits());
19423}
19424
19425/// Getter of the upper bound of the subrange type.
19426///
19427/// @return the upper bound of the subrange type.
19428int64_t
19430{return priv_->upper_bound_.get_signed_value();}
19431
19432/// Getter of the lower bound of the subrange type.
19433///
19434/// @return the lower bound of the subrange type.
19435int64_t
19437{return priv_->lower_bound_.get_signed_value();}
19438
19439/// Setter of the upper bound of the subrange type.
19440///
19441/// @param ub the new value of the upper bound.
19442void
19444{priv_->upper_bound_ = ub;}
19445
19446/// Setter of the lower bound.
19447///
19448/// @param lb the new value of the lower bound.
19449void
19451{priv_->lower_bound_ = lb;}
19452
19453/// Getter of the length of the subrange type.
19454///
19455/// Note that a length of zero means the array has an infinite (or
19456/// rather a non-known) size.
19457///
19458/// @return the length of the subrange type.
19459uint64_t
19461{
19462 if (is_non_finite())
19463 return 0;
19464
19465 // A subrange can have an upper bound that is lower than its lower
19466 // bound. This is possible in Ada for instance. In that case, the
19467 // length of the subrange is considered to be zero.
19468 if (get_upper_bound() >= get_lower_bound())
19469 return get_upper_bound() - get_lower_bound() + 1;
19470 return 0;
19471}
19472
19473/// Test if the length of the subrange type is infinite.
19474///
19475/// @return true iff the length of the subrange type is infinite.
19476bool
19478{return priv_->infinite_;}
19479
19480/// Set the infinite-ness status of the subrange type.
19481///
19482/// @param f true iff the length of the subrange type should be set to
19483/// being infinite.
19484void
19486{priv_->infinite_ = f;}
19487
19488/// Getter of the language that generated this type.
19489///
19490/// @return the language of this type.
19493{return priv_->language_;}
19494
19495/// Return a string representation of the sub range.
19496///
19497/// @return the string representation of the sub range.
19498string
19500{
19501 std::ostringstream o;
19502
19504 {
19505 type_base_sptr underlying_type = get_underlying_type();
19506 if (underlying_type)
19507 o << ir::get_pretty_representation(underlying_type, false) << " ";
19508 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
19509 }
19510 else if (is_non_finite())
19511 o << "[]";
19512 else
19513 o << "[" << get_length() << "]";
19514
19515 return o.str();
19516}
19517
19518/// Return a string representation of a vector of subranges
19519///
19520/// @return the string representation of a vector of sub ranges.
19521string
19523{
19524 if (v.empty())
19525 return "[]";
19526
19527 string r;
19528 for (vector<subrange_sptr>::const_iterator i = v.begin();
19529 i != v.end();
19530 ++i)
19531 r += (*i)->as_string();
19532
19533 return r;
19534}
19535
19536/// Compares two isntances of @ref array_type_def::subrange_type.
19537///
19538/// If the two intances are different, set a bitfield to give some
19539/// insight about the kind of differences there are.
19540///
19541/// @param l the first artifact of the comparison.
19542///
19543/// @param r the second artifact of the comparison.
19544///
19545/// @param k a pointer to a bitfield that gives information about the
19546/// kind of changes there are between @p l and @p r. This one is set
19547/// iff @p k is non-null and the function returns false.
19548///
19549/// Please note that setting k to a non-null value does have a
19550/// negative performance impact because even if @p l and @p r are not
19551/// equal, the function keeps up the comparison in order to determine
19552/// the different kinds of ways in which they are different.
19553///
19554/// @return true if @p l equals @p r, false otherwise.
19555bool
19558 change_kind* k)
19559{
19560 bool result = true;
19561
19562 if (l.get_lower_bound() != r.get_lower_bound()
19563 || l.get_upper_bound() != r.get_upper_bound()
19564 || l.get_name() != r.get_name())
19565 {
19566 result = false;
19567 if (k)
19569 else
19570 ABG_RETURN(result);
19571 }
19572
19573 if (l.get_underlying_type()
19574 && r.get_underlying_type()
19575 && (*l.get_underlying_type() != *r.get_underlying_type()))
19576 {
19577 result = false;
19578 if (k)
19579 *k |= SUBTYPE_CHANGE_KIND;
19580 else
19581 ABG_RETURN(result);
19582 }
19583
19584 ABG_RETURN(result);
19585}
19586
19587/// Equality operator.
19588///
19589/// @param o the other subrange to test against.
19590///
19591/// @return true iff @p o equals the current instance of
19592/// array_type_def::subrange_type.
19593bool
19595{
19596 const subrange_type* other =
19597 dynamic_cast<const subrange_type*>(&o);
19598 if (!other)
19599 return false;
19600 return try_canonical_compare(this, other);
19601}
19602
19603/// Equality operator.
19604///
19605/// @param o the other subrange to test against.
19606///
19607/// @return true iff @p o equals the current instance of
19608/// array_type_def::subrange_type.
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/// Equality operator.
19619///
19620/// @param o the other subrange to test against.
19621///
19622/// @return true iff @p o equals the current instance of
19623/// array_type_def::subrange_type.
19624bool
19626{
19627 const type_base &t = o;
19628 return operator==(t);
19629}
19630
19631/// Equality operator.
19632///
19633/// @param o the other subrange to test against.
19634///
19635/// @return true iff @p o equals the current instance of
19636/// array_type_def::subrange_type.
19637bool
19640
19641/// Equality operator.
19642///
19643/// @param o the other subrange to test against.
19644///
19645/// @return true iff @p o equals the current instance of
19646/// array_type_def::subrange_type.
19647bool
19650
19651/// Inequality operator.
19652///
19653/// @param o the other subrange to test against.
19654///
19655/// @return true iff @p o is different from the current instance of
19656/// array_type_def::subrange_type.
19657bool
19660
19661/// Build a pretty representation for an
19662/// array_type_def::subrange_type.
19663///
19664/// @param internal set to true if the call is intended to get a
19665/// representation of the decl (or type) for the purpose of canonical
19666/// type comparison. This is mainly used in the function
19667/// type_base::get_canonical_type_for().
19668///
19669/// In other words if the argument for this parameter is true then the
19670/// call is meant for internal use (for technical use inside the
19671/// library itself), false otherwise. If you don't know what this is
19672/// for, then set it to false.
19673///
19674/// @return a copy of the pretty representation of the current
19675/// instance of typedef_decl.
19676string
19678{
19679 string name = get_name();
19680 string repr;
19681
19682 if (name.empty())
19683 repr += "<anonymous range>";
19684 else
19685 repr += "<range " + get_name() + ">";
19686 repr += as_string();
19687
19688 return repr;
19689}
19690
19691/// This implements the ir_traversable_base::traverse pure virtual
19692/// function.
19693///
19694/// @param v the visitor used on the current instance.
19695///
19696/// @return true if the entire IR node tree got traversed, false
19697/// otherwise.
19698bool
19700{
19701 if (v.type_node_has_been_visited(this))
19702 return true;
19703
19704 if (v.visit_begin(this))
19705 {
19706 visiting(true);
19707 if (type_base_sptr u = get_underlying_type())
19708 u->traverse(v);
19709 visiting(false);
19710 }
19711
19712 bool result = v.visit_end(this);
19714 return result;
19715}
19716
19717// </array_type_def::subrange_type>
19718
19719struct array_type_def::priv
19720{
19721 type_base_wptr element_type_;
19722 subranges_type subranges_;
19723 interned_string temp_internal_qualified_name_;
19724 interned_string internal_qualified_name_;
19725
19726 priv(type_base_sptr t)
19727 : element_type_(t)
19728 {}
19729
19730 priv(type_base_sptr t, subranges_type subs)
19731 : element_type_(t), subranges_(subs)
19732 {}
19733
19734 priv()
19735 {}
19736};
19737
19738/// Constructor for the type array_type_def
19739///
19740/// Note how the constructor expects a vector of subrange
19741/// objects. Parsing of the array information always entails
19742/// parsing the subrange info as well, thus the class subrange_type
19743/// is defined inside class array_type_def and also parsed
19744/// simultaneously.
19745///
19746/// @param e_type the type of the elements contained in the array
19747///
19748/// @param subs a vector of the array's subranges(dimensions)
19749///
19750/// @param locus the source location of the array type definition.
19751array_type_def::array_type_def(const type_base_sptr e_type,
19752 const std::vector<subrange_sptr>& subs,
19753 const location& locus)
19755 ARRAY_TYPE
19756 | ABSTRACT_TYPE_BASE
19757 | ABSTRACT_DECL_BASE),
19758 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
19759 decl_base(e_type->get_environment(), locus),
19760 priv_(new priv(e_type))
19761{
19763 append_subranges(subs);
19764}
19765
19766/// Constructor for the type array_type_def
19767///
19768/// This constructor builds a temporary array that has no element type
19769/// associated. Later when the element type is available, it be set
19770/// with the array_type_def::set_element_type() member function.
19771///
19772/// Note how the constructor expects a vector of subrange
19773/// objects. Parsing of the array information always entails
19774/// parsing the subrange info as well, thus the class subrange_type
19775/// is defined inside class array_type_def and also parsed
19776/// simultaneously.
19777///
19778/// @param env the environment of the array type.
19779///
19780/// @param subs a vector of the array's subranges(dimensions)
19781///
19782/// @param locus the source location of the array type definition.
19783array_type_def::array_type_def(const environment& env,
19784 const std::vector<subrange_sptr>& subs,
19785 const location& locus)
19786 : type_or_decl_base(env,
19787 ARRAY_TYPE
19788 | ABSTRACT_TYPE_BASE
19789 | ABSTRACT_DECL_BASE),
19790 type_base(env, 0, 0),
19791 decl_base(env, locus),
19792 priv_(new priv)
19793{
19795 append_subranges(subs);
19796}
19797
19798/// Return the hash value of the current IR node.
19799///
19800/// Note that upon the first invocation, this member functions
19801/// computes the hash value and returns it. Subsequent invocations
19802/// just return the hash value that was previously calculated.
19803///
19804/// @return the hash value of the current IR node.
19805hash_t
19807{
19809 return h;
19810}
19811
19812/// Update the size of the array.
19813///
19814/// This function computes the size of the array and sets it using
19815/// type_base::set_size_in_bits().
19816void
19817array_type_def::update_size()
19818{
19819 type_base_sptr e = priv_->element_type_.lock();
19820 if (e)
19821 {
19822 size_t s = e->get_size_in_bits();
19823 if (s)
19824 {
19825 for (const auto &sub : get_subranges())
19826 s *= sub->get_length();
19828 }
19829 set_alignment_in_bits(e->get_alignment_in_bits());
19830 }
19831}
19832
19833string
19834array_type_def::get_subrange_representation() const
19835{
19837 return r;
19838}
19839
19840/// Get the pretty representation of the current instance of @ref
19841/// array_type_def.
19842///
19843/// @param internal set to true if the call is intended to get a
19844/// representation of the decl (or type) for the purpose of canonical
19845/// type comparison. This is mainly used in the function
19846/// type_base::get_canonical_type_for().
19847///
19848/// In other words if the argument for this parameter is true then the
19849/// call is meant for internal use (for technical use inside the
19850/// library itself), false otherwise. If you don't know what this is
19851/// for, then set it to false.
19852/// @param internal set to true if the call is intended for an
19853/// internal use (for technical use inside the library itself), false
19854/// otherwise. If you don't know what this is for, then set it to
19855/// false.
19856///
19857/// @return the pretty representation of the ABI artifact.
19858string
19860 bool qualified_name) const
19861{
19862 return array_declaration_name(this, /*variable_name=*/"",
19863 qualified_name, internal);
19864}
19865
19866/// Compares two instances of @ref array_type_def.
19867///
19868/// If the two intances are different, set a bitfield to give some
19869/// insight about the kind of differences there are.
19870///
19871/// @param l the first artifact of the comparison.
19872///
19873/// @param r the second artifact of the comparison.
19874///
19875/// @param k a pointer to a bitfield that gives information about the
19876/// kind of changes there are between @p l and @p r. This one is set
19877/// iff @p k is non-null and the function returns false.
19878///
19879/// Please note that setting k to a non-null value does have a
19880/// negative performance impact because even if @p l and @p r are not
19881/// equal, the function keeps up the comparison in order to determine
19882/// the different kinds of ways in which they are different.
19883///
19884/// @return true if @p l equals @p r, false otherwise.
19885bool
19887{
19888 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
19889 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
19890
19891 bool result = true;
19892 if (this_subs.size() != other_subs.size())
19893 {
19894 result = false;
19895 if (k)
19897 else
19899 }
19900
19901 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19902 for (i = this_subs.begin(), j = other_subs.begin();
19903 i != this_subs.end() && j != other_subs.end();
19904 ++i, ++j)
19905 if (**i != **j)
19906 {
19907 result = false;
19908 if (k)
19909 {
19911 break;
19912 }
19913 else
19915 }
19916
19917 // Compare the element types modulo the typedefs they might have
19918 if (l.get_element_type() != r.get_element_type())
19919 {
19920 result = false;
19921 if (k)
19922 *k |= SUBTYPE_CHANGE_KIND;
19923 else
19925 }
19926
19927 ABG_RETURN(result);
19928}
19929
19930/// Test if two array types are equals modulo CV qualifiers.
19931///
19932/// @param l the first array of the comparison.
19933///
19934/// @param r the second array of the comparison.
19935///
19936/// @return true iff @p l equals @p r or, if they are different, the
19937/// difference between the too is just a matter of CV qualifiers.
19938bool
19940{
19941 if (l == r)
19942 return true;
19943
19944 if (!l || !r)
19946
19949
19950 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
19951 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
19952
19953 if (this_subs.size() != other_subs.size())
19955
19956 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19957 for (i = this_subs.begin(), j = other_subs.begin();
19958 i != this_subs.end() && j != other_subs.end();
19959 ++i, ++j)
19960 if (**i != **j)
19962
19963 type_base *first_element_type =
19965 type_base *second_element_type =
19967
19968 if (*first_element_type != *second_element_type)
19970
19971 return true;
19972}
19973
19974/// Test if two array types are equals modulo CV qualifiers.
19975///
19976/// @param l the first array of the comparison.
19977///
19978/// @param r the second array of the comparison.
19979///
19980/// @return true iff @p l equals @p r or, if they are different, the
19981/// difference between the too is just a matter of CV qualifiers.
19982bool
19984 const array_type_def_sptr& r)
19985{return equals_modulo_cv_qualifier(l.get(), r.get());}
19986
19987/// Test if two pointer types are equals modulo CV qualifiers.
19988///
19989/// @param l the first pointer of the comparison.
19990///
19991/// @param r the second pointer of the comparison.
19992///
19993/// @return true iff @p l equals @p r or, if they are different, the
19994/// difference between the too is just a matter of CV qualifiers.
19995bool
19997{
19998 if (l == r)
19999 return true;
20000
20001 if (!l || !r)
20003
20004 type_base_sptr l_ptt = l->get_pointed_to_type(),
20005 r_ptt = r->get_pointed_to_type();
20006
20007 do
20008 {
20009 l_ptt = peel_qualified_or_typedef_type(l_ptt);
20010 r_ptt = peel_qualified_or_typedef_type(r_ptt);
20011
20012 l_ptt = is_pointer_type(l_ptt)
20014 : l_ptt;
20015
20016 r_ptt = is_pointer_type(r_ptt)
20018 : r_ptt;
20019 } while (is_pointer_type(l_ptt) && is_pointer_type(r_ptt));
20020
20021 l_ptt = peel_qualified_or_typedef_type(l_ptt);
20022 r_ptt = peel_qualified_or_typedef_type(r_ptt);
20023
20024 return *l_ptt == *r_ptt;
20025}
20026
20027/// Test if two pointer types are equals modulo CV qualifiers.
20028///
20029/// @param l the first pointer of the comparison.
20030///
20031/// @param r the second pointer of the comparison.
20032///
20033/// @return true iff @p l equals @p r or, if they are different, the
20034/// difference between the too is just a matter of CV qualifiers.
20035bool
20039
20040/// Get the language of the array.
20041///
20042/// @return the language of the array.
20045{
20046 const std::vector<subrange_sptr>& subranges =
20047 get_subranges();
20048
20049 if (subranges.empty())
20050 return translation_unit::LANG_C11;
20051 return subranges.front()->get_language();
20052}
20053
20054bool
20056{
20057 const array_type_def* other =
20058 dynamic_cast<const array_type_def*>(&o);
20059 if (!other)
20060 return false;
20061 return try_canonical_compare(this, other);
20062}
20063
20064bool
20066{
20067 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20068 if (!other)
20069 return false;
20070 return *this == *other;
20071}
20072
20073/// Getter of the type of an array element.
20074///
20075/// @return the type of an array element.
20076const type_base_sptr
20078{return priv_->element_type_.lock();}
20079
20080/// Setter of the type of array element.
20081///
20082/// Beware that after using this function, one might want to
20083/// re-compute the canonical type of the array, if one has already
20084/// been computed.
20085///
20086/// The intended use of this method is to permit in-place adjustment
20087/// of the element type's qualifiers. In particular, the size of the
20088/// element type should not be changed.
20089///
20090/// @param element_type the new element type to set.
20091void
20092array_type_def::set_element_type(const type_base_sptr& element_type)
20093{
20094 priv_->element_type_ = element_type;
20095 update_size();
20097}
20098
20099/// Append subranges from the vector @param subs to the current
20100/// vector of subranges.
20101void
20102array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
20103{
20104
20105 for (const auto &sub : subs)
20106 priv_->subranges_.push_back(sub);
20107
20108 update_size();
20110}
20111
20112/// @return true if one of the sub-ranges of the array is infinite, or
20113/// if the array has no sub-range at all, also meaning that the size
20114/// of the array is infinite.
20115bool
20117{
20118 if (priv_->subranges_.empty())
20119 return true;
20120
20121 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
20122 priv_->subranges_.begin();
20123 i != priv_->subranges_.end();
20124 ++i)
20125 if ((*i)->is_non_finite())
20126 return true;
20127
20128 return false;
20129}
20130
20131int
20132array_type_def::get_dimension_count() const
20133{return priv_->subranges_.size();}
20134
20135/// Build and return the qualified name of the current instance of the
20136/// @ref array_type_def.
20137///
20138/// @param qn output parameter. Is set to the newly-built qualified
20139/// name of the current instance of @ref array_type_def.
20140///
20141/// @param internal set to true if the call is intended for an
20142/// internal use (for technical use inside the library itself), false
20143/// otherwise. If you don't know what this is for, then set it to
20144/// false.
20145void
20147{qn = get_qualified_name(internal);}
20148
20149/// Compute the qualified name of the array.
20150///
20151/// @param internal set to true if the call is intended for an
20152/// internal use (for technical use inside the library itself), false
20153/// otherwise. If you don't know what this is for, then set it to
20154/// false.
20155///
20156/// @return the resulting qualified name.
20157const interned_string&
20159{
20160 if (internal)
20161 {
20162 if (get_canonical_type())
20163 {
20164 if (priv_->internal_qualified_name_.empty())
20165 priv_->internal_qualified_name_ =
20166 array_declaration_name(this, /*variable_name=*/"",
20167 /*qualified=*/false,
20168 /*internal=*/true);
20169 return priv_->internal_qualified_name_;
20170 }
20171 else
20172 {
20173 priv_->temp_internal_qualified_name_ =
20174 array_declaration_name(this, /*variable_name=*/"",
20175 /*qualified*/false, /*internal*/true);
20176 return priv_->temp_internal_qualified_name_;
20177 }
20178 }
20179 else
20180 {
20181 if (get_canonical_type())
20182 {
20183 if (decl_base::peek_qualified_name().empty())
20184 set_qualified_name(array_declaration_name(this,
20185 /*variable_name=*/"",
20186 /*qualified=*/false,
20187 /*internal=*/false));
20189 }
20190 else
20191 {
20193 (array_declaration_name(this, /*variable_name=*/"",
20194 /*qualified=*/false,
20195 /*internal=*/false));
20197 }
20198 }
20199}
20200
20201/// This implements the ir_traversable_base::traverse pure virtual
20202/// function.
20203///
20204/// @param v the visitor used on the current instance.
20205///
20206/// @return true if the entire IR node tree got traversed, false
20207/// otherwise.
20208bool
20210{
20211 if (v.type_node_has_been_visited(this))
20212 return true;
20213
20214 if (visiting())
20215 return true;
20216
20217 if (v.visit_begin(this))
20218 {
20219 visiting(true);
20220 if (type_base_sptr t = get_element_type())
20221 t->traverse(v);
20222 visiting(false);
20223 }
20224
20225 bool result = v.visit_end(this);
20227 return result;
20228}
20229
20230const location&
20231array_type_def::get_location() const
20232{return decl_base::get_location();}
20233
20234/// Get the array's subranges
20235const std::vector<array_type_def::subrange_sptr>&
20237{return priv_->subranges_;}
20238
20239array_type_def::~array_type_def()
20240{}
20241
20242// </array_type_def definitions>
20243
20244// <enum_type_decl definitions>
20245
20246class enum_type_decl::priv
20247{
20248 type_base_sptr underlying_type_;
20249 enumerators enumerators_;
20250 mutable enumerators sorted_enumerators_;
20251
20252 friend class enum_type_decl;
20253
20254 priv();
20255
20256public:
20257 priv(type_base_sptr underlying_type,
20259 : underlying_type_(underlying_type),
20260 enumerators_(enumerators)
20261 {}
20262}; // end class enum_type_decl::priv
20263
20264/// Constructor.
20265///
20266/// @param name the name of the type declaration.
20267///
20268/// @param locus the source location where the type was defined.
20269///
20270/// @param underlying_type the underlying type of the enum.
20271///
20272/// @param enums the enumerators of this enum type.
20273///
20274/// @param linkage_name the linkage name of the enum.
20275///
20276/// @param vis the visibility of the enum type.
20277enum_type_decl::enum_type_decl(const string& name,
20278 const location& locus,
20279 type_base_sptr underlying_type,
20280 enumerators& enums,
20281 const string& linkage_name,
20282 visibility vis)
20283 : type_or_decl_base(underlying_type->get_environment(),
20284 ENUM_TYPE
20285 | ABSTRACT_TYPE_BASE
20286 | ABSTRACT_DECL_BASE),
20287 type_base(underlying_type->get_environment(),
20288 underlying_type->get_size_in_bits(),
20289 underlying_type->get_alignment_in_bits()),
20290 decl_base(underlying_type->get_environment(),
20291 name, locus, linkage_name, vis),
20292 priv_(new priv(underlying_type, enums))
20293{
20295 for (enumerators::iterator e = get_enumerators().begin();
20296 e != get_enumerators().end();
20297 ++e)
20298 e->set_enum_type(this);
20299}
20300
20301/// Return the hash value of the current IR node.
20302///
20303/// Note that upon the first invocation, this member functions
20304/// computes the hash value and returns it. Subsequent invocations
20305/// just return the hash value that was previously calculated.
20306///
20307/// @return the hash value of the current IR node.
20308hash_t
20310{
20312 return h;
20313}
20314
20315/// Return the underlying type of the enum.
20316type_base_sptr
20318{return priv_->underlying_type_;}
20319
20320/// @return the list of enumerators of the enum.
20323{return priv_->enumerators_;}
20324
20325/// @return the list of enumerators of the enum.
20328{return priv_->enumerators_;}
20329
20330/// Get the lexicographically sorted vector of enumerators.
20331///
20332/// @return the lexicographically sorted vector of enumerators.
20335{
20336 if (priv_->sorted_enumerators_.empty())
20337 {
20338 for (auto e = get_enumerators().rbegin();
20339 e != get_enumerators().rend();
20340 ++e)
20341 priv_->sorted_enumerators_.push_back(*e);
20342
20343 std::sort(priv_->sorted_enumerators_.begin(),
20344 priv_->sorted_enumerators_.end(),
20345 [](const enum_type_decl::enumerator& l,
20347 {
20348 if (l.get_name() == r.get_name())
20349 return l.get_value() < r.get_value();
20350 return (l.get_name() < r.get_name());
20351 });
20352 }
20353
20354 return priv_->sorted_enumerators_;
20355}
20356
20357/// Find an enumerator by its value.
20358///
20359/// @param value the enumerator value to look for.
20360///
20361/// @param result output parameter. This is set to the enumerator
20362/// which value is @p value, if found. This is set iff the function
20363/// returns true.
20364///
20365/// @return true iff an enumerator with value @p value was found and
20366/// returned by argument via @p result.
20367bool
20369 enum_type_decl:: enumerator& result)
20370{
20371 for (auto& e : get_enumerators())
20372 if (e.get_value() == value)
20373 {
20374 result = e;
20375 return true;
20376 }
20377
20378 return false;
20379}
20380
20381/// Find an enumerator by its name
20382///
20383/// @param name the enumerator name to look for.
20384///
20385/// @param result output parameter. This is set to the enumerator
20386/// which name is @p name, if found. This is set iff the function
20387/// returns true.
20388///
20389/// @return true iff an enumerator with name @p name was found and
20390/// returned by argument via @p result.
20391bool
20394{
20395 for (auto& e : get_enumerators())
20396 if (e.get_name() == name)
20397 {
20398 result = e;
20399 return true;
20400 }
20401
20402 return false;
20403}
20404
20405/// Get the pretty representation of the current instance of @ref
20406/// enum_type_decl.
20407///
20408/// @param internal set to true if the call is intended to get a
20409/// representation of the decl (or type) for the purpose of canonical
20410/// type comparison. This is mainly used in the function
20411/// type_base::get_canonical_type_for().
20412///
20413/// In other words if the argument for this parameter is true then the
20414/// call is meant for internal use (for technical use inside the
20415/// library itself), false otherwise. If you don't know what this is
20416/// for, then set it to false.
20417///
20418/// @param qualified_name if true, names emitted in the pretty
20419/// representation are fully qualified.
20420///
20421/// @return the pretty representation of the enum type.
20422string
20424 bool qualified_name) const
20425{
20426 string r = "enum ";
20427
20428 if (internal && get_is_anonymous())
20429 r += get_type_name(this, qualified_name, /*internal=*/true);
20430 else if (get_is_anonymous())
20431 r += get_enum_flat_representation(*this, "",
20432 /*one_line=*/true,
20433 qualified_name);
20434 else
20436 qualified_name);
20437 return r;
20438}
20439
20440/// This implements the ir_traversable_base::traverse pure virtual
20441/// function.
20442///
20443/// @param v the visitor used on the current instance.
20444///
20445/// @return true if the entire IR node tree got traversed, false
20446/// otherwise.
20447bool
20449{
20450 if (v.type_node_has_been_visited(this))
20451 return true;
20452
20453 if (visiting())
20454 return true;
20455
20456 if (v.visit_begin(this))
20457 {
20458 visiting(true);
20459 if (type_base_sptr t = get_underlying_type())
20460 t->traverse(v);
20461 visiting(false);
20462 }
20463
20464 bool result = v.visit_end(this);
20466 return result;
20467}
20468
20469/// Destructor for the enum type declaration.
20472
20473/// Test if two enums differ, but not by a name change.
20474///
20475/// @param l the first enum to consider.
20476///
20477/// @param r the second enum to consider.
20478///
20479/// @return true iff @p l differs from @p r by anything but a name
20480/// change.
20481bool
20483 const enum_type_decl& r,
20484 change_kind* k)
20485{
20486 bool result = false;
20488 {
20489 result = true;
20490 if (k)
20491 *k |= SUBTYPE_CHANGE_KIND;
20492 else
20493 return true;
20494 }
20495
20496 enum_type_decl::enumerators::const_iterator i, j;
20497 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
20498 i != l.get_enumerators().end() && j != r.get_enumerators().end();
20499 ++i, ++j)
20500 if (*i != *j)
20501 {
20502 result = true;
20503 if (k)
20504 {
20506 break;
20507 }
20508 else
20509 return true;
20510 }
20511
20512 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
20513 {
20514 result = true;
20515 if (k)
20517 else
20518 return true;
20519 }
20520
20521 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
20524 string n_l = l.get_name();
20525 string n_r = r.get_name();
20526 local_r.set_qualified_name(qn_l);
20527 local_r.set_name(n_l);
20528
20529 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
20530 {
20531 result = true;
20532 if (k)
20533 {
20534 if (!l.decl_base::operator==(r))
20536 if (!l.type_base::operator==(r))
20538 }
20539 else
20540 {
20541 local_r.set_name(n_r);
20542 local_r.set_qualified_name(qn_r);
20543 return true;
20544 }
20545 }
20546 local_r.set_qualified_name(qn_r);
20547 local_r.set_name(n_r);
20548
20549 return result;
20550}
20551
20552/// Test if a given enumerator is found present in an enum.
20553///
20554/// This is a subroutine of the equals function for enums.
20555///
20556/// @param enr the enumerator to consider.
20557///
20558/// @param enom the enum to consider.
20559///
20560/// @return true iff the enumerator @p enr is present in the enum @p
20561/// enom.
20562bool
20564 const enum_type_decl &enom)
20565{
20566 for (const auto &e : enom.get_enumerators())
20567 if (e == enr)
20568 return true;
20569 return false;
20570}
20571
20572/// Check if two enumerators values are equal.
20573///
20574/// This function doesn't check if the names of the enumerators are
20575/// equal or not.
20576///
20577/// @param enr the first enumerator to consider.
20578///
20579/// @param enl the second enumerator to consider.
20580///
20581/// @return true iff @p enr has the same value as @p enl.
20582static bool
20583enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
20584 const enum_type_decl::enumerator &enl)
20585{return enr.get_value() == enl.get_value();}
20586
20587/// Detect if a given enumerator value is present in an enum.
20588///
20589/// This function looks inside the enumerators of a given enum and
20590/// detect if the enum contains at least one enumerator or a given
20591/// value. The function also detects if the enumerator value we are
20592/// looking at is present in the enum with a different name. An
20593/// enumerator with the same value but with a different name is named
20594/// a "redundant enumerator". The function returns the set of
20595/// enumerators that are redundant with the value we are looking at.
20596///
20597/// @param enr the enumerator to consider.
20598///
20599/// @param enom the enum to consider.
20600///
20601/// @param redundant_enrs if the function returns true, then this
20602/// vector is filled with enumerators that are redundant with the
20603/// value of @p enr.
20604///
20605/// @return true iff the function detects that @p enom contains
20606/// enumerators with the same value as @p enr.
20607static bool
20608is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
20609 const enum_type_decl &enom,
20610 vector<enum_type_decl::enumerator>& redundant_enrs)
20611{
20612 bool found = false;
20613 for (const auto &e : enom.get_enumerators())
20614 if (enumerators_values_are_equal(e, enr))
20615 {
20616 found = true;
20617 if (e != enr)
20618 redundant_enrs.push_back(e);
20619 }
20620
20621 return found;
20622}
20623
20624/// Check if an enumerator value is redundant in a given enum.
20625///
20626/// Given an enumerator value, this function detects if an enum
20627/// contains at least one enumerator with the the same value but with
20628/// a different name.
20629///
20630/// @param enr the enumerator to consider.
20631///
20632/// @param enom the enum to consider.
20633///
20634/// @return true iff @p enr is a redundant enumerator in enom.
20635static bool
20636is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
20637 const enum_type_decl &enom)
20638{
20639 vector<enum_type_decl::enumerator> redundant_enrs;
20640 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
20641 {
20642 if (!redundant_enrs.empty())
20643 return true;
20644 }
20645 return false;
20646}
20647
20648/// Compares two instances of @ref enum_type_decl.
20649///
20650/// If the two intances are different, set a bitfield to give some
20651/// insight about the kind of differences there are.
20652///
20653/// @param l the first artifact of the comparison.
20654///
20655/// @param r the second artifact of the comparison.
20656///
20657/// @param k a pointer to a bitfield that gives information about the
20658/// kind of changes there are between @p l and @p r. This one is set
20659/// iff @p k is non-null and the function returns false.
20660///
20661/// Please note that setting k to a non-null value does have a
20662/// negative performance impact because even if @p l and @p r are not
20663/// equal, the function keeps up the comparison in order to determine
20664/// the different kinds of ways in which they are different.
20665///
20666/// @return true if @p l equals @p r, false otherwise.
20667bool
20669{
20670 bool result = true;
20671
20672 //
20673 // Look through decl-only-enum.
20674 //
20675
20676 const enum_type_decl *def1 =
20679 : &l;
20680
20681 const enum_type_decl *def2 =
20684 : &r;
20685
20686 if (!!def1 != !!def2)
20687 {
20688 // One enum is decl-only while the other is not.
20689 // So the two enums are different.
20690 result = false;
20691 if (k)
20692 *k |= SUBTYPE_CHANGE_KIND;
20693 else
20695 }
20696
20697 //
20698 // At this point, both enums have the same state of decl-only-ness.
20699 // So we can compare oranges to oranges.
20700 //
20701
20702 if (!def1)
20703 def1 = &l;
20704 if (!def2)
20705 def2 = &r;
20706
20707 if (def1->get_underlying_type() != def2->get_underlying_type())
20708 {
20709 result = false;
20710 if (k)
20711 *k |= SUBTYPE_CHANGE_KIND;
20712 else
20714 }
20715
20716 if (!(def1->decl_base::operator==(*def2)
20717 && def1->type_base::operator==(*def2)))
20718 {
20719 result = false;
20720 if (k)
20721 {
20722 if (!def1->decl_base::operator==(*def2))
20724 if (!def1->type_base::operator==(*def2))
20726 }
20727 else
20729 }
20730
20731 // Now compare the enumerators.
20732
20733 // First in a naive (but potentially fast) way in case both enums
20734 // are equal in a naive manner.
20735
20736 if (def1->get_enumerators().size() == def2->get_enumerators().size())
20737 {
20738 bool equals = true;
20739 for (auto e1 = def1->get_enumerators().begin(),
20740 e2 = def2->get_enumerators().begin();
20741 (e1 != def1->get_enumerators().end()
20742 && e2 != def2->get_enumerators().end());
20743 ++e1, ++e2)
20744 {
20745 if (*e1 != *e2)
20746 {
20747 equals = false;
20748 break;
20749 }
20750 }
20751 if (equals)
20752 ABG_RETURN(result);
20753 }
20754
20755 // If the two enums where not naively equals, let's try a more
20756 // clever (and slow) way.
20757
20758 // Note that the order of declaration
20759 // of enumerators should not matter in the comparison.
20760 //
20761 // Also if an enumerator value is redundant, that shouldn't impact
20762 // the comparison.
20763 //
20764 // In that case, note that the two enums below are considered equal:
20765 //
20766 // enum foo
20767 // {
20768 // e0 = 0;
20769 // e1 = 1;
20770 // e2 = 2;
20771 // };
20772 //
20773 // enum foo
20774 // {
20775 // e0 = 0;
20776 // e1 = 1;
20777 // e2 = 2;
20778 // e_added = 1; // <-- this value is redundant with the value
20779 // // of the enumerator e1.
20780 // };
20781 //
20782 // Note however that in the case below, the enums are different.
20783 //
20784 // enum foo
20785 // {
20786 // e0 = 0;
20787 // e1 = 1;
20788 // };
20789 //
20790 // enum foo
20791 // {
20792 // e0 = 0;
20793 // e2 = 1; // <-- this enum value is present in the first version
20794 // // of foo, but is not redundant with any enumerator
20795 // // in the second version of of enum foo.
20796 // };
20797 //
20798 // These two enums are considered equal.
20799
20800 for(const auto &e : def1->get_enumerators())
20801 if (!is_enumerator_present_in_enum(e, *def2)
20802 && (!is_enumerator_value_redundant(e, *def2)
20803 || !is_enumerator_value_redundant(e, *def1)))
20804 {
20805 result = false;
20806 if (k)
20807 {
20809 break;
20810 }
20811 else
20813 }
20814
20815 for(const auto &e : def2->get_enumerators())
20816 if (!is_enumerator_present_in_enum(e, *def1)
20817 && (!is_enumerator_value_redundant(e, *def1)
20818 || !is_enumerator_value_redundant(e, *def2)))
20819 {
20820 result = false;
20821 if (k)
20822 {
20824 break;
20825 }
20826 else
20828 }
20829
20830 ABG_RETURN(result);
20831}
20832
20833/// Equality operator.
20834///
20835/// @param o the other enum to test against.
20836///
20837/// @return true iff @p o equals the current instance of enum type
20838/// decl.
20839bool
20841{
20842 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
20843 if (!op)
20844 return false;
20845 return try_canonical_compare(this, op);
20846}
20847
20848/// Equality operator.
20849///
20850/// @param o the other enum to test against.
20851///
20852/// @return true iff @p o is equals the current instance of enum type
20853/// decl.
20854bool
20856{
20857 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20858 if (!other)
20859 return false;
20860 return *this == *other;
20861}
20862
20863/// Equality operator for @ref enum_type_decl_sptr.
20864///
20865/// @param l the first operand to compare.
20866///
20867/// @param r the second operand to compare.
20868///
20869/// @return true iff @p l equals @p r.
20870bool
20872{
20873 if (!!l != !!r)
20874 return false;
20875 if (l.get() == r.get())
20876 return true;
20877 decl_base_sptr o = r;
20878 return *l == *o;
20879}
20880
20881/// Inequality operator for @ref enum_type_decl_sptr.
20882///
20883/// @param l the first operand to compare.
20884///
20885/// @param r the second operand to compare.
20886///
20887/// @return true iff @p l equals @p r.
20888bool
20890{return !operator==(l, r);}
20891
20892/// The type of the private data of an @ref
20893/// enum_type_decl::enumerator.
20894class enum_type_decl::enumerator::priv
20895{
20896 string name_;
20897 int64_t value_;
20898 string qualified_name_;
20899 enum_type_decl* enum_type_;
20900
20901 friend class enum_type_decl::enumerator;
20902
20903public:
20904
20905 priv()
20906 : enum_type_()
20907 {}
20908
20909 priv(const string& name,
20910 int64_t value,
20911 enum_type_decl* e = 0)
20912 : name_(name),
20913 value_(value),
20914 enum_type_(e)
20915 {}
20916}; // end class enum_type_def::enumerator::priv
20917
20918/// Default constructor of the @ref enum_type_decl::enumerator type.
20920 : priv_(new priv)
20921{}
20922
20923enum_type_decl::enumerator::~enumerator() = default;
20924
20925/// Constructor of the @ref enum_type_decl::enumerator type.
20926///
20927/// @param env the environment we are operating from.
20928///
20929/// @param name the name of the enumerator.
20930///
20931/// @param value the value of the enumerator.
20933 int64_t value)
20934 : priv_(new priv(name, value))
20935{}
20936
20937/// Copy constructor of the @ref enum_type_decl::enumerator type.
20938///
20939/// @param other enumerator to copy.
20941 : priv_(new priv(other.get_name(),
20942 other.get_value(),
20943 other.get_enum_type()))
20944{}
20945
20946/// Assignment operator of the @ref enum_type_decl::enumerator type.
20947///
20948/// @param o
20951{
20952 priv_->name_ = o.get_name();
20953 priv_->value_ = o.get_value();
20954 priv_->enum_type_ = o.get_enum_type();
20955 return *this;
20956}
20957
20958/// Equality operator
20959///
20960/// @param other the enumerator to compare to the current
20961/// instance of enum_type_decl::enumerator.
20962///
20963/// @return true if @p other equals the current instance of
20964/// enum_type_decl::enumerator.
20965bool
20967{
20968 bool names_equal = true;
20969 names_equal = (get_name() == other.get_name());
20970 return names_equal && (get_value() == other.get_value());
20971}
20972
20973/// Inequality operator.
20974///
20975/// @param other the other instance to compare against.
20976///
20977/// @return true iff @p other is different from the current instance.
20978bool
20980{return !operator==(other);}
20981
20982/// Getter for the name of the current instance of
20983/// enum_type_decl::enumerator.
20984///
20985/// @return a reference to the name of the current instance of
20986/// enum_type_decl::enumerator.
20987const string&
20989{return priv_->name_;}
20990
20991/// Getter for the qualified name of the current instance of
20992/// enum_type_decl::enumerator. The first invocation of the method
20993/// builds the qualified name, caches it and return a reference to the
20994/// cached qualified name. Subsequent invocations just return the
20995/// cached value.
20996///
20997/// @param internal set to true if the call is intended for an
20998/// internal use (for technical use inside the library itself), false
20999/// otherwise. If you don't know what this is for, then set it to
21000/// false.
21001///
21002/// @return the qualified name of the current instance of
21003/// enum_type_decl::enumerator.
21004const string&
21006{
21007 if (priv_->qualified_name_.empty())
21008 {
21009 priv_->qualified_name_ =
21010 get_enum_type()->get_qualified_name(internal)
21011 + "::"
21012 + get_name();
21013 }
21014 return priv_->qualified_name_;
21015}
21016
21017/// Setter for the name of @ref enum_type_decl::enumerator.
21018///
21019/// @param n the new name.
21020void
21022{priv_->name_ = n;}
21023
21024/// Getter for the value of @ref enum_type_decl::enumerator.
21025///
21026/// @return the value of the current instance of
21027/// enum_type_decl::enumerator.
21028int64_t
21030{return priv_->value_;}
21031
21032/// Setter for the value of @ref enum_type_decl::enumerator.
21033///
21034/// @param v the new value of the enum_type_decl::enumerator.
21035void
21037{priv_->value_= v;}
21038
21039/// Getter for the enum type that this enumerator is for.
21040///
21041/// @return the enum type that this enumerator is for.
21044{return priv_->enum_type_;}
21045
21046/// Setter for the enum type that this enumerator is for.
21047///
21048/// @param e the new enum type.
21049void
21052// </enum_type_decl definitions>
21053
21054// <typedef_decl definitions>
21055
21056/// Private data structure of the @ref typedef_decl.
21057struct typedef_decl::priv
21058{
21059 type_base_wptr underlying_type_;
21060
21061 priv(const type_base_sptr& t)
21062 : underlying_type_(t)
21063 {}
21064}; // end struct typedef_decl::priv
21065
21066/// Constructor of the typedef_decl type.
21067///
21068/// @param name the name of the typedef.
21069///
21070/// @param underlying_type the underlying type of the typedef.
21071///
21072/// @param locus the source location of the typedef declaration.
21073///
21074/// @param linkage_name the mangled name of the typedef.
21075///
21076/// @param vis the visibility of the typedef type.
21077typedef_decl::typedef_decl(const string& name,
21078 const type_base_sptr underlying_type,
21079 const location& locus,
21080 const string& linkage_name,
21081 visibility vis)
21082 : type_or_decl_base(underlying_type->get_environment(),
21083 TYPEDEF_TYPE
21084 | ABSTRACT_TYPE_BASE
21085 | ABSTRACT_DECL_BASE),
21086 type_base(underlying_type->get_environment(),
21087 underlying_type->get_size_in_bits(),
21088 underlying_type->get_alignment_in_bits()),
21089 decl_base(underlying_type->get_environment(),
21090 name, locus, linkage_name, vis),
21091 priv_(new priv(underlying_type))
21092{
21094}
21095
21096/// Constructor of the typedef_decl type.
21097///
21098/// @param name the name of the typedef.
21099///
21100/// @param env the environment of the current typedef.
21101///
21102/// @param locus the source location of the typedef declaration.
21103///
21104/// @param mangled_name the mangled name of the typedef.
21105///
21106/// @param vis the visibility of the typedef type.
21107typedef_decl::typedef_decl(const string& name,
21108 const environment& env,
21109 const location& locus,
21110 const string& mangled_name,
21111 visibility vis)
21112 : type_or_decl_base(env,
21113 TYPEDEF_TYPE
21114 | ABSTRACT_TYPE_BASE
21115 | ABSTRACT_DECL_BASE),
21116 type_base(env, /*size_in_bits=*/0,
21117 /*alignment_in_bits=*/0),
21118 decl_base(env, name, locus, mangled_name, vis),
21119 priv_(new priv(nullptr))
21120{
21122}
21123
21124/// Return the hash value of the current IR node.
21125///
21126/// Note that upon the first invocation, this member functions
21127/// computes the hash value and returns it. Subsequent invocations
21128/// just return the hash value that was previously calculated.
21129///
21130/// @return the hash value of the current IR node.
21131hash_t
21133{
21135 return h;
21136}
21137
21138/// Return the size of the typedef.
21139///
21140/// This function looks at the size of the underlying type and ensures
21141/// that it's the same as the size of the typedef.
21142///
21143/// @return the size of the typedef.
21144size_t
21146{
21147 if (!get_underlying_type())
21148 return 0;
21149 size_t s = get_underlying_type()->get_size_in_bits();
21150 if (s != type_base::get_size_in_bits())
21151 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
21153}
21154
21155/// Return the alignment of the typedef.
21156///
21157/// This function looks at the alignment of the underlying type and
21158/// ensures that it's the same as the alignment of the typedef.
21159///
21160/// @return the size of the typedef.
21161size_t
21163{
21164 if (!get_underlying_type())
21165 return 0;
21166 size_t s = get_underlying_type()->get_alignment_in_bits();
21168 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
21170}
21171
21172/// Compares two instances of @ref typedef_decl.
21173///
21174/// If the two intances are different, set a bitfield to give some
21175/// insight about the kind of differences there are.
21176///
21177/// @param l the first artifact of the comparison.
21178///
21179/// @param r the second artifact of the comparison.
21180///
21181/// @param k a pointer to a bitfield that gives information about the
21182/// kind of changes there are between @p l and @p r. This one is set
21183/// iff @p k is non-null and the function returns false.
21184///
21185/// Please note that setting k to a non-null value does have a
21186/// negative performance impact because even if @p l and @p r are not
21187/// equal, the function keeps up the comparison in order to determine
21188/// the different kinds of ways in which they are different.
21189///
21190/// @return true if @p l equals @p r, false otherwise.
21191bool
21193{
21194 bool result = true;
21195
21196 // No need to go further if the types have different names or
21197 // different size / alignment.
21198 if (!(l.decl_base::operator==(r)))
21199 {
21200 result = false;
21201 if (k)
21203 else
21205 }
21206
21208 {
21209 // Changes to the underlying type of a typedef are considered
21210 // local, a bit like for pointers.
21211 result = false;
21212 if (k)
21214 else
21216 }
21217
21218 ABG_RETURN(result);
21219}
21220
21221/// Equality operator
21222///
21223/// @param o the other typedef_decl to test against.
21224bool
21226{
21227 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
21228 if (!other)
21229 return false;
21230 return try_canonical_compare(this, other);
21231}
21232
21233/// Equality operator
21234///
21235/// @param o the other typedef_decl to test against.
21236///
21237/// @return true if the current instance of @ref typedef_decl equals
21238/// @p o.
21239bool
21241{
21242 const decl_base* other = dynamic_cast<const decl_base*>(&o);
21243 if (!other)
21244 return false;
21245 return *this == *other;
21246}
21247
21248/// Build a pretty representation for a typedef_decl.
21249///
21250/// @param internal set to true if the call is intended to get a
21251/// representation of the decl (or type) for the purpose of canonical
21252/// type comparison. This is mainly used in the function
21253/// type_base::get_canonical_type_for().
21254///
21255/// In other words if the argument for this parameter is true then the
21256/// call is meant for internal use (for technical use inside the
21257/// library itself), false otherwise. If you don't know what this is
21258/// for, then set it to false.
21259
21260/// @param qualified_name if true, names emitted in the pretty
21261/// representation are fully qualified.
21262///
21263/// @return a copy of the pretty representation of the current
21264/// instance of typedef_decl.
21265string
21267 bool qualified_name) const
21268{
21269
21270 string result = "typedef ";
21271 if (qualified_name)
21272 result += get_qualified_name(internal);
21273 else
21274 result += get_name();
21275
21276 return result;
21277}
21278
21279/// Getter of the underlying type of the typedef.
21280///
21281/// @return the underlying_type.
21282type_base_sptr
21284{return priv_->underlying_type_.lock();}
21285
21286/// Setter ofthe underlying type of the typedef.
21287///
21288/// @param t the new underlying type of the typedef.
21289void
21291{
21292 priv_->underlying_type_ = t;
21293 set_size_in_bits(t->get_size_in_bits());
21294 set_alignment_in_bits(t->get_alignment_in_bits());
21295}
21296
21297/// Implementation of the virtual "get_qualified_name" method.
21298///
21299/// @param qualified_name the resuling qualified name of the typedef type.
21300///
21301/// @param internal if true, then it means the qualified name is for
21302/// "internal" purposes, meaning mainly for type canonicalization
21303/// purposes.
21304void
21306 bool internal) const
21307{qualified_name = get_qualified_name(internal);}
21308
21309/// Implementation of the virtual "get_qualified_name" method.
21310///
21311/// @param internal if true, then it means the qualified name is for
21312/// "internal" purposes, meaning mainly for type canonicalization
21313/// purposes.
21314///
21315/// @return the qualified name.
21316const interned_string&
21318{
21319 // Note that the qualified name has been already set by
21320 // qualified_name_setter::do_update, which is invoked by
21321 // update_qualified_name. The latter is itself invoked whenever the
21322 // typedef is added to its scope, in scope_decl::add_member_decl.
21323 if (internal)
21324 return decl_base::priv_->internal_qualified_name_;
21325 else
21326 return decl_base::priv_->qualified_name_;
21327}
21328
21329/// This implements the ir_traversable_base::traverse pure virtual
21330/// function.
21331///
21332/// @param v the visitor used on the current instance.
21333///
21334/// @return true if the entire IR node tree got traversed, false
21335/// otherwise.
21336bool
21338{
21339 if (v.type_node_has_been_visited(this))
21340 return true;
21341
21342 if (visiting())
21343 return true;
21344
21345 if (v.visit_begin(this))
21346 {
21347 visiting(true);
21348 if (type_base_sptr t = get_underlying_type())
21349 t->traverse(v);
21350 visiting(false);
21351 }
21352
21353 bool result = v.visit_end(this);
21355 return result;
21356}
21357
21358typedef_decl::~typedef_decl()
21359{}
21360// </typedef_decl definitions>
21361
21362// <var_decl definitions>
21363
21364struct var_decl::priv
21365{
21366 type_base_wptr type_;
21367 type_base* naked_type_;
21368 decl_base::binding binding_;
21369 elf_symbol_sptr symbol_;
21370 interned_string id_;
21371
21372 priv()
21373 : naked_type_(),
21374 binding_(decl_base::BINDING_GLOBAL)
21375 {}
21376
21377 priv(type_base_sptr t,
21379 : type_(t),
21380 naked_type_(t.get()),
21381 binding_(b)
21382 {}
21383
21384 /// Setter of the type of the variable.
21385 ///
21386 /// @param t the new variable type.
21387 void
21388 set_type(type_base_sptr t)
21389 {
21390 type_ = t;
21391 naked_type_ = t.get();
21392 }
21393}; // end struct var_decl::priv
21394
21395/// Constructor of the @ref var_decl type.
21396///
21397/// @param name the name of the variable declaration
21398///
21399/// @param type the type of the variable declaration
21400///
21401/// @param locus the source location where the variable was defined.
21402///
21403/// @param linkage_name the linkage name of the variable.
21404///
21405/// @param vis the visibility of of the variable.
21406///
21407/// @param bind the binding kind of the variable.
21408var_decl::var_decl(const string& name,
21409 type_base_sptr type,
21410 const location& locus,
21411 const string& linkage_name,
21412 visibility vis,
21413 binding bind)
21414 : type_or_decl_base(type->get_environment(),
21415 VAR_DECL | ABSTRACT_DECL_BASE),
21416 decl_base(type->get_environment(), name, locus, linkage_name, vis),
21417 priv_(new priv(type, bind))
21418{
21420}
21421
21422/// Getter of the type of the variable.
21423///
21424/// @return the type of the variable.
21425const type_base_sptr
21427{return priv_->type_.lock();}
21428
21429/// Setter of the type of the variable.
21430///
21431/// @param the new type of the variable.
21432void
21433var_decl::set_type(type_base_sptr& t)
21434{priv_->set_type(t);}
21435
21436/// Getter of the type of the variable.
21437///
21438/// This getter returns a bare pointer, as opposed to a smart pointer.
21439/// It's to be used on performance sensitive code paths identified by
21440/// careful profiling.
21441///
21442/// @return the type of the variable, as a bare pointer.
21443const type_base*
21445{return priv_->naked_type_;}
21446
21447/// Getter of the binding of the variable.
21448///
21449/// @return the biding of the variable.
21452{return priv_->binding_;}
21453
21454/// Setter of the binding of the variable.
21455///
21456/// @param b the new binding value.
21457void
21459{priv_->binding_ = b;}
21460
21461/// Sets the underlying ELF symbol for the current variable.
21462///
21463/// And underlyin$g ELF symbol for the current variable might exist
21464/// only if the corpus that this variable originates from was
21465/// constructed from an ELF binary file.
21466///
21467/// Note that comparing two variables that have underlying ELF symbols
21468/// involves comparing their underlying elf symbols. The decl name
21469/// for the variable thus becomes irrelevant in the comparison.
21470///
21471/// @param sym the new ELF symbol for this variable decl.
21472void
21474{
21475 priv_->symbol_ = sym;
21476 // The variable id cache that depends on the symbol must be
21477 // invalidated because the symbol changed.
21478 priv_->id_ = get_environment().intern("");
21479}
21480
21481/// Gets the the underlying ELF symbol for the current variable,
21482/// that was set using var_decl::set_symbol(). Please read the
21483/// documentation for that member function for more information about
21484/// "underlying ELF symbols".
21485///
21486/// @return sym the underlying ELF symbol for this variable decl, if
21487/// one exists.
21488const elf_symbol_sptr&
21490{return priv_->symbol_;}
21491
21492/// Create a new var_decl that is a clone of the current one.
21493///
21494/// @return the cloned var_decl.
21497{
21499 get_type(),
21500 get_location(),
21503 get_binding()));
21504
21505 v->set_symbol(get_symbol());
21506
21507 if (is_member_decl(*this))
21508 {
21512 get_member_is_static(*this),
21513 get_data_member_offset(*this));
21514 }
21515 else
21517
21518 return v;
21519}
21520/// Setter of the scope of the current var_decl.
21521///
21522/// Note that the decl won't hold a reference on the scope. It's
21523/// rather the scope that holds a reference on its members.
21524///
21525/// @param scope the new scope.
21526void
21527var_decl::set_scope(scope_decl* scope)
21528{
21529 if (!get_context_rel())
21530 set_context_rel(new dm_context_rel(scope));
21531 else
21532 get_context_rel()->set_scope(scope);
21533}
21534
21535/// Compares two instances of @ref var_decl without taking their type
21536/// into account.
21537///
21538/// If the two intances are different modulo their type, set a
21539/// bitfield to give some insight about the kind of differences there
21540/// are.
21541///
21542/// @param l the first artifact of the comparison.
21543///
21544/// @param r the second artifact of the comparison.
21545///
21546/// @param k a pointer to a bitfield that gives information about the
21547/// kind of changes there are between @p l and @p r. This one is set
21548/// iff @p k is non-null and the function returns false.
21549///
21550/// Please note that setting k to a non-null value does have a
21551/// negative performance impact because even if @p l and @p r are not
21552/// equal, the function keeps up the comparison in order to determine
21553/// the different kinds of ways in which they are different.
21554///
21555/// @return true if @p l equals @p r, false otherwise.
21556bool
21558{
21559 bool result = true;
21560
21561 // If there are underlying elf symbols for these variables,
21562 // compare them. And then compare the other parts.
21563 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
21564 if (!!s0 != !!s1)
21565 {
21566 result = false;
21567 if (k)
21569 else
21571 }
21572 else if (s0 && !textually_equals(*s0, *s1, k))
21573 {
21574 result = false;
21575 if (!k)
21577 }
21578 bool symbols_are_equal = (s0 && s1 && result);
21579
21580 if (symbols_are_equal)
21581 {
21582 // The variables have underlying elf symbols that are equal, so
21583 // now, let's compare the decl_base part of the variables w/o
21584 // considering their decl names.
21585 const environment& env = l.get_environment();
21586 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
21587 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
21588 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
21589 bool decl_bases_different = !l.decl_base::operator==(r);
21590 const_cast<var_decl&>(l).set_qualified_name(n1);
21591 const_cast<var_decl&>(r).set_qualified_name(n2);
21592
21593 if (decl_bases_different)
21594 {
21595 result = false;
21596 if (k)
21598 else
21600 }
21601 }
21602 else
21603 if (!l.decl_base::operator==(r))
21604 {
21605 result = false;
21606 if (k)
21608 else
21610 }
21611
21612 const dm_context_rel* c0 =
21613 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
21614 const dm_context_rel* c1 =
21615 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
21616 ABG_ASSERT(c0 && c1);
21617
21618 if (*c0 != *c1)
21619 {
21620 result = false;
21621 if (k)
21623 else
21625 }
21626
21627 ABG_RETURN(result);
21628}
21629
21630/// Compares two instances of @ref var_decl.
21631///
21632/// If the two intances are different, set a bitfield to give some
21633/// insight about the kind of differences there are.
21634///
21635/// @param l the first artifact of the comparison.
21636///
21637/// @param r the second artifact of the comparison.
21638///
21639/// @param k a pointer to a bitfield that gives information about the
21640/// kind of changes there are between @p l and @p r. This one is set
21641/// iff @p k is non-null and the function returns false.
21642///
21643/// Please note that setting k to a non-null value does have a
21644/// negative performance impact because even if @p l and @p r are not
21645/// equal, the function keeps up the comparison in order to determine
21646/// the different kinds of ways in which they are different.
21647///
21648/// @return true if @p l equals @p r, false otherwise.
21649bool
21650equals(const var_decl& l, const var_decl& r, change_kind* k)
21651{
21652 bool result = true;
21653
21654 // First test types of variables. This should be fast because in
21655 // the general case, most types should be canonicalized.
21656 if (*l.get_naked_type() != *r.get_naked_type())
21657 {
21658 result = false;
21659 if (k)
21660 {
21662 r.get_naked_type()))
21663 *k |= (LOCAL_TYPE_CHANGE_KIND);
21664 else
21665 *k |= SUBTYPE_CHANGE_KIND;
21666 }
21667 else
21669 }
21670
21671 result &= var_equals_modulo_types(l, r, k);
21672
21673 ABG_RETURN(result);
21674}
21675
21676/// Comparison operator of @ref var_decl.
21677///
21678/// @param o the instance of @ref var_decl to compare against.
21679///
21680/// @return true iff the current instance of @ref var_decl equals @p o.
21681bool
21683{
21684 const var_decl* other = dynamic_cast<const var_decl*>(&o);
21685 if (!other)
21686 return false;
21687
21688 return equals(*this, *other, 0);
21689}
21690
21691/// Return an ID that tries to uniquely identify the variable inside a
21692/// program or a library.
21693///
21694/// So if the variable has an underlying elf symbol, the ID is the
21695/// concatenation of the symbol name and its version. Otherwise, the
21696/// ID is the linkage name if its non-null. Otherwise, it's the
21697/// pretty representation of the variable.
21698///
21699/// @return the ID.
21702{
21703 if (priv_->id_.empty())
21704 {
21705 string repr = get_name();
21706 string sym_str;
21707 if (elf_symbol_sptr s = get_symbol())
21708 sym_str = s->get_id_string();
21709 else if (!get_linkage_name().empty())
21710 sym_str = get_linkage_name();
21711
21712 const environment& env = get_type()->get_environment();
21713 priv_->id_ = env.intern(repr);
21714 if (!sym_str.empty())
21715 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
21716 }
21717 return priv_->id_;
21718}
21719
21720/// Get the qualified name of a given variable or data member.
21721///
21722///
21723/// Note that if the current instance of @ref var_decl is an anonymous
21724/// data member, then the qualified name is actually the flat
21725/// representation (the definition) of the type of the anonymous data
21726/// member. We chose the flat representation because otherwise, the
21727/// name of an *anonymous* data member is empty, by construction, e.g:
21728///
21729/// struct foo {
21730/// int a;
21731/// union {
21732/// char b;
21733/// char c;
21734/// }; // <---- this data member is anonymous.
21735/// int d;
21736/// }
21737///
21738/// The string returned for the anonymous member here is going to be:
21739///
21740/// "union {char b; char c}"
21741///
21742/// @param internal if true then this is for a purpose to the library,
21743/// otherwise, it's for being displayed to users.
21744///
21745/// @return the resulting qualified name.
21746const interned_string&
21748{
21749 if (is_anonymous_data_member(this)
21750 && decl_base::get_qualified_name().empty())
21751 {
21752 // Display the anonymous data member in a way that makes sense.
21753 string r = get_pretty_representation(internal);
21755 }
21756
21757 return decl_base::get_qualified_name(internal);
21758}
21759
21760/// Build and return the pretty representation of this variable.
21761///
21762/// @param internal set to true if the call is intended to get a
21763/// representation of the decl (or type) for the purpose of canonical
21764/// type comparison. This is mainly used in the function
21765/// type_base::get_canonical_type_for().
21766///
21767/// In other words if the argument for this parameter is true then the
21768/// call is meant for internal use (for technical use inside the
21769/// library itself), false otherwise. If you don't know what this is
21770/// for, then set it to false.
21771///
21772/// @param qualified_name if true, names emitted in the pretty
21773/// representation are fully qualified.
21774///
21775/// @return a copy of the pretty representation of this variable.
21776string
21777var_decl::get_pretty_representation(bool internal, bool qualified_name) const
21778{
21779 string result;
21780
21781 if (is_member_decl(this) && get_member_is_static(this))
21782 result = "static ";
21783
21784 // Detect if the current instance of var_decl is a member of
21785 // an anonymous class or union.
21786 bool member_of_anonymous_class = false;
21787 if (class_or_union* scope = is_at_class_scope(this))
21788 if (scope->get_is_anonymous())
21789 member_of_anonymous_class = true;
21790
21791 type_base_sptr type = get_type();
21792 if (is_array_type(type, /*look_through_qualifiers=*/true)
21793 || is_pointer_type(type, /*look_through_qualifiers=*/true)
21794 || is_reference_type(type, /*look_through_qualifiers=*/true)
21795 || is_ptr_to_mbr_type(type, /*look_through_qualifiers=*/true))
21796 {
21797 string name;
21798 if (member_of_anonymous_class || !qualified_name)
21799 name = get_name();
21800 else
21801 name = get_qualified_name(internal);
21802
21803 if (qualified_type_def_sptr q = is_qualified_type(type))
21804 {
21805 string quals_repr =
21806 get_string_representation_of_cv_quals(q->get_cv_quals());
21807 if (!quals_repr.empty())
21808 name = quals_repr + " " + name;
21809 type = peel_qualified_type(type);
21810 }
21811
21812 name = string(" ") + name;
21813 if (array_type_def_sptr t = is_array_type(type))
21814 result += array_declaration_name(t, name, qualified_name, internal);
21815 else if (pointer_type_def_sptr t = is_pointer_type(type))
21816 result += pointer_declaration_name(t, name, qualified_name, internal);
21817 else if (reference_type_def_sptr t = is_reference_type(type))
21818 result += pointer_declaration_name(t, name, qualified_name, internal);
21819 else if (ptr_to_mbr_type_sptr t = is_ptr_to_mbr_type(type))
21820 result += ptr_to_mbr_declaration_name(t, name,
21821 qualified_name,
21822 internal);
21823 }
21824 else
21825 {
21826 if (/*The current var_decl is to be used as an anonymous data
21827 member. */
21828 get_name().empty())
21829 {
21830 // Display the anonymous data member in a way that
21831 // makes sense.
21832 result +=
21835 "", /*one_line=*/true, internal);
21836 }
21837 else if (data_member_has_anonymous_type(this))
21838 {
21841 "", /*one_line=*/true, internal);
21842 result += " ";
21843 if (!internal
21844 && (member_of_anonymous_class || !qualified_name))
21845 // It doesn't make sense to name the member of an
21846 // anonymous class or union like:
21847 // "__anonymous__::data_member_name". So let's just use
21848 // its non-qualified name.
21849 result += get_name();
21850 else
21851 result += get_qualified_name(internal);
21852 }
21853 else
21854 {
21855 result +=
21857 + " ";
21858
21859 if (!internal
21860 && (member_of_anonymous_class || !qualified_name))
21861 // It doesn't make sense to name the member of an
21862 // anonymous class or union like:
21863 // "__anonymous__::data_member_name". So let's just use
21864 // its non-qualified name.
21865 result += get_name();
21866 else
21867 result += get_qualified_name(internal);
21868 }
21869 }
21870 return result;
21871}
21872
21873/// Get a name that is valid even for an anonymous data member.
21874///
21875/// If the current @ref var_decl is an anonymous data member, then
21876/// return its pretty representation. As of now, that pretty
21877/// representation is actually its flat representation as returned by
21878/// get_class_or_union_flat_representation().
21879///
21880/// Otherwise, just return the name of the current @ref var_decl.
21881///
21882/// @param qualified if true, return the qualified name. This doesn't
21883/// have an effet if the current @ref var_decl represents an anonymous
21884/// data member.
21885string
21887{
21888 string name;
21889 if (is_anonymous_data_member(this))
21890 // This function is used in the comparison engine to determine
21891 // which anonymous data member was deleted. So it's not involved
21892 // in type comparison or canonicalization. We don't want to use
21893 // the 'internal' version of the pretty presentation.
21894 name = get_pretty_representation(/*internal=*/false, qualified);
21895 else
21896 name = get_name();
21897
21898 return name;
21899}
21900
21901/// This implements the ir_traversable_base::traverse pure virtual
21902/// function.
21903///
21904/// @param v the visitor used on the current instance.
21905///
21906/// @return true if the entire IR node tree got traversed, false
21907/// otherwise.
21908bool
21910{
21911 if (visiting())
21912 return true;
21913
21914 if (v.visit_begin(this))
21915 {
21916 visiting(true);
21917 if (type_base_sptr t = get_type())
21918 t->traverse(v);
21919 visiting(false);
21920 }
21921 return v.visit_end(this);
21922}
21923
21924var_decl::~var_decl()
21925{}
21926
21927// </var_decl definitions>
21928
21929/// This function is automatically invoked whenever an instance of
21930/// this type is canonicalized.
21931///
21932/// It's an overload of the virtual type_base::on_canonical_type_set.
21933///
21934/// We put here what is thus meant to be executed only at the point of
21935/// type canonicalization.
21936void
21938{
21939 priv_->cached_name_.clear();
21940 priv_->internal_cached_name_.clear();
21941}
21942
21943/// The most straightforward constructor for the function_type class.
21944///
21945/// @param return_type the return type of the function type.
21946///
21947/// @param parms the list of parameters of the function type.
21948/// Stricto sensu, we just need a list of types; we are using a list
21949/// of parameters (where each parameter also carries the name of the
21950/// parameter and its source location) to try and provide better
21951/// diagnostics whenever it makes sense. If it appears that this
21952/// wasts too many resources, we can fall back to taking just a
21953/// vector of types here.
21954///
21955/// @param size_in_bits the size of this type, in bits.
21956///
21957/// @param alignment_in_bits the alignment of this type, in bits.
21958///
21959/// @param size_in_bits the size of this type.
21960function_type::function_type(type_base_sptr return_type,
21961 const parameters& parms,
21962 size_t size_in_bits,
21963 size_t alignment_in_bits)
21964 : type_or_decl_base(return_type->get_environment(),
21965 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21966 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21967 priv_(new priv(parms, return_type))
21968{
21970
21971 for (parameters::size_type i = 0, j = 1;
21972 i < priv_->parms_.size();
21973 ++i, ++j)
21974 {
21975 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21976 // If the first parameter is artificial, then it certainly
21977 // means that this is a member function, and the first
21978 // parameter is the implicit this pointer. In that case, set
21979 // the index of that implicit parameter to zero. Otherwise,
21980 // the index of the first parameter starts at one.
21981 j = 0;
21982 priv_->parms_[i]->set_index(j);
21983 }
21984}
21985
21986/// A constructor for a function_type that takes no parameters.
21987///
21988/// @param return_type the return type of this function_type.
21989///
21990/// @param size_in_bits the size of this type, in bits.
21991///
21992/// @param alignment_in_bits the alignment of this type, in bits.
21993function_type::function_type(type_base_sptr return_type,
21994 size_t size_in_bits, size_t alignment_in_bits)
21995 : type_or_decl_base(return_type->get_environment(),
21996 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21997 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21998 priv_(new priv(return_type))
21999{
22001}
22002
22003/// A constructor for a function_type that takes no parameter and
22004/// that has no return_type yet. These missing parts can (and must)
22005/// be added later.
22006///
22007/// @param env the environment we are operating from.
22008///
22009/// @param size_in_bits the size of this type, in bits.
22010///
22011/// @param alignment_in_bits the alignment of this type, in bits.
22012function_type::function_type(const environment& env,
22013 size_t size_in_bits,
22014 size_t alignment_in_bits)
22015 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
22016 type_base(env, size_in_bits, alignment_in_bits),
22017 priv_(new priv)
22018{
22020}
22021
22022/// Return the hash value of the current IR node.
22023///
22024/// Note that upon the first invocation, this member functions
22025/// computes the hash value and returns it. Subsequent invocations
22026/// just return the hash value that was previously calculated.
22027///
22028/// @return the hash value of the current IR node.
22029hash_t
22031{
22033 return h;
22034}
22035
22036/// Getter for the return type of the current instance of @ref
22037/// function_type.
22038///
22039/// @return the return type.
22040type_base_sptr
22042{return priv_->return_type_.lock();}
22043
22044/// Setter of the return type of the current instance of @ref
22045/// function_type.
22046///
22047/// @param t the new return type to set.
22048void
22050{priv_->return_type_ = t;}
22051
22052/// Getter for the set of parameters of the current intance of @ref
22053/// function_type.
22054///
22055/// @return the parameters of the current instance of @ref
22056/// function_type.
22059{return priv_->parms_;}
22060
22061/// Get the Ith parameter of the vector of parameters of the current
22062/// instance of @ref function_type.
22063///
22064/// Note that the first parameter is at index 0. That parameter is
22065/// the first parameter that comes after the possible implicit "this"
22066/// parameter, when the current instance @ref function_type is for a
22067/// member function. Otherwise, if the current instance of @ref
22068/// function_type is for a non-member function, the parameter at index
22069/// 0 is the first parameter of the function.
22070///
22071///
22072/// @param i the index of the parameter to return. If i is greater
22073/// than the index of the last parameter, then this function returns
22074/// an empty parameter (smart) pointer.
22075///
22076/// @return the @p i th parameter that is not implicit.
22079{
22080 parameter_sptr result;
22081 if (dynamic_cast<const method_type*>(this))
22082 {
22083 if (i + 1 < get_parameters().size())
22084 result = get_parameters()[i + 1];
22085 }
22086 else
22087 {
22088 if (i < get_parameters().size())
22089 result = get_parameters()[i];
22090 }
22091 return result;
22092}
22093
22094/// Setter for the parameters of the current instance of @ref
22095/// function_type.
22096///
22097/// @param p the new vector of parameters to set.
22098void
22100{
22101 priv_->parms_ = p;
22102 for (parameters::size_type i = 0, j = 1;
22103 i < priv_->parms_.size();
22104 ++i, ++j)
22105 {
22106 if (i == 0 && priv_->parms_[i]->get_is_artificial())
22107 // If the first parameter is artificial, then it certainly
22108 // means that this is a member function, and the first
22109 // parameter is the implicit this pointer. In that case, set
22110 // the index of that implicit parameter to zero. Otherwise,
22111 // the index of the first parameter starts at one.
22112 j = 0;
22113 priv_->parms_[i]->set_index(j);
22114 }
22115}
22116
22117/// Append a new parameter to the vector of parameters of the current
22118/// instance of @ref function_type.
22119///
22120/// @param parm the parameter to append.
22121void
22123{
22124 parm->set_index(priv_->parms_.size());
22125 priv_->parms_.push_back(parm);
22126}
22127
22128/// Test if the current instance of @ref function_type is for a
22129/// variadic function.
22130///
22131/// A variadic function is a function that takes a variable number of
22132/// arguments.
22133///
22134/// @return true iff the current instance of @ref function_type is for
22135/// a variadic function.
22136bool
22138{
22139 return (!priv_->parms_.empty()
22140 && priv_->parms_.back()->get_variadic_marker());
22141}
22142
22143/// Compare two function types.
22144///
22145/// In case these function types are actually method types, this
22146/// function avoids comparing two parameters (of the function types)
22147/// if the types of the parameters are actually the types of the
22148/// classes of the method types. This prevents infinite recursion
22149/// during the comparison of two classes that are structurally
22150/// identical.
22151///
22152/// This is a subroutine of the equality operator of function_type.
22153///
22154/// @param lhs the first function type to consider
22155///
22156/// @param rhs the second function type to consider
22157///
22158/// @param k a pointer to a bitfield set by the function to give
22159/// information about the kind of changes carried by @p lhs and @p
22160/// rhs. It is set iff @p k is non-null and the function returns
22161/// false.
22162///
22163/// Please note that setting k to a non-null value does have a
22164/// negative performance impact because even if @p l and @p r are not
22165/// equal, the function keeps up the comparison in order to determine
22166/// the different kinds of ways in which they are different.
22167///
22168///@return true if lhs == rhs, false otherwise.
22169bool
22171{
22172#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
22173
22175
22176 {
22177 // First of all, let's see if these two function types haven't
22178 // already been compared. If so, and if the result of the
22179 // comparison has been cached, let's just re-use it, rather than
22180 // comparing them all over again.
22181 bool cached_result = false;
22182 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
22183 cached_result))
22184 ABG_RETURN(cached_result);
22185 }
22186
22188
22189 bool result = true;
22190
22191 if (!l.type_base::operator==(r))
22192 {
22193 result = false;
22194 if (k)
22196 else
22197 RETURN(result);
22198 }
22199
22200 class_or_union* l_class = 0, *r_class = 0;
22201 if (const method_type* m = dynamic_cast<const method_type*>(&l))
22202 l_class = m->get_class_type().get();
22203
22204 if (const method_type* m = dynamic_cast<const method_type*>(&r))
22205 r_class = m->get_class_type().get();
22206
22207 // Compare the names of the class of the method
22208
22209 if (!!l_class != !!r_class)
22210 {
22211 result = false;
22212 if (k)
22214 else
22215 RETURN(result);
22216 }
22217 else if (l_class
22218 && (l_class->get_qualified_name()
22219 != r_class->get_qualified_name()))
22220 {
22221 result = false;
22222 if (k)
22224 else
22225 RETURN(result);
22226 }
22227
22228 // Then compare the return type; Beware if it's t's a class type
22229 // that is the same as the method class name; we can recurse for
22230 // ever in that case.
22231
22232 decl_base* l_return_type_decl =
22234 decl_base* r_return_type_decl =
22236 bool compare_result_types = true;
22237 string l_rt_name = l_return_type_decl
22238 ? l_return_type_decl->get_qualified_name()
22239 : string();
22240 string r_rt_name = r_return_type_decl
22241 ? r_return_type_decl->get_qualified_name()
22242 : string();
22243
22244 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
22245 ||
22246 (r_class && (r_class->get_qualified_name() == r_rt_name)))
22247 compare_result_types = false;
22248
22249 if (compare_result_types)
22250 {
22251 // Let's not consider typedefs when comparing return types to
22252 // avoid spurious changes.
22253 //
22254 // TODO: We should also do this for parameter types, or rather,
22255 // we should teach the equality operators in the IR, at some
22256 // point, to peel typedefs off.
22257 if (l.get_return_type() != r.get_return_type())
22258 {
22259 result = false;
22260 if (k)
22261 {
22263 r.get_return_type()))
22265 else
22266 *k |= SUBTYPE_CHANGE_KIND;
22267 }
22268 else
22269 RETURN(result);
22270 }
22271 }
22272 else
22273 if (l_rt_name != r_rt_name)
22274 {
22275 result = false;
22276 if (k)
22277 *k |= SUBTYPE_CHANGE_KIND;
22278 else
22279 RETURN(result);
22280 }
22281
22282 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
22283 for (i = l.get_first_parm(), j = r.get_first_parm();
22284 i != l.get_parameters().end() && j != r.get_parameters().end();
22285 ++i, ++j)
22286 {
22287 if (**i != **j)
22288 {
22289 result = false;
22290 if (k)
22291 {
22292 if (!types_have_similar_structure((*i)->get_type(),
22293 (*j)->get_type()))
22295 else
22296 *k |= SUBTYPE_CHANGE_KIND;
22297 }
22298 else
22299 RETURN(result);
22300 }
22301 }
22302
22303 if ((i != l.get_parameters().end()
22304 || j != r.get_parameters().end()))
22305 {
22306 result = false;
22307 if (k)
22309 else
22310 RETURN(result);
22311 }
22312
22313 RETURN(result);
22314#undef RETURN
22315}
22316
22317/// Get the first parameter of the function.
22318///
22319/// If the function is a non-static member function, the parameter
22320/// returned is the first one following the implicit 'this' parameter.
22321///
22322/// @return the first non implicit parameter of the function.
22323function_type::parameters::const_iterator
22325{
22326 if (get_parameters().empty())
22327 return get_parameters().end();
22328
22329 bool is_method = dynamic_cast<const method_type*>(this);
22330
22331 parameters::const_iterator i = get_parameters().begin();
22332
22333 if (is_method && (*i)->get_is_artificial())
22334 ++i;
22335
22336 return i;
22337}
22338
22339/// Get the first parameter of the function.
22340///
22341/// Note that if the function is a non-static member function, the
22342/// parameter returned is the implicit 'this' parameter.
22343///
22344/// @return the first parameter of the function.
22345function_type::parameters::const_iterator
22347{return get_parameters().begin();}
22348
22349/// Get the name of the current @ref function_type.
22350///
22351/// The name is retrieved from a cache. If the cache is empty, this
22352/// function computes the name of the type, stores it in the cache and
22353/// returns it. Subsequent invocation of the function are going to
22354/// just hit the cache.
22355///
22356/// Note that if the type is *NOT* canonicalized then function type
22357/// name is never cached.
22358///
22359/// @param internal if true then it means the function type name is
22360/// going to be used for purposes that are internal to libabigail
22361/// itself. If you don't know what this is then you probably should
22362/// set this parameter to 'false'.
22363///
22364/// @return the name of the function type.
22365const interned_string&
22367{
22368 if (internal)
22369 {
22371 {
22372 if (priv_->internal_cached_name_.empty())
22373 priv_->internal_cached_name_ =
22374 get_function_type_name(this, /*internal=*/true);
22375 return priv_->internal_cached_name_;
22376 }
22377 else
22378 {
22379 priv_->temp_internal_cached_name_ =
22380 get_function_type_name(this, /*internal=*/true);
22381 return priv_->temp_internal_cached_name_;
22382 }
22383 }
22384 else
22385 {
22387 {
22388 if (priv_->cached_name_.empty())
22389 priv_->cached_name_ =
22390 get_function_type_name(this, /*internal=*/false);
22391 return priv_->cached_name_;
22392 }
22393 else
22394 {
22395 priv_->cached_name_ =
22396 get_function_type_name(this, /*internal=*/false);
22397 return priv_->cached_name_;
22398 }
22399 }
22400}
22401
22402/// Equality operator for function_type.
22403///
22404/// @param o the other function_type to compare against.
22405///
22406/// @return true iff the two function_type are equal.
22407bool
22409{
22410 const function_type* o = dynamic_cast<const function_type*>(&other);
22411 if (!o)
22412 return false;
22413 return try_canonical_compare(this, o);
22414}
22415
22416/// Return a copy of the pretty representation of the current @ref
22417/// function_type.
22418///
22419/// @param internal set to true if the call is intended to get a
22420/// representation of the decl (or type) for the purpose of canonical
22421/// type comparison. This is mainly used in the function
22422/// type_base::get_canonical_type_for().
22423///
22424/// In other words if the argument for this parameter is true then the
22425/// call is meant for internal use (for technical use inside the
22426/// library itself), false otherwise. If you don't know what this is
22427/// for, then set it to false.
22428///
22429/// @return a copy of the pretty representation of the current @ref
22430/// function_type.
22431string
22433 bool /*qualified_name*/) const
22434{return ir::get_pretty_representation(this, internal);}
22435
22436/// Traverses an instance of @ref function_type, visiting all the
22437/// sub-types and decls that it might contain.
22438///
22439/// @param v the visitor that is used to visit every IR sub-node of
22440/// the current node.
22441///
22442/// @return true if either
22443/// - all the children nodes of the current IR node were traversed
22444/// and the calling code should keep going with the traversing.
22445/// - or the current IR node is already being traversed.
22446/// Otherwise, returning false means that the calling code should not
22447/// keep traversing the tree.
22448bool
22450{
22451 // TODO: should we allow the walker to avoid visiting function type
22452 // twice? I think that if we do, then ir_node_visitor needs an
22453 // option to specifically disallow this feature for function types.
22454
22455 if (visiting())
22456 return true;
22457
22458 if (v.visit_begin(this))
22459 {
22460 visiting(true);
22461 bool keep_going = true;
22462
22463 if (type_base_sptr t = get_return_type())
22464 {
22465 if (!t->traverse(v))
22466 keep_going = false;
22467 }
22468
22469 if (keep_going)
22470 for (parameters::const_iterator i = get_parameters().begin();
22471 i != get_parameters().end();
22472 ++i)
22473 if (type_base_sptr parm_type = (*i)->get_type())
22474 if (!parm_type->traverse(v))
22475 break;
22476
22477 visiting(false);
22478 }
22479 return v.visit_end(this);
22480}
22481
22482function_type::~function_type()
22483{}
22484// </function_type>
22485
22486// <method_type>
22487
22488struct method_type::priv
22489{
22490 class_or_union_wptr class_type_;
22491 bool is_const;
22492
22493 priv()
22494 : is_const()
22495 {}
22496}; // end struct method_type::priv
22497
22498/// Constructor for instances of method_type.
22499///
22500/// Instances of method_decl must be of type method_type.
22501///
22502/// @param return_type the type of the return value of the method.
22503///
22504/// @param class_type the base type of the method type. That is, the
22505/// type of the class the method belongs to.
22506///
22507/// @param p the vector of the parameters of the method.
22508///
22509/// @param is_const whether this method type is for a const method.
22510/// Note that const-ness is a property of the method *type* and of the
22511/// relationship between a method *declaration* and its scope.
22512///
22513/// @param size_in_bits the size of an instance of method_type,
22514/// expressed in bits.
22515///
22516/// @param alignment_in_bits the alignment of an instance of
22517/// method_type, expressed in bits.
22518method_type::method_type (type_base_sptr return_type,
22519 class_or_union_sptr class_type,
22520 const std::vector<function_decl::parameter_sptr>& p,
22521 bool is_const,
22522 size_t size_in_bits,
22523 size_t alignment_in_bits)
22524 : type_or_decl_base(class_type->get_environment(),
22525 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22526 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22527 function_type(return_type, p, size_in_bits, alignment_in_bits),
22528 priv_(new priv)
22529{
22531 set_class_type(class_type);
22532 set_is_const(is_const);
22533}
22534
22535/// Constructor of instances of method_type.
22536///
22537///Instances of method_decl must be of type method_type.
22538///
22539/// @param return_type the type of the return value of the method.
22540///
22541/// @param class_type the type of the class the method belongs to.
22542/// The actual (dynamic) type of class_type must be a pointer
22543/// class_type. We are setting it to pointer to type_base here to
22544/// help client code that is compiled without rtti and thus cannot
22545/// perform dynamic casts.
22546///
22547/// @param p the vector of the parameters of the method type.
22548///
22549/// @param is_const whether this method type is for a const method.
22550/// Note that const-ness is a property of the method *type* and of the
22551/// relationship between a method *declaration* and its scope.
22552///
22553/// @param size_in_bits the size of an instance of method_type,
22554/// expressed in bits.
22555///
22556/// @param alignment_in_bits the alignment of an instance of
22557/// method_type, expressed in bits.
22558method_type::method_type(type_base_sptr return_type,
22559 type_base_sptr class_type,
22560 const std::vector<function_decl::parameter_sptr>& p,
22561 bool is_const,
22562 size_t size_in_bits,
22563 size_t alignment_in_bits)
22564 : type_or_decl_base(class_type->get_environment(),
22565 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22566 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22567 function_type(return_type, p, size_in_bits, alignment_in_bits),
22568 priv_(new priv)
22569{
22571 set_class_type(is_class_type(class_type));
22572 set_is_const(is_const);
22573}
22574
22575/// Constructor of the qualified_type_def
22576///
22577/// @param env the environment we are operating from.
22578///
22579/// @param size_in_bits the size of the type, expressed in bits.
22580///
22581/// @param alignment_in_bits the alignment of the type, expressed in bits
22582method_type::method_type(const environment& env,
22583 size_t size_in_bits,
22584 size_t alignment_in_bits)
22585 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22586 type_base(env, size_in_bits, alignment_in_bits),
22587 function_type(env, size_in_bits, alignment_in_bits),
22588 priv_(new priv)
22589{
22591}
22592
22593/// Constructor of instances of method_type.
22594///
22595/// When constructed with this constructor, and instane of method_type
22596/// must set a return type using method_type::set_return_type
22597///
22598/// @param class_typ the base type of the method type. That is, the
22599/// type of the class (or union) the method belongs to.
22600///
22601/// @param size_in_bits the size of an instance of method_type,
22602/// expressed in bits.
22603///
22604/// @param alignment_in_bits the alignment of an instance of
22605/// method_type, expressed in bits.
22606method_type::method_type(class_or_union_sptr class_type,
22607 bool is_const,
22608 size_t size_in_bits,
22609 size_t alignment_in_bits)
22610 : type_or_decl_base(class_type->get_environment(),
22611 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22612 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22613 function_type(class_type->get_environment(),
22614 size_in_bits,
22615 alignment_in_bits),
22616 priv_(new priv)
22617{
22619 set_class_type(class_type);
22620 set_is_const(is_const);
22621}
22622
22623/// Return the hash value of the current IR node.
22624///
22625/// Note that upon the first invocation, this member functions
22626/// computes the hash value and returns it. Subsequent invocations
22627/// just return the hash value that was previously calculated.
22628///
22629/// @return the hash value of the current IR node.
22630hash_t
22632{
22634 return h;
22635}
22636
22637/// Get the class type this method belongs to.
22638///
22639/// @return the class type.
22640class_or_union_sptr
22642{return class_or_union_sptr(priv_->class_type_);}
22643
22644/// Sets the class type of the current instance of method_type.
22645///
22646/// The class type is the type of the class the method belongs to.
22647///
22648/// @param t the new class type to set.
22649void
22650method_type::set_class_type(const class_or_union_sptr& t)
22651{
22652 if (!t)
22653 return;
22654
22655 priv_->class_type_ = t;
22656}
22657
22658/// Return a copy of the pretty representation of the current @ref
22659/// method_type.
22660///
22661/// @param internal set to true if the call is intended to get a
22662/// representation of the decl (or type) for the purpose of canonical
22663/// type comparison. This is mainly used in the function
22664/// type_base::get_canonical_type_for().
22665///
22666/// In other words if the argument for this parameter is true then the
22667/// call is meant for internal use (for technical use inside the
22668/// library itself), false otherwise. If you don't know what this is
22669/// for, then set it to false.
22670///
22671/// @return a copy of the pretty representation of the current @ref
22672/// method_type.
22673string
22675 bool /*qualified_name*/) const
22676{return ir::get_pretty_representation(*this, internal);}
22677
22678/// Setter of the "is-const" property of @ref method_type.
22679///
22680/// @param the new value of the "is-const" property.
22681void
22683{priv_->is_const = f;}
22684
22685/// Getter of the "is-const" property of @ref method_type.
22686///
22687/// @return true iff the "is-const" property was set.
22688bool
22690{return priv_->is_const;}
22691
22692/// Test if the current method type is for a static method or not.
22693///
22694/// @return true iff the current method_type denotes a the type of a
22695/// static method.
22696bool
22698{
22699 // Let's see if the first parameter is artificial and is a pointer
22700 // to an instance of the same class type as the current class.
22702 if (!get_parameters().empty())
22703 first_parm = get_parameters()[0];
22704 if (!first_parm)
22705 return true;
22706 if (!first_parm->get_is_artificial())
22707 return true;
22708
22709 type_base_sptr this_ptr_type = first_parm->get_type();
22710 // Sometimes, the type of the "this" pointer is "const class_type*
22711 // const". Meaning that the "this pointer" itself is const
22712 // qualified. So let's get the underlying non-qualified pointer.
22713 this_ptr_type = peel_qualified_type(this_ptr_type);
22714 if (!is_pointer_type(this_ptr_type))
22715 return true;
22716
22717 type_base_sptr candidate_class_type =
22718 is_pointer_type(this_ptr_type)->get_pointed_to_type();
22719 candidate_class_type = peel_qualified_type(candidate_class_type);
22720 if (is_class_type(candidate_class_type)
22721 && get_type_name(candidate_class_type) == get_type_name(get_class_type()))
22722 // At this point, we are sure we are looking at a *non-static*
22723 // method.
22724 return false;
22725
22726 return true;
22727}
22728
22729/// The destructor of method_type
22732
22733// </method_type>
22734
22735// <function_decl definitions>
22736
22737struct function_decl::priv
22738{
22739 bool declared_inline_;
22740 decl_base::binding binding_;
22741 function_type_wptr type_;
22742 function_type* naked_type_;
22743 elf_symbol_sptr symbol_;
22744 interned_string id_;
22745
22746 priv()
22747 : declared_inline_(false),
22748 binding_(decl_base::BINDING_GLOBAL),
22749 naked_type_()
22750 {}
22751
22752 priv(function_type_sptr t,
22753 bool declared_inline,
22755 : declared_inline_(declared_inline),
22756 binding_(binding),
22757 type_(t),
22758 naked_type_(t.get())
22759 {}
22760
22761 priv(function_type_sptr t,
22762 bool declared_inline,
22765 : declared_inline_(declared_inline),
22766 binding_(binding),
22767 type_(t),
22768 naked_type_(t.get()),
22769 symbol_(s)
22770 {}
22771}; // end sruct function_decl::priv
22772
22773/// Constructor of the @ref function_decl.
22774///
22775/// @param name the name of the function.
22776///
22777/// @param function_type the type of the function.
22778///
22779/// @param declared_inline wether the function is declared inline.
22780///
22781/// @param locus the source location of the function.
22782///
22783/// @param mangled_name the linkage name of the function.
22784///
22785/// @param vis the visibility of the function.
22786///
22787/// @param bind the binding of the function.
22790 bool declared_inline,
22791 const location& locus,
22792 const string& mangled_name,
22793 visibility vis,
22794 binding bind)
22795 : type_or_decl_base(function_type->get_environment(),
22796 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22797 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
22798 priv_(new priv(function_type, declared_inline, bind))
22799{
22801}
22802
22803/// Constructor of the function_decl type.
22804///
22805/// This flavour of constructor is for when the pointer to the
22806/// instance of function_type that the client code has is presented as
22807/// a pointer to type_base. In that case, this constructor saves the
22808/// client code from doing a dynamic_cast to get the function_type
22809/// pointer.
22810///
22811/// @param name the name of the function declaration.
22812///
22813/// @param fn_type the type of the function declaration. The dynamic
22814/// type of this parameter should be 'pointer to function_type'
22815///
22816/// @param declared_inline whether this function was declared inline
22817///
22818/// @param locus the source location of the function declaration.
22819///
22820/// @param linkage_name the mangled name of the function declaration.
22821///
22822/// @param vis the visibility of the function declaration.
22823///
22824/// @param bind the kind of the binding of the function
22825/// declaration.
22827 type_base_sptr fn_type,
22828 bool declared_inline,
22829 const location& locus,
22830 const string& linkage_name,
22831 visibility vis,
22832 binding bind)
22833 : type_or_decl_base(fn_type->get_environment(),
22834 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22835 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
22836 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
22837 declared_inline,
22838 bind))
22839{
22841}
22842
22843/// Get the pretty representation of the current instance of @ref function_decl.
22844///
22845/// @param internal set to true if the call is intended to get a
22846/// representation of the decl (or type) for the purpose of canonical
22847/// type comparison. This is mainly used in the function
22848/// type_base::get_canonical_type_for().
22849///
22850/// In other words if the argument for this parameter is true then the
22851/// call is meant for internal use (for technical use inside the
22852/// library itself), false otherwise. If you don't know what this is
22853/// for, then set it to false.
22854///
22855/// @return the pretty representation for a function.
22856string
22858 bool qualified_name) const
22859{
22860 const method_decl* mem_fn =
22861 dynamic_cast<const method_decl*>(this);
22862
22863 string fn_prefix = mem_fn ? "method ": "function ";
22864 string result;
22865
22866 if (mem_fn
22867 && is_member_function(mem_fn)
22869 fn_prefix += "virtual ";
22870
22871 decl_base_sptr return_type;
22872 if ((mem_fn
22873 && is_member_function(mem_fn)
22874 && (get_member_function_is_dtor(*mem_fn)
22875 || get_member_function_is_ctor(*mem_fn))))
22876 /*cdtors do not have return types. */;
22877 else
22878 return_type = mem_fn
22879 ? get_type_declaration(mem_fn->get_type()->get_return_type())
22881
22882 result = get_pretty_representation_of_declarator(internal);
22883 if (return_type)
22884 {
22885 if (is_npaf_type(is_type(return_type))
22886 || !(is_pointer_to_function_type(is_type(return_type))
22887 || is_pointer_to_array_type(is_type(return_type))))
22888 result = get_type_name(is_type(return_type).get(), qualified_name,
22889 internal) + " " + result;
22890 else if (pointer_type_def_sptr p =
22892 result = add_outer_pointer_to_fn_type_expr(p, result,
22893 /*qualified=*/true,
22894 internal);
22895 else if(pointer_type_def_sptr p =
22896 is_pointer_to_array_type(is_type(return_type)))
22897 result = add_outer_pointer_to_array_type_expr(p, result,
22898 qualified_name,
22899 internal);
22900 else
22902 }
22903
22904 return fn_prefix + result;
22905}
22906
22907/// Compute and return the pretty representation for the part of the
22908/// function declaration that starts at the declarator. That is, the
22909/// return type and the other specifiers of the beginning of the
22910/// function's declaration ar omitted.
22911///
22912/// @param internal set to true if the call is intended to get a
22913/// representation of the decl (or type) for the purpose of canonical
22914/// type comparison. This is mainly used in the function
22915/// type_base::get_canonical_type_for().
22916///
22917/// In other words if the argument for this parameter is true then the
22918/// call is meant for internal use (for technical use inside the
22919/// library itself), false otherwise. If you don't know what this is
22920/// for, then set it to false.
22921///
22922/// @return the pretty representation for the part of the function
22923/// declaration that starts at the declarator.
22924string
22926{
22927 const method_decl* mem_fn =
22928 dynamic_cast<const method_decl*>(this);
22929
22930 string result;
22931
22932 if (mem_fn)
22933 {
22934 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
22935 + "::" + mem_fn->get_name();
22936 }
22937 else
22938 result += get_qualified_name();
22939
22940 std::ostringstream fn_parms;
22941 stream_pretty_representation_of_fn_parms(*get_type(),
22942 fn_parms,
22943 /*qualified=*/true,
22944 internal);
22945 result += fn_parms.str();
22946
22947 if (mem_fn
22948 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
22949 || is_method_type(mem_fn->get_type())->get_is_const()))
22950 result += " const";
22951
22952 return result;
22953}
22954
22955/// Getter for the first non-implicit parameter of a function decl.
22956///
22957/// If the function is a non-static member function, the parameter
22958/// returned is the first one following the implicit 'this' parameter.
22959///
22960/// @return the first non implicit parm.
22961function_decl::parameters::const_iterator
22963{
22964 if (get_parameters().empty())
22965 return get_parameters().end();
22966
22967 bool is_method = dynamic_cast<const method_decl*>(this);
22968
22969 parameters::const_iterator i = get_parameters().begin();
22970 if (is_method)
22971 ++i;
22972
22973 return i;
22974}
22975
22976/// Return the type of the current instance of @ref function_decl.
22977///
22978/// It's either a function_type or method_type.
22979/// @return the type of the current instance of @ref function_decl.
22980const shared_ptr<function_type>
22982{return priv_->type_.lock();}
22983
22984/// Fast getter of the type of the current instance of @ref function_decl.
22985///
22986/// Note that this function returns the underlying pointer managed by
22987/// the smart pointer returned by function_decl::get_type(). It's
22988/// faster than function_decl::get_type(). This getter is to be used
22989/// in code paths that are proven to be performance hot spots;
22990/// especially (for instance) when comparing function types. Those
22991/// are compared extremely frequently when libabigail is used to
22992/// handle huge binaries with a lot of functions.
22993///
22994/// @return the type of the current instance of @ref function_decl.
22995const function_type*
22997{return priv_->naked_type_;}
22998
22999void
23000function_decl::set_type(const function_type_sptr& fn_type)
23001{
23002 priv_->type_ = fn_type;
23003 priv_->naked_type_ = fn_type.get();
23004}
23005
23006/// This sets the underlying ELF symbol for the current function decl.
23007///
23008/// And underlyin$g ELF symbol for the current function decl might
23009/// exist only if the corpus that this function decl originates from
23010/// was constructed from an ELF binary file.
23011///
23012/// Note that comparing two function decls that have underlying ELF
23013/// symbols involves comparing their underlying elf symbols. The decl
23014/// name for the function thus becomes irrelevant in the comparison.
23015///
23016/// @param sym the new ELF symbol for this function decl.
23017void
23019{
23020 priv_->symbol_ = sym;
23021 // The function id cache that depends on the symbol must be
23022 // invalidated because the symbol changed.
23023 priv_->id_ = get_environment().intern("");
23024}
23025
23026/// Gets the the underlying ELF symbol for the current variable,
23027/// that was set using function_decl::set_symbol(). Please read the
23028/// documentation for that member function for more information about
23029/// "underlying ELF symbols".
23030///
23031/// @return sym the underlying ELF symbol for this function decl, if
23032/// one exists.
23033const elf_symbol_sptr&
23035{return priv_->symbol_;}
23036
23037/// Test if the function was declared inline.
23038///
23039/// @return true iff the function was declared inline.
23040bool
23042{return priv_->declared_inline_;}
23043
23044/// Set the property of the function being declared inline.
23045///
23046/// @param value true iff the function was declared inline.
23047void
23049{priv_->declared_inline_ = value;}
23050
23052function_decl::get_binding() const
23053{return priv_->binding_;}
23054
23055/// @return the return type of the current instance of function_decl.
23056const shared_ptr<type_base>
23058{return get_type()->get_return_type();}
23059
23060/// @return the parameters of the function.
23061const std::vector<shared_ptr<function_decl::parameter> >&
23063{return get_type()->get_parameters();}
23064
23065/// Append a parameter to the type of this function.
23066///
23067/// @param parm the parameter to append.
23068void
23069function_decl::append_parameter(shared_ptr<parameter> parm)
23070{get_type()->append_parameter(parm);}
23071
23072/// Append a vector of parameters to the type of this function.
23073///
23074/// @param parms the vector of parameters to append.
23075void
23076function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
23077{
23078 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
23079 i != parms.end();
23080 ++i)
23081 get_type()->append_parameter(*i);
23082}
23083
23084/// Create a new instance of function_decl that is a clone of the
23085/// current one.
23086///
23087/// @return the new clone.
23090{
23092 if (is_member_function(*this))
23093 {
23094 method_decl_sptr
23095 m(new method_decl(get_name(),
23096 get_type(),
23098 get_location(),
23101 get_binding()));
23103 ABG_ASSERT(scope);
23107 get_member_is_static(*this),
23111 f = m;
23112 }
23113 else
23114 {
23115 f.reset(new function_decl(get_name(),
23116 get_type(),
23118 get_location(),
23121 get_binding()));
23123 }
23124 f->set_symbol(get_symbol());
23125
23126 return f;
23127}
23128
23129/// Compares two instances of @ref function_decl.
23130///
23131/// If the two intances are different, set a bitfield to give some
23132/// insight about the kind of differences there are.
23133///
23134/// @param l the first artifact of the comparison.
23135///
23136/// @param r the second artifact of the comparison.
23137///
23138/// @param k a pointer to a bitfield that gives information about the
23139/// kind of changes there are between @p l and @p r. This one is set
23140/// iff @p k is non-null and the function returns false.
23141///
23142/// Please note that setting k to a non-null value does have a
23143/// negative performance impact because even if @p l and @p r are not
23144/// equal, the function keeps up the comparison in order to determine
23145/// the different kinds of ways in which they are different.
23146///
23147/// @return true if @p l equals @p r, false otherwise.
23148bool
23150{
23151 bool result = true;
23152
23153 // Compare function types
23154 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
23155 if (t0 == t1 || *t0 == *t1)
23156 ; // the types are equal, let's move on to compare the other
23157 // properties of the functions.
23158 else
23159 {
23160 result = false;
23161 if (k)
23162 {
23163 if (!types_have_similar_structure(t0, t1))
23165 else
23166 *k |= SUBTYPE_CHANGE_KIND;
23167 }
23168 else
23170 }
23171
23172 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
23173 if (!!s0 != !!s1)
23174 {
23175 result = false;
23176 if (k)
23178 else
23180 }
23181 else if (s0 && s0 != s1)
23182 {
23183 if (!elf_symbols_alias(s0, s1))
23184 {
23185 result = false;
23186 if (k)
23188 else
23190 }
23191 }
23192 bool symbols_are_equal = (s0 && s1 && result);
23193
23194 if (symbols_are_equal)
23195 {
23196 // The functions have underlying elf symbols that are equal,
23197 // so now, let's compare the decl_base part of the functions
23198 // w/o considering their decl names.
23199 interned_string n1 = l.get_name(), n2 = r.get_name();
23201 const_cast<function_decl&>(l).set_name("");
23202 const_cast<function_decl&>(l).set_linkage_name("");
23203 const_cast<function_decl&>(r).set_name("");
23204 const_cast<function_decl&>(r).set_linkage_name("");
23205
23206 bool decl_bases_different = !l.decl_base::operator==(r);
23207
23208 const_cast<function_decl&>(l).set_name(n1);
23209 const_cast<function_decl&>(l).set_linkage_name(ln1);
23210 const_cast<function_decl&>(r).set_name(n2);
23211 const_cast<function_decl&>(r).set_linkage_name(ln2);
23212
23213 if (decl_bases_different)
23214 {
23215 result = false;
23216 if (k)
23218 else
23220 }
23221 }
23222 else
23223 if (!l.decl_base::operator==(r))
23224 {
23225 result = false;
23226 if (k)
23228 else
23230 }
23231
23232 // Compare the remaining properties. Note that we don't take into
23233 // account the fact that the function was declared inline or not as
23234 // that doesn't have any impact on the final ABI.
23235 if (l.get_binding() != r.get_binding())
23236 {
23237 result = false;
23238 if (k)
23240 else
23242 }
23243
23245 {
23246 result = false;
23247 if (k)
23249 else
23251 }
23252
23254 {
23267 {
23268 result = false;
23269 if (k)
23271 else
23273 }
23274 }
23275
23276 ABG_RETURN(result);
23277}
23278
23279/// Comparison operator for @ref function_decl.
23280///
23281/// @param other the other instance of @ref function_decl to compare
23282/// against.
23283///
23284/// @return true iff the current instance of @ref function_decl equals
23285/// @p other.
23286bool
23288{
23289 const function_decl* o = dynamic_cast<const function_decl*>(&other);
23290 if (!o)
23291 return false;
23292 return equals(*this, *o, 0);
23293}
23294
23295/// Return true iff the function takes a variable number of
23296/// parameters.
23297///
23298/// @return true if the function taks a variable number
23299/// of parameters.
23300bool
23302{
23303 return (!get_parameters().empty()
23304 && get_parameters().back()->get_variadic_marker());
23305}
23306
23307/// Return an ID that tries to uniquely identify the function inside a
23308/// program or a library.
23309///
23310/// So if the function has an underlying elf symbol, the ID is the
23311/// concatenation of the symbol name and its version. Otherwise, the
23312/// ID is the linkage name if its non-null. Otherwise, it's the
23313/// pretty representation of the function.
23314///
23315/// @return the ID.
23318{
23319 if (priv_->id_.empty())
23320 {
23321 const environment& env = get_type()->get_environment();
23322 if (elf_symbol_sptr s = get_symbol())
23323 {
23324 string virtual_member_suffix;
23325 if (is_member_function(this))
23326 {
23327 method_decl* m = is_method_decl(this);
23328 ABG_ASSERT(m);
23330 {
23332 (m->get_type()->get_class_type(),
23333 /*look_through_decl_only=*/true))
23334 virtual_member_suffix += "/o";
23335 }
23336 }
23337 if (s->has_aliases())
23338 // The symbol has several aliases, so let's use a scheme
23339 // that allows all aliased functions to have different
23340 // IDs.
23341 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
23342 else
23343 // Let's use the full symbol name with its version as ID.
23344 priv_->id_ = env.intern(s->get_id_string());
23345
23346 if (!virtual_member_suffix.empty())
23347 priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
23348 }
23349 else if (!get_linkage_name().empty())
23350 priv_->id_= env.intern(get_linkage_name());
23351 else
23352 priv_->id_ = env.intern(get_pretty_representation());
23353 }
23354 return priv_->id_;
23355}
23356
23357/// Test if two function declarations are aliases.
23358///
23359/// Two functions declarations are aliases if their symbols are
23360/// aliases, in the ELF sense.
23361///
23362/// @param f1 the first function to consider.
23363///
23364/// @param f2 the second function to consider.
23365///
23366/// @return true iff @p f1 is an alias of @p f2
23367bool
23369{
23370 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
23371
23372 if (!s1 || !s2)
23373 return false;
23374
23375 return elf_symbols_alias(s1, s2);
23376}
23377
23378/// This implements the ir_traversable_base::traverse pure virtual
23379/// function.
23380///
23381/// @param v the visitor used on the current instance.
23382///
23383/// @return true if the entire IR node tree got traversed, false
23384/// otherwise.
23385bool
23387{
23388 if (visiting())
23389 return true;
23390
23391 if (v.visit_begin(this))
23392 {
23393 visiting(true);
23394 if (type_base_sptr t = get_type())
23395 t->traverse(v);
23396 visiting(false);
23397 }
23398 return v.visit_end(this);
23399}
23400
23401/// Destructor of the @ref function_decl type.
23403{delete priv_;}
23404
23405/// A deep comparison operator for a shared pointer to @ref function_decl
23406///
23407/// This function compares to shared pointers to @ref function_decl by
23408/// looking at the pointed-to instances of @ref function_dec
23409/// comparing them too. If the two pointed-to objects are equal then
23410/// this function returns true.
23411///
23412/// @param l the left-hand side argument of the equality operator.
23413///
23414/// @param r the right-hand side argument of the equality operator.
23415///
23416/// @return true iff @p l equals @p r.
23417bool
23419{
23420 if (l.get() == r.get())
23421 return true;
23422 if (!!l != !!r)
23423 return false;
23424
23425 return *l == *r;
23426}
23427
23428/// A deep inequality operator for smart pointers to functions.
23429///
23430/// @param l the left-hand side argument of the inequality operator.
23431///
23432/// @pram r the right-hand side argument of the inequality operator.
23433///
23434/// @return true iff @p is not equal to @p r.
23435bool
23437{return !operator==(l, r);}
23438
23439// <function_decl definitions>
23440
23441// <function_decl::parameter definitions>
23442
23443struct function_decl::parameter::priv
23444{
23445 type_base_wptr type_;
23446 unsigned index_;
23447 bool variadic_marker_;
23448
23449 priv()
23450 : index_(),
23451 variadic_marker_()
23452 {}
23453
23454 priv(type_base_sptr type,
23455 unsigned index,
23456 bool variadic_marker)
23457 : type_(type),
23458 index_(index),
23459 variadic_marker_(variadic_marker)
23460 {}
23461};// end struct function_decl::parameter::priv
23462
23463function_decl::parameter::parameter(const type_base_sptr type,
23464 unsigned index,
23465 const string& name,
23466 const location& loc,
23467 bool is_variadic)
23468 : type_or_decl_base(type->get_environment(),
23469 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23470 decl_base(type->get_environment(), name, loc),
23471 priv_(new priv(type, index, is_variadic))
23472{
23473 runtime_type_instance(this);
23474}
23475
23476function_decl::parameter::parameter(const type_base_sptr type,
23477 unsigned index,
23478 const string& name,
23479 const location& loc,
23480 bool is_variadic,
23481 bool is_artificial)
23482 : type_or_decl_base(type->get_environment(),
23483 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23484 decl_base(type->get_environment(), name, loc),
23485 priv_(new priv(type, index, is_variadic))
23486{
23487 runtime_type_instance(this);
23488 set_is_artificial(is_artificial);
23489}
23490
23491function_decl::parameter::parameter(const type_base_sptr type,
23492 const string& name,
23493 const location& loc,
23494 bool is_variadic,
23495 bool is_artificial)
23496 : type_or_decl_base(type->get_environment(),
23497 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23498 decl_base(type->get_environment(), name, loc),
23499 priv_(new priv(type, 0, is_variadic))
23500{
23501 runtime_type_instance(this);
23502 set_is_artificial(is_artificial);
23503}
23504
23505function_decl::parameter::parameter(const type_base_sptr type,
23506 unsigned index,
23507 bool variad)
23508 : type_or_decl_base(type->get_environment(),
23509 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23510 decl_base(type->get_environment(), "", location()),
23511 priv_(new priv(type, index, variad))
23512{
23513 runtime_type_instance(this);
23514}
23515
23516function_decl::parameter::~parameter() = default;
23517
23518const type_base_sptr
23519function_decl::parameter::get_type()const
23520{return priv_->type_.lock();}
23521
23522/// @return a copy of the type name of the parameter.
23523interned_string
23525{
23526 const environment& env = get_environment();
23527
23528 type_base_sptr t = get_type();
23529 string str;
23530 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
23531 str = "...";
23532 else
23533 {
23534 ABG_ASSERT(t);
23536 }
23537 return env.intern(str);
23538}
23539
23540/// @return a copy of the pretty representation of the type of the
23541/// parameter.
23542const string
23544{
23545 type_base_sptr t = get_type();
23546 string str;
23547 if (get_variadic_marker()
23548 || get_environment().is_variadic_parameter_type(t))
23549 str = "...";
23550 else
23551 {
23552 ABG_ASSERT(t);
23554 }
23555 return str;
23556}
23557
23558/// Get a name uniquely identifying the parameter in the function.
23559///
23560///@return the unique parm name id.
23563{
23564 const environment& env = get_environment();
23565
23566
23567 std::ostringstream o;
23568 o << "parameter-" << get_index();
23569
23570 return env.intern(o.str());
23571}
23572
23573unsigned
23574function_decl::parameter::get_index() const
23575{return priv_->index_;}
23576
23577void
23578function_decl::parameter::set_index(unsigned i)
23579{priv_->index_ = i;}
23580
23581
23582bool
23583function_decl::parameter::get_variadic_marker() const
23584{return priv_->variadic_marker_;}
23585
23586/// Compares two instances of @ref function_decl::parameter.
23587///
23588/// If the two intances are different, set a bitfield to give some
23589/// insight about the kind of differences there are.
23590///
23591/// @param l the first artifact of the comparison.
23592///
23593/// @param r the second artifact of the comparison.
23594///
23595/// @param k a pointer to a bitfield that gives information about the
23596/// kind of changes there are between @p l and @p r. This one is set
23597/// iff @p k is non-null and the function returns false.
23598///
23599/// Please note that setting k to a non-null value does have a
23600/// negative performance impact because even if @p l and @p r are not
23601/// equal, the function keeps up the comparison in order to determine
23602/// the different kinds of ways in which they are different.
23603///
23604/// @return true if @p l equals @p r, false otherwise.
23605bool
23607 const function_decl::parameter& r,
23608 change_kind* k)
23609{
23610 bool result = true;
23611
23612 if ((l.get_variadic_marker() != r.get_variadic_marker())
23613 || (l.get_index() != r.get_index())
23614 || (!!l.get_type() != !!r.get_type()))
23615 {
23616 result = false;
23617 if (k)
23618 {
23619 if (l.get_index() != r.get_index())
23621 if (l.get_variadic_marker() != r.get_variadic_marker()
23622 || !!l.get_type() != !!r.get_type())
23624 }
23625 else
23627 }
23628
23629 type_base_sptr l_type = l.get_type();
23630 type_base_sptr r_type = r.get_type();
23631
23632 if (l_type != r_type)
23633 {
23634 result = false;
23635 if (k)
23636 {
23637 if (!types_have_similar_structure(l_type, r_type))
23639 else
23640 *k |= SUBTYPE_CHANGE_KIND;
23641 }
23642 else
23644 }
23645
23646 ABG_RETURN(result);
23647}
23648
23649bool
23650function_decl::parameter::operator==(const parameter& o) const
23651{return equals(*this, o, 0);}
23652
23653bool
23654function_decl::parameter::operator==(const decl_base& o) const
23655{
23656 const function_decl::parameter* p =
23657 dynamic_cast<const function_decl::parameter*>(&o);
23658 if (!p)
23659 return false;
23660 return function_decl::parameter::operator==(*p);
23661}
23662
23663/// Non-member equality operator for @ref function_decl::parameter.
23664///
23665/// @param l the left-hand side of the equality operator
23666///
23667/// @param r the right-hand side of the equality operator
23668///
23669/// @return true iff @p l and @p r equals.
23670bool
23673{
23674 if (!!l != !!r)
23675 return false;
23676 if (!l)
23677 return true;
23678 return *l == *r;
23679}
23680
23681/// Non-member inequality operator for @ref function_decl::parameter.
23682///
23683/// @param l the left-hand side of the equality operator
23684///
23685/// @param r the right-hand side of the equality operator
23686///
23687/// @return true iff @p l and @p r different.
23688bool
23692
23693/// Traverse the diff sub-tree under the current instance
23694/// function_decl.
23695///
23696/// @param v the visitor to invoke on each diff node of the sub-tree.
23697///
23698/// @return true if the traversing has to keep going on, false
23699/// otherwise.
23700bool
23702{
23703 if (visiting())
23704 return true;
23705
23706 if (v.visit_begin(this))
23707 {
23708 visiting(true);
23709 if (type_base_sptr t = get_type())
23710 t->traverse(v);
23711 visiting(false);
23712 }
23713 return v.visit_end(this);
23714}
23715
23716/// Compute the qualified name of the parameter.
23717///
23718/// @param internal set to true if the call is intended for an
23719/// internal use (for technical use inside the library itself), false
23720/// otherwise. If you don't know what this is for, then set it to
23721/// false.
23722///
23723/// @param qn the resulting qualified name.
23724void
23726 bool /*internal*/) const
23727{qualified_name = get_name();}
23728
23729/// Compute and return a copy of the pretty representation of the
23730/// current function parameter.
23731///
23732/// @param internal set to true if the call is intended to get a
23733/// representation of the decl (or type) for the purpose of canonical
23734/// type comparison. This is mainly used in the function
23735/// type_base::get_canonical_type_for().
23736///
23737/// In other words if the argument for this parameter is true then the
23738/// call is meant for internal use (for technical use inside the
23739/// library itself), false otherwise. If you don't know what this is
23740/// for, then set it to false.
23741///
23742/// @return a copy of the textual representation of the current
23743/// function parameter.
23744string
23746 bool qualified_name) const
23747{
23748 const environment& env = get_environment();
23749
23750 string type_repr;
23751 type_base_sptr t = get_type();
23752 if (!t)
23753 type_repr = "void";
23754 else if (env.is_variadic_parameter_type(t))
23755 type_repr = "...";
23756 else
23757 type_repr = ir::get_type_name(t, qualified_name, internal);
23758
23759 string result = type_repr;
23760 string parm_name = get_name_id();
23761
23762 if (!parm_name.empty())
23763 result += " " + parm_name;
23764
23765 return result;
23766}
23767
23768// </function_decl::parameter definitions>
23769
23770// <class_or_union definitions>
23771
23772/// A Constructor for instances of @ref class_or_union
23773///
23774/// @param env the environment we are operating from.
23775///
23776/// @param name the identifier of the class.
23777///
23778/// @param size_in_bits the size of an instance of @ref
23779/// class_or_union, expressed in bits
23780///
23781/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23782/// expressed in bits.
23783///
23784/// @param locus the source location of declaration point this class.
23785///
23786/// @param vis the visibility of instances of @ref class_or_union.
23787///
23788/// @param mem_types the vector of member types of this instance of
23789/// @ref class_or_union.
23790///
23791/// @param data_members the vector of data members of this instance of
23792/// @ref class_or_union.
23793///
23794/// @param member_fns the vector of member functions of this instance
23795/// of @ref class_or_union.
23796class_or_union::class_or_union(const environment& env, const string& name,
23797 size_t size_in_bits, size_t align_in_bits,
23798 const location& locus, visibility vis,
23799 member_types& mem_types,
23801 member_functions& member_fns)
23802 : type_or_decl_base(env,
23803 ABSTRACT_TYPE_BASE
23804 | ABSTRACT_DECL_BASE
23805 | ABSTRACT_SCOPE_TYPE_DECL
23806 | ABSTRACT_SCOPE_DECL),
23807 decl_base(env, name, locus, name, vis),
23808 type_base(env, size_in_bits, align_in_bits),
23809 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23810 priv_(new priv(data_members, member_fns))
23811{
23812 for (member_types::iterator i = mem_types.begin();
23813 i != mem_types.end();
23814 ++i)
23817
23818 for (data_members::iterator i = data_members.begin();
23819 i != data_members.end();
23820 ++i)
23821 if (!has_scope(*i))
23822 add_decl_to_scope(*i, this);
23823
23824 for (member_functions::iterator i = member_fns.begin();
23825 i != member_fns.end();
23826 ++i)
23827 if (!has_scope(static_pointer_cast<decl_base>(*i)))
23828 add_decl_to_scope(*i, this);
23829}
23830
23831/// A constructor for instances of @ref class_or_union.
23832///
23833/// @param env the environment we are operating from.
23834///
23835/// @param name the name of the class.
23836///
23837/// @param size_in_bits the size of an instance of @ref
23838/// class_or_union, expressed in bits
23839///
23840/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23841/// expressed in bits.
23842///
23843/// @param locus the source location of declaration point this class.
23844///
23845/// @param vis the visibility of instances of @ref class_or_union.
23846class_or_union::class_or_union(const environment& env, const string& name,
23847 size_t size_in_bits, size_t align_in_bits,
23848 const location& locus, visibility vis)
23849 : type_or_decl_base(env,
23850 ABSTRACT_TYPE_BASE
23851 | ABSTRACT_DECL_BASE
23852 | ABSTRACT_SCOPE_TYPE_DECL
23853 | ABSTRACT_SCOPE_DECL),
23854 decl_base(env, name, locus, name, vis),
23855 type_base(env, size_in_bits, align_in_bits),
23856 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23857 priv_(new priv)
23858{}
23859
23860/// Constructor of the @ref class_or_union type.
23861///
23862/// @param env the @ref environment we are operating from.
23863///
23864/// @param name the name of the @ref class_or_union.
23865///
23866/// @param is_declaration_only a boolean saying whether the instance
23867/// represents a declaration only, or not.
23868class_or_union::class_or_union(const environment& env, const string& name,
23869 bool is_declaration_only)
23870 : type_or_decl_base(env,
23871 ABSTRACT_TYPE_BASE
23872 | ABSTRACT_DECL_BASE
23873 | ABSTRACT_SCOPE_TYPE_DECL
23874 | ABSTRACT_SCOPE_DECL),
23875 decl_base(env, name, location(), name),
23876 type_base(env, 0, 0),
23877 scope_type_decl(env, name, 0, 0, location()),
23878 priv_(new priv)
23879{
23880 set_is_declaration_only(is_declaration_only);
23881}
23882
23883/// Return the hash value of the current IR node.
23884///
23885/// Note that upon the first invocation, this member functions
23886/// computes the hash value and returns it. Subsequent invocations
23887/// just return the hash value that was previously calculated.
23888///
23889/// @return the hash value of the current IR node.
23890hash_t
23892{
23893 class_or_union::hash do_hash;
23894 hash_t h = do_hash(this);
23895 return h;
23896}
23897
23898/// This implements the ir_traversable_base::traverse pure virtual
23899/// function.
23900///
23901/// @param v the visitor used on the member nodes of the translation
23902/// unit during the traversal.
23903///
23904/// @return true if the entire IR node tree got traversed, false
23905/// otherwise.
23906bool
23908{
23909 if (v.type_node_has_been_visited(this))
23910 return true;
23911
23912 if (visiting())
23913 return true;
23914
23915 if (v.visit_begin(this))
23916 {
23917 visiting(true);
23918 bool stop = false;
23919
23920 if (!stop)
23921 for (data_members::const_iterator i = get_data_members().begin();
23922 i != get_data_members().end();
23923 ++i)
23924 if (!(*i)->traverse(v))
23925 {
23926 stop = true;
23927 break;
23928 }
23929
23930 if (!stop)
23931 for (member_functions::const_iterator i= get_member_functions().begin();
23932 i != get_member_functions().end();
23933 ++i)
23934 if (!(*i)->traverse(v))
23935 {
23936 stop = true;
23937 break;
23938 }
23939
23940 if (!stop)
23941 for (member_types::const_iterator i = get_member_types().begin();
23942 i != get_member_types().end();
23943 ++i)
23944 if (!(*i)->traverse(v))
23945 {
23946 stop = true;
23947 break;
23948 }
23949
23950 if (!stop)
23951 for (member_function_templates::const_iterator i =
23953 i != get_member_function_templates().end();
23954 ++i)
23955 if (!(*i)->traverse(v))
23956 {
23957 stop = true;
23958 break;
23959 }
23960
23961 if (!stop)
23962 for (member_class_templates::const_iterator i =
23964 i != get_member_class_templates().end();
23965 ++i)
23966 if (!(*i)->traverse(v))
23967 {
23968 stop = true;
23969 break;
23970 }
23971 visiting(false);
23972 }
23973
23974 bool result = v.visit_end(this);
23976 return result;
23977}
23978
23979/// Destrcutor of the @ref class_or_union type.
23981{delete priv_;}
23982
23983/// Add a member declaration to the current instance of class_or_union.
23984/// The member declaration can be either a member type, data member,
23985/// member function, or member template.
23986///
23987/// @param d the member declaration to add.
23988decl_base_sptr
23989class_or_union::add_member_decl(const decl_base_sptr& d)
23990{return insert_member_decl(d);}
23991
23992/// Remove a given decl from the current @ref class_or_union scope.
23993///
23994/// Note that only type declarations are supported by this method for
23995/// now. Support for the other kinds of declaration is left as an
23996/// exercise for the interested reader of the code.
23997///
23998/// @param decl the declaration to remove from this @ref
23999/// class_or_union scope.
24000void
24002{
24003 type_base_sptr t = is_type(decl);
24004
24005 // For now we want to support just removing types from classes. For
24006 // other kinds of IR node, we need more work.
24007 ABG_ASSERT(t);
24008
24010}
24011
24012/// Fixup the members of the type of an anonymous data member.
24013///
24014/// Walk all data members of (the type of) a given anonymous data
24015/// member and set a particular property of the relationship between
24016/// each data member and its containing type.
24017///
24018/// That property records the fact that the data member belongs to the
24019/// anonymous data member we consider.
24020///
24021/// In the future, if there are other properties of this relationship
24022/// to set in this manner, they ought to be added here.
24023///
24024/// @param anon_dm the anonymous data member to consider.
24025void
24027{
24028 class_or_union * anon_dm_type =
24030 if (!anon_dm_type)
24031 return;
24032
24033 for (class_or_union::data_members::const_iterator it =
24034 anon_dm_type->get_non_static_data_members().begin();
24035 it != anon_dm_type->get_non_static_data_members().end();
24036 ++it)
24037 {
24038 dm_context_rel *rel =
24039 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
24040 ABG_ASSERT(rel);
24041 rel->set_anonymous_data_member(anon_dm.get());
24042 }
24043}
24044
24045/// Getter of the alignment of the @ref class_or_union type.
24046///
24047/// If this @ref class_or_union is a declaration of a definition that
24048/// is elsewhere, then the size of the definition is returned.
24049///
24050/// @return the alignment of the @ref class_or_union type.
24051size_t
24060
24061/// Setter of the alignment of the class type.
24062///
24063/// If this class is a declaration of a definition that is elsewhere,
24064/// then the new alignment is set to the definition.
24065///
24066/// @param s the new alignment.
24067void
24076
24077/// Setter of the size of the @ref class_or_union type.
24078///
24079/// If this @ref class_or_union is a declaration of a definition that
24080/// is elsewhere, then the new size is set to the definition.
24081///
24082/// @param s the new size.
24083void
24092
24093/// Getter of the size of the @ref class_or_union type.
24094///
24095/// If this @ref class_or_union is a declaration of a definition that
24096/// is elsewhere, then the size of the definition is returned.
24097///
24098/// @return the size of the @ref class_or_union type.
24099size_t
24108
24109/// Get the number of anonymous member classes contained in this
24110/// class.
24111///
24112/// @return the number of anonymous member classes contained in this
24113/// class.
24114size_t
24116{
24117 int result = 0;
24118 for (member_types::const_iterator it = get_member_types().begin();
24119 it != get_member_types().end();
24120 ++it)
24121 if (class_decl_sptr t = is_class_type(*it))
24122 if (t->get_is_anonymous())
24123 ++result;
24124
24125 return result;
24126}
24127
24128/// Get the number of anonymous member unions contained in this class.
24129///
24130/// @return the number of anonymous member unions contained in this
24131/// class.
24132size_t
24134{
24135 int result = 0;
24136 for (member_types::const_iterator it = get_member_types().begin();
24137 it != get_member_types().end();
24138 ++it)
24139 if (union_decl_sptr t = is_union_type(*it))
24140 if (t->get_is_anonymous())
24141 ++result;
24142
24143 return result;
24144}
24145
24146/// Get the number of anonymous member enums contained in this class.
24147///
24148/// @return the number of anonymous member enums contained in this
24149/// class.
24150size_t
24152{
24153 int result = 0;
24154 for (member_types::const_iterator it = get_member_types().begin();
24155 it != get_member_types().end();
24156 ++it)
24157 if (enum_type_decl_sptr t = is_enum_type(*it))
24158 if (t->get_is_anonymous())
24159 ++result;
24160
24161 return result;
24162}
24163
24164/// Add a data member to the current instance of class_or_union.
24165///
24166/// @param v a var_decl to add as a data member. A proper
24167/// class_or_union::data_member is created from @p v and added to the
24168/// class_or_union. This var_decl should not have been already added
24169/// to a scope.
24170///
24171/// @param access the access specifier for the data member.
24172///
24173/// @param is_laid_out whether the data member was laid out. That is,
24174/// if its offset has been computed. In the pattern of a class
24175/// template for instance, this would be set to false.
24176///
24177/// @param is_static whether the data memer is static.
24178///
24179/// @param offset_in_bits if @p is_laid_out is true, this is the
24180/// offset of the data member, expressed (oh, surprise) in bits.
24181void
24183 bool is_laid_out, bool is_static,
24184 size_t offset_in_bits)
24185{
24186 ABG_ASSERT(!has_scope(v));
24187
24188 priv_->data_members_.push_back(v);
24190 set_data_member_is_laid_out(v, is_laid_out);
24191 set_data_member_offset(v, offset_in_bits);
24192 set_member_access_specifier(v, access);
24193 set_member_is_static(v, is_static);
24194
24195 // Add the variable to the set of static or non-static data members,
24196 // if it's not already in there.
24197 bool is_already_in = false;
24198 if (is_static)
24199 {
24200 for (const auto& s_dm: priv_->static_data_members_)
24201 {
24202 if (s_dm == v)
24203 {
24204 is_already_in = true;
24205 break;
24206 }
24207 }
24208 if (!is_already_in)
24209 priv_->static_data_members_.push_back(v);
24210 }
24211 else
24212 {
24213 // If this is a non-static variable, add it to the set of
24214 // non-static variables, if it's not already in there.
24215 for (data_members::const_iterator i =
24216 priv_->non_static_data_members_.begin();
24217 i != priv_->non_static_data_members_.end();
24218 ++i)
24219 if (*i == v)
24220 {
24221 is_already_in = true;
24222 break;
24223 }
24224 if (!is_already_in)
24225 priv_->non_static_data_members_.push_back(v);
24226 }
24227
24228 // If v is an anonymous data member, then fixup its data members.
24229 // For now, the only thing the fixup does is to make the data
24230 // members of the anonymous data member be aware of their containing
24231 // anonymous data member. That is helpful to compute the absolute
24232 // bit offset of each of the members of the anonymous data member.
24234}
24235
24236/// Get the data members of this @ref class_or_union.
24237///
24238/// @return a vector of the data members of this @ref class_or_union.
24241{return priv_->data_members_;}
24242
24243/// Find a data member of a given name in the current @ref class_or_union.
24244///
24245/// @param name the name of the data member to find in the current
24246/// @ref class_or_union.
24247///
24248/// @return a pointer to the @ref var_decl that represents the data
24249/// member to find inside the current @ref class_or_union.
24250const var_decl_sptr
24251class_or_union::find_data_member(const string& name) const
24252{
24253 for (data_members::const_iterator i = get_data_members().begin();
24254 i != get_data_members().end();
24255 ++i)
24256 if ((*i)->get_name() == name)
24257 return *i;
24258
24259 // We haven't found a data member with the name 'name'. Let's look
24260 // closer again, this time in our anonymous data members.
24261 for (data_members::const_iterator i = get_data_members().begin();
24262 i != get_data_members().end();
24263 ++i)
24265 {
24266 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
24267 ABG_ASSERT(type);
24268 if (var_decl_sptr data_member = type->find_data_member(name))
24269 return data_member;
24270 }
24271
24272 return var_decl_sptr();
24273}
24274
24275/// Find an anonymous data member in the class.
24276///
24277/// @param v the anonymous data member to find.
24278///
24279/// @return the anonymous data member found, or nil if none was found.
24280const var_decl_sptr
24282{
24283 if (!v->get_name().empty())
24284 return var_decl_sptr();
24285
24286 for (data_members::const_iterator it = get_non_static_data_members().begin();
24287 it != get_non_static_data_members().end();
24288 ++it)
24289 {
24290 if (is_anonymous_data_member(*it))
24291 if ((*it)->get_pretty_representation(/*internal=*/false, true)
24292 == v->get_pretty_representation(/*internal=*/false, true))
24293 return *it;
24294 }
24295
24296 return var_decl_sptr();
24297}
24298
24299/// Find a given data member.
24300///
24301/// This function takes a @ref var_decl as an argument. If it has a
24302/// non-empty name, then it tries to find a data member which has the
24303/// same name as the argument.
24304///
24305/// If it has an empty name, then the @ref var_decl is considered as
24306/// an anonymous data member. In that case, this function tries to
24307/// find an anonymous data member which type equals that of the @ref
24308/// var_decl argument.
24309///
24310/// @param v this carries either the name of the data member we need
24311/// to look for, or the type of the anonymous data member we are
24312/// looking for.
24313const var_decl_sptr
24315{
24316 if (!v)
24317 return var_decl_sptr();
24318
24319 if (v->get_name().empty())
24321
24322 return find_data_member(v->get_name());
24323}
24324
24325
24326/// Get the non-static data members of this @ref class_or_union.
24327///
24328/// @return a vector of the non-static data members of this @ref
24329/// class_or_union.
24332{return priv_->non_static_data_members_;}
24333
24334/// Get the static data memebers of this @ref class_or_union.
24335///
24336/// @return a vector of the static data members of this @ref
24337/// class_or_union.
24340{return priv_->static_data_members_;}
24341
24342/// Add a member function.
24343///
24344/// @param f the new member function to add.
24345///
24346/// @param a the access specifier to use for the new member function.
24347///
24348/// @param is_static whether the new member function is static.
24349///
24350/// @param is_ctor whether the new member function is a constructor.
24351///
24352/// @param is_dtor whether the new member function is a destructor.
24353///
24354/// @param is_const whether the new member function is const.
24355void
24358 bool is_static, bool is_ctor,
24359 bool is_dtor, bool is_const)
24360{
24361 ABG_ASSERT(!has_scope(f));
24362
24364
24365 set_member_function_is_ctor(f, is_ctor);
24366 set_member_function_is_dtor(f, is_dtor);
24368 set_member_is_static(f, is_static);
24369 set_member_function_is_const(f, is_const);
24370
24371 priv_->member_functions_.push_back(f);
24372
24373 // Update the map of linkage name -> member functions. It's useful,
24374 // so that class_or_union::find_member_function() can function.
24375 if (!f->get_linkage_name().empty())
24376 priv_->mem_fns_map_[f->get_linkage_name()] = f;
24377}
24378
24379/// Get the member functions of this @ref class_or_union.
24380///
24381/// @return a vector of the member functions of this @ref
24382/// class_or_union.
24385{return priv_->member_functions_;}
24386
24387/// Find a method, using its linkage name as a key.
24388///
24389/// @param linkage_name the linkage name of the method to find.
24390///
24391/// @return the method found, or nil if none was found.
24392const method_decl*
24393class_or_union::find_member_function(const string& linkage_name) const
24394{
24395 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
24396}
24397
24398/// Find a method, using its linkage name as a key.
24399///
24400/// @param linkage_name the linkage name of the method to find.
24401///
24402/// @return the method found, or nil if none was found.
24404class_or_union::find_member_function(const string& linkage_name)
24405{
24406 string_mem_fn_sptr_map_type::const_iterator i =
24407 priv_->mem_fns_map_.find(linkage_name);
24408 if (i == priv_->mem_fns_map_.end())
24409 return 0;
24410 return i->second.get();
24411}
24412
24413/// Find a method, using its linkage name as a key.
24414///
24415/// @param linkage_name the linkage name of the method to find.
24416///
24417/// @return the method found, or nil if none was found.
24418method_decl_sptr
24420{
24421 string_mem_fn_sptr_map_type::const_iterator i =
24422 priv_->mem_fns_map_.find(linkage_name);
24423 if (i == priv_->mem_fns_map_.end())
24424 return 0;
24425 return i->second;
24426}
24427
24428/// Find a method (member function) using its signature (pretty
24429/// representation) as a key.
24430///
24431/// @param s the signature of the method.
24432///
24433/// @return the method found, or nil if none was found.
24434const method_decl*
24436{
24437 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
24438}
24439
24440/// Find a method (member function) using its signature (pretty
24441/// representation) as a key.
24442///
24443/// @param s the signature of the method.
24444///
24445/// @return the method found, or nil if none was found.
24448{
24449 string_mem_fn_ptr_map_type::const_iterator i =
24450 priv_->signature_2_mem_fn_map_.find(s);
24451 if (i == priv_->signature_2_mem_fn_map_.end())
24452 return 0;
24453 return i->second;
24454}
24455
24456/// Get the member function templates of this class.
24457///
24458/// @return a vector of the member function templates of this class.
24459const member_function_templates&
24461{return priv_->member_function_templates_;}
24462
24463/// Get the member class templates of this class.
24464///
24465/// @return a vector of the member class templates of this class.
24466const member_class_templates&
24468{return priv_->member_class_templates_;}
24469
24470/// Append a member function template to the @ref class_or_union.
24471///
24472/// @param m the member function template to append.
24473void
24474class_or_union::add_member_function_template(member_function_template_sptr m)
24475{
24476 decl_base* c = m->as_function_tdecl()->get_scope();
24477 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24478 /// error message or something like a structured error.
24479 priv_->member_function_templates_.push_back(m);
24480 if (!c)
24481 scope_decl::add_member_decl(m->as_function_tdecl());
24482}
24483
24484/// Append a member class template to the @ref class_or_union.
24485///
24486/// @param m the member function template to append.
24487void
24489{
24490 decl_base* c = m->as_class_tdecl()->get_scope();
24491 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24492 /// error message or something like a structured error.
24493 m->set_scope(this);
24494 priv_->member_class_templates_.push_back(m);
24495 if (!c)
24496 scope_decl::add_member_decl(m->as_class_tdecl());
24497}
24498
24499///@return true iff the current instance has no member.
24500bool
24502{
24503 return (get_member_types().empty()
24504 && priv_->data_members_.empty()
24505 && priv_->member_functions_.empty()
24506 && priv_->member_function_templates_.empty()
24507 && priv_->member_class_templates_.empty());
24508}
24509
24510/// Insert a data member to this @ref class_or_union type.
24511///
24512/// @param d the data member to insert.
24513///
24514/// @return the decl @p that got inserted.
24515decl_base_sptr
24517{
24518 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
24519 {
24520 add_data_member(v, public_access,
24521 /*is_laid_out=*/false,
24522 /*is_static=*/true,
24523 /*offset_in_bits=*/0);
24524 d = v;
24525 }
24526 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24527 add_member_function(f, public_access,
24528 /*is_static=*/false,
24529 /*is_ctor=*/false,
24530 /*is_dtor=*/false,
24531 /*is_const=*/false);
24532 else if (member_function_template_sptr f =
24533 dynamic_pointer_cast<member_function_template>(d))
24535 else if (member_class_template_sptr c =
24536 dynamic_pointer_cast<member_class_template>(d))
24538 else
24540
24541 return d;
24542}
24543
24544/// Equality operator.
24545///
24546/// @param other the other @ref class_or_union to compare against.
24547///
24548/// @return true iff @p other equals the current @ref class_or_union.
24549bool
24551{
24552 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
24553 if (!op)
24554 return false;
24555
24556 // If this is a decl-only type (and thus with no canonical type),
24557 // use the canonical type of the definition, if any.
24558 const class_or_union *l = 0;
24560 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
24561 if (l == 0)
24562 l = this;
24563
24564 // Likewise for the other class.
24565 const class_or_union *r = 0;
24566 if (op->get_is_declaration_only())
24567 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
24568 if (r == 0)
24569 r = op;
24570
24571 return try_canonical_compare(l, r);
24572}
24573
24574/// Equality operator.
24575///
24576/// @param other the other @ref class_or_union to compare against.
24577///
24578/// @return true iff @p other equals the current @ref class_or_union.
24579bool
24581{
24582 const decl_base* o = dynamic_cast<const decl_base*>(&other);
24583 if (!o)
24584 return false;
24585 return *this == *o;
24586}
24587
24588/// Equality operator.
24589///
24590/// @param other the other @ref class_or_union to compare against.
24591///
24592/// @return true iff @p other equals the current @ref class_or_union.
24593bool
24595{
24596 const decl_base& o = other;
24598}
24599
24600/// Compares two instances of @ref class_or_union.
24601///
24602/// If the two intances are different, set a bitfield to give some
24603/// insight about the kind of differences there are.
24604///
24605/// @param l the first artifact of the comparison.
24606///
24607/// @param r the second artifact of the comparison.
24608///
24609/// @param k a pointer to a bitfield that gives information about the
24610/// kind of changes there are between @p l and @p r. This one is set
24611/// iff it's non-null and if the function returns false.
24612///
24613/// Please note that setting k to a non-null value does have a
24614/// negative performance impact because even if @p l and @p r are not
24615/// equal, the function keeps up the comparison in order to determine
24616/// the different kinds of ways in which they are different.
24617///
24618/// @return true if @p l equals @p r, false otherwise.
24619bool
24621{
24622 // if one of the classes is declaration-only, look through it to
24623 // get its definition.
24624 bool l_is_decl_only = l.get_is_declaration_only();
24625 bool r_is_decl_only = r.get_is_declaration_only();
24626 if (l_is_decl_only || r_is_decl_only)
24627 {
24628 const class_or_union* def1 = l_is_decl_only
24630 : &l;
24631
24632 const class_or_union* def2 = r_is_decl_only
24634 : &r;
24635
24636 if (!def1 || !def2)
24637 {
24638 if (!l.get_is_anonymous()
24639 && !r.get_is_anonymous()
24640 && l_is_decl_only && r_is_decl_only
24642 // The two decl-only classes differ from their size. A
24643 // true decl-only class should not have a size property to
24644 // begin with. This comes from a DWARF oddity and can
24645 // results in a false positive, so let's not consider that
24646 // change.
24647 return true;
24648
24652 {
24653 const interned_string& q1 = l.get_scoped_name();
24654 const interned_string& q2 = r.get_scoped_name();
24655 if (q1 == q2)
24656 // Not using RETURN(true) here, because that causes
24657 // performance issues. We don't need to do
24658 // l.priv_->unmark_as_being_compared({l,r}) here because
24659 // we haven't marked l or r as being compared yet, and
24660 // doing so has a peformance cost that shows up on
24661 // performance profiles for *big* libraries.
24662 return true;
24663 else
24664 {
24665 if (k)
24667 // Not using RETURN(true) here, because that causes
24668 // performance issues. We don't need to do
24669 // l.priv_->unmark_as_being_compared({l,r}) here because
24670 // we haven't marked l or r as being compared yet, and
24671 // doing so has a peformance cost that shows up on
24672 // performance profiles for *big* libraries.
24674 }
24675 }
24676 else // A decl-only class is considered different from a
24677 // class definition of the same name.
24678 {
24679 if (!!def1 != !!def2)
24680 {
24681 if (k)
24684 }
24685
24686 // both definitions are empty
24687 if (!(l.decl_base::operator==(r)
24688 && l.type_base::operator==(r)))
24689 {
24690 if (k)
24693 }
24694
24695 return true;
24696 }
24697 }
24698
24699 bool val = *def1 == *def2;
24700 if (!val)
24701 if (k)
24703 ABG_RETURN(val);
24704 }
24705
24706 // No need to go further if the classes have different names or
24707 // different size / alignment.
24708 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
24709 {
24710 if (k)
24713 }
24714
24715 if (types_defined_same_linux_kernel_corpus_public(l, r))
24716 return true;
24717
24718 //TODO: Maybe remove this (cycle detection and canonical type
24719 //propagation handling) from here and have it only in the equal
24720 //overload for class_decl and union_decl because this one ( the
24721 //equal overload for class_or_union) is just a sub-routine of these
24722 //two above.
24723#define RETURN(value) \
24724 return return_comparison_result(l, r, value);
24725
24727
24729
24730 bool result = true;
24731
24732 //compare data_members
24733 {
24734 if (l.get_non_static_data_members().size()
24735 != r.get_non_static_data_members().size())
24736 {
24737 result = false;
24738 if (k)
24740 else
24741 RETURN(result);
24742 }
24743
24744 for (class_or_union::data_members::const_iterator
24745 d0 = l.get_non_static_data_members().begin(),
24746 d1 = r.get_non_static_data_members().begin();
24747 (d0 != l.get_non_static_data_members().end()
24748 && d1 != r.get_non_static_data_members().end());
24749 ++d0, ++d1)
24750 if (**d0 != **d1)
24751 {
24752 result = false;
24753 if (k)
24754 {
24755 // Report any representation change as being local.
24756 if (!types_have_similar_structure((*d0)->get_type(),
24757 (*d1)->get_type())
24758 || (*d0)->get_type() == (*d1)->get_type())
24760 else
24761 *k |= SUBTYPE_CHANGE_KIND;
24762 }
24763 else
24764 RETURN(result);
24765 }
24766 }
24767
24768 // Do not compare member functions. DWARF does not necessarily
24769 // all the member functions, be they virtual or not, in all
24770 // translation units. So we cannot have a clear view of them, per
24771 // class
24772
24773 // compare member function templates
24774 {
24775 if (l.get_member_function_templates().size()
24776 != r.get_member_function_templates().size())
24777 {
24778 result = false;
24779 if (k)
24781 else
24782 RETURN(result);
24783 }
24784
24785 for (member_function_templates::const_iterator
24786 fn_tmpl_it0 = l.get_member_function_templates().begin(),
24787 fn_tmpl_it1 = r.get_member_function_templates().begin();
24788 fn_tmpl_it0 != l.get_member_function_templates().end()
24789 && fn_tmpl_it1 != r.get_member_function_templates().end();
24790 ++fn_tmpl_it0, ++fn_tmpl_it1)
24791 if (**fn_tmpl_it0 != **fn_tmpl_it1)
24792 {
24793 result = false;
24794 if (k)
24795 {
24797 break;
24798 }
24799 else
24800 RETURN(result);
24801 }
24802 }
24803
24804 // compare member class templates
24805 {
24806 if (l.get_member_class_templates().size()
24807 != r.get_member_class_templates().size())
24808 {
24809 result = false;
24810 if (k)
24812 else
24813 RETURN(result);
24814 }
24815
24816 for (member_class_templates::const_iterator
24817 cl_tmpl_it0 = l.get_member_class_templates().begin(),
24818 cl_tmpl_it1 = r.get_member_class_templates().begin();
24819 cl_tmpl_it0 != l.get_member_class_templates().end()
24820 && cl_tmpl_it1 != r.get_member_class_templates().end();
24821 ++cl_tmpl_it0, ++cl_tmpl_it1)
24822 if (**cl_tmpl_it0 != **cl_tmpl_it1)
24823 {
24824 result = false;
24825 if (k)
24826 {
24828 break;
24829 }
24830 else
24831 RETURN(result);
24832 }
24833 }
24834
24835 RETURN(result);
24836#undef RETURN
24837}
24838
24839
24840/// Copy a method of a @ref class_or_union into a new @ref
24841/// class_or_union.
24842///
24843/// @param t the @ref class_or_union into which the method is to be copied.
24844///
24845/// @param method the method to copy into @p t.
24846///
24847/// @return the resulting newly copied method.
24848method_decl_sptr
24849copy_member_function(class_or_union_sptr t,
24850 const method_decl_sptr& method)
24851{return copy_member_function(t, method.get());}
24852
24853
24854/// Copy a method of a @ref class_or_union into a new @ref
24855/// class_or_union.
24856///
24857/// @param t the @ref class_or_union into which the method is to be copied.
24858///
24859/// @param method the method to copy into @p t.
24860///
24861/// @return the resulting newly copied method.
24862method_decl_sptr
24863copy_member_function(class_or_union_sptr t, const method_decl* method)
24864{
24865 ABG_ASSERT(t);
24866 ABG_ASSERT(method);
24867
24868 method_type_sptr old_type = method->get_type();
24869 ABG_ASSERT(old_type);
24870 method_type_sptr new_type(new method_type(old_type->get_return_type(),
24871 t,
24872 old_type->get_parameters(),
24873 old_type->get_is_const(),
24874 old_type->get_size_in_bits(),
24875 old_type->get_alignment_in_bits()));
24876 t->get_translation_unit()->bind_function_type_life_time(new_type);
24877
24878 method_decl_sptr
24879 new_method(new method_decl(method->get_name(),
24880 new_type,
24881 method->is_declared_inline(),
24882 method->get_location(),
24883 method->get_linkage_name(),
24884 method->get_visibility(),
24885 method->get_binding()));
24886 new_method->set_symbol(method->get_symbol());
24887
24888 if (class_decl_sptr class_type = is_class_type(t))
24889 class_type->add_member_function(new_method,
24893 get_member_is_static(*method),
24897 else
24898 t->add_member_function(new_method,
24900 get_member_is_static(*method),
24904 return new_method;
24905}
24906
24907/// Copy a data member of a @ref class_or_union into a new @ref
24908/// class_or_union.
24909///
24910/// @param t the @ref class_or_union into which the data member is to
24911/// be copied.
24912///
24913/// @param variable the data member to copy into @p t.
24914///
24915/// @return the resulting newly copied method.
24917copy_member_variable(class_or_union_sptr t, const var_decl* variable)
24918{
24919 ABG_ASSERT(variable);
24920 ABG_ASSERT(is_data_member(variable));
24921 ABG_ASSERT(t);
24922 ABG_ASSERT(!t->find_data_member(variable->get_name()));
24923
24924 type_base_sptr old_type = variable->get_type();
24925
24926 var_decl_sptr new_variable(new var_decl(variable->get_name(),
24927 old_type,
24928 variable->get_location(),
24929 variable->get_linkage_name(),
24930 variable->get_visibility(),
24931 variable->get_binding()));
24932
24933 size_t offset_in_bits = 0;
24934 if (get_data_member_is_laid_out(*variable))
24935 offset_in_bits = get_data_member_offset(*variable);
24936
24937 t->add_data_member(new_variable,
24938 get_member_access_specifier(*variable),
24939 get_data_member_is_laid_out(*variable),
24940 get_member_is_static(*variable),
24941 offset_in_bits);
24942
24943 return new_variable;
24944}
24945
24946/// Copy a data member of a @ref class_or_union into a new @ref
24947/// class_or_union.
24948///
24949/// @param t the @ref class_or_union into which the data member is to
24950/// be copied.
24951///
24952/// @param variable the data member to copy into @p t.
24953///
24954/// @return the resulting newly copied method.
24956copy_member_variable(class_or_union_sptr t, const var_decl_sptr& variable)
24957{return copy_member_variable(t, variable.get());}
24958
24959/// Copy a data member of a @ref class_or_union into a new @ref
24960/// class_or_union.
24961///
24962/// @param t the @ref class_or_union into which the data member is to
24963/// be copied.
24964///
24965/// @param variable the data member to copy into @p t.
24966///
24967/// @return the resulting newly copied method.
24970{return copy_member_variable(static_pointer_cast<class_or_union>(t), variable);}
24971// </class_or_union definitions>
24972
24973// <class_decl definitions>
24974
24975static void
24976sort_virtual_member_functions(class_decl::member_functions& mem_fns);
24977
24978/// The private data for the class_decl type.
24979struct class_decl::priv
24980{
24981 base_specs bases_;
24982 unordered_map<string, base_spec_sptr> bases_map_;
24983 member_functions virtual_mem_fns_;
24984 virtual_mem_fn_map_type virtual_mem_fns_map_;
24985 bool is_struct_;
24986
24987 priv()
24988 : is_struct_(false)
24989 {}
24990
24991 priv(bool is_struct, class_decl::base_specs& bases)
24992 : bases_(bases),
24993 is_struct_(is_struct)
24994 {
24995 }
24996
24997 priv(bool is_struct)
24998 : is_struct_(is_struct)
24999 {}
25000};// end struct class_decl::priv
25001
25002/// A Constructor for instances of \ref class_decl
25003///
25004/// @param env the environment we are operating from.
25005///
25006/// @param name the identifier of the class.
25007///
25008/// @param size_in_bits the size of an instance of class_decl, expressed
25009/// in bits
25010///
25011/// @param align_in_bits the alignment of an instance of class_decl,
25012/// expressed in bits.
25013///
25014/// @param locus the source location of declaration point this class.
25015///
25016/// @param vis the visibility of instances of class_decl.
25017///
25018/// @param bases the vector of base classes for this instance of class_decl.
25019///
25020/// @param mbrs the vector of member types of this instance of
25021/// class_decl.
25022///
25023/// @param data_mbrs the vector of data members of this instance of
25024/// class_decl.
25025///
25026/// @param mbr_fns the vector of member functions of this instance of
25027/// class_decl.
25028class_decl::class_decl(const environment& env, const string& name,
25029 size_t size_in_bits, size_t align_in_bits,
25030 bool is_struct, const location& locus,
25031 visibility vis, base_specs& bases,
25032 member_types& mbr_types,
25033 data_members& data_mbrs,
25034 member_functions& mbr_fns)
25035 : type_or_decl_base(env,
25036 CLASS_TYPE
25037 | ABSTRACT_TYPE_BASE
25038 | ABSTRACT_DECL_BASE
25039 | ABSTRACT_SCOPE_TYPE_DECL
25040 | ABSTRACT_SCOPE_DECL),
25041 decl_base(env, name, locus, name, vis),
25042 type_base(env, size_in_bits, align_in_bits),
25043 class_or_union(env, name, size_in_bits, align_in_bits,
25044 locus, vis, mbr_types, data_mbrs, mbr_fns),
25045 priv_(new priv(is_struct, bases))
25046{
25048}
25049
25050/// A Constructor for instances of @ref class_decl
25051///
25052/// @param env the environment we are operating from.
25053///
25054/// @param name the identifier of the class.
25055///
25056/// @param size_in_bits the size of an instance of class_decl, expressed
25057/// in bits
25058///
25059/// @param align_in_bits the alignment of an instance of class_decl,
25060/// expressed in bits.
25061///
25062/// @param locus the source location of declaration point this class.
25063///
25064/// @param vis the visibility of instances of class_decl.
25065///
25066/// @param bases the vector of base classes for this instance of class_decl.
25067///
25068/// @param mbrs the vector of member types of this instance of
25069/// class_decl.
25070///
25071/// @param data_mbrs the vector of data members of this instance of
25072/// class_decl.
25073///
25074/// @param mbr_fns the vector of member functions of this instance of
25075/// class_decl.
25076///
25077/// @param is_anonymous whether the newly created instance is
25078/// anonymous.
25079class_decl::class_decl(const environment& env, const string& name,
25080 size_t size_in_bits, size_t align_in_bits,
25081 bool is_struct, const location& locus,
25082 visibility vis, base_specs& bases,
25083 member_types& mbr_types, data_members& data_mbrs,
25084 member_functions& mbr_fns, bool is_anonymous)
25085 : type_or_decl_base(env,
25086 CLASS_TYPE
25087 | ABSTRACT_TYPE_BASE
25088 | ABSTRACT_DECL_BASE
25089 | ABSTRACT_SCOPE_TYPE_DECL
25090 | ABSTRACT_SCOPE_DECL),
25091 decl_base(env, name, locus,
25092 // If the class is anonymous then by default it won't
25093 // have a linkage name. Also, the anonymous class does
25094 // have an internal-only unique name that is generally
25095 // not taken into account when comparing classes; such a
25096 // unique internal-only name, when used as a linkage
25097 // name might introduce spurious comparison false
25098 // negatives.
25099 /*linkage_name=*/is_anonymous ? string() : name,
25100 vis),
25101 type_base(env, size_in_bits, align_in_bits),
25102 class_or_union(env, name, size_in_bits, align_in_bits,
25103 locus, vis, mbr_types, data_mbrs, mbr_fns),
25104 priv_(new priv(is_struct, bases))
25105{
25107 set_is_anonymous(is_anonymous);
25108}
25109
25110/// A constructor for instances of class_decl.
25111///
25112/// @param env the environment we are operating from.
25113///
25114/// @param name the name of the class.
25115///
25116/// @param size_in_bits the size of an instance of class_decl, expressed
25117/// in bits
25118///
25119/// @param align_in_bits the alignment of an instance of class_decl,
25120/// expressed in bits.
25121///
25122/// @param locus the source location of declaration point this class.
25123///
25124/// @param vis the visibility of instances of class_decl.
25125class_decl::class_decl(const environment& env, const string& name,
25126 size_t size_in_bits, size_t align_in_bits,
25127 bool is_struct, const location& locus,
25128 visibility vis)
25129 : type_or_decl_base(env,
25130 CLASS_TYPE
25131 | ABSTRACT_TYPE_BASE
25132 | ABSTRACT_DECL_BASE
25133 | ABSTRACT_SCOPE_TYPE_DECL
25134 | ABSTRACT_SCOPE_DECL),
25135 decl_base(env, name, locus, name, vis),
25136 type_base(env, size_in_bits, align_in_bits),
25137 class_or_union(env, name, size_in_bits, align_in_bits,
25138 locus, vis),
25139 priv_(new priv(is_struct))
25140{
25142}
25143
25144/// A constructor for instances of @ref class_decl.
25145///
25146/// @param env the environment we are operating from.
25147///
25148/// @param name the name of the class.
25149///
25150/// @param size_in_bits the size of an instance of class_decl, expressed
25151/// in bits
25152///
25153/// @param align_in_bits the alignment of an instance of class_decl,
25154/// expressed in bits.
25155///
25156/// @param locus the source location of declaration point this class.
25157///
25158/// @param vis the visibility of instances of class_decl.
25159///
25160/// @param is_anonymous whether the newly created instance is
25161/// anonymous.
25162class_decl:: class_decl(const environment& env, const string& name,
25163 size_t size_in_bits, size_t align_in_bits,
25164 bool is_struct, const location& locus,
25165 visibility vis, bool is_anonymous)
25166 : type_or_decl_base(env,
25167 CLASS_TYPE
25168 | ABSTRACT_TYPE_BASE
25169 | ABSTRACT_DECL_BASE
25170 | ABSTRACT_SCOPE_TYPE_DECL
25171 | ABSTRACT_SCOPE_DECL),
25172 decl_base(env, name, locus,
25173 // If the class is anonymous then by default it won't
25174 // have a linkage name. Also, the anonymous class does
25175 // have an internal-only unique name that is generally
25176 // not taken into account when comparing classes; such a
25177 // unique internal-only name, when used as a linkage
25178 // name might introduce spurious comparison false
25179 // negatives.
25180 /*linkage_name=*/ is_anonymous ? string() : name,
25181 vis),
25182 type_base(env, size_in_bits, align_in_bits),
25183 class_or_union(env, name, size_in_bits, align_in_bits,
25184 locus, vis),
25185 priv_(new priv(is_struct))
25186{
25188 set_is_anonymous(is_anonymous);
25189}
25190
25191/// A constuctor for instances of class_decl that represent a
25192/// declaration without definition.
25193///
25194/// @param env the environment we are operating from.
25195///
25196/// @param name the name of the class.
25197///
25198/// @param is_declaration_only a boolean saying whether the instance
25199/// represents a declaration only, or not.
25200class_decl::class_decl(const environment& env, const string& name,
25201 bool is_struct, bool is_declaration_only)
25202 : type_or_decl_base(env,
25203 CLASS_TYPE
25204 | ABSTRACT_TYPE_BASE
25205 | ABSTRACT_DECL_BASE
25206 | ABSTRACT_SCOPE_TYPE_DECL
25207 | ABSTRACT_SCOPE_DECL),
25208 decl_base(env, name, location(), name),
25209 type_base(env, 0, 0),
25210 class_or_union(env, name, is_declaration_only),
25211 priv_(new priv(is_struct))
25212{
25214}
25215
25216/// This method is invoked automatically right after the current
25217/// instance of @ref class_decl has been canonicalized.
25218///
25219/// Currently, the only thing it does is to sort the virtual member
25220/// functions vector.
25221void
25223{
25225
25226 for (class_decl::virtual_mem_fn_map_type::iterator i =
25227 priv_->virtual_mem_fns_map_.begin();
25228 i != priv_->virtual_mem_fns_map_.end();
25229 ++i)
25230 sort_virtual_member_functions(i->second);
25231}
25232
25233/// Set the "is-struct" flag of the class.
25234///
25235/// @param f the new value of the flag.
25236void
25238{priv_->is_struct_ = f;}
25239
25240/// Test if the class is a struct.
25241///
25242/// @return true iff the class is a struct.
25243bool
25245{return priv_->is_struct_;}
25246
25247/// Add a base specifier to this class.
25248///
25249/// @param b the new base specifier.
25250void
25252{
25253 priv_->bases_.push_back(b);
25254 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
25255}
25256
25257/// Get the base specifiers for this class.
25258///
25259/// @return a vector of the base specifiers.
25262{return priv_->bases_;}
25263
25264/// Find a base class of a given qualified name for the current class.
25265///
25266/// @param qualified_name the qualified name of the base class to look for.
25267///
25268/// @return a pointer to the @ref class_decl that represents the base
25269/// class of name @p qualified_name, if found.
25271class_decl::find_base_class(const string& qualified_name) const
25272{
25273 unordered_map<string, base_spec_sptr>::iterator i =
25274 priv_->bases_map_.find(qualified_name);
25275
25276 if (i != priv_->bases_map_.end())
25277 return i->second->get_base_class();
25278
25279 return class_decl_sptr();
25280}
25281
25282/// Get the virtual member functions of this class.
25283///
25284/// @param return a vector of the virtual member functions of this
25285/// class.
25288{return priv_->virtual_mem_fns_;}
25289
25290/// Get the map that associates a virtual table offset to the virtual
25291/// member functions with that virtual table offset.
25292///
25293/// Usually, there should be a 1:1 mapping between a given vtable
25294/// offset and virtual member functions of that vtable offset. But
25295/// because of some implementation details, there can be several C++
25296/// destructor functions that are *generated* by compilers, for a
25297/// given destructor that is defined in the source code. If the
25298/// destructor is virtual then those generated functions have some
25299/// DWARF attributes in common with the constructor that the user
25300/// actually defined in its source code. Among those attributes are
25301/// the vtable offset of the destructor.
25302///
25303/// @return the map that associates a virtual table offset to the
25304/// virtual member functions with that virtual table offset.
25307{return priv_->virtual_mem_fns_map_;}
25308
25309/// Sort the virtual member functions by their virtual index.
25310void
25312{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
25313
25314/// Getter of the pretty representation of the current instance of
25315/// @ref class_decl.
25316///
25317/// @param internal set to true if the call is intended to get a
25318/// representation of the decl (or type) for the purpose of canonical
25319/// type comparison. This is mainly used in the function
25320/// type_base::get_canonical_type_for().
25321///
25322/// In other words if the argument for this parameter is true then the
25323/// call is meant for internal use (for technical use inside the
25324/// library itself), false otherwise. If you don't know what this is
25325/// for, then set it to false.
25326///
25327/// @param qualified_name if true, names emitted in the pretty
25328/// representation are fully qualified.
25329///
25330/// @return the pretty representaion for a class_decl.
25331string
25333 bool qualified_name) const
25334{
25335 string cl = "class ";
25336 if (!internal && is_struct())
25337 cl = "struct ";
25338
25339 // When computing the pretty representation for internal purposes,
25340 // if an anonymous class is named by a typedef, then consider that
25341 // it has a name, which is the typedef name.
25342 if (get_is_anonymous())
25343 {
25344 if (internal && !get_name().empty())
25345 return cl + get_type_name(this, qualified_name, /*internal=*/true);
25347 /*one_line=*/true,
25348 internal);
25349
25350 }
25351
25352 string result = cl;
25353 if (qualified_name)
25354 result += get_qualified_name(internal);
25355 else
25356 result += get_name();
25357
25358 return result;
25359}
25360
25361decl_base_sptr
25362class_decl::insert_member_decl(decl_base_sptr d)
25363{
25364 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
25365 add_member_function(f, public_access,
25366 /*is_virtual=*/false,
25367 /*vtable_offset=*/0,
25368 /*is_static=*/false,
25369 /*is_ctor=*/false,
25370 /*is_dtor=*/false,
25371 /*is_const=*/false);
25372 else
25374
25375 return d;
25376}
25377
25378/// The private data structure of class_decl::base_spec.
25379struct class_decl::base_spec::priv
25380{
25381 class_decl_wptr base_class_;
25382 long offset_in_bits_;
25383 bool is_virtual_;
25384
25385 priv(const class_decl_sptr& cl,
25386 long offset_in_bits,
25387 bool is_virtual)
25388 : base_class_(cl),
25389 offset_in_bits_(offset_in_bits),
25390 is_virtual_(is_virtual)
25391 {}
25392};
25393
25394/// Constructor for base_spec instances.
25395///
25396/// @param base the base class to consider
25397///
25398/// @param a the access specifier of the base class.
25399///
25400/// @param offset_in_bits if positive or null, represents the offset
25401/// of the base in the layout of its containing type.. If negative,
25402/// means that the current base is not laid out in its containing type.
25403///
25404/// @param is_virtual if true, means that the current base class is
25405/// virtual in it's containing type.
25406class_decl::base_spec::base_spec(const class_decl_sptr& base,
25408 long offset_in_bits,
25409 bool is_virtual)
25410 : type_or_decl_base(base->get_environment(),
25411 ABSTRACT_DECL_BASE),
25412 decl_base(base->get_environment(), base->get_name(), base->get_location(),
25413 base->get_linkage_name(), base->get_visibility()),
25414 member_base(a),
25415 priv_(new priv(base, offset_in_bits, is_virtual))
25416{
25418 set_qualified_name(base->get_qualified_name());
25419}
25420
25421/// Return the hash value of the current IR node.
25422///
25423/// Note that upon the first invocation, this member functions
25424/// computes the hash value and returns it. Subsequent invocations
25425/// just return the hash value that was previously calculated.
25426///
25427/// @return the hash value of the current IR node.
25428hash_t
25430{
25432 return h;
25433}
25434
25435/// Get the base class referred to by the current base class
25436/// specifier.
25437///
25438/// @return the base class.
25441{return priv_->base_class_.lock();}
25442
25443/// Getter of the "is-virtual" proprerty of the base class specifier.
25444///
25445/// @return true iff this specifies a virtual base class.
25446bool
25448{return priv_->is_virtual_;}
25449
25450/// Getter of the offset of the base.
25451///
25452/// @return the offset of the base.
25453long
25455{return priv_->offset_in_bits_;}
25456
25457/// Traverses an instance of @ref class_decl::base_spec, visiting all
25458/// the sub-types and decls that it might contain.
25459///
25460/// @param v the visitor that is used to visit every IR sub-node of
25461/// the current node.
25462///
25463/// @return true if either
25464/// - all the children nodes of the current IR node were traversed
25465/// and the calling code should keep going with the traversing.
25466/// - or the current IR node is already being traversed.
25467/// Otherwise, returning false means that the calling code should not
25468/// keep traversing the tree.
25469bool
25471{
25472 if (visiting())
25473 return true;
25474
25475 if (v.visit_begin(this))
25476 {
25477 visiting(true);
25478 get_base_class()->traverse(v);
25479 visiting(false);
25480 }
25481
25482 return v.visit_end(this);
25483}
25484
25485/// Constructor for base_spec instances.
25486///
25487/// Note that this constructor is for clients that don't support RTTI
25488/// and that have a base class of type_base, but of dynamic type
25489/// class_decl.
25490///
25491/// @param base the base class to consider. Must be a pointer to an
25492/// instance of class_decl
25493///
25494/// @param a the access specifier of the base class.
25495///
25496/// @param offset_in_bits if positive or null, represents the offset
25497/// of the base in the layout of its containing type.. If negative,
25498/// means that the current base is not laid out in its containing type.
25499///
25500/// @param is_virtual if true, means that the current base class is
25501/// virtual in it's containing type.
25502class_decl::base_spec::base_spec(const type_base_sptr& base,
25504 long offset_in_bits,
25505 bool is_virtual)
25507 ABSTRACT_DECL_BASE),
25512 member_base(a),
25513 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
25514 offset_in_bits,
25515 is_virtual))
25516{
25518}
25519
25520class_decl::base_spec::~base_spec() = default;
25521
25522/// Compares two instances of @ref class_decl::base_spec.
25523///
25524/// If the two intances are different, set a bitfield to give some
25525/// insight about the kind of differences there are.
25526///
25527/// @param l the first artifact of the comparison.
25528///
25529/// @param r the second artifact of the comparison.
25530///
25531/// @param k a pointer to a bitfield that gives information about the
25532/// kind of changes there are between @p l and @p r. This one is set
25533/// iff @p k is non-null and the function returns false.
25534///
25535/// Please note that setting k to a non-null value does have a
25536/// negative performance impact because even if @p l and @p r are not
25537/// equal, the function keeps up the comparison in order to determine
25538/// the different kinds of ways in which they are different.
25539///
25540/// @return true if @p l equals @p r, false otherwise.
25541bool
25543 const class_decl::base_spec& r,
25544 change_kind* k)
25545{
25546 if (!l.member_base::operator==(r))
25547 {
25548 if (k)
25551 }
25552
25554}
25555
25556/// Comparison operator for @ref class_decl::base_spec.
25557///
25558/// @param other the instance of @ref class_decl::base_spec to compare
25559/// against.
25560///
25561/// @return true if the current instance of @ref class_decl::base_spec
25562/// equals @p other.
25563bool
25565{
25566 const class_decl::base_spec* o =
25567 dynamic_cast<const class_decl::base_spec*>(&other);
25568
25569 if (!o)
25570 return false;
25571
25572 return equals(*this, *o, 0);
25573}
25574
25575/// Comparison operator for @ref class_decl::base_spec.
25576///
25577/// @param other the instance of @ref class_decl::base_spec to compare
25578/// against.
25579///
25580/// @return true if the current instance of @ref class_decl::base_spec
25581/// equals @p other.
25582bool
25584{
25585 const class_decl::base_spec* o =
25586 dynamic_cast<const class_decl::base_spec*>(&other);
25587 if (!o)
25588 return false;
25589
25590 return operator==(static_cast<const decl_base&>(*o));
25591}
25592
25593mem_fn_context_rel::~mem_fn_context_rel()
25594{
25595}
25596
25597/// A constructor for instances of method_decl.
25598///
25599/// @param name the name of the method.
25600///
25601/// @param type the type of the method.
25602///
25603/// @param declared_inline whether the method was
25604/// declared inline or not.
25605///
25606/// @param locus the source location of the method.
25607///
25608/// @param linkage_name the mangled name of the method.
25609///
25610/// @param vis the visibility of the method.
25611///
25612/// @param bind the binding of the method.
25613method_decl::method_decl(const string& name,
25614 method_type_sptr type,
25615 bool declared_inline,
25616 const location& locus,
25617 const string& linkage_name,
25618 visibility vis,
25619 binding bind)
25621 METHOD_DECL
25622 | ABSTRACT_DECL_BASE
25623 |FUNCTION_DECL),
25624 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25625 function_decl(name, static_pointer_cast<function_type>(type),
25626 declared_inline, locus, linkage_name, vis, bind)
25627{
25629 set_context_rel(new mem_fn_context_rel(0));
25630 set_member_function_is_const(*this, type->get_is_const());
25631}
25632
25633/// A constructor for instances of method_decl.
25634///
25635/// @param name the name of the method.
25636///
25637/// @param type the type of the method. Must be an instance of
25638/// method_type.
25639///
25640/// @param declared_inline whether the method was
25641/// declared inline or not.
25642///
25643/// @param locus the source location of the method.
25644///
25645/// @param linkage_name the mangled name of the method.
25646///
25647/// @param vis the visibility of the method.
25648///
25649/// @param bind the binding of the method.
25650method_decl::method_decl(const string& name,
25651 function_type_sptr type,
25652 bool declared_inline,
25653 const location& locus,
25654 const string& linkage_name,
25655 visibility vis,
25656 binding bind)
25657 : type_or_decl_base(type->get_environment(),
25658 METHOD_DECL
25659 | ABSTRACT_DECL_BASE
25660 | FUNCTION_DECL),
25661 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25662 function_decl(name, static_pointer_cast<function_type>
25663 (dynamic_pointer_cast<method_type>(type)),
25664 declared_inline, locus, linkage_name, vis, bind)
25665{
25667 set_context_rel(new mem_fn_context_rel(0));
25668}
25669
25670/// A constructor for instances of method_decl.
25671///
25672/// @param name the name of the method.
25673///
25674/// @param type the type of the method. Must be an instance of
25675/// method_type.
25676///
25677/// @param declared_inline whether the method was
25678/// declared inline or not.
25679///
25680/// @param locus the source location of the method.
25681///
25682/// @param linkage_name the mangled name of the method.
25683///
25684/// @param vis the visibility of the method.
25685///
25686/// @param bind the binding of the method.
25687method_decl::method_decl(const string& name,
25688 type_base_sptr type,
25689 bool declared_inline,
25690 const location& locus,
25691 const string& linkage_name,
25692 visibility vis,
25693 binding bind)
25694 : type_or_decl_base(type->get_environment(),
25695 METHOD_DECL
25696 | ABSTRACT_DECL_BASE
25697 | FUNCTION_DECL),
25698 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25699 function_decl(name, static_pointer_cast<function_type>
25700 (dynamic_pointer_cast<method_type>(type)),
25701 declared_inline, locus, linkage_name, vis, bind)
25702{
25704 set_context_rel(new mem_fn_context_rel(0));
25705}
25706
25707/// Set the linkage name of the method.
25708///
25709/// @param l the new linkage name of the method.
25710void
25712{
25713 string old_lname = get_linkage_name();
25715 // Update the linkage_name -> member function map of the containing
25716 // class declaration.
25717 if (!l.empty())
25718 {
25720 class_or_union_sptr cl = t->get_class_type();
25721 method_decl_sptr m(this, sptr_utils::noop_deleter());
25722 cl->priv_->mem_fns_map_[l] = m;
25723 if (!old_lname.empty() && l != old_lname)
25724 {
25725 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
25726 {
25727 ABG_ASSERT(m.get() == this);
25728 cl->priv_->mem_fns_map_.erase(old_lname);
25729 }
25730 }
25731 }
25732}
25733
25734method_decl::~method_decl()
25735{}
25736
25737const method_type_sptr
25739{
25740 method_type_sptr result;
25742 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
25743 return result;
25744}
25745
25746/// Set the containing class of a method_decl.
25747///
25748/// @param scope the new containing class_decl.
25749void
25750method_decl::set_scope(scope_decl* scope)
25751{
25752 if (!get_context_rel())
25753 set_context_rel(new mem_fn_context_rel(scope));
25754 else
25755 get_context_rel()->set_scope(scope);
25756}
25757
25758/// Equality operator for @ref method_decl_sptr.
25759///
25760/// This is a deep equality operator, as it compares the @ref
25761/// method_decl that is pointed-to by the smart pointer.
25762///
25763/// @param l the left-hand side argument of the equality operator.
25764///
25765/// @param r the righ-hand side argument of the equality operator.
25766///
25767/// @return true iff @p l equals @p r.
25768bool
25769operator==(const method_decl_sptr& l, const method_decl_sptr& r)
25770{
25771 if (l.get() == r.get())
25772 return true;
25773 if (!!l != !!r)
25774 return false;
25775
25776 return *l == *r;
25777}
25778
25779/// Inequality operator for @ref method_decl_sptr.
25780///
25781/// This is a deep equality operator, as it compares the @ref
25782/// method_decl that is pointed-to by the smart pointer.
25783///
25784/// @param l the left-hand side argument of the equality operator.
25785///
25786/// @param r the righ-hand side argument of the equality operator.
25787///
25788/// @return true iff @p l differs from @p r.
25789bool
25790operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
25791{return !operator==(l, r);}
25792
25793/// Test if a function_decl is actually a method_decl.
25794///
25795///@param d the @ref function_decl to consider.
25796///
25797/// @return the method_decl sub-object of @p d if inherits
25798/// a method_decl type.
25801{
25802 return dynamic_cast<method_decl*>
25803 (const_cast<type_or_decl_base*>(d));
25804}
25805
25806/// Test if a function_decl is actually a method_decl.
25807///
25808///@param d the @ref function_decl to consider.
25809///
25810/// @return the method_decl sub-object of @p d if inherits
25811/// a method_decl type.
25815
25816/// Test if a function_decl is actually a method_decl.
25817///
25818///@param d the @ref function_decl to consider.
25819///
25820/// @return the method_decl sub-object of @p d if inherits
25821/// a method_decl type.
25822method_decl_sptr
25824{return dynamic_pointer_cast<method_decl>(d);}
25825
25826/// A "less than" functor to sort a vector of instances of
25827/// method_decl that are virtual.
25828struct virtual_member_function_less_than
25829{
25830 /// The less than operator. First, it sorts the methods by their
25831 /// vtable index. If they have the same vtable index, it sorts them
25832 /// by the name of their ELF symbol. If they don't have elf
25833 /// symbols, it sorts them by considering their pretty
25834 /// representation.
25835 ///
25836 /// Note that this method expects virtual methods.
25837 ///
25838 /// @param f the first method to consider.
25839 ///
25840 /// @param s the second method to consider.
25841 ///
25842 /// @return true if method @p is less than method @s.
25843 bool
25844 operator()(const method_decl& f,
25845 const method_decl& s)
25846 {
25849
25850 ssize_t f_offset = get_member_function_vtable_offset(f);
25851 ssize_t s_offset = get_member_function_vtable_offset(s);
25852 if (f_offset != s_offset) return f_offset < s_offset;
25853
25854 string fn, sn;
25855 // Try the linkage names (important for destructors).
25856 fn = f.get_linkage_name();
25857 sn = s.get_linkage_name();
25858 if (fn != sn) return fn < sn;
25859
25860 // If the functions have symbols, then compare their symbol-id
25861 // string.
25862 elf_symbol_sptr f_sym = f.get_symbol();
25863 elf_symbol_sptr s_sym = s.get_symbol();
25864 if ((!f_sym) != (!s_sym)) return !f_sym;
25865 if (f_sym && s_sym)
25866 {
25867 fn = f_sym->get_id_string();
25868 sn = s_sym->get_id_string();
25869 if (fn != sn) return fn < sn;
25870 }
25871
25872 // None of the functions have symbols or linkage names that
25873 // distinguish them, so compare their pretty representation.
25876 if (fn != sn) return fn < sn;
25877
25878 /// If it's just the file paths that are different then sort them
25879 /// too.
25880 string fn_filepath, sn_filepath;
25881 unsigned line = 0, column = 0;
25882 location fn_loc = f.get_location(), sn_loc = s.get_location();
25883 if (fn_loc)
25884 fn_loc.expand(fn_filepath, line, column);
25885 if (sn_loc)
25886 sn_loc.expand(sn_filepath, line, column);
25887 return fn_filepath < sn_filepath;
25888 }
25889
25890 /// The less than operator. First, it sorts the methods by their
25891 /// vtable index. If they have the same vtable index, it sorts them
25892 /// by the name of their ELF symbol. If they don't have elf
25893 /// symbols, it sorts them by considering their pretty
25894 /// representation.
25895 ///
25896 /// Note that this method expects to take virtual methods.
25897 ///
25898 /// @param f the first method to consider.
25899 ///
25900 /// @param s the second method to consider.
25901 bool
25902 operator()(const method_decl_sptr f,
25903 const method_decl_sptr s)
25904 {return operator()(*f, *s);}
25905}; // end struct virtual_member_function_less_than
25906
25907/// Sort a vector of instances of virtual member functions.
25908///
25909/// @param mem_fns the vector of member functions to sort.
25910static void
25911sort_virtual_member_functions(class_decl::member_functions& mem_fns)
25912{
25913 virtual_member_function_less_than lt;
25914 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25915}
25916
25917/// Add a member function to the current instance of @ref class_or_union.
25918///
25919/// @param f a method_decl to add to the current class. This function
25920/// should not have been already added to a scope.
25921///
25922/// @param access the access specifier for the member function to add.
25923///
25924/// @param is_virtual if this is true then it means the function @p f
25925/// is a virtual function. That also means that the current instance
25926/// of @ref class_or_union is actually an instance of @ref class_decl.
25927///
25928/// @param vtable_offset the offset of the member function in the
25929/// virtual table. This parameter is taken into account only if @p
25930/// is_virtual is true.
25931///
25932/// @param is_static whether the member function is static.
25933///
25934/// @param is_ctor whether the member function is a constructor.
25935///
25936/// @param is_dtor whether the member function is a destructor.
25937///
25938/// @param is_const whether the member function is const.
25939void
25942 bool is_virtual,
25943 size_t vtable_offset,
25944 bool is_static, bool is_ctor,
25945 bool is_dtor, bool is_const)
25946{
25947 add_member_function(f, a, is_static, is_ctor,
25948 is_dtor, is_const);
25949
25950 if (class_decl* klass = is_class_type(this))
25951 {
25952 if (is_virtual)
25953 {
25954 set_member_function_virtuality(f, is_virtual, vtable_offset);
25955 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
25956 }
25957 }
25958}
25959
25960/// When a virtual member function has seen its virtualness set by
25961/// set_member_function_is_virtual(), this function ensures that the
25962/// member function is added to the specific vectors and maps of
25963/// virtual member function of its class.
25964///
25965/// @param method the method to fixup.
25966void
25967fixup_virtual_member_function(method_decl_sptr method)
25968{
25969 if (!method || !get_member_function_is_virtual(method))
25970 return;
25971
25972 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
25973
25974 class_decl::member_functions::const_iterator m;
25975 for (m = klass->priv_->virtual_mem_fns_.begin();
25976 m != klass->priv_->virtual_mem_fns_.end();
25977 ++m)
25978 if (m->get() == method.get()
25979 || (*m)->get_linkage_name() == method->get_linkage_name())
25980 break;
25981 if (m == klass->priv_->virtual_mem_fns_.end())
25982 klass->priv_->virtual_mem_fns_.push_back(method);
25983
25984 // Build or udpate the map that associates a vtable offset to the
25985 // number of virtual member functions that "point" to it.
25986 ssize_t voffset = get_member_function_vtable_offset(method);
25987 if (voffset == -1)
25988 return;
25989
25990 class_decl::virtual_mem_fn_map_type::iterator i =
25991 klass->priv_->virtual_mem_fns_map_.find(voffset);
25992 if (i == klass->priv_->virtual_mem_fns_map_.end())
25993 {
25994 class_decl::member_functions virtual_mem_fns_at_voffset;
25995 virtual_mem_fns_at_voffset.push_back(method);
25996 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
25997 }
25998 else
25999 {
26000 for (m = i->second.begin() ; m != i->second.end(); ++m)
26001 if (m->get() == method.get()
26002 || (*m)->get_linkage_name() == method->get_linkage_name())
26003 break;
26004 if (m == i->second.end())
26005 i->second.push_back(method);
26006 }
26007}
26008
26009/// Return true iff the class has no entity in its scope.
26010bool
26012{return priv_->bases_.empty() && has_no_member();}
26013
26014/// Test if the current instance of @ref class_decl has virtual member
26015/// functions.
26016///
26017/// @return true iff the current instance of @ref class_decl has
26018/// virtual member functions.
26019bool
26022
26023/// Test if the current instance of @ref class_decl has at least one
26024/// virtual base.
26025///
26026/// @return true iff the current instance of @ref class_decl has a
26027/// virtual member function.
26028bool
26030{
26031 for (base_specs::const_iterator b = get_base_specifiers().begin();
26032 b != get_base_specifiers().end();
26033 ++b)
26034 if ((*b)->get_is_virtual()
26035 || (*b)->get_base_class()->has_virtual_bases())
26036 return true;
26037
26038 return false;
26039}
26040
26041/// Test if the current instance has a vtable.
26042///
26043/// This is only valid for a C++ program.
26044///
26045/// Basically this function checks if the class has either virtual
26046/// functions, or virtual bases.
26047bool
26049{
26051 || has_virtual_bases())
26052 return true;
26053 return false;
26054}
26055
26056/// Get the highest vtable offset of all the virtual methods of the
26057/// class.
26058///
26059/// @return the highest vtable offset of all the virtual methods of
26060/// the class.
26061ssize_t
26063{
26064 ssize_t offset = -1;
26065 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
26066 get_virtual_mem_fns_map().begin();
26067 e != get_virtual_mem_fns_map().end();
26068 ++e)
26069 if (e->first > offset)
26070 offset = e->first;
26071
26072 return offset;
26073}
26074
26075/// Return the hash value of the current IR node.
26076///
26077/// Note that upon the first invocation, this member functions
26078/// computes the hash value and returns it. Subsequent invocations
26079/// just return the hash value that was previously calculated.
26080///
26081/// @return the hash value of the current IR node.
26082hash_t
26084{
26086 return h;
26087}
26088
26089/// Test if two methods are equal without taking their symbol or
26090/// linkage name into account.
26091///
26092/// @param f the first method.
26093///
26094/// @param s the second method.
26095///
26096/// @return true iff @p f equals @p s without taking their linkage
26097/// name or symbol into account.
26098static bool
26099methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
26100 const method_decl_sptr& s)
26101{
26102 method_decl_sptr first = f, second = s;
26103 elf_symbol_sptr saved_first_elf_symbol =
26104 first->get_symbol();
26105 elf_symbol_sptr saved_second_elf_symbol =
26106 second->get_symbol();
26107 interned_string saved_first_linkage_name =
26108 first->get_linkage_name();
26109 interned_string saved_second_linkage_name =
26110 second->get_linkage_name();
26111
26112 first->set_symbol(elf_symbol_sptr());
26113 first->set_linkage_name("");
26114 second->set_symbol(elf_symbol_sptr());
26115 second->set_linkage_name("");
26116
26117 bool equal = *first == *second;
26118
26119 first->set_symbol(saved_first_elf_symbol);
26120 first->set_linkage_name(saved_first_linkage_name);
26121 second->set_symbol(saved_second_elf_symbol);
26122 second->set_linkage_name(saved_second_linkage_name);
26123
26124 return equal;
26125}
26126
26127/// Test if a given method is equivalent to at least of other method
26128/// that is in a vector of methods.
26129///
26130/// Note that "equivalent" here means being equal without taking the
26131/// linkage name or the symbol of the methods into account.
26132///
26133/// This is a sub-routine of the 'equals' function that compares @ref
26134/// class_decl.
26135///
26136/// @param method the method to compare.
26137///
26138/// @param fns the vector of functions to compare @p method against.
26139///
26140/// @return true iff @p is equivalent to at least one method in @p
26141/// fns.
26142static bool
26143method_matches_at_least_one_in_vector(const method_decl_sptr& method,
26145{
26146 for (class_decl::member_functions::const_iterator i = fns.begin();
26147 i != fns.end();
26148 ++i)
26149 // Note that the comparison must be done in this order: method ==
26150 // *i This is to keep the consistency of the comparison. It's
26151 // important especially when doing type canonicalization. The
26152 // already canonicalize type is the left operand, and the type
26153 // being canonicalized is the right operand. This comes from the
26154 // code in type_base::get_canonical_type_for().
26155 if (methods_equal_modulo_elf_symbol(method, *i))
26156 return true;
26157
26158 return false;
26159}
26160
26161/// Compares two instances of @ref class_decl.
26162///
26163/// If the two intances are different, set a bitfield to give some
26164/// insight about the kind of differences there are.
26165///
26166/// @param l the first artifact of the comparison.
26167///
26168/// @param r the second artifact of the comparison.
26169///
26170/// @param k a pointer to a bitfield that gives information about the
26171/// kind of changes there are between @p l and @p r. This one is set
26172/// iff @p k is non-null and the function returns false.
26173///
26174/// Please note that setting k to a non-null value does have a
26175/// negative performance impact because even if @p l and @p r are not
26176/// equal, the function keeps up the comparison in order to determine
26177/// the different kinds of ways in which they are different.
26178///
26179/// @return true if @p l equals @p r, false otherwise.
26180bool
26182{
26183 {
26184 // First of all, let's see if these two types haven't already been
26185 // compared. If so, and if the result of the comparison has been
26186 // cached, let's just re-use it, rather than comparing them all
26187 // over again.
26188 bool result = false;
26189 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
26190 ABG_RETURN(result);
26191 }
26192
26193 // if one of the classes is declaration-only then we take a fast
26194 // path here.
26196 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
26197 static_cast<const class_or_union&>(r),
26198 k));
26199
26200 bool result = true;
26201 if (!equals(static_cast<const class_or_union&>(l),
26202 static_cast<const class_or_union&>(r),
26203 k))
26204 {
26205 result = false;
26206 if (!k)
26207 ABG_RETURN(result);
26208 }
26209
26211
26213
26214#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
26215
26216 // Compare bases.
26217 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
26218 {
26219 result = false;
26220 if (k)
26222 else
26223 RETURN(result);
26224 }
26225
26226 for (class_decl::base_specs::const_iterator
26227 b0 = l.get_base_specifiers().begin(),
26228 b1 = r.get_base_specifiers().begin();
26229 (b0 != l.get_base_specifiers().end()
26230 && b1 != r.get_base_specifiers().end());
26231 ++b0, ++b1)
26232 if (*b0 != *b1)
26233 {
26234 result = false;
26235 if (k)
26236 {
26237 if (!types_have_similar_structure((*b0)->get_base_class().get(),
26238 (*b1)->get_base_class().get()))
26240 else
26241 *k |= SUBTYPE_CHANGE_KIND;
26242 break;
26243 }
26244 RETURN(result);
26245 }
26246
26247 // Compare virtual member functions
26248
26249 // We look at the map that associates a given vtable offset to a
26250 // vector of virtual member functions that point to that offset.
26251 //
26252 // This is because there are cases where several functions can
26253 // point to the same virtual table offset.
26254 //
26255 // This is usually the case for virtual destructors. Even though
26256 // there can be only one virtual destructor declared in source
26257 // code, there are actually potentially up to three generated
26258 // functions for that destructor. Some of these generated
26259 // functions can be clones of other functions that are among those
26260 // generated ones. In any cases, they all have the same
26261 // properties, including the vtable offset property.
26262
26263 // So, there should be the same number of different vtable
26264 // offsets, the size of two maps must be equals.
26265 if (l.get_virtual_mem_fns_map().size()
26266 != r.get_virtual_mem_fns_map().size())
26267 {
26268 result = false;
26269 if (k)
26271 else
26272 RETURN(result);
26273 }
26274
26275 // Then, each virtual member function of a given vtable offset in
26276 // the first class type, must match an equivalent virtual member
26277 // function of a the same vtable offset in the second class type.
26278 //
26279 // By "match", I mean that the two virtual member function should
26280 // be equal if we don't take into account their symbol name or
26281 // their linkage name. This is because two destructor functions
26282 // clones (for instance) might have different linkage name, but
26283 // are still equivalent if their other properties are the same.
26284 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
26285 l.get_virtual_mem_fns_map().begin();
26286 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
26287 ++first_v_fn_entry)
26288 {
26289 unsigned voffset = first_v_fn_entry->first;
26290 const class_decl::member_functions& first_vfns =
26291 first_v_fn_entry->second;
26292
26293 const class_decl::virtual_mem_fn_map_type::const_iterator
26294 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
26295
26296 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
26297 {
26298 result = false;
26299 if (k)
26301 RETURN(result);
26302 }
26303
26304 const class_decl::member_functions& second_vfns =
26305 second_v_fn_entry->second;
26306
26307 bool matches = false;
26308 for (class_decl::member_functions::const_iterator i =
26309 first_vfns.begin();
26310 i != first_vfns.end();
26311 ++i)
26312 if (method_matches_at_least_one_in_vector(*i, second_vfns))
26313 {
26314 matches = true;
26315 break;
26316 }
26317
26318 if (!matches)
26319 {
26320 result = false;
26321 if (k)
26322 *k |= SUBTYPE_CHANGE_KIND;
26323 else
26324 RETURN(result);
26325 }
26326 }
26327
26328 RETURN(result);
26329#undef RETURN
26330}
26331
26332/// Copy a method of a class into a new class.
26333///
26334/// @param klass the class into which the method is to be copied.
26335///
26336/// @param method the method to copy into @p klass.
26337///
26338/// @return the resulting newly copied method.
26339method_decl_sptr
26340copy_member_function(class_decl_sptr clazz, const method_decl_sptr& f)
26341{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26342
26343/// Copy a method of a class into a new class.
26344///
26345/// @param klass the class into which the method is to be copied.
26346///
26347/// @param method the method to copy into @p klass.
26348///
26349/// @return the resulting newly copied method.
26350method_decl_sptr
26352{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26353
26354/// Comparison operator for @ref class_decl.
26355///
26356/// @param other the instance of @ref class_decl to compare against.
26357///
26358/// @return true iff the current instance of @ref class_decl equals @p
26359/// other.
26360bool
26362{
26363 const class_decl* op = is_class_type(&other);
26364 if (!op)
26365 {
26366 if (class_or_union* cou = is_class_or_union_type(&other))
26367 return class_or_union::operator==(*cou);
26368 return false;
26369 }
26370
26371 // If this is a decl-only type (and thus with no canonical type),
26372 // use the canonical type of the definition, if any.
26373 const class_decl *l = 0;
26375 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
26376 if (l == 0)
26377 l = this;
26378
26379 ABG_ASSERT(l);
26380
26381 // Likewise for the other type.
26382 const class_decl *r = 0;
26383 if (op->get_is_declaration_only())
26384 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
26385 if (r == 0)
26386 r = op;
26387
26388 ABG_ASSERT(r);
26389
26390 return try_canonical_compare(l, r);
26391}
26392
26393/// Equality operator for class_decl.
26394///
26395/// Re-uses the equality operator that takes a decl_base.
26396///
26397/// @param other the other class_decl to compare against.
26398///
26399/// @return true iff the current instance equals the other one.
26400bool
26402{
26403 const decl_base* o = is_decl(&other);
26404 if (!o)
26405 return false;
26406 return *this == *o;
26407}
26408
26409/// Equality operator for class_decl.
26410///
26411/// Re-uses the equality operator that takes a decl_base.
26412///
26413/// @param other the other class_decl to compare against.
26414///
26415/// @return true iff the current instance equals the other one.
26416bool
26418{
26419 const decl_base& o = other;
26420 return *this == o;
26421}
26422
26423/// Comparison operator for @ref class_decl.
26424///
26425/// @param other the instance of @ref class_decl to compare against.
26426///
26427/// @return true iff the current instance of @ref class_decl equals @p
26428/// other.
26429bool
26431{
26432 const decl_base& o = other;
26433 return *this == o;
26434}
26435
26436/// Turn equality of shared_ptr of class_decl into a deep equality;
26437/// that is, make it compare the pointed to objects too.
26438///
26439/// @param l the shared_ptr of class_decl on left-hand-side of the
26440/// equality.
26441///
26442/// @param r the shared_ptr of class_decl on right-hand-side of the
26443/// equality.
26444///
26445/// @return true if the class_decl pointed to by the shared_ptrs are
26446/// equal, false otherwise.
26447bool
26449{
26450 if (l.get() == r.get())
26451 return true;
26452 if (!!l != !!r)
26453 return false;
26454
26455 return *l == *r;
26456}
26457
26458/// Turn inequality of shared_ptr of class_decl into a deep equality;
26459/// that is, make it compare the pointed to objects too.
26460///
26461/// @param l the shared_ptr of class_decl on left-hand-side of the
26462/// equality.
26463///
26464/// @param r the shared_ptr of class_decl on right-hand-side of the
26465/// equality.
26466///
26467/// @return true if the class_decl pointed to by the shared_ptrs are
26468/// different, false otherwise.
26469bool
26471{return !operator==(l, r);}
26472
26473/// Turn equality of shared_ptr of class_or_union into a deep
26474/// equality; that is, make it compare the pointed to objects too.
26475///
26476/// @param l the left-hand-side operand of the operator
26477///
26478/// @param r the right-hand-side operand of the operator.
26479///
26480/// @return true iff @p l equals @p r.
26481bool
26482operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
26483{
26484 if (l.get() == r.get())
26485 return true;
26486 if (!!l != !!r)
26487 return false;
26488
26489 return *l == *r;
26490}
26491
26492/// Turn inequality of shared_ptr of class_or_union into a deep
26493/// equality; that is, make it compare the pointed to objects too.
26494///
26495/// @param l the left-hand-side operand of the operator
26496///
26497/// @param r the right-hand-side operand of the operator.
26498///
26499/// @return true iff @p l is different from @p r.
26500bool
26501operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
26502{return !operator==(l, r);}
26503
26504/// This implements the ir_traversable_base::traverse pure virtual
26505/// function.
26506///
26507/// @param v the visitor used on the current instance and on its
26508/// members.
26509///
26510/// @return true if the entire IR node tree got traversed, false
26511/// otherwise.
26512bool
26514{
26515 if (v.type_node_has_been_visited(this))
26516 return true;
26517
26518 if (visiting())
26519 return true;
26520
26521 if (v.visit_begin(this))
26522 {
26523 visiting(true);
26524 bool stop = false;
26525
26526 for (base_specs::const_iterator i = get_base_specifiers().begin();
26527 i != get_base_specifiers().end();
26528 ++i)
26529 {
26530 if (!(*i)->traverse(v))
26531 {
26532 stop = true;
26533 break;
26534 }
26535 }
26536
26537 if (!stop)
26538 for (data_members::const_iterator i = get_data_members().begin();
26539 i != get_data_members().end();
26540 ++i)
26541 if (!(*i)->traverse(v))
26542 {
26543 stop = true;
26544 break;
26545 }
26546
26547 if (!stop)
26548 for (member_functions::const_iterator i= get_member_functions().begin();
26549 i != get_member_functions().end();
26550 ++i)
26551 if (!(*i)->traverse(v))
26552 {
26553 stop = true;
26554 break;
26555 }
26556
26557 if (!stop)
26558 for (member_types::const_iterator i = get_member_types().begin();
26559 i != get_member_types().end();
26560 ++i)
26561 if (!(*i)->traverse(v))
26562 {
26563 stop = true;
26564 break;
26565 }
26566
26567 if (!stop)
26568 for (member_function_templates::const_iterator i =
26570 i != get_member_function_templates().end();
26571 ++i)
26572 if (!(*i)->traverse(v))
26573 {
26574 stop = true;
26575 break;
26576 }
26577
26578 if (!stop)
26579 for (member_class_templates::const_iterator i =
26581 i != get_member_class_templates().end();
26582 ++i)
26583 if (!(*i)->traverse(v))
26584 {
26585 stop = true;
26586 break;
26587 }
26588 visiting(false);
26589 }
26590
26591 bool result = v.visit_end(this);
26593 return result;
26594}
26595
26596/// Destructor of the @ref class_decl type.
26598{delete priv_;}
26599
26600context_rel::~context_rel()
26601{}
26602
26603bool
26604member_base::operator==(const member_base& o) const
26605{
26607 && get_is_static() == o.get_is_static());
26608}
26609
26610/// Equality operator for smart pointers to @ref
26611/// class_decl::base_specs.
26612///
26613/// This compares the pointed-to objects.
26614///
26615/// @param l the first instance to consider.
26616///
26617/// @param r the second instance to consider.
26618///
26619/// @return true iff @p l equals @p r.
26620bool
26623{
26624 if (l.get() == r.get())
26625 return true;
26626 if (!!l != !!r)
26627 return false;
26628
26629 return *l == static_cast<const decl_base&>(*r);
26630}
26631
26632/// Inequality operator for smart pointers to @ref
26633/// class_decl::base_specs.
26634///
26635/// This compares the pointed-to objects.
26636///
26637/// @param l the first instance to consider.
26638///
26639/// @param r the second instance to consider.
26640///
26641/// @return true iff @p l is different from @p r.
26642bool
26645{return !operator==(l, r);}
26646
26647/// Test if an ABI artifact is a class base specifier.
26648///
26649/// @param tod the ABI artifact to consider.
26650///
26651/// @return a pointer to the @ref class_decl::base_spec sub-object of
26652/// @p tod iff it's a class base specifier.
26655{
26656 return dynamic_cast<class_decl::base_spec*>
26657 (const_cast<type_or_decl_base*>(tod));
26658}
26659
26660/// Test if an ABI artifact is a class base specifier.
26661///
26662/// @param tod the ABI artifact to consider.
26663///
26664/// @return a pointer to the @ref class_decl::base_spec sub-object of
26665/// @p tod iff it's a class base specifier.
26668{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
26669
26670bool
26671member_function_template::operator==(const member_base& other) const
26672{
26673 try
26674 {
26675 const member_function_template& o =
26676 dynamic_cast<const member_function_template&>(other);
26677
26678 if (!(is_constructor() == o.is_constructor()
26679 && is_const() == o.is_const()
26680 && member_base::operator==(o)))
26681 return false;
26682
26683 if (function_tdecl_sptr ftdecl = as_function_tdecl())
26684 {
26685 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
26686 if (other_ftdecl)
26687 return ftdecl->function_tdecl::operator==(*other_ftdecl);
26688 }
26689 }
26690 catch(...)
26691 {}
26692 return false;
26693}
26694
26695/// Equality operator for smart pointers to @ref
26696/// member_function_template. This is compares the
26697/// pointed-to instances.
26698///
26699/// @param l the first instance to consider.
26700///
26701/// @param r the second instance to consider.
26702///
26703/// @return true iff @p l equals @p r.
26704bool
26705operator==(const member_function_template_sptr& l,
26706 const member_function_template_sptr& r)
26707{
26708 if (l.get() == r.get())
26709 return true;
26710 if (!!l != !!r)
26711 return false;
26712
26713 return *l == *r;
26714}
26715
26716/// Inequality operator for smart pointers to @ref
26717/// member_function_template. This is compares the pointed-to
26718/// instances.
26719///
26720/// @param l the first instance to consider.
26721///
26722/// @param r the second instance to consider.
26723///
26724/// @return true iff @p l equals @p r.
26725bool
26726operator!=(const member_function_template_sptr& l,
26727 const member_function_template_sptr& r)
26728{return !operator==(l, r);}
26729
26730/// This implements the ir_traversable_base::traverse pure virtual
26731/// function.
26732///
26733/// @param v the visitor used on the current instance and on its
26734/// underlying function template.
26735///
26736/// @return true if the entire IR node tree got traversed, false
26737/// otherwise.
26738bool
26740{
26741 if (visiting())
26742 return true;
26743
26744 if (v.visit_begin(this))
26745 {
26746 visiting(true);
26747 if (function_tdecl_sptr f = as_function_tdecl())
26748 f->traverse(v);
26749 visiting(false);
26750 }
26751 return v.visit_end(this);
26752}
26753
26754/// Equality operator of the the @ref member_class_template class.
26755///
26756/// @param other the other @ref member_class_template to compare against.
26757///
26758/// @return true iff the current instance equals @p other.
26759bool
26761{
26762 try
26763 {
26764 const member_class_template& o =
26765 dynamic_cast<const member_class_template&>(other);
26766
26767 if (!member_base::operator==(o))
26768 return false;
26769
26770 return as_class_tdecl()->class_tdecl::operator==(o);
26771 }
26772 catch(...)
26773 {return false;}
26774}
26775
26776/// Equality operator of the the @ref member_class_template class.
26777///
26778/// @param other the other @ref member_class_template to compare against.
26779///
26780/// @return true iff the current instance equals @p other.
26781bool
26783{
26784 if (!decl_base::operator==(other))
26785 return false;
26786 return as_class_tdecl()->class_tdecl::operator==(other);
26787}
26788
26789/// Comparison operator for the @ref member_class_template
26790/// type.
26791///
26792/// @param other the other instance of @ref
26793/// member_class_template to compare against.
26794///
26795/// @return true iff the two instances are equal.
26796bool
26798{
26799 const decl_base* o = dynamic_cast<const decl_base*>(&other);
26800 return *this == *o;
26801}
26802
26803/// Comparison operator for the @ref member_class_template
26804/// type.
26805///
26806/// @param l the first argument of the operator.
26807///
26808/// @param r the second argument of the operator.
26809///
26810/// @return true iff the two instances are equal.
26811bool
26812operator==(const member_class_template_sptr& l,
26813 const member_class_template_sptr& r)
26814{
26815 if (l.get() == r.get())
26816 return true;
26817 if (!!l != !!r)
26818 return false;
26819
26820 return *l == *r;
26821}
26822
26823/// Inequality operator for the @ref member_class_template
26824/// type.
26825///
26826/// @param l the first argument of the operator.
26827///
26828/// @param r the second argument of the operator.
26829///
26830/// @return true iff the two instances are equal.
26831bool
26832operator!=(const member_class_template_sptr& l,
26833 const member_class_template_sptr& r)
26834{return !operator==(l, r);}
26835
26836/// This implements the ir_traversable_base::traverse pure virtual
26837/// function.
26838///
26839/// @param v the visitor used on the current instance and on the class
26840/// pattern of the template.
26841///
26842/// @return true if the entire IR node tree got traversed, false
26843/// otherwise.
26844bool
26846{
26847 if (visiting())
26848 return true;
26849
26850 if (v.visit_begin(this))
26851 {
26852 visiting(true);
26853 if (class_tdecl_sptr t = as_class_tdecl())
26854 t->traverse(v);
26855 visiting(false);
26856 }
26857 return v.visit_end(this);
26858}
26859
26860/// Streaming operator for class_decl::access_specifier.
26861///
26862/// @param o the output stream to serialize the access specifier to.
26863///
26864/// @param a the access specifier to serialize.
26865///
26866/// @return the output stream.
26867std::ostream&
26868operator<<(std::ostream& o, access_specifier a)
26869{
26870 string r;
26871
26872 switch (a)
26873 {
26874 case no_access:
26875 r = "none";
26876 break;
26877 case private_access:
26878 r = "private";
26879 break;
26880 case protected_access:
26881 r = "protected";
26882 break;
26883 case public_access:
26884 r= "public";
26885 break;
26886 };
26887 o << r;
26888 return o;
26889}
26890
26891/// Sets the static-ness property of a class member.
26892///
26893/// @param d the class member to set the static-ness property for.
26894/// Note that this must be a class member otherwise the function
26895/// aborts the current process.
26896///
26897/// @param s this must be true if the member is to be static, false
26898/// otherwise.
26899void
26901{
26903
26905 ABG_ASSERT(c);
26906
26907 c->set_is_static(s);
26908
26909 scope_decl* scope = d.get_scope();
26910
26911 if (class_or_union* cl = is_class_or_union_type(scope))
26912 {
26913 if (var_decl* v = is_var_decl(&d))
26914 {
26915 // First, find v in the set of data members.
26916 var_decl_sptr var;
26917 for (const auto& dm : cl->get_data_members())
26918 if (dm->get_name() == v->get_name())
26919 {
26920 var = dm;
26921 break;
26922 }
26923 if (!var)
26924 return;
26925
26926 if (s)
26927 {
26928 // remove from the non-static data members
26929 for (class_decl::data_members::iterator i =
26930 cl->priv_->non_static_data_members_.begin();
26931 i != cl->priv_->non_static_data_members_.end();
26932 ++i)
26933 {
26934 if ((*i)->get_name() == v->get_name())
26935 {
26936 cl->priv_->non_static_data_members_.erase(i);
26937 break;
26938 }
26939 }
26940
26941 // If it's not in the static data members, then add it
26942 // there.
26943 bool already_in_static_dms = false;
26944 for (const auto& s_dm : cl->priv_->static_data_members_)
26945 if (s_dm->get_name() == v->get_name())
26946 {
26947 already_in_static_dms = true;
26948 break;
26949 }
26950 if (!already_in_static_dms)
26951 cl->priv_->static_data_members_.push_back(var);
26952 }
26953 else // is non-static
26954 {
26955 // Remove from the static data members.
26956 for (class_or_union::data_members::iterator i =
26957 cl->priv_->static_data_members_.begin();
26958 i != cl->priv_->static_data_members_.end();
26959 ++i)
26960 if ((*i)->get_name() == v->get_name())
26961 {
26962 cl->priv_->static_data_members_.erase(i);
26963 break;
26964 }
26965
26966 // If it's not already in the non-static data members
26967 // then add it there.
26968 bool is_already_in_non_static_data_members = false;
26969 for (const auto& ns_dm : cl->priv_->non_static_data_members_)
26970 if (ns_dm->get_name() == v->get_name())
26971 {
26972 is_already_in_non_static_data_members = true;
26973 break;
26974 }
26975 if (!is_already_in_non_static_data_members)
26976 cl->priv_->non_static_data_members_.push_back(var);
26977 }
26978 }
26979 }
26980}
26981
26982/// Sets the static-ness property of a class member.
26983///
26984/// @param d the class member to set the static-ness property for.
26985/// Note that this must be a class member otherwise the function
26986/// aborts the current process.
26987///
26988/// @param s this must be true if the member is to be static, false
26989/// otherwise.
26990void
26991set_member_is_static(const decl_base_sptr& d, bool s)
26992{set_member_is_static(*d, s);}
26993
26994// </class_decl>
26995
26996// <union_decl>
26997
26998/// Constructor for the @ref union_decl type.
26999///
27000/// @param env the @ref environment we are operating from.
27001///
27002/// @param name the name of the union type.
27003///
27004/// @param size_in_bits the size of the union, in bits.
27005///
27006/// @param locus the location of the type.
27007///
27008/// @param vis the visibility of instances of @ref union_decl.
27009///
27010/// @param mbr_types the member types of the union.
27011///
27012/// @param data_mbrs the data members of the union.
27013///
27014/// @param member_fns the member functions of the union.
27015union_decl::union_decl(const environment& env, const string& name,
27016 size_t size_in_bits, const location& locus,
27017 visibility vis, member_types& mbr_types,
27018 data_members& data_mbrs, member_functions& member_fns)
27019 : type_or_decl_base(env,
27020 UNION_TYPE
27021 | ABSTRACT_TYPE_BASE
27022 | ABSTRACT_DECL_BASE),
27023 decl_base(env, name, locus, name, vis),
27024 type_base(env, size_in_bits, 0),
27025 class_or_union(env, name, size_in_bits, 0,
27026 locus, vis, mbr_types, data_mbrs, member_fns)
27027{
27029}
27030
27031/// Constructor for the @ref union_decl type.
27032///
27033/// @param env the @ref environment we are operating from.
27034///
27035/// @param name the name of the union type.
27036///
27037/// @param size_in_bits the size of the union, in bits.
27038///
27039/// @param locus the location of the type.
27040///
27041/// @param vis the visibility of instances of @ref union_decl.
27042///
27043/// @param mbr_types the member types of the union.
27044///
27045/// @param data_mbrs the data members of the union.
27046///
27047/// @param member_fns the member functions of the union.
27048///
27049/// @param is_anonymous whether the newly created instance is
27050/// anonymous.
27051union_decl::union_decl(const environment& env, const string& name,
27052 size_t size_in_bits, const location& locus,
27053 visibility vis, member_types& mbr_types,
27054 data_members& data_mbrs, member_functions& member_fns,
27055 bool is_anonymous)
27056 : type_or_decl_base(env,
27057 UNION_TYPE
27058 | ABSTRACT_TYPE_BASE
27059 | ABSTRACT_DECL_BASE),
27060 decl_base(env, name, locus,
27061 // If the class is anonymous then by default it won't
27062 // have a linkage name. Also, the anonymous class does
27063 // have an internal-only unique name that is generally
27064 // not taken into account when comparing classes; such a
27065 // unique internal-only name, when used as a linkage
27066 // name might introduce spurious comparison false
27067 // negatives.
27068 /*linkage_name=*/is_anonymous ? string() : name,
27069 vis),
27070 type_base(env, size_in_bits, 0),
27071 class_or_union(env, name, size_in_bits, 0,
27072 locus, vis, mbr_types, data_mbrs, member_fns)
27073{
27075 set_is_anonymous(is_anonymous);
27076}
27077
27078/// Constructor for the @ref union_decl type.
27079///
27080/// @param env the @ref environment we are operating from.
27081///
27082/// @param name the name of the union type.
27083///
27084/// @param size_in_bits the size of the union, in bits.
27085///
27086/// @param locus the location of the type.
27087///
27088/// @param vis the visibility of instances of @ref union_decl.
27089union_decl::union_decl(const environment& env, const string& name,
27090 size_t size_in_bits, const location& locus,
27091 visibility vis)
27092 : type_or_decl_base(env,
27093 UNION_TYPE
27094 | ABSTRACT_TYPE_BASE
27095 | ABSTRACT_DECL_BASE
27096 | ABSTRACT_SCOPE_TYPE_DECL
27097 | ABSTRACT_SCOPE_DECL),
27098 decl_base(env, name, locus, name, vis),
27099 type_base(env, size_in_bits, 0),
27100 class_or_union(env, name, size_in_bits,
27101 0, locus, vis)
27102{
27104}
27105
27106/// Constructor for the @ref union_decl type.
27107///
27108/// @param env the @ref environment we are operating from.
27109///
27110/// @param name the name of the union type.
27111///
27112/// @param size_in_bits the size of the union, in bits.
27113///
27114/// @param locus the location of the type.
27115///
27116/// @param vis the visibility of instances of @ref union_decl.
27117///
27118/// @param is_anonymous whether the newly created instance is
27119/// anonymous.
27120union_decl::union_decl(const environment& env, const string& name,
27121 size_t size_in_bits, const location& locus,
27122 visibility vis, bool is_anonymous)
27123 : type_or_decl_base(env,
27124 UNION_TYPE
27125 | ABSTRACT_TYPE_BASE
27126 | ABSTRACT_DECL_BASE
27127 | ABSTRACT_SCOPE_TYPE_DECL
27128 | ABSTRACT_SCOPE_DECL),
27129 decl_base(env, name, locus,
27130 // If the class is anonymous then by default it won't
27131 // have a linkage name. Also, the anonymous class does
27132 // have an internal-only unique name that is generally
27133 // not taken into account when comparing classes; such a
27134 // unique internal-only name, when used as a linkage
27135 // name might introduce spurious comparison false
27136 // negatives.
27137 /*linkage_name=*/is_anonymous ? string() : name,
27138 vis),
27139 type_base(env, size_in_bits, 0),
27140 class_or_union(env, name, size_in_bits,
27141 0, locus, vis)
27142{
27144 set_is_anonymous(is_anonymous);
27145}
27146
27147/// Constructor for the @ref union_decl type.
27148///
27149/// @param env the @ref environment we are operating from.
27150///
27151/// @param name the name of the union type.
27152///
27153/// @param is_declaration_only a boolean saying whether the instance
27154/// represents a declaration only, or not.
27155union_decl::union_decl(const environment& env,
27156 const string& name,
27157 bool is_declaration_only)
27158 : type_or_decl_base(env,
27159 UNION_TYPE
27160 | ABSTRACT_TYPE_BASE
27161 | ABSTRACT_DECL_BASE
27162 | ABSTRACT_SCOPE_TYPE_DECL
27163 | ABSTRACT_SCOPE_DECL),
27164 decl_base(env, name, location(), name),
27165 type_base(env, 0, 0),
27166 class_or_union(env, name, is_declaration_only)
27167{
27169}
27170
27171/// Return the hash value of the current IR node.
27172///
27173/// Note that upon the first invocation, this member functions
27174/// computes the hash value and returns it. Subsequent invocations
27175/// just return the hash value that was previously calculated.
27176///
27177/// @return the hash value of the current IR node.
27178hash_t
27180{
27182 return h;
27183}
27184
27185/// Getter of the pretty representation of the current instance of
27186/// @ref union_decl.
27187///
27188/// @param internal set to true if the call is intended to get a
27189/// representation of the decl (or type) for the purpose of canonical
27190/// type comparison. This is mainly used in the function
27191/// type_base::get_canonical_type_for().
27192///
27193/// In other words if the argument for this parameter is true then the
27194/// call is meant for internal use (for technical use inside the
27195/// library itself), false otherwise. If you don't know what this is
27196/// for, then set it to false.
27197///
27198/// @param qualified_name if true, names emitted in the pretty
27199/// representation are fully qualified.
27200///
27201/// @return the pretty representaion for a union_decl.
27202string
27204 bool qualified_name) const
27205{
27206 string repr;
27207 if (get_is_anonymous())
27208 {
27209 if (internal && !get_name().empty())
27210 repr = string("union ") +
27211 get_type_name(this, qualified_name, /*internal=*/true);
27212 else
27214 /*one_line=*/true,
27215 internal);
27216 }
27217 else
27218 {
27219 repr = "union ";
27220 if (qualified_name)
27221 repr += get_qualified_name(internal);
27222 else
27223 repr += get_name();
27224 }
27225
27226 return repr;
27227}
27228
27229/// Comparison operator for @ref union_decl.
27230///
27231/// @param other the instance of @ref union_decl to compare against.
27232///
27233/// @return true iff the current instance of @ref union_decl equals @p
27234/// other.
27235bool
27237{
27238 const union_decl* op = dynamic_cast<const union_decl*>(&other);
27239 if (!op)
27240 return false;
27241 return try_canonical_compare(this, op);
27242}
27243
27244/// Equality operator for union_decl.
27245///
27246/// Re-uses the equality operator that takes a decl_base.
27247///
27248/// @param other the other union_decl to compare against.
27249///
27250/// @return true iff the current instance equals the other one.
27251bool
27253{
27254 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27255 if (!o)
27256 return false;
27257 return *this == *o;
27258}
27259
27260/// Equality operator for union_decl.
27261///
27262/// Re-uses the equality operator that takes a decl_base.
27263///
27264/// @param other the other union_decl to compare against.
27265///
27266/// @return true iff the current instance equals the other one.
27267bool
27269{
27270 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27271 return *this == *o;
27272}
27273
27274/// Comparison operator for @ref union_decl.
27275///
27276/// @param other the instance of @ref union_decl to compare against.
27277///
27278/// @return true iff the current instance of @ref union_decl equals @p
27279/// other.
27280bool
27282{
27283 const decl_base& o = other;
27284 return *this == o;
27285}
27286
27287/// This implements the ir_traversable_base::traverse pure virtual
27288/// function.
27289///
27290/// @param v the visitor used on the current instance and on its
27291/// members.
27292///
27293/// @return true if the entire IR node tree got traversed, false
27294/// otherwise.
27295bool
27297{
27298 if (v.type_node_has_been_visited(this))
27299 return true;
27300
27301 if (visiting())
27302 return true;
27303
27304 if (v.visit_begin(this))
27305 {
27306 visiting(true);
27307 bool stop = false;
27308
27309 if (!stop)
27310 for (data_members::const_iterator i = get_data_members().begin();
27311 i != get_data_members().end();
27312 ++i)
27313 if (!(*i)->traverse(v))
27314 {
27315 stop = true;
27316 break;
27317 }
27318
27319 if (!stop)
27320 for (member_functions::const_iterator i= get_member_functions().begin();
27321 i != get_member_functions().end();
27322 ++i)
27323 if (!(*i)->traverse(v))
27324 {
27325 stop = true;
27326 break;
27327 }
27328
27329 if (!stop)
27330 for (member_types::const_iterator i = get_member_types().begin();
27331 i != get_member_types().end();
27332 ++i)
27333 if (!(*i)->traverse(v))
27334 {
27335 stop = true;
27336 break;
27337 }
27338
27339 if (!stop)
27340 for (member_function_templates::const_iterator i =
27342 i != get_member_function_templates().end();
27343 ++i)
27344 if (!(*i)->traverse(v))
27345 {
27346 stop = true;
27347 break;
27348 }
27349
27350 if (!stop)
27351 for (member_class_templates::const_iterator i =
27353 i != get_member_class_templates().end();
27354 ++i)
27355 if (!(*i)->traverse(v))
27356 {
27357 stop = true;
27358 break;
27359 }
27360 visiting(false);
27361 }
27362
27363 bool result = v.visit_end(this);
27365 return result;
27366}
27367
27368/// Destructor of the @ref union_decl type.
27371
27372/// Compares two instances of @ref union_decl.
27373///
27374/// If the two intances are different, set a bitfield to give some
27375/// insight about the kind of differences there are.
27376///
27377/// @param l the first artifact of the comparison.
27378///
27379/// @param r the second artifact of the comparison.
27380///
27381/// @param k a pointer to a bitfield that gives information about the
27382/// kind of changes there are between @p l and @p r. This one is set
27383/// iff @p k is non-null and the function returns false.
27384///
27385/// Please note that setting k to a non-null value does have a
27386/// negative performance impact because even if @p l and @p r are not
27387/// equal, the function keeps up the comparison in order to determine
27388/// the different kinds of ways in which they are different.
27389///
27390/// @return true if @p l equals @p r, false otherwise.
27391bool
27393{
27394
27396
27397 {
27398 // First of all, let's see if these two types haven't already been
27399 // compared. If so, and if the result of the comparison has been
27400 // cached, let's just re-use it, rather than comparing them all
27401 // over again.
27402 bool result = false;
27403 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
27404 ABG_RETURN(result);
27405 }
27406
27407 bool result = equals(static_cast<const class_or_union&>(l),
27408 static_cast<const class_or_union&>(r),
27409 k);
27410
27412}
27413
27414/// Copy a method of a @ref union_decl into a new @ref
27415/// union_decl.
27416///
27417/// @param t the @ref union_decl into which the method is to be copied.
27418///
27419/// @param method the method to copy into @p t.
27420///
27421/// @return the resulting newly copied method.
27422method_decl_sptr
27423copy_member_function(union_decl_sptr union_type,
27424 const method_decl_sptr& f)
27425{return copy_member_function(union_type, f.get());}
27426
27427/// Copy a method of a @ref union_decl into a new @ref
27428/// union_decl.
27429///
27430/// @param t the @ref union_decl into which the method is to be copied.
27431///
27432/// @param method the method to copy into @p t.
27433///
27434/// @return the resulting newly copied method.
27435method_decl_sptr
27436copy_member_function(union_decl_sptr union_type,
27437 const method_decl* f)
27438{
27439 const class_or_union_sptr t = union_type;
27440 return copy_member_function(t, f);
27441}
27442
27443/// Turn equality of shared_ptr of union_decl into a deep equality;
27444/// that is, make it compare the pointed to objects too.
27445///
27446/// @param l the left-hand-side operand of the operator
27447///
27448/// @param r the right-hand-side operand of the operator.
27449///
27450/// @return true iff @p l equals @p r.
27451bool
27452operator==(const union_decl_sptr& l, const union_decl_sptr& r)
27453{
27454 if (l.get() == r.get())
27455 return true;
27456 if (!!l != !!r)
27457 return false;
27458
27459 return *l == *r;
27460}
27461
27462/// Turn inequality of shared_ptr of union_decl into a deep equality;
27463/// that is, make it compare the pointed to objects too.
27464///
27465/// @param l the left-hand-side operand of the operator
27466///
27467/// @param r the right-hand-side operand of the operator.
27468///
27469/// @return true iff @p l is different from @p r.
27470bool
27471operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
27472{return !operator==(l, r);}
27473// </union_decl>
27474
27475// <template_decl stuff>
27476
27477/// Data type of the private data of the @template_decl type.
27478class template_decl::priv
27479{
27480 friend class template_decl;
27481
27482 std::list<template_parameter_sptr> parms_;
27483public:
27484
27485 priv()
27486 {}
27487}; // end class template_decl::priv
27488
27489/// Add a new template parameter to the current instance of @ref
27490/// template_decl.
27491///
27492/// @param p the new template parameter to add.
27493void
27495{priv_->parms_.push_back(p);}
27496
27497/// Get the list of template parameters of the current instance of
27498/// @ref template_decl.
27499///
27500/// @return the list of template parameters.
27501const std::list<template_parameter_sptr>&
27503{return priv_->parms_;}
27504
27505/// Constructor.
27506///
27507/// @param env the environment we are operating from.
27508///
27509/// @param name the name of the template decl.
27510///
27511/// @param locus the source location where the template declaration is
27512/// defined.
27513///
27514/// @param vis the visibility of the template declaration.
27515template_decl::template_decl(const environment& env,
27516 const string& name,
27517 const location& locus,
27518 visibility vis)
27519 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
27520 decl_base(env, name, locus, /*mangled_name=*/"", vis),
27521 priv_(new priv)
27522{
27524}
27525
27526/// Destructor.
27529
27530/// Equality operator.
27531///
27532/// @param o the other instance to compare against.
27533///
27534/// @return true iff @p equals the current instance.
27535bool
27537{
27538 const template_decl* other = dynamic_cast<const template_decl*>(&o);
27539 if (!other)
27540 return false;
27541 return *this == *other;
27542}
27543
27544/// Equality operator.
27545///
27546/// @param o the other instance to compare against.
27547///
27548/// @return true iff @p equals the current instance.
27549bool
27551{
27552 try
27553 {
27554 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
27555 for (t0 = get_template_parameters().begin(),
27556 t1 = o.get_template_parameters().begin();
27557 (t0 != get_template_parameters().end()
27558 && t1 != o.get_template_parameters().end());
27559 ++t0, ++t1)
27560 {
27561 if (**t0 != **t1)
27562 return false;
27563 }
27564
27565 if (t0 != get_template_parameters().end()
27566 || t1 != o.get_template_parameters().end())
27567 return false;
27568
27569 return true;
27570 }
27571 catch(...)
27572 {return false;}
27573}
27574
27575// </template_decl stuff>
27576
27577//<template_parameter>
27578
27579/// The type of the private data of the @ref template_parameter type.
27580class template_parameter::priv
27581{
27582 friend class template_parameter;
27583
27584 unsigned index_;
27585 template_decl_wptr template_decl_;
27586 mutable bool hashing_started_;
27587 mutable bool comparison_started_;
27588
27589 priv();
27590
27591public:
27592
27593 priv(unsigned index, template_decl_sptr enclosing_template_decl)
27594 : index_(index),
27595 template_decl_(enclosing_template_decl),
27596 hashing_started_(),
27597 comparison_started_()
27598 {}
27599}; // end class template_parameter::priv
27600
27601template_parameter::template_parameter(unsigned index,
27602 template_decl_sptr enclosing_template)
27603 : priv_(new priv(index, enclosing_template))
27604 {}
27605
27606unsigned
27607template_parameter::get_index() const
27608{return priv_->index_;}
27609
27611template_parameter::get_enclosing_template_decl() const
27612{return priv_->template_decl_.lock();}
27613
27614
27615bool
27616template_parameter::operator==(const template_parameter& o) const
27617{
27618 if (get_index() != o.get_index())
27619 return false;
27620
27621 if (priv_->comparison_started_)
27622 return true;
27623
27624 bool result = false;
27625
27626 // Avoid inifite loops due to the fact that comparison the enclosing
27627 // template decl might lead to comparing this very same template
27628 // parameter with another one ...
27629 priv_->comparison_started_ = true;
27630
27631 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
27632 ;
27633 else if (get_enclosing_template_decl()
27634 && (*get_enclosing_template_decl()
27635 != *o.get_enclosing_template_decl()))
27636 ;
27637 else
27638 result = true;
27639
27640 priv_->comparison_started_ = false;
27641
27642 return result;
27643}
27644
27645/// Inequality operator.
27646///
27647/// @param other the other instance to compare against.
27648///
27649/// @return true iff the other instance is different from the current
27650/// one.
27651bool
27653{return !operator==(other);}
27654
27655/// Destructor.
27658
27659/// The type of the private data of the @ref type_tparameter type.
27660class type_tparameter::priv
27661{
27662 friend class type_tparameter;
27663}; // end class type_tparameter::priv
27664
27665/// Constructor of the @ref type_tparameter type.
27666///
27667/// @param index the index the type template parameter.
27668///
27669/// @param enclosing_tdecl the enclosing template declaration.
27670///
27671/// @param name the name of the template parameter.
27672///
27673/// @param locus the location of the declaration of this type template
27674/// parameter.
27675type_tparameter::type_tparameter(unsigned index,
27676 template_decl_sptr enclosing_tdecl,
27677 const string& name,
27678 const location& locus)
27679 : type_or_decl_base(enclosing_tdecl->get_environment(),
27680 ABSTRACT_DECL_BASE
27681 | ABSTRACT_TYPE_BASE
27682 | BASIC_TYPE),
27683 decl_base(enclosing_tdecl->get_environment(), name, locus),
27684 type_base(enclosing_tdecl->get_environment(), 0, 0),
27685 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
27686 template_parameter(index, enclosing_tdecl),
27687 priv_(new priv)
27688{
27690}
27691
27692/// Equality operator.
27693///
27694/// @param other the other template type parameter to compare against.
27695///
27696/// @return true iff @p other equals the current instance.
27697bool
27699{
27700 if (!type_decl::operator==(other))
27701 return false;
27702
27703 try
27704 {
27705 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27706 return template_parameter::operator==(o);
27707 }
27708 catch (...)
27709 {return false;}
27710}
27711
27712/// Equality operator.
27713///
27714/// @param other the other template type parameter to compare against.
27715///
27716/// @return true iff @p other equals the current instance.
27717bool
27719{
27720 if (!type_decl::operator==(other))
27721 return false;
27722
27723 try
27724 {
27725 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27726 return template_parameter::operator==(o);
27727 }
27728 catch (...)
27729 {return false;}
27730}
27731
27732/// Equality operator.
27733///
27734/// @param other the other template type parameter to compare against.
27735///
27736/// @return true iff @p other equals the current instance.
27737bool
27739{
27740 if (!decl_base::operator==(other))
27741 return false;
27742
27743 try
27744 {
27745 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27746 return template_parameter::operator==(o);
27747 }
27748 catch (...)
27749 {return false;}
27750}
27751
27752/// Equality operator.
27753///
27754/// @param other the other template type parameter to compare against.
27755///
27756/// @return true iff @p other equals the current instance.
27757bool
27759{
27760 try
27761 {
27762 const type_base& o = dynamic_cast<const type_base&>(other);
27763 return *this == o;
27764 }
27765 catch(...)
27766 {return false;}
27767}
27768
27769/// Equality operator.
27770///
27771/// @param other the other template type parameter to compare against.
27772///
27773/// @return true iff @p other equals the current instance.
27774bool
27776{return *this == static_cast<const type_base&>(other);}
27777
27778type_tparameter::~type_tparameter()
27779{}
27780
27781/// The type of the private data of the @ref non_type_tparameter type.
27782class non_type_tparameter::priv
27783{
27784 friend class non_type_tparameter;
27785
27786 type_base_wptr type_;
27787
27788 priv();
27789
27790public:
27791
27792 priv(type_base_sptr type)
27793 : type_(type)
27794 {}
27795}; // end class non_type_tparameter::priv
27796
27797/// The constructor for the @ref non_type_tparameter type.
27798///
27799/// @param index the index of the template parameter.
27800///
27801/// @param enclosing_tdecl the enclosing template declaration that
27802/// holds this parameter parameter.
27803///
27804/// @param name the name of the template parameter.
27805///
27806/// @param type the type of the template parameter.
27807///
27808/// @param locus the location of the declaration of this template
27809/// parameter.
27810non_type_tparameter::non_type_tparameter(unsigned index,
27811 template_decl_sptr enclosing_tdecl,
27812 const string& name,
27813 type_base_sptr type,
27814 const location& locus)
27815 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
27816 decl_base(type->get_environment(), name, locus, ""),
27817 template_parameter(index, enclosing_tdecl),
27818 priv_(new priv(type))
27819{
27821}
27822
27823/// Getter for the type of the template parameter.
27824///
27825/// @return the type of the template parameter.
27826const type_base_sptr
27828{return priv_->type_.lock();}
27829
27830
27831bool
27833{
27834 if (!decl_base::operator==(other))
27835 return false;
27836
27837 try
27838 {
27839 const non_type_tparameter& o =
27840 dynamic_cast<const non_type_tparameter&>(other);
27841 return (template_parameter::operator==(o)
27842 && get_type() == o.get_type());
27843 }
27844 catch(...)
27845 {return false;}
27846}
27847
27848bool
27850{
27851 try
27852 {
27853 const decl_base& o = dynamic_cast<const decl_base&>(other);
27854 return *this == o;
27855 }
27856 catch(...)
27857 {return false;}
27858}
27859
27860non_type_tparameter::~non_type_tparameter()
27861{}
27862
27863// <template_tparameter stuff>
27864
27865/// Type of the private data of the @ref template_tparameter type.
27866class template_tparameter::priv
27867{
27868}; //end class template_tparameter::priv
27869
27870/// Constructor for the @ref template_tparameter.
27871///
27872/// @param index the index of the template parameter.
27873///
27874/// @param enclosing_tdecl the enclosing template declaration.
27875///
27876/// @param name the name of the template parameter.
27877///
27878/// @param locus the location of the declaration of the template
27879/// parameter.
27880template_tparameter::template_tparameter(unsigned index,
27881 template_decl_sptr enclosing_tdecl,
27882 const string& name,
27883 const location& locus)
27884 : type_or_decl_base(enclosing_tdecl->get_environment(),
27885 ABSTRACT_DECL_BASE
27886 | ABSTRACT_TYPE_BASE
27887 | BASIC_TYPE),
27888 decl_base(enclosing_tdecl->get_environment(), name, locus),
27889 type_base(enclosing_tdecl->get_environment(), 0, 0),
27890 type_decl(enclosing_tdecl->get_environment(), name,
27891 0, 0, locus, name, VISIBILITY_DEFAULT),
27892 type_tparameter(index, enclosing_tdecl, name, locus),
27893 template_decl(enclosing_tdecl->get_environment(), name, locus),
27894 priv_(new priv)
27895{
27897}
27898
27899/// Equality operator.
27900///
27901/// @param other the other template parameter to compare against.
27902///
27903/// @return true iff @p other equals the current instance.
27904bool
27906{
27907 try
27908 {
27909 const template_tparameter& o =
27910 dynamic_cast<const template_tparameter&>(other);
27911 return (type_tparameter::operator==(o)
27913 }
27914 catch(...)
27915 {return false;}
27916}
27917
27918/// Equality operator.
27919///
27920/// @param other the other template parameter to compare against.
27921///
27922/// @return true iff @p other equals the current instance.
27923bool
27925{
27926 try
27927 {
27928 const template_tparameter& o =
27929 dynamic_cast<const template_tparameter&>(other);
27930 return (type_tparameter::operator==(o)
27932 }
27933 catch(...)
27934 {return false;}
27935}
27936
27937bool
27939{
27940 try
27941 {
27942 const template_tparameter& other =
27943 dynamic_cast<const template_tparameter&>(o);
27944 return *this == static_cast<const type_base&>(other);
27945 }
27946 catch(...)
27947 {return false;}
27948}
27949
27950bool
27952{
27953 try
27954 {
27955 const template_tparameter& other =
27956 dynamic_cast<const template_tparameter&>(o);
27957 return type_base::operator==(other);
27958 }
27959 catch(...)
27960 {return false;}
27961}
27962
27963template_tparameter::~template_tparameter()
27964{}
27965
27966// </template_tparameter stuff>
27967
27968// <type_composition stuff>
27969
27970/// The type of the private data of the @ref type_composition type.
27971class type_composition::priv
27972{
27973 friend class type_composition;
27974
27975 type_base_wptr type_;
27976
27977 // Forbid this.
27978 priv();
27979
27980public:
27981
27982 priv(type_base_wptr type)
27983 : type_(type)
27984 {}
27985}; //end class type_composition::priv
27986
27987/// Constructor for the @ref type_composition type.
27988///
27989/// @param index the index of the template type composition.
27990///
27991/// @param tdecl the enclosing template parameter that owns the
27992/// composition.
27993///
27994/// @param t the resulting type.
27995type_composition::type_composition(unsigned index,
27996 template_decl_sptr tdecl,
27997 type_base_sptr t)
27998 : type_or_decl_base(tdecl->get_environment(),
27999 ABSTRACT_DECL_BASE),
28000 decl_base(tdecl->get_environment(), "", location()),
28001 template_parameter(index, tdecl),
28002 priv_(new priv(t))
28003{
28005}
28006
28007/// Getter for the resulting composed type.
28008///
28009/// @return the composed type.
28010const type_base_sptr
28012{return priv_->type_.lock();}
28013
28014/// Setter for the resulting composed type.
28015///
28016/// @param t the composed type.
28017void
28019{priv_->type_ = t;}
28020
28021type_composition::~type_composition()
28022{}
28023
28024// </type_composition stuff>
28025
28026//</template_parameter stuff>
28027
28028// <function_template>
28029
28030class function_tdecl::priv
28031{
28032 friend class function_tdecl;
28033
28034 function_decl_sptr pattern_;
28035 binding binding_;
28036
28037 priv();
28038
28039public:
28040
28041 priv(function_decl_sptr pattern, binding bind)
28042 : pattern_(pattern), binding_(bind)
28043 {}
28044
28045 priv(binding bind)
28046 : binding_(bind)
28047 {}
28048}; // end class function_tdecl::priv
28049
28050/// Constructor for a function template declaration.
28051///
28052/// @param env the environment we are operating from.
28053///
28054/// @param locus the location of the declaration.
28055///
28056/// @param vis the visibility of the declaration. This is the
28057/// visibility the functions instantiated from this template are going
28058/// to have.
28059///
28060/// @param bind the binding of the declaration. This is the binding
28061/// the functions instantiated from this template are going to have.
28062function_tdecl::function_tdecl(const environment& env,
28063 const location& locus,
28064 visibility vis,
28065 binding bind)
28066 : type_or_decl_base(env,
28067 ABSTRACT_DECL_BASE
28068 | TEMPLATE_DECL
28069 | ABSTRACT_SCOPE_DECL),
28070 decl_base(env, "", locus, "", vis),
28071 template_decl(env, "", locus, vis),
28072 scope_decl(env, "", locus),
28073 priv_(new priv(bind))
28074{
28076}
28077
28078/// Constructor for a function template declaration.
28079///
28080/// @param pattern the pattern of the template.
28081///
28082/// @param locus the location of the declaration.
28083///
28084/// @param vis the visibility of the declaration. This is the
28085/// visibility the functions instantiated from this template are going
28086/// to have.
28087///
28088/// @param bind the binding of the declaration. This is the binding
28089/// the functions instantiated from this template are going to have.
28090function_tdecl::function_tdecl(function_decl_sptr pattern,
28091 const location& locus,
28092 visibility vis,
28093 binding bind)
28094 : type_or_decl_base(pattern->get_environment(),
28095 ABSTRACT_DECL_BASE
28096 | TEMPLATE_DECL
28097 | ABSTRACT_SCOPE_DECL),
28098 decl_base(pattern->get_environment(), pattern->get_name(), locus,
28099 pattern->get_name(), vis),
28100 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
28101 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
28102 priv_(new priv(pattern, bind))
28103{
28105}
28106
28107/// Set a new pattern to the function template.
28108///
28109/// @param p the new pattern.
28110void
28112{
28113 priv_->pattern_ = p;
28114 add_decl_to_scope(p, this);
28115 set_name(p->get_name());
28116}
28117
28118/// Get the pattern of the function template.
28119///
28120/// @return the pattern.
28123{return priv_->pattern_;}
28124
28125/// Get the binding of the function template.
28126///
28127/// @return the binding
28130{return priv_->binding_;}
28131
28132/// Comparison operator for the @ref function_tdecl type.
28133///
28134/// @param other the other instance of @ref function_tdecl to compare against.
28135///
28136/// @return true iff the two instance are equal.
28137bool
28139{
28140 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
28141 if (o)
28142 return *this == *o;
28143 return false;
28144}
28145
28146/// Comparison operator for the @ref function_tdecl type.
28147///
28148/// @param other the other instance of @ref function_tdecl to compare against.
28149///
28150/// @return true iff the two instance are equal.
28151bool
28153{
28154 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
28155 if (o)
28156 return *this == *o;
28157 return false;
28158}
28159
28160/// Comparison operator for the @ref function_tdecl type.
28161///
28162/// @param o the other instance of @ref function_tdecl to compare against.
28163///
28164/// @return true iff the two instance are equal.
28165bool
28167{
28168 if (!(get_binding() == o.get_binding()
28169 && template_decl::operator==(o)
28170 && scope_decl::operator==(o)
28171 && !!get_pattern() == !!o.get_pattern()))
28172 return false;
28173
28174 if (get_pattern())
28175 return (*get_pattern() == *o.get_pattern());
28176
28177 return true;
28178}
28179
28180/// This implements the ir_traversable_base::traverse pure virtual
28181/// function.
28182///
28183/// @param v the visitor used on the current instance and on the
28184/// function pattern of the template.
28185///
28186/// @return true if the entire IR node tree got traversed, false
28187/// otherwise.
28188bool
28190{
28191 if (visiting())
28192 return true;
28193
28194 if (!v.visit_begin(this))
28195 {
28196 visiting(true);
28197 if (get_pattern())
28198 get_pattern()->traverse(v);
28199 visiting(false);
28200 }
28201 return v.visit_end(this);
28202}
28203
28204function_tdecl::~function_tdecl()
28205{}
28206
28207// </function_template>
28208
28209// <class template>
28210
28211/// Type of the private data of the the @ref class_tdecl type.
28212class class_tdecl::priv
28213{
28214 friend class class_tdecl;
28215 class_decl_sptr pattern_;
28216
28217public:
28218
28219 priv()
28220 {}
28221
28222 priv(class_decl_sptr pattern)
28223 : pattern_(pattern)
28224 {}
28225}; // end class class_tdecl::priv
28226
28227/// Constructor for the @ref class_tdecl type.
28228///
28229/// @param env the environment we are operating from.
28230///
28231/// @param locus the location of the declaration of the class_tdecl
28232/// type.
28233///
28234/// @param vis the visibility of the instance of class instantiated
28235/// from this template.
28236class_tdecl::class_tdecl(const environment& env,
28237 const location& locus,
28238 visibility vis)
28239 : type_or_decl_base(env,
28240 ABSTRACT_DECL_BASE
28241 | TEMPLATE_DECL
28242 | ABSTRACT_SCOPE_DECL),
28243 decl_base(env, "", locus, "", vis),
28244 template_decl(env, "", locus, vis),
28245 scope_decl(env, "", locus),
28246 priv_(new priv)
28247{
28249}
28250
28251/// Constructor for the @ref class_tdecl type.
28252///
28253/// @param pattern The details of the class template. This must NOT be a
28254/// null pointer. If you really this to be null, please use the
28255/// constructor above instead.
28256///
28257/// @param locus the source location of the declaration of the type.
28258///
28259/// @param vis the visibility of the instances of class instantiated
28260/// from this template.
28261class_tdecl::class_tdecl(class_decl_sptr pattern,
28262 const location& locus,
28263 visibility vis)
28264 : type_or_decl_base(pattern->get_environment(),
28265 ABSTRACT_DECL_BASE
28266 | TEMPLATE_DECL
28267 | ABSTRACT_SCOPE_DECL),
28268 decl_base(pattern->get_environment(), pattern->get_name(),
28269 locus, pattern->get_name(), vis),
28270 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
28271 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
28272 priv_(new priv(pattern))
28273{
28275}
28276
28277/// Setter of the pattern of the template.
28278///
28279/// @param p the new template.
28280void
28282{
28283 priv_->pattern_ = p;
28284 add_decl_to_scope(p, this);
28285 set_name(p->get_name());
28286}
28287
28288/// Getter of the pattern of the template.
28289///
28290/// @return p the new template.
28293{return priv_->pattern_;}
28294
28295bool
28297{
28298 try
28299 {
28300 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28301
28302 if (!(template_decl::operator==(o)
28303 && scope_decl::operator==(o)
28304 && !!get_pattern() == !!o.get_pattern()))
28305 return false;
28306
28307 if (!get_pattern() || !o.get_pattern())
28308 return true;
28309
28310 return get_pattern()->decl_base::operator==(*o.get_pattern());
28311 }
28312 catch(...) {}
28313 return false;
28314}
28315
28316bool
28318{
28319 try
28320 {
28321 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28322 return *this == static_cast<const decl_base&>(o);
28323 }
28324 catch(...)
28325 {return false;}
28326}
28327
28328bool
28330{return *this == static_cast<const decl_base&>(o);}
28331
28332/// This implements the ir_traversable_base::traverse pure virtual
28333/// function.
28334///
28335/// @param v the visitor used on the current instance and on the class
28336/// pattern of the template.
28337///
28338/// @return true if the entire IR node tree got traversed, false
28339/// otherwise.
28340bool
28342{
28343 if (visiting())
28344 return true;
28345
28346 if (v.visit_begin(this))
28347 {
28348 visiting(true);
28349 if (class_decl_sptr pattern = get_pattern())
28350 pattern->traverse(v);
28351 visiting(false);
28352 }
28353 return v.visit_end(this);
28354}
28355
28356class_tdecl::~class_tdecl()
28357{}
28358
28359/// This visitor checks if a given type as non-canonicalized sub
28360/// types.
28361class non_canonicalized_subtype_detector : public ir::ir_node_visitor
28362{
28363 type_base* type_;
28364 type_base* has_non_canonical_type_;
28365
28366private:
28367 non_canonicalized_subtype_detector();
28368
28369public:
28370 non_canonicalized_subtype_detector(type_base* type)
28371 : type_(type),
28372 has_non_canonical_type_()
28373 {}
28374
28375 /// Return true if the visitor detected that there is a
28376 /// non-canonicalized sub-type.
28377 ///
28378 /// @return true if the visitor detected that there is a
28379 /// non-canonicalized sub-type.
28380 type_base*
28381 has_non_canonical_type() const
28382 {return has_non_canonical_type_;}
28383
28384 /// The intent of this visitor handler is to avoid looking into
28385 /// sub-types of member functions of the type we are traversing.
28386 bool
28387 visit_begin(function_decl* f)
28388 {
28389 // Do not look at sub-types of non-virtual member functions.
28390 if (is_member_function(f)
28392 return false;
28393 return true;
28394 }
28395
28396 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
28397 /// the 'has_non_canonical_type' flag. And in any case, when
28398 /// visiting a sub-type, do not visit its children nodes. So this
28399 /// function only goes to the level below the level of the top-most
28400 /// type.
28401 ///
28402 /// @return true if we are at the same level as the top-most type,
28403 /// otherwise return false.
28404 bool
28405 visit_begin(type_base* t)
28406 {
28407 if (t != type_)
28408 {
28409 if (!t->get_canonical_type())
28410 // We are looking a sub-type of 'type_' which has no
28411 // canonical type. So tada! we found one! Get out right
28412 // now with the trophy.
28413 has_non_canonical_type_ = t;
28414
28415 return false;
28416 }
28417 return true;
28418 }
28419
28420 /// When we are done visiting a sub-type, if it's been flagged as
28421 /// been non-canonicalized, then stop the traversing.
28422 ///
28423 /// Otherwise, keep going.
28424 ///
28425 /// @return false iff the sub-type that has been visited is
28426 /// non-canonicalized.
28427 bool
28428 visit_end(type_base* )
28429 {
28430 if (has_non_canonical_type_)
28431 return false;
28432 return true;
28433 }
28434}; //end class non_canonicalized_subtype_detector
28435
28436/// Test if a type has sub-types that are non-canonicalized.
28437///
28438/// @param t the type which sub-types to consider.
28439///
28440/// @return true if a type has sub-types that are non-canonicalized.
28441type_base*
28443{
28444 if (!t)
28445 return 0;
28446
28447 non_canonicalized_subtype_detector v(t.get());
28448 t->traverse(v);
28449 return v.has_non_canonical_type();
28450}
28451
28452/// Tests if the change of a given type effectively comes from just
28453/// its sub-types. That is, if the type has changed but its type name
28454/// hasn't changed, then the change of the type mostly likely is a
28455/// sub-type change.
28456///
28457/// @param t_v1 the first version of the type.
28458///
28459/// @param t_v2 the second version of the type.
28460///
28461/// @return true iff the type changed and the change is about its
28462/// sub-types.
28463bool
28464type_has_sub_type_changes(const type_base_sptr t_v1,
28465 const type_base_sptr t_v2)
28466{
28467 type_base_sptr t1 = strip_typedef(t_v1);
28468 type_base_sptr t2 = strip_typedef(t_v2);
28469
28470 string repr1 = get_pretty_representation(t1, /*internal=*/false),
28471 repr2 = get_pretty_representation(t2, /*internal=*/false);
28472 return (t1 != t2 && repr1 == repr2);
28473}
28474
28475/// Make sure that the life time of a given (smart pointer to a) type
28476/// is the same as the life time of the libabigail library.
28477///
28478/// @param t the type to consider.
28479void
28480keep_type_alive(type_base_sptr t)
28481{
28482 const environment& env = t->get_environment();
28483 env.priv_->extra_live_types_.push_back(t);
28484}
28485
28486/// Hash an ABI artifact that is either a type or a decl.
28487///
28488/// This function intends to provides the fastest possible hashing for
28489/// types and decls, while being completely correct.
28490///
28491/// Note that if the artifact is a type and if it has a canonical
28492/// type, the hash value is going to be the pointer value of the
28493/// canonical type. Otherwise, this function computes a hash value
28494/// for the type by recursively walking the type members. This last
28495/// code path is possibly *very* slow and should only be used when
28496/// only handful of types are going to be hashed.
28497///
28498/// If the artifact is a decl, then a combination of the hash of its
28499/// type and the hash of the other properties of the decl is computed.
28500///
28501/// @param tod the type or decl to hash.
28502///
28503/// @return the resulting hash value.
28504size_t
28506{
28507 hash_t result = 0;
28508
28509 if (tod == 0)
28510 ;
28511 else if (const type_base* t = is_type(tod))
28512 result = hash_type(t);
28513 else if (const decl_base* d = is_decl(tod))
28514 {
28515 if (const scope_decl* s = is_scope_decl(d))
28516 {
28517 if (const global_scope* g = is_global_scope(s))
28518 result = reinterpret_cast<size_t>(g);
28519 else
28520 result = reinterpret_cast<size_t>(s);
28521 }
28522 else if (var_decl* v = is_var_decl(d))
28523 {
28524 ABG_ASSERT(v->get_type());
28525 hash_t h = hash_type_or_decl(v->get_type());
28526 string repr = v->get_pretty_representation(/*internal=*/true);
28527 std::hash<string> hash_string;
28528 h = hashing::combine_hashes(h, hash_string(repr));
28529 result = h;
28530 }
28531 else if (function_decl* f = is_function_decl(d))
28532 {
28533 ABG_ASSERT(f->get_type());
28534 hash_t h = hash_type_or_decl(f->get_type());
28535 string repr = f->get_pretty_representation(/*internal=*/true);
28536 std::hash<string> hash_string;
28537 h = hashing::combine_hashes(h, hash_string(repr));
28538 result = h;
28539 }
28541 {
28542 type_base_sptr parm_type = p->get_type();
28543 ABG_ASSERT(parm_type);
28544 std::hash<bool> hash_bool;
28545 std::hash<unsigned> hash_unsigned;
28546 hash_t h = hash_type_or_decl(parm_type);
28547 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
28548 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
28549 result = h;
28550 }
28551 else if (class_decl::base_spec *bs = is_class_base_spec(d))
28552 {
28553 member_base::hash hash_member;
28554 std::hash<size_t> hash_size;
28555 std::hash<bool> hash_bool;
28556 type_base_sptr type = bs->get_base_class();
28557 hash_t h = hash_type_or_decl(type);
28558 h = hashing::combine_hashes(h, hash_member(*bs));
28559 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
28560 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
28561 result = h;
28562 }
28563 else
28564 // This is a *really* *SLOW* path. If it shows up in a
28565 // performance profile, I bet it'd be a good idea to try to
28566 // avoid it altogether.
28567 // TODO: recode this function or get rid of it altogethe.
28568 abort();
28569 }
28570 else
28571 // We should never get here.
28572 abort();
28573 return *result;
28574}
28575
28576/// Hash an ABI artifact that is a type.
28577///
28578/// This function intends to provides the fastest possible hashing for
28579/// types while being completely correct.
28580///
28581/// Note that if the type artifact has a canonical type, the hash
28582/// value is going to be the pointer value of the canonical type.
28583/// Otherwise, this function computes a hash value for the type by
28584/// recursively walking the type members. This last code path is
28585/// possibly *very* slow and should only be used when only handful of
28586/// types are going to be hashed.
28587///
28588/// @param t the type or decl to hash.
28589///
28590/// @return the resulting hash value.
28591size_t
28593{return hash_as_canonical_type_or_constant(t);}
28594
28595/// Hash an ABI artifact that is either a type of a decl.
28596///
28597/// @param tod the ABI artifact to hash.
28598///
28599/// @return the hash value of the ABI artifact.
28600size_t
28602{return hash_type_or_decl(tod.get());}
28603
28604/// Get the hash value associated to an IR node.
28605///
28606/// Unlike type_or_decl_base::hash_value(), if the IR has no
28607/// associated hash value, an empty hash value is returned.
28608///
28609/// @param artefact the IR node to consider.
28610///
28611/// @return the hash value stored on the IR node or an empty hash if
28612/// no hash value is stored in the @p artefact.
28613hash_t
28615{
28616 const type_or_decl_base* artefactp = &artefact;
28617 if (decl_base *d = is_decl(artefactp))
28618 {
28620 if (d->type_or_decl_base::priv_->get_hashing_state()
28622 return d->type_or_decl_base::priv_->hash_value_;
28623 }
28624 else if (artefact.priv_->get_hashing_state() == hashing::HASHING_FINISHED_STATE)
28625 return artefact.priv_->hash_value_;
28626
28627 return hash_t();
28628}
28629
28630/// Test if a given type is allowed to be non canonicalized
28631///
28632/// This is a subroutine of hash_as_canonical_type_or_constant.
28633///
28634/// For now, the only types allowed to be non canonicalized in the
28635/// system are (typedefs & pointers to) decl-only class/union, the
28636/// void type and variadic parameter types.
28637///
28638/// @return true iff @p t is a one of the only types allowed to be
28639/// non-canonicalized in the system.
28640bool
28642{
28643 if (!t)
28644 return true;
28645
28646 return (// The IR nodes for the types below are unique across the
28647 // entire ABI corpus. Thus, no need to canonicalize them.
28648 // Maybe we could say otherwise and canonicalize them once
28649 // for all so that they can be removed from here.
28651
28652 // An IR node for the types below can be equal to several
28653 // other types (i.e, a decl-only type t equals a fully
28654 // defined type of the same name in ODR-supported
28655 // languages). Hence, they can't be given a canonical type.
28656 //
28657 // TODO: Maybe add a mode that would detect ODR violations
28658 // that would make a decl-only type co-exists with several
28659 // different definitions of the type in the ABI corpus.
28662 /*look_through_decl_only=*/true)
28664
28665}
28666
28667/// Test if a type is unique in the entire environment.
28668///
28669/// Examples of unique types are void, void* and variadic parameter
28670/// types.
28671///
28672/// @param t the type to test for.
28673///
28674/// @return true iff the type @p t is unique in the entire
28675/// environment.
28676bool
28677is_unique_type(const type_base_sptr& t)
28678{return is_unique_type(t.get());}
28679
28680/// Test if a type is unique in the entire environment.
28681///
28682/// Examples of unique types are void, void* and variadic parameter
28683/// types.
28684///
28685/// @param t the type to test for.
28686///
28687/// @return true iff the type @p t is unique in the entire
28688/// environment.
28689bool
28691{
28692 if (!t)
28693 return false;
28694
28695 const environment& env = t->get_environment();
28696 return (env.is_void_type(t)
28697 || env.is_void_pointer_type(t)
28698 || env.is_variadic_parameter_type(t));
28699}
28700
28701/// For a given type, return its exemplar type.
28702///
28703/// For a given type, its exemplar type is either its canonical type
28704/// or the canonical type of the definition type of a given
28705/// declaration-only type. If the neither of those two types exist,
28706/// then the exemplar type is the given type itself.
28707///
28708/// @param type the input to consider.
28709///
28710/// @return the exemplar type.
28711type_base*
28713{
28714 if (decl_base * decl = is_decl(type))
28715 {
28716 // Make sure we get the real definition of a decl-only type.
28717 decl = look_through_decl_only(decl);
28718 type = is_type(decl);
28719 ABG_ASSERT(type);
28720 }
28721 type_base *exemplar = type->get_naked_canonical_type();
28722 if (!exemplar)
28723 {
28724 // The type has no canonical type. Let's be sure that it's one
28725 // of those rare types that are allowed to be non canonicalized
28726 // in the system.
28727 exemplar = const_cast<type_base*>(type);
28729 }
28730 return exemplar;
28731}
28732
28733/// Test if a given type is allowed to be non canonicalized
28734///
28735/// This is a subroutine of hash_as_canonical_type_or_constant.
28736///
28737/// For now, the only types allowed to be non canonicalized in the
28738/// system are decl-only class/union and the void type.
28739///
28740/// @return true iff @p t is a one of the only types allowed to be
28741/// non-canonicalized in the system.
28742bool
28743is_non_canonicalized_type(const type_base_sptr& t)
28744{return is_non_canonicalized_type(t.get());}
28745
28746/// Hash a type by either returning the pointer value of its canonical
28747/// type or by returning a constant if the type doesn't have a
28748/// canonical type.
28749///
28750/// This is a subroutine of hash_type.
28751///
28752/// @param t the type to consider.
28753///
28754/// @return the hash value.
28755static size_t
28756hash_as_canonical_type_or_constant(const type_base *t)
28757{
28758 type_base *canonical_type = 0;
28759
28760 if (t)
28761 canonical_type = t->get_naked_canonical_type();
28762
28763 if (!canonical_type)
28764 {
28765 // If the type doesn't have a canonical type, maybe it's because
28766 // it's a declaration-only type? If that's the case, let's try
28767 // to get the canonical type of the definition of this
28768 // declaration.
28769 decl_base *decl = is_decl(t);
28770 if (decl
28771 && decl->get_is_declaration_only()
28773 {
28774 type_base *definition =
28776 ABG_ASSERT(definition);
28777 canonical_type = definition->get_naked_canonical_type();
28778 }
28779 }
28780
28781 if (canonical_type)
28782 return reinterpret_cast<size_t>(canonical_type);
28783
28784 // If we reached this point, it means we are seeing a
28785 // non-canonicalized type. It must be a decl-only class or a void
28786 // type, otherwise it means that for some weird reason, the type
28787 // hasn't been canonicalized. It should be!
28789
28790 return 0xDEADBABE;
28791}
28792
28793/// Test if the pretty representation of a given @ref function_decl is
28794/// lexicographically less then the pretty representation of another
28795/// @ref function_decl.
28796///
28797/// @param f the first @ref function_decl to consider for comparison.
28798///
28799/// @param s the second @ref function_decl to consider for comparison.
28800///
28801/// @return true iff the pretty representation of @p f is
28802/// lexicographically less than the pretty representation of @p s.
28803bool
28805{
28808
28809 if (fr != sr)
28810 return fr < sr;
28811
28812 fr = f.get_pretty_representation(/*internal=*/true),
28813 sr = s.get_pretty_representation(/*internal=*/true);
28814
28815 if (fr != sr)
28816 return fr < sr;
28817
28818 if (f.get_symbol())
28819 fr = f.get_symbol()->get_id_string();
28820 else if (!f.get_linkage_name().empty())
28821 fr = f.get_linkage_name();
28822
28823 if (s.get_symbol())
28824 sr = s.get_symbol()->get_id_string();
28825 else if (!s.get_linkage_name().empty())
28826 sr = s.get_linkage_name();
28827
28828 return fr < sr;
28829}
28830
28831/// Test if two types have similar structures, even though they are
28832/// (or can be) different.
28833///
28834/// const and volatile qualifiers are completely ignored.
28835///
28836/// typedef are resolved to their definitions; their names are ignored.
28837///
28838/// Two indirect types (pointers or references) have similar structure
28839/// if their underlying types are of the same kind and have the same
28840/// name. In the indirect types case, the size of the underlying type
28841/// does not matter.
28842///
28843/// Two direct types (i.e, non indirect) have a similar structure if
28844/// they have the same kind, name and size. Two class types have
28845/// similar structure if they have the same name, size, and if the
28846/// types of their data members have similar types.
28847///
28848/// @param first the first type to consider.
28849///
28850/// @param second the second type to consider.
28851///
28852/// @param indirect_type whether to do an indirect comparison
28853///
28854/// @return true iff @p first and @p second have similar structures.
28855bool
28856types_have_similar_structure(const type_base_sptr& first,
28857 const type_base_sptr& second,
28858 bool indirect_type)
28859{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
28860
28861/// Test if two types have similar structures, even though they are
28862/// (or can be) different.
28863///
28864/// const and volatile qualifiers are completely ignored.
28865///
28866/// typedef are resolved to their definitions; their names are ignored.
28867///
28868/// Two indirect types (pointers, references or arrays) have similar
28869/// structure if their underlying types are of the same kind and have
28870/// the same name. In the indirect types case, the size of the
28871/// underlying type does not matter.
28872///
28873/// Two direct types (i.e, non indirect) have a similar structure if
28874/// they have the same kind, name and size. Two class types have
28875/// similar structure if they have the same name, size, and if the
28876/// types of their data members have similar types.
28877///
28878/// @param first the first type to consider.
28879///
28880/// @param second the second type to consider.
28881///
28882/// @param indirect_type if true, then consider @p first and @p
28883/// second as being underlying types of indirect types. Meaning that
28884/// their size does not matter.
28885///
28886/// @return true iff @p first and @p second have similar structures.
28887bool
28889 const type_base* second,
28890 bool indirect_type)
28891{
28892 if (!!first != !!second)
28893 return false;
28894
28895 if (!first)
28896 return false;
28897
28898 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
28899 first = peel_qualified_or_typedef_type(first);
28900 second = peel_qualified_or_typedef_type(second);
28901
28902 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
28903 // various ty2 below cannot be null.
28904 if (typeid(*first) != typeid(*second))
28905 return false;
28906
28907 // Peel off matching pointers.
28908 if (const pointer_type_def* ty1 = is_pointer_type(first))
28909 {
28910 const pointer_type_def* ty2 = is_pointer_type(second);
28911 return types_have_similar_structure(ty1->get_pointed_to_type(),
28912 ty2->get_pointed_to_type(),
28913 /*indirect_type=*/true);
28914 }
28915
28916 // Peel off matching references.
28917 if (const reference_type_def* ty1 = is_reference_type(first))
28918 {
28919 const reference_type_def* ty2 = is_reference_type(second);
28920 if (ty1->is_lvalue() != ty2->is_lvalue())
28921 return false;
28922 return types_have_similar_structure(ty1->get_pointed_to_type(),
28923 ty2->get_pointed_to_type(),
28924 /*indirect_type=*/true);
28925 }
28926
28927 // Peel off matching pointer-to-member types.
28928 if (const ptr_to_mbr_type* ty1 = is_ptr_to_mbr_type(first))
28929 {
28930 const ptr_to_mbr_type* ty2 = is_ptr_to_mbr_type(second);
28931 return (types_have_similar_structure(ty1->get_member_type(),
28932 ty2->get_member_type(),
28933 /*indirect_type=*/true)
28934 && types_have_similar_structure(ty1->get_containing_type(),
28935 ty2->get_containing_type(),
28936 /*indirect_type=*/true));
28937 }
28938
28939 if (const type_decl* ty1 = is_type_decl(first))
28940 {
28941 const type_decl* ty2 = is_type_decl(second);
28942 if (!indirect_type)
28943 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28944 return false;
28945
28946 return ty1->get_name() == ty2->get_name();
28947 }
28948
28949 if (const enum_type_decl* ty1 = is_enum_type(first))
28950 {
28951 const enum_type_decl* ty2 = is_enum_type(second);
28952 if (!indirect_type)
28953 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28954 return false;
28955
28956 return (get_name(ty1->get_underlying_type())
28957 == get_name(ty2->get_underlying_type()));
28958 }
28959
28960 if (const class_decl* ty1 = is_class_type(first))
28961 {
28962 const class_decl* ty2 = is_class_type(second);
28963 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28964 && ty1->get_name() != ty2->get_name())
28965 return false;
28966
28967 if (!indirect_type)
28968 {
28969 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
28970 || (ty1->get_non_static_data_members().size()
28971 != ty2->get_non_static_data_members().size()))
28972 return false;
28973
28974 for (class_or_union::data_members::const_iterator
28975 i = ty1->get_non_static_data_members().begin(),
28976 j = ty2->get_non_static_data_members().begin();
28977 (i != ty1->get_non_static_data_members().end()
28978 && j != ty2->get_non_static_data_members().end());
28979 ++i, ++j)
28980 {
28981 var_decl_sptr dm1 = *i;
28982 var_decl_sptr dm2 = *j;
28983 if (!types_have_similar_structure(dm1->get_type().get(),
28984 dm2->get_type().get(),
28985 indirect_type))
28986 return false;
28987 }
28988 }
28989
28990 return true;
28991 }
28992
28993 if (const union_decl* ty1 = is_union_type(first))
28994 {
28995 const union_decl* ty2 = is_union_type(second);
28996 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28997 && ty1->get_name() != ty2->get_name())
28998 return false;
28999
29000 if (!indirect_type)
29001 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
29002
29003 return true;
29004 }
29005
29006 if (const array_type_def* ty1 = is_array_type(first))
29007 {
29008 const array_type_def* ty2 = is_array_type(second);
29009 if (!indirect_type)
29010 {
29011 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
29012 || ty1->get_dimension_count() != ty2->get_dimension_count())
29013 return false;
29014
29015 // Handle int[5][2] vs int[2][5] ...
29016 //
29017 // 6.2.5/20 of
29018 // https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
29019 // says:
29020 //
29021 // "Array types are characterized by their element
29022 // type and by the number of elements in the array"
29023 //
29024 // and 6.5.2.1/3 says:
29025 //
29026 // "arrays are stored in row-major order (last subscript
29027 // varies fastest)."
29028 //
29029 // So, let's ensure that all dimensions (sub-ranges) have
29030 // the same length.
29031
29032 for (auto r1 = ty1->get_subranges().begin(),
29033 r2 = ty1->get_subranges().begin();
29034 (r1 != ty1->get_subranges().end()
29035 && r2 != ty2->get_subranges().end());
29036 ++r1, ++r2)
29037 if ((*r1)->get_length() != (*r2)->get_length())
29038 return false;
29039 }
29040
29041 // ... then compare the elements of the arrays.
29042 if (!types_have_similar_structure(ty1->get_element_type(),
29043 ty2->get_element_type(),
29044 /*indirect_type=*/true))
29045 return false;
29046
29047 return true;
29048 }
29049
29050 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
29051 {
29053 if (ty1->get_upper_bound() != ty2->get_upper_bound()
29054 || ty1->get_lower_bound() != ty2->get_lower_bound()
29055 || ty1->get_language() != ty2->get_language()
29056 || !types_have_similar_structure(ty1->get_underlying_type(),
29057 ty2->get_underlying_type(),
29058 indirect_type))
29059 return false;
29060
29061 return true;
29062 }
29063
29064 if (const function_type* ty1 = is_function_type(first))
29065 {
29066 const function_type* ty2 = is_function_type(second);
29067 if (!types_have_similar_structure(ty1->get_return_type(),
29068 ty2->get_return_type(),
29069 indirect_type))
29070 return false;
29071
29072 if (ty1->get_parameters().size() != ty2->get_parameters().size())
29073 return false;
29074
29075 for (function_type::parameters::const_iterator
29076 i = ty1->get_parameters().begin(),
29077 j = ty2->get_parameters().begin();
29078 (i != ty1->get_parameters().end()
29079 && j != ty2->get_parameters().end());
29080 ++i, ++j)
29081 if (!types_have_similar_structure((*i)->get_type(),
29082 (*j)->get_type(),
29083 indirect_type))
29084 return false;
29085
29086 return true;
29087 }
29088
29089 // All kinds of type should have been handled at this point.
29091
29092 return false;
29093}
29094
29095/// Look for a data member of a given class, struct or union type and
29096/// return it.
29097///
29098/// The data member is designated by its name.
29099///
29100/// @param type the class, struct or union type to consider.
29101///
29102/// @param dm_name the name of the data member to lookup.
29103///
29104/// @return the data member iff it was found in @type or NULL if no
29105/// data member with that name was found.
29106const var_decl*
29108 const char* dm_name)
29109
29110{
29112 if (!cou)
29113 return 0;
29114
29115 return cou->find_data_member(dm_name).get();
29116}
29117
29118/// Look for a data member of a given class, struct or union type and
29119/// return it.
29120///
29121/// The data member is designated by its name.
29122///
29123/// @param type the class, struct or union type to consider.
29124///
29125/// @param dm the data member to lookup.
29126///
29127/// @return the data member iff it was found in @type or NULL if no
29128/// data member with that name was found.
29129const var_decl_sptr
29130lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
29131{
29132 class_or_union_sptr cou = is_class_or_union_type(type);
29133 if (!cou)
29134 return var_decl_sptr();
29135
29136 return cou->find_data_member(dm);
29137}
29138
29139/// Get the function parameter designated by its index.
29140///
29141/// Note that the first function parameter has index 0.
29142///
29143/// @param fun the function to consider.
29144///
29145/// @param parm_index the index of the function parameter to get.
29146///
29147/// @return the function parameter designated by its index, of NULL if
29148/// no function parameter with that index was found.
29151 unsigned parm_index)
29152{
29154 if (!fn)
29155 return 0;
29156
29157 const function_decl::parameters &parms = fn->get_type()->get_parameters();
29158 if (parms.size() <= parm_index)
29159 return 0;
29160
29161 return parms[parm_index].get();
29162}
29163
29164/// Build the internal name of the underlying type of an enum.
29165///
29166/// @param base_name the (unqualified) name of the enum the underlying
29167/// type is destined to.
29168///
29169/// @param is_anonymous true if the underlying type of the enum is to
29170/// be anonymous.
29171string
29173 bool is_anonymous,
29174 uint64_t size)
29175{
29176 std::ostringstream o;
29177
29178 if (is_anonymous)
29179 o << "unnamed-enum";
29180 else
29181 o << "enum-" << base_name;
29182
29183 o << "-underlying-type-" << size;
29184
29185 return o.str();
29186}
29187
29188/// Find the first data member of a class or union which name matches
29189/// a regular expression.
29190///
29191/// @param t the class or union to consider.
29192///
29193/// @param r the regular expression to consider.
29194///
29195/// @return the data member matched by @p r or nil if none was found.
29198 const regex::regex_t_sptr& r)
29199{
29200 for (auto data_member : t.get_data_members())
29201 {
29202 if (regex::match(r, data_member->get_name()))
29203 return data_member;
29204 }
29205
29206 return var_decl_sptr();
29207}
29208
29209/// Find the last data member of a class or union which name matches
29210/// a regular expression.
29211///
29212/// @param t the class or union to consider.
29213///
29214/// @param r the regular expression to consider.
29215///
29216/// @return the data member matched by @p r or nil if none was found.
29219 const regex::regex_t_sptr& regex)
29220{
29221 auto d = t.get_data_members().rbegin();
29222 auto e = t.get_data_members().rend();
29223 for (; d != e; ++d)
29224 {
29225 if (regex::match(regex, (*d)->get_name()))
29226 return *d;
29227 }
29228
29229 return var_decl_sptr();
29230}
29231
29232/// Emit the pretty representation of the parameters of a function
29233/// type.
29234///
29235/// @param fn_type the function type to consider.
29236///
29237/// @param o the output stream to emit the pretty representation to.
29238///
29239/// @param qualified if true, emit fully qualified names.
29240///
29241/// @param internal if true, then the result is to be used for the
29242/// purpose of type canonicalization.
29243static void
29244stream_pretty_representation_of_fn_parms(const function_type& fn_type,
29245 ostream& o, bool qualified,
29246 bool internal)
29247{
29248 o << "(";
29249 if (fn_type.get_parameters().empty())
29250 o << "void";
29251 else
29252 {
29253 type_base_sptr type;
29254 auto end = fn_type.get_parameters().end();
29255 auto first_parm = fn_type.get_first_non_implicit_parm();
29257 const environment& env = fn_type.get_environment();
29258 for (auto i = fn_type.get_first_non_implicit_parm(); i != end; ++i)
29259 {
29260 if (i != first_parm)
29261 o << ", ";
29262 parm = *i;
29263 type = parm->get_type();
29264 // If the type is a decl-only class, union or enum that has a
29265 // definition, use the definition instead. That definition
29266 // is what is going to be serialized out in ABIXML anyway,
29267 // so use that for consistency.
29268 if (decl_base_sptr def = look_through_decl_only(is_decl(type)))
29269 type = is_type(def);
29270 if (env.is_variadic_parameter_type(type))
29271 o << "...";
29272 else
29273 o << get_type_name(type, qualified, internal);
29274 }
29275 }
29276 o << ")";
29277}
29278
29279/// When constructing the name of a pointer to function type, add the
29280/// return type to the left of the existing type identifier, and the
29281/// parameters declarator to the right.
29282///
29283/// This function considers the name of the type as an expression.
29284///
29285/// The resulting type expr is going to be made of three parts:
29286/// left_expr inner_expr right_expr.
29287///
29288/// Suppose we want to build the type expression representing:
29289///
29290/// "an array of pointer to function taking a char parameter and
29291/// returning an int".
29292///
29293/// It's going to look like:
29294///
29295/// int(*a[])(char);
29296///
29297/// Suppose the caller of this function started to emit the inner
29298/// "a[]" part of the expression already. It thus calls this
29299/// function with that input "a[]" part. We consider that "a[]" as
29300/// the "type identifier".
29301///
29302/// So the inner_expr is going to be "(*a[])".
29303///
29304/// The left_expr part is "int". The right_expr part is "(char)".
29305///
29306/// In other words, this function adds the left_expr and right_expr to
29307/// the inner_expr. left_expr and right_expr are called "outer
29308/// pointer to function type expression".
29309///
29310/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29311/// array_declaration_name()
29312///
29313/// @param p the pointer to function type to consider.
29314///
29315/// @param input the type-id to use as the inner expression of the
29316/// overall pointer-to-function type expression
29317///
29318/// @param qualified if true then use qualified names in the resulting
29319/// type name.
29320///
29321/// @param internal if true then the resulting type name is going to
29322/// be used for type canonicalization purposes.
29323///
29324/// @return the name of the pointer to function type.
29325static string
29326add_outer_pointer_to_fn_type_expr(const type_base* p,
29327 const string& input,
29328 bool qualified, bool internal)
29329{
29330 if (!p)
29331 return "";
29332
29333 function_type_sptr pointed_to_fn;
29334 string star_or_ref;
29335
29336 if (const pointer_type_def* ptr = is_pointer_type(p))
29337 {
29338 pointed_to_fn = is_function_type(ptr->get_pointed_to_type());
29339 star_or_ref= "*";
29340 }
29341 else if (const reference_type_def* ref = is_reference_type(p))
29342 {
29343 star_or_ref = "&";
29344 pointed_to_fn = is_function_type(ref->get_pointed_to_type());
29345 }
29346
29347 if (!pointed_to_fn)
29348 return "";
29349
29350 if (pointed_to_fn->priv_->is_pretty_printing())
29351 // We have just detected a cycle while walking the sub-tree of
29352 // this function type for the purpose of printing its
29353 // representation. We need to get out of here pronto or else
29354 // we'll be spinning endlessly.
29355 return "";
29356
29357 // Let's mark thie function type to signify that we started walking
29358 // its subtree. This is to detect potential cycles and avoid
29359 // looping endlessly.
29360 pointed_to_fn->priv_->set_is_pretty_printing();
29361
29362 std::ostringstream left, right, inner;
29363
29364 inner << "(" << star_or_ref << input << ")";
29365
29366 type_base_sptr type;
29367 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
29368 qualified, internal);
29369
29370 type_base_sptr return_type = pointed_to_fn->get_return_type();
29371 string result;
29372
29373 if (is_npaf_type(return_type)
29374 || !(is_pointer_to_function_type(return_type)
29375 || is_pointer_to_array_type(return_type)))
29376 {
29377 if (return_type)
29378 left << get_type_name(return_type, qualified, internal);
29379 result = left.str() + " " + inner.str() + right.str();
29380 }
29381 else if (pointer_type_def_sptr p = is_pointer_to_function_type(return_type))
29382 {
29383 string inner_string = inner.str() + right.str();
29384 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
29385 qualified, internal);
29386 }
29387 else if (pointer_type_def_sptr p = is_pointer_to_array_type(return_type))
29388 {
29389 string inner_string = inner.str() + right.str();
29390 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29391 qualified, internal);
29392 }
29393 else
29395
29396 // Lets unmark this function type to signify that we are done
29397 // walking its subtree. This was to detect potential cycles and
29398 // avoid looping endlessly.
29399 pointed_to_fn->priv_->unset_is_pretty_printing();
29400 return result;
29401}
29402
29403/// When constructing the name of a pointer to function type, add the
29404/// return type to the left of the existing type identifier, and the
29405/// parameters declarator to the right.
29406///
29407/// This function considers the name of the type as an expression.
29408///
29409/// The resulting type expr is going to be made of three parts:
29410/// left_expr inner_expr right_expr.
29411///
29412/// Suppose we want to build the type expression representing:
29413///
29414/// "an array of pointer to function taking a char parameter and
29415/// returning an int".
29416///
29417/// It's going to look like:
29418///
29419/// int(*a[])(char);
29420///
29421/// Suppose the caller of this function started to emit the inner
29422/// "a[]" part of the expression already. It thus calls this
29423/// function with that input "a[]" part. We consider that "a[]" as
29424/// the "type identifier".
29425///
29426/// So the inner_expr is going to be "(*a[])".
29427///
29428/// The left_expr part is "int". The right_expr part is "(char)".
29429///
29430/// In other words, this function adds the left_expr and right_expr to
29431/// the inner_expr. left_expr and right_expr are called "outer
29432/// pointer to function type expression".
29433///
29434/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29435/// array_declaration_name()
29436///
29437/// @param p the pointer to function type to consider.
29438///
29439/// @param input the type-id to use as the inner expression of the
29440/// overall pointer-to-function type expression
29441///
29442/// @param qualified if true then use qualified names in the resulting
29443/// type name.
29444///
29445/// @param internal if true then the resulting type name is going to
29446/// be used for type canonicalization purposes.
29447///
29448/// @return the name of the pointer to function type.
29449static string
29450add_outer_pointer_to_fn_type_expr(const type_base_sptr& p,
29451 const string& input,
29452 bool qualified, bool internal)
29453{return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
29454
29455/// When constructing the name of a pointer to array type, add the
29456/// array element type type to the left of the existing type
29457/// identifier, and the array declarator part to the right.
29458///
29459/// This function considers the name of the type as an expression.
29460///
29461/// The resulting type expr is going to be made of three parts:
29462/// left_expr inner_expr right_expr.
29463///
29464/// Suppose we want to build the type expression representing:
29465///
29466/// "a pointer to an array of int".
29467///
29468/// It's going to look like:
29469///
29470/// int(*foo)[];
29471///
29472/// Suppose the caller of this function started to emit the inner
29473/// "foo" part of the expression already. It thus calls this function
29474/// with that input "foo" part. We consider that "foo" as the "type
29475/// identifier".
29476///
29477/// So we are passed an input string that is "foo" and it's going to
29478/// be turned into the inner_expr part, which is going to be "(*foo)".
29479///
29480/// The left_expr part is "int". The right_expr part is "[]".
29481///
29482/// In other words, this function adds the left_expr and right_expr to
29483/// the inner_expr. left_expr and right_expr are called "outer
29484/// pointer to array type expression".
29485///
29486/// The model of this function was taken from the article "Reading C
29487/// type declaration", from Steve Friedl at
29488/// http://unixwiz.net/techtips/reading-cdecl.html.
29489///
29490/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29491/// array_declaration_name()
29492///
29493/// @param p the pointer to array type to consider.
29494///
29495/// @param input the type-id to start from as the inner part of the
29496/// final type name.
29497///
29498/// @param qualified if true then use qualified names in the resulting
29499/// type name.
29500///
29501/// @param internal if true then the resulting type name is going to
29502/// be used for type canonicalization purposes.
29503///
29504/// @return the name of the pointer to array type.
29505static string
29506add_outer_pointer_to_array_type_expr(const type_base* p,
29507 const string& input, bool qualified,
29508 bool internal)
29509{
29510 if (!p)
29511 return "";
29512
29513 string star_or_ref;
29514 type_base_sptr pointed_to_type;
29515
29516 if (const pointer_type_def *ptr = is_pointer_type(p))
29517 {
29518 pointed_to_type = ptr->get_pointed_to_type();
29519 star_or_ref = "*";
29520 }
29521 else if (const reference_type_def *ref = is_reference_type(p))
29522 {
29523 pointed_to_type = ref->get_pointed_to_type();
29524 star_or_ref = "&";
29525 }
29526
29527 array_type_def_sptr array = is_array_type(pointed_to_type);
29528 if (!array)
29529 return "";
29530
29531 std::ostringstream left, right, inner;
29532 inner << "(" << star_or_ref << input << ")";
29533 right << array->get_subrange_representation();
29534 string result;
29535
29536 type_base_sptr array_element_type = array->get_element_type();
29537
29538 if (is_npaf_type(array_element_type)
29539 || !(is_pointer_to_function_type(array_element_type)
29540 || is_pointer_to_array_type(array_element_type)))
29541 {
29542 left << get_type_name(array_element_type, qualified, internal);
29543 result = left.str() + inner.str() + right.str();
29544 }
29545 else if (pointer_type_def_sptr p =
29546 is_pointer_to_function_type(array_element_type))
29547 {
29548 string r = inner.str() + right.str();
29549 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
29550 }
29551 else if (pointer_type_def_sptr p =
29552 is_pointer_to_array_type(array_element_type))
29553 {
29554 string inner_string = inner.str() + right.str();
29555 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29556 qualified, internal);
29557 }
29558 else
29560
29561 return result;
29562}
29563
29564/// When constructing the name of a pointer to array type, add the
29565/// array element type type to the left of the existing type
29566/// identifier, and the array declarator part to the right.
29567///
29568/// This function considers the name of the type as an expression.
29569///
29570/// The resulting type expr is going to be made of three parts:
29571/// left_expr inner_expr right_expr.
29572///
29573/// Suppose we want to build the type expression representing:
29574///
29575/// "a pointer to an array of int".
29576///
29577/// It's going to look like:
29578///
29579/// int(*foo)[];
29580///
29581/// Suppose the caller of this function started to emit the inner
29582/// "foo" part of the expression already. It thus calls this function
29583/// with that input "foo" part. We consider that "foo" as the "type
29584/// identifier".
29585///
29586/// So we are passed an input string that is "foo" and it's going to
29587/// be turned into the inner_expr part, which is going to be "(*foo)".
29588///
29589/// The left_expr part is "int". The right_expr part is "[]".
29590///
29591/// In other words, this function adds the left_expr and right_expr to
29592/// the inner_expr. left_expr and right_expr are called "outer
29593/// pointer to array type expression".
29594///
29595/// The model of this function was taken from the article "Reading C
29596/// type declaration", from Steve Friedl at
29597/// http://unixwiz.net/techtips/reading-cdecl.html.
29598///
29599/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29600/// array_declaration_name()
29601///
29602/// @param p the pointer to array type to consider.
29603///
29604/// @param input the type-id to start from as the inner part of the
29605/// final type name.
29606///
29607/// @param qualified if true then use qualified names in the resulting
29608/// type name.
29609///
29610/// @param internal if true then the resulting type name is going to
29611/// be used for type canonicalization purposes.
29612///
29613/// @return the name of the pointer to array type.
29614static string
29615add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
29616 const string& input, bool qualified,
29617 bool internal)
29618{return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
29619 input, qualified, internal);}
29620
29621/// When constructing the name of a pointer to mebmer type, add the
29622/// return type to the left of the existing type identifier, and the
29623/// parameters declarator to the right.
29624///
29625/// This function considers the name of the type as an expression.
29626///
29627/// The resulting type expr is going to be made of three parts:
29628/// left_expr inner_expr right_expr.
29629///
29630/// Suppose we want to build the type expression representing:
29631///
29632/// "an array of pointer to member function (of a containing struct
29633/// X) taking a char parameter and returning an int".
29634///
29635/// It's going to look like:
29636///
29637/// int (X::* a[])(char);
29638///
29639/// Suppose the caller of this function started to emit the inner
29640/// "a[]" part of the expression already. It thus calls this
29641/// function with that input "a[]" part. We consider that "a[]" as
29642/// the "type identifier".
29643///
29644/// So the inner_expr is going to be "(X::* a[])".
29645///
29646/// The left_expr part is "int". The right_expr part is "(char)".
29647///
29648/// In other words, this function adds the left_expr and right_expr to
29649/// the inner_expr. left_expr and right_expr are called "outer
29650/// pointer to member type expression".
29651///
29652/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29653///
29654/// @param p the pointer to member type to consider.
29655///
29656/// @param input the type-id to use as the inner expression of the
29657/// overall pointer-to-member type expression
29658///
29659/// @param qualified if true then use qualified names in the resulting
29660/// type name.
29661///
29662/// @param internal if true then the resulting type name is going to
29663/// be used for type canonicalization purposes.
29664///
29665/// @return the name of the pointer to member type.
29666static string
29667add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
29668 const string& input, bool qualified,
29669 bool internal)
29670{
29671 if (!p)
29672 return "";
29673
29674 std::ostringstream left, right, inner;
29675 type_base_sptr void_type = p->get_environment().get_void_type();
29676 string containing_type_name = get_type_name(p->get_containing_type(),
29677 qualified, internal);
29678 type_base_sptr mbr_type = p->get_member_type();
29679 string result;
29680 if (function_type_sptr fn_type = is_function_type(mbr_type))
29681 {
29682 inner << "(" << containing_type_name << "::*" << input << ")";
29683 stream_pretty_representation_of_fn_parms(*fn_type, right,
29684 qualified, internal);
29685 type_base_sptr return_type = fn_type->get_return_type();
29686 if (!return_type)
29687 return_type = void_type;
29688 if (is_npaf_type(return_type)
29689 || !(is_pointer_to_function_type(return_type)
29690 || is_pointer_to_array_type(return_type)
29691 || is_pointer_to_ptr_to_mbr_type(return_type)
29692 || is_ptr_to_mbr_type(return_type)))
29693 {
29694 left << get_type_name(return_type, qualified, internal) << " ";;
29695 result = left.str() + inner.str() + right.str();
29696 }
29697 else if (pointer_type_def_sptr p = is_pointer_type(return_type))
29698 {
29699 string inner_str = inner.str() + right.str();
29700 result = pointer_declaration_name(p, inner_str, qualified, internal);
29701 }
29702 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(return_type))
29703 {
29704 string inner_str = inner.str() + right.str();
29705 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
29706 qualified, internal);
29707 }
29708 else
29710 }
29711 else if (ptr_to_mbr_type_sptr ptr_mbr_type = is_ptr_to_mbr_type(mbr_type))
29712 {
29713 inner << "(" << containing_type_name << "::*" << input << ")";
29714 stream_pretty_representation_of_fn_parms(*fn_type, right,
29715 qualified, internal);
29716 string inner_str = inner.str() + right.str();
29717 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
29718 qualified, internal);
29719 }
29720 else
29721 {
29722 left << get_type_name(p->get_member_type(), qualified, internal) << " ";
29723 inner << containing_type_name << "::*" << input;
29724 result = left.str()+ inner.str();
29725 }
29726
29727 return result;
29728}
29729
29730/// Test if two decls have different names.
29731///
29732/// Note that this function takes into account decls whose names are
29733/// relevant from an ABI standpoint. For instance, function parameter
29734/// names are not relevant in that context.
29735///
29736/// @param d1 the first declaration to consider.
29737///
29738/// @param d2 the second declaration to consider.
29739///
29740/// @return true if d1 and d2 have different names.
29741bool
29743{
29744 string d1_name, d2_name;
29745
29746 const decl_base *d1 = dynamic_cast<const decl_base*>(a1);
29747 if (d1 == 0)
29748 return false;
29749
29750 const decl_base *d2 = dynamic_cast<const decl_base*>(a2);
29751 if (d2 == 0)
29752 return false;
29753
29755 // Name changes for fn parms are irrelevant.
29756 return false;
29757
29758 d1_name = d1->get_qualified_name();
29759 d2_name = d2->get_qualified_name();
29760
29761 return d1_name != d2_name;
29762}
29763
29764/// Test if two decls have different names.
29765///
29766/// @param d1 the first declaration to consider.
29767///
29768/// @param d2 the second declaration to consider.
29769///
29770/// @return true if d1 and d2 have different names.
29771bool
29773 const type_or_decl_base_sptr& d2)
29774{return decl_name_changed(d1.get(), d2.get());}
29775
29776/// Test if a diff node carries a change whereby two integral types
29777/// have different names in a harmless way.
29778///
29779/// Basically, if the integral type name change is accompanied by a
29780/// size change then the change is considered harmful. If there are
29781/// modifiers change, the change is considered harmful.
29782bool
29784 const type_base_sptr& s)
29785{
29786 if (is_decl(f)
29787 && is_decl(s)
29788 && ((is_integral_type(f) && is_integral_type(s))
29789 || (is_decl(f)->get_name().empty()
29790 && is_type_decl(f)
29791 && is_integral_type(s))
29792 || (is_decl(s)->get_name().empty()
29793 && is_type_decl(s)
29794 && is_integral_type(f)))
29796 && (f->get_size_in_bits() == s->get_size_in_bits())
29797 && (f->get_alignment_in_bits() == s->get_alignment_in_bits()))
29798 return true;
29799
29800 return false;
29801}
29802
29803/// Test if a diff node carries a change whereby two integral types
29804/// have different names in a harmless way.
29805///
29806/// Basically, if the integral type name change is accompanied by a
29807/// size change then the change is considered harmful. If there are
29808/// modifiers change, the change is considered harmful.
29809bool
29811 const decl_base_sptr& s)
29813
29814
29815/// When constructing the name of a pointer to mebmer type, add the
29816/// return type to the left of the existing type identifier, and the
29817/// parameters declarator to the right.
29818///
29819/// This function considers the name of the type as an expression.
29820///
29821/// The resulting type expr is going to be made of three parts:
29822/// left_expr inner_expr right_expr.
29823///
29824/// Suppose we want to build the type expression representing:
29825///
29826/// "an array of pointer to member function (of a containing struct
29827/// X) taking a char parameter and returning an int".
29828///
29829/// It's going to look like:
29830///
29831/// int (X::* a[])(char);
29832///
29833/// Suppose the caller of this function started to emit the inner
29834/// "a[]" part of the expression already. It thus calls this
29835/// function with that input "a[]" part. We consider that "a[]" as
29836/// the "type identifier".
29837///
29838/// So the inner_expr is going to be "(X::* a[])".
29839///
29840/// The left_expr part is "int". The right_expr part is "(char)".
29841///
29842/// In other words, this function adds the left_expr and right_expr to
29843/// the inner_expr. left_expr and right_expr are called "outer
29844/// pointer to member type expression".
29845///
29846/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29847///
29848/// @param p the pointer to member type to consider.
29849///
29850/// @param input the type-id to use as the inner expression of the
29851/// overall pointer-to-member type expression
29852///
29853/// @param qualified if true then use qualified names in the resulting
29854/// type name.
29855///
29856/// @param internal if true then the resulting type name is going to
29857/// be used for type canonicalization purposes.
29858///
29859/// @return the name of the pointer to member type.
29860static string
29861add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
29862 const string& input, bool qualified,
29863 bool internal)
29864{return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
29865
29866/// This adds the outer parts of a pointer to a pointer-to-member
29867/// expression.
29868///
29869/// Please read the comments of @ref add_outer_ptr_to_mbr_type_expr to
29870/// learn more about this function, which is similar.
29871///
29872/// This is a sub-routine of @ref pointer_declaration_name().
29873///
29874/// @param a pointer (or reference) to a pointer-to-member type.
29875///
29876/// @param input the inner type-id to add the outer parts to.
29877///
29878/// @param qualified if true then use qualified names in the resulting
29879/// type name.
29880///
29881/// @param internal if true then the resulting type name is going to
29882/// be used for type canonicalization purposes.
29883static string
29884add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
29885 const string& input, bool qualified,
29886 bool internal)
29887{
29888 if (!p)
29889 return "";
29890
29891 string star_or_ref;
29892 type_base_sptr pointed_to_type;
29893
29894 if (const pointer_type_def* ptr = is_pointer_type(p))
29895 {
29896 pointed_to_type = ptr->get_pointed_to_type();
29897 star_or_ref = "*";
29898 }
29899 else if (const reference_type_def* ref = is_reference_type(p))
29900 {
29901 pointed_to_type= ref->get_pointed_to_type();
29902 star_or_ref = "&";
29903 }
29904
29905 if (!pointed_to_type)
29906 return "";
29907
29908 ptr_to_mbr_type_sptr pointed_to_ptr_to_mbr =
29909 is_ptr_to_mbr_type(pointed_to_type);
29910 if (!pointed_to_ptr_to_mbr)
29911 return "";
29912
29913 std::ostringstream inner;
29914 inner << star_or_ref << input;
29915 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
29916 inner.str(),
29917 qualified, internal);
29918 return result;
29919}
29920
29921/// Emit the name of a pointer declaration.
29922///
29923/// @param the pointer to consider.
29924///
29925/// @param idname the name of the variable that has @p as a type or
29926/// the id of the type. If it's empty then the resulting name is
29927/// going to be the abstract name of the type.
29928///
29929/// @param qualified if true then the type name is going to be
29930/// fully qualified.
29931///
29932/// @param internal if true then the type name is going to be used for
29933/// type canonicalization purposes.
29934static interned_string
29935pointer_declaration_name(const type_base* ptr,
29936 const string& idname,
29937 bool qualified, bool internal)
29938{
29939 if (!ptr)
29940 return interned_string();
29941
29942 type_base_sptr pointed_to_type;
29943 string star_or_ref;
29944 if (const pointer_type_def* p = is_pointer_type(ptr))
29945 {
29946 pointed_to_type = p->get_pointed_to_type();
29947 star_or_ref = "*";
29948 }
29949 else if (const reference_type_def* p = is_reference_type(ptr))
29950 {
29951 pointed_to_type = p->get_pointed_to_type();
29952 star_or_ref = "&";
29953 }
29954
29955 if (!pointed_to_type)
29956 return interned_string();
29957
29958 string result;
29959 if (is_npaf_type(pointed_to_type)
29960 || !(is_function_type(pointed_to_type)
29961 || is_array_type(pointed_to_type)
29962 || is_ptr_to_mbr_type(pointed_to_type)))
29963 {
29964 result = get_type_name(pointed_to_type,
29965 qualified,
29966 internal)
29967 + star_or_ref;
29968
29969 if (!idname.empty())
29970 result += idname;
29971 }
29972 else
29973 {
29974 // derived type
29975 if (is_function_type(pointed_to_type))
29976 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
29977 qualified, internal);
29978 else if (is_array_type(pointed_to_type))
29979 result = add_outer_pointer_to_array_type_expr(ptr, idname,
29980 qualified, internal);
29981 else if (is_ptr_to_mbr_type(pointed_to_type))
29982 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
29983 qualified, internal);
29984 else
29986 }
29987 return ptr->get_environment().intern(result);
29988}
29989
29990
29991/// Emit the name of a pointer declaration.
29992///
29993/// @param the pointer to consider.
29994///
29995/// @param the name of the variable that has @p as a type. If it's
29996/// empty then the resulting name is going to be the abstract name of
29997/// the type.
29998///
29999/// @param qualified if true then the type name is going to be
30000/// fully qualified.
30001///
30002/// @param internal if true then the type name is going to be used for
30003/// type canonicalization purposes.
30004static interned_string
30005pointer_declaration_name(const type_base_sptr& ptr,
30006 const string& variable_name,
30007 bool qualified, bool internal)
30008{return pointer_declaration_name(ptr.get(), variable_name,
30009 qualified, internal);}
30010
30011/// Emit the name of a array declaration.
30012///
30013/// @param the array to consider.
30014///
30015/// @param the name of the variable that has @p as a type. If it's
30016/// empty then the resulting name is going to be the abstract name of
30017/// the type.
30018///
30019/// @param qualified if true then the type name is going to be
30020/// fully qualified.
30021///
30022/// @param internal if true then the type name is going to be used for
30023/// type canonicalization purposes.
30024static interned_string
30025array_declaration_name(const array_type_def* array,
30026 const string& variable_name,
30027 bool qualified, bool internal)
30028{
30029 if (!array)
30030 return interned_string();
30031
30032 type_base_sptr e_type = array->get_element_type();
30033 string e_type_repr =
30034 (e_type
30035 ? get_type_name(e_type, qualified, internal)
30036 : string("void"));
30037
30038 string result;
30039 if (is_ada_language(array->get_language()))
30040 {
30041 std::ostringstream o;
30042 if (!variable_name.empty())
30043 o << variable_name << " is ";
30044 o << "array ("
30045 << array->get_subrange_representation()
30046 << ") of " << e_type_repr;
30047 result = o.str();
30048 }
30049 else
30050 {
30051 if (is_npaf_type(e_type)
30052 || !(is_pointer_to_function_type(e_type)
30053 || is_pointer_to_array_type(e_type)
30055 || is_ptr_to_mbr_type(e_type)))
30056 {
30057 result = e_type_repr;
30058 if (!variable_name.empty())
30059 result += variable_name;
30060 result += array->get_subrange_representation();
30061 }
30062 else if (pointer_type_def_sptr p = is_pointer_type(e_type))
30063 {
30064 string s = variable_name + array->get_subrange_representation();
30065 result = pointer_declaration_name(p, s, qualified, internal);
30066 }
30067 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(e_type))
30068 {
30069 string s = variable_name + array->get_subrange_representation();
30070 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
30071 }
30072 else
30074 }
30075 return array->get_environment().intern(result);
30076}
30077
30078/// Emit the name of a array declaration.
30079///
30080/// @param the array to consider.
30081///
30082/// @param the name of the variable that has @p as a type. If it's
30083/// empty then the resulting name is going to be the abstract name of
30084/// the type.
30085///
30086/// @param qualified if true then the type name is going to be
30087/// fully qualified.
30088///
30089/// @param internal if true then the type name is going to be used for
30090/// type canonicalization purposes.
30091static interned_string
30092array_declaration_name(const array_type_def_sptr& array,
30093 const string& variable_name,
30094 bool qualified, bool internal)
30095{return array_declaration_name(array.get(), variable_name,
30096 qualified, internal);}
30097
30098/// Emit the name of a pointer-to-member declaration.
30099///
30100/// @param ptr the pointer-to-member to consider.
30101///
30102/// @param variable_name the name of the variable that has @p as a
30103/// type. If it's empty then the resulting name is going to be the
30104/// abstract name of the type.
30105///
30106/// @param qualified if true then the type name is going to be
30107/// fully qualified.
30108///
30109/// @param internal if true then the type name is going to be used for
30110/// type canonicalization purposes.
30111static interned_string
30112ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
30113 const string& variable_name,
30114 bool qualified, bool internal)
30115{
30116 if (!ptr)
30117 return interned_string();
30118
30119 string input = variable_name;
30120 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
30121 qualified, internal);
30122 return ptr->get_environment().intern(result);
30123}
30124
30125/// Emit the name of a pointer-to-member declaration.
30126///
30127/// @param ptr the pointer-to-member to consider.
30128///
30129/// @param variable_name the name of the variable that has @p as a
30130/// type. If it's empty then the resulting name is going to be the
30131/// abstract name of the type.
30132///
30133/// @param qualified if true then the type name is going to be
30134/// fully qualified.
30135///
30136/// @param internal if true then the type name is going to be used for
30137/// type canonicalization purposes.
30138static interned_string
30139ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
30140 const string& variable_name,
30141 bool qualified, bool internal)
30142{
30143 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
30144 qualified, internal);
30145}
30146
30147/// Sort types right before hashing and canonicalizing them.
30148///
30149/// @param types the vector of types to sort.
30150void
30151sort_types_for_hash_computing_and_c14n(vector<type_base_sptr>& types)
30152{
30153 sort_types_for_hash_computing_and_c14n(types.begin(), types.end());
30154}
30155
30156bool
30159
30160// <ir_node_visitor stuff>
30161
30162/// The private data structure of the ir_node_visitor type.
30163struct ir_node_visitor::priv
30164{
30165 pointer_set visited_ir_nodes;
30166 bool allow_visiting_already_visited_type_node;
30167
30168 priv()
30169 : allow_visiting_already_visited_type_node(true)
30170 {}
30171}; // end struct ir_node_visitory::priv
30172
30173/// Default Constructor of the ir_node_visitor type.
30175 : priv_(new priv)
30176{}
30177
30178ir_node_visitor::~ir_node_visitor() = default;
30179
30180/// Set if the walker using this visitor is allowed to re-visit a type
30181/// node that was previously visited or not.
30182///
30183/// @param f if true, then the walker using this visitor is allowed to
30184/// re-visit a type node that was previously visited.
30185void
30187{priv_->allow_visiting_already_visited_type_node = f;}
30188
30189/// Get if the walker using this visitor is allowed to re-visit a type
30190/// node that was previously visited or not.
30191///
30192/// @return true iff the walker using this visitor is allowed to
30193/// re-visit a type node that was previously visited.
30194bool
30196{return priv_->allow_visiting_already_visited_type_node;}
30197
30198/// Mark a given type node as having been visited.
30199///
30200/// Note that for this function to work, the type node must have been
30201/// canonicalized. Otherwise the process is aborted.
30202///
30203/// @param p the type to mark as having been visited.
30204void
30206{
30208 return;
30209
30210 if (p == 0 || type_node_has_been_visited(p))
30211 return;
30212
30213 type_base* canonical_type = p->get_naked_canonical_type();
30215 {
30216 ABG_ASSERT(!canonical_type);
30217 canonical_type = p;
30218 }
30219 ABG_ASSERT(canonical_type);
30220
30221 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
30222 priv_->visited_ir_nodes.insert(canonical_ptr_value);
30223}
30224
30225/// Un-mark all visited type nodes.
30226///
30227/// That is, no type node is going to be considered as having been
30228/// visited anymore.
30229///
30230/// In other words, after invoking this funciton,
30231/// ir_node_visitor::type_node_has_been_visited() is going to return
30232/// false on all type nodes.
30233void
30235{priv_->visited_ir_nodes.clear();}
30236
30237/// Test if a given type node has been marked as visited.
30238///
30239/// @param p the type node to consider.
30240///
30241/// @return true iff the type node @p p has been marked as visited by
30242/// the function ir_node_visitor::mark_type_node_as_visited.
30243bool
30245{
30247 return false;
30248
30249 if (p == 0)
30250 return false;
30251
30252 type_base *canonical_type = p->get_naked_canonical_type();
30254 {
30255 ABG_ASSERT(!canonical_type);
30256 canonical_type = p;
30257 }
30258 ABG_ASSERT(canonical_type);
30259
30260 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
30261 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
30262 if (it == priv_->visited_ir_nodes.end())
30263 return false;
30264
30265 return true;
30266}
30267
30268bool
30269ir_node_visitor::visit_begin(decl_base*)
30270{return true;}
30271
30272bool
30273ir_node_visitor::visit_end(decl_base*)
30274{return true;}
30275
30276bool
30277ir_node_visitor::visit_begin(scope_decl*)
30278{return true;}
30279
30280bool
30281ir_node_visitor::visit_end(scope_decl*)
30282{return true;}
30283
30284bool
30285ir_node_visitor::visit_begin(type_base*)
30286{return true;}
30287
30288bool
30289ir_node_visitor::visit_end(type_base*)
30290{return true;}
30291
30292bool
30293ir_node_visitor::visit_begin(scope_type_decl* t)
30294{return visit_begin(static_cast<type_base*>(t));}
30295
30296bool
30297ir_node_visitor::visit_end(scope_type_decl* t)
30298{return visit_end(static_cast<type_base*>(t));}
30299
30300bool
30301ir_node_visitor::visit_begin(type_decl* t)
30302{return visit_begin(static_cast<type_base*>(t));}
30303
30304bool
30305ir_node_visitor::visit_end(type_decl* t)
30306{return visit_end(static_cast<type_base*>(t));}
30307
30308bool
30309ir_node_visitor::visit_begin(namespace_decl* d)
30310{return visit_begin(static_cast<decl_base*>(d));}
30311
30312bool
30313ir_node_visitor::visit_end(namespace_decl* d)
30314{return visit_end(static_cast<decl_base*>(d));}
30315
30316bool
30317ir_node_visitor::visit_begin(qualified_type_def* t)
30318{return visit_begin(static_cast<type_base*>(t));}
30319
30320bool
30321ir_node_visitor::visit_end(qualified_type_def* t)
30322{return visit_end(static_cast<type_base*>(t));}
30323
30324bool
30325ir_node_visitor::visit_begin(pointer_type_def* t)
30326{return visit_begin(static_cast<type_base*>(t));}
30327
30328bool
30329ir_node_visitor::visit_end(pointer_type_def* t)
30330{return visit_end(static_cast<type_base*>(t));}
30331
30332bool
30333ir_node_visitor::visit_begin(reference_type_def* t)
30334{return visit_begin(static_cast<type_base*>(t));}
30335
30336bool
30337ir_node_visitor::visit_end(reference_type_def* t)
30338{return visit_end(static_cast<type_base*>(t));}
30339
30340bool
30341ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
30342{return visit_begin(static_cast<type_base*>(t));}
30343
30344bool
30345ir_node_visitor::visit_end(ptr_to_mbr_type* t)
30346{return visit_end(static_cast<type_base*>(t));}
30347
30348bool
30349ir_node_visitor::visit_begin(array_type_def* t)
30350{return visit_begin(static_cast<type_base*>(t));}
30351
30352bool
30353ir_node_visitor::visit_end(array_type_def* t)
30354{return visit_end(static_cast<type_base*>(t));}
30355
30356bool
30357ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
30358{return visit_begin(static_cast<type_base*>(t));}
30359
30360bool
30361ir_node_visitor::visit_end(array_type_def::subrange_type* t)
30362{return visit_end(static_cast<type_base*>(t));}
30363
30364bool
30365ir_node_visitor::visit_begin(enum_type_decl* t)
30366{return visit_begin(static_cast<type_base*>(t));}
30367
30368bool
30369ir_node_visitor::visit_end(enum_type_decl* t)
30370{return visit_end(static_cast<type_base*>(t));}
30371
30372bool
30373ir_node_visitor::visit_begin(typedef_decl* t)
30374{return visit_begin(static_cast<type_base*>(t));}
30375
30376bool
30377ir_node_visitor::visit_end(typedef_decl* t)
30378{return visit_end(static_cast<type_base*>(t));}
30379
30380bool
30381ir_node_visitor::visit_begin(function_type* t)
30382{return visit_begin(static_cast<type_base*>(t));}
30383
30384bool
30385ir_node_visitor::visit_end(function_type* t)
30386{return visit_end(static_cast<type_base*>(t));}
30387
30388bool
30389ir_node_visitor::visit_begin(var_decl* d)
30390{return visit_begin(static_cast<decl_base*>(d));}
30391
30392bool
30393ir_node_visitor::visit_end(var_decl* d)
30394{return visit_end(static_cast<decl_base*>(d));}
30395
30396bool
30397ir_node_visitor::visit_begin(function_decl* d)
30398{return visit_begin(static_cast<decl_base*>(d));}
30399
30400bool
30401ir_node_visitor::visit_end(function_decl* d)
30402{return visit_end(static_cast<decl_base*>(d));}
30403
30404bool
30405ir_node_visitor::visit_begin(function_decl::parameter* d)
30406{return visit_begin(static_cast<decl_base*>(d));}
30407
30408bool
30409ir_node_visitor::visit_end(function_decl::parameter* d)
30410{return visit_end(static_cast<decl_base*>(d));}
30411
30412bool
30413ir_node_visitor::visit_begin(function_tdecl* d)
30414{return visit_begin(static_cast<decl_base*>(d));}
30415
30416bool
30417ir_node_visitor::visit_end(function_tdecl* d)
30418{return visit_end(static_cast<decl_base*>(d));}
30419
30420bool
30421ir_node_visitor::visit_begin(class_tdecl* d)
30422{return visit_begin(static_cast<decl_base*>(d));}
30423
30424bool
30425ir_node_visitor::visit_end(class_tdecl* d)
30426{return visit_end(static_cast<decl_base*>(d));}
30427
30428bool
30429ir_node_visitor::visit_begin(class_or_union* t)
30430{return visit_begin(static_cast<type_base*>(t));}
30431
30432bool
30433ir_node_visitor::visit_end(class_or_union* t)
30434{return visit_end(static_cast<type_base*>(t));}
30435
30436bool
30437ir_node_visitor::visit_begin(class_decl* t)
30438{return visit_begin(static_cast<type_base*>(t));}
30439
30440bool
30441ir_node_visitor::visit_end(class_decl* t)
30442{return visit_end(static_cast<type_base*>(t));}
30443
30444bool
30445ir_node_visitor::visit_begin(union_decl* t)
30446{return visit_begin(static_cast<type_base*>(t));}
30447
30448bool
30449ir_node_visitor::visit_end(union_decl* t)
30450{return visit_end(static_cast<type_base*>(t));}
30451
30452bool
30453ir_node_visitor::visit_begin(class_decl::base_spec* d)
30454{return visit_begin(static_cast<decl_base*>(d));}
30455
30456bool
30457ir_node_visitor::visit_end(class_decl::base_spec* d)
30458{return visit_end(static_cast<decl_base*>(d));}
30459
30460bool
30461ir_node_visitor::visit_begin(member_function_template* d)
30462{return visit_begin(static_cast<decl_base*>(d));}
30463
30464bool
30465ir_node_visitor::visit_end(member_function_template* d)
30466{return visit_end(static_cast<decl_base*>(d));}
30467
30468bool
30469ir_node_visitor::visit_begin(member_class_template* d)
30470{return visit_begin(static_cast<decl_base*>(d));}
30471
30472bool
30473ir_node_visitor::visit_end(member_class_template* d)
30474{return visit_end(static_cast<decl_base*>(d));}
30475
30476// </ir_node_visitor stuff>
30477
30478// <debugging facilities>
30479
30480/// Generate a different string at each invocation.
30481///
30482/// @return the resulting string.
30483static string
30484get_next_string()
30485{
30486 static __thread size_t counter;
30487 ++counter;
30488 std::ostringstream o;
30489 o << counter;
30490 return o.str();
30491}
30492
30493/// A hashing functor for a @ref function_decl
30494struct function_decl_hash
30495{
30496 size_t operator()(const function_decl* f) const
30497 {return reinterpret_cast<size_t>(f);}
30498
30499 size_t operator()(const function_decl_sptr& f) const
30500 {return operator()(f.get());}
30501};
30502
30503/// Convenience typedef for a hash map of pointer to function_decl and
30504/// string.
30505typedef unordered_map<const function_decl*, string,
30506 function_decl_hash,
30508
30509/// Return a string associated to a given function. Two functions
30510/// that compare equal would yield the same string, as far as this
30511/// routine is concerned. And two functions that are different would
30512/// yield different strings.
30513///
30514/// This is used to debug core diffing issues on functions. The
30515/// sequence of strings can be given to the 'testdiff2' program that
30516/// is in the tests/ directory of the source tree, to reproduce core
30517/// diffing issues on string and thus ease the debugging.
30518///
30519/// @param fn the function to generate a string for.
30520///
30521/// @param m the function_decl* <-> string map to be used by this
30522/// function to generate strings associated to a function.
30523///
30524/// @return the resulting string.
30525static const string&
30526fn_to_str(const function_decl* fn,
30528{
30529 fns_to_str_map_type::const_iterator i = m.find(fn);
30530 if (i != m.end())
30531 return i->second;
30532 string s = get_next_string();
30533 return m[fn]= s;
30534}
30535
30536/// Generate a sequence of string that matches a given sequence of
30537/// function. In the resulting sequence, each function is "uniquely
30538/// representated" by a string. For instance, if the same function "foo"
30539/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
30540/// we don't care about the actual string) would appear at index 1 and 3.
30541///
30542/// @param begin the beginning of the sequence of functions to consider.
30543///
30544/// @param end the end of the sequence of functions. This points to
30545/// one-passed-the-end of the actual sequence.
30546///
30547/// @param m the function_decl* <-> string map to be used by this
30548/// function to generate strings associated to a function.
30549///
30550/// @param o the output stream where to emit the generated list of
30551/// strings to.
30552static void
30553fns_to_str(vector<function_decl*>::const_iterator begin,
30554 vector<function_decl*>::const_iterator end,
30556 std::ostream& o)
30557{
30558 vector<function_decl*>::const_iterator i;
30559 for (i = begin; i != end; ++i)
30560 o << "'" << fn_to_str(*i, m) << "' ";
30561}
30562
30563/// For each sequence of functions given in argument, generate a
30564/// sequence of string that matches a given sequence of function. In
30565/// the resulting sequence, each function is "uniquely representated"
30566/// by a string. For instance, if the same function "foo" appears at
30567/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30568/// care about the actual string) would appear at index 1 and 3.
30569///
30570/// @param a_begin the beginning of the sequence of functions to consider.
30571///
30572/// @param a_end the end of the sequence of functions. This points to
30573/// one-passed-the-end of the actual sequence.
30574///
30575/// @param b_begin the beginning of the second sequence of functions
30576/// to consider.
30577///
30578/// @param b_end the end of the second sequence of functions.
30579///
30580/// @param m the function_decl* <-> string map to be used by this
30581/// function to generate strings associated to a function.
30582///
30583/// @param o the output stream where to emit the generated list of
30584/// strings to.
30585static void
30586fns_to_str(vector<function_decl*>::const_iterator a_begin,
30587 vector<function_decl*>::const_iterator a_end,
30588 vector<function_decl*>::const_iterator b_begin,
30589 vector<function_decl*>::const_iterator b_end,
30591 std::ostream& o)
30592{
30593 fns_to_str(a_begin, a_end, m, o);
30594 o << "->|<- ";
30595 fns_to_str(b_begin, b_end, m, o);
30596 o << "\n";
30597}
30598
30599/// For each sequence of functions given in argument, generate a
30600/// sequence of string that matches a given sequence of function. In
30601/// the resulting sequence, each function is "uniquely representated"
30602/// by a string. For instance, if the same function "foo" appears at
30603/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30604/// care about the actual string) would appear at index 1 and 3.
30605///
30606/// @param a_begin the beginning of the sequence of functions to consider.
30607///
30608/// @param a_end the end of the sequence of functions. This points to
30609/// one-passed-the-end of the actual sequence.
30610///
30611/// @param b_begin the beginning of the second sequence of functions
30612/// to consider.
30613///
30614/// @param b_end the end of the second sequence of functions.
30615///
30616/// @param o the output stream where to emit the generated list of
30617/// strings to.
30618void
30619fns_to_str(vector<function_decl*>::const_iterator a_begin,
30620 vector<function_decl*>::const_iterator a_end,
30621 vector<function_decl*>::const_iterator b_begin,
30622 vector<function_decl*>::const_iterator b_end,
30623 std::ostream& o)
30624{
30626 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
30627}
30628
30629// </debugging facilities>
30630
30631// </class template>
30632
30633}// end namespace ir
30634}//end namespace abigail
30635
30636namespace
30637{
30638
30639/// Update the qualified parent name, qualified name and scoped name
30640/// of a tree decl node.
30641///
30642/// @return true if the tree walking should continue, false otherwise.
30643///
30644/// @param d the tree node to take in account.
30645bool
30646qualified_name_setter::do_update(abigail::ir::decl_base* d)
30647{
30648 std::string parent_qualified_name;
30649 abigail::ir::scope_decl* parent = d->get_scope();
30650 if (parent)
30651 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
30652 else
30653 d->priv_->qualified_parent_name_ = abigail::interned_string();
30654
30655 const abigail::ir::environment& env = d->get_environment();
30656
30657 if (!d->priv_->qualified_parent_name_.empty())
30658 {
30659 if (d->get_name().empty())
30660 d->priv_->qualified_name_ = abigail::interned_string();
30661 else
30662 {
30663 d->priv_->qualified_name_ =
30664 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
30665 d->priv_->internal_qualified_name_ = env.intern(d->get_name());
30666 }
30667 }
30668 // Make sure the internal qualified name (used for type
30669 // canonicalization puroses) is always the qualified name. For
30670 // integral/real types however, only the non qualified type is used.
30671 if (!is_integral_type(d))
30672 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
30673
30674 if (d->priv_->scoped_name_.empty())
30675 {
30676 if (parent
30677 && !parent->get_is_anonymous()
30678 && !parent->get_name().empty())
30679 d->priv_->scoped_name_ =
30680 env.intern(parent->get_name() + "::" + d->get_name());
30681 else
30682 d->priv_->scoped_name_ =
30683 env.intern(d->get_name());
30684 }
30685
30686 if (!is_scope_decl(d))
30687 return false;
30688
30689 return true;
30690}
30691
30692/// This is called when we start visiting a decl node, during the
30693/// udpate of the qualified name of a given sub-tree.
30694///
30695/// @param d the decl node we are visiting.
30696///
30697/// @return true iff the traversal should keep going.
30698bool
30699qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
30700{return do_update(d);}
30701
30702/// This is called when we start visiting a type node, during the
30703/// udpate of the qualified name of a given sub-tree.
30704///
30705/// @param d the decl node we are visiting.
30706///
30707/// @return true iff the traversal should keep going.
30708bool
30709qualified_name_setter::visit_begin(abigail::ir::type_base* t)
30710{
30712 return do_update(d);
30713 return false;
30714}
30715}// 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:1743
Declaration of types pertaining to the interned string pool used throughout Libabigail,...
This contains the private implementation of the suppression engine of libabigail.
#define CACHE_COMPARISON_RESULT_AND_RETURN(value)
Cache the result of a comparison between too artifacts (l & r) and return immediately.
Definition abg-ir.cc:1145
#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r)
This macro is to be used while comparing composite types that might recursively refer to themselves....
Definition abg-ir.cc:1031
Types of the main internal representation of libabigail.
Wrappers around regex types and functions.
#define ABG_ASSERT_NOT_REACHED
A macro that expands to aborting the program when executed.
This type abstracts the configuration information of the library.
Definition abg-config.h:18
bool has_string(const char *s) const
Test if the interned string pool already contains a string with a given value.
Definition abg-ir.cc:96
const char * get_string(const char *s) const
Get a pointer to the interned string which has a given value.
Definition abg-ir.cc:106
interned_string create_string(const std::string &)
Create an interned string with a given value.
Definition abg-ir.cc:123
interned_string_pool()
Default constructor.
Definition abg-ir.cc:83
~interned_string_pool()
Destructor.
Definition abg-ir.cc:132
The abstraction of an interned string.
bool empty() const
Test if the current instance of interned_string is empty.
This class is to hold the value of the bound of a subrange. The value can be either signed or unsigne...
Definition abg-ir.h:2589
void set_signed(int64_t v)
Setter of the bound value as signed.
Definition abg-ir.cc:19259
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition abg-ir.cc:19227
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition abg-ir.cc:19220
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition abg-ir.cc:19234
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition abg-ir.cc:19271
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition abg-ir.cc:19242
bound_value()
Default constructor of the array_type_def::subrange_type::bound_value class.
Definition abg-ir.cc:19192
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition abg-ir.cc:19249
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++.
Definition abg-ir.h:2574
void set_lower_bound(int64_t lb)
Setter of the lower bound.
Definition abg-ir.cc:19450
bool is_non_finite() const
Test if the length of the subrange type is infinite.
Definition abg-ir.cc:19477
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition abg-ir.cc:19443
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:19417
string as_string() const
Return a string representation of the sub range.
Definition abg-ir.cc:19499
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:19398
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:19699
bool operator!=(const decl_base &o) const
Equality operator.
Definition abg-ir.cc:19638
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition abg-ir.cc:19429
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:19409
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:19594
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition abg-ir.cc:19436
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:19677
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition abg-ir.cc:19522
uint64_t get_length() const
Getter of the length of the subrange type.
Definition abg-ir.cc:19460
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition abg-ir.cc:19492
The abstraction of an array type.
Definition abg-ir.h:2548
virtual bool is_non_finite() const
Definition abg-ir.cc:20116
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:20146
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:19806
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition abg-ir.cc:20077
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition abg-ir.cc:20092
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition abg-ir.h:2566
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:20209
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition abg-ir.cc:20236
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:20055
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
Definition abg-ir.h:2569
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of array_type_def.
Definition abg-ir.cc:19859
translation_unit::language get_language() const
Get the language of the array.
Definition abg-ir.cc:20044
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition abg-ir.cc:20102
Abstraction of a base specifier in a class declaration.
Definition abg-ir.h:4364
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
Definition abg-ir.cc:25440
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition abg-ir.cc:25447
long get_offset_in_bits() const
Getter of the offset of the base.
Definition abg-ir.cc:25454
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:25429
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:25470
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Definition abg-ir.cc:25564
Abstracts a class declaration.
Definition abg-ir.h:4174
void is_struct(bool f)
Set the "is-struct" flag of the class.
Definition abg-ir.cc:25237
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition abg-ir.cc:26020
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:25306
bool is_struct() const
Test if the class is a struct.
Definition abg-ir.cc:25244
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:26083
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition abg-ir.cc:25261
virtual ~class_decl()
Destructor of the class_decl type.
Definition abg-ir.cc:26597
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:25222
bool has_vtable() const
Test if the current instance has a vtable.
Definition abg-ir.cc:26048
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition abg-ir.cc:26062
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition abg-ir.cc:26029
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26513
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition abg-ir.h:4192
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
Definition abg-ir.cc:25251
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition abg-ir.cc:25287
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition abg-ir.cc:25311
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition abg-ir.cc:26181
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition abg-ir.cc:26361
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:25271
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition abg-ir.cc:26011
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition abg-ir.h:4193
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:25332
The base type of class_decl and union_decl.
Definition abg-ir.h:3977
virtual size_t get_num_anonymous_member_classes() const
Get the number of anonymous member classes contained in this class.
Definition abg-ir.cc:24115
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:24356
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:24281
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition abg-ir.cc:24384
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
Definition abg-ir.cc:24001
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition abg-ir.cc:24460
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition abg-ir.cc:24100
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition abg-ir.cc:24133
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
Definition abg-ir.cc:24474
unordered_map< ssize_t, member_functions > virtual_mem_fn_map_type
Convenience typedef.
Definition abg-ir.h:4009
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition abg-ir.h:4008
const data_members & get_data_members() const
Get the data members of this class_or_union.
Definition abg-ir.cc:24240
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:23891
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:24182
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:24435
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:24419
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition abg-ir.cc:24084
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
Definition abg-ir.cc:24516
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:23989
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:23907
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition abg-ir.cc:24488
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
Definition abg-ir.cc:24331
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:24393
const data_members & get_static_data_members() const
Get the static data memebers of this class_or_union.
Definition abg-ir.cc:24339
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:24026
vector< var_decl_sptr > data_members
Convenience typedef.
Definition abg-ir.h:4007
virtual ~class_or_union()
Destrcutor of the class_or_union type.
Definition abg-ir.cc:23980
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:24550
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition abg-ir.cc:26900
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition abg-ir.cc:24052
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition abg-ir.cc:24467
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition abg-ir.cc:24068
vector< type_base_sptr > member_types
Convenience typedef.
Definition abg-ir.h:4006
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
Definition abg-ir.cc:24151
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:24251
Abstract a class template.
Definition abg-ir.h:3797
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition abg-ir.cc:28292
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
Definition abg-ir.cc:28281
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:28341
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:28296
The abstraction of the relationship between an entity and its containing scope (its context)....
Definition abg-ir.h:1285
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition abg-corpus.h:25
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr<exported_decls_builder>.
Definition abg-corpus.h:45
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
origin get_origin() const
Getter for the origin of the corpus.
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
type_maps & get_type_per_loc_map()
Get the maps that associate a location string to a certain kind of type.
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
const environment & get_environment() const
Getter of the enviroment of the corpus.
The base type of all declarations.
Definition abg-ir.h:1585
void set_definition_of_declaration(const decl_base_sptr &)
Set the definition of this declaration-only decl_base.
Definition abg-ir.cc:16337
void set_is_declaration_only(bool f)
Set a flag saying if the enum_type_decl is a declaration-only enum_type_decl.
Definition abg-ir.cc:5012
virtual bool operator!=(const decl_base &) const
Inequality operator.
Definition abg-ir.cc:5227
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current decl.
Definition abg-ir.cc:4901
scope_decl * get_scope() const
Return the type containing the current decl, if any.
Definition abg-ir.cc:4799
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
Definition abg-ir.cc:4530
void set_is_in_public_symbol_table(bool)
Set the flag saying if this decl is from a symbol that is in a public symbols table,...
Definition abg-ir.cc:4592
friend bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
Definition abg-ir.cc:5582
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
Definition abg-ir.cc:4960
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
Definition abg-ir.cc:4774
const decl_base * get_naked_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
Definition abg-ir.cc:4996
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition abg-ir.cc:4830
void clear_qualified_name()
Clear the qualified name of this decl.
Definition abg-ir.cc:4523
virtual void set_name(const string &n)
Setter for the name of the decl.
Definition abg-ir.cc:4662
const location & get_location() const
Get the location of a given declaration.
Definition abg-ir.cc:4612
binding
ELF binding.
Definition abg-ir.h:1636
typedef_decl_sptr get_naming_typedef() const
Getter for the naming typedef of the current decl.
Definition abg-ir.cc:4722
virtual const interned_string & get_name() const
Getter for the name of the current decl.
Definition abg-ir.cc:4818
virtual void set_scope(scope_decl *)
Setter of the scope of the current decl.
Definition abg-ir.cc:5254
const interned_string & peek_qualified_name() const
Getter for the qualified name.
Definition abg-ir.cc:4514
const context_rel * get_context_rel() const
Getter for the context relationship.
Definition abg-ir.cc:4564
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Definition abg-ir.cc:4675
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scpe)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition abg-ir.cc:8457
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
Definition abg-ir.cc:4952
const decl_base_sptr get_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
Definition abg-ir.cc:4980
friend void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition abg-ir.cc:5551
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
Definition abg-ir.cc:4740
void set_location(const location &l)
Set the location for a given declaration.
Definition abg-ir.cc:4650
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
Definition abg-ir.cc:4685
void set_visibility(visibility v)
Setter for the visibility of the decl.
Definition abg-ir.cc:4791
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
Definition abg-ir.cc:4557
visibility get_visibility() const
Getter for the visibility of the decl.
Definition abg-ir.cc:4784
visibility
ELF visibility.
Definition abg-ir.h:1626
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Definition abg-ir.cc:5003
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:5243
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition abg-ir.cc:4968
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition abg-ir.cc:4767
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition abg-ir.cc:5522
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition abg-ir.cc:6648
virtual ~decl_base()
Destructor of the decl_base type.
Definition abg-ir.cc:5231
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:5216
const interned_string & get_qualified_parent_name() const
Return a copy of the qualified name of the parent of the current decl.
Definition abg-ir.cc:4811
bool get_is_anonymous_or_has_anonymous_parent() const
Definition abg-ir.cc:4708
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
Definition abg-ir.cc:4697
bool get_is_in_public_symbol_table() const
Test if the decl is defined in a ELF symbol table as a public symbol.
Definition abg-ir.cc:4584
friend bool equals(const decl_base &, const decl_base &, change_kind *)
Compares two instances of decl_base.
Definition abg-ir.cc:5145
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
Definition abg-ir.cc:4543
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representatin of the current declaration.
Definition abg-ir.cc:4853
The abstraction for a data member context relationship. This relates a data member to its parent clas...
Definition abg-ir.h:3003
const var_decl * get_anonymous_data_member() const
Return a non-nil value if this data member context relationship has an anonymous data member....
Definition abg-ir.cc:3351
void set_anonymous_data_member(var_decl *)
Set the containing anonymous data member of this data member context relationship....
Definition abg-ir.cc:3361
The abstraction of the version of an ELF symbol.
Definition abg-ir.h:1232
version & operator=(const version &o)
Assign a version to the current one.
Definition abg-ir.cc:3264
bool operator==(const version &o) const
Compares the current version against another one.
Definition abg-ir.cc:3246
bool is_default() const
Getter for the 'is_default' property of the version.
Definition abg-ir.cc:3226
const string & str() const
Getter for the version name.
Definition abg-ir.cc:3212
bool operator!=(const version &o) const
Inequality operator.
Definition abg-ir.cc:3255
Abstraction of an elf symbol.
Definition abg-ir.h:961
const abg_compat::optional< std::string > & get_namespace() const
Getter of the 'namespace' property.
Definition abg-ir.cc:2342
elf_symbol_sptr get_alias_which_equals(const elf_symbol &other) const
In the list of aliases of a given elf symbol, get the alias that equals this current symbol.
Definition abg-ir.cc:2665
elf_symbol_sptr get_next_common_instance() const
Get the next common instance of the current common symbol.
Definition abg-ir.cc:2560
type get_type() const
Getter for the type of the current instance of elf_symbol.
Definition abg-ir.cc:2176
const elf_symbol_sptr get_main_symbol() const
Get the main symbol of an alias chain.
Definition abg-ir.cc:2397
void set_is_in_ksymtab(bool is_in_ksymtab)
Setter of the 'is-in-ksymtab' property.
Definition abg-ir.cc:2321
bool has_aliases() const
Check if the current elf_symbol has an alias.
Definition abg-ir.cc:2426
void set_name(const string &n)
Setter for the name of the current intance of elf_symbol.
Definition abg-ir.cc:2166
bool is_suppressed() const
Getter for the 'is-suppressed' property.
Definition abg-ir.cc:2358
binding
The binding of a symbol.
Definition abg-ir.h:978
int get_number_of_aliases() const
Get the number of aliases to this elf symbol.
Definition abg-ir.cc:2433
string get_aliases_id_string(const string_elf_symbols_map_type &symtab, bool include_symbol_itself=true) const
Return a comma separated list of the id of the current symbol as well as the id string of its aliases...
Definition abg-ir.cc:2686
void set_binding(binding b)
Setter for the binding of the current instance of elf_symbol.
Definition abg-ir.cc:2211
void add_common_instance(const elf_symbol_sptr &)
Add a common instance to the current common elf symbol.
Definition abg-ir.cc:2571
void add_alias(const elf_symbol_sptr &)
Add an alias to the current elf symbol.
Definition abg-ir.cc:2450
void set_is_suppressed(bool is_suppressed)
Setter for the 'is-suppressed' property.
Definition abg-ir.cc:2367
bool is_variable() const
Test if the current instance of elf_symbol is a variable symbol or not.
Definition abg-ir.cc:2299
elf_symbol_sptr update_main_symbol(const std::string &)
Update the main symbol for a group of aliased symbols.
Definition abg-ir.cc:2496
void set_size(size_t)
Setter of the size of the symbol.
Definition abg-ir.cc:2197
const string & get_name() const
Getter for the name of the elf_symbol.
Definition abg-ir.cc:2159
binding get_binding() const
Getter for the binding of the current instance of elf_symbol.
Definition abg-ir.cc:2204
static bool get_name_and_version_from_id(const string &id, string &name, string &ver)
Given the ID of a symbol, get the name and the version of said symbol.
Definition abg-ir.cc:2752
bool is_function() const
Test if the current instance of elf_symbol is a function symbol or not.
Definition abg-ir.cc:2290
type
The type of a symbol.
Definition abg-ir.h:965
void set_version(const version &v)
Setter for the version of the current instance of elf_symbol.
Definition abg-ir.cc:2225
const abg_compat::optional< uint32_t > & get_crc() const
Getter of the 'crc' property.
Definition abg-ir.cc:2328
void set_visibility(visibility v)
Setter of the visibility of the current instance of elf_symbol.
Definition abg-ir.cc:2236
bool does_alias(const elf_symbol &) const
Test if the current symbol aliases another one.
Definition abg-ir.cc:2811
bool is_main_symbol() const
Tests whether this symbol is the main symbol.
Definition abg-ir.cc:2411
void set_crc(const abg_compat::optional< uint32_t > &crc)
Setter of the 'crc' property.
Definition abg-ir.cc:2335
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
Definition abg-ir.cc:2063
visibility
The visibility of the symbol.
Definition abg-ir.h:987
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition abg-ir.cc:2218
bool is_common_symbol() const
Return true if the symbol is a common one.
Definition abg-ir.cc:2529
void set_index(size_t)
Setter for the index.
Definition abg-ir.cc:2152
visibility get_visibility() const
Getter of the visibility of the current instance of elf_symbol.
Definition abg-ir.cc:2244
bool has_other_common_instances() const
Return true if this common common symbol has other common instances.
Definition abg-ir.cc:2545
size_t get_index() const
Getter for the index.
Definition abg-ir.cc:2145
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
Definition abg-ir.cc:2616
elf_symbol_sptr get_alias_from_name(const string &name) const
From the aliases of the current symbol, lookup one with a given name.
Definition abg-ir.cc:2643
const environment & get_environment() const
Getter of the environment used by the current instance of elf_symbol.
Definition abg-ir.cc:2138
void set_type(type t)
Setter for the type of the current instance of elf_symbol.
Definition abg-ir.cc:2183
bool is_public() const
Test if the current instance of elf_symbol is public or not.
Definition abg-ir.cc:2274
bool is_in_ksymtab() const
Getter of the 'is-in-ksymtab' property.
Definition abg-ir.cc:2313
size_t get_size() const
Getter of the size of the symbol.
Definition abg-ir.cc:2190
bool is_defined() const
Test if the current instance of elf_symbol is defined or not.
Definition abg-ir.cc:2252
void set_namespace(const abg_compat::optional< std::string > &ns)
Setter of the 'namespace' property.
Definition abg-ir.cc:2349
elf_symbol_sptr get_next_alias() const
Get the next alias of the current symbol.
Definition abg-ir.cc:2418
bool operator==(const elf_symbol &) const
Test if two main symbols are textually equal, or, if they have aliases that are textually equal.
Definition abg-ir.cc:2797
The abstraction of an enumerator.
Definition abg-ir.h:2881
enumerator()
Default constructor of the enum_type_decl::enumerator type.
Definition abg-ir.cc:20919
bool operator!=(const enumerator &other) const
Inequality operator.
Definition abg-ir.cc:20979
void set_name(const string &n)
Setter for the name of enum_type_decl::enumerator.
Definition abg-ir.cc:21021
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition abg-ir.cc:21043
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition abg-ir.cc:20988
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition abg-ir.cc:21050
void set_value(int64_t v)
Setter for the value of enum_type_decl::enumerator.
Definition abg-ir.cc:21036
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:21005
int64_t get_value() const
Getter for the value of enum_type_decl::enumerator.
Definition abg-ir.cc:21029
bool operator==(const enumerator &other) const
Equality operator.
Definition abg-ir.cc:20966
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::enumerator type.
Definition abg-ir.cc:20950
Abstracts a declaration for an enum type.
Definition abg-ir.h:2785
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition abg-ir.h:2801
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:20309
virtual ~enum_type_decl()
Destructor for the enum type declaration.
Definition abg-ir.cc:20470
const enumerators & get_enumerators() const
Definition abg-ir.cc:20322
bool find_enumerator_by_value(int64_t value, enum_type_decl::enumerator &result)
Find an enumerator by its value.
Definition abg-ir.cc:20368
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
Definition abg-ir.cc:20334
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:20448
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition abg-ir.cc:20317
bool find_enumerator_by_name(const string &name, enum_type_decl::enumerator &result)
Find an enumerator by its name.
Definition abg-ir.cc:20392
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:20840
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:20423
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition abg-ir.h:148
bool decl_only_class_equals_definition() const
Getter of the "decl-only-class-equals-definition" flag.
Definition abg-ir.cc:3598
bool is_void_pointer_type(const type_base_sptr &) const
Test if a given type is the same as the void pointer type of the environment.
Definition abg-ir.cc:3665
std::unordered_map< string, std::vector< type_base_sptr > > canonical_types_map_type
A convenience typedef for a map of canonical types. The key is the pretty representation string of a ...
Definition abg-ir.h:158
bool user_set_analyze_exported_interfaces_only() const
Getter for a property that says if the user actually did set the analyze_exported_interfaces_only() p...
Definition abg-ir.cc:3745
const vector< type_base_sptr > * get_canonical_types(const char *name) const
Get the vector of canonical types which have a given "string representation".
Definition abg-ir.cc:3882
const type_base_sptr & get_void_type() const
Get the unique type_decl that represents a "void" type for the current environment....
Definition abg-ir.cc:3475
bool is_variadic_parameter_type(const type_base *) const
Test if a type is a variadic parameter type as defined in the current environment.
Definition abg-ir.cc:3697
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
Definition abg-ir.cc:3526
const type_base_sptr & get_void_pointer_type() const
Getter of the "pointer-to-void" IR node that is shared across the ABI corpus. This node must be the o...
Definition abg-ir.cc:3494
const config & get_config() const
Getter of the general configuration object.
Definition abg-ir.cc:3735
environment()
Default constructor of the environment type.
Definition abg-ir.cc:3376
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition abg-ir.cc:3538
type_base * get_canonical_type(const char *name, unsigned index)
Get a given canonical type which has a given "string representation".
Definition abg-ir.cc:3905
const type_base_sptr & get_variadic_parameter_type() const
Get a type_decl instance that represents a the type of a variadic function parameter....
Definition abg-ir.cc:3513
bool is_void_type(const type_base_sptr &) const
Test if a given type is a void type as defined in the current environment.
Definition abg-ir.cc:3634
virtual ~environment()
Destructor for the environment type.
Definition abg-ir.cc:3381
bool canonicalization_started() const
Getter of a flag saying if the canonicalization process has started or not.
Definition abg-ir.cc:3565
interned_string intern(const string &) const
Do intern a string.
Definition abg-ir.cc:3728
bool analyze_exported_interfaces_only() const
Getter for the property that controls if we are to restrict the analysis to the types that are only r...
Definition abg-ir.cc:3771
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Definition abg-ir.cc:3389
Abstraction of a function parameter.
Definition abg-ir.h:3335
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
Definition abg-ir.cc:23725
interned_string get_type_name() const
Definition abg-ir.cc:23524
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition abg-ir.cc:23562
const string get_type_pretty_representation() const
Definition abg-ir.cc:23543
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition abg-ir.cc:23701
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:23745
Abstraction for a function declaration.
Definition abg-ir.h:3165
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition abg-ir.h:3187
string get_pretty_representation_of_declarator(bool internal=false) const
Compute and return the pretty representation for the part of the function declaration that starts at ...
Definition abg-ir.cc:22925
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition abg-ir.cc:22996
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:23386
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition abg-ir.cc:23076
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition abg-ir.cc:23301
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition abg-ir.cc:22962
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition abg-ir.cc:22981
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:22788
const type_base_sptr get_return_type() const
Definition abg-ir.cc:23057
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition abg-ir.cc:23089
const std::vector< parameter_sptr > & get_parameters() const
Definition abg-ir.cc:23062
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition abg-ir.cc:23069
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition abg-ir.cc:23018
virtual ~function_decl()
Destructor of the function_decl type.
Definition abg-ir.cc:23402
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:23034
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition abg-ir.cc:23287
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition abg-ir.h:3190
bool is_declared_inline() const
Test if the function was declared inline.
Definition abg-ir.cc:23041
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:22857
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:23317
Abstract a function template declaration.
Definition abg-ir.h:3752
binding get_binding() const
Get the binding of the function template.
Definition abg-ir.cc:28129
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
Definition abg-ir.cc:28111
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition abg-ir.cc:28122
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:28189
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition abg-ir.cc:28138
Abstraction of a function type.
Definition abg-ir.h:3420
shared_ptr< function_decl::parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition abg-ir.h:3430
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:22030
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:22449
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition abg-ir.cc:22137
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition abg-ir.cc:22346
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:21937
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition abg-ir.cc:22408
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:22122
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition abg-ir.cc:22099
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition abg-ir.cc:22366
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:22078
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition abg-ir.cc:22041
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition abg-ir.cc:22049
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition abg-ir.cc:22324
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition abg-ir.cc:22058
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition abg-ir.h:3432
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Return a copy of the pretty representation of the current function_type.
Definition abg-ir.cc:22432
This abstracts the global scope of a given translation unit.
Definition abg-ir.h:1982
The base class for the visitor type hierarchy used for traversing a translation unit.
Definition abg-ir.h:4811
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:30195
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition abg-ir.cc:30244
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition abg-ir.cc:30234
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition abg-ir.cc:30174
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition abg-ir.cc:30205
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:4497
bool is_constructor() const
Getter for the 'is-constructor' property.
Definition abg-ir.h:4575
bool is_const() const
Getter for the 'is-const' property.
Definition abg-ir.h:4610
size_t vtable_offset() const
Getter for the vtable offset property.
Definition abg-ir.h:4555
bool is_destructor() const
Getter for the 'is-destructor' property.
Definition abg-ir.h:4592
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition abg-ir.h:3839
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition abg-ir.h:3859
bool get_is_static() const
Definition abg-ir.h:3871
Abstracts a member class template template.
Definition abg-ir.h:4702
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
Definition abg-ir.cc:26760
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26845
Abstract a member function template.
Definition abg-ir.h:4647
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26739
Abstraction of the declaration of a method.
Definition abg-ir.h:3887
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
Definition abg-ir.cc:6545
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
Definition abg-ir.cc:25711
const method_type_sptr get_type() const
Definition abg-ir.cc:25738
Abstracts the type of a class member function.
Definition abg-ir.h:3506
void set_class_type(const class_or_union_sptr &t)
Sets the class type of the current instance of method_type.
Definition abg-ir.cc:22650
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:22631
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition abg-ir.cc:22682
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
Definition abg-ir.cc:22697
virtual ~method_type()
The destructor of method_type.
Definition abg-ir.cc:22730
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:22674
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition abg-ir.cc:22641
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition abg-ir.cc:22689
The abstraction of a namespace declaration.
Definition abg-ir.h:2207
bool is_empty_or_has_empty_sub_namespaces() const
Test if the current namespace_decl is empty or contains empty namespaces itself.
Definition abg-ir.cc:17458
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17489
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition abg-ir.cc:17392
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition abg-ir.cc:17444
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:17430
Abstracts non type template parameters.
Definition abg-ir.h:3662
const type_base_sptr get_type() const
Getter for the type of the template parameter.
Definition abg-ir.cc:27827
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:27832
The abstraction of a pointer type.
Definition abg-ir.h:2350
void set_pointed_to_type(const type_base_sptr &)
Set the pointed-to type of the pointer.
Definition abg-ir.cc:18151
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:18277
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18141
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:18068
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:18371
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition abg-ir.cc:18213
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition abg-ir.cc:18257
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition abg-ir.cc:18264
The abstraction of a pointer-to-member type.
Definition abg-ir.h:2485
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Get the qualified name for the current ptr_to_mbr_type.
Definition abg-ir.cc:19041
virtual const interned_string & get_name() const
Getter of the name of the current ptr-to-mbr-type.
Definition abg-ir.cc:18951
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18964
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:18984
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
Definition abg-ir.cc:19025
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:19092
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
Definition abg-ir.cc:18975
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
Definition abg-ir.cc:19117
The abstraction of a qualified type.
Definition abg-ir.h:2236
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation for the virtual qualified name builder for qualified_type_def.
Definition abg-ir.cc:17794
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition abg-ir.cc:17919
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition abg-ir.cc:17658
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:17646
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:17907
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition abg-ir.h:2255
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:17584
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition abg-ir.cc:17898
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17867
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition abg-ir.cc:17893
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition abg-ir.cc:17912
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition abg-ir.cc:17738
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition abg-ir.cc:17561
The internal representation of an integral type.
Definition abg-ir-priv.h:49
void set_modifiers(modifiers_type)
Setter of the modifiers bitmap of the real_type.
Definition abg-ir.cc:16834
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
Definition abg-ir.cc:16857
base_type get_base_type() const
Getter of the base type of the real_type.
Definition abg-ir.cc:16820
bool operator==(const real_type &) const
Equality operator for the real_type.
Definition abg-ir.cc:16844
real_type()
Default constructor of the real_type.
Definition abg-ir.cc:16790
modifiers_type
The modifiers of the base types above. Several modifiers can be combined for a given base type....
Definition abg-ir-priv.h:89
@ LONG_LONG_MODIFIER
The "long long" modifier.
@ LONG_MODIFIER
The "long" modifier.
Definition abg-ir-priv.h:98
@ SIGNED_MODIFIER
The "signed" modifier.
Definition abg-ir-priv.h:92
@ UNSIGNED_MODIFIER
The "unsigned" modier.
Definition abg-ir-priv.h:94
@ SHORT_MODIFIER
The "short" modifier.
Definition abg-ir-priv.h:96
base_type
The possible base types of integral types. We might have forgotten many of these, so do not hesitate ...
Definition abg-ir-priv.h:57
@ WCHAR_T_BASE_TYPE
The "wchar_t" base type.
Definition abg-ir-priv.h:73
@ CHAR32_T_BASE_TYPE
The "char32_t" base type.
Definition abg-ir-priv.h:71
@ FLOAT_BASE_TYPE
The "float" base type.
Definition abg-ir-priv.h:67
@ BOOL_BASE_TYPE
The "bool" base type in C++ or "_Bool" in C11.
Definition abg-ir-priv.h:63
@ CHAR_BASE_TYPE
The "char" base type.
Definition abg-ir-priv.h:61
@ CHAR16_T_BASE_TYPE
The "char16_t base type.
Definition abg-ir-priv.h:69
@ INT_BASE_TYPE
The "int" base type.
Definition abg-ir-priv.h:59
@ ARRAY_SIZE_BASE_TYPE
The aray size type used by Clang.
Definition abg-ir-priv.h:79
@ DOUBLE_BASE_TYPE
The "double" base type.
Definition abg-ir-priv.h:65
modifiers_type get_modifiers() const
Getter of the modifiers bitmap of the real_type.
Definition abg-ir.cc:16827
Abstracts a reference type.
Definition abg-ir.h:2416
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Build and return the qualified name of the current instance of the reference_type_def.
Definition abg-ir.cc:18700
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18563
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:18465
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:18822
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:18573
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition abg-ir.cc:18642
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:18801
A declaration that introduces a scope.
Definition abg-ir.h:1853
virtual size_t get_num_anonymous_member_classes() const
Getter for the number of anonymous classes contained in this scope.
Definition abg-ir.cc:7928
void remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
Definition abg-ir.cc:8137
void insert_member_type(type_base_sptr t, declarations::iterator before)
Insert a member type.
Definition abg-ir.cc:8095
void add_member_type(type_base_sptr t)
Add a member type to the current instance of class_or_union.
Definition abg-ir.cc:8112
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
Definition abg-ir.cc:7946
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
Definition abg-ir.cc:7981
std::vector< scope_decl_sptr > scopes
Convenience typedef for a vector of scope_decl_sptr.
Definition abg-ir.h:1864
bool is_empty() const
Test if the current scope is empty.
Definition abg-ir.cc:7995
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:8427
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
Definition abg-ir.cc:8070
decl_base_sptr insert_member_decl(decl_base_sptr member, declarations::iterator before)
Insert a member decl to this scope, right before an element pointed to by a given iterator....
Definition abg-ir.cc:8205
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
Definition abg-ir.h:1860
const type_base_sptrs_type & get_sorted_canonical_types() const
Return a vector of sorted canonical types of the current scope.
Definition abg-ir.cc:7864
bool find_iterator_for_member(const decl_base *, declarations::iterator &)
Find a member of the current scope and return an iterator on it.
Definition abg-ir.cc:8379
virtual void remove_member_decl(decl_base_sptr member)
Remove a declaration from the current scope.
Definition abg-ir.cc:8230
virtual decl_base_sptr add_member_decl(const decl_base_sptr &member)
Add a member decl to this scope. Note that user code should not use this, but rather use add_decl_to_...
Definition abg-ir.cc:8041
type_base_sptr find_member_type(const string &name) const
Find a member type of a given name, inside the current scope_decl.
Definition abg-ir.cc:8081
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition abg-ir.cc:7888
const canonical_type_sptr_set_type & get_canonical_types() const
@eturn the set of canonical types of the the current scope.
Definition abg-ir.cc:7852
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
Definition abg-ir.cc:8156
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition abg-ir.cc:8457
virtual bool operator==(const decl_base &) const
Return true iff both scopes have the same names and have the same member decls.
Definition abg-ir.cc:8333
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
Definition abg-ir.cc:7906
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
Definition abg-ir.cc:7964
A type that introduces a scope.
Definition abg-ir.h:2184
virtual bool traverse(ir_node_visitor &)
Traverses an instance of scope_type_decl, visiting all the sub-types and decls that it might contain.
Definition abg-ir.cc:17351
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition abg-ir.cc:17313
The base class of templates.
Definition abg-ir.h:3567
const std::list< template_parameter_sptr > & get_template_parameters() const
Get the list of template parameters of the current instance of template_decl.
Definition abg-ir.cc:27502
virtual ~template_decl()
Destructor.
Definition abg-ir.cc:27527
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:27494
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition abg-ir.cc:27536
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition abg-ir.h:3599
virtual ~template_parameter()
Destructor.
Definition abg-ir.cc:27656
bool operator!=(const template_parameter &) const
Inequality operator.
Definition abg-ir.cc:27652
Abstracts a template template parameter.
Definition abg-ir.h:3695
virtual bool operator==(const type_base &) const
Equality operator.
Definition abg-ir.cc:27905
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
Definition abg-ir.h:695
void set_address_size(char)
Setter of the address size in this translation unit.
Definition abg-ir.cc:1426
const std::string & get_absolute_path() const
Get the concatenation of the build directory and the relative path of the translation unit.
Definition abg-ir.cc:1341
void set_is_constructed(bool)
Setter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
Definition abg-ir.cc:1458
bool operator==(const translation_unit &) const
Compare the current translation unit against another one.
Definition abg-ir.cc:1468
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
Definition abg-ir.cc:1384
char get_address_size() const
Getter of the address size in this translation unit.
Definition abg-ir.cc:1419
const std::string & get_compilation_dir_path() const
Get the path of the directory that was 'current' when the translation unit was compiled.
Definition abg-ir.cc:1322
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
Definition abg-ir.cc:1368
void set_language(language l)
Setter of the language of the source code of the translation unit.
Definition abg-ir.cc:1285
void bind_function_type_life_time(function_type_sptr) const
Ensure that the life time of a function type is bound to the life time of the current translation uni...
Definition abg-ir.cc:1494
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
Definition abg-ir.cc:1221
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
Definition abg-ir.cc:1408
bool is_constructed() const
Getter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
Definition abg-ir.cc:1442
const std::string & get_path() const
Get the path of the current translation unit.
Definition abg-ir.cc:1298
void set_compilation_dir_path(const std::string &)
Set the path of the directory that was 'current' when the translation unit was compiled.
Definition abg-ir.cc:1333
location_manager & get_loc_mgr()
Getter of the location manager for the current translation unit.
Definition abg-ir.cc:1392
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
Definition abg-ir.cc:1309
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse virtual function.
Definition abg-ir.cc:1528
language
The language of the translation unit.
Definition abg-ir.h:708
bool operator!=(const translation_unit &) const
Inequality operator.
Definition abg-ir.cc:1483
const vector< function_type_sptr > & get_live_fn_types() const
Get the vector of function types that are used in the current translation unit.
Definition abg-ir.cc:1264
const environment & get_environment() const
Getter of the environment of the current translation_unit.
Definition abg-ir.cc:1271
const type_maps & get_types() const
Getter of the types of the current translation_unit.
Definition abg-ir.cc:1248
language get_language() const
Getter of the language of the source code of the translation unit.
Definition abg-ir.cc:1278
bool visiting() const
This should returns false before and after the node has been visiting. During the visiting of the nod...
An abstraction helper for type declarations.
Definition abg-ir.h:2003
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
Definition abg-ir.cc:16420
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition abg-ir.cc:16396
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition abg-ir.cc:16499
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:16366
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:16525
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:16091
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition abg-ir.cc:16492
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition abg-ir.cc:16485
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition abg-ir.cc:16475
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition abg-ir.cc:16513
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition abg-ir.cc:16506
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition abg-ir.cc:16380
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition abg-ir.h:3730
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition abg-ir.cc:28011
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition abg-ir.cc:28018
A basic type declaration that introduces no scope.
Definition abg-ir.h:2118
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation for the virtual qualified name builder for type_decl.
Definition abg-ir.cc:17145
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:16985
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17224
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition abg-ir.cc:17083
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition abg-ir.cc:17039
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:17204
This is a type that aggregates maps of all the kinds of types that are supported by libabigail.
Definition abg-ir.h:602
istring_type_base_wptrs_map_type & typedef_types()
Getter for the map that associates the name of a typedef to the vector of instances of typedef_decl_s...
Definition abg-ir.cc:651
istring_type_base_wptrs_map_type & function_types()
Getter for the map that associates the name of a function type to the vector of instances of function...
Definition abg-ir.cc:754
istring_type_base_wptrs_map_type & reference_types()
Getter for the map that associates the name of a reference type to the vector of instances of referen...
Definition abg-ir.cc:705
const istring_type_base_wptrs_map_type & class_types() const
Getter for the map that associates the name of a class type to the vector of instances of class_decl_...
Definition abg-ir.cc:609
istring_type_base_wptrs_map_type & union_types()
Getter for the map that associates the name of a union type to the vector of instances of union_decl_...
Definition abg-ir.cc:623
istring_type_base_wptrs_map_type & array_types()
Getter for the map that associates the name of an array type to the vector of instances of array_type...
Definition abg-ir.cc:719
istring_type_base_wptrs_map_type & enum_types()
Getter for the map that associates the name of an enum type to the vector of instances of enum_type_d...
Definition abg-ir.cc:637
bool empty() const
Test if the type_maps is empty.
Definition abg-ir.cc:577
istring_type_base_wptrs_map_type & qualified_types()
Getter for the map that associates the name of a qualified type to the vector of instances of qualifi...
Definition abg-ir.cc:664
istring_type_base_wptrs_map_type & ptr_to_mbr_types()
Getter for the map that associates the name of a pointer-to-member type to the vector of instances of...
Definition abg-ir.cc:684
const vector< type_base_wptr > & get_types_sorted_by_name() const
Getter of all types types sorted by their pretty representation.
Definition abg-ir.cc:1157
istring_type_base_wptrs_map_type & pointer_types()
Getter for the map that associates the name of a pointer type to the vector of instances of pointer_t...
Definition abg-ir.cc:677
const istring_type_base_wptrs_map_type & basic_types() const
Getter for the map that associates the name of a basic type to the vector instances of type_decl_sptr...
Definition abg-ir.cc:595
const istring_type_base_wptrs_map_type & subrange_types() const
Getter for the map that associates the name of a subrange type to the vector of instances of array_ty...
Definition abg-ir.cc:740
The base class of both types and declarations.
Definition abg-ir.h:1406
void set_translation_unit(translation_unit *)
Set the translation_unit this ABI artifact belongs to.
Definition abg-ir.cc:4285
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
Definition abg-ir.cc:4098
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
Definition abg-ir.cc:4087
location & get_artificial_location() const
Getter of the artificial location of the artifact.
Definition abg-ir.cc:4245
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
Definition abg-ir.cc:4252
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Definition abg-ir.cc:4277
friend hash_t set_or_get_cached_hash_value(const T &type_or_decl)
Set the hash value of an IR node and return it.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:4198
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
Definition abg-ir.cc:4121
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition abg-ir.cc:4110
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
Definition abg-ir.cc:4310
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
Definition abg-ir.cc:4141
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition abg-ir.cc:11181
friend hash_t peek_hash_value(const type_or_decl_base &)
Get the hash value associated to an IR node.
Definition abg-ir.cc:28614
const void * type_or_decl_base_pointer() const
Getter of the pointer to either the type_base sub-object of the current instance if it's a type,...
Definition abg-ir.cc:4176
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10754
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
Definition abg-ir.cc:4227
type_or_decl_kind
This is a bitmap type which instance is meant to contain the runtime type of a given ABI artifact....
Definition abg-ir.h:1418
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition abg-ir.cc:4209
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
Definition abg-ir.cc:10827
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Definition abg-ir.cc:4302
Abstracts a type template parameter.
Definition abg-ir.h:3628
virtual bool operator==(const type_base &) const
Equality operator.
Definition abg-ir.cc:27698
The abstraction of a typedef declaration.
Definition abg-ir.h:2935
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation of the virtual "get_qualified_name" method.
Definition abg-ir.cc:21305
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition abg-ir.cc:21290
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition abg-ir.cc:21145
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:21132
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:21337
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition abg-ir.cc:21283
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:21225
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition abg-ir.cc:21162
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:21266
Abstracts a union type declaration.
Definition abg-ir.h:4422
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:27179
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:27296
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition abg-ir.cc:27236
virtual ~union_decl()
Destructor of the union_decl type.
Definition abg-ir.cc:27369
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:27203
Abstracts a variable declaration.
Definition abg-ir.h:3068
binding get_binding() const
Getter of the binding of the variable.
Definition abg-ir.cc:21451
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition abg-ir.cc:21433
void set_binding(binding b)
Setter of the binding of the variable.
Definition abg-ir.cc:21458
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
Definition abg-ir.cc:6206
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
Definition abg-ir.cc:21496
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:21747
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition abg-ir.cc:21444
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition abg-ir.cc:6351
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition abg-ir.cc:21426
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:21909
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:21886
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition abg-ir.cc:21473
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:21489
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition abg-ir.cc:21682
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:21777
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:21701
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:16582
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:20482
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:12965
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition abg-ir.cc:28641
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Definition abg-ir.cc:6461
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
Definition abg-ir.cc:7271
hash_t peek_hash_value(const type_or_decl_base &artefact)
Get the hash value associated to an IR node.
Definition abg-ir.cc:28614
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:12452
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:28592
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:12316
var_decl_sptr get_last_data_member(const class_or_union &klass)
Get the last data member of a class type.
Definition abg-ir.cc:5788
bool is_anonymous_or_typedef_named(const decl_base &d)
Test if a given decl is anonymous or has a naming typedef.
Definition abg-ir.cc:6161
bool is_template_parm_composition_type(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter composition type.
Definition abg-ir.cc:12103
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:16258
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
Definition abg-ir.cc:5582
pointer_type_def_sptr is_pointer_to_npaf_type(const type_base_sptr &t)
Test if we are looking at a pointer to a neither-a-pointer-to-an-array-nor-a-function type.
Definition abg-ir.cc:11561
bool debug_equals(const type_or_decl_base *l, const type_or_decl_base *r)
Test if two ABI artifacts are equal.
Definition abg-ir.cc:10149
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition abg-fwd.h:269
access_specifier
Access specifier for class members.
Definition abg-ir.h:917
size_t get_canonical_type_index(const type_base &t)
Getter of the canonical type index of a given type.
Definition abg-ir.cc:345
const type_base_wptrs_type * lookup_enum_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the enum type*s* that have a given qualified name.
Definition abg-ir.cc:14033
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition abg-ir.cc:23368
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:11543
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:15832
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:14705
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:14195
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition abg-ir.cc:6585
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
Definition abg-fwd.h:142
scope_decl * get_type_scope(type_base *t)
Get the scope of a given type.
Definition abg-ir.cc:8807
void fixup_virtual_member_function(method_decl_sptr method)
When a virtual member function has seen its virtualness set by set_member_function_is_virtual(),...
Definition abg-ir.cc:25967
void pop_composite_type_comparison_operands(const type_base &left, const type_base &right)
Pop a pair of operands from the stack of operands to the current type comparison.
Definition abg-ir.cc:332
bool equals_modulo_cv_qualifier(const array_type_def *l, const array_type_def *r)
Test if two array types are equals modulo CV qualifiers.
Definition abg-ir.cc:19939
const scope_decl * is_scope_decl(const decl_base *d)
Test if a declaration is a scope_decl.
Definition abg-ir.cc:5452
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
Definition abg-ir.cc:7622
const type_base * is_void_pointer_type(const type_base *t)
Test if a type is a pointer to void type.
Definition abg-ir.cc:11794
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition abg-ir.cc:10814
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition abg-ir.cc:5879
bool is_template_parameter(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter.
Definition abg-ir.cc:10688
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
Definition abg-ir.cc:1540
weak_ptr< type_base > type_base_wptr
Convenience typedef for a weak pointer on a type_base.
Definition abg-fwd.h:128
type_base_sptr peel_reference_type(const type_base_sptr &type)
Return the leaf pointed-to type node of a reference_type_def node.
Definition abg-ir.cc:7180
class_decl::base_spec * is_class_base_spec(const type_or_decl_base *tod)
Test if an ABI artifact is a class base specifier.
Definition abg-ir.cc:26654
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
Definition abg-ir.cc:5406
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
Definition abg-ir.cc:12222
T * maybe_get_canonical_type(T *t)
Get the canonical type of a given type T* as a T*.
Definition abg-ir.cc:894
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition abg-ir.h:926
type_base_sptr lookup_type_from_translation_unit(const string &type_name, const string &tu_path, const corpus &corp)
Lookup a type from a given translation unit present in a give corpus.
Definition abg-ir.cc:13592
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
Definition abg-ir.cc:28712
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:16775
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
Definition abg-ir.cc:8482
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
Definition abg-ir.cc:10214
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
Definition abg-ir.cc:7555
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
Definition abg-ir.h:1361
@ LOCAL_TYPE_CHANGE_KIND
This means that a given IR artifact has a local type change.
Definition abg-ir.h:1365
@ SUBTYPE_CHANGE_KIND
This means that a given IR artifact has changes in some of its sub-types, with respect to the other a...
Definition abg-ir.h:1381
@ LOCAL_NON_TYPE_CHANGE_KIND
This means that a given IR artifact has a local non-type change. That is a change that is carried by ...
Definition abg-ir.h:1370
var_decl_sptr find_last_data_member_matching_regexp(const class_or_union &t, const regex::regex_t_sptr &regex)
Find the last data member of a class or union which name matches a regular expression.
Definition abg-ir.cc:29218
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:11718
const var_decl_sptr get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
Get the first non-anonymous data member of a given anonymous data member.
Definition abg-ir.cc:5725
class_decl_sptr lookup_class_type_through_scopes(const list< string > &fqn, const translation_unit &tu)
Lookup a class type from a translation unit by walking its scopes in sequence and by looking into the...
Definition abg-ir.cc:13327
string get_enum_flat_representation(const enum_type_decl &enum_type, const string &indent, bool one_line, bool qualified_names)
Get the flat representation of an instance of enum_type_decl type.
Definition abg-ir.cc:9691
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
Definition abg-ir.cc:5486
bool operator==(const translation_unit_sptr &l, const translation_unit_sptr &r)
A deep comparison operator for pointers to translation units.
Definition abg-ir.cc:1849
weak_ptr< class_decl > class_decl_wptr
Convenience typedef for a weak pointer on a class_decl.
Definition abg-fwd.h:202
string components_to_type_name(const list< string > &comps)
Turn a set of qualified name components (that name a type) into a qualified name string.
Definition abg-ir.cc:12342
void unmark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being not compared anymore.
Definition abg-ir.cc:1085
vector< type_base_sptr > type_base_sptrs_type
Helper typedef for a vector of shared pointer to a type_base.
Definition abg-ir.h:127
void debug_comp_stack(const environment &env)
Emit a trace of the two comparison operands stack on the standard error stream.
Definition abg-ir.cc:10199
bool collect_non_anonymous_data_members(const class_or_union *cou, string_decl_base_sptr_map &dms)
Collect all the non-anonymous data members of a class or union type.
Definition abg-ir.cc:5822
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition abg-ir.cc:11172
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:15278
void set_member_function_virtuality(function_decl &fn, bool is_virtual, ssize_t voffset)
Set the virtual-ness of a member fcuntion.
Definition abg-ir.cc:6722
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition abg-fwd.h:244
function_type_sptr lookup_or_synthesize_fn_type(const function_type_sptr &fn_t, const corpus &corpus)
Look into an ABI corpus for a function type.
Definition abg-ir.cc:13617
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:11356
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
Definition abg-ir.cc:9293
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
Definition abg-ir.cc:10865
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:14220
type_base_sptr peel_const_qualified_type(const qualified_type_def_sptr &q)
If a qualified type is const, then return its underlying type.
Definition abg-ir.cc:7340
const class_or_union_sptr data_member_has_anonymous_type(const var_decl &d)
Test if a data member has annonymous type or not.
Definition abg-ir.cc:6065
type_decl * is_integral_type(const type_or_decl_base *t)
Test if a type is an integral type.
Definition abg-ir.cc:10974
bool anonymous_data_member_exists_in_class(const var_decl &anon_dm, const class_or_union &clazz)
Test if a given anonymous data member exists in a class or union.
Definition abg-ir.cc:6121
class_decl_sptr lookup_class_type_per_location(const interned_string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
Definition abg-ir.cc:13896
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition abg-ir.cc:6489
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
Definition abg-ir.cc:7229
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
Definition abg-ir.cc:12783
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:28856
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:11403
var_decl_sptr get_data_member(class_or_union *clazz, const char *member_name)
Get a given data member, referred to by its name, of a class type.
Definition abg-ir.cc:10031
type_base * look_through_decl_only_type(type_base *t)
If a type is is decl-only, then get its definition. Otherwise, just return the initial type.
Definition abg-ir.cc:12034
const var_decl_sptr get_next_data_member(const class_or_union *klass, const var_decl_sptr &data_member)
In the context of a given class or union, this function returns the data member that is located after...
Definition abg-ir.cc:5749
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition abg-fwd.h:193
type_base_sptr peel_typedef_pointer_or_reference_type(const type_base_sptr type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def,...
Definition abg-ir.cc:7416
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
Definition abg-ir.cc:6545
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
Definition abg-ir.cc:6922
bool is_comparison_cycle_detected(T &l, T &r)
Detect if a recursive comparison cycle is detected while structurally comparing two types (a....
Definition abg-ir.cc:989
bool string_to_elf_symbol_type(const string &s, elf_symbol::type &t)
Convert a string representing a symbol type into an elf_symbol::type.
Definition abg-ir.cc:3071
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
Definition abg-ir.cc:12085
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:10916
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10794
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:11974
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:11865
string get_name(const type_or_decl_base *tod, bool qualified)
Build and return a copy of the name of an ABI artifact that is either a type or a decl.
Definition abg-ir.cc:8693
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition abg-ir.cc:5551
const class_decl * is_compatible_with_class_type(const type_base *t)
Test if a type is a class. This function looks through typedefs.
Definition abg-ir.cc:11125
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition abg-ir.cc:11018
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
Definition abg-ir.h:105
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
Definition abg-ir.cc:6323
enum_type_decl_sptr lookup_enum_type_per_location(const interned_string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
Definition abg-ir.cc:14063
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
Definition abg-ir.cc:9840
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition abg-fwd.h:210
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
Definition abg-fwd.h:167
function_type_sptr synthesize_function_type_from_translation_unit(const function_type &fn_type, translation_unit &tu)
In a translation unit, lookup the sub-types that make up a given function type and if the sub-types a...
Definition abg-ir.cc:15361
std::ostream & operator<<(std::ostream &o, elf_symbol::type t)
Serialize an instance of symbol_type and stream it to a given output stream.
Definition abg-ir.cc:2943
type_base_sptr peel_pointer_type(const type_base_sptr &type)
Return the leaf pointed-to type node of a pointer_type_def node.
Definition abg-ir.cc:7124
bool var_equals_modulo_types(const var_decl &l, const var_decl &r, change_kind *k)
Compares two instances of var_decl without taking their type into account.
Definition abg-ir.cc:21557
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:12492
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:13567
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:12163
void sort_types(const canonical_type_sptr_set_type &types, vector< type_base_sptr > &result)
Sort types in a hopefully stable manner.
Definition abg-ir.cc:3455
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
Definition abg-ir.cc:11621
type_base * peel_pointer_or_reference_type(const type_base *type, bool peel_qual_type)
Return the leaf underlying or pointed-to type node of a, pointer_type_def, reference_type_def or qual...
Definition abg-ir.cc:7518
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
Definition abg-ir.cc:11658
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
bool elf_symbol_is_function(elf_symbol::type t)
Test if the type of an ELF symbol denotes a function symbol.
Definition abg-ir.cc:3152
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
Definition abg-ir.cc:1808
bool lookup_decl_only_class_types(const interned_string &qualified_name, const corpus &corp, type_base_wptrs_type &result)
Look into a given corpus to find the class type*s* that have a given qualified name and that are decl...
Definition abg-ir.cc:13820
bool member_function_has_vtable_offset(const function_decl &f)
Test if a virtual member function has a vtable offset set.
Definition abg-ir.cc:6574
decl_base_sptr insert_decl_into_scope(decl_base_sptr decl, scope_decl::declarations::iterator before, scope_decl *scope)
Inserts a declaration into a given scope, before a given IR child node of the scope.
Definition abg-ir.cc:8501
unordered_map< interned_string, bool, hash_interned_string > interned_string_bool_map_type
Convenience typedef for a map of interned_string -> bool.
Definition abg-ir.cc:3372
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
Definition abg-ir.cc:11107
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:28804
bool elf_symbols_alias(const elf_symbol &s1, const elf_symbol &s2)
Test if two symbols alias.
Definition abg-ir.cc:2867
var_decl_sptr find_data_member_from_anonymous_data_member(const var_decl_sptr &anon_dm, const string &name)
Find a data member inside an anonymous data member.
Definition abg-ir.cc:10657
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
Definition abg-ir.cc:8550
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition abg-fwd.h:256
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
Definition abg-fwd.h:239
const location & get_natural_or_artificial_location(const decl_base *decl)
Get the non-artificial (natural) location of a decl.
Definition abg-ir.cc:10059
size_t hash_type_or_decl(const type_or_decl_base *tod)
Hash an ABI artifact that is either a type or a decl.
Definition abg-ir.cc:28505
method_decl_sptr copy_member_function(class_or_union_sptr t, const method_decl_sptr &method)
Copy a method of a class_or_union into a new class_or_union.
Definition abg-ir.cc:24849
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:12245
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
Definition abg-fwd.h:264
bool string_to_elf_symbol_binding(const string &s, elf_symbol::binding &b)
Convert a string representing a an elf symbol binding into an elf_symbol::binding.
Definition abg-ir.cc:3104
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
Definition abg-fwd.h:120
pointer_type_def_sptr lookup_pointer_type(const interned_string &type_name, const translation_unit &tu)
Lookup a pointer type from a translation unit.
Definition abg-ir.cc:12721
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition abg-fwd.h:136
bool is_data_member_of_anonymous_class_or_union(const var_decl &d)
Test if a var_decl is a data member belonging to an anonymous type.
Definition abg-ir.cc:5997
bool integral_type_has_harmless_name_change(const type_base_sptr &f, const type_base_sptr &s)
Test if a diff node carries a change whereby two integral types have different names in a harmless wa...
Definition abg-ir.cc:29783
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:11757
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:30507
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition abg-ir.cc:12251
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:12982
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:28442
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:12675
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:12898
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
Definition abg-ir.cc:1824
function_decl::parameter * is_function_parameter(const type_or_decl_base *tod)
Test whether a declaration is a function_decl.
Definition abg-ir.cc:10731
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
Definition abg-ir.cc:5145
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition abg-ir.cc:6351
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
Definition abg-ir.cc:12529
bool string_to_elf_symbol_visibility(const string &s, elf_symbol::visibility &v)
Convert a string representing a an elf symbol visibility into an elf_symbol::visibility.
Definition abg-ir.cc:3129
const enum_type_decl * is_compatible_with_enum_type(const type_base *t)
Test if a type is an enum. This function looks through typedefs.
Definition abg-ir.cc:11058
weak_ptr< elf_symbol > elf_symbol_wptr
A convenience typedef for a weak pointer to elf_symbol.
Definition abg-ir.h:929
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition abg-ir.cc:6517
interned_string get_name_of_reference_to_type(const type_base &pointed_to_type, bool lvalue_reference, bool qualified, bool internal)
Get the name of the reference to a given type.
Definition abg-ir.cc:9048
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
Definition abg-fwd.h:226
void maybe_update_types_lookup_map(const type_decl_sptr &basic_type)
Update the map that associates the fully qualified name of a basic type with the type itself.
Definition abg-ir.cc:14735
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:20563
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
Definition abg-ir.cc:7308
translation_unit::language string_to_translation_unit_language(const string &l)
Parse a string representing a language into a translation_unit::language enumerator into a string.
Definition abg-ir.cc:1670
type_base_sptr lookup_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a type from a corpus, by its location.
Definition abg-ir.cc:14525
bool get_next_data_member_offset(const class_or_union *klass, const var_decl_sptr &dm, uint64_t &offset)
Get the offset of the non-static data member that comes after a given one.
Definition abg-ir.cc:6236
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
Definition abg-ir.cc:6280
shared_ptr< ir_traversable_base > ir_traversable_base_sptr
Convenience typedef for a shared pointer to ir_traversable_base.
Definition abg-fwd.h:109
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
Definition abg-ir.cc:6375
const function_decl::parameter * get_function_parameter(const decl_base *fun, unsigned parm_index)
Get the function parameter designated by its index.
Definition abg-ir.cc:29150
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition abg-ir.cc:12066
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
Definition abg-ir.cc:1792
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10754
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:28480
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:25800
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:12827
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition abg-ir.cc:5471
string get_class_or_union_flat_representation(const class_or_union &cou, const string &indent, bool one_line, bool internal, bool qualified_names)
Get the flat representation of an instance of class_or_union type.
Definition abg-ir.cc:9515
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition abg-ir.cc:8457
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
Definition abg-ir.cc:29172
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:10901
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition abg-ir.cc:5522
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition abg-fwd.h:175
void set_data_member_offset(var_decl_sptr m, uint64_t o)
Set the offset of a data member into its containing class.
Definition abg-ir.cc:6174
type_base_sptr strip_typedef(const type_base_sptr type)
Recursively returns the the underlying type of a typedef. The return type should not be a typedef of ...
Definition abg-ir.cc:6787
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition abg-ir.cc:6191
unordered_set< uintptr_t > pointer_set
A convenience typedef for an unordered set of pointer values.
Definition abg-ir.h:99
void sort_types_for_hash_computing_and_c14n(IteratorType begin, IteratorType end)
Sort types before hashing (and then canonicalizing) them.
class_or_union * is_at_class_scope(const decl_base_sptr decl)
Tests whether a given decl is at class scope.
Definition abg-ir.cc:10614
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition abg-ir.cc:6648
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
Definition abg-ir.cc:11486
string get_class_or_enum_flat_representation(const type_base &coe, const string &indent, bool one_line, bool internal, bool qualified_name)
Get the flat representation of an instance of enum_type_decl type.
Definition abg-ir.cc:9812
class_or_union * anonymous_data_member_to_class_or_union(const var_decl *d)
Get the class_or_union type of a given anonymous data member.
Definition abg-ir.cc:6037
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
Definition abg-ir.cc:8773
pointer_type_def_sptr is_pointer_to_function_type(const type_base_sptr &t)
Test if a type is a pointer to function type.
Definition abg-ir.cc:11526
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
Definition abg-ir.cc:10510
weak_ptr< decl_base > decl_base_wptr
Convenience typedef for a weak pointer to a decl_base.
Definition abg-fwd.h:181
var_decl_sptr has_fake_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with one element.
Definition abg-ir.cc:11283
interned_string get_function_type_name(const function_type_sptr &fn_type, bool internal)
Get the name of a given function type and return a copy of it.
Definition abg-ir.cc:9125
bool is_function_template_pattern(const shared_ptr< decl_base > decl)
Test whether a decl is the pattern of a function template.
Definition abg-ir.cc:12117
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:11925
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition abg-ir.cc:11452
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition abg-ir.cc:10078
enum_type_decl_sptr lookup_enum_type(const interned_string &type_name, const translation_unit &tu)
Lookup an enum type from a translation unit.
Definition abg-ir.cc:12597
type_base_sptr peel_typedef_type(const type_base_sptr &type)
Return the leaf underlying type node of a typedef_decl node.
Definition abg-ir.cc:7070
const type_base_wptrs_type * lookup_union_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the union type*s* that have a given qualified name.
Definition abg-ir.cc:13851
var_decl_sptr copy_member_variable(class_or_union_sptr t, const var_decl *variable)
Copy a data member of a class_or_union into a new class_or_union.
Definition abg-ir.cc:24917
interned_string get_name_of_qualified_type(const type_base_sptr &underlying_type, qualified_type_def::CV quals, bool qualified, bool internal)
Get the name of a qualified type, given the underlying type and its qualifiers.
Definition abg-ir.cc:9078
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
Definition abg-fwd.h:306
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
Definition abg-ir.cc:12201
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:12847
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
Definition abg-ir.cc:10559
string get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
Get the string representation of a CV qualifier bitmap.
Definition abg-ir.cc:8663
void set_data_member_is_laid_out(var_decl_sptr m, bool l)
Set a flag saying if a data member is laid out.
Definition abg-ir.cc:6337
pointer_type_def_sptr is_pointer_to_ptr_to_mbr_type(const type_base_sptr &t)
Test if we are looking at a pointer to pointer to member type.
Definition abg-ir.cc:11578
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition abg-ir.cc:5620
var_decl_sptr find_first_data_member_matching_regexp(const class_or_union &t, const regex::regex_t_sptr &r)
Find the first data member of a class or union which name matches a regular expression.
Definition abg-ir.cc:29197
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:13800
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition abg-ir.cc:10236
var_decl_sptr has_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with non-finite data member.
Definition abg-ir.cc:11213
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition abg-ir.cc:26900
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:12130
interned_string get_method_type_name(const method_type_sptr fn_type, bool internal)
Get the name of a given method type and return a copy of it.
Definition abg-ir.cc:9215
weak_ptr< template_decl > template_decl_wptr
Convenience typedef for a weak pointer to template_decl.
Definition abg-fwd.h:309
const var_decl * lookup_data_member(const type_base *type, const char *dm_name)
Look for a data member of a given class, struct or union type and return it.
Definition abg-ir.cc:29107
interned_string get_function_id_or_pretty_representation(const function_decl *fn)
Get the ID of a function, or, if the ID can designate several different functions,...
Definition abg-ir.cc:9187
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition abg-fwd.h:161
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
Definition abg-ir.cc:7597
type_decl_sptr lookup_basic_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a type_decl type from a given corpus, by its location.
Definition abg-ir.cc:13688
bool compare_using_locations(const decl_base *f, const decl_base *s)
Compare decls using their locations.
Definition abg-ir.cc:3420
bool classes_have_same_layout(const type_base_sptr &f, const type_base_sptr &s)
Test if two classes have the same layout.
Definition abg-ir.cc:10269
const type_base_sptr lookup_type_through_scopes(const type_base_sptr type, const translation_unit &tu)
Lookup a type from a translation unit by walking the scopes of the translation unit in sequence and l...
Definition abg-ir.cc:13259
type_or_decl_base * debug(const type_or_decl_base *artifact)
Emit a textual representation of an artifact to std error stream for debugging purposes.
Definition abg-ir.cc:10098
unordered_set< type_base_sptr, canonical_type_hash > canonical_type_sptr_set_type
Helper typedef for an unordered set of type_base_sptr which uses pointer value to tell its members ap...
Definition abg-ir.h:121
bool return_comparison_result(T &l, T &r, bool value)
Return the result of the comparison of two (sub) types.
Definition abg-ir.cc:1127
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
Definition abg-fwd.h:284
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
Definition abg-ir.cc:1833
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
Definition abg-ir.cc:15435
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition abg-ir.cc:28677
bool types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
Test if two types are equal modulo a typedef or CV qualifiers.
Definition abg-ir.cc:10404
void mark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being compared.
Definition abg-ir.cc:1050
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
Definition abg-ir.cc:8842
const scope_decl * get_top_most_scope_under(const decl_base *decl, const scope_decl *scope)
Return the a scope S containing a given declaration and that is right under a given scope P.
Definition abg-ir.cc:8594
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
Definition abg-ir.cc:7675
bool operator!=(const translation_unit_sptr &l, const translation_unit_sptr &r)
A deep inequality operator for pointers to translation units.
Definition abg-ir.cc:1868
interned_string get_name_of_pointer_to_type(const type_base &pointed_to_type, bool qualified, bool internal)
Get the name of the pointer to a given type.
Definition abg-ir.cc:9026
bool decl_name_changed(const type_or_decl_base *a1, const type_or_decl_base *a2)
Test if two decls have different names.
Definition abg-ir.cc:29742
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
Definition abg-ir.cc:10679
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:14158
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition abg-ir.cc:10702
bool elf_symbol_is_variable(elf_symbol::type t)
Test if the type of an ELF symbol denotes a function symbol.
Definition abg-ir.cc:3162
bool type_has_sub_type_changes(const type_base_sptr t_v1, const type_base_sptr t_v2)
Tests if the change of a given type effectively comes from just its sub-types. That is,...
Definition abg-ir.cc:28464
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:14643
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:11895
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:11845
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:12635
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:11598
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol.
Definition abg-ir.h:947
union_decl_sptr lookup_union_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
Definition abg-ir.cc:12562
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:11424
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
Definition abg-ir.cc:8739
bool is_ptr_ref_or_qual_type(const type_base *t)
Helper to detect if a type is either a reference, a pointer, or a qualified type.
Definition abg-ir.cc:3403
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
Definition abg-ir.cc:11955
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
Definition abg-fwd.h:294
type_base * peel_qualified_or_typedef_type(const type_base *type)
Return the leaf underlying type of a qualified or typedef type.
Definition abg-ir.cc:7365
type_base_sptr type_or_void(const type_base_sptr t, const environment &env)
Return either the type given in parameter if it's non-null, or the void type.
Definition abg-ir.cc:15465
bool is_at_global_scope(const decl_base &decl)
Tests whether a given declaration is at global scope.
Definition abg-ir.cc:10587
type_decl * is_real_type(const type_or_decl_base *t)
Test if a type is a real type.
Definition abg-ir.cc:10934
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition abg-ir.cc:5424
bool maybe_compare_as_member_decls(const decl_base &l, const decl_base &r, change_kind *k)
Compare the properties that belong to the "is-a-member-relation" of a decl.
Definition abg-ir.cc:5076
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition abg-ir.cc:6402
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
Definition abg-ir.cc:6432
bool is_declaration_only_class_type(const type_base_sptr &t, bool look_through_decl_only)
Test wheter a type is a declaration-only class.
Definition abg-ir.cc:11392
bool match(const regex_t_sptr &r, const std::string &str)
See if a string matches a regex.
Definition abg-regex.cc:127
std::shared_ptr< regex_t > regex_t_sptr
A convenience typedef for a shared pointer of regex_t.
Definition abg-fwd.h:87
const char * get_anonymous_subrange_internal_name_prefix()
Getter of the prefix for the name of anonymous range.
const char * get_anonymous_enum_internal_name_prefix()
Getter of the prefix for the name of anonymous enums.
const char * get_anonymous_struct_internal_name_prefix()
Getter of the prefix for the name of anonymous structs.
const char * get_anonymous_union_internal_name_prefix()
Getter of the prefix for the name of anonymous unions.
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
Definition abg-ir.cc:151
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
Definition abg-ir.cc:185
unordered_map< string, string * > pool_map_type
Convenience typedef for a map of string -> string*.
Definition abg-ir.cc:73
A functor to hash instances of interned_string.
size_t operator()(const type_base_sptr &l) const
Hash a type by returning the pointer value of its canonical type.
Definition abg-ir.cc:7790
Hasher for the class_or_union type.
Definition abg-hash.h:250
bool is_printing_flat_representation() const
Getter of the 'is_printing_flat_representation_' boolean.
void unset_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to false.
void set_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to true.
A functor to sort decls somewhat topologically. That is, types are sorted in a way that makes the one...
The private data of the environment type.
Equality functor for instances of function_decl.
Definition abg-ir.h:4772
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:30157
The hashing functor for member_base.
Definition abg-hash.h:243
Private type to hold private members of translation_unit.
Hash functor for instances of type_base.
Definition abg-hash.h:111
Definition of the private data of type_base.
The private data of type_or_decl_base.
A predicate for deep equality of instances of shared_ptr<type_base>
Definition abg-ir.h:2096
A functor to sort types somewhat topologically. That is, types are sorted in a way that makes the one...
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.