libabigail
abg-ir.cc
Go to the documentation of this file.
1// C++ -*-
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// -*- Mode: C++ -*-
4
5// Copyright (C) 2013-2025 Red Hat, Inc.
6//
7//Author: Dodji Seketeli
8
9/// @file
10///
11/// Definitions for the Internal Representation artifacts of libabigail.
12
13#include <cxxabi.h>
14#include <cstdint>
15#include <functional>
16#include <iterator>
17#include <memory>
18#include <sstream>
19#include <typeinfo>
20#include <unordered_map>
21#include <utility>
22#include <vector>
23
24#include "abg-internal.h"
25// <headers defining libabigail's API go under here>
26ABG_BEGIN_EXPORT_DECLARATIONS
27
28#include "abg-interned-str.h"
29#include "abg-ir.h"
30#include "abg-corpus.h"
31#include "abg-regex.h"
32
33ABG_END_EXPORT_DECLARATIONS
34// </headers defining libabigail's API>
35
36#include "abg-corpus-priv.h"
37#include "abg-comp-filter.h"
38#include "abg-ir-priv.h"
39
40namespace
41{
42/// This internal type is a tree walking that is used to set the
43/// qualified name of a tree of decls and types. It used by the
44/// function update_qualified_name().
45class qualified_name_setter : public abigail::ir::ir_node_visitor
46{
47
48public:
49 bool
50 do_update(abigail::ir::decl_base* d);
51
52 bool
53 visit_begin(abigail::ir::decl_base* d);
54
55 bool
56 visit_begin(abigail::ir::type_base* d);
57}; // end class qualified_name_setter
58
59}// end anon namespace
60
61namespace abigail
62{
63
64// Inject.
65using std::string;
66using std::list;
67using std::vector;
68using std::unordered_map;
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
71
72/// Convenience typedef for a map of string -> string*.
73typedef unordered_map<string, string*> pool_map_type;
74
75/// The type of the private data structure of type @ref
76/// intered_string_pool.
77struct interned_string_pool::priv
78{
79 pool_map_type map;
80}; //end struc struct interned_string_pool::priv
81
82/// Default constructor.
84 : priv_(new priv)
85{
86 priv_->map[""] = 0;
87}
88
89/// Test if the interned string pool already contains a string with a
90/// given value.
91///
92/// @param s the string to test for.
93///
94/// @return true if the pool contains a string with the value @p s.
95bool
97{return priv_->map.find(s) != priv_->map.end();}
98
99/// Get a pointer to the interned string which has a given value.
100///
101/// @param s the value of the interned string to look for.
102///
103/// @return a pointer to the raw string of characters which has the
104/// value of @p s. Or null if no string with value @p s was interned.
105const char*
107{
108 unordered_map<string, string*>::const_iterator i =
109 priv_->map.find(s);
110 if (i == priv_->map.end())
111 return 0;
112 if (i->second)
113 return i->second->c_str();
114 return "";
115}
116
117/// Create an interned string with a given value.
118///
119/// @param str_value the value of the interned string to create.
120///
121/// @return the new created instance of @ref interned_string created.
123interned_string_pool::create_string(const std::string& str_value)
124{
125 string*& result = priv_->map[str_value];
126 if (!result && !str_value.empty())
127 result = new string(str_value);
128 return interned_string(result);
129}
130
131/// Destructor.
133{
134 for (pool_map_type::iterator i = priv_->map.begin();
135 i != priv_->map.end();
136 ++i)
137 if (i->second)
138 delete i->second;
139}
140
141/// Equality operator.
142///
143/// @param l the instance of std::string on the left-hand-side of the
144/// equality operator.
145///
146/// @param r the instance of @ref interned_string on the
147/// right-hand-side of the equality operator.
148///
149/// @return true iff the two string are equal.
150bool
151operator==(const std::string& l, const interned_string& r)
152{return r.operator==(l);}
153
154bool
155operator!=(const std::string& l, const interned_string& r)
156{return !(l == r);}
157
158/// Streaming operator.
159///
160/// Streams an instance of @ref interned_string to an output stream.
161///
162/// @param o the destination output stream.
163///
164/// @param s the instance of @ref interned_string to stream out.
165///
166/// @return the output stream this function just streamed to.
167std::ostream&
168operator<<(std::ostream& o, const interned_string& s)
169{
170 o << static_cast<std::string>(s);
171 return o;
172}
173
174/// Concatenation operator.
175///
176/// Concatenate two instances of @ref interned_string, builds an
177/// instance of std::string with the resulting string and return it.
178///
179/// @param s1 the first string to consider.
180///
181/// @param s2 the second string to consider.
182///
183/// @return the resuting concatenated string.
184std::string
185operator+(const interned_string& s1,const std::string& s2)
186{return static_cast<std::string>(s1) + s2;}
187
188/// Concatenation operator.
189///
190/// Concatenate two instances of @ref interned_string, builds an
191/// instance of std::string with the resulting string and return it.
192///
193/// @param s1 the first string to consider.
194///
195/// @param s2 the second string to consider.
196///
197/// @return the resuting concatenated string.
198std::string
199operator+(const std::string& s1, const interned_string& s2)
200{return s1 + static_cast<std::string>(s2);}
201
202namespace ir
203{
204
205static size_t
206hash_as_canonical_type_or_constant(const type_base *t);
207
208static bool
209has_generic_anonymous_internal_type_name(const decl_base *d);
210
211static interned_string
212get_generic_anonymous_internal_type_name(const decl_base *d);
213
214static string
215get_internal_real_type_name(const type_base*);
216
217static void
218update_qualified_name(decl_base * d);
219
220static void
221update_qualified_name(decl_base_sptr d);
222
223static interned_string
224pointer_declaration_name(const type_base* ptr,
225 const string& variable_name,
226 bool qualified, bool internal);
227
228static interned_string
229pointer_declaration_name(const type_base_sptr& ptr,
230 const string& variable_name,
231 bool qualified, bool internal);
232
233static interned_string
234ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
235 const string& variable_name,
236 bool qualified, bool internal);
237
238static interned_string
239ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
240 const string& variable_name,
241 bool qualified, bool internal);
242
243static interned_string
244array_declaration_name(const array_type_def* array,
245 const string& variable_name,
246 bool qualified, bool internal);
247
248static interned_string
249array_declaration_name(const array_type_def_sptr& array,
250 const string& variable_name,
251 bool qualified, bool internal);
252
253static void
254stream_pretty_representation_of_fn_parms(const function_type& fn_type,
255 ostream& o, bool qualified,
256 bool internal);
257static string
258add_outer_pointer_to_fn_type_expr(const type_base* pointer_to_fn,
259 const string& input, bool qualified,
260 bool internal);
261
262static string
263add_outer_pointer_to_fn_type_expr(const type_base_sptr& pointer_to_fn,
264 const string& input, bool qualified,
265 bool internal);
266
267static string
268add_outer_pointer_to_array_type_expr(const type_base* pointer_to_ar,
269 const string& input, bool qualified,
270 bool internal);
271
272static string
273add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
274 const string& input, bool qualified,
275 bool internal);
276
277static string
278add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
279 const string& input, bool qualified,
280 bool internal);
281
282static string
283add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
284 const string& input, bool qualified,
285 bool internal);
286
287static string
288add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
289 const string& input,
290 bool qualified, bool internal);
291
292void
293push_composite_type_comparison_operands(const type_base& left,
294 const type_base& right);
295
296void
297pop_composite_type_comparison_operands(const type_base& left,
298 const type_base& right);
299
300
301/// Push a pair of operands on the stack of operands of the current
302/// type comparison, during type canonicalization.
303///
304/// For more information on this, please look at the description of
305/// the environment::priv::right_type_comp_operands_ data member.
306///
307/// @param left the left-hand-side comparison operand to push.
308///
309/// @param right the right-hand-side comparison operand to push.
310void
312 const type_base& right)
313{
314 const environment& env = left.get_environment();
315 env.priv_->push_composite_type_comparison_operands(&left, &right);
316}
317
318/// Pop a pair of operands from the stack of operands to the current
319/// type comparison.
320///
321/// For more information on this, please look at the description of
322/// the environment::privright_type_comp_operands_ data member.
323///
324/// @param left the left-hand-side comparison operand we expect to
325/// pop from the top of the stack. If this doesn't match the
326/// operand found on the top of the stack, the function aborts.
327///
328/// @param right the right-hand-side comparison operand we expect to
329/// pop from the bottom of the stack. If this doesn't match the
330/// operand found on the top of the stack, the function aborts.
331void
333 const type_base& right)
334{
335 const environment& env = left.get_environment();
336 env.priv_->pop_composite_type_comparison_operands(&left, &right);
337}
338
339/// Getter of the canonical type index of a given type.
340///
341/// @param t the type to consider.
342///
343/// @return the CTI of the type.
344size_t
346{return t.priv_->canonical_type_index;}
347
348/// Getter of the canonical type index of a given type.
349///
350/// @param t the type to consider.
351///
352/// @return the CTI of the type.
353size_t
355{return get_canonical_type_index(*t);}
356
357/// Getter of the canonical type index of a given type.
358///
359/// @param t the type to consider.
360///
361/// @return the CTI of the type.
362size_t
363get_canonical_type_index(const type_base_sptr& t)
364{return get_canonical_type_index(t.get());}
365
366/// Test if a type originates from a corpus.
367///
368/// Note that this function supports testing if a type originates from
369/// a corpus group.
370///
371/// @param t the type to consider.
372///
373/// @param c the corpus or corpus group to consider.
374///
375/// @return true iff the type @p t originates from the corpus (or
376/// group) @p c.
377bool
378type_originates_from_corpus(type_base_sptr t, corpus_sptr& c)
379{
380 bool result = false;
381 if (c && t->get_corpus())
382 {
383 corpus_group_sptr g = is_corpus_group(c);
384 if (g)
385 {
386 if (t->get_corpus()->get_group() == g.get())
387 result = true;
388 }
389 else
390 {
391 if (t->get_corpus() == c.get())
392 result = true;
393 }
394 }
395 return result;
396}
397/// @brief the location of a token represented in its simplest form.
398/// Instances of this type are to be stored in a sorted vector, so the
399/// type must have proper relational operators.
400class expanded_location
401{
402 string path_;
403 unsigned line_;
404 unsigned column_;
405
406 expanded_location();
407
408public:
409
410 friend class location_manager;
411
412 expanded_location(const string& path, unsigned line, unsigned column)
413 : path_(path), line_(line), column_(column)
414 {}
415
416 bool
417 operator==(const expanded_location& l) const
418 {
419 return (path_ == l.path_
420 && line_ == l.line_
421 && column_ && l.column_);
422 }
423
424 bool
425 operator<(const expanded_location& l) const
426 {
427 if (path_ < l.path_)
428 return true;
429 else if (path_ > l.path_)
430 return false;
431
432 if (line_ < l.line_)
433 return true;
434 else if (line_ > l.line_)
435 return false;
436
437 return column_ < l.column_;
438 }
439};
440
441/// Expand the location into a tripplet path, line and column number.
442///
443/// @param path the output parameter where this function sets the
444/// expanded path.
445///
446/// @param line the output parameter where this function sets the
447/// expanded line.
448///
449/// @param column the ouptut parameter where this function sets the
450/// expanded column.
451void
452location::expand(std::string& path, unsigned& line, unsigned& column) const
453{
454 if (!get_location_manager())
455 {
456 // We don't have a location manager maybe because this location
457 // was just freshly instanciated. We still want to be able to
458 // expand to default values.
459 path = "";
460 line = 0;
461 column = 0;
462 return;
463 }
464 get_location_manager()->expand_location(*this, path, line, column);
465}
466
467
468/// Expand the location into a string.
469///
470/// @return the string representing the location.
471string
473{
474 string path, result;
475 unsigned line = 0, column = 0;
476 expand(path, line, column);
477
478 std::ostringstream o;
479 o << path << ":" << line << ":" << column;
480 return o.str();
481}
482
483struct location_manager::priv
484{
485 /// This sorted vector contains the expanded locations of the tokens
486 /// coming from a given ABI Corpus. The index of a given expanded
487 /// location in the table gives us an integer that is used to build
488 /// instance of location types.
489 std::vector<expanded_location> locs;
490};
491
492location_manager::location_manager()
493 : priv_(new location_manager::priv)
494{}
495
496location_manager::~location_manager() = default;
497
498/// Insert the triplet representing a source locus into our internal
499/// vector of location triplet. Return an instance of location type,
500/// built from an real type that represents the index of the
501/// source locus triplet into our source locus table.
502///
503/// @param file_path the file path of the source locus
504/// @param line the line number of the source location
505/// @param col the column number of the source location
506location
507location_manager::create_new_location(const std::string& file_path,
508 size_t line,
509 size_t col)
510{
511 expanded_location l(file_path, line, col);
512
513 // Just append the new expanded location to the end of the vector
514 // and return its index. Note that indexes start at 1.
515 priv_->locs.push_back(l);
516 return location(priv_->locs.size(), this);
517}
518
519/// Given an instance of location type, return the triplet
520/// {path,line,column} that represents the source locus. Note that
521/// the location must have been previously created from the function
522/// location_manager::create_new_location, otherwise this function yields
523/// unexpected results, including possibly a crash.
524///
525/// @param location the instance of location type to expand
526/// @param path the resulting path of the source locus
527/// @param line the resulting line of the source locus
528/// @param column the resulting colum of the source locus
529void
531 std::string& path,
532 unsigned& line,
533 unsigned& column) const
534{
535 if (location.value_ == 0)
536 return;
537 expanded_location &l = priv_->locs[location.value_ - 1];
538 path = l.path_;
539 line = l.line_;
540 column = l.column_;
541}
542
543typedef unordered_map<function_type_sptr,
544 bool,
546 type_shared_ptr_equal> fn_type_ptr_map;
547
548// <type_maps stuff>
549
550struct type_maps::priv
551{
552 mutable istring_type_base_wptrs_map_type basic_types_;
553 mutable istring_type_base_wptrs_map_type class_types_;
554 mutable istring_type_base_wptrs_map_type union_types_;
555 mutable istring_type_base_wptrs_map_type enum_types_;
556 mutable istring_type_base_wptrs_map_type typedef_types_;
557 mutable istring_type_base_wptrs_map_type qualified_types_;
558 mutable istring_type_base_wptrs_map_type pointer_types_;
559 mutable istring_type_base_wptrs_map_type ptr_to_mbr_types_;
560 mutable istring_type_base_wptrs_map_type reference_types_;
561 mutable istring_type_base_wptrs_map_type array_types_;
562 mutable istring_type_base_wptrs_map_type subrange_types_;
563 mutable istring_type_base_wptrs_map_type function_types_;
564 mutable vector<type_base_wptr> sorted_types_;
565}; // end struct type_maps::priv
566
567type_maps::type_maps()
568 : priv_(new priv)
569{}
570
571type_maps::~type_maps() = default;
572
573/// Test if the type_maps is empty.
574///
575/// @return true iff the type_maps is empty.
576bool
578{
579 return (basic_types().empty()
580 && class_types().empty()
581 && union_types().empty()
582 && enum_types().empty()
583 && typedef_types().empty()
585 && pointer_types().empty()
587 && array_types().empty()
588 && subrange_types().empty()
589 && function_types().empty());
590}
591
592/// Getter for the map that associates the name of a basic type to the
593/// vector instances of type_decl_sptr that represents that type.
596{return priv_->basic_types_;}
597
598/// Getter for the map that associates the name of a basic type to the
599/// vector of instances of @ref type_decl_sptr that represents that
600/// type.
603{return priv_->basic_types_;}
604
605/// Getter for the map that associates the name of a class type to the
606/// vector of instances of @ref class_decl_sptr that represents that
607/// type.
610{return priv_->class_types_;}
611
612/// Getter for the map that associates the name of a class type to the
613/// vector of instances of @ref class_decl_sptr that represents that
614/// type.
617{return priv_->class_types_;}
618
619/// Getter for the map that associates the name of a union type to the
620/// vector of instances of @ref union_decl_sptr that represents that
621/// type.
624{return priv_->union_types_;}
625
626/// Getter for the map that associates the name of a union type to the
627/// vector of instances of @ref union_decl_sptr that represents that
628/// type.
631{return priv_->union_types_;}
632
633/// Getter for the map that associates the name of an enum type to the
634/// vector of instances of @ref enum_type_decl_sptr that represents
635/// that type.
638{return priv_->enum_types_;}
639
640/// Getter for the map that associates the name of an enum type to the
641/// vector of instances of @ref enum_type_decl_sptr that represents
642/// that type.
645{return priv_->enum_types_;}
646
647/// Getter for the map that associates the name of a typedef to the
648/// vector of instances of @ref typedef_decl_sptr that represents tha
649/// type.
652{return priv_->typedef_types_;}
653
654/// Getter for the map that associates the name of a typedef to the
655/// vector of instances of @ref typedef_decl_sptr that represents tha
656/// type.
659{return priv_->typedef_types_;}
660
661/// Getter for the map that associates the name of a qualified type to
662/// the vector of instances of @ref qualified_type_def_sptr.
665{return priv_->qualified_types_;}
666
667/// Getter for the map that associates the name of a qualified type to
668/// the vector of instances of @ref qualified_type_def_sptr.
671{return priv_->qualified_types_;}
672
673/// Getter for the map that associates the name of a pointer type to
674/// the vector of instances of @ref pointer_type_def_sptr that
675/// represents that type.
678{return priv_->pointer_types_;}
679
680/// Getter for the map that associates the name of a pointer-to-member
681/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
682/// represents that type.
685{return priv_->ptr_to_mbr_types_;}
686
687/// Getter for the map that associates the name of a pointer-to-member
688/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
689/// represents that type.
692{return priv_->ptr_to_mbr_types_;}
693
694/// Getter for the map that associates the name of a pointer type to
695/// the vector of instances of @ref pointer_type_def_sptr that
696/// represents that type.
699{return priv_->pointer_types_;}
700
701/// Getter for the map that associates the name of a reference type to
702/// the vector of instances of @ref reference_type_def_sptr that
703/// represents that type.
706{return priv_->reference_types_;}
707
708/// Getter for the map that associates the name of a reference type to
709/// the vector of instances of @ref reference_type_def_sptr that
710/// represents that type.
713{return priv_->reference_types_;}
714
715/// Getter for the map that associates the name of an array type to
716/// the vector of instances of @ref array_type_def_sptr that
717/// represents that type.
720{return priv_->array_types_;}
721
722/// Getter for the map that associates the name of an array type to
723/// the vector of instances of @ref array_type_def_sptr that
724/// represents that type.
727{return priv_->array_types_;}
728
729/// Getter for the map that associates the name of a subrange type to
730/// the vector of instances of @ref array_type_def::subrange_sptr that
731/// represents that type.
734{return priv_->subrange_types_;}
735
736/// Getter for the map that associates the name of a subrange type to
737/// the vector of instances of @ref array_type_def::subrange_sptr that
738/// represents that type.
741{return priv_->subrange_types_;}
742
743/// Getter for the map that associates the name of a function type to
744/// the vector of instances of @ref function_type_sptr that represents
745/// that type.
748{return priv_->function_types_;}
749
750/// Getter for the map that associates the name of a function type to
751/// the vector of instances of @ref function_type_sptr that represents
752/// that type.
755{return priv_->function_types_;}
756
757/// A comparison functor to compare/sort types based on their pretty
758/// representations.
759struct type_name_comp
760{
761 /// Comparison operator for two instances of @ref type_base.
762 ///
763 /// This compares the two types by lexicographically comparing their
764 /// pretty representation.
765 ///
766 /// @param l the left-most type to compare.
767 ///
768 /// @param r the right-most type to compare.
769 ///
770 /// @return true iff @p l < @p r.
771 bool
772 operator()(type_base *l, type_base *r) const
773 {
774 if (l == 0 && r == 0)
775 return false;
776
777 string l_repr = get_pretty_representation(l);
778 string r_repr = get_pretty_representation(r);
779 return l_repr < r_repr;
780 }
781
782 /// Comparison operator for two instances of @ref type_base.
783 ///
784 /// This compares the two types by lexicographically comparing their
785 /// pretty representation.
786 ///
787 /// @param l the left-most type to compare.
788 ///
789 /// @param r the right-most type to compare.
790 ///
791 /// @return true iff @p l < @p r.
792 bool
793 operator()(const type_base_sptr &l, const type_base_sptr &r) const
794 {return operator()(l.get(), r.get());}
795
796 /// Comparison operator for two instances of @ref type_base.
797 ///
798 /// This compares the two types by lexicographically comparing their
799 /// pretty representation.
800 ///
801 /// @param l the left-most type to compare.
802 ///
803 /// @param r the right-most type to compare.
804 ///
805 /// @return true iff @p l < @p r.
806 bool
807 operator()(const type_base_wptr &l, const type_base_wptr &r) const
808 {return operator()(type_base_sptr(l), type_base_sptr(r));}
809}; // end struct type_name_comp
810
811#ifdef WITH_DEBUG_SELF_COMPARISON
812
813/// This is a function called when the ABG_RETURN* macros defined
814/// below return false.
815///
816/// The purpose of this function is to ease debugging. To know where
817/// the equality functions first compare non-equal, we can just set a
818/// breakpoint on this notify_equality_failed function and run the
819/// equality functions. Because all the equality functions use the
820/// ABG_RETURN* macros to return their values, this function is always
821/// called when any of those equality function return false.
822///
823/// @param l the first operand of the equality.
824///
825/// @param r the second operand of the equality.
826static void
827notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
828 const type_or_decl_base &r __attribute__((unused)))
829{}
830
831/// This is a function called when the ABG_RETURN* macros defined
832/// below return false.
833///
834/// The purpose of this function is to ease debugging. To know where
835/// the equality functions first compare non-equal, we can just set a
836/// breakpoint on this notify_equality_failed function and run the
837/// equality functions. Because all the equality functions use the
838/// ABG_RETURN* macros to return their values, this function is always
839/// called when any of those equality function return false.
840///
841/// @param l the first operand of the equality.
842///
843/// @param r the second operand of the equality.
844static void
845notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
846 const type_or_decl_base *r __attribute__((unused)))
847{}
848
849#define ABG_RETURN_EQUAL(l, r) \
850 do \
851 { \
852 if (l != r) \
853 notify_equality_failed(l, r); \
854 return (l == r); \
855 } \
856 while(false)
857
858
859#define ABG_RETURN_FALSE \
860 do \
861 { \
862 notify_equality_failed(l, r); \
863 return false; \
864 } while(false)
865
866#define ABG_RETURN(value) \
867 do \
868 { \
869 if (value == false) \
870 notify_equality_failed(l, r); \
871 return value; \
872 } while (false)
873
874#else // WITH_DEBUG_SELF_COMPARISON
875
876#define ABG_RETURN_FALSE return false
877#define ABG_RETURN(value) return (value)
878#define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
879#endif
880
881/// Get the canonical type of a given type T* as a T*.
882///
883/// Note that normally, canonical types are returned as @ref
884/// type_base* (un-typed form, kind of). This function returns the
885/// canonical type as a T*, just like the T* it is looking at.
886///
887///
888/// @param t the type to consider.
889///
890/// @return either the canonical type of @p t or @p t itself if it
891/// doesn't have any canonical type.
892template<typename T>
893T*
895{
896 if (!t)
897 return nullptr;
898 if (type_base* type = t->get_naked_canonical_type())
899 return dynamic_cast<T*>(type);
900 return t;
901}
902
903/// Compare two types by comparing their canonical types if present.
904///
905/// If the canonical types are not present (because the types have not
906/// yet been canonicalized, for instance) then the types are compared
907/// structurally.
908///
909/// @param l the first type to take into account in the comparison.
910///
911/// @param r the second type to take into account in the comparison.
912template<typename T>
913bool
914try_canonical_compare(const T *l, const T *r)
915{
916#if WITH_DEBUG_TYPE_CANONICALIZATION
917 // We are debugging the canonicalization of a type down the stack.
918 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
919 // type being canonicalized. We are at a point where we can compare
920 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
921 // have canonical types) or structural comparison.
922 //
923 // Because we are debugging the process of type canonicalization, we
924 // want to compare 'l' and 'r' canonically *AND* structurally. Both
925 // kinds of comparison should yield the same result, otherwise type
926 // canonicalization just failed for the subtype 'r' of the type
927 // being canonicalized.
928 //
929 // In concrete terms, this function is going to be called twice with
930 // the same pair {'l', 'r'} to compare: The first time with
931 // environment::priv_->use_canonical_type_comparison_ set to true,
932 // instructing us to compare them canonically, and the second time
933 // with that boolean set to false, instructing us to compare them
934 // structurally.
935 const environment&env = l->get_environment();
936 if (env.priv_->use_canonical_type_comparison_)
937 {
938 if (const type_base *lc = l->get_naked_canonical_type())
939 if (const type_base *rc = r->get_naked_canonical_type())
940 ABG_RETURN_EQUAL(lc, rc);
941 }
942
943 // If the two types have a non-empty hash value, then consider those
944 // hash values. If the hashes are different then the two types are
945 // different. If the hashes are equal then we'll compare then
946 // structurally.
947 if (hash_t l_hash = peek_hash_value(*l))
948 if (hash_t r_hash = peek_hash_value(*r))
949 if (l_hash != r_hash)
951
952 // If a type has a canonical type, use its canonical type, always.
955
956 return equals(*l, *r, 0);
957#else
958 if (const type_base *lc = l->get_naked_canonical_type())
959 if (const type_base *rc = r->get_naked_canonical_type())
960 ABG_RETURN_EQUAL(lc, rc);
961
962 // If the two types have a non-empty hash value, then consider those
963 // hash values. If the hashes are different then the two types are
964 // different. If the hashes are equal then we'll compare then
965 // structurally.
966 if (hash_t l_hash = peek_hash_value(*l))
967 if (hash_t r_hash = peek_hash_value(*r))
968 if (l_hash != r_hash)
970
971 // If a type has a canonical type, use its canonical type, always.
974
975 return equals(*l, *r, 0);
976#endif
977}
978
979/// Detect if a recursive comparison cycle is detected while
980/// structurally comparing two types (a.k.a member-wise comparison).
981///
982/// @param l the left-hand-side operand of the current comparison.
983///
984/// @param r the right-hand-side operand of the current comparison.
985///
986/// @return true iff a comparison cycle is detected.
987template<typename T>
988bool
990{
991 bool result = l.priv_->comparison_started(l, r);
992 return result ;
993}
994
995/// Detect if a recursive comparison cycle is detected while
996/// structurally comparing two @ref class_decl types.
997///
998/// @param l the left-hand-side operand of the current comparison.
999///
1000/// @param r the right-hand-side operand of the current comparison.
1001///
1002/// @return true iff a comparison cycle is detected.
1003template<>
1004bool
1006{
1007 return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
1008 static_cast<const class_or_union&>(r));
1009}
1010
1011/// This macro is to be used while comparing composite types that
1012/// might recursively refer to themselves. Comparing two such types
1013/// might get us into a cyle.
1014///
1015/// Practically, if we detect that we are already into comparing 'l'
1016/// and 'r'; then, this is a cycle.
1017//
1018/// To break the cycle, we assume the result of the comparison is true
1019/// for now. Comparing the other sub-types of l & r will tell us later
1020/// if l & r are actually different or not.
1021///
1022/// In the mean time, returning true from this macro should not be
1023/// used to propagate the canonical type of 'l' onto 'r' as we don't
1024/// know yet if l equals r. All the types that depend on l and r
1025/// can't (and that are in the comparison stack currently) can't have
1026/// their canonical type propagated either. So this macro disallows
1027/// canonical type propagation for those types that depend on a
1028/// recursively defined sub-type for now.
1029///
1030/// @param l the left-hand-side operand of the comparison.
1031#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
1032 do \
1033 { \
1034 if (is_comparison_cycle_detected(l, r)) \
1035 return true; \
1036 } \
1037 while(false)
1038
1039
1040/// Mark a pair of types as being compared.
1041///
1042/// This is helpful to later detect recursive cycles in the comparison
1043/// stack.
1044///
1045/// @param l the left-hand-side operand of the comparison.
1046///
1047/// @parm r the right-hand-side operand of the comparison.
1048template<typename T>
1049void
1051{
1052 l.priv_->mark_as_being_compared(l, r);
1054}
1055
1056/// Mark a pair of @ref class_decl types as being compared.
1057///
1058/// This is helpful to later detect recursive cycles in the comparison
1059/// stack.
1060///
1061/// @param l the left-hand-side operand of the comparison.
1062///
1063/// @parm r the right-hand-side operand of the comparison.
1064template<>
1065void
1067{
1068 return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
1069 static_cast<const class_or_union&>(r));
1070}
1071
1072/// Mark a pair of types as being not compared anymore.
1073///
1074/// This is helpful to later detect recursive cycles in the comparison
1075/// stack.
1076///
1077/// Note that the types must have been passed to
1078/// mark_types_as_being_compared prior to calling this function.
1079///
1080/// @param l the left-hand-side operand of the comparison.
1081///
1082/// @parm r the right-hand-side operand of the comparison.
1083template<typename T>
1084void
1086{
1087 l.priv_->unmark_as_being_compared(l, r);
1089}
1090
1091/// Mark a pair of @ref class_decl types as being not compared
1092/// anymore.
1093///
1094/// This is helpful to later detect recursive cycles in the comparison
1095/// stack.
1096///
1097/// Note that the types must have been passed to
1098/// mark_types_as_being_compared prior to calling this function.
1099///
1100/// @param l the left-hand-side operand of the comparison.
1101///
1102/// @parm r the right-hand-side operand of the comparison.
1103template<>
1104void
1106{
1107 return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
1108 static_cast<const class_or_union&>(r));
1109}
1110
1111/// Return the result of the comparison of two (sub) types.
1112///
1113/// The function does the necessary book keeping before returning the
1114/// result of the comparison of two (sub) types.
1115///
1116/// The book-keeping done is essentially about type comparison cycle detection.
1117///
1118/// @param l the left-hand-side operand of the type comparison
1119///
1120/// @param r the right-hand-side operand of the type comparison
1121///
1122/// @param value the result of the comparison of @p l and @p r.
1123///
1124/// @return the value @p value.
1125template<typename T>
1126bool
1127return_comparison_result(T& l, T& r, bool value)
1128{
1130 ABG_RETURN(value);
1131}
1132
1133#define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1134 do \
1135 { \
1136 bool res = return_comparison_result(l, r, value); \
1137 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1138 return res; \
1139 } while (false)
1140
1141/// Cache the result of a comparison between too artifacts (l & r) and
1142/// return immediately.
1143///
1144/// @param value the value to cache.
1145#define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1146 do \
1147 { \
1148 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1149 return value; \
1150 } while (false)
1151
1152/// Getter of all types types sorted by their pretty representation.
1153///
1154/// @return a sorted vector of all types sorted by their pretty
1155/// representation.
1156const vector<type_base_wptr>&
1158{
1159 if (priv_->sorted_types_.empty())
1160 {
1161 istring_type_base_wptrs_map_type::const_iterator i;
1162 vector<type_base_wptr>::const_iterator j;
1163
1164 for (i = basic_types().begin(); i != basic_types().end(); ++i)
1165 for (j = i->second.begin(); j != i->second.end(); ++j)
1166 priv_->sorted_types_.push_back(*j);
1167
1168 for (i = class_types().begin(); i != class_types().end(); ++i)
1169 for (j = i->second.begin(); j != i->second.end(); ++j)
1170 priv_->sorted_types_.push_back(*j);
1171
1172 for (i = union_types().begin(); i != union_types().end(); ++i)
1173 for (j = i->second.begin(); j != i->second.end(); ++j)
1174 priv_->sorted_types_.push_back(*j);
1175
1176 for (i = enum_types().begin(); i != enum_types().end(); ++i)
1177 for (j = i->second.begin(); j != i->second.end(); ++j)
1178 priv_->sorted_types_.push_back(*j);
1179
1180 for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
1181 for (j = i->second.begin(); j != i->second.end(); ++j)
1182 priv_->sorted_types_.push_back(*j);
1183
1184 type_name_comp comp;
1185 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1186 }
1187
1188 return priv_->sorted_types_;
1189}
1190
1191// </type_maps stuff>
1192
1193// <translation_unit stuff>
1194
1195/// Constructor of translation_unit.
1196///
1197/// @param env the environment of this translation unit. Please note
1198/// that the life time of the environment must be greater than the
1199/// life time of the translation unit because the translation uses
1200/// resources that are allocated in the environment.
1201///
1202/// @param path the location of the translation unit.
1203///
1204/// @param address_size the size of addresses in the translation unit,
1205/// in bits.
1206translation_unit::translation_unit(const environment& env,
1207 const std::string& path,
1208 char address_size)
1209 : priv_(new priv(env))
1210{
1211 priv_->path_ = path;
1212 priv_->address_size_ = address_size;
1213}
1214
1215/// Getter of the the global scope of the translation unit.
1216///
1217/// @return the global scope of the current translation unit. If
1218/// there is not global scope allocated yet, this function creates one
1219/// and returns it.
1220const scope_decl_sptr&
1222{
1223 return const_cast<translation_unit*>(this)->get_global_scope();
1224}
1225
1226/// Getter of the global scope of the translation unit.
1227///
1228/// @return the global scope of the current translation unit. If
1229/// there is not allocated yet, this function creates one and returns
1230/// it.
1233{
1234 if (!priv_->global_scope_)
1235 {
1236 priv_->global_scope_.reset
1237 (new global_scope(const_cast<translation_unit*>(this)));
1238 priv_->global_scope_->set_translation_unit
1239 (const_cast<translation_unit*>(this));
1240 }
1241 return priv_->global_scope_;
1242}
1243
1244/// Getter of the types of the current @ref translation_unit.
1245///
1246/// @return the maps of the types of the translation unit.
1247const type_maps&
1249{return priv_->types_;}
1250
1251/// Getter of the types of the current @ref translation_unit.
1252///
1253/// @return the maps of the types of the translation unit.
1254type_maps&
1256{return priv_->types_;}
1257
1258/// Get the vector of function types that are used in the current
1259/// translation unit.
1260///
1261/// @return the vector of function types that are used in the current
1262/// translation unit.
1263const vector<function_type_sptr>&
1265{return priv_->live_fn_types_;}
1266
1267/// Getter of the environment of the current @ref translation_unit.
1268///
1269/// @return the translation unit of the current translation unit.
1270const environment&
1272{return priv_->env_;}
1273
1274/// Getter of the language of the source code of the translation unit.
1275///
1276/// @return the language of the source code.
1279{return priv_->language_;}
1280
1281/// Setter of the language of the source code of the translation unit.
1282///
1283/// @param l the new language.
1284void
1286{priv_->language_ = l;}
1287
1288
1289/// Get the path of the current translation unit.
1290///
1291/// This path is relative to the build directory of the translation
1292/// unit as returned by translation_unit::get_compilation_dir_path.
1293///
1294/// @return the relative path of the compilation unit associated to
1295/// the current instance of translation_unit.
1296//
1297const std::string&
1299{return priv_->path_;}
1300
1301/// Set the path associated to the current instance of
1302/// translation_unit.
1303///
1304/// This path is relative to the build directory of the translation
1305/// unit as returned by translation_unit::get_compilation_dir_path.
1306///
1307/// @param a_path the new relative path to set.
1308void
1309translation_unit::set_path(const string& a_path)
1310{priv_->path_ = a_path;}
1311
1312
1313/// Get the path of the directory that was 'current' when the
1314/// translation unit was compiled.
1315///
1316/// Note that the path returned by translation_unit::get_path is
1317/// relative to the path returned by this function.
1318///
1319/// @return the compilation directory for the current translation
1320/// unit.
1321const std::string&
1323{return priv_->comp_dir_path_;}
1324
1325/// Set the path of the directory that was 'current' when the
1326/// translation unit was compiled.
1327///
1328/// Note that the path returned by translation_unit::get_path is
1329/// relative to the path returned by this function.
1330///
1331/// @param the compilation directory for the current translation unit.
1332void
1334{priv_->comp_dir_path_ = d;}
1335
1336/// Get the concatenation of the build directory and the relative path
1337/// of the translation unit.
1338///
1339/// @return the absolute path of the translation unit.
1340const std::string&
1342{
1343 if (priv_->abs_path_.empty())
1344 {
1345 string path;
1346 if (!priv_->path_.empty())
1347 {
1348 if (!priv_->comp_dir_path_.empty())
1349 {
1350 path = priv_->comp_dir_path_;
1351 path += "/";
1352 }
1353 path += priv_->path_;
1354 }
1355 priv_->abs_path_ = path;
1356 }
1357
1358 return priv_->abs_path_;
1359}
1360
1361/// Set the corpus this translation unit is a member of.
1362///
1363/// Note that adding a translation unit to a @ref corpus automatically
1364/// triggers a call to this member function.
1365///
1366/// @param corpus the corpus.
1367void
1369{priv_->corp = c;}
1370
1371/// Get the corpus this translation unit is a member of.
1372///
1373/// @return the parent corpus, or nil if this doesn't belong to any
1374/// corpus yet.
1375corpus*
1377{return priv_->corp;}
1378
1379/// Get the corpus this translation unit is a member of.
1380///
1381/// @return the parent corpus, or nil if this doesn't belong to any
1382/// corpus yet.
1383const corpus*
1385{return const_cast<translation_unit*>(this)->get_corpus();}
1386
1387/// Getter of the location manager for the current translation unit.
1388///
1389/// @return a reference to the location manager for the current
1390/// translation unit.
1393{return priv_->loc_mgr_;}
1394
1395/// const Getter of the location manager.
1396///
1397/// @return a const reference to the location manager for the current
1398/// translation unit.
1399const location_manager&
1401{return priv_->loc_mgr_;}
1402
1403/// Tests whether if the current translation unit contains ABI
1404/// artifacts or not.
1405///
1406/// @return true iff the current translation unit is empty.
1407bool
1409{
1410 if (!priv_->global_scope_)
1411 return true;
1412 return get_global_scope()->is_empty();
1413}
1414
1415/// Getter of the address size in this translation unit.
1416///
1417/// @return the address size, in bits.
1418char
1420{return priv_->address_size_;}
1421
1422/// Setter of the address size in this translation unit.
1423///
1424/// @param a the new address size in bits.
1425void
1427{priv_->address_size_= a;}
1428
1429/// Getter of the 'is_constructed" flag. It says if the translation
1430/// unit is fully constructed or not.
1431///
1432/// This flag is important for cases when comparison might depend on
1433/// if the translation unit is fully built or not. For instance, when
1434/// reading types from DWARF, the virtual methods of a class are not
1435/// necessarily fully constructed until we have reached the end of the
1436/// translation unit. In that case, before we've reached the end of
1437/// the translation unit, we might not take virtual functions into
1438/// account when comparing classes.
1439///
1440/// @return true if the translation unit is constructed.
1441bool
1443{return priv_->is_constructed_;}
1444
1445/// Setter of the 'is_constructed" flag. It says if the translation
1446/// unit is fully constructed or not.
1447///
1448/// This flag is important for cases when comparison might depend on
1449/// if the translation unit is fully built or not. For instance, when
1450/// reading types from DWARF, the virtual methods of a class are not
1451/// necessarily fully constructed until we have reached the end of the
1452/// translation unit. In that case, before we've reached the end of
1453/// the translation unit, we might not take virtual functions into
1454/// account when comparing classes.
1455///
1456/// @param f true if the translation unit is constructed.
1457void
1459{priv_->is_constructed_ = f;}
1460
1461/// Compare the current translation unit against another one.
1462///
1463/// @param other the other tu to compare against.
1464///
1465/// @return true if the two translation units are equal, false
1466/// otherwise.
1467bool
1469{
1470 if (get_address_size() != other.get_address_size())
1471 return false;
1472
1473 return *get_global_scope() == *other.get_global_scope();
1474}
1475
1476/// Inequality operator.
1477///
1478/// @param o the instance of @ref translation_unit to compare the
1479/// current instance against.
1480///
1481/// @return true iff the current instance is different from @p o.
1482bool
1484{return ! operator==(o);}
1485
1486/// Ensure that the life time of a function type is bound to the life
1487/// time of the current translation unit.
1488///
1489/// @param ftype the function time which life time to bind to the life
1490/// time of the current instance of @ref translation_unit. That is,
1491/// it's onlyh when the translation unit is destroyed that the
1492/// function type can be destroyed to.
1493void
1495{
1496 const environment& env = get_environment();
1497
1498 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1499
1500 interned_string repr = get_type_name(ftype);
1501 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1502 push_back(ftype);
1503
1504 // The function type must be out of the same environment as its
1505 // translation unit.
1506 {
1507 const environment& e = ftype->get_environment();
1508 ABG_ASSERT(&env == &e);
1509 }
1510
1511 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1512 ABG_ASSERT(existing_tu == this);
1513 else
1514 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1515
1517}
1518
1519/// This implements the ir_traversable_base::traverse virtual
1520/// function.
1521///
1522/// @param v the visitor used on the member nodes of the translation
1523/// unit during the traversal.
1524///
1525/// @return true if the entire type IR tree got traversed, false
1526/// otherwise.
1527bool
1529{return get_global_scope()->traverse(v);}
1530
1531translation_unit::~translation_unit()
1532{}
1533
1534/// Converts a translation_unit::language enumerator into a string.
1535///
1536/// @param l the language enumerator to translate.
1537///
1538/// @return the resulting string.
1539string
1541{
1542 switch (l)
1543 {
1544 case translation_unit::LANG_UNKNOWN:
1545 return "LANG_UNKNOWN";
1546 case translation_unit::LANG_Cobol74:
1547 return "LANG_Cobol74";
1548 case translation_unit::LANG_Cobol85:
1549 return "LANG_Cobol85";
1550 case translation_unit::LANG_C89:
1551 return "LANG_C89";
1552 case translation_unit::LANG_C99:
1553 return "LANG_C99";
1554 case translation_unit::LANG_C11:
1555 return "LANG_C11";
1556 case translation_unit::LANG_C17:
1557 return "LANG_C17";
1558 case translation_unit::LANG_C23:
1559 return "LANG_C23";
1560 case translation_unit::LANG_C:
1561 return "LANG_C";
1562 case translation_unit::LANG_C_plus_plus_03:
1563 return "LANG_C_plus_plus_03";
1564 case translation_unit::LANG_C_plus_plus_11:
1565 return "LANG_C_plus_plus_11";
1566 case translation_unit::LANG_C_plus_plus_14:
1567 return "LANG_C_plus_plus_14";
1568 case translation_unit::LANG_C_plus_plus_17:
1569 return "LANG_C_plus_plus_17";
1570 case translation_unit::LANG_C_plus_plus_20:
1571 return "LANG_C_plus_plus_20";
1572 case translation_unit::LANG_C_plus_plus_23:
1573 return "LANG_C_plus_plus_23";
1574 case translation_unit::LANG_C_plus_plus:
1575 return "LANG_C_plus_plus";
1576 case translation_unit::LANG_OCaml:
1577 return "LANG_OCaml";
1578 case translation_unit::LANG_Zig:
1579 return "LANG_Zig";
1580 case translation_unit::LANG_ObjC:
1581 return "LANG_ObjC";
1582 case translation_unit::LANG_ObjC_plus_plus:
1583 return "LANG_ObjC_plus_plus";
1584 case translation_unit::LANG_D:
1585 return "LANG_D";
1586 case translation_unit::LANG_Go:
1587 return "LANG_Go";
1588 case translation_unit::LANG_Rust:
1589 return "LANG_Rust";
1590 case translation_unit::LANG_Fortran77:
1591 return "LANG_Fortran77";
1592 case translation_unit::LANG_Fortran90:
1593 return "LANG_Fortran90";
1594 case translation_unit::LANG_Fortran95:
1595 return "LANG_Fortran95";
1596 case translation_unit::LANG_Fortran18:
1597 return "LANG_Fortran18";
1598 case translation_unit::LANG_Fortran23:
1599 return "LANG_Fortran23";
1600 case translation_unit::LANG_Ada83:
1601 return "LANG_Ada83";
1602 case translation_unit::LANG_Ada95:
1603 return "LANG_Ada95";
1604 case translation_unit::LANG_Ada2005:
1605 return "LANG_Ada2005";
1606 case translation_unit::LANG_Ada2012:
1607 return "LANG_Ada2012";
1608 case translation_unit::LANG_Pascal83:
1609 return "LANG_Pascal83";
1610 case translation_unit::LANG_Modula2:
1611 return "LANG_Modula2";
1612 case translation_unit::LANG_Java:
1613 return "LANG_Java";
1614 case translation_unit::LANG_Kotlin:
1615 return "LANG_Kotlin";
1616 case translation_unit::LANG_C_sharp:
1617 return "LANG_C_sharp";
1618 case translation_unit::LANG_Python:
1619 return "LANG_Python";
1620 case translation_unit::LANG_Ruby:
1621 return "LANG_Ruby";
1622 case translation_unit::LANG_PLI:
1623 return "LANG_PLI";
1624 case translation_unit::LANG_UPC:
1625 return "LANG_UPC";
1626 case translation_unit::LANG_Mips_Assembler:
1627 return "LANG_Mips_Assembler";
1628 case translation_unit::LANG_Assembly:
1629 return "LANG_Assembly";
1630 case translation_unit::LANG_Crystal:
1631 return "LANG_Crystal";
1632 case translation_unit::LANG_HIP:
1633 return "LANG_HIP";
1634 case translation_unit::LANG_Mojo:
1635 return "LANG_Mojo";
1636 case translation_unit::LANG_GLSL:
1637 return "LANG_GLSL";
1638 case translation_unit::LANG_GLSL_ES:
1639 return "LANG_GLSL_ES";
1640 case translation_unit::LANG_HLSL:
1641 return "LANG_HLSL";
1642 case translation_unit::LANG_OpenCL_CPP:
1643 return "LANG_OpenCL_CPP";
1644 case translation_unit::LANG_CPP_for_OpenCL:
1645 return "LANG_CPP_for_OpenCL";
1646 case translation_unit::LANG_SYCL:
1647 return "LANG_SYCL";
1648 case translation_unit::LANG_Odin:
1649 return "LANG_Odin";
1650 case translation_unit::LANG_P4:
1651 return "LANG_P4";
1652 case translation_unit::LANG_Metal:
1653 return "LANG_Metal";
1654 case translation_unit::LANG_Move:
1655 return "LANG_Move";
1656 case translation_unit::LANG_Hylo:
1657 return "LANG_Hylo";
1658 }
1659
1660 return "LANG_UNKNOWN";
1661}
1662
1663/// Parse a string representing a language into a
1664/// translation_unit::language enumerator into a string.
1665///
1666/// @param l the string representing the language.
1667///
1668/// @return the resulting translation_unit::language enumerator.
1671{
1672 if (l == "LANG_Cobol74")
1673 return translation_unit::LANG_Cobol74;
1674 else if (l == "LANG_Cobol85")
1675 return translation_unit::LANG_Cobol85;
1676 else if (l == "LANG_C89")
1677 return translation_unit::LANG_C89;
1678 else if (l == "LANG_C99")
1679 return translation_unit::LANG_C99;
1680 else if (l == "LANG_C11")
1681 return translation_unit::LANG_C11;
1682 else if (l == "LANG_C17")
1683 return translation_unit::LANG_C17;
1684 else if (l == "LANG_C23")
1685 return translation_unit::LANG_C23;
1686 else if (l == "LANG_C")
1687 return translation_unit::LANG_C;
1688 else if (l == "LANG_C_plus_plus_03")
1689 return translation_unit::LANG_C_plus_plus_03;
1690 else if (l == "LANG_C_plus_plus_11")
1691 return translation_unit::LANG_C_plus_plus_11;
1692 else if (l == "LANG_C_plus_plus_14")
1693 return translation_unit::LANG_C_plus_plus_14;
1694 else if (l == "LANG_C_plus_plus_17")
1695 return translation_unit::LANG_C_plus_plus_17;
1696 else if (l == "LANG_C_plus_plus_20")
1697 return translation_unit::LANG_C_plus_plus_20;
1698 else if (l == "LANG_C_plus_plus_23")
1699 return translation_unit::LANG_C_plus_plus_23;
1700 else if (l == "LANG_C_plus_plus")
1701 return translation_unit::LANG_C_plus_plus;
1702 else if (l == "LANG_OCaml")
1703 return translation_unit::LANG_OCaml;
1704 else if (l == "LANG_ObjC")
1705 return translation_unit::LANG_ObjC;
1706 else if (l == "LANG_ObjC_plus_plus")
1707 return translation_unit::LANG_ObjC_plus_plus;
1708 else if (l == "LANG_Zig")
1709 return translation_unit::LANG_Zig;
1710 else if (l == "LANG_Metal")
1711 return translation_unit::LANG_Metal;
1712 else if (l == "LANG_Fortran77")
1713 return translation_unit::LANG_Fortran77;
1714 else if (l == "LANG_Fortran90")
1715 return translation_unit::LANG_Fortran90;
1716 else if (l == "LANG_Fortran95")
1717 return translation_unit::LANG_Fortran95;
1718 else if (l == "LANG_Fortran18")
1719 return translation_unit::LANG_Fortran23;
1720 else if (l == "LANG_Ada83")
1721 return translation_unit::LANG_Ada83;
1722 else if (l == "LANG_Ada95")
1723 return translation_unit::LANG_Ada95;
1724 else if (l == "LANG_Ada2005")
1725 return translation_unit::LANG_Ada2005;
1726 else if (l == "LANG_Ada2012")
1727 return translation_unit::LANG_Ada2012;
1728 else if (l == "LANG_Pascal83")
1729 return translation_unit::LANG_Pascal83;
1730 else if (l == "LANG_Modula2")
1731 return translation_unit::LANG_Modula2;
1732 else if (l == "LANG_Java")
1733 return translation_unit::LANG_Java;
1734 else if (l == "LANG_Kotlin")
1735 return translation_unit::LANG_Kotlin;
1736 else if (l == "LANG_PLI")
1737 return translation_unit::LANG_PLI;
1738 else if (l == "LANG_UPC")
1739 return translation_unit::LANG_UPC;
1740 else if (l == "LANG_D")
1741 return translation_unit::LANG_D;
1742 else if (l == "LANG_Go")
1743 return translation_unit::LANG_Go;
1744 else if (l == "LANG_Rust")
1745 return translation_unit::LANG_Rust;
1746 else if (l == "LANG_Python")
1747 return translation_unit::LANG_Python;
1748 else if (l == "LANG_Ruby")
1749 return translation_unit::LANG_Ruby;
1750 else if (l == "LANG_Mips_Assembler")
1751 return translation_unit::LANG_Mips_Assembler;
1752 else if (l == "LANG_Assembly")
1753 return translation_unit::LANG_Assembly;
1754 else if (l == "LANG_Crystal")
1755 return translation_unit::LANG_Crystal;
1756 else if (l == "LANG_HIP")
1757 return translation_unit::LANG_HIP;
1758 else if (l == "LANG_C_sharp")
1759 return translation_unit::LANG_C_sharp;
1760 else if (l == "LANG_Mojo")
1761 return translation_unit::LANG_Mojo;
1762 else if (l == "LANG_GLSL")
1763 return translation_unit::LANG_GLSL;
1764 else if (l == "LANG_GLSL_ES")
1765 return translation_unit::LANG_GLSL_ES;
1766 else if (l == "LANG_HLSL")
1767 return translation_unit::LANG_HLSL;
1768 else if (l == "LANG_OpenCL_CPP")
1769 return translation_unit::LANG_OpenCL_CPP;
1770 else if (l == "LANG_CPP_for_OpenCL")
1771 return translation_unit::LANG_CPP_for_OpenCL;
1772 else if (l == "LANG_SYCL")
1773 return translation_unit::LANG_SYCL;
1774 else if (l == "LANG_Odin")
1775 return translation_unit::LANG_Odin;
1776 else if (l == "LANG_P4")
1777 return translation_unit::LANG_P4;
1778 else if (l == "LANG_Move")
1779 return translation_unit::LANG_Move;
1780 else if (l == "LANG_Hylo")
1781 return translation_unit::LANG_Hylo;
1782
1783 return translation_unit::LANG_UNKNOWN;
1784}
1785
1786/// Test if a language enumerator designates the C language.
1787///
1788/// @param l the language enumerator to consider.
1789///
1790/// @return true iff @p l designates the C language.
1791bool
1793{
1794 return (l == translation_unit::LANG_C89
1795 || l == translation_unit::LANG_C99
1796 || l == translation_unit::LANG_C11
1797 || l == translation_unit::LANG_C17
1798 || l == translation_unit::LANG_C23
1799 || l == translation_unit::LANG_C);
1800}
1801
1802/// Test if a language enumerator designates the C++ language.
1803///
1804/// @param l the language enumerator to consider.
1805///
1806/// @return true iff @p l designates the C++ language.
1807bool
1809{
1810 return (l == translation_unit::LANG_C_plus_plus_03
1811 || l == translation_unit::LANG_C_plus_plus_11
1812 || l == translation_unit::LANG_C_plus_plus_14
1813 || l == translation_unit::LANG_C_plus_plus_20
1814 || l == translation_unit::LANG_C_plus_plus_23
1815 || l == translation_unit::LANG_C_plus_plus);
1816}
1817
1818/// Test if a language enumerator designates the Java language.
1819///
1820/// @param l the language enumerator to consider.
1821///
1822/// @return true iff @p l designates the Java language.
1823bool
1825{return l == translation_unit::LANG_Java;}
1826
1827/// Test if a language enumerator designates the Ada language.
1828///
1829/// @param l the language enumerator to consider.
1830///
1831/// @return true iff @p l designates the Ada language.
1832bool
1834{
1835 return (l == translation_unit::LANG_Ada83
1836 || l == translation_unit::LANG_Ada95
1837 || l == translation_unit::LANG_Ada2005
1838 || l == translation_unit::LANG_Ada2012);
1839}
1840
1841/// A deep comparison operator for pointers to translation units.
1842///
1843/// @param l the first translation unit to consider for the comparison.
1844///
1845/// @param r the second translation unit to consider for the comparison.
1846///
1847/// @return true if the two translation units are equal, false otherwise.
1848bool
1850{
1851 if (l.get() == r.get())
1852 return true;
1853
1854 if (!!l != !!r)
1855 return false;
1856
1857 return *l == *r;
1858}
1859
1860/// A deep inequality operator for pointers to translation units.
1861///
1862/// @param l the first translation unit to consider for the comparison.
1863///
1864/// @param r the second translation unit to consider for the comparison.
1865///
1866/// @return true iff the two translation units are different.
1867bool
1869{return !operator==(l, r);}
1870
1871// </translation_unit stuff>
1872
1873// <elf_symbol stuff>
1874struct elf_symbol::priv
1875{
1876 const environment& env_;
1877 size_t index_;
1878 size_t size_;
1879 string name_;
1880 elf_symbol::type type_;
1881 elf_symbol::binding binding_;
1882 elf_symbol::version version_;
1883 elf_symbol::visibility visibility_;
1884 bool is_defined_;
1885 // This flag below says if the symbol is a common elf symbol. In
1886 // relocatable files, a common symbol is a symbol defined in a
1887 // section of kind SHN_COMMON.
1888 //
1889 // Note that a symbol of kind STT_COMMON is also considered a common
1890 // symbol. Here is what the gABI says about STT_COMMON and
1891 // SHN_COMMON:
1892 //
1893 // Symbols with type STT_COMMON label uninitialized common
1894 // blocks. In relocatable objects, these symbols are not
1895 // allocated and must have the special section index SHN_COMMON
1896 // (see below). In shared objects and executables these symbols
1897 // must be allocated to some section in the defining object.
1898 //
1899 // In relocatable objects, symbols with type STT_COMMON are
1900 // treated just as other symbols with index SHN_COMMON. If the
1901 // link-editor allocates space for the SHN_COMMON symbol in an
1902 // output section of the object it is producing, it must
1903 // preserve the type of the output symbol as STT_COMMON.
1904 //
1905 // When the dynamic linker encounters a reference to a symbol
1906 // that resolves to a definition of type STT_COMMON, it may (but
1907 // is not required to) change its symbol resolution rules as
1908 // follows: instead of binding the reference to the first symbol
1909 // found with the given name, the dynamic linker searches for
1910 // the first symbol with that name with type other than
1911 // STT_COMMON. If no such symbol is found, it looks for the
1912 // STT_COMMON definition of that name that has the largest size.
1913 bool is_common_;
1914 bool is_in_ksymtab_;
1917 bool is_suppressed_;
1918 elf_symbol_wptr main_symbol_;
1919 elf_symbol_wptr next_alias_;
1920 elf_symbol_wptr next_common_instance_;
1921 string id_string_;
1922
1923 priv(const environment& e)
1924 : env_(e),
1925 index_(),
1926 size_(),
1927 type_(elf_symbol::NOTYPE_TYPE),
1928 binding_(elf_symbol::GLOBAL_BINDING),
1929 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1930 is_defined_(false),
1931 is_common_(false),
1932 is_in_ksymtab_(false),
1933 crc_(),
1934 namespace_(),
1935 is_suppressed_(false)
1936 {}
1937
1938 priv(const environment& e,
1939 size_t i,
1940 size_t s,
1941 const string& n,
1944 bool d,
1945 bool c,
1946 const elf_symbol::version& ve,
1948 bool is_in_ksymtab,
1951 bool is_suppressed)
1952 : env_(e),
1953 index_(i),
1954 size_(s),
1955 name_(n),
1956 type_(t),
1957 binding_(b),
1958 version_(ve),
1959 visibility_(vi),
1960 is_defined_(d),
1961 is_common_(c),
1962 is_in_ksymtab_(is_in_ksymtab),
1963 crc_(crc),
1964 namespace_(ns),
1965 is_suppressed_(is_suppressed)
1966 {
1967 if (!is_common_)
1968 is_common_ = type_ == COMMON_TYPE;
1969 }
1970}; // end struct elf_symbol::priv
1971
1972/// Constructor of the @ref elf_symbol type.
1973///
1974/// Note that this constructor is private, so client code cannot use
1975/// it to create instances of @ref elf_symbol. Rather, client code
1976/// should use the @ref elf_symbol::create() function to create
1977/// instances of @ref elf_symbol instead.
1978///
1979/// @param e the environment we are operating from.
1980///
1981/// @param i the index of the symbol in the (ELF) symbol table.
1982///
1983/// @param s the size of the symbol.
1984///
1985/// @param n the name of the symbol.
1986///
1987/// @param t the type of the symbol.
1988///
1989/// @param b the binding of the symbol.
1990///
1991/// @param d true if the symbol is defined, false otherwise.
1992///
1993/// @param c true if the symbol is a common symbol, false otherwise.
1994///
1995/// @param ve the version of the symbol.
1996///
1997/// @param vi the visibility of the symbol.
1998///
1999/// @param crc the CRC (modversions) value of Linux Kernel symbols
2000///
2001/// @param ns the namespace of Linux Kernel symbols, if any
2002elf_symbol::elf_symbol(const environment& e,
2003 size_t i,
2004 size_t s,
2005 const string& n,
2006 type t,
2007 binding b,
2008 bool d,
2009 bool c,
2010 const version& ve,
2011 visibility vi,
2012 bool is_in_ksymtab,
2015 bool is_suppressed)
2016 : priv_(new priv(e,
2017 i,
2018 s,
2019 n,
2020 t,
2021 b,
2022 d,
2023 c,
2024 ve,
2025 vi,
2026 is_in_ksymtab,
2027 crc,
2028 ns,
2029 is_suppressed))
2030{}
2031
2032/// Factory of instances of @ref elf_symbol.
2033///
2034/// This is the function to use to create instances of @ref elf_symbol.
2035///
2036/// @param e the environment we are operating from.
2037///
2038/// @param i the index of the symbol in the (ELF) symbol table.
2039///
2040/// @param s the size of the symbol.
2041///
2042/// @param n the name of the symbol.
2043///
2044/// @param t the type of the symbol.
2045///
2046/// @param b the binding of the symbol.
2047///
2048/// @param d true if the symbol is defined, false otherwise.
2049///
2050/// @param c true if the symbol is a common symbol.
2051///
2052/// @param ve the version of the symbol.
2053///
2054/// @param vi the visibility of the symbol.
2055///
2056/// @param crc the CRC (modversions) value of Linux Kernel symbols
2057///
2058/// @param ns the namespace of Linux Kernel symbols, if any
2059///
2060/// @return a (smart) pointer to a newly created instance of @ref
2061/// elf_symbol.
2064 size_t i,
2065 size_t s,
2066 const string& n,
2067 type t,
2068 binding b,
2069 bool d,
2070 bool c,
2071 const version& ve,
2072 visibility vi,
2073 bool is_in_ksymtab,
2076 bool is_suppressed)
2077{
2078 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
2079 is_in_ksymtab, crc, ns, is_suppressed));
2080 sym->priv_->main_symbol_ = sym;
2081 return sym;
2082}
2083
2084/// Test textual equality between two symbols.
2085///
2086/// Textual equality means that the aliases of the compared symbols
2087/// are not taken into account. Only the name, type, and version of
2088/// the symbols are compared.
2089///
2090/// @parm l the first ELF symbol to take into consideration in the
2091/// comparison.
2092///
2093/// @param r the second ELF symbol to take into consideration in the
2094/// comparison.
2095///
2096/// @param k a pointer to a bitfield that gives information about the
2097/// kind of changes there are between @p l and @p r. This one is set
2098/// iff it's non-null and if the function returns false.
2099///
2100/// @return true iff the two symbols are textually equal.
2101static bool
2102textually_equals(const elf_symbol&l, const elf_symbol&r,
2103 change_kind* k = nullptr)
2104{
2105 bool equals = (l.get_name() == r.get_name()
2106 && l.get_type() == r.get_type()
2107 && l.is_public() == r.is_public()
2108 && l.is_defined() == r.is_defined()
2110 && l.get_version() == r.get_version()
2111 && l.get_crc() == r.get_crc()
2112 && l.get_namespace() == r.get_namespace());
2113
2114 if (!equals)
2115 if (k)
2117
2118 if (equals && l.is_variable())
2119 // These are variable symbols. Let's compare their symbol size.
2120 // The symbol size in this case is the size taken by the storage
2121 // of the variable. If that size changes, then it's an ABI
2122 // change.
2123 if (l.get_size() != r.get_size())
2124 {
2125 equals = false;
2126 if (k)
2128 }
2129
2130 return equals;
2131}
2132
2133/// Getter of the environment used by the current instance of @ref
2134/// elf_symbol.
2135///
2136/// @return the enviroment used by the current instance of @ref elf_symbol.
2137const environment&
2139{return priv_->env_;}
2140
2141/// Getter for the index
2142///
2143/// @return the index of the symbol.
2144size_t
2146{return priv_->index_;}
2147
2148/// Setter for the index.
2149///
2150/// @param s the new index.
2151void
2153{priv_->index_ = s;}
2154
2155/// Getter for the name of the @ref elf_symbol.
2156///
2157/// @return a reference to the name of the @ref symbol.
2158const string&
2160{return priv_->name_;}
2161
2162/// Setter for the name of the current intance of @ref elf_symbol.
2163///
2164/// @param n the new name.
2165void
2166elf_symbol::set_name(const string& n)
2167{
2168 priv_->name_ = n;
2169 priv_->id_string_.clear();
2170}
2171
2172/// Getter for the type of the current instance of @ref elf_symbol.
2173///
2174/// @return the type of the elf symbol.
2177{return priv_->type_;}
2178
2179/// Setter for the type of the current instance of @ref elf_symbol.
2180///
2181/// @param t the new symbol type.
2182void
2184{priv_->type_ = t;}
2185
2186/// Getter of the size of the symbol.
2187///
2188/// @return the size of the symbol, in bytes.
2189size_t
2191{return priv_->size_;}
2192
2193/// Setter of the size of the symbol.
2194///
2195/// @param size the new size of the symbol, in bytes.
2196void
2198{priv_->size_ = size;}
2199
2200/// Getter for the binding of the current instance of @ref elf_symbol.
2201///
2202/// @return the binding of the symbol.
2205{return priv_->binding_;}
2206
2207/// Setter for the binding of the current instance of @ref elf_symbol.
2208///
2209/// @param b the new binding.
2210void
2212{priv_->binding_ = b;}
2213
2214/// Getter for the version of the current instanc of @ref elf_symbol.
2215///
2216/// @return the version of the elf symbol.
2219{return priv_->version_;}
2220
2221/// Setter for the version of the current instance of @ref elf_symbol.
2222///
2223/// @param v the new version of the elf symbol.
2224void
2226{
2227 priv_->version_ = v;
2228 priv_->id_string_.clear();
2229}
2230
2231/// Setter of the visibility of the current instance of @ref
2232/// elf_symbol.
2233///
2234/// @param v the new visibility of the elf symbol.
2235void
2237{priv_->visibility_ = v;}
2238
2239/// Getter of the visibility of the current instance of @ref
2240/// elf_symbol.
2241///
2242/// @return the visibility of the elf symbol.
2245{return priv_->visibility_;}
2246
2247/// Test if the current instance of @ref elf_symbol is defined or not.
2248///
2249/// @return true if the current instance of @ref elf_symbol is
2250/// defined, false otherwise.
2251bool
2253{return priv_->is_defined_;}
2254
2255/// Sets a flag saying if the current instance of @ref elf_symbol is
2256/// defined
2257///
2258/// @param b the new value of the flag.
2259void
2261{priv_->is_defined_ = d;}
2262
2263/// Test if the current instance of @ref elf_symbol is public or not.
2264///
2265/// This tests if the symbol is defined, has default or protected
2266///visibility, and either:
2267/// - has global binding
2268/// - has weak binding
2269/// - or has a GNU_UNIQUE binding.
2270///
2271/// return true if the current instance of @ref elf_symbol is public,
2272/// false otherwise.
2273bool
2275{
2276 return (is_defined()
2277 && (get_binding() == GLOBAL_BINDING
2278 || get_binding() == WEAK_BINDING
2279 || get_binding() == GNU_UNIQUE_BINDING)
2280 && (get_visibility() == DEFAULT_VISIBILITY
2281 || get_visibility() == PROTECTED_VISIBILITY));
2282}
2283
2284/// Test if the current instance of @ref elf_symbol is a function
2285/// symbol or not.
2286///
2287/// @return true if the current instance of @ref elf_symbol is a
2288/// function symbol, false otherwise.
2289bool
2291{return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2292
2293/// Test if the current instance of @ref elf_symbol is a variable
2294/// symbol or not.
2295///
2296/// @return true if the current instance of @ref elf_symbol is a
2297/// variable symbol, false otherwise.
2298bool
2300{
2301 return (get_type() == OBJECT_TYPE
2302 || get_type() == TLS_TYPE
2303 // It appears that undefined variables have NOTYPE type.
2304 || (get_type() == NOTYPE_TYPE
2305 && !is_defined()));
2306}
2307
2308/// Getter of the 'is-in-ksymtab' property.
2309///
2310/// @return true iff the current symbol is in the Linux Kernel
2311/// specific 'ksymtab' symbol table.
2312bool
2314{return priv_->is_in_ksymtab_;}
2315
2316/// Setter of the 'is-in-ksymtab' property.
2317///
2318/// @param is_in_ksymtab this is true iff the current symbol is in the
2319/// Linux Kernel specific 'ksymtab' symbol table.
2320void
2322{priv_->is_in_ksymtab_ = is_in_ksymtab;}
2323
2324/// Getter of the 'crc' property.
2325///
2326/// @return the CRC (modversions) value for Linux Kernel symbols, if any
2329{return priv_->crc_;}
2330
2331/// Setter of the 'crc' property.
2332///
2333/// @param crc the new CRC (modversions) value for Linux Kernel symbols
2334void
2336{priv_->crc_ = crc;}
2337
2338/// Getter of the 'namespace' property.
2339///
2340/// @return the namespace for Linux Kernel symbols, if any
2343{return priv_->namespace_;}
2344
2345/// Setter of the 'namespace' property.
2346///
2347/// @param ns the new namespace for Linux Kernel symbols, if any
2348void
2350{priv_->namespace_ = ns;}
2351
2352/// Getter for the 'is-suppressed' property.
2353///
2354/// @return true iff the current symbol has been suppressed by a
2355/// suppression specification that was provided in the context that
2356/// led to the creation of the corpus this ELF symbol belongs to.
2357bool
2359{return priv_->is_suppressed_;}
2360
2361/// Setter for the 'is-suppressed' property.
2362///
2363/// @param true iff the current symbol has been suppressed by a
2364/// suppression specification that was provided in the context that
2365/// led to the creation of the corpus this ELF symbol belongs to.
2366void
2368{priv_->is_suppressed_ = is_suppressed;}
2369
2370/// @name Elf symbol aliases
2371///
2372/// An alias A for an elf symbol S is a symbol that is defined at the
2373/// same address as S. S is chained to A through the
2374/// elf_symbol::get_next_alias() method.
2375///
2376/// When there are several aliases to a symbol, the main symbol is the
2377/// the first symbol found in the symbol table for a given address.
2378///
2379/// The alias chain is circular. That means if S is the main symbol
2380/// and A is the alias, S is chained to A and A
2381/// is chained back to the main symbol S. The last alias in an alias
2382///chain is always chained to the main symbol.
2383///
2384/// Thus, when looping over the aliases of an elf_symbol A, detecting
2385/// an alias that is equal to the main symbol should logically be a
2386/// loop exit condition.
2387///
2388/// Accessing and adding aliases for instances of elf_symbol is done
2389/// through the member functions below.
2390
2391/// @{
2392
2393/// Get the main symbol of an alias chain.
2394///
2395///@return the main symbol.
2396const elf_symbol_sptr
2398{return priv_->main_symbol_.lock();}
2399
2400/// Get the main symbol of an alias chain.
2401///
2402///@return the main symbol.
2405{return priv_->main_symbol_.lock();}
2406
2407/// Tests whether this symbol is the main symbol.
2408///
2409/// @return true iff this symbol is the main symbol.
2410bool
2412{return get_main_symbol().get() == this;}
2413
2414/// Get the next alias of the current symbol.
2415///
2416///@return the alias, or NULL if there is no alias.
2419{return priv_->next_alias_.lock();}
2420
2421
2422/// Check if the current elf_symbol has an alias.
2423///
2424///@return true iff the current elf_symbol has an alias.
2425bool
2427{return bool(get_next_alias());}
2428
2429/// Get the number of aliases to this elf symbol
2430///
2431/// @return the number of aliases to this elf symbol.
2432int
2434{
2435 int result = 0;
2436
2438 a && a.get() != get_main_symbol().get();
2439 a = a->get_next_alias())
2440 ++result;
2441
2442 return result;
2443}
2444
2445/// Add an alias to the current elf symbol.
2446///
2447/// @param alias the new alias. Note that this elf_symbol should *NOT*
2448/// have aliases prior to the invocation of this function.
2449void
2451{
2452 if (!alias)
2453 return;
2454
2455 ABG_ASSERT(!alias->has_aliases());
2457
2458 if (has_aliases())
2459 {
2460 elf_symbol_sptr last_alias;
2462 a && !a->is_main_symbol();
2463 a = a->get_next_alias())
2464 {
2465 if (a->get_next_alias()->is_main_symbol())
2466 {
2467 ABG_ASSERT(last_alias == 0);
2468 last_alias = a;
2469 }
2470 }
2471 ABG_ASSERT(last_alias);
2472
2473 last_alias->priv_->next_alias_ = alias;
2474 }
2475 else
2476 priv_->next_alias_ = alias;
2477
2478 alias->priv_->next_alias_ = get_main_symbol();
2479 alias->priv_->main_symbol_ = get_main_symbol();
2480}
2481
2482/// Update the main symbol for a group of aliased symbols
2483///
2484/// If after the construction of the symbols (in order of discovery), the
2485/// actual main symbol can be identified (e.g. as the symbol that actually is
2486/// defined in the code), this method offers a way of updating the main symbol
2487/// through one of the aliased symbols.
2488///
2489/// For that, locate the new main symbol by name and update all references to
2490/// the main symbol among the group of aliased symbols.
2491///
2492/// @param name the name of the main symbol
2493///
2494/// @return the new main elf_symbol
2496elf_symbol::update_main_symbol(const std::string& name)
2497{
2499 if (!has_aliases() || get_name() == name)
2500 return get_main_symbol();
2501
2502 // find the new main symbol
2503 elf_symbol_sptr new_main;
2504 // we've already checked this; check the rest of the aliases
2505 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2506 a = a->get_next_alias())
2507 if (a->get_name() == name)
2508 {
2509 new_main = a;
2510 break;
2511 }
2512
2513 if (!new_main)
2514 return get_main_symbol();
2515
2516 // now update all main symbol references
2517 priv_->main_symbol_ = new_main;
2518 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2519 a = a->get_next_alias())
2520 a->priv_->main_symbol_ = new_main;
2521
2522 return new_main;
2523}
2524
2525/// Return true if the symbol is a common one.
2526///
2527/// @return true iff the symbol is common.
2528bool
2530{return priv_->is_common_;}
2531
2532/// Return true if this common common symbol has other common instances.
2533///
2534/// A common instance of a given common symbol is another common
2535/// symbol with the same name. Those exist in relocatable files. The
2536/// linker normally allocates all the instances into a common block in
2537/// the final output file.
2538///
2539/// Note that the current object must be a common symbol, otherwise,
2540/// this function aborts.
2541///
2542/// @return true iff the current common symbol has other common
2543/// instances.
2544bool
2546{
2548 return bool(get_next_common_instance());
2549}
2550
2551/// Get the next common instance of the current common symbol.
2552///
2553/// A common instance of a given common symbol is another common
2554/// symbol with the same name. Those exist in relocatable files. The
2555/// linker normally allocates all the instances into a common block in
2556/// the final output file.
2557///
2558/// @return the next common instance, or nil if there is not any.
2561{return priv_->next_common_instance_.lock();}
2562
2563/// Add a common instance to the current common elf symbol.
2564///
2565/// Note that this symbol must be the main symbol. Being the main
2566/// symbol means being the first common symbol to appear in the symbol
2567/// table.
2568///
2569/// @param common the other common instance to add.
2570void
2572{
2573 if (!common)
2574 return;
2575
2576 ABG_ASSERT(!common->has_other_common_instances());
2579
2581 {
2582 elf_symbol_sptr last_common_instance;
2584 c && (c.get() != get_main_symbol().get());
2585 c = c->get_next_common_instance())
2586 {
2587 if (c->get_next_common_instance().get() == get_main_symbol().get())
2588 {
2589 ABG_ASSERT(last_common_instance == 0);
2590 last_common_instance = c;
2591 }
2592 }
2593 ABG_ASSERT(last_common_instance);
2594
2595 last_common_instance->priv_->next_common_instance_ = common;
2596 }
2597 else
2598 priv_->next_common_instance_ = common;
2599
2600 common->priv_->next_common_instance_ = get_main_symbol();
2601 common->priv_->main_symbol_ = get_main_symbol();
2602}
2603
2604/// Get a string that is representative of a given elf_symbol.
2605///
2606/// If the symbol has a version, then the ID string is the
2607/// concatenation of the name of the symbol, the '@' character, and
2608/// the version of the symbol. If the version is the default version
2609/// of the symbol then the '@' character is replaced by a "@@" string.
2610///
2611/// Otherwise, if the symbol does not have any version, this function
2612/// returns the name of the symbol.
2613///
2614/// @return a the ID string.
2615const string&
2617{
2618 if (priv_->id_string_.empty())
2619 {
2620 string s = get_name ();
2621
2622 if (!get_version().is_empty())
2623 {
2624 if (get_version().is_default())
2625 s += "@@";
2626 else
2627 s += "@";
2628 s += get_version().str();
2629 }
2630 priv_->id_string_ = s;
2631 }
2632
2633 return priv_->id_string_;
2634}
2635
2636/// From the aliases of the current symbol, lookup one with a given name.
2637///
2638/// @param name the name of symbol alias we are looking for.
2639///
2640/// @return the symbol alias that has the name @p name, or nil if none
2641/// has been found.
2643elf_symbol::get_alias_from_name(const string& name) const
2644{
2645 if (name == get_name())
2646 return elf_symbol_sptr(priv_->main_symbol_);
2647
2649 a && a.get() != get_main_symbol().get();
2650 a = a->get_next_alias())
2651 if (a->get_name() == name)
2652 return a;
2653
2654 return elf_symbol_sptr();
2655}
2656
2657/// In the list of aliases of a given elf symbol, get the alias that
2658/// equals this current symbol.
2659///
2660/// @param other the elf symbol to get the potential aliases from.
2661///
2662/// @return the alias of @p other that texually equals the current
2663/// symbol, or nil if no alias textually equals the current symbol.
2666{
2667 for (elf_symbol_sptr a = other.get_next_alias();
2668 a && a.get() != a->get_main_symbol().get();
2669 a = a->get_next_alias())
2670 if (textually_equals(*this, *a))
2671 return a;
2672 return elf_symbol_sptr();
2673}
2674
2675/// Return a comma separated list of the id of the current symbol as
2676/// well as the id string of its aliases.
2677///
2678/// @param syms a map of all the symbols of the corpus the current
2679/// symbol belongs to.
2680///
2681/// @param include_symbol_itself if set to true, then the name of the
2682/// current symbol is included in the list of alias names that is emitted.
2683///
2684/// @return the string.
2685string
2687 bool include_symbol_itself) const
2688{
2689 string result;
2690
2691 if (include_symbol_itself)
2692 result = get_id_string();
2693
2694 vector<elf_symbol_sptr> aliases;
2695 compute_aliases_for_elf_symbol(*this, syms, aliases);
2696 if (!aliases.empty() && include_symbol_itself)
2697 result += ", ";
2698
2699 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2700 i != aliases.end();
2701 ++i)
2702 {
2703 if (i != aliases.begin())
2704 result += ", ";
2705 result += (*i)->get_id_string();
2706 }
2707 return result;
2708}
2709
2710/// Return a comma separated list of the id of the current symbol as
2711/// well as the id string of its aliases.
2712///
2713/// @param include_symbol_itself if set to true, then the name of the
2714/// current symbol is included in the list of alias names that is emitted.
2715///
2716/// @return the string.
2717string
2718elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2719{
2720 vector<elf_symbol_sptr> aliases;
2721 if (include_symbol_itself)
2722 aliases.push_back(get_main_symbol());
2723
2725 a && a.get() != get_main_symbol().get();
2726 a = a->get_next_alias())
2727 aliases.push_back(a);
2728
2729 string result;
2730 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2731 i != aliases.end();
2732 ++i)
2733 {
2734 if (i != aliases.begin())
2735 result += ", ";
2736 result += (*i)->get_id_string();
2737 }
2738
2739 return result;
2740}
2741
2742/// Given the ID of a symbol, get the name and the version of said
2743/// symbol.
2744///
2745/// @param id the symbol ID to consider.
2746///
2747/// @param name the symbol name extracted from the ID. This is set
2748/// only if the function returned true.
2749///
2750/// @param ver the symbol version extracted from the ID.
2751bool
2753 string& name,
2754 string& ver)
2755{
2756 name.clear(), ver.clear();
2757
2758 string::size_type i = id.find('@');
2759 if (i == string::npos)
2760 {
2761 name = id;
2762 return true;
2763 }
2764
2765 name = id.substr(0, i);
2766 ++i;
2767
2768 if (i >= id.size())
2769 return true;
2770
2771 string::size_type j = id.find('@', i);
2772 if (j == string::npos)
2773 j = i;
2774 else
2775 ++j;
2776
2777 if (j >= id.size())
2778 {
2779 ver = "";
2780 return true;
2781 }
2782
2783 ver = id.substr(j);
2784 return true;
2785}
2786
2787///@}
2788
2789/// Test if two main symbols are textually equal, or, if they have
2790/// aliases that are textually equal.
2791///
2792/// @param other the symbol to compare against.
2793///
2794/// @return true iff the current instance of elf symbol equals the @p
2795/// other.
2796bool
2798{
2799 bool are_equal = textually_equals(*this, other);
2800 if (!are_equal)
2801 are_equal = bool(get_alias_which_equals(other));
2802 return are_equal;
2803}
2804
2805/// Test if the current symbol aliases another one.
2806///
2807/// @param o the other symbol to test against.
2808///
2809/// @return true iff the current symbol aliases @p o.
2810bool
2812{
2813 if (*this == o)
2814 return true;
2815
2816 if (get_main_symbol() == o.get_main_symbol())
2817 return true;
2818
2820 a && !a->is_main_symbol();
2821 a = a->get_next_alias())
2822 {
2823 if (o == *a)
2824 return true;
2825 }
2826 return false;
2827}
2828
2829/// Equality operator for smart pointers to elf_symbol.
2830///
2831/// @param lhs the first elf symbol to consider.
2832///
2833/// @param rhs the second elf symbol to consider.
2834///
2835/// @return true iff @p lhs equals @p rhs.
2836bool
2838{
2839 if (!!lhs != !!rhs)
2840 return false;
2841
2842 if (!lhs)
2843 return true;
2844
2845 return *lhs == *rhs;
2846}
2847
2848/// Inequality operator for smart pointers to elf_symbol.
2849///
2850/// @param lhs the first elf symbol to consider.
2851///
2852/// @param rhs the second elf symbol to consider.
2853///
2854/// @return true iff @p lhs is different from @p rhs.
2855bool
2857{return !operator==(lhs, rhs);}
2858
2859/// Test if two symbols alias.
2860///
2861/// @param s1 the first symbol to consider.
2862///
2863/// @param s2 the second symbol to consider.
2864///
2865/// @return true if @p s1 aliases @p s2.
2866bool
2868{return s1.does_alias(s2) || s2.does_alias(s1);}
2869
2870void
2871compute_aliases_for_elf_symbol(const elf_symbol& sym,
2872 const string_elf_symbols_map_type& symtab,
2873 vector<elf_symbol_sptr>& aliases)
2874{
2875
2876 if (elf_symbol_sptr a = sym.get_next_alias())
2877 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2878 aliases.push_back(a);
2879 else
2880 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2881 i != symtab.end();
2882 ++i)
2883 for (elf_symbols::const_iterator j = i->second.begin();
2884 j != i->second.end();
2885 ++j)
2886 {
2887 if (**j == sym)
2888 for (elf_symbol_sptr s = (*j)->get_next_alias();
2889 s && !s->is_main_symbol();
2890 s = s->get_next_alias())
2891 aliases.push_back(s);
2892 else
2893 for (elf_symbol_sptr s = (*j)->get_next_alias();
2894 s && !s->is_main_symbol();
2895 s = s->get_next_alias())
2896 if (*s == sym)
2897 aliases.push_back(*j);
2898 }
2899}
2900
2901/// Test if two symbols alias.
2902///
2903/// @param s1 the first symbol to consider.
2904///
2905/// @param s2 the second symbol to consider.
2906///
2907/// @return true if @p s1 aliases @p s2.
2908bool
2910{
2911 if (!!s1 != !!s2)
2912 return false;
2913 if (s1 == s2)
2914 return true;
2915 return elf_symbols_alias(*s1, *s2);
2916}
2917
2918/// Test if two symbols alias.
2919///
2920/// @param s1 the first symbol to consider.
2921///
2922/// @param s2 the second symbol to consider.
2923///
2924/// @return true if @p s1 aliases @p s2.
2925bool
2927{return elf_symbols_alias(s1.get(), s2.get());}
2928
2929/// Serialize an instance of @ref symbol_type and stream it to a given
2930/// output stream.
2931///
2932/// @param o the output stream to serialize the symbole type to.
2933///
2934/// @param t the symbol type to serialize.
2935std::ostream&
2936operator<<(std::ostream& o, elf_symbol::type t)
2937{
2938 string repr;
2939
2940 switch (t)
2941 {
2942 case elf_symbol::NOTYPE_TYPE:
2943 repr = "unspecified symbol type";
2944 break;
2945 case elf_symbol::OBJECT_TYPE:
2946 repr = "variable symbol type";
2947 break;
2948 case elf_symbol::FUNC_TYPE:
2949 repr = "function symbol type";
2950 break;
2951 case elf_symbol::SECTION_TYPE:
2952 repr = "section symbol type";
2953 break;
2954 case elf_symbol::FILE_TYPE:
2955 repr = "file symbol type";
2956 break;
2957 case elf_symbol::COMMON_TYPE:
2958 repr = "common data object symbol type";
2959 break;
2960 case elf_symbol::TLS_TYPE:
2961 repr = "thread local data object symbol type";
2962 break;
2963 case elf_symbol::GNU_IFUNC_TYPE:
2964 repr = "indirect function symbol type";
2965 break;
2966 default:
2967 {
2968 std::ostringstream s;
2969 s << "unknown symbol type (" << (char)t << ')';
2970 repr = s.str();
2971 }
2972 break;
2973 }
2974
2975 o << repr;
2976 return o;
2977}
2978
2979/// Serialize an instance of @ref symbol_binding and stream it to a
2980/// given output stream.
2981///
2982/// @param o the output stream to serialize the symbole type to.
2983///
2984/// @param b the symbol binding to serialize.
2985std::ostream&
2986operator<<(std::ostream& o, elf_symbol::binding b)
2987{
2988 string repr;
2989
2990 switch (b)
2991 {
2992 case elf_symbol::LOCAL_BINDING:
2993 repr = "local binding";
2994 break;
2995 case elf_symbol::GLOBAL_BINDING:
2996 repr = "global binding";
2997 break;
2998 case elf_symbol::WEAK_BINDING:
2999 repr = "weak binding";
3000 break;
3001 case elf_symbol::GNU_UNIQUE_BINDING:
3002 repr = "GNU unique binding";
3003 break;
3004 default:
3005 {
3006 std::ostringstream s;
3007 s << "unknown binding (" << (unsigned char) b << ")";
3008 repr = s.str();
3009 }
3010 break;
3011 }
3012
3013 o << repr;
3014 return o;
3015}
3016
3017/// Serialize an instance of @ref elf_symbol::visibility and stream it
3018/// to a given output stream.
3019///
3020/// @param o the output stream to serialize the symbole type to.
3021///
3022/// @param v the symbol visibility to serialize.
3023std::ostream&
3024operator<<(std::ostream& o, elf_symbol::visibility v)
3025{
3026 string repr;
3027
3028 switch (v)
3029 {
3030 case elf_symbol::DEFAULT_VISIBILITY:
3031 repr = "default visibility";
3032 break;
3033 case elf_symbol::PROTECTED_VISIBILITY:
3034 repr = "protected visibility";
3035 break;
3036 case elf_symbol::HIDDEN_VISIBILITY:
3037 repr = "hidden visibility";
3038 break;
3039 case elf_symbol::INTERNAL_VISIBILITY:
3040 repr = "internal visibility";
3041 break;
3042 default:
3043 {
3044 std::ostringstream s;
3045 s << "unknown visibility (" << (unsigned char) v << ")";
3046 repr = s.str();
3047 }
3048 break;
3049 }
3050
3051 o << repr;
3052 return o;
3053}
3054
3055/// Convert a string representing a symbol type into an
3056/// elf_symbol::type.
3057///
3058///@param s the string to convert.
3059///
3060///@param t the resulting elf_symbol::type.
3061///
3062/// @return true iff the conversion completed successfully.
3063bool
3065{
3066 if (s == "no-type")
3067 t = elf_symbol::NOTYPE_TYPE;
3068 else if (s == "object-type")
3069 t = elf_symbol::OBJECT_TYPE;
3070 else if (s == "func-type")
3071 t = elf_symbol::FUNC_TYPE;
3072 else if (s == "section-type")
3073 t = elf_symbol::SECTION_TYPE;
3074 else if (s == "file-type")
3075 t = elf_symbol::FILE_TYPE;
3076 else if (s == "common-type")
3077 t = elf_symbol::COMMON_TYPE;
3078 else if (s == "tls-type")
3079 t = elf_symbol::TLS_TYPE;
3080 else if (s == "gnu-ifunc-type")
3081 t = elf_symbol::GNU_IFUNC_TYPE;
3082 else
3083 return false;
3084
3085 return true;
3086}
3087
3088/// Convert a string representing a an elf symbol binding into an
3089/// elf_symbol::binding.
3090///
3091/// @param s the string to convert.
3092///
3093/// @param b the resulting elf_symbol::binding.
3094///
3095/// @return true iff the conversion completed successfully.
3096bool
3098{
3099 if (s == "local-binding")
3100 b = elf_symbol::LOCAL_BINDING;
3101 else if (s == "global-binding")
3102 b = elf_symbol::GLOBAL_BINDING;
3103 else if (s == "weak-binding")
3104 b = elf_symbol::WEAK_BINDING;
3105 else if (s == "gnu-unique-binding")
3106 b = elf_symbol::GNU_UNIQUE_BINDING;
3107 else
3108 return false;
3109
3110 return true;
3111}
3112
3113/// Convert a string representing a an elf symbol visibility into an
3114/// elf_symbol::visibility.
3115///
3116/// @param s the string to convert.
3117///
3118/// @param b the resulting elf_symbol::visibility.
3119///
3120/// @return true iff the conversion completed successfully.
3121bool
3123{
3124 if (s == "default-visibility")
3125 v = elf_symbol::DEFAULT_VISIBILITY;
3126 else if (s == "protected-visibility")
3127 v = elf_symbol::PROTECTED_VISIBILITY;
3128 else if (s == "hidden-visibility")
3129 v = elf_symbol::HIDDEN_VISIBILITY;
3130 else if (s == "internal-visibility")
3131 v = elf_symbol::INTERNAL_VISIBILITY;
3132 else
3133 return false;
3134
3135 return true;
3136}
3137
3138/// Test if the type of an ELF symbol denotes a function symbol.
3139///
3140/// @param t the type of the ELF symbol.
3141///
3142/// @return true iff elf symbol type @p t denotes a function symbol
3143/// type.
3144bool
3146{return t == elf_symbol::FUNC_TYPE;}
3147
3148/// Test if the type of an ELF symbol denotes a function symbol.
3149///
3150/// @param t the type of the ELF symbol.
3151///
3152/// @return true iff elf symbol type @p t denotes a function symbol
3153/// type.
3154bool
3156{return t == elf_symbol::OBJECT_TYPE;}
3157
3158// <elf_symbol::version stuff>
3159
3160struct elf_symbol::version::priv
3161{
3162 string version_;
3163 bool is_default_;
3164
3165 priv()
3166 : is_default_(false)
3167 {}
3168
3169 priv(const string& v,
3170 bool d)
3171 : version_(v),
3172 is_default_(d)
3173 {}
3174}; // end struct elf_symbol::version::priv
3175
3176elf_symbol::version::version()
3177 : priv_(new priv)
3178{}
3179
3180/// @param v the name of the version.
3181///
3182/// @param is_default true if this is a default version.
3183elf_symbol::version::version(const string& v,
3184 bool is_default)
3185 : priv_(new priv(v, is_default))
3186{}
3187
3188elf_symbol::version::version(const elf_symbol::version& v)
3189 : priv_(new priv(v.str(), v.is_default()))
3190{
3191}
3192
3193elf_symbol::version::~version() = default;
3194
3195/// Cast the version_type into a string that is its name.
3196///
3197/// @return the name of the version.
3198elf_symbol::version::operator const string&() const
3199{return priv_->version_;}
3200
3201/// Getter for the version name.
3202///
3203/// @return the version name.
3204const string&
3206{return priv_->version_;}
3207
3208/// Setter for the version name.
3209///
3210/// @param s the version name.
3211void
3213{priv_->version_ = s;}
3214
3215/// Getter for the 'is_default' property of the version.
3216///
3217/// @return true iff this is a default version.
3218bool
3220{return priv_->is_default_;}
3221
3222/// Setter for the 'is_default' property of the version.
3223///
3224/// @param f true if this is the default version.
3225void
3227{priv_->is_default_ = f;}
3228
3229bool
3230elf_symbol::version::is_empty() const
3231{return str().empty();}
3232
3233/// Compares the current version against another one.
3234///
3235/// @param o the other version to compare the current one to.
3236///
3237/// @return true iff the current version equals @p o.
3238bool
3240{return str() == o.str();}
3241
3242/// Inequality operator.
3243///
3244/// @param o the version to compare against the current one.
3245///
3246/// @return true iff both versions are different.
3247bool
3249{return !operator==(o);}
3250
3251/// Assign a version to the current one.
3252///
3253/// @param o the other version to assign to this one.
3254///
3255/// @return a reference to the assigned version.
3258{
3259 str(o.str());
3260 is_default(o.is_default());
3261 return *this;
3262}
3263
3264// </elf_symbol::version stuff>
3265
3266// </elf_symbol stuff>
3267
3268// <class dm_context_rel stuff>
3269struct dm_context_rel::priv
3270{
3271 bool is_laid_out_;
3272 size_t offset_in_bits_;
3273 var_decl* anonymous_data_member_;
3274
3275 priv(bool is_static = false)
3276 : is_laid_out_(!is_static),
3277 offset_in_bits_(0),
3278 anonymous_data_member_()
3279 {}
3280
3281 priv(bool is_laid_out, size_t offset_in_bits)
3282 : is_laid_out_(is_laid_out),
3283 offset_in_bits_(offset_in_bits),
3284 anonymous_data_member_()
3285 {}
3286}; //end struct dm_context_rel::priv
3287
3288dm_context_rel::dm_context_rel()
3289 : context_rel(),
3290 priv_(new priv)
3291{}
3292
3293dm_context_rel::dm_context_rel(scope_decl* s,
3294 bool is_laid_out,
3295 size_t offset_in_bits,
3297 bool is_static)
3298 : context_rel(s, a, is_static),
3299 priv_(new priv(is_laid_out, offset_in_bits))
3300{}
3301
3302dm_context_rel::dm_context_rel(scope_decl* s)
3303 : context_rel(s),
3304 priv_(new priv())
3305{}
3306
3307bool
3308dm_context_rel::get_is_laid_out() const
3309{return priv_->is_laid_out_;}
3310
3311void
3312dm_context_rel::set_is_laid_out(bool f)
3313{priv_->is_laid_out_ = f;}
3314
3315size_t
3316dm_context_rel::get_offset_in_bits() const
3317{return priv_->offset_in_bits_;}
3318
3319void
3320dm_context_rel::set_offset_in_bits(size_t o)
3321{priv_->offset_in_bits_ = o;}
3322
3323bool
3324dm_context_rel::operator==(const dm_context_rel& o) const
3325{
3326 if (!context_rel::operator==(o))
3327 return false;
3328
3329 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3330 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3331}
3332
3333bool
3334dm_context_rel::operator!=(const dm_context_rel& o) const
3335{return !operator==(o);}
3336
3337/// Return a non-nil value if this data member context relationship
3338/// has an anonymous data member. That means, if the data member this
3339/// relation belongs to is part of an anonymous data member.
3340///
3341/// @return the containing anonymous data member of this data member
3342/// relationship. Nil if there is none.
3343const var_decl*
3345{return priv_->anonymous_data_member_;}
3346
3347/// Set the containing anonymous data member of this data member
3348/// context relationship. That means that the data member this
3349/// relation belongs to is part of an anonymous data member.
3350///
3351/// @param anon_dm the containing anonymous data member of this data
3352/// member relationship. Nil if there is none.
3353void
3355{priv_->anonymous_data_member_ = anon_dm;}
3356
3357dm_context_rel::~dm_context_rel()
3358{}
3359// </class dm_context_rel stuff>
3360
3361// <environment stuff>
3362
3363/// Convenience typedef for a map of interned_string -> bool.
3364typedef unordered_map<interned_string,
3366
3367
3368/// Default constructor of the @ref environment type.
3370 :priv_(new priv)
3371{}
3372
3373/// Destructor for the @ref environment type.
3375{}
3376
3377/// Getter the map of canonical types.
3378///
3379/// @return the map of canonical types. The key of the map is the
3380/// hash of the canonical type and its value if the canonical type.
3383{return priv_->canonical_types_;}
3384
3385/// Getter the map of canonical types.
3386///
3387/// @return the map of canonical types. The key of the map is the
3388/// hash of the canonical type and its value if the canonical type.
3391{return const_cast<environment*>(this)->get_canonical_types_map();}
3392
3393/// Helper to detect if a type is either a reference, a pointer, or a
3394/// qualified type.
3395bool
3397{
3398 if (is_pointer_type(t)
3399 || is_reference_type(t)
3400 || is_qualified_type(t))
3401 return true;
3402 return false;
3403}
3404
3405/// Compare decls using their locations.
3406///
3407/// @param f the first decl to compare.
3408///
3409/// @param s the second decl to compare.
3410///
3411/// @return true if @p f compares less than @p s.
3412bool
3414 const decl_base *s)
3415{
3416 // If a decl has artificial location, then use that one over the
3417 // natural one.
3420
3421 ABG_ASSERT(fl.get_value() && sl.get_value());
3422 if (fl.get_is_artificial() == sl.get_is_artificial())
3423 {
3424 // The locations of the two artfifacts have the same
3425 // artificial-ness so they can be compared.
3426 string p1, p2;
3427 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3428 fl.expand(p1, l1, c1);
3429 sl.expand(p2, l2, c2);
3430 if (p1 != p2)
3431 return p1 < p2;
3432 if (l1 != l2)
3433 return l1 < l2;
3434 if (c1 != c2)
3435 return c1 < c2;
3436 }
3437
3438 return (get_pretty_representation(f, /*internal=*/false)
3439 < get_pretty_representation(s, /*internal=*/false));
3440}
3441
3442/// Sort types in a hopefully stable manner.
3443///
3444/// @param types a set of types with canonical types to sort.
3445///
3446/// @param result the resulting sorted vector.
3447void
3449 vector<type_base_sptr>& result)
3450{
3451 for (auto t: types)
3452 result.push_back(t);
3453
3454 type_topo_comp comp;
3455 std::stable_sort(result.begin(), result.end(), comp);
3456}
3457
3458/// Get the unique @ref type_decl that represents a "void" type for
3459/// the current environment. This node must be the only one
3460/// representing a void type in the system.
3461///
3462/// Note that upon first use of this IR node (by the relevant
3463/// front-end, for instance) it must be added to a scope using e.g,
3464/// the @ref add_decl_to_scope() function.
3465///
3466/// @return the @ref type_decl that represents a "void" type.
3467const type_base_sptr&
3469{
3470 if (!priv_->void_type_)
3471 priv_->void_type_.reset(new type_decl(*this,
3472 intern("void"),
3473 0, 0, location()));
3474 return priv_->void_type_;
3475}
3476
3477/// Getter of the "pointer-to-void" IR node that is shared across the
3478/// ABI corpus. This node must be the only one representing a void
3479/// pointer type in the system.
3480///
3481/// Note that upon first use of this IR node (by the relevant
3482/// front-end, for instance) it must be added to a scope using e.g,
3483/// the @ref add_decl_to_scope() function.
3484///
3485/// @return the "pointer-to-void" IR node.
3486const type_base_sptr&
3488{
3489 if (!priv_->void_pointer_type_)
3490 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3491 0, 0, location()));
3492 return priv_->void_pointer_type_;
3493}
3494
3495/// Get a @ref type_decl instance that represents a the type of a
3496/// variadic function parameter. This node must be the only one
3497/// representing a variadic parameter type in the system.
3498///
3499/// Note that upon first use of this IR node (by the relevant
3500/// front-end, for instance) it must be added to a scope using e.g,
3501/// the @ref add_decl_to_scope() function.
3502///
3503/// @return the Get a @ref type_decl instance that represents a the
3504/// type of a variadic function parameter.
3505const type_base_sptr&
3507{
3508 if (!priv_->variadic_marker_type_)
3509 priv_->variadic_marker_type_.
3511 0, 0, location()));
3512 return priv_->variadic_marker_type_;
3513}
3514
3515/// Getter of the name of the variadic parameter type.
3516///
3517/// @return the name of the variadic parameter type.
3518string&
3520{
3521 static string variadic_parameter_type_name = "variadic parameter type";
3522 return variadic_parameter_type_name;
3523}
3524
3525/// Test if the canonicalization of types created out of the current
3526/// environment is done.
3527///
3528/// @return true iff the canonicalization of types created out of the current
3529/// environment is done.
3530bool
3532{return priv_->canonicalization_is_done_;}
3533
3534/// Set a flag saying if the canonicalization of types created out of
3535/// the current environment is done or not.
3536///
3537/// Note that this function must only be called by internal code of
3538/// the library that creates ABI artifacts (e.g, read an abi corpus
3539/// from elf or from our own xml format and creates representations of
3540/// types out of it) and thus needs to canonicalize types to speed-up
3541/// further type comparison.
3542///
3543/// @param f the new value of the flag.
3544void
3546{
3547 priv_->canonicalization_is_done_ = f;
3548 if (priv_->canonicalization_is_done_)
3550}
3551
3552/// Getter of a flag saying if the canonicalization process has
3553/// started or not.
3554///
3555/// @return the flag saying if the canonicalization process has
3556/// started or not.
3557bool
3559{return priv_->canonicalization_started_;}
3560
3561/// Setter of a flag saying if the canonicalization process has
3562/// started or not.
3563///
3564/// @param f the new value of the flag saying if the canonicalization
3565/// process has started or not.
3566void
3568{priv_->canonicalization_started_ = f;}
3569
3570/// Getter of the "decl-only-class-equals-definition" flag.
3571///
3572/// Usually, a declaration-only class named 'struct foo' compares
3573/// equal to any class definition named "struct foo'. This is at
3574/// least true for C++.
3575///
3576/// In C, though, because there can be multiple definitions of 'struct
3577/// foo' in the binary, a declaration-only "struct foo" might be
3578/// considered to *NOT* resolve to any of the struct foo defined. In
3579/// that case, the declaration-only "struct foo" is considered
3580/// different from the definitions.
3581///
3582/// This flag controls the behaviour of the comparison of an
3583/// unresolved decl-only class against a definition of the same name.
3584///
3585/// If set to false, the the declaration equals the definition. If
3586/// set to false, then the decalration is considered different from
3587/// the declaration.
3588///
3589/// @return the value of the "decl-only-class-equals-definition" flag.
3590bool
3592{return priv_->decl_only_class_equals_definition_;}
3593
3594/// Setter of the "decl-only-class-equals-definition" flag.
3595///
3596/// Usually, a declaration-only class named 'struct foo' compares
3597/// equal to any class definition named "struct foo'. This is at
3598/// least true for C++.
3599///
3600/// In C, though, because there can be multiple definitions of 'struct
3601/// foo' in the binary, a declaration-only "struct foo" might be
3602/// considered to *NOT* resolve to any of the struct foo defined. In
3603/// that case, the declaration-only "struct foo" is considered
3604/// different from the definitions.
3605///
3606/// This flag controls the behaviour of the comparison of an
3607/// unresolved decl-only class against a definition of the same name.
3608///
3609/// If set to false, the the declaration equals the definition. If
3610/// set to false, then the decalration is considered different from
3611/// the declaration.
3612///
3613/// @param the new value of the "decl-only-class-equals-definition"
3614/// flag.
3615void
3617{priv_->decl_only_class_equals_definition_ = f;}
3618
3619/// Test if a given type is a void type as defined in the current
3620/// environment.
3621///
3622/// @param t the type to consider.
3623///
3624/// @return true iff @p t is a void type as defined in the current
3625/// environment.
3626bool
3627environment::is_void_type(const type_base_sptr& t) const
3628{
3629 if (!t)
3630 return false;
3631 return is_void_type(t.get());
3632}
3633
3634/// Test if a given type is a void type as defined in the current
3635/// environment.
3636///
3637/// @param t the type to consider.
3638///
3639/// @return true iff @p t is a void type as defined in the current
3640/// environment.
3641bool
3643{
3644 if (!t)
3645 return false;
3646 return (t == get_void_type().get()
3647 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3648}
3649
3650/// Test if a given type is the same as the void pointer type of the
3651/// environment.
3652///
3653/// @param t the IR type to test.
3654///
3655/// @return true iff @p t is the void pointer returned by
3656/// environment::get_void_pointer_type().
3657bool
3658environment::is_void_pointer_type(const type_base_sptr& t) const
3659{
3660 if (!t)
3661 return false;
3662
3663 return t.get() == get_void_pointer_type().get();
3664}
3665
3666/// Test if a given type is the same as the void pointer type of the
3667/// environment.
3668///
3669/// @param t the IR type to test.
3670///
3671/// @return true iff @p t is the void pointer returned by
3672/// environment::get_void_pointer_type().
3673bool
3675{
3676 if (!t)
3677 return false;
3678
3679 return t == get_void_pointer_type().get();
3680}
3681
3682/// Test if a type is a variadic parameter type as defined in the
3683/// current environment.
3684///
3685/// @param t the type to consider.
3686///
3687/// @return true iff @p t is a variadic parameter type as defined in
3688/// the current environment.
3689bool
3691{
3692 if (!t)
3693 return false;
3694 return t == get_variadic_parameter_type().get();
3695}
3696
3697/// Test if a type is a variadic parameter type as defined in the
3698/// current environment.
3699///
3700/// @param t the type to consider.
3701///
3702/// @return true iff @p t is a variadic parameter type as defined in
3703/// the current environment.
3704bool
3705environment::is_variadic_parameter_type(const type_base_sptr& t) const
3706{return is_variadic_parameter_type(t.get());}
3707
3708/// Do intern a string.
3709///
3710/// If a value of this string already exists in the interned string
3711/// pool of the current environment, then this function returns a new
3712/// interned_string pointing to that already existing string.
3713/// Otherwise, a new string is created, stored in the interned string
3714/// pool and a new interned_string instance is created to point to
3715/// that new intrerned string, and it's return.
3716///
3717/// @param s the value of the string to intern.
3718///
3719/// @return the interned string.
3721environment::intern(const string& s) const
3722{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3723
3724/// Getter of the general configuration object.
3725///
3726/// @return the configuration object.
3727const config&
3729{return priv_->config_;}
3730
3731/// Getter for a property that says if the user actually did set the
3732/// analyze_exported_interfaces_only() property. If not, it means
3733/// the default behaviour prevails.
3734///
3735/// @return tru iff the user did set the
3736/// analyze_exported_interfaces_only() property.
3737bool
3739{return priv_->analyze_exported_interfaces_only_.has_value();}
3740
3741/// Setter for the property that controls if we are to restrict the
3742/// analysis to the types that are only reachable from the exported
3743/// interfaces only, or if the set of types should be more broad than
3744/// that. Typically, we'd restrict the analysis to types reachable
3745/// from exported interfaces only (stricto sensu, that would really be
3746/// only the types that are part of the ABI of well designed
3747/// libraries) for performance reasons.
3748///
3749/// @param f the value of the flag.
3750void
3752{priv_->analyze_exported_interfaces_only_ = f;}
3753
3754/// Getter for the property that controls if we are to restrict the
3755/// analysis to the types that are only reachable from the exported
3756/// interfaces only, or if the set of types should be more broad than
3757/// that. Typically, we'd restrict the analysis to types reachable
3758/// from exported interfaces only (stricto sensu, that would really be
3759/// only the types that are part of the ABI of well designed
3760/// libraries) for performance reasons.
3761///
3762/// @param f the value of the flag.
3763bool
3765{return priv_->analyze_exported_interfaces_only_.value_or(false);}
3766
3767#ifdef WITH_DEBUG_SELF_COMPARISON
3768/// Setter of the corpus of the input corpus of the self comparison
3769/// that takes place when doing "abidw --debug-abidiff <binary>".
3770///
3771/// The first invocation of this function sets the first corpus of the
3772/// self comparison. The second invocation of this very same function
3773/// sets the second corpus of the self comparison. That second corpus
3774/// is supposed to come from the abixml serialization of the first
3775/// corpus.
3776///
3777/// @param c the corpus of the input binary or the corpus of the
3778/// abixml serialization of the initial binary input.
3779void
3780environment::set_self_comparison_debug_input(const corpus_sptr& c)
3781{
3782 self_comparison_debug_is_on(true);
3783 if (priv_->first_self_comparison_corpus_.expired())
3784 priv_->first_self_comparison_corpus_ = c;
3785 else if (priv_->second_self_comparison_corpus_.expired()
3786 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3787 priv_->second_self_comparison_corpus_ = c;
3788}
3789
3790/// Getter for the corpora of the input binary and the intermediate
3791/// abixml of the self comparison that takes place when doing
3792/// 'abidw --debug-abidiff <binary>'.
3793///
3794/// @param first_corpus output parameter that is set to the corpus of
3795/// the input corpus.
3796///
3797/// @param second_corpus output parameter that is set to the corpus of
3798/// the second corpus.
3799void
3800environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3801 corpus_sptr& second_corpus)
3802{
3803 first_corpus = priv_->first_self_comparison_corpus_.lock();
3804 second_corpus = priv_->second_self_comparison_corpus_.lock();
3805}
3806
3807/// Turn on/off the self comparison debug mode.
3808///
3809/// @param f true iff the self comparison debug mode is turned on.
3810void
3811environment::self_comparison_debug_is_on(bool f)
3812{priv_->self_comparison_debug_on_ = f;}
3813
3814/// Test if we are in the process of the 'self-comparison
3815/// debugging' as triggered by 'abidw --debug-abidiff' command.
3816///
3817/// @return true if self comparison debug is on.
3818bool
3819environment::self_comparison_debug_is_on() const
3820{return priv_->self_comparison_debug_on_;}
3821#endif
3822
3823#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3824/// Set the "type canonicalization debugging" mode, triggered by using
3825/// the command: "abidw --debug-tc".
3826///
3827/// @param flag if true then the type canonicalization debugging mode
3828/// is enabled.
3829void
3830environment::debug_type_canonicalization_is_on(bool flag)
3831{priv_->debug_type_canonicalization_ = flag;}
3832
3833/// Getter of the "type canonicalization debugging" mode, triggered by
3834/// using the command: "abidw --debug-tc".
3835///
3836/// @return true iff the type canonicalization debugging mode is
3837/// enabled.
3838bool
3839environment::debug_type_canonicalization_is_on() const
3840{return priv_->debug_type_canonicalization_;}
3841
3842/// Setter of the "DIE canonicalization debugging" mode, triggered by
3843/// using the command: "abidw --debug-dc".
3844///
3845/// @param flag true iff the DIE canonicalization debugging mode is
3846/// enabled.
3847void
3848environment::debug_die_canonicalization_is_on(bool flag)
3849{priv_->debug_die_canonicalization_ = flag;}
3850
3851/// Getter of the "DIE canonicalization debugging" mode, triggered by
3852/// using the command: "abidw --debug-dc".
3853///
3854/// @return true iff the DIE canonicalization debugging mode is
3855/// enabled.
3856bool
3857environment::debug_die_canonicalization_is_on() const
3858{return priv_->debug_die_canonicalization_;}
3859#endif // WITH_DEBUG_TYPE_CANONICALIZATION
3860
3861/// Get the vector of canonical types which have a given "string
3862/// representation".
3863///
3864/// @param 'name', the textual representation of the type as returned
3865/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3866/// /*qualified=*/true)
3867///
3868/// This is useful to for debugging purposes as it's handy to use from
3869/// inside a debugger like GDB.
3870///
3871/// @return a pointer to the vector of canonical types having the
3872/// representation @p name, or nullptr if no type with that
3873/// representation exists.
3874const vector<type_base_sptr>*
3876{
3877 auto ti = get_canonical_types_map().find(name);
3878 if (ti == get_canonical_types_map().end())
3879 return nullptr;
3880 return &ti->second;
3881}
3882
3883/// Get a given canonical type which has a given "string
3884/// representation".
3885///
3886/// @param 'name', the textual representation of the type as returned
3887/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3888/// /*qualified=*/true).
3889///
3890/// @param index, the index of the type in the vector of types that
3891/// all have the same textual representation @p 'name'. That vector
3892/// is returned by the function environment::get_canonical_types().
3893///
3894/// @return the canonical type which has the representation @p name,
3895/// and which is at index @p index in the vector of canonical types
3896/// having that same textual representation.
3897type_base*
3898environment::get_canonical_type(const char* name, unsigned index)
3899{
3900 const vector<type_base_sptr> *types = get_canonical_types(name);
3901 if (!types ||index >= types->size())
3902 return nullptr;
3903 return (*types)[index].get();
3904}
3905
3906#ifdef WITH_DEBUG_SELF_COMPARISON
3907/// Get the set of abixml type-id and the pointer value of the
3908/// (canonical) type it's associated to.
3909///
3910/// This is useful for debugging purposes, especially in the context
3911/// of the use of the command:
3912/// 'abidw --debug-abidiff <binary>'.
3913///
3914/// @return the set of abixml type-id and the pointer value of the
3915/// (canonical) type it's associated to.
3916const unordered_map<string, uintptr_t>&
3917environment::get_type_id_canonical_type_map() const
3918{return priv_->get_type_id_canonical_type_map();}
3919
3920/// Get the set of abixml type-id and the pointer value of the
3921/// (canonical) type it's associated to.
3922///
3923/// This is useful for debugging purposes, especially in the context
3924/// of the use of the command:
3925/// 'abidw --debug-abidiff <binary>'.
3926///
3927/// @return the set of abixml type-id and the pointer value of the
3928/// (canonical) type it's associated to.
3929unordered_map<string, uintptr_t>&
3930environment::get_type_id_canonical_type_map()
3931{return priv_->get_type_id_canonical_type_map();}
3932
3933/// Getter of the map that associates the values of type pointers to
3934/// their type-id strings.
3935///
3936/// Note that this map is populated at abixml reading time, (by
3937/// build_type()) when a given XML element representing a type is
3938/// read into a corresponding abigail::ir::type_base.
3939///
3940/// This is used only for the purpose of debugging the
3941/// self-comparison process. That is, when invoking "abidw
3942/// --debug-abidiff".
3943///
3944/// @return the map that associates the values of type pointers to
3945/// their type-id strings.
3946const unordered_map<uintptr_t, string>&
3947environment::get_pointer_type_id_map() const
3948{return priv_->get_pointer_type_id_map();}
3949
3950/// Getter of the map that associates the values of type pointers to
3951/// their type-id strings.
3952///
3953/// Note that this map is populated at abixml reading time, (by
3954/// build_type()) when a given XML element representing a type is
3955/// read into a corresponding abigail::ir::type_base.
3956///
3957/// This is used only for the purpose of debugging the
3958/// self-comparison process. That is, when invoking "abidw
3959/// --debug-abidiff".
3960///
3961/// @return the map that associates the values of type pointers to
3962/// their type-id strings.
3963unordered_map<uintptr_t, string>&
3964environment::get_pointer_type_id_map()
3965{return priv_->get_pointer_type_id_map();}
3966
3967/// Getter of the type-id that corresponds to the value of a pointer
3968/// to abigail::ir::type_base that was created from the abixml reader.
3969///
3970/// That value is retrieved from the map returned from
3971/// environment::get_pointer_type_id_map().
3972///
3973/// That map is populated at abixml reading time, (by build_type())
3974/// when a given XML element representing a type is read into a
3975/// corresponding abigail::ir::type_base.
3976///
3977/// This is used only for the purpose of debugging the
3978/// self-comparison process. That is, when invoking "abidw
3979/// --debug-abidiff".
3980///
3981/// @return the type-id strings that corresponds
3982string
3983environment::get_type_id_from_pointer(uintptr_t ptr) const
3984{return priv_->get_type_id_from_pointer(ptr);}
3985
3986/// Getter of the type-id that corresponds to the value of an
3987/// abigail::ir::type_base that was created from the abixml reader.
3988///
3989/// That value is retrieved from the map returned from
3990/// environment::get_pointer_type_id_map().
3991///
3992/// That map is populated at abixml reading time, (by build_type())
3993/// when a given XML element representing a type is read into a
3994/// corresponding abigail::ir::type_base.
3995///
3996/// This is used only for the purpose of debugging the
3997/// self-comparison process. That is, when invoking "abidw
3998/// --debug-abidiff".
3999///
4000/// @return the type-id strings that corresponds
4001string
4002environment::get_type_id_from_type(const type_base *t) const
4003{return priv_->get_type_id_from_type(t);}
4004
4005/// Getter of the canonical type of the artifact designated by a
4006/// type-id.
4007///
4008/// That type-id was generated by the abixml writer at the emitting
4009/// time of the abixml file. The corresponding canonical type was
4010/// stored in the map returned by
4011/// environment::get_type_id_canonical_type_map().
4012///
4013/// This is useful for debugging purposes, especially in the context
4014/// of the use of the command:
4015/// 'abidw --debug-abidiff <binary>'.
4016///
4017/// @return the set of abixml type-id and the pointer value of the
4018/// (canonical) type it's associated to.
4019uintptr_t
4020environment::get_canonical_type_from_type_id(const char* type_id) const
4021{return priv_->get_canonical_type_from_type_id(type_id);}
4022#endif
4023
4024// </environment stuff>
4025
4026// <type_or_decl_base stuff>
4027
4028/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
4029/// bitmap type.
4033{
4034 return static_cast<type_or_decl_base::type_or_decl_kind>
4035 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4036}
4037
4038/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4039/// bitmap type.
4043{
4044 l = l | r;
4045 return l;
4046}
4047
4048/// bitwise "AND" operator for the
4049/// type_or_decl_base::type_or_decl_kind bitmap type.
4053{
4054 return static_cast<type_or_decl_base::type_or_decl_kind>
4055 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4056}
4057
4058/// bitwise "A&=" operator for the
4059/// type_or_decl_base::type_or_decl_kind bitmap type.
4063{
4064 l = l & r;
4065 return l;
4066}
4067
4068/// Constructor of @ref type_or_decl_base.
4069///
4070/// @param the environment the current ABI artifact is constructed
4071/// from.
4072///
4073/// @param k the runtime identifier bitmap of the type being built.
4074type_or_decl_base::type_or_decl_base(const environment& e,
4075 enum type_or_decl_kind k)
4076 :priv_(new priv(e, k))
4077{}
4078
4079/// The destructor of the @ref type_or_decl_base type.
4081{}
4082
4083/// Getter of the flag that says if the artefact is artificial.
4084///
4085/// Being artificial means it was not explicitely mentionned in the
4086/// source code, but was rather artificially created by the compiler
4087/// or libabigail.
4088///
4089/// @return true iff the declaration is artificial.
4090bool
4092{return priv_->is_artificial_;}
4093
4094/// Setter of the flag that says if the artefact is artificial.
4095///
4096/// Being artificial means the artefact was not explicitely
4097/// mentionned in the source code, but was rather artificially created
4098/// by the compiler or by libabigail.
4099///
4100/// @param f the new value of the flag that says if the artefact is
4101/// artificial.
4102void
4104{priv_->is_artificial_ = f;}
4105
4106/// Getter for the "kind" property of @ref type_or_decl_base type.
4107///
4108/// This property holds the identifier bitmap of the runtime type of
4109/// an ABI artifact.
4110///
4111/// @return the runtime type identifier bitmap of the current ABI
4112/// artifact.
4115{return priv_->kind();}
4116
4117/// Setter for the "kind" property of @ref type_or_decl_base type.
4118///
4119/// This property holds the identifier bitmap of the runtime type of
4120/// an ABI artifact.
4121///
4122/// @param the runtime type identifier bitmap of the current ABI
4123/// artifact.
4124void
4126{priv_->kind(k);}
4127
4128/// Getter of the pointer to the runtime type sub-object of the
4129/// current instance.
4130///
4131/// @return the pointer to the runtime type sub-object of the current
4132/// instance.
4133const void*
4135{return priv_->rtti_;}
4136
4137/// Getter of the pointer to the runtime type sub-object of the
4138/// current instance.
4139///
4140/// @return the pointer to the runtime type sub-object of the current
4141/// instance.
4142void*
4144{return priv_->rtti_;}
4145
4146/// Setter of the pointer to the runtime type sub-object of the
4147/// current instance.
4148///
4149/// @param i the new pointer to the runtime type sub-object of the
4150/// current instance.
4151void
4153{
4154 priv_->rtti_ = i;
4155 if (type_base* t = dynamic_cast<type_base*>(this))
4156 priv_->type_or_decl_ptr_ = t;
4157 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4158 priv_->type_or_decl_ptr_ = d;
4159}
4160
4161/// Getter of the pointer to either the type_base sub-object of the
4162/// current instance if it's a type, or to the decl_base sub-object of
4163/// the current instance if it's a decl.
4164///
4165/// @return the pointer to either the type_base sub-object of the
4166/// current instance if it's a type, or to the decl_base sub-object of
4167/// the current instance if it's a decl.
4168const void*
4170{return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
4171
4172/// Getter of the pointer to either the type_base sub-object of the
4173/// current instance if it's a type, or to the decl_base sub-object of
4174/// the current instance if it's a decl.
4175///
4176/// @return the pointer to either the type_base sub-object of the
4177/// current instance if it's a type, or to the decl_base sub-object of
4178/// the current instance if it's a decl.
4179void*
4181{return priv_->type_or_decl_ptr_;}
4182
4183/// Return the hash value of the current IR node.
4184///
4185/// Note that upon the first invocation, this member functions
4186/// computes the hash value and returns it. Subsequent invocations
4187/// just return the hash value that was previously calculated.
4188///
4189/// @return the hash value of the current IR node.
4190hash_t
4192{return priv_->hash_value_;}
4193
4194void
4195type_or_decl_base::set_hash_value(hash_t h) const
4196{priv_->set_hash_value(h);}
4197
4198/// Getter of the environment of the current ABI artifact.
4199///
4200/// @return the environment of the artifact.
4201const environment&
4203{return priv_->env_;}
4204
4205/// Setter of the artificial location of the artificat.
4206///
4207/// The artificial location is a location that was artificially
4208/// generated by libabigail, not generated by the original emitter of
4209/// the ABI meta-data. For instance, when reading an XML element from
4210/// an abixml file, the artificial location is the source location of
4211/// the XML element within the file, not the value of the
4212/// 'location'property that might be carried by the element.
4213///
4214/// Artificial locations might be useful to ensure that abixml emitted
4215/// by the abixml writer are sorted the same way as the input abixml
4216/// read by the reader.
4217///
4218/// @param l the new artificial location.
4219void
4221{priv_->artificial_location_ = l;}
4222
4223/// Getter of the artificial location of the artifact.
4224///
4225/// The artificial location is a location that was artificially
4226/// generated by libabigail, not generated by the original emitter of
4227/// the ABI meta-data. For instance, when reading an XML element from
4228/// an abixml file, the artificial location is the source location of
4229/// the XML element within the file, not the value of the
4230/// 'location'property that might be carried by the element.
4231///
4232/// Artificial locations might be useful to ensure that the abixml
4233/// emitted by the abixml writer is sorted the same way as the input
4234/// abixml read by the reader.
4235///
4236/// @return the new artificial location.
4237location&
4239{return priv_->artificial_location_;}
4240
4241/// Test if the current ABI artifact carries an artificial location.
4242///
4243/// @return true iff the current ABI artifact carries an artificial location.
4244bool
4246{
4247 return (priv_->artificial_location_
4248 && priv_->artificial_location_.get_is_artificial());
4249}
4250
4251/// Get the @ref corpus this ABI artifact belongs to.
4252///
4253/// @return the corpus this ABI artifact belongs to, or nil if it
4254/// belongs to none for now.
4255corpus*
4257{
4259 if (!tu)
4260 return 0;
4261 return tu->get_corpus();
4262}
4263
4264
4265/// Get the @ref corpus this ABI artifact belongs to.
4266///
4267/// @return the corpus this ABI artifact belongs to, or nil if it
4268/// belongs to none for now.
4269const corpus*
4271{return const_cast<type_or_decl_base*>(this)->get_corpus();}
4272
4273/// Set the @ref translation_unit this ABI artifact belongs to.
4274///
4275/// Note that adding an ABI artifact to a containining on should
4276/// invoke this member function.
4277void
4279{priv_->translation_unit_ = tu;}
4280
4281
4282/// Get the @ref translation_unit this ABI artifact belongs to.
4283///
4284/// @return the translation unit this ABI artifact belongs to, or nil
4285/// if belongs to none for now.
4288{return priv_->translation_unit_;}
4289
4290/// Get the @ref translation_unit this ABI artifact belongs to.
4291///
4292/// @return the translation unit this ABI artifact belongs to, or nil
4293/// if belongs to none for now.
4294const translation_unit*
4296{return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
4297
4298/// Traverse the the ABI artifact.
4299///
4300/// @param v the visitor used to traverse the sub-tree nodes of the
4301/// artifact.
4302bool
4304{return true;}
4305
4306/// Non-member equality operator for the @type_or_decl_base type.
4307///
4308/// @param lr the left-hand operand of the equality.
4309///
4310/// @param rr the right-hand operatnr of the equality.
4311///
4312/// @return true iff @p lr equals @p rr.
4313bool
4315{
4316 const type_or_decl_base* l = &lr;
4317 const type_or_decl_base* r = &rr;
4318
4319 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4320 *dr = dynamic_cast<const decl_base*>(r);
4321
4322 if (!!dl != !!dr)
4323 return false;
4324
4325 if (dl && dr)
4326 return *dl == *dr;
4327
4328 const type_base* tl = dynamic_cast<const type_base*>(l),
4329 *tr = dynamic_cast<const type_base*>(r);
4330
4331 if (!!tl != !!tr)
4332 return false;
4333
4334 if (tl && tr)
4335 return *tl == *tr;
4336
4337 return false;
4338}
4339
4340/// Non-member equality operator for the @type_or_decl_base type.
4341///
4342/// @param l the left-hand operand of the equality.
4343///
4344/// @param r the right-hand operatnr of the equality.
4345///
4346/// @return true iff @p l equals @p r.
4347bool
4349{
4350 if (!! l != !!r)
4351 return false;
4352
4353 if (!l)
4354 return true;
4355
4356 return *r == *l;
4357}
4358
4359/// Non-member inequality operator for the @type_or_decl_base type.
4360///
4361/// @param l the left-hand operand of the equality.
4362///
4363/// @param r the right-hand operator of the equality.
4364///
4365/// @return true iff @p l is different from @p r.
4366bool
4368{return !operator==(l, r);}
4369
4370// </type_or_decl_base stuff>
4371
4372// <Decl definition>
4373
4374struct decl_base::priv
4375{
4376 bool in_pub_sym_tab_;
4377 bool is_anonymous_;
4378 location location_;
4379 context_rel *context_;
4380 interned_string name_;
4381 interned_string qualified_parent_name_;
4382 // This temporary qualified name is the cache used for the qualified
4383 // name before the type associated to this decl (if applicable) is
4384 // canonicalized. Once the type is canonicalized, the cached use is
4385 // the data member qualified_parent_name_ above.
4386 interned_string temporary_qualified_name_;
4387 // This is the fully qualified name of the decl. It contains the
4388 // name of the decl and the qualified name of its scope. So if in
4389 // the parent scopes of the decl, there is one anonymous struct,
4390 // somewhere in the name, there is going to by an
4391 // __anonymous_struct__ string, even if the anonymous struct is not
4392 // the direct containing scope of this decl.
4393 interned_string qualified_name_;
4394 interned_string temporary_internal_qualified_name_;
4395 interned_string internal_qualified_name_;
4396 interned_string internal_cached_repr_;
4397 interned_string cached_repr_;
4398 // Unline qualified_name_, scoped_name_ contains the name of the
4399 // decl and the name of its scope; not the qualified name of the
4400 // scope.
4401 interned_string scoped_name_;
4402 interned_string linkage_name_;
4403 visibility visibility_;
4404 decl_base_sptr declaration_;
4405 decl_base_wptr definition_of_declaration_;
4406 decl_base* naked_definition_of_declaration_;
4407 bool is_declaration_only_;
4408 typedef_decl_sptr naming_typedef_;
4409
4410 priv()
4411 : in_pub_sym_tab_(false),
4412 is_anonymous_(true),
4413 context_(),
4414 visibility_(VISIBILITY_DEFAULT),
4415 naked_definition_of_declaration_(),
4416 is_declaration_only_(false)
4417 {}
4418
4419 priv(interned_string name, interned_string linkage_name, visibility vis)
4420 : in_pub_sym_tab_(false),
4421 context_(),
4422 name_(name),
4423 qualified_name_(name),
4424 linkage_name_(linkage_name),
4425 visibility_(vis),
4426 naked_definition_of_declaration_(),
4427 is_declaration_only_(false)
4428 {
4429 is_anonymous_ = name_.empty();
4430 }
4431
4432 ~priv()
4433 {
4434 delete context_;
4435 }
4436};// end struct decl_base::priv
4437
4438/// Constructor for the @ref decl_base type.
4439///
4440/// @param e the environment the current @ref decl_base is being
4441/// created in.
4442///
4443/// @param name the name of the declaration.
4444///
4445/// @param locus the location where to find the declaration in the
4446/// source code.
4447///
4448/// @param linkage_name the linkage name of the declaration.
4449///
4450/// @param vis the visibility of the declaration.
4451decl_base::decl_base(const environment& e,
4452 const string& name,
4453 const location& locus,
4454 const string& linkage_name,
4455 visibility vis)
4456 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4457 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4458{
4459 set_location(locus);
4460}
4461
4462/// Constructor.
4463///
4464/// @param e the environment this instance of @ref decl_base is
4465/// created in.
4466///
4467/// @param name the name of the declaration being constructed.
4468///
4469/// @param locus the source location of the declaration being constructed.
4470///
4471/// @param linkage_name the linkage name of the declaration being
4472/// constructed.
4473///
4474/// @param vis the visibility of the declaration being constructed.
4475decl_base::decl_base(const environment& e,
4476 const interned_string& name,
4477 const location& locus,
4478 const interned_string& linkage_name,
4479 visibility vis)
4480 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4481 priv_(new priv(name, linkage_name, vis))
4482{
4483 set_location(locus);
4484}
4485
4486/// Constructor for the @ref decl_base type.
4487///
4488///@param environment the environment this instance of @ref decl_base
4489/// is being constructed in.
4490///
4491/// @param l the location where to find the declaration in the source
4492/// code.
4493decl_base::decl_base(const environment& e, const location& l)
4494 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4495 priv_(new priv())
4496{
4497 set_location(l);
4498}
4499
4500/// Getter for the qualified name.
4501///
4502/// Unlike decl_base::get_qualified_name() this doesn't try to update
4503/// the qualified name.
4504///
4505/// @return the qualified name.
4506const interned_string&
4508{return priv_->qualified_name_;}
4509
4510/// Clear the qualified name of this decl.
4511///
4512/// This is useful to ensure that the cache for the qualified name of
4513/// the decl is refreshed right after type canonicalization, for
4514/// instance.
4515void
4517{priv_->qualified_name_.clear();}
4518
4519/// Setter for the qualified name.
4520///
4521/// @param n the new qualified name.
4522void
4524{priv_->qualified_name_ = n;}
4525
4526/// Getter of the temporary qualified name of the current declaration.
4527///
4528/// This temporary qualified name is used as a qualified name cache by
4529/// the type for which this is the declaration (when applicable)
4530/// before the type is canonicalized. Once the type is canonicalized,
4531/// it's the result of decl_base::peek_qualified_name() that becomes
4532/// the qualified name cached.
4533///
4534/// @return the temporary qualified name.
4535const interned_string&
4537{return priv_->temporary_qualified_name_;}
4538
4539/// Setter for the temporary qualified name of the current
4540/// declaration.
4541///
4542///@param n the new temporary qualified name.
4543///
4544/// This temporary qualified name is used as a qualified name cache by
4545/// the type for which this is the declaration (when applicable)
4546/// before the type is canonicalized. Once the type is canonicalized,
4547/// it's the result of decl_base::peek_qualified_name() that becomes
4548/// the qualified name cached.
4549void
4551{priv_->temporary_qualified_name_ = n;}
4552
4553///Getter for the context relationship.
4554///
4555///@return the context relationship for the current decl_base.
4556const context_rel*
4558{return priv_->context_;}
4559
4560///Getter for the context relationship.
4561///
4562///@return the context relationship for the current decl_base.
4565{return priv_->context_;}
4566
4567void
4568decl_base::set_context_rel(context_rel *c)
4569{priv_->context_ = c;}
4570
4571/// Test if the decl is defined in a ELF symbol table as a public
4572/// symbol.
4573///
4574/// @return true iff the decl is defined in a ELF symbol table as a
4575/// public symbol.
4576bool
4578{return priv_->in_pub_sym_tab_;}
4579
4580/// Set the flag saying if this decl is from a symbol that is in
4581/// a public symbols table, defined as public (global or weak).
4582///
4583/// @param f the new flag value.
4584void
4586{priv_->in_pub_sym_tab_ = f;}
4587
4588/// Get the location of a given declaration.
4589///
4590/// The location is an abstraction for the tripplet {file path,
4591/// line, column} that defines where the declaration appeared in the
4592/// source code.
4593///
4594/// To get the value of the tripplet {file path, line, column} from
4595/// the @ref location, you need to use the
4596/// location_manager::expand_location() method.
4597///
4598/// The instance of @ref location_manager that you want is
4599/// accessible from the instance of @ref translation_unit that the
4600/// current instance of @ref decl_base belongs to, via a call to
4601/// translation_unit::get_loc_mgr().
4602///
4603/// @return the location of the current instance of @ref decl_base.
4604const location&
4606{return priv_->location_;}
4607
4608/// Set the location for a given declaration.
4609///
4610/// The location is an abstraction for the tripplet {file path,
4611/// line, column} that defines where the declaration appeared in the
4612/// source code.
4613///
4614/// To create a location from a tripplet {file path, line, column},
4615/// you need to use the method @ref
4616/// location_manager::create_new_location().
4617///
4618/// Note that there can be two kinds of location. An artificial
4619/// location and a non-artificial one. The non-artificial location is
4620/// the one emitted by the original emitter of the ABI artifact, for
4621/// instance, if the ABI artifact comes from debug info, then the
4622/// source location that is present in the debug info represent a
4623/// non-artificial location. When looking at an abixml file on the
4624/// other hand, the value of the 'location' attribute of an XML
4625/// element describing an artifact is the non-artificial location.
4626/// The artificial location is the location (line number from the
4627/// beginning of the file) of the XML element within the abixml file.
4628///
4629/// So, if the location that is being set is artificial, note that the
4630/// type_or_decl_base::has_artificial_location() method of this decl will
4631/// subsequently return true and that artificial location will have to
4632/// be retrieved using type_or_decl_base::get_artificial_location().
4633/// If the location is non-artificial however,
4634/// type_or_decl_base::has_artificial_location() will subsequently
4635/// return false and the non-artificial location will have to be
4636/// retrieved using decl_base::get_location().
4637///
4638/// The instance of @ref location_manager that you want is
4639/// accessible from the instance of @ref translation_unit that the
4640/// current instance of @ref decl_base belongs to, via a call to
4641/// translation_unit::get_loc_mgr().
4642void
4644{
4645 if (l.get_is_artificial())
4647 else
4648 priv_->location_ = l;
4649}
4650
4651/// Setter for the name of the decl.
4652///
4653/// @param n the new name to set.
4654void
4655decl_base::set_name(const string& n)
4656{
4657 priv_->name_ = get_environment().intern(n);
4658 priv_->is_anonymous_ = n.empty();
4659}
4660
4661/// Test if the current declaration is anonymous.
4662///
4663/// Being anonymous means that the declaration was created without a
4664/// name. This can usually happen for enum or struct types.
4665///
4666/// @return true iff the type is anonymous.
4667bool
4669{return priv_->is_anonymous_;}
4670
4671/// Set the "is_anonymous" flag of the current declaration.
4672///
4673/// Being anonymous means that the declaration was created without a
4674/// name. This can usually happen for enum or struct types.
4675///
4676/// @param f the new value of the flag.
4677void
4679{priv_->is_anonymous_ = f;}
4680
4681
4682/// Get the "has_anonymous_parent" flag of the current declaration.
4683///
4684/// Having an anoymous parent means having a anonymous parent scope
4685/// (containing type or namespace) which is either direct or indirect.
4686///
4687/// @return true iff the current decl has a direct or indirect scope
4688/// which is anonymous.
4689bool
4691{
4692 scope_decl *scope = get_scope();
4693 if (!scope)
4694 return false;
4695 return scope->get_is_anonymous();
4696}
4697
4698/// @return the logical "OR" of decl_base::get_is_anonymous() and
4699/// decl_base::get_has_anonymous_parent().
4700bool
4703
4704/// Getter for the naming typedef of the current decl.
4705///
4706/// Consider the C idiom:
4707///
4708/// typedef struct {int member;} foo_type;
4709///
4710/// In that idiom, foo_type is the naming typedef of the anonymous
4711/// struct that is declared.
4712///
4713/// @return the naming typedef, if any. Otherwise, returns nil.
4716{return priv_->naming_typedef_;}
4717
4718/// Set the naming typedef of the current instance of @ref decl_base.
4719///
4720/// Consider the C idiom:
4721///
4722/// typedef struct {int member;} foo_type;
4723///
4724/// In that idiom, foo_type is the naming typedef of the anonymous
4725/// struct that is declared.
4726///
4727/// After completion of this function, the decl will not be considered
4728/// anonymous anymore. It's name is going to be the name of the
4729/// naming typedef.
4730///
4731/// @param typedef_type the new naming typedef.
4732void
4734{
4735 // A naming typedef is usually for an anonymous type.
4737 // Whe the typedef-named decl is saved into abixml, it's
4738 // not anonymous anymore. Its name is the typedef name.
4739 // So when we read it back, we must still be able to
4740 // apply the naming typedef to the decl.
4741 || t->get_name() == get_name());
4742 // Only non canonicalized types can be edited this way.
4743 ABG_ASSERT(is_type(this)
4744 && is_type(this)->get_naked_canonical_type() == nullptr);
4745
4746 priv_->naming_typedef_ = t;
4747 set_name(t->get_name());
4748 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4749 set_qualified_name(get_environment().intern(qualified_name));
4750 set_is_anonymous(false);
4751 // Now that the qualified type of the decl has changed, let's update
4752 // the qualified names of the member types of this decls.
4753 update_qualified_name(this);
4754}
4755
4756/// Getter for the mangled name.
4757///
4758/// @return the new mangled name.
4759const interned_string&
4761{return priv_->linkage_name_;}
4762
4763/// Setter for the linkage name.
4764///
4765/// @param m the new linkage name.
4766void
4768{
4769 const environment& env = get_environment();
4770 priv_->linkage_name_ = env.intern(m);
4771}
4772
4773/// Getter for the visibility of the decl.
4774///
4775/// @return the new visibility.
4778{return priv_->visibility_;}
4779
4780/// Setter for the visibility of the decl.
4781///
4782/// @param v the new visibility.
4783void
4785{priv_->visibility_ = v;}
4786
4787/// Return the type containing the current decl, if any.
4788///
4789/// @return the type that contains the current decl, or NULL if there
4790/// is none.
4793{
4794 if (priv_->context_)
4795 return priv_->context_->get_scope();
4796 return 0;
4797}
4798
4799/// Return a copy of the qualified name of the parent of the current
4800/// decl.
4801///
4802/// @return the newly-built qualified name of the of the current decl.
4803const interned_string&
4805{return priv_->qualified_parent_name_;}
4806
4807/// Getter for the name of the current decl.
4808///
4809/// @return the name of the current decl.
4810const interned_string&
4812{return priv_->name_;}
4813
4814/// Compute the qualified name of the decl.
4815///
4816/// @param qn the resulting qualified name.
4817///
4818/// @param internal set to true if the call is intended for an
4819/// internal use (for technical use inside the library itself), false
4820/// otherwise. If you don't know what this is for, then set it to
4821/// false.
4822void
4824{qn = get_qualified_name(internal);}
4825
4826/// Get the pretty representatin of the current declaration.
4827///
4828///
4829/// @param internal set to true if the call is intended to get a
4830/// representation of the decl (or type) for the purpose of canonical
4831/// type comparison. This is mainly used in the function
4832/// type_base::get_canonical_type_for().
4833///
4834/// In other words if the argument for this parameter is true then the
4835/// call is meant for internal use (for technical use inside the
4836/// library itself), false otherwise. If you don't know what this is
4837/// for, then set it to false.
4838///
4839/// @param qualified_name if true, names emitted in the pretty
4840/// representation are fully qualified.
4841///
4842/// @return the default pretty representation for a decl. This is
4843/// basically the fully qualified name of the decl optionally prefixed
4844/// with a meaningful string to add context for the user.
4845string
4847 bool qualified_name) const
4848{
4849 if (internal
4850 && get_is_anonymous()
4851 && has_generic_anonymous_internal_type_name(this))
4852 {
4853 // We are looking at an anonymous enum, union or class and we
4854 // want an *internal* pretty representation for it. All
4855 // anonymous types of this kind in the same namespace must have
4856 // the same internal representation for type canonicalization to
4857 // work properly.
4858 //
4859 // OK, in practise, we are certainly looking at an enum because
4860 // classes and unions should have their own overloaded virtual
4861 // member function for this.
4862 string name = get_generic_anonymous_internal_type_name(this);
4863 if (qualified_name && !get_qualified_parent_name().empty())
4864 name = get_qualified_parent_name() + "::" + name;
4865 return name;
4866 }
4867
4868 if (qualified_name)
4869 return get_qualified_name(internal);
4870 return get_name();
4871}
4872
4873/// Get the pretty representation of the current decl.
4874///
4875/// The pretty representation is retrieved from a cache. If the cache
4876/// is empty, this function computes the pretty representation, put it
4877/// in the cache and returns it.
4878///
4879/// Please note that if this function is called too early in the life
4880/// cycle of the decl (before it is fully constructed), then the
4881/// pretty representation that is cached is going to represent a
4882/// non-complete (and thus wrong) representation of the decl. Thus
4883/// this function must be called only once the decl is fully
4884/// constructed.
4885///
4886/// @param internal if true, then the pretty representation is to be
4887/// used for purpuses that are internal to the libabigail library
4888/// itself. If you don't know what this means, then you probably
4889/// should set this parameter to "false".
4890///
4891/// @return a reference to a cached @ref interned_string holding the
4892/// pretty representation of the current decl.
4893const interned_string&
4895{
4896 if (internal)
4897 {
4898 if (priv_->internal_cached_repr_.empty())
4899 {
4900 string r = ir::get_pretty_representation(this, internal);
4901 priv_->internal_cached_repr_ = get_environment().intern(r);
4902 }
4903 return priv_->internal_cached_repr_;
4904 }
4905
4906 if (priv_->cached_repr_.empty())
4907 {
4908 string r = ir::get_pretty_representation(this, internal);
4909 priv_->cached_repr_ = get_environment().intern(r);
4910 }
4911
4912 return priv_->cached_repr_;
4913}
4914
4915/// Return the qualified name of the decl.
4916///
4917/// This is the fully qualified name of the decl. It's made of the
4918/// concatenation of the name of the decl with the qualified name of
4919/// its scope.
4920///
4921/// Note that the value returned by this function is computed by @ref
4922/// update_qualified_name when the decl is added to its scope.
4923///
4924/// @param internal set to true if the call is intended for an
4925/// internal use (for technical use inside the library itself), false
4926/// otherwise. If you don't know what this is for, then set it to
4927/// false.
4928///
4929/// @return the resulting qualified name.
4930const interned_string&
4931decl_base::get_qualified_name(bool /*internal*/) const
4932{return priv_->qualified_name_;}
4933
4934/// Return the scoped name of the decl.
4935///
4936/// This is made of the concatenation of the name of the decl with the
4937/// name of its scope. It doesn't contain the qualified name of its
4938/// scope, unlike what is returned by decl_base::get_qualified_name.
4939///
4940/// Note that the value returned by this function is computed by @ref
4941/// update_qualified_name when the decl is added to its scope.
4942///
4943/// @return the scoped name of the decl.
4944const interned_string&
4946{return priv_->scoped_name_;}
4947
4948/// If this @ref decl_base is a definition, get its earlier
4949/// declaration.
4950///
4951/// @return the earlier declaration of the class, if any.
4952const decl_base_sptr
4954{return priv_->declaration_;}
4955
4956/// set the earlier declaration of this @ref decl_base definition.
4957///
4958/// @param d the earlier declaration to set. Note that it's set only
4959/// if it's a pure declaration.
4960void
4962{
4963 if (d && d->get_is_declaration_only())
4964 priv_->declaration_ = d;
4965}
4966
4967
4968/// If this @ref decl_base is declaration-only, get its definition, if
4969/// any.
4970///
4971/// @return the definition of this decl-only @ref decl_base.
4972const decl_base_sptr
4974{return priv_->definition_of_declaration_.lock();}
4975
4976/// If this @ref decl_base is declaration-only, get its definition,
4977/// if any.
4978///
4979/// Note that this function doesn't return a smart pointer, but rather
4980/// the underlying pointer managed by the smart pointer. So it's as
4981/// fast as possible. This getter is to be used in code paths that
4982/// are proven to be performance hot spots; especially, when comparing
4983/// sensitive types like enums, classes or unions. Those are compared
4984/// extremely frequently and thus, their access to the definition of
4985/// declaration must be fast.
4986///
4987/// @return the definition of the declaration.
4988const decl_base*
4990{return priv_->naked_definition_of_declaration_;}
4991
4992/// Test if a @ref decl_base is a declaration-only decl.
4993///
4994/// @return true iff the current @ref decl_base is declaration-only.
4995bool
4997{return priv_->is_declaration_only_;}
4998
4999/// Set a flag saying if the @ref enum_type_decl is a declaration-only
5000/// @ref enum_type_decl.
5001///
5002/// @param f true if the @ref enum_type_decl is a declaration-only
5003/// @ref enum_type_decl.
5004void
5006{
5007 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
5008
5009 priv_->is_declaration_only_ = f;
5010
5011 if (update_types_lookup_map)
5012 if (scope_decl* s = get_scope())
5013 {
5014 scope_decl::declarations::iterator i;
5015 if (s->find_iterator_for_member(this, i))
5017 else
5019 }
5020}
5021
5024{
5025 return static_cast<change_kind>(static_cast<unsigned>(l)
5026 | static_cast<unsigned>(r));
5027}
5028
5031{
5032 return static_cast<change_kind>(static_cast<unsigned>(l)
5033 & static_cast<unsigned>(r));
5034}
5035
5038{
5039 l = l | r;
5040 return l;
5041}
5042
5045{
5046 l = l & r;
5047 return l;
5048}
5049
5050/// Compare the properties that belong to the "is-a-member-relation"
5051/// of a decl.
5052///
5053/// For instance, access specifiers are part of the
5054/// "is-a-member-relation" of a decl.
5055///
5056/// This comparison however doesn't take decl names into account. So
5057/// typedefs for instance are decls that we want to compare with this
5058/// function.
5059///
5060/// This function is a sub-routine of the more general 'equals'
5061/// overload for instances of decl_base.
5062///
5063/// @param l the left-hand side operand of the comparison.
5064///
5065/// @param r the right-hand side operand of the comparison.
5066///
5067/// @return true iff @p l compare equals, as a member decl, to @p r.
5068bool
5070 const decl_base& r,
5071 change_kind* k)
5072{
5073 bool result = true;
5074 if (is_member_decl(l) && is_member_decl(r))
5075 {
5076 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
5077 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
5078
5079 access_specifier la = no_access, ra = no_access;
5080 bool member_types_or_functions =
5081 ((is_type(l) && is_type(r))
5082 || (is_function_decl(l) && is_function_decl(r)));
5083
5084 if (member_types_or_functions)
5085 {
5086 // Access specifiers on member types in DWARF is not
5087 // reliable; in the same DSO, the same struct can be either
5088 // a class or a struct, and the access specifiers of its
5089 // member types are not necessarily given, so they
5090 // effectively can be considered differently, again, in the
5091 // same DSO. So, here, let's avoid considering those!
5092 // during comparison.
5093 la = r1->get_access_specifier();
5094 ra = r2->get_access_specifier();
5095 r1->set_access_specifier(no_access);
5096 r2->set_access_specifier(no_access);
5097 }
5098
5099 bool rels_are_different = *r1 != *r2;
5100
5101 if (member_types_or_functions)
5102 {
5103 // restore the access specifiers.
5104 r1->set_access_specifier(la);
5105 r2->set_access_specifier(ra);
5106 }
5107
5108 if (rels_are_different)
5109 {
5110 result = false;
5111 if (k)
5113 }
5114 }
5115 ABG_RETURN(result);
5116}
5117
5118/// Compares two instances of @ref decl_base.
5119///
5120/// If the two intances are different, set a bitfield to give some
5121/// insight about the kind of differences there are.
5122///
5123/// @param l the first artifact of the comparison.
5124///
5125/// @param r the second artifact of the comparison.
5126///
5127/// @param k a pointer to a bitfield that gives information about the
5128/// kind of changes there are between @p l and @p r. This one is set
5129/// iff it's non-null and if the function returns false.
5130///
5131/// Please note that setting k to a non-null value does have a
5132/// negative performance impact because even if @p l and @p r are not
5133/// equal, the function keeps up the comparison in order to determine
5134/// the different kinds of ways in which they are different.
5135///
5136/// @return true if @p l equals @p r, false otherwise.
5137bool
5138equals(const decl_base& l, const decl_base& r, change_kind* k)
5139{
5140 bool result = true;
5141 const interned_string &l_linkage_name = l.get_linkage_name();
5142 const interned_string &r_linkage_name = r.get_linkage_name();
5143 if (!l_linkage_name.empty() && !r_linkage_name.empty())
5144 {
5145 if (l_linkage_name != r_linkage_name)
5146 {
5147 // Linkage names are different. That usually means the two
5148 // decls are different, unless we are looking at two
5149 // function declarations which have two different symbols
5150 // that are aliases of each other.
5151 const function_decl *f1 = is_function_decl(&l),
5152 *f2 = is_function_decl(&r);
5153 if (f1 && f2 && function_decls_alias(*f1, *f2))
5154 ;// The two functions are aliases, so they are not
5155 // different.
5156 else
5157 {
5158 result = false;
5159 if (k)
5161 else
5163 }
5164 }
5165 }
5166
5167 if (r.get_is_anonymous() && l.get_is_anonymous())
5168 // We are looking at too anonymous types (or two members of
5169 // anonymous types) with one not yet been added to the IR. That
5170 // means we want to compare just the object part of the
5171 // anonymous type and not their qualified names. This is used
5172 // when looking up an anonymous type inside a class type.
5173 ABG_RETURN(result);
5174
5175 // This is the name of the decls that we want to compare.
5176 interned_string ln = l.get_name(), rn = r.get_name();
5177
5178 /// If both of the current decls have an anonymous scope then let's
5179 /// compare their name component by component by properly handling
5180 /// anonymous scopes. That's the slow path.
5181 ///
5182 /// Otherwise, let's just compare their name, the obvious way.
5183 /// That's the fast path because in that case the names are
5184 /// interned_string and comparing them is much faster.
5185 bool decls_are_same = (ln == rn);
5186
5187 if (!decls_are_same)
5188 {
5189 result = false;
5190 if (k)
5192 else
5194 }
5195
5196 result &= maybe_compare_as_member_decls(l, r, k);
5197
5198 ABG_RETURN(result);
5199}
5200
5201/// Return true iff the two decls have the same name.
5202///
5203/// This function doesn't test if the scopes of the the two decls are
5204/// equal.
5205///
5206/// Note that this virtual function is to be implemented by classes
5207/// that extend the \p decl_base class.
5208bool
5210{return equals(*this, other, 0);}
5211
5212/// Inequality operator.
5213///
5214/// @param other to other instance of @ref decl_base to compare the
5215/// current instance to.
5216///
5217/// @return true iff the current instance of @ref decl_base is
5218/// different from @p other.
5219bool
5221{return !operator==(other);}
5222
5223/// Destructor of the @ref decl_base type.
5225{delete priv_;}
5226
5227/// This implements the ir_traversable_base::traverse pure virtual
5228/// function.
5229///
5230/// @param v the visitor used on the member nodes of the translation
5231/// unit during the traversal.
5232///
5233/// @return true if the entire IR node tree got traversed, false
5234/// otherwise.
5235bool
5237{
5238 // Do nothing in the base class.
5239 return true;
5240}
5241
5242/// Setter of the scope of the current decl.
5243///
5244/// Note that the decl won't hold a reference on the scope. It's
5245/// rather the scope that holds a reference on its members.
5246void
5248{
5249 if (!priv_->context_)
5250 priv_->context_ = new context_rel(scope);
5251 else
5252 priv_->context_->set_scope(scope);
5253}
5254
5255// </decl_base definition>
5256
5257/// Streaming operator for the decl_base::visibility.
5258///
5259/// @param o the output stream to serialize the visibility to.
5260///
5261/// @param v the visibility to serialize.
5262///
5263/// @return the output stream.
5264std::ostream&
5265operator<<(std::ostream& o, decl_base::visibility v)
5266{
5267 string r;
5268 switch (v)
5269 {
5270 case decl_base::VISIBILITY_NONE:
5271 r = "none";
5272 break;
5273 case decl_base::VISIBILITY_DEFAULT:
5274 r = "default";
5275 break;
5276 case decl_base::VISIBILITY_PROTECTED:
5277 r = "protected";
5278 break;
5279 case decl_base::VISIBILITY_HIDDEN:
5280 r = "hidden";
5281 break;
5282 case decl_base::VISIBILITY_INTERNAL:
5283 r = "internal";
5284 break;
5285 }
5286 return o;
5287}
5288
5289/// Streaming operator for decl_base::binding.
5290///
5291/// @param o the output stream to serialize the visibility to.
5292///
5293/// @param b the binding to serialize.
5294///
5295/// @return the output stream.
5296std::ostream&
5297operator<<(std::ostream& o, decl_base::binding b)
5298{
5299 string r;
5300 switch (b)
5301 {
5302 case decl_base::BINDING_NONE:
5303 r = "none";
5304 break;
5305 case decl_base::BINDING_LOCAL:
5306 r = "local";
5307 break;
5308 case decl_base::BINDING_GLOBAL:
5309 r = "global";
5310 break;
5311 case decl_base::BINDING_WEAK:
5312 r = "weak";
5313 break;
5314 }
5315 o << r;
5316 return o;
5317}
5318
5319/// Turn equality of shared_ptr of decl_base into a deep equality;
5320/// that is, make it compare the pointed to objects, not just the
5321/// pointers.
5322///
5323/// @param l the shared_ptr of decl_base on left-hand-side of the
5324/// equality.
5325///
5326/// @param r the shared_ptr of decl_base on right-hand-side of the
5327/// equality.
5328///
5329/// @return true if the decl_base pointed to by the shared_ptrs are
5330/// equal, false otherwise.
5331bool
5332operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5333{
5334 if (l.get() == r.get())
5335 return true;
5336 if (!!l != !!r)
5337 return false;
5338
5339 return *l == *r;
5340}
5341
5342/// Inequality operator of shared_ptr of @ref decl_base.
5343///
5344/// This is a deep equality operator, that is, it compares the
5345/// pointed-to objects, rather than just the pointers.
5346///
5347/// @param l the left-hand-side operand.
5348///
5349/// @param r the right-hand-side operand.
5350///
5351/// @return true iff @p l is different from @p r.
5352bool
5353operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5354{return !operator==(l, r);}
5355
5356/// Turn equality of shared_ptr of type_base into a deep equality;
5357/// that is, make it compare the pointed to objects too.
5358///
5359/// @param l the shared_ptr of type_base on left-hand-side of the
5360/// equality.
5361///
5362/// @param r the shared_ptr of type_base on right-hand-side of the
5363/// equality.
5364///
5365/// @return true if the type_base pointed to by the shared_ptrs are
5366/// equal, false otherwise.
5367bool
5368operator==(const type_base_sptr& l, const type_base_sptr& r)
5369{
5370 if (l.get() == r.get())
5371 return true;
5372 if (!!l != !!r)
5373 return false;
5374
5375 return *l == *r;
5376}
5377
5378/// Turn inequality of shared_ptr of type_base into a deep equality;
5379/// that is, make it compare the pointed to objects..
5380///
5381/// @param l the shared_ptr of type_base on left-hand-side of the
5382/// equality.
5383///
5384/// @param r the shared_ptr of type_base on right-hand-side of the
5385/// equality.
5386///
5387/// @return true iff the type_base pointed to by the shared_ptrs are
5388/// different.
5389bool
5390operator!=(const type_base_sptr& l, const type_base_sptr& r)
5391{return !operator==(l, r);}
5392
5393/// Tests if a declaration has got a scope.
5394///
5395/// @param d the declaration to consider.
5396///
5397/// @return true if the declaration has got a scope, false otherwise.
5398bool
5400{return (d.get_scope());}
5401
5402/// Tests if a declaration has got a scope.
5403///
5404/// @param d the declaration to consider.
5405///
5406/// @return true if the declaration has got a scope, false otherwise.
5407bool
5408has_scope(const decl_base_sptr d)
5409{return has_scope(*d.get());}
5410
5411/// Tests if a declaration is a class member.
5412///
5413/// @param d the declaration to consider.
5414///
5415/// @return true if @p d is a class member, false otherwise.
5416bool
5417is_member_decl(const decl_base_sptr d)
5418{return is_at_class_scope(d) || is_method_decl(d);}
5419
5420/// Tests if a declaration is a class member.
5421///
5422/// @param d the declaration to consider.
5423///
5424/// @return true if @p d is a class member, false otherwise.
5425bool
5427{return is_at_class_scope(d) || is_method_decl(d);}
5428
5429/// Tests if a declaration is a class member.
5430///
5431/// @param d the declaration to consider.
5432///
5433/// @return true if @p d is a class member, false otherwise.
5434bool
5436{return is_at_class_scope(d) || is_method_decl(d);}
5437
5438/// Test if a declaration is a @ref scope_decl.
5439///
5440/// @param d the declaration to take in account.
5441///
5442/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5443/// if d is a @ref scope_decl.
5444const scope_decl*
5446{return dynamic_cast<const scope_decl*>(d);}
5447
5448/// Test if a declaration is a @ref scope_decl.
5449///
5450/// @param d the declaration to take in account.
5451///
5452/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5453/// if d is a @ref scope_decl.
5455is_scope_decl(const decl_base_sptr& d)
5456{return dynamic_pointer_cast<scope_decl>(d);}
5457
5458/// Tests if a type is a class member.
5459///
5460/// @param t the type to consider.
5461///
5462/// @return true if @p t is a class member type, false otherwise.
5463bool
5464is_member_type(const type_base_sptr& t)
5465{
5466 decl_base_sptr d = get_type_declaration(t);
5467 return is_member_decl(d);
5468}
5469
5470/// Test if a type is user-defined.
5471///
5472/// A type is considered user-defined if it's a
5473/// struct/class/union/enum that is *NOT* artificial.
5474///
5475/// @param t the type to consider.
5476///
5477/// @return true iff the type @p t is user-defined.
5478bool
5480{
5481 if (t == 0)
5482 return false;
5483
5485 decl_base *d = is_decl(t);
5486
5488 && d && !d->get_is_artificial())
5489 return true;
5490
5491 return false;
5492}
5493
5494/// Test if a type is user-defined.
5495///
5496/// A type is considered user-defined if it's a
5497/// struct/class/union/enum.
5498///
5499///
5500/// @param t the type to consider.
5501///
5502/// @return true iff the type @p t is user-defined.
5503bool
5504is_user_defined_type(const type_base_sptr& t)
5505{return is_user_defined_type(t.get());}
5506
5507/// Gets the access specifier for a class member.
5508///
5509/// @param d the declaration of the class member to consider. Note
5510/// that this must be a class member otherwise the function aborts the
5511/// current process.
5512///
5513/// @return the access specifier for the class member @p d.
5516{
5518
5519 const context_rel* c = d.get_context_rel();
5520 ABG_ASSERT(c);
5521
5522 return c->get_access_specifier();
5523}
5524
5525/// Gets the access specifier for a class member.
5526///
5527/// @param d the declaration of the class member to consider. Note
5528/// that this must be a class member otherwise the function aborts the
5529/// current process.
5530///
5531/// @return the access specifier for the class member @p d.
5533get_member_access_specifier(const decl_base_sptr& d)
5534{return get_member_access_specifier(*d);}
5535
5536/// Sets the access specifier for a class member.
5537///
5538/// @param d the class member to set the access specifier for. Note
5539/// that this must be a class member otherwise the function aborts the
5540/// current process.
5541///
5542/// @param a the new access specifier to set the class member to.
5543void
5546{
5548
5550 ABG_ASSERT(c);
5551
5552 c->set_access_specifier(a);
5553}
5554
5555/// Sets the access specifier for a class member.
5556///
5557/// @param d the class member to set the access specifier for. Note
5558/// that this must be a class member otherwise the function aborts the
5559/// current process.
5560///
5561/// @param a the new access specifier to set the class member to.
5562void
5563set_member_access_specifier(const decl_base_sptr& d,
5566
5567/// Gets a flag saying if a class member is static or not.
5568///
5569/// @param d the declaration for the class member to consider. Note
5570/// that this must be a class member otherwise the function aborts the
5571/// current process.
5572///
5573/// @return true if the class member @p d is static, false otherwise.
5574bool
5576{
5578
5579 const context_rel* c = d.get_context_rel();
5580 ABG_ASSERT(c);
5581
5582 return c->get_is_static();
5583}
5584
5585/// Gets a flag saying if a class member is static or not.
5586///
5587/// @param d the declaration for the class member to consider. Note
5588/// that this must be a class member otherwise the function aborts the
5589/// current process.
5590///
5591/// @return true if the class member @p d is static, false otherwise.
5592bool
5594{return get_member_is_static(*d);}
5595
5596/// Gets a flag saying if a class member is static or not.
5597///
5598/// @param d the declaration for the class member to consider. Note
5599/// that this must be a class member otherwise the function aborts the
5600/// current process.
5601///
5602/// @return true if the class member @p d is static, false otherwise.
5603bool
5604get_member_is_static(const decl_base_sptr& d)
5605{return get_member_is_static(*d);}
5606
5607/// Test if a var_decl is a data member.
5608///
5609/// @param v the var_decl to consider.
5610///
5611/// @return true if @p v is data member, false otherwise.
5612bool
5614{return is_at_class_scope(v);}
5615
5616/// Test if a var_decl is a data member.
5617///
5618/// @param v the var_decl to consider.
5619///
5620/// @return true if @p v is data member, false otherwise.
5621bool
5623{return is_data_member(*v);}
5624
5625/// Test if a var_decl is a data member.
5626///
5627/// @param v the var_decl to consider.
5628///
5629/// @return true if @p v is data member, false otherwise.
5630bool
5632{return is_at_class_scope(d);}
5633
5634/// Test if a decl is a data member.
5635///
5636/// @param d the decl to consider.
5637///
5638/// @return a pointer to the data member iff @p d is a data member, or
5639/// a null pointer.
5641is_data_member(const decl_base_sptr& d)
5642{
5643 if (var_decl_sptr v = is_var_decl(d))
5644 {
5645 if (is_data_member(v))
5646 return v;
5647 }
5648 return var_decl_sptr();
5649}
5650
5651/// Test if a decl is a data member.
5652///
5653/// @param d the decl to consider.
5654///
5655/// @return a pointer to the data member iff @p d is a data member, or
5656/// a null pointer.
5659{
5660 if (var_decl_sptr v = is_var_decl(d))
5661 {
5662 if (is_data_member(v))
5663 return v;
5664 }
5665 return var_decl_sptr();
5666}
5667
5668/// Test if a decl is a data member.
5669///
5670/// @param d the decl to consider.
5671///
5672/// @return a pointer to the data member iff @p d is a data member, or
5673/// a null pointer.
5674var_decl*
5676{
5677 if (var_decl *v = is_var_decl(d))
5678 if (is_data_member(v))
5679 return v;
5680 return 0;
5681}
5682
5683/// Test if a decl is a data member.
5684///
5685/// @param d the decl to consider.
5686///
5687/// @return a pointer to the data member iff @p d is a data member, or
5688/// a null pointer.
5689var_decl*
5691{
5692 if (var_decl *v = is_var_decl(d))
5693 if (is_data_member(v))
5694 return v;
5695 return 0;
5696}
5697
5698/// Get the first non-anonymous data member of a given anonymous data
5699/// member.
5700///
5701/// E.g:
5702///
5703/// struct S
5704/// {
5705/// union // <-- for this anonymous data member, the function
5706/// // returns a.
5707/// {
5708/// int a;
5709/// charb;
5710/// };
5711/// };
5712///
5713/// @return anon_dm the anonymous data member to consider.
5714///
5715/// @return the first non-anonymous data member of @p anon_dm. If no
5716/// data member was found then this function returns @p anon_dm.
5717const var_decl_sptr
5719{
5720 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5721 return anon_dm;
5722
5723 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5724 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5725
5726 if (is_anonymous_data_member(first))
5728
5729 return first;
5730}
5731
5732/// In the context of a given class or union, this function returns
5733/// the data member that is located after a given data member.
5734///
5735/// @param klass the class or union to consider.
5736///
5737/// @param the data member to consider.
5738///
5739/// @return the data member that is located right after @p
5740/// data_member.
5741const var_decl_sptr
5743 const var_decl_sptr &data_member)
5744{
5745 if (!klass ||!data_member)
5746 return var_decl_sptr();
5747
5748 for (class_or_union::data_members::const_iterator it =
5749 klass->get_non_static_data_members().begin();
5750 it != klass->get_non_static_data_members().end();
5751 ++it)
5752 if (**it == *data_member)
5753 {
5754 ++it;
5755 if (it != klass->get_non_static_data_members().end())
5757 break;
5758 }
5759
5760 return var_decl_sptr();
5761}
5762
5763/// In the context of a given class or union, this function returns
5764/// the data member that is located after a given data member.
5765///
5766/// @param klass the class or union to consider.
5767///
5768/// @param the data member to consider.
5769///
5770/// @return the data member that is located right after @p
5771/// data_member.
5772const var_decl_sptr
5773get_next_data_member(const class_or_union_sptr& klass,
5774 const var_decl_sptr &data_member)
5775{return get_next_data_member(klass.get(), data_member);}
5776
5777/// Get the last data member of a class type.
5778///
5779/// @param klass the class type to consider.
5782{return klass.get_non_static_data_members().back();}
5783
5784/// Get the last data member of a class type.
5785///
5786/// @param klass the class type to consider.
5789{return get_last_data_member(*klass);}
5790
5791/// Get the last data member of a class type.
5792///
5793/// @param klass the class type to consider.
5795get_last_data_member(const class_or_union_sptr &klass)
5796{return get_last_data_member(klass.get());}
5797
5798/// Collect all the non-anonymous data members of a class or union type.
5799///
5800/// If the class contains any anonymous data member, this function
5801/// looks through it to collect the non-anonymous data members that it
5802/// contains. The function also looks through the base classes of the
5803/// current type.
5804///
5805/// @param cou the class or union type to consider.
5806///
5807/// @param dms output parameter. This is populated by the function
5808/// with a map containing the non-anonymous data members that were
5809/// collected. The key of the map is the name of the data member.
5810/// This is set iff the function returns true.
5811///
5812/// @return true iff at least one non-anonymous data member was
5813/// collected.
5814bool
5817{
5818 if (!cou)
5819 return false;
5820
5821 bool result = false;
5822 class_decl* klass = is_class_type(cou);
5823 if (klass)
5824 // First look into base classes for data members.
5826 result |= collect_non_anonymous_data_members(base->get_base_class().get(), dms);
5827
5828 // Then look into our data members
5829 for (var_decl_sptr member : cou->get_non_static_data_members())
5830 {
5831 if (is_anonymous_data_member(member))
5832 {
5833 class_or_union_sptr cl = anonymous_data_member_to_class_or_union(member);
5834 ABG_ASSERT(cl);
5835 result |= collect_non_anonymous_data_members(cl.get(), dms);
5836 }
5837 else
5838 {
5839 dms[member->get_name()] = member;
5840 result = true;
5841 }
5842 }
5843 return true;
5844}
5845
5846/// Collect all the non-anonymous data members of a class or union type.
5847///
5848/// If the class contains any anonymous data member, this function
5849/// looks through it to collect the non-anonymous data members that it
5850/// contains. The function also also looks through the base classes
5851/// of the current type.
5852///
5853/// @param cou the class or union type to consider.
5854///
5855/// @param dms output parameter. This is populated by the function
5856/// with a map containing the non-anonymous data members that were
5857/// collected. The key of the map is the name of the data member.
5858/// This is set iff the function returns true.
5859///
5860/// @return true iff at least one non-anonymous data member was
5861/// collected.
5862bool
5864{return collect_non_anonymous_data_members(cou.get(), dms);}
5865
5866/// Test if a decl is an anonymous data member.
5867///
5868/// @param d the decl to consider.
5869///
5870/// @return true iff @p d is an anonymous data member.
5871bool
5873{return is_anonymous_data_member(&d);}
5874
5875/// Test if a decl is an anonymous data member.
5876///
5877/// @param d the decl to consider.
5878///
5879/// @return the var_decl representing the data member iff @p d is an
5880/// anonymous data member.
5881const var_decl*
5883{
5884 if (const var_decl* v = is_data_member(d))
5885 {
5887 return v;
5888 }
5889 return 0;
5890}
5891
5892/// Test if a decl is an anonymous data member.
5893///
5894/// @param d the decl to consider.
5895///
5896/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5897/// it's an anonymous data member. Otherwise returns a nil pointer.
5898const var_decl*
5900{
5901 if (const var_decl* v = is_data_member(d))
5902 {
5904 return v;
5905 }
5906 return 0;
5907}
5908
5909/// Test if a decl is an anonymous data member.
5910///
5911/// @param d the decl to consider.
5912///
5913/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5914/// it's an anonymous data member. Otherwise returns a nil pointer.
5917{
5918 if (var_decl_sptr v = is_data_member(d))
5919 {
5921 return v;
5922 }
5923 return var_decl_sptr();
5924}
5925
5926/// Test if a decl is an anonymous data member.
5927///
5928/// @param d the decl to consider.
5929///
5930/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5931/// it's an anonymous data member. Otherwise returns a nil pointer.
5933is_anonymous_data_member(const decl_base_sptr& d)
5934{
5935 if (var_decl_sptr v = is_data_member(d))
5936 return is_anonymous_data_member(v);
5937 return var_decl_sptr();
5938}
5939
5940/// Test if a @ref var_decl is an anonymous data member.
5941///
5942/// @param d the @ref var_decl to consider.
5943///
5944/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5945/// it's an anonymous data member. Otherwise returns a nil pointer.
5948{
5949 if (is_anonymous_data_member(d.get()))
5950 return d;
5951 return var_decl_sptr();
5952}
5953
5954/// Test if a @ref var_decl is an anonymous data member.
5955///
5956/// @param d the @ref var_decl to consider.
5957///
5958/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5959/// it's an anonymous data member. Otherwise returns a nil pointer.
5960const var_decl*
5962{
5963 if (d && is_anonymous_data_member(*d))
5964 return d;
5965 return 0;
5966}
5967
5968/// Test if a @ref var_decl is an anonymous data member.
5969///
5970/// @param d the @ref var_decl to consider.
5971///
5972/// @return true iff @p d is an anonymous data member.
5973bool
5975{
5976 return (is_data_member(d)
5977 && d.get_is_anonymous()
5978 && d.get_name().empty()
5980}
5981
5982/// Test if a @ref var_decl is a data member belonging to an anonymous
5983/// type.
5984///
5985/// @param d the @ref var_decl to consider.
5986///
5987/// @return true iff @p d is a data member belonging to an anonymous
5988/// type.
5989bool
5991{
5992 if (is_data_member(d))
5993 {
5994 scope_decl* scope = d.get_scope();
5995 if (scope && scope->get_is_anonymous())
5996 return true;
5997 }
5998 return false;
5999}
6000
6001/// Test if a @ref var_decl is a data member belonging to an anonymous
6002/// type.
6003///
6004/// @param d the @ref var_decl to consider.
6005///
6006/// @return true iff @p d is a data member belonging to an anonymous
6007/// type.
6008bool
6011
6012/// Test if a @ref var_decl is a data member belonging to an anonymous
6013/// type.
6014///
6015/// @param d the @ref var_decl to consider.
6016///
6017/// @return true iff @p d is a data member belonging to an anonymous
6018/// type.
6019bool
6022
6023/// Get the @ref class_or_union type of a given anonymous data member.
6024///
6025/// @param d the anonymous data member to consider.
6026///
6027/// @return the @ref class_or_union type of the anonymous data member
6028/// @p d.
6031{
6032 if ((d = is_anonymous_data_member(d)))
6033 return is_class_or_union_type(d->get_type().get());
6034 return 0;
6035}
6036
6037/// Get the @ref class_or_union type of a given anonymous data member.
6038///
6039/// @param d the anonymous data member to consider.
6040///
6041/// @return the @ref class_or_union type of the anonymous data member
6042/// @p d.
6043class_or_union_sptr
6045{
6047 return is_class_or_union_type(d.get_type());
6048 return class_or_union_sptr();
6049}
6050
6051/// Test if a data member has annonymous type or not.
6052///
6053/// @param d the data member to consider.
6054///
6055/// @return the anonymous class or union type iff @p turns out to have
6056/// an anonymous type. Otherwise, returns nil.
6057const class_or_union_sptr
6059{
6060 if (is_data_member(d))
6061 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
6062 if (cou->get_is_anonymous())
6063 return cou;
6064
6065 return class_or_union_sptr();
6066}
6067
6068/// Test if a data member has annonymous type or not.
6069///
6070/// @param d the data member to consider.
6071///
6072/// @return the anonymous class or union type iff @p turns out to have
6073/// an anonymous type. Otherwise, returns nil.
6074const class_or_union_sptr
6076{
6077 if (d)
6079 return class_or_union_sptr();
6080}
6081
6082/// Test if a data member has annonymous type or not.
6083///
6084/// @param d the data member to consider.
6085///
6086/// @return the anonymous class or union type iff @p turns out to have
6087/// an anonymous type. Otherwise, returns nil.
6088const class_or_union_sptr
6090{return data_member_has_anonymous_type(d.get());}
6091
6092/// Get the @ref class_or_union type of a given anonymous data member.
6093///
6094/// @param d the anonymous data member to consider.
6095///
6096/// @return the @ref class_or_union type of the anonymous data member
6097/// @p d.
6098class_or_union_sptr
6100{
6102 return is_class_or_union_type(v->get_type());
6103 return class_or_union_sptr();
6104}
6105
6106/// Test if a given anonymous data member exists in a class or union.
6107///
6108/// @param anon_dm the anonymous data member to consider.
6109///
6110/// @param clazz the class to consider.
6111///
6112/// @return true iff @p anon_dm exists in the @clazz.
6113bool
6115 const class_or_union& clazz)
6116{
6117 if (!anon_dm.get_is_anonymous()
6118 || !is_class_or_union_type(anon_dm.get_type()))
6119 return false;
6120
6121 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
6122 ABG_ASSERT(cl);
6123
6124 // Look for the presence of each data member of anon_dm in clazz.
6125 //
6126 // If one data member of anon_dm is not present in clazz, then the
6127 // data member anon_dm is considered to not exist in clazz.
6128 for (auto anon_dm_m : cl->get_non_static_data_members())
6129 {
6130 // If the data member anon_dm_m is not an anonymous data member,
6131 // it's easy to look for it.
6132 if (!is_anonymous_data_member(anon_dm_m))
6133 {
6134 if (!clazz.find_data_member(anon_dm_m->get_name()))
6135 return false;
6136 }
6137 // If anon_dm_m is itself an anonymous data member then recurse
6138 else
6139 {
6140 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
6141 return false;
6142 }
6143 }
6144
6145 return true;
6146}
6147
6148/// Test if a given decl is anonymous or has a naming typedef.
6149///
6150/// @param d the decl to consider.
6151///
6152/// @return true iff @p d is anonymous or has a naming typedef.
6153bool
6155{
6156 if (d.get_is_anonymous() || d.get_naming_typedef())
6157 return true;
6158 return false;
6159}
6160
6161/// Set the offset of a data member into its containing class.
6162///
6163/// @param m the data member to consider.
6164///
6165/// @param o the offset, in bits.
6166void
6168{
6170
6171 dm_context_rel* ctxt_rel =
6172 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6173 ABG_ASSERT(ctxt_rel);
6174
6175 ctxt_rel->set_offset_in_bits(o);
6176}
6177
6178/// Get the offset of a data member.
6179///
6180/// @param m the data member to consider.
6181///
6182/// @return the offset (in bits) of @p m in its containing class.
6183uint64_t
6185{
6187 const dm_context_rel* ctxt_rel =
6188 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6189 ABG_ASSERT(ctxt_rel);
6190 return ctxt_rel->get_offset_in_bits();
6191}
6192
6193/// Get the offset of a data member.
6194///
6195/// @param m the data member to consider.
6196///
6197/// @return the offset (in bits) of @p m in its containing class.
6198uint64_t
6200{return get_data_member_offset(*m);}
6201
6202/// Get the offset of a data member.
6203///
6204/// @param m the data member to consider.
6205///
6206/// @return the offset (in bits) of @p m in its containing class.
6207uint64_t
6208get_data_member_offset(const decl_base_sptr d)
6209{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6210
6211/// Get the offset of the non-static data member that comes after a
6212/// given one.
6213///
6214/// If there is no data member after after the one given to this
6215/// function (maybe because the given one is the last data member of
6216/// the class type) then the function return false.
6217///
6218/// @param klass the class to consider.
6219///
6220/// @param dm the data member before the one we want to retrieve.
6221///
6222/// @param offset out parameter. This parameter is set by the
6223/// function to the offset of the data member that comes right after
6224/// the data member @p dm, iff the function returns true.
6225///
6226/// @return true iff the data member coming right after @p dm was
6227/// found.
6228bool
6230 const var_decl_sptr& dm,
6231 uint64_t& offset)
6232{
6233 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6234 if (!next_dm)
6235 return false;
6236 offset = get_data_member_offset(next_dm);
6237 return true;
6238}
6239
6240/// Get the offset of the non-static data member that comes after a
6241/// given one.
6242///
6243/// If there is no data member after after the one given to this
6244/// function (maybe because the given one is the last data member of
6245/// the class type) then the function return false.
6246///
6247/// @param klass the class to consider.
6248///
6249/// @param dm the data member before the one we want to retrieve.
6250///
6251/// @param offset out parameter. This parameter is set by the
6252/// function to the offset of the data member that comes right after
6253/// the data member @p dm, iff the function returns true.
6254///
6255/// @return true iff the data member coming right after @p dm was
6256/// found.
6257bool
6258get_next_data_member_offset(const class_or_union_sptr& klass,
6259 const var_decl_sptr& dm,
6260 uint64_t& offset)
6261{return get_next_data_member_offset(klass.get(), dm, offset);}
6262
6263/// Get the absolute offset of a data member.
6264///
6265/// If the data member is part of an anonymous data member then this
6266/// returns the absolute offset -- relative to the beginning of the
6267/// containing class of the anonymous data member.
6268///
6269/// @param m the data member to consider.
6270///
6271/// @return the aboslute offset of the data member @p m.
6272uint64_t
6274{
6276 const dm_context_rel* ctxt_rel =
6277 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6278 ABG_ASSERT(ctxt_rel);
6279
6280 const var_decl *containing_anonymous_data_member =
6281 ctxt_rel->get_anonymous_data_member();
6282
6283 uint64_t containing_anonymous_data_member_offset = 0;
6284 if (containing_anonymous_data_member)
6285 containing_anonymous_data_member_offset =
6286 get_absolute_data_member_offset(*containing_anonymous_data_member);
6287
6288 return (ctxt_rel->get_offset_in_bits()
6289 +
6290 containing_anonymous_data_member_offset);
6291}
6292
6293/// Get the absolute offset of a data member.
6294///
6295/// If the data member is part of an anonymous data member then this
6296/// returns the absolute offset -- relative to the beginning of the
6297/// containing class of the anonymous data member.
6298///
6299/// @param m the data member to consider.
6300///
6301/// @return the aboslute offset of the data member @p m.
6302uint64_t
6304{
6305 if (!m)
6306 return 0;
6308}
6309
6310/// Get the size of a given variable.
6311///
6312/// @param v the variable to consider.
6313///
6314/// @return the size of variable @p v.
6315uint64_t
6317{
6318 type_base_sptr t = v->get_type();
6319 ABG_ASSERT(t);
6320
6321 return t->get_size_in_bits();
6322}
6323
6324/// Set a flag saying if a data member is laid out.
6325///
6326/// @param m the data member to consider.
6327///
6328/// @param l true if @p m is to be considered as laid out.
6329void
6331{
6333 dm_context_rel* ctxt_rel =
6334 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6335 ctxt_rel->set_is_laid_out(l);
6336}
6337
6338/// Test whether a data member is laid out.
6339///
6340/// @param m the data member to consider.
6341///
6342/// @return true if @p m is laid out, false otherwise.
6343bool
6345{
6347 const dm_context_rel* ctxt_rel =
6348 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6349
6350 return ctxt_rel->get_is_laid_out();
6351}
6352
6353/// Test whether a data member is laid out.
6354///
6355/// @param m the data member to consider.
6356///
6357/// @return true if @p m is laid out, false otherwise.
6358bool
6360{return get_data_member_is_laid_out(*m);}
6361
6362/// Test whether a function_decl is a member function.
6363///
6364/// @param f the function_decl to test.
6365///
6366/// @return true if @p f is a member function, false otherwise.
6367bool
6369{return is_member_decl(f);}
6370
6371/// Test whether a function_decl is a member function.
6372///
6373/// @param f the function_decl to test.
6374///
6375/// @return true if @p f is a member function, false otherwise.
6376bool
6378{return is_member_decl(*f);}
6379
6380/// Test whether a function_decl is a member function.
6381///
6382/// @param f the function_decl to test.
6383///
6384/// @return true if @p f is a member function, false otherwise.
6385bool
6387{return is_member_decl(*f);}
6388
6389/// Test whether a member function is a constructor.
6390///
6391/// @param f the member function to test.
6392///
6393/// @return true if @p f is a constructor, false otherwise.
6394bool
6396{
6398
6399 const method_decl* m = is_method_decl(&f);
6400 ABG_ASSERT(m);
6401
6402 const mem_fn_context_rel* ctxt =
6403 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6404
6405 return ctxt->is_constructor();
6406}
6407
6408/// Test whether a member function is a constructor.
6409///
6410/// @param f the member function to test.
6411///
6412/// @return true if @p f is a constructor, false otherwise.
6413bool
6415{return get_member_function_is_ctor(*f);}
6416
6417
6418/// Setter for the is_ctor property of the member function.
6419///
6420/// @param f the member function to set.
6421///
6422/// @param f the new boolean value of the is_ctor property. Is true
6423/// if @p f is a constructor, false otherwise.
6424void
6426{
6428
6429 method_decl* m = is_method_decl(&f);
6430 ABG_ASSERT(m);
6431
6432 mem_fn_context_rel* ctxt =
6433 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6434
6435 ctxt->is_constructor(c);
6436}
6437
6438/// Setter for the is_ctor property of the member function.
6439///
6440/// @param f the member function to set.
6441///
6442/// @param f the new boolean value of the is_ctor property. Is true
6443/// if @p f is a constructor, false otherwise.
6444void
6447
6448/// Test whether a member function is a destructor.
6449///
6450/// @param f the function to test.
6451///
6452/// @return true if @p f is a destructor, false otherwise.
6453bool
6455{
6457
6458 const method_decl* m = is_method_decl(&f);
6459 ABG_ASSERT(m);
6460
6461 const mem_fn_context_rel* ctxt =
6462 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6463
6464 return ctxt->is_destructor();
6465}
6466
6467/// Test whether a member function is a destructor.
6468///
6469/// @param f the function to test.
6470///
6471/// @return true if @p f is a destructor, false otherwise.
6472bool
6474{return get_member_function_is_dtor(*f);}
6475
6476/// Set the destructor-ness property of a member function.
6477///
6478/// @param f the function to set.
6479///
6480/// @param d true if @p f is a destructor, false otherwise.
6481void
6483{
6485
6486 method_decl* m = is_method_decl(&f);
6487 ABG_ASSERT(m);
6488
6489 mem_fn_context_rel* ctxt =
6490 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6491
6492 ctxt->is_destructor(d);
6493}
6494
6495/// Set the destructor-ness property of a member function.
6496///
6497/// @param f the function to set.
6498///
6499/// @param d true if @p f is a destructor, false otherwise.
6500void
6503
6504/// Test whether a member function is const.
6505///
6506/// @param f the function to test.
6507///
6508/// @return true if @p f is const, false otherwise.
6509bool
6511{
6513
6514 const method_decl* m = is_method_decl(&f);
6515 ABG_ASSERT(m);
6516
6517 const mem_fn_context_rel* ctxt =
6518 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6519
6520 return ctxt->is_const();
6521}
6522
6523/// Test whether a member function is const.
6524///
6525/// @param f the function to test.
6526///
6527/// @return true if @p f is const, false otherwise.
6528bool
6530{return get_member_function_is_const(*f);}
6531
6532/// set the const-ness property of a member function.
6533///
6534/// @param f the function to set.
6535///
6536/// @param is_const the new value of the const-ness property of @p f
6537void
6539{
6541
6542 method_decl* m = is_method_decl(&f);
6543 ABG_ASSERT(m);
6544
6545 mem_fn_context_rel* ctxt =
6546 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6547
6548 ctxt->is_const(is_const);
6549}
6550
6551/// set the const-ness property of a member function.
6552///
6553/// @param f the function to set.
6554///
6555/// @param is_const the new value of the const-ness property of @p f
6556void
6558{set_member_function_is_const(*f, is_const);}
6559
6560/// Test if a virtual member function has a vtable offset set.
6561///
6562/// @param f the virtual member function to consider.
6563///
6564/// @return true iff the virtual member function has its vtable offset
6565/// set, i.e, if the vtable offset of @p is different from -1.
6566bool
6568{return get_member_function_vtable_offset(f) != -1;}
6569
6570/// Get the vtable offset of a member function.
6571///
6572/// @param f the member function to consider.
6573///
6574/// @return the vtable offset of @p f. Note that a vtable offset of
6575/// value -1 means that the member function does *NOT* yet have a
6576/// vtable offset associated to it.
6577ssize_t
6579{
6581
6582 const method_decl* m =
6583 dynamic_cast<const method_decl*>(&f);
6584 ABG_ASSERT(m);
6585
6586 const mem_fn_context_rel* ctxt =
6587 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6588
6589 return ctxt->vtable_offset();
6590}
6591
6592/// Get the vtable offset of a member function.
6593///
6594/// @param f the member function to consider.
6595///
6596/// @return the vtable offset of @p f. Note that a vtable offset of
6597/// value -1 means that the member function does *NOT* yet have a
6598/// vtable offset associated to it.
6599ssize_t
6602
6603/// Set the vtable offset of a member function.
6604///
6605/// @param f the member function to consider.
6606///
6607/// @param s the new vtable offset. Please note that a vtable offset
6608/// of value -1 means that the virtual member function does not (yet)
6609/// have any vtable offset associated to it.
6610static void
6611set_member_function_vtable_offset(function_decl& f, ssize_t s)
6612{
6614
6615 method_decl* m = is_method_decl(&f);
6616 ABG_ASSERT(m);
6617
6618 mem_fn_context_rel* ctxt =
6619 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6620
6621 ctxt->vtable_offset(s);
6622}
6623
6624/// Get the vtable offset of a member function.
6625///
6626/// @param f the member function to consider.
6627///
6628/// @param s the new vtable offset. Please note that a vtable offset
6629/// of value -1 means that the virtual member function does not (yet)
6630/// have any vtable offset associated to it.
6631static void
6632set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
6633{return set_member_function_vtable_offset(*f, s);}
6634
6635/// Test if a given member function is virtual.
6636///
6637/// @param mem_fn the member function to consider.
6638///
6639/// @return true iff a @p mem_fn is virtual.
6640bool
6642{
6644
6645 const method_decl* m =
6646 dynamic_cast<const method_decl*>(&f);
6647 ABG_ASSERT(m);
6648
6649 const mem_fn_context_rel* ctxt =
6650 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6651
6652 return ctxt->is_virtual();
6653}
6654
6655/// Test if a given member function is virtual.
6656///
6657/// @param mem_fn the member function to consider.
6658///
6659/// @return true iff a @p mem_fn is virtual.
6660bool
6662{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6663
6664/// Test if a given member function is virtual.
6665///
6666/// @param mem_fn the member function to consider.
6667///
6668/// @return true iff a @p mem_fn is virtual.
6669bool
6671{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6672
6673/// Set the virtual-ness of a member function.
6674///
6675/// @param f the member function to consider.
6676///
6677/// @param is_virtual set to true if the function is virtual.
6678static void
6679set_member_function_is_virtual(function_decl& f, bool is_virtual)
6680{
6682
6683 method_decl* m = is_method_decl(&f);
6684 ABG_ASSERT(m);
6685
6686 mem_fn_context_rel* ctxt =
6687 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6688
6689 ctxt->is_virtual(is_virtual);
6690}
6691
6692/// Set the virtual-ness of a member function.
6693///
6694/// @param f the member function to consider.
6695///
6696/// @param is_virtual set to true if the function is virtual.
6697static void
6698set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
6699{
6700 if (fn)
6701 {
6702 set_member_function_is_virtual(*fn, is_virtual);
6704 }
6705}
6706
6707/// Set the virtual-ness of a member fcuntion
6708///
6709/// @param fn the member function to consider.
6710///
6711/// @param is_virtual whether the function is virtual.
6712///
6713/// @param voffset the virtual offset of the virtual function.
6714void
6716 bool is_virtual,
6717 ssize_t voffset)
6718{
6719 // Setting the offset must come first because the second function
6720 // does assume the voffset is set, in case of virtuality
6721 set_member_function_vtable_offset(fn, voffset);
6722 set_member_function_is_virtual(fn, is_virtual);
6723}
6724
6725/// Set the virtual-ness of a member fcuntion
6726///
6727/// @param fn the member function to consider.
6728///
6729/// @param is_virtual whether the function is virtual.
6730///
6731/// @param voffset the virtual offset of the virtual function.
6732void
6734 bool is_virtual,
6735 ssize_t voffset)
6736{
6737 if (fn)
6738 set_member_function_virtuality(*fn, is_virtual, voffset);
6739}
6740
6741/// Set the virtual-ness of a member fcuntion
6742///
6743/// @param fn the member function to consider.
6744///
6745/// @param is_virtual whether the function is virtual.
6746///
6747/// @param voffset the virtual offset of the virtual function.
6748void
6750 bool is_virtual,
6751 ssize_t voffset)
6752{
6753 set_member_function_vtable_offset(fn, voffset);
6754 set_member_function_is_virtual(fn, is_virtual);
6755}
6756
6757/// Recursively returns the the underlying type of a typedef. The
6758/// return type should not be a typedef of anything anymore.
6759///
6760///
6761/// Also recursively strip typedefs from the sub-types of the type
6762/// given in arguments.
6763///
6764/// Note that this function builds types in which typedefs are
6765/// stripped off. Usually, types are held by their scope, so their
6766/// life time is bound to the life time of their scope. But as this
6767/// function cannot really insert the built type into it's scope, it
6768/// must ensure that the newly built type stays live long enough.
6769///
6770/// So, if the newly built type has a canonical type, this function
6771/// returns the canonical type. Otherwise, this function ensure that
6772/// the newly built type has a life time that is the same as the life
6773/// time of the entire libabigail library.
6774///
6775/// @param type the type to strip the typedefs from.
6776///
6777/// @return the resulting type stripped from its typedefs, or just
6778/// return @p type if it has no typedef in any of its sub-types.
6779type_base_sptr
6780strip_typedef(const type_base_sptr type)
6781{
6782 if (!type)
6783 return type;
6784
6785 // If type is a class type then do not try to strip typedefs from it.
6786 // And if it has no canonical type (which can mean that it's a
6787 // declaration-only class), then, make sure its live for ever and
6788 // return it.
6789 if (class_decl_sptr cl = is_class_type(type))
6790 {
6791 if (!cl->get_canonical_type())
6792 keep_type_alive(type);
6793 return type;
6794 }
6795
6796 const environment& env = type->get_environment();
6797 type_base_sptr t = type;
6798
6799 if (const typedef_decl_sptr ty = is_typedef(t))
6800 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6801 else if (const reference_type_def_sptr ty = is_reference_type(t))
6802 {
6803 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6804 env));
6805 ABG_ASSERT(p);
6806 t.reset(new reference_type_def(p,
6807 ty->is_lvalue(),
6808 ty->get_size_in_bits(),
6809 ty->get_alignment_in_bits(),
6810 ty->get_location()));
6811 }
6812 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6813 {
6814 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6815 env));
6816 ABG_ASSERT(p);
6817 t.reset(new pointer_type_def(p,
6818 ty->get_size_in_bits(),
6819 ty->get_alignment_in_bits(),
6820 ty->get_location()));
6821 }
6822 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6823 {
6824 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6825 env));
6826 ABG_ASSERT(p);
6827 t.reset(new qualified_type_def(p,
6828 ty->get_cv_quals(),
6829 ty->get_location()));
6830 }
6831 else if (const array_type_def_sptr ty = is_array_type(t))
6832 {
6833 type_base_sptr p = strip_typedef(ty->get_element_type());
6834 ABG_ASSERT(p);
6835 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6836 }
6837 else if (const method_type_sptr ty = is_method_type(t))
6838 {
6840 for (function_decl::parameters::const_iterator i =
6841 ty->get_parameters().begin();
6842 i != ty->get_parameters().end();
6843 ++i)
6844 {
6846 type_base_sptr typ = strip_typedef(p->get_type());
6847 ABG_ASSERT(typ);
6849 (new function_decl::parameter(typ,
6850 p->get_index(),
6851 p->get_name(),
6852 p->get_location(),
6853 p->get_variadic_marker(),
6854 p->get_is_artificial()));
6855 parm.push_back(stripped);
6856 }
6857 type_base_sptr p = strip_typedef(ty->get_return_type());
6858 ABG_ASSERT(!!p == !!ty->get_return_type());
6859 t.reset(new method_type(p, ty->get_class_type(),
6860 parm, ty->get_is_const(),
6861 ty->get_size_in_bits(),
6862 ty->get_alignment_in_bits()));
6863 }
6864 else if (const function_type_sptr ty = is_function_type(t))
6865 {
6867 for (function_decl::parameters::const_iterator i =
6868 ty->get_parameters().begin();
6869 i != ty->get_parameters().end();
6870 ++i)
6871 {
6873 type_base_sptr typ = strip_typedef(p->get_type());
6874 ABG_ASSERT(typ);
6876 (new function_decl::parameter(typ,
6877 p->get_index(),
6878 p->get_name(),
6879 p->get_location(),
6880 p->get_variadic_marker(),
6881 p->get_is_artificial()));
6882 parm.push_back(stripped);
6883 }
6884 type_base_sptr p = strip_typedef(ty->get_return_type());
6885 ABG_ASSERT(!!p == !!ty->get_return_type());
6886 t.reset(new function_type(p, parm,
6887 ty->get_size_in_bits(),
6888 ty->get_alignment_in_bits()));
6889 }
6890
6891 if (!t->get_translation_unit())
6892 t->set_translation_unit(type->get_translation_unit());
6893
6894 if (!(type->get_canonical_type() && canonicalize(t)))
6895 keep_type_alive(t);
6896
6897 return t->get_canonical_type() ? t->get_canonical_type() : t;
6898}
6899
6900/// Strip qualification from a qualified type, when it makes sense.
6901///
6902/// DWARF constructs "const reference". This is redundant because a
6903/// reference is always const. It also constructs the useless "const
6904/// void" type. The issue is these redundant types then leak into the
6905/// IR and make for bad diagnostics.
6906///
6907/// This function thus strips the const qualifier from the type in
6908/// that case. It might contain code to strip other cases like this
6909/// in the future.
6910///
6911/// @param t the type to strip const qualification from.
6912///
6913/// @return the stripped type or just return @p t.
6914decl_base_sptr
6915strip_useless_const_qualification(const qualified_type_def_sptr t)
6916{
6917 if (!t)
6918 return t;
6919
6920 decl_base_sptr result = t;
6921 type_base_sptr u = t->get_underlying_type();
6922 const environment& env = t->get_environment();
6923
6924 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6925 && (is_reference_type(u)))
6926 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6927 && env.is_void_type(u))
6928 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6929 // Let's strip the const qualifier because a reference is always
6930 // 'const' and a const void doesn't make sense. They will just
6931 // lead to spurious changes later down the pipeline, that we'll
6932 // have to deal with by doing painful and error-prone editing of
6933 // the diff IR. Dropping that useless and inconsistent artefact
6934 // right here seems to be a good way to go.
6935 result = is_decl(u);
6936
6937 return result;
6938}
6939
6940/// Merge redundant qualifiers from a tree of qualified types.
6941///
6942/// Suppose a tree of qualified types leads to:
6943///
6944/// const virtual const restrict const int;
6945///
6946/// Suppose the IR tree of qualified types ressembles (with C meaning
6947/// const, V meaning virtual and R meaning restrict):
6948///
6949/// [C|V]-->[C|R] -->[C] --> [int].
6950///
6951/// This function walks the IR and remove the redundant CV qualifiers
6952/// so the IR becomes:
6953///
6954/// [C|V] --> [R] --> [] -->[int].
6955///
6956/// Note that the empty qualified type (noted []) represents a
6957/// qualified type with no qualifier. It's rare, but it can exist.
6958/// I've put it here just for the sake of example.
6959///
6960/// The resulting IR thus represents the (merged) type:
6961///
6962/// const virtual restrict int.
6963///
6964/// This function is a sub-routine of the overload @ref
6965/// strip_useless_const_qualification which doesn't return any value.
6966///
6967/// @param t the qualified type to consider.
6968///
6969/// @param redundant_quals the (redundant) qualifiers to be removed
6970/// from the qualifiers of the underlying types of @p t.
6971///
6972/// @return the underlying type of @p t which might have had its
6973/// redundant qualifiers removed.
6974static qualified_type_def_sptr
6975strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
6976 qualified_type_def::CV redundant_quals)
6977{
6978 if (!t)
6979 return t;
6980
6981 // We must NOT edit canonicalized types.
6982 ABG_ASSERT(!t->get_canonical_type());
6983
6984 qualified_type_def_sptr underlying_qualified_type =
6985 is_qualified_type(t->get_underlying_type());
6986
6987 // Let's build 'currated qualifiers' that are the qualifiers of the
6988 // current type from which redundant qualifiers are removed.
6989 qualified_type_def::CV currated_quals = t->get_cv_quals();
6990
6991 // Remove the redundant qualifiers from these currated qualifiers
6992 currated_quals &= ~redundant_quals;
6993 t->set_cv_quals(currated_quals);
6994
6995 // The redundant qualifiers, moving forward, is now the union of the
6996 // previous set of redundant qualifiers and the currated qualifiers.
6997 redundant_quals |= currated_quals;
6998
6999 qualified_type_def_sptr result = t;
7000 if (underlying_qualified_type)
7001 // Now remove the redundant qualifiers from the qualified types
7002 // potentially carried by the underlying type.
7003 result =
7004 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
7005 redundant_quals);
7006
7007 return result;
7008}
7009
7010/// Merge redundant qualifiers from a tree of qualified types.
7011///
7012/// Suppose a tree of qualified types leads to:
7013///
7014/// const virtual const restrict const int;
7015///
7016/// Suppose the IR tree of qualified types ressembles (with C meaning
7017/// const, V meaning virtual and R meaning restrict):
7018///
7019/// [C|V]-->[C|R] -->[C] --> [int].
7020///
7021/// This function walks the IR and remove the redundant CV qualifiers
7022/// so the IR becomes:
7023///
7024/// [C|V] --> [R] --> [] -->[int].
7025///
7026/// Note that the empty qualified type (noted []) represents a
7027/// qualified type with no qualifier. It's rare, but it can exist.
7028/// I've put it here just for the sake of example.
7029///
7030/// The resulting IR thus represents the (merged) type:
7031///
7032/// const virtual restrict int.
7033///
7034/// @param t the qualified type to consider. The IR below the
7035/// argument to this parameter will be edited to remove redundant
7036/// qualifiers where applicable.
7037void
7038strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
7039{
7040 if (!t)
7041 return;
7042
7043 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
7044 strip_redundant_quals_from_underyling_types(t, redundant_quals);
7045}
7046
7047/// Return the leaf underlying type node of a @ref typedef_decl node.
7048///
7049/// If the underlying type of a @ref typedef_decl node is itself a
7050/// @ref typedef_decl node, then recursively look at the underlying
7051/// type nodes to get the first one that is not a a @ref typedef_decl
7052/// node. This is what a leaf underlying type node means.
7053///
7054/// Otherwise, if the underlying type node of @ref typedef_decl is
7055/// *NOT* a @ref typedef_decl node, then just return the underlying
7056/// type node.
7057///
7058/// And if the type node considered is not a @ref typedef_decl node,
7059/// then just return it.
7060///
7061/// @return the leaf underlying type node of a @p type.
7062type_base_sptr
7063peel_typedef_type(const type_base_sptr& type)
7064{
7065 typedef_decl_sptr t = is_typedef(type);
7066 if (!t)
7067 return type;
7068
7069 if (is_typedef(t->get_underlying_type()))
7070 return peel_typedef_type(t->get_underlying_type());
7071 return t->get_underlying_type();
7072}
7073
7074/// Return the leaf underlying type node of a @ref typedef_decl node.
7075///
7076/// If the underlying type of a @ref typedef_decl node is itself a
7077/// @ref typedef_decl node, then recursively look at the underlying
7078/// type nodes to get the first one that is not a a @ref typedef_decl
7079/// node. This is what a leaf underlying type node means.
7080///
7081/// Otherwise, if the underlying type node of @ref typedef_decl is
7082/// *NOT* a @ref typedef_decl node, then just return the underlying
7083/// type node.
7084///
7085/// And if the type node considered is not a @ref typedef_decl node,
7086/// then just return it.
7087///
7088/// @return the leaf underlying type node of a @p type.
7089const type_base*
7091{
7092 const typedef_decl* t = is_typedef(type);
7093 if (!t)
7094 return type;
7095
7096 return peel_typedef_type(t->get_underlying_type()).get();
7097}
7098
7099/// Return the leaf pointed-to type node of a @ref pointer_type_def
7100/// node.
7101///
7102/// If the pointed-to type of a @ref pointer_type_def node is itself a
7103/// @ref pointer_type_def node, then recursively look at the
7104/// pointed-to type nodes to get the first one that is not a a @ref
7105/// pointer_type_def node. This is what a leaf pointed-to type node
7106/// means.
7107///
7108/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7109/// *NOT* a @ref pointer_type_def node, then just return the
7110/// pointed-to type node.
7111///
7112/// And if the type node considered is not a @ref pointer_type_def
7113/// node, then just return it.
7114///
7115/// @return the leaf pointed-to type node of a @p type.
7116type_base_sptr
7117peel_pointer_type(const type_base_sptr& type)
7118{
7120 if (!t)
7121 return type;
7122
7123 if (is_pointer_type(t->get_pointed_to_type()))
7124 return peel_pointer_type(t->get_pointed_to_type());
7125 return t->get_pointed_to_type();
7126}
7127
7128/// Return the leaf pointed-to type node of a @ref pointer_type_def
7129/// node.
7130///
7131/// If the pointed-to type of a @ref pointer_type_def node is itself a
7132/// @ref pointer_type_def node, then recursively look at the
7133/// pointed-to type nodes to get the first one that is not a a @ref
7134/// pointer_type_def node. This is what a leaf pointed-to type node
7135/// means.
7136///
7137/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7138/// *NOT* a @ref pointer_type_def node, then just return the
7139/// pointed-to type node.
7140///
7141/// And if the type node considered is not a @ref pointer_type_def
7142/// node, then just return it.
7143///
7144/// @return the leaf pointed-to type node of a @p type.
7145const type_base*
7147{
7148 const pointer_type_def* t = is_pointer_type(type);
7149 if (!t)
7150 return type;
7151
7152 return peel_pointer_type(t->get_pointed_to_type()).get();
7153}
7154
7155/// Return the leaf pointed-to type node of a @ref reference_type_def
7156/// node.
7157///
7158/// If the pointed-to type of a @ref reference_type_def node is itself
7159/// a @ref reference_type_def node, then recursively look at the
7160/// pointed-to type nodes to get the first one that is not a a @ref
7161/// reference_type_def node. This is what a leaf pointed-to type node
7162/// means.
7163///
7164/// Otherwise, if the pointed-to type node of @ref reference_type_def
7165/// is *NOT* a @ref reference_type_def node, then just return the
7166/// pointed-to type node.
7167///
7168/// And if the type node considered is not a @ref reference_type_def
7169/// node, then just return it.
7170///
7171/// @return the leaf pointed-to type node of a @p type.
7172type_base_sptr
7173peel_reference_type(const type_base_sptr& type)
7174{
7176 if (!t)
7177 return type;
7178
7179 if (is_reference_type(t->get_pointed_to_type()))
7180 return peel_reference_type(t->get_pointed_to_type());
7181 return t->get_pointed_to_type();
7182}
7183
7184/// Return the leaf pointed-to type node of a @ref reference_type_def
7185/// node.
7186///
7187/// If the pointed-to type of a @ref reference_type_def node is itself
7188/// a @ref reference_type_def node, then recursively look at the
7189/// pointed-to type nodes to get the first one that is not a a @ref
7190/// reference_type_def node. This is what a leaf pointed-to type node
7191/// means.
7192///
7193/// Otherwise, if the pointed-to type node of @ref reference_type_def
7194/// is *NOT* a @ref reference_type_def node, then just return the
7195/// pointed-to type node.
7196///
7197/// And if the type node considered is not a @ref reference_type_def
7198/// node, then just return it.
7199///
7200/// @return the leaf pointed-to type node of a @p type.
7201const type_base*
7203{
7204 const reference_type_def* t = is_reference_type(type);
7205 if (!t)
7206 return type;
7207
7208 return peel_reference_type(t->get_pointed_to_type()).get();
7209}
7210
7211/// Return the leaf element type of an array.
7212///
7213/// If the element type is itself an array, then recursively return
7214/// the element type of that array itself.
7215///
7216/// @param type the array type to consider. If this is not an array
7217/// type, this type is returned by the function.
7218///
7219/// @return the leaf element type of the array @p type, or, if it's
7220/// not an array type, then just return @p.
7221const type_base_sptr
7222peel_array_type(const type_base_sptr& type)
7223{
7224 const array_type_def_sptr t = is_array_type(type);
7225 if (!t)
7226 return type;
7227
7228 return peel_array_type(t->get_element_type());
7229}
7230
7231/// Return the leaf element type of an array.
7232///
7233/// If the element type is itself an array, then recursively return
7234/// the element type of that array itself.
7235///
7236/// @param type the array type to consider. If this is not an array
7237/// type, this type is returned by the function.
7238///
7239/// @return the leaf element type of the array @p type, or, if it's
7240/// not an array type, then just return @p.
7241const type_base*
7243{
7244 const array_type_def* t = is_array_type(type);
7245 if (!t)
7246 return type;
7247
7248 return peel_array_type(t->get_element_type()).get();
7249}
7250
7251/// Return the leaf underlying type of a qualified type.
7252///
7253/// If the underlying type is itself a qualified type, then
7254/// recursively return the first underlying type of that qualified
7255/// type to return the first underlying type that is not a qualified type.
7256///
7257/// If the underlying type is NOT a qualified type, then just return
7258/// that underlying type.
7259///
7260/// @param type the qualified type to consider.
7261///
7262/// @return the leaf underlying type.
7263const type_base*
7265{
7266 const qualified_type_def* t = is_qualified_type(type);
7267 if (!t)
7268 return type;
7269
7270 return peel_qualified_type(t->get_underlying_type().get());
7271}
7272
7273/// Return the leaf underlying type of a qualified type.
7274///
7275/// If the underlying type is itself a qualified type, then
7276/// recursively return the first underlying type of that qualified
7277/// type to return the first underlying type that is not a qualified type.
7278///
7279/// If the underlying type is NOT a qualified type, then just return
7280/// that underlying type.
7281///
7282/// @param type the qualified type to consider.
7283///
7284/// @return the leaf underlying type.
7285const type_base_sptr
7286peel_qualified_type(const type_base_sptr& type)
7287{
7288 const qualified_type_def_sptr t = is_qualified_type(type);
7289 if (!t)
7290 return type;
7291
7292 return peel_qualified_type(t->get_underlying_type());
7293}
7294
7295/// Test if a given qualified type is const.
7296///
7297/// @pram t the qualified type to consider.
7298///
7299/// @return true iff @p t is a const qualified type.
7300bool
7301is_const_qualified_type(const qualified_type_def_sptr& t)
7302{
7303 if (!t)
7304 return false;
7305
7306 if (t->get_cv_quals() == qualified_type_def::CV_CONST)
7307 return true;
7308
7309 return false;
7310}
7311
7312/// Test if a given type is const-qualified.
7313///
7314/// @pram t the type to consider.
7315///
7316/// @return true iff @p t is a const qualified type.
7317bool
7318is_const_qualified_type(const type_base_sptr& t)
7319{
7320 qualified_type_def_sptr q = is_qualified_type(t);
7321 if (!q)
7322 return false;
7323 return is_const_qualified_type(q);
7324}
7325
7326/// If a qualified type is const, then return its underlying type.
7327///
7328/// @param q the qualified type to consider.
7329///
7330/// @return the underlying type of @p q if it's a const-qualified
7331/// type, otherwise, return @p q itself.
7332type_base_sptr
7333peel_const_qualified_type(const qualified_type_def_sptr& q)
7334{
7335 if (!q)
7336 return q;
7337
7339 return q->get_underlying_type();
7340
7341 return q;
7342}
7343
7344/// Return the leaf underlying type of a qualified or typedef type.
7345///
7346/// If the underlying type is itself a qualified or typedef type, then
7347/// recursively return the first underlying type of that qualified or
7348/// typedef type to return the first underlying type that is not a
7349/// qualified or typedef type.
7350///
7351/// If the underlying type is NOT a qualified nor a typedef type, then
7352/// just return that underlying type.
7353///
7354/// @param type the qualified or typedef type to consider.
7355///
7356/// @return the leaf underlying type.
7357type_base*
7359{
7360 while (is_typedef(type) || is_qualified_type(type))
7361 {
7362 if (const typedef_decl* t = is_typedef(type))
7363 type = peel_typedef_type(t);
7364
7365 if (const qualified_type_def* t = is_qualified_type(type))
7366 type = peel_qualified_type(t);
7367 }
7368
7369 return const_cast<type_base*>(type);
7370}
7371
7372/// Return the leaf underlying type of a qualified or typedef type.
7373///
7374/// If the underlying type is itself a qualified or typedef type, then
7375/// recursively return the first underlying type of that qualified or
7376/// typedef type to return the first underlying type that is not a
7377/// qualified or typedef type.
7378///
7379/// If the underlying type is NOT a qualified nor a typedef type, then
7380/// just return that underlying type.
7381///
7382/// @param type the qualified or typedef type to consider.
7383///
7384/// @return the leaf underlying type.
7385type_base_sptr
7386peel_qualified_or_typedef_type(const type_base_sptr &t)
7387{
7388 type_base_sptr type = t;
7389 while (is_typedef(type) || is_qualified_type(type))
7390 {
7391 if (typedef_decl_sptr t = is_typedef(type))
7392 type = peel_typedef_type(t);
7393
7394 if (qualified_type_def_sptr t = is_qualified_type(type))
7395 type = peel_qualified_type(t);
7396 }
7397
7398 return type;
7399}
7400
7401/// Return the leaf underlying or pointed-to type node of a @ref
7402/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7403/// or @ref array_type_def node.
7404///
7405/// @param type the type to peel.
7406///
7407/// @return the leaf underlying or pointed-to type node of @p type.
7408type_base_sptr
7410{
7411 type_base_sptr typ = type;
7412 while (is_typedef(typ)
7413 || is_pointer_type(typ)
7414 || is_reference_type(typ)
7415 || is_array_type(typ))
7416 {
7417 if (typedef_decl_sptr t = is_typedef(typ))
7418 typ = peel_typedef_type(t);
7419
7421 typ = peel_pointer_type(t);
7422
7424 typ = peel_reference_type(t);
7425
7426 if (const array_type_def_sptr t = is_array_type(typ))
7427 typ = peel_array_type(t);
7428 }
7429
7430 return typ;
7431}
7432
7433/// Return the leaf underlying or pointed-to type node of a @ref
7434/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7435/// node.
7436///
7437/// @param type the type to peel.
7438///
7439/// @return the leaf underlying or pointed-to type node of @p type.
7440type_base*
7442{
7443 while (is_typedef(type)
7444 || is_pointer_type(type)
7445 || is_reference_type(type)
7446 || is_array_type(type))
7447 {
7448 if (const typedef_decl* t = is_typedef(type))
7449 type = peel_typedef_type(t);
7450
7451 if (const pointer_type_def* t = is_pointer_type(type))
7452 type = peel_pointer_type(t);
7453
7454 if (const reference_type_def* t = is_reference_type(type))
7455 type = peel_reference_type(t);
7456
7457 if (const array_type_def* t = is_array_type(type))
7458 type = peel_array_type(t);
7459 }
7460
7461 return const_cast<type_base*>(type);
7462}
7463
7464/// Return the leaf underlying or pointed-to type node of a @ref
7465/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7466/// node.
7467///
7468/// @param type the type to peel.
7469///
7470/// @return the leaf underlying or pointed-to type node of @p type.
7471type_base*
7473 bool peel_qual_type)
7474{
7475 while (is_typedef(type)
7476 || is_pointer_type(type)
7477 || is_reference_type(type)
7478 || is_array_type(type)
7479 || (peel_qual_type && is_qualified_type(type)))
7480 {
7481 if (const typedef_decl* t = is_typedef(type))
7482 type = peel_typedef_type(t);
7483
7484 if (const pointer_type_def* t = is_pointer_type(type))
7485 type = peel_pointer_type(t);
7486
7487 if (const reference_type_def* t = is_reference_type(type))
7488 type = peel_reference_type(t);
7489
7490 if (const array_type_def* t = is_array_type(type))
7491 type = peel_array_type(t);
7492
7493 if (peel_qual_type)
7494 if (const qualified_type_def* t = is_qualified_type(type))
7495 type = peel_qualified_type(t);
7496 }
7497
7498 return const_cast<type_base*>(type);
7499}
7500
7501/// Return the leaf underlying or pointed-to type node of a, @ref
7502/// pointer_type_def, @ref reference_type_def or @ref
7503/// qualified_type_def type node.
7504///
7505/// @param type the type to peel.
7506///
7507/// @param peel_qualified_type if true, also peel qualified types.
7508///
7509/// @return the leaf underlying or pointed-to type node of @p type.
7510type_base*
7512 bool peel_qual_type)
7513{
7514 while (is_pointer_type(type)
7515 || is_reference_type(type)
7516 || is_array_type(type)
7517 || (peel_qual_type && is_qualified_type(type)))
7518 {
7519 if (const pointer_type_def* t = is_pointer_type(type))
7520 type = peel_pointer_type(t);
7521
7522 if (const reference_type_def* t = is_reference_type(type))
7523 type = peel_reference_type(t);
7524
7525 if (const array_type_def* t = is_array_type(type))
7526 type = peel_array_type(t);
7527
7528 if (peel_qual_type)
7529 if (const qualified_type_def* t = is_qualified_type(type))
7530 type = peel_qualified_type(t);
7531 }
7532
7533 return const_cast<type_base*>(type);
7534}
7535
7536/// Clone an array type.
7537///
7538/// Note that the element type of the new array is shared witht the
7539/// old one.
7540///
7541/// @param array the array type to clone.
7542///
7543/// @return a newly built array type. Note that it needs to be added
7544/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7545/// bound to the one of that scope. Otherwise, its lifetime is bound
7546/// to the lifetime of its containing shared pointer.
7549{
7550 vector<array_type_def::subrange_sptr> subranges;
7551
7552 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7553 array->get_subranges().begin();
7554 i != array->get_subranges().end();
7555 ++i)
7556 {
7558 (new array_type_def::subrange_type(array->get_environment(),
7559 (*i)->get_name(),
7560 (*i)->get_lower_bound(),
7561 (*i)->get_upper_bound(),
7562 (*i)->get_underlying_type(),
7563 (*i)->get_location(),
7564 (*i)->get_language()));
7565 subrange->is_non_finite((*i)->is_non_finite());
7566 if (scope_decl *scope = (*i)->get_scope())
7567 add_decl_to_scope(subrange, scope);
7568 subranges.push_back(subrange);
7569 }
7570
7571 array_type_def_sptr result
7572 (new array_type_def(array->get_element_type(),
7573 subranges, array->get_location()));
7574
7575 return result;
7576}
7577
7578/// Clone a typedef type.
7579///
7580/// Note that the underlying type of the newly constructed typedef is
7581/// shared with the old one.
7582///
7583/// @param t the typedef to clone.
7584///
7585/// @return the newly constructed typedef. Note that it needs to be
7586/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7587/// to be bound to the one of that scope. Otherwise, its lifetime is
7588/// bound to the lifetime of its containing shared pointer.
7591{
7592 if (!t)
7593 return t;
7594
7595 typedef_decl_sptr result
7596 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7597 t->get_location(), t->get_linkage_name(),
7598 t->get_visibility()));
7599 return result;
7600}
7601
7602/// Clone a qualifiend type.
7603///
7604/// Note that underlying type of the newly constructed qualified type
7605/// is shared with the old one.
7606///
7607/// @param t the qualified type to clone.
7608///
7609/// @return the newly constructed qualified type. Note that it needs
7610/// to be added to a scope (e.g, using add_decl_to_scope) for its
7611/// lifetime to be bound to the one of that scope. Otherwise, its
7612/// lifetime is bound to the lifetime of its containing shared
7613/// pointer.
7614qualified_type_def_sptr
7615clone_qualified_type(const qualified_type_def_sptr& t)
7616{
7617 if (!t)
7618 return t;
7619
7620 qualified_type_def_sptr result
7621 (new qualified_type_def(t->get_underlying_type(),
7622 t->get_cv_quals(), t->get_location()));
7623
7624 return result;
7625}
7626
7627/// Clone a typedef, an array or a qualified tree.
7628///
7629/// @param type the typedef, array or qualified tree to clone. any
7630/// order.
7631///
7632/// @return the cloned type, or NULL if @type was neither a typedef,
7633/// array nor a qualified type.
7634static type_base_sptr
7635clone_typedef_array_qualified_type(type_base_sptr type)
7636{
7637 if (!type)
7638 return type;
7639
7640 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7641 type_base_sptr result;
7642
7643 if (typedef_decl_sptr t = is_typedef(type))
7644 result = clone_typedef(is_typedef(t));
7645 else if (qualified_type_def_sptr t = is_qualified_type(type))
7646 result = clone_qualified_type(t);
7647 else if (array_type_def_sptr t = is_array_type(type))
7648 result = clone_array(t);
7649 else
7650 return type_base_sptr();
7651
7652 if (scope)
7653 add_decl_to_scope(is_decl(result), scope);
7654
7655 return result;
7656}
7657
7658/// Clone a type tree made of an array or a typedef of array.
7659///
7660/// Note that this can be a tree which root node is a typedef an which
7661/// sub-tree can be any arbitrary combination of typedef, qualified
7662/// type and arrays.
7663///
7664/// @param t the array or typedef of qualified array to consider.
7665///
7666/// @return a clone of @p t.
7667type_base_sptr
7668clone_array_tree(const type_base_sptr t)
7669{
7671
7672 scope_decl* scope = is_decl(t)->get_scope();
7673 type_base_sptr result = clone_typedef_array_qualified_type(t);
7674 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7675
7676 type_base_sptr subtree;
7677 if (typedef_decl_sptr type = is_typedef(result))
7678 {
7679 type_base_sptr s =
7680 clone_typedef_array_qualified_type(type->get_underlying_type());
7681 if (s)
7682 {
7683 subtree = s;
7684 type->set_underlying_type(subtree);
7685 }
7686 }
7687 else if (array_type_def_sptr type = is_array_type(result))
7688 {
7689 type_base_sptr s =
7690 clone_typedef_array_qualified_type(type->get_element_type());
7691 if (s)
7692 {
7693 subtree = s;
7694 type->set_element_type(subtree);
7695 }
7696 }
7697 add_decl_to_scope(is_decl(subtree), scope);
7698
7699 for (;;)
7700 {
7701 if (typedef_decl_sptr t = is_typedef(subtree))
7702 {
7703 type_base_sptr s =
7704 clone_typedef_array_qualified_type(t->get_underlying_type());
7705 if (s)
7706 {
7707 scope_decl* scope =
7708 is_decl(t->get_underlying_type())->get_scope();
7709 ABG_ASSERT(scope);
7710 add_decl_to_scope(is_decl(s), scope);
7711 t->set_underlying_type (s);
7712 subtree = s;
7713 }
7714 else
7715 break;
7716 }
7717 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7718 {
7719 type_base_sptr s =
7720 clone_typedef_array_qualified_type(t->get_underlying_type());
7721 if (s)
7722 {
7723 scope_decl* scope =
7724 is_decl(t->get_underlying_type())->get_scope();
7725 ABG_ASSERT(scope);
7726 add_decl_to_scope(is_decl(s), scope);
7727 t->set_underlying_type(s);
7728 subtree = s;
7729 }
7730 else
7731 break;
7732 }
7733 else if (array_type_def_sptr t = is_array_type(subtree))
7734 {
7735 type_base_sptr e = t->get_element_type();
7736 if (is_typedef(e) || is_qualified_type(e))
7737 {
7738 type_base_sptr s =
7739 clone_typedef_array_qualified_type(e);
7740 if (s)
7741 {
7742 scope_decl* scope = is_decl(e)->get_scope();
7743 ABG_ASSERT(scope);
7744 add_decl_to_scope(is_decl(s), scope);
7745 t->set_element_type(s);
7746 }
7747 else
7748 break;
7749 }
7750 break;
7751 }
7752 else
7753 break;
7754 }
7755 return result;
7756}
7757
7758/// Update the qualified name of a given sub-tree.
7759///
7760/// @param d the sub-tree for which to update the qualified name.
7761static void
7762update_qualified_name(decl_base * d)
7763{
7764 ::qualified_name_setter setter;
7765 d->traverse(setter);
7766}
7767
7768/// Update the qualified name of a given sub-tree.
7769///
7770/// @param d the sub-tree for which to update the qualified name.
7771static void
7772update_qualified_name(decl_base_sptr d)
7773{return update_qualified_name(d.get());}
7774
7775// <scope_decl stuff>
7776
7777/// Hash a type by returning the pointer value of its canonical type.
7778///
7779/// @param l the type to hash.
7780///
7781/// @return the the pointer value of the canonical type of @p l.
7782size_t
7783canonical_type_hash::operator()(const type_base_sptr& l) const
7784{return operator()(l.get());}
7785
7786/// Hash a (canonical) type by returning its pointer value
7787///
7788/// @param l the canonical type to hash.
7789///
7790/// @return the pointer value of the canonical type of @p l.
7791size_t
7793{return reinterpret_cast<size_t>(l);}
7794
7795struct scope_decl::priv
7796{
7797 declarations members_;
7798 declarations sorted_members_;
7799 type_base_sptrs_type member_types_;
7800 type_base_sptrs_type sorted_member_types_;
7801 scopes member_scopes_;
7802 canonical_type_sptr_set_type canonical_types_;
7803 type_base_sptrs_type sorted_canonical_types_;
7804 bool clear_sorted_member_types_cache_ = false;
7805}; // end struct scope_decl::priv
7806
7807/// Constructor of the @ref scope_decl type.
7808///
7809/// @param the environment to use for the new instance.
7810///
7811/// @param the name of the scope decl.
7812///
7813/// @param locus the source location where the scope_decl is defined.
7814///
7815/// @param vis the visibility of the declaration.
7816scope_decl::scope_decl(const environment& env,
7817 const string& name,
7818 const location& locus,
7819 visibility vis)
7820 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7821 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7822 priv_(new priv)
7823{}
7824
7825/// Constructor of the @ref scope_decl type.
7826///
7827/// @param the environment to use for the new instance.
7828///
7829/// @param l the source location where the scope_decl is defined.
7830///
7831/// @param vis the visibility of the declaration.
7832scope_decl::scope_decl(const environment& env, location& l)
7833 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7834 decl_base(env, "", l),
7835 priv_(new priv)
7836{}
7837
7838/// @eturn the set of canonical types of the the current scope.
7841{return priv_->canonical_types_;}
7842
7843/// @eturn the set of canonical types of the the current scope.
7846{return const_cast<scope_decl*>(this)->get_canonical_types();}
7847
7848/// Return a vector of sorted canonical types of the current scope.
7849///
7850/// The types are sorted "almost topologically". That means, they are
7851/// sorted using the lexicographic order of the string representing
7852/// the location their definition point. If a type doesn't have a
7853/// location, then its pretty representation is used.
7854///
7855/// @return a vector of sorted canonical types of the current scope.
7858{
7859 if (priv_->sorted_canonical_types_.empty())
7860 {
7861 for (canonical_type_sptr_set_type::const_iterator e =
7862 get_canonical_types().begin();
7863 e != get_canonical_types().end();
7864 ++e)
7865 priv_->sorted_canonical_types_.push_back(*e);
7866
7867 type_topo_comp comp;
7868 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7869 priv_->sorted_canonical_types_.end(),
7870 comp);
7871 }
7872 return priv_->sorted_canonical_types_;
7873}
7874
7875/// Getter for the member declarations carried by the current @ref
7876/// scope_decl.
7877///
7878/// @return the member declarations carried by the current @ref
7879/// scope_decl.
7882{return priv_->members_;}
7883
7884/// Getter for the member declarations carried by the current @ref
7885/// scope_decl.
7886///
7887/// @return the member declarations carried by the current @ref
7888/// scope_decl.
7891{return priv_->members_;}
7892
7893/// Getter for the sorted member declarations carried by the current
7894/// @ref scope_decl.
7895///
7896/// @return the sorted member declarations carried by the current @ref
7897/// scope_decl. The declarations are sorted topologically.
7900{
7901 decl_topo_comp comp;
7902 if (priv_->sorted_members_.empty())
7903 {
7904 for (declarations::const_iterator i = get_member_decls().begin();
7905 i != get_member_decls().end();
7906 ++i)
7907 priv_->sorted_members_.push_back(*i);
7908
7909 std::stable_sort(priv_->sorted_members_.begin(),
7910 priv_->sorted_members_.end(),
7911 comp);
7912 }
7913 return priv_->sorted_members_;
7914}
7915
7916/// Getter for the number of anonymous classes contained in this
7917/// scope.
7918///
7919/// @return the number of anonymous classes contained in this scope.
7920size_t
7922{
7923 int result = 0;
7924 for (declarations::const_iterator it = get_member_decls().begin();
7925 it != get_member_decls().end();
7926 ++it)
7927 if (class_decl_sptr t = is_class_type(*it))
7928 if (t->get_is_anonymous())
7929 ++result;
7930
7931 return result;
7932}
7933
7934/// Getter for the number of anonymous unions contained in this
7935/// scope.
7936///
7937/// @return the number of anonymous unions contained in this scope.
7938size_t
7940{
7941 int result = 0;
7942 for (declarations::const_iterator it = get_member_decls().begin();
7943 it != get_member_decls().end();
7944 ++it)
7945 if (union_decl_sptr t = is_union_type(*it))
7946 if (t->get_is_anonymous())
7947 ++result;
7948
7949 return result;
7950}
7951
7952/// Getter for the number of anonymous enums contained in this
7953/// scope.
7954///
7955/// @return the number of anonymous enums contained in this scope.
7956size_t
7958{
7959 int result = 0;
7960 for (declarations::const_iterator it = get_member_decls().begin();
7961 it != get_member_decls().end();
7962 ++it)
7963 if (enum_type_decl_sptr t = is_enum_type(*it))
7964 if (t->get_is_anonymous())
7965 ++result;
7966
7967 return result;
7968}
7969
7970/// Getter for the scopes carried by the current scope.
7971///
7972/// @return the scopes carried by the current scope.
7975{return priv_->member_scopes_;}
7976
7977/// Getter for the scopes carried by the current scope.
7978///
7979/// @return the scopes carried by the current scope.
7980const scope_decl::scopes&
7982{return priv_->member_scopes_;}
7983
7984/// Test if the current scope is empty.
7985///
7986/// @return true iff the current scope is empty.
7987bool
7989{
7990 return (get_member_decls().empty()
7991 && get_canonical_types().empty());
7992}
7993
7994/// Set the translation unit of a decl
7995///
7996/// It also perform some IR integrity checks.
7997///
7998/// This is a sub-routine of scope_decl::{insert,add}_member_decl.
7999///
8000/// @param decl the decl to set the translation unit for.
8001///
8002/// @param tu the translation unit to set.
8003static void
8004maybe_set_translation_unit(const decl_base_sptr& decl,
8005 translation_unit* tu)
8006{
8007 ABG_ASSERT(tu);
8008
8009 if (translation_unit* existing_tu = decl->get_translation_unit())
8010 // The decl already belongs to a translation unit.
8011 // Either:
8012 //
8013 // 1/ it's a unique type, in which case we should not add it to
8014 // any translation unique since unique types are "logically"
8015 // supposed to belong to no translation unit in particular, as
8016 // they are unique.
8017 //
8018 // 2/ or the decl was already added to this translation unit.
8019 ABG_ASSERT(tu == existing_tu || is_unique_type(is_type(decl)));
8020 else
8021 decl->set_translation_unit(tu);
8022}
8023
8024/// Add a member decl to this scope. Note that user code should not
8025/// use this, but rather use add_decl_to_scope.
8026///
8027/// Note that this function updates the qualified name of the member
8028/// decl that is added. It also sets the scope of the member. Thus,
8029/// it ABG_ASSERTs that member should not have its scope set, prior to
8030/// calling this function.
8031///
8032/// @param member the new member decl to add to this scope.
8033decl_base_sptr
8034scope_decl::add_member_decl(const decl_base_sptr& member)
8035{
8036 ABG_ASSERT(!has_scope(member));
8037
8038 member->set_scope(this);
8039 priv_->members_.push_back(member);
8040 if (is_type(member))
8041 {
8042 priv_->member_types_.push_back(is_type(member));
8043 priv_->clear_sorted_member_types_cache_ = true;
8044 }
8045
8046 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8047 priv_->member_scopes_.push_back(m);
8048
8049 update_qualified_name(member);
8050
8052 maybe_set_translation_unit(member, tu);
8053
8055
8056 return member;
8057}
8058
8059/// Get the member types of this @ref scope_decl.
8060///
8061/// @return a vector of the member types of this ref class_or_union.
8064{return priv_->member_types_;}
8065
8066/// Find a member type of a given name, inside the current @ref
8067/// scope_decl.
8068///
8069/// @param name the name of the member type to look for.
8070///
8071/// @return a pointer to the @ref type_base that represents the member
8072/// type of name @p name, for the current scope.
8073type_base_sptr
8074scope_decl::find_member_type(const string& name) const
8075{
8076 for (auto t : get_member_types())
8077 if (get_type_name(t, /*qualified*/false) == name)
8078 return t;
8079 return type_base_sptr();
8080}
8081
8082/// Insert a member type.
8083///
8084/// @param t the type to insert in the @ref scope_decl type.
8085///
8086/// @param an iterator right before which @p t has to be inserted.
8087void
8089 declarations::iterator before)
8090{
8091 decl_base_sptr d = get_type_declaration(t);
8092 ABG_ASSERT(d);
8093 ABG_ASSERT(!has_scope(d));
8094
8095 priv_->member_types_.push_back(t);
8096 priv_->clear_sorted_member_types_cache_= true;
8097 insert_member_decl(d, before);
8098}
8099
8100/// Add a member type to the current instance of class_or_union.
8101///
8102/// @param t the member type to add. It must not have been added to a
8103/// scope, otherwise this will violate an ABG_ASSERTion.
8104void
8107
8108/// Add a member type to the current instance of class_or_union.
8109///
8110/// @param t the type to be added as a member type to the current
8111/// instance of class_or_union. An instance of class_or_union::member_type
8112/// will be created out of @p t and and added to the the class.
8113///
8114/// @param a the access specifier for the member type to be created.
8115type_base_sptr
8117{
8118 decl_base_sptr d = get_type_declaration(t);
8119 ABG_ASSERT(d);
8121 add_member_type(t);
8123 return t;
8124}
8125
8126/// Remove a member type from the current @ref class_or_union scope.
8127///
8128/// @param t the type to remove.
8129void
8131{
8132 for (auto i = priv_->member_types_.begin();
8133 i != priv_->member_types_.end();
8134 ++i)
8135 {
8136 if (*((*i)) == *t)
8137 {
8138 priv_->member_types_.erase(i);
8139 return;
8140 }
8141 }
8142}
8143
8144/// Get the sorted member types of this @ref scope_decl
8145///
8146/// @return a vector of the sorted member types of this ref
8147/// class_or_union.
8150{
8151 if (priv_->clear_sorted_member_types_cache_)
8152 {
8153 priv_->sorted_member_types_.clear();
8154 priv_->clear_sorted_member_types_cache_ = false;
8155 }
8156
8157 if (priv_->sorted_member_types_.empty())
8158 {
8159 unordered_set<type_base_sptr> canonical_pointer_types;
8160 for (auto t : get_member_types())
8161 {
8163 priv_->sorted_member_types_.push_back(t);
8164 else if (auto c = t->get_canonical_type())
8165 canonical_pointer_types.insert(c);
8166 else
8167 canonical_pointer_types.insert(t);
8168 }
8169
8170 for (auto t : canonical_pointer_types)
8171 priv_->sorted_member_types_.push_back(t);
8172
8173 type_topo_comp comp;
8174 std::stable_sort(priv_->sorted_member_types_.begin(),
8175 priv_->sorted_member_types_.end(),
8176 comp);
8177 }
8178
8179 const ir::environment& env = get_environment();
8181 priv_->clear_sorted_member_types_cache_ = true;
8182
8183 return priv_->sorted_member_types_;
8184}
8185
8186/// Insert a member decl to this scope, right before an element
8187/// pointed to by a given iterator. Note that user code should not
8188/// use this, but rather use insert_decl_into_scope.
8189///
8190/// Note that this function updates the qualified name of the inserted
8191/// member.
8192///
8193/// @param member the new member decl to add to this scope.
8194///
8195/// @param before an interator pointing to the element before which
8196/// the new member should be inserted.
8197decl_base_sptr
8199 declarations::iterator before)
8200{
8201 ABG_ASSERT(!member->get_scope());
8202
8203 member->set_scope(this);
8204 priv_->members_.insert(before, member);
8205
8206 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8207 priv_-> member_scopes_.push_back(m);
8208
8209 update_qualified_name(member);
8210
8212 maybe_set_translation_unit(member, tu);
8213
8215
8216 return member;
8217}
8218
8219/// Remove a declaration from the current scope.
8220///
8221/// @param member the declaration to remove from the scope.
8222void
8224{
8225 for (declarations::iterator i = priv_->members_.begin();
8226 i != priv_->members_.end();
8227 ++i)
8228 {
8229 if (**i == *member)
8230 {
8231 priv_->members_.erase(i);
8232 // Do not access i after this point as it's invalided by the
8233 // erase call.
8234 break;
8235 }
8236 }
8237
8238 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8239 if (scope)
8240 {
8241 for (scopes::iterator i = priv_->member_scopes_.begin();
8242 i != priv_->member_scopes_.end();
8243 ++i)
8244 {
8245 if (**i == *member)
8246 {
8247 priv_->member_scopes_.erase(i);
8248 break;
8249 }
8250 }
8251 }
8252
8253 member->set_scope(nullptr);
8254 member->set_translation_unit(nullptr);
8255}
8256
8257/// Compares two instances of @ref scope_decl.
8258///
8259/// If the two intances are different, set a bitfield to give some
8260/// insight about the kind of differences there are.
8261///
8262/// @param l the first artifact of the comparison.
8263///
8264/// @param r the second artifact of the comparison.
8265///
8266/// @param k a pointer to a bitfield that gives information about the
8267/// kind of changes there are between @p l and @p r. This one is set
8268/// iff @p k is non-null and the function returns false.
8269///
8270/// Please note that setting k to a non-null value does have a
8271/// negative performance impact because even if @p l and @p r are not
8272/// equal, the function keeps up the comparison in order to determine
8273/// the different kinds of ways in which they are different.
8274///
8275/// @return true if @p l equals @p r, false otherwise.
8276bool
8278{
8279 bool result = true;
8280
8281 if (!l.decl_base::operator==(r))
8282 {
8283 result = false;
8284 if (k)
8286 else
8288 }
8289
8290 scope_decl::declarations::const_iterator i, j;
8291 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8292 i != l.get_member_decls().end() && j != r.get_member_decls().end();
8293 ++i, ++j)
8294 {
8295 if (**i != **j)
8296 {
8297 result = false;
8298 if (k)
8299 {
8300 *k |= SUBTYPE_CHANGE_KIND;
8301 break;
8302 }
8303 else
8305 }
8306 }
8307
8308 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8309 {
8310 result = false;
8311 if (k)
8313 else
8315 }
8316
8317 ABG_RETURN(result);
8318}
8319
8320/// Return true iff both scopes have the same names and have the same
8321/// member decls.
8322///
8323/// This function doesn't check for equality of the scopes of its
8324/// arguments.
8325bool
8327{
8328 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8329 if (!other)
8330 return false;
8331
8332 return equals(*this, *other, 0);
8333}
8334
8335/// Equality operator for @ref scope_decl_sptr.
8336///
8337/// @param l the left hand side operand of the equality operator.
8338///
8339/// @pram r the right hand side operand of the equalify operator.
8340///
8341/// @return true iff @p l equals @p r.
8342bool
8344{
8345 if (!!l != !!r)
8346 return false;
8347 if (l.get() == r.get())
8348 return true;
8349 return *l == *r;
8350}
8351
8352/// Inequality operator for @ref scope_decl_sptr.
8353///
8354/// @param l the left hand side operand of the equality operator.
8355///
8356/// @pram r the right hand side operand of the equalify operator.
8357///
8358/// @return true iff @p l equals @p r.
8359bool
8361{return !operator==(l, r);}
8362
8363/// Find a member of the current scope and return an iterator on it.
8364///
8365/// @param decl the scope member to find.
8366///
8367/// @param i the iterator to set to the member @p decl. This is set
8368/// iff the function returns true.
8369///
8370/// @return true if the member decl was found, false otherwise.
8371bool
8373 declarations::iterator& i)
8374{
8375 if (!decl)
8376 return false;
8377
8378 if (get_member_decls().empty())
8379 {
8380 i = get_member_decls().end();
8381 return false;
8382 }
8383
8384 for (declarations::iterator it = get_member_decls().begin();
8385 it != get_member_decls().end();
8386 ++it)
8387 {
8388 if ((*it).get() == decl)
8389 {
8390 i = it;
8391 return true;
8392 }
8393 }
8394
8395 return false;
8396}
8397
8398/// Find a member of the current scope and return an iterator on it.
8399///
8400/// @param decl the scope member to find.
8401///
8402/// @param i the iterator to set to the member @p decl. This is set
8403/// iff the function returns true.
8404///
8405/// @return true if the member decl was found, false otherwise.
8406bool
8408 declarations::iterator& i)
8409{return find_iterator_for_member(decl.get(), i);}
8410
8411/// This implements the ir_traversable_base::traverse pure virtual
8412/// function.
8413///
8414/// @param v the visitor used on the current instance of scope_decl
8415/// and on its member nodes.
8416///
8417/// @return true if the traversal of the tree should continue, false
8418/// otherwise.
8419bool
8421{
8422 if (visiting())
8423 return true;
8424
8425 if (v.visit_begin(this))
8426 {
8427 visiting(true);
8428 for (scope_decl::declarations::const_iterator i =
8429 get_member_decls().begin();
8430 i != get_member_decls ().end();
8431 ++i)
8432 if (!(*i)->traverse(v))
8433 break;
8434 visiting(false);
8435 }
8436 return v.visit_end(this);
8437}
8438
8439scope_decl::~scope_decl()
8440{}
8441
8442/// Appends a declaration to a given scope, if the declaration
8443/// doesn't already belong to one and if the declaration is not for a
8444/// type that is supposed to be unique.
8445///
8446/// @param decl the declaration to add to the scope
8447///
8448/// @param scope the scope to append the declaration to
8449decl_base_sptr
8450add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8451{
8452 if (!scope)
8453 return decl;
8454
8455 if (scope && decl && !decl->get_scope())
8456 decl = scope->add_member_decl(decl);
8457
8458 return decl;
8459}
8460
8461/// Appends a declaration to a given scope, if the declaration doesn't
8462/// already belong to a scope.
8463///
8464/// @param decl the declaration to add append to the scope
8465///
8466/// @param scope the scope to append the decl to
8467decl_base_sptr
8468add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8469{return add_decl_to_scope(decl, scope.get());}
8470
8471/// Remove a given decl from its scope
8472///
8473/// @param decl the decl to remove from its scope.
8474void
8475remove_decl_from_scope(decl_base_sptr decl)
8476{
8477 if (!decl)
8478 return;
8479
8480 scope_decl* scope = decl->get_scope();
8481 scope->remove_member_decl(decl);
8482}
8483
8484/// Inserts a declaration into a given scope, before a given IR child
8485/// node of the scope.
8486///
8487/// @param decl the declaration to insert into the scope.
8488///
8489/// @param before an iterator pointing to the child IR node before
8490/// which to insert the declaration.
8491///
8492/// @param scope the scope into which to insert the declaration.
8493decl_base_sptr
8494insert_decl_into_scope(decl_base_sptr decl,
8495 scope_decl::declarations::iterator before,
8496 scope_decl* scope)
8497{
8498 if (scope && decl && !decl->get_scope())
8499 {
8500 decl_base_sptr d = scope->insert_member_decl(decl, before);
8501 decl = d;
8502 }
8503 return decl;
8504}
8505
8506/// Inserts a declaration into a given scope, before a given IR child
8507/// node of the scope.
8508///
8509/// @param decl the declaration to insert into the scope.
8510///
8511/// @param before an iterator pointing to the child IR node before
8512/// which to insert the declaration.
8513///
8514/// @param scope the scope into which to insert the declaration.
8515decl_base_sptr
8516insert_decl_into_scope(decl_base_sptr decl,
8517 scope_decl::declarations::iterator before,
8518 scope_decl_sptr scope)
8519{return insert_decl_into_scope(decl, before, scope.get());}
8520
8521/// Constructor of the @ref global_scope type.
8522///
8523/// @param tu the translation unit the scope belongs to.
8524global_scope::global_scope(translation_unit *tu)
8525 : type_or_decl_base(tu->get_environment(),
8526 GLOBAL_SCOPE_DECL
8527 | ABSTRACT_DECL_BASE
8528 | ABSTRACT_SCOPE_DECL),
8529 decl_base(tu->get_environment(), "", location()),
8530 scope_decl(tu->get_environment(), "", location()),
8531 translation_unit_(tu)
8532{
8533 runtime_type_instance(this);
8534}
8535
8536/// return the global scope as seen by a given declaration.
8537///
8538/// @param decl the declaration to consider.
8539///
8540/// @return the global scope of the decl, or a null pointer if the
8541/// decl is not yet added to a translation_unit.
8542const global_scope*
8544{
8545 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8546 return s;
8547
8548 scope_decl* scope = decl.get_scope();
8549 while (scope && !dynamic_cast<global_scope*>(scope))
8550 scope = scope->get_scope();
8551
8552 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8553}
8554
8555/// return the global scope as seen by a given declaration.
8556///
8557/// @param decl the declaration to consider.
8558///
8559/// @return the global scope of the decl, or a null pointer if the
8560/// decl is not yet added to a translation_unit.
8561const global_scope*
8563{return get_global_scope(*decl);}
8564
8565/// Return the global scope as seen by a given declaration.
8566///
8567/// @param decl the declaration to consider.
8568///
8569/// @return the global scope of the decl, or a null pointer if the
8570/// decl is not yet added to a translation_unit.
8571const global_scope*
8572get_global_scope(const shared_ptr<decl_base> decl)
8573{return get_global_scope(decl.get());}
8574
8575/// Return the a scope S containing a given declaration and that is
8576/// right under a given scope P.
8577///
8578/// Note that @p scope must come before @p decl in topological
8579/// order.
8580///
8581/// @param decl the decl for which to find a scope.
8582///
8583/// @param scope the scope under which the resulting scope must be.
8584///
8585/// @return the resulting scope.
8586const scope_decl*
8588 const scope_decl* scope)
8589{
8590 if (!decl)
8591 return 0;
8592
8593 if (scope == 0)
8594 return get_global_scope(decl);
8595
8596 // Handle the case where decl is a scope itself.
8597 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8598 if (!s)
8599 s = decl->get_scope();
8600
8601 if (is_global_scope(s))
8602 return scope;
8603
8604 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8605 // same. The caller needs to be prepared to deal with this case.
8606 if (s == scope)
8607 return s;
8608
8609 while (s && !is_global_scope(s) && s->get_scope() != scope)
8610 s = s->get_scope();
8611
8612 if (!s || is_global_scope(s))
8613 // SCOPE must come before decl in topological order, but I don't
8614 // know how to ensure that ...
8615 return scope;
8616 ABG_ASSERT(s);
8617
8618 return s;
8619}
8620
8621/// Return the a scope S containing a given declaration and that is
8622/// right under a given scope P.
8623///
8624/// @param decl the decl for which to find a scope.
8625///
8626/// @param scope the scope under which the resulting scope must be.
8627///
8628/// @return the resulting scope.
8629const scope_decl*
8630get_top_most_scope_under(const decl_base_sptr decl,
8631 const scope_decl* scope)
8632{return get_top_most_scope_under(decl.get(), scope);}
8633
8634/// Return the a scope S containing a given declaration and that is
8635/// right under a given scope P.
8636///
8637/// @param decl the decl for which to find a scope.
8638///
8639/// @param scope the scope under which the resulting scope must be.
8640///
8641/// @return the resulting scope.
8642const scope_decl*
8643get_top_most_scope_under(const decl_base_sptr decl,
8644 const scope_decl_sptr scope)
8645{return get_top_most_scope_under(decl, scope.get());}
8646
8647// </scope_decl stuff>
8648
8649
8650/// Get the string representation of a CV qualifier bitmap.
8651///
8652/// @param cv_quals the bitmap of CV qualifiers to consider.
8653///
8654/// @return the string representation.
8655string
8657{
8658 string repr;
8659 if (cv_quals & qualified_type_def::CV_RESTRICT)
8660 repr = "restrict";
8661 if (cv_quals & qualified_type_def::CV_CONST)
8662 {
8663 if (!repr.empty())
8664 repr += ' ';
8665 repr += "const";
8666 }
8667 if (cv_quals & qualified_type_def::CV_VOLATILE)
8668 {
8669 if (!repr.empty())
8670 repr += ' ';
8671 repr += "volatile";
8672 }
8673 return repr;
8674}
8675
8676/// Build and return a copy of the name of an ABI artifact that is
8677/// either a type or a decl.
8678///
8679/// @param tod the ABI artifact to get the name for.
8680///
8681/// @param qualified if yes, return the qualified name of @p tod;
8682/// otherwise, return the non-qualified name;
8683///
8684/// @return the name of @p tod.
8685string
8686get_name(const type_or_decl_base *tod, bool qualified)
8687{
8688 string result;
8689
8690 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8691
8692 if (type_base* t = dynamic_cast<type_base*>(a))
8693 result = get_type_name(t, qualified);
8694 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8695 {
8696 if (qualified)
8697 result = d->get_qualified_name();
8698 else
8699 result = d->get_name();
8700 }
8701 else
8702 // We should never reach this point.
8703 abort();
8704
8705 return result;
8706}
8707
8708/// Build and return a copy of the name of an ABI artifact that is
8709/// either a type of a decl.
8710///
8711/// @param tod the ABI artifact to get the name for.
8712///
8713/// @param qualified if yes, return the qualified name of @p tod;
8714/// otherwise, return the non-qualified name;
8715///
8716/// @return the name of @p tod.
8717string
8718get_name(const type_or_decl_base_sptr& tod, bool qualified)
8719{return get_name(tod.get(), qualified);}
8720
8721/// Build and return a qualified name from a name and its scope.
8722///
8723/// The name is supposed to be for an entity that is part of the
8724/// scope.
8725///
8726/// @param the scope to consider.
8727///
8728/// @param name of the name to consider.
8729///
8730/// @return a copy of the string that represents the qualified name.
8731string
8732build_qualified_name(const scope_decl* scope, const string& name)
8733{
8734 if (name.empty())
8735 return "";
8736
8737 string qualified_name;
8738 if (scope)
8739 qualified_name = scope->get_qualified_name();
8740
8741 if (qualified_name.empty())
8742 qualified_name = name;
8743 else
8744 qualified_name = qualified_name + "::" + name;
8745
8746 return qualified_name;
8747}
8748
8749/// Build and return the qualified name of a type in its scope.
8750///
8751/// @param scope the scope of the type to consider.
8752///
8753/// @param type the type to consider.
8754string
8755build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8756{return build_qualified_name(scope, get_name((type)));}
8757
8758// </scope_decl stuff>
8759
8760/// Get the location of the declaration of a given type.
8761///
8762/// @param type the type to consider.
8763///
8764/// @return the location of the declaration of type @p type.
8766get_location(const type_base_sptr& type)
8767{
8768 if (decl_base_sptr decl = get_type_declaration(type))
8769 return get_location(decl);
8770 return location();
8771}
8772
8773/// Get the location of a given declaration.
8774///
8775/// @param decl the declaration to consider.
8776///
8777/// @return the location of the declaration @p decl.
8779get_location(const decl_base_sptr& decl)
8780{
8781 location loc = decl->get_location();
8782 if (!loc)
8783 {
8784 if (class_or_union_sptr c = is_class_or_union_type(decl))
8785 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8786 {
8787 c = is_class_or_union_type(c->get_definition_of_declaration());
8788 loc = c->get_location();
8789 }
8790 }
8791 return loc;
8792}
8793
8794/// Get the scope of a given type.
8795///
8796/// @param t the type to consider.
8797///
8798/// @return the scope of type @p t or 0 if the type has no scope yet.
8801{
8802 if (!t)
8803 return 0;
8804
8806 if (d)
8807 return d->get_scope();
8808 return 0;
8809}
8810
8811/// Get the scope of a given type.
8812///
8813/// @param t the type to consider.
8814///
8815/// @return the scope of type @p t or 0 if the type has no scope yet.
8817get_type_scope(const type_base_sptr& t)
8818{return get_type_scope(t.get());}
8819
8820/// Get the name of a given type and return a copy of it.
8821///
8822/// @param t the type to consider.
8823///
8824/// @param qualified if true then return the qualified name of the
8825/// type.
8826///
8827/// @param internal set to true if the call is intended for an
8828/// internal use (for technical use inside the library itself), false
8829/// otherwise. If you don't know what this is for, then set it to
8830/// false.
8831///
8832/// @return a copy of the type name if the type has a name, or the
8833/// empty string if it does not.
8835get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8836{return get_type_name(t.get(), qualified, internal);}
8837
8838/// Return true iff a decl is for a type type that has a generic
8839/// anonymous internal type name.
8840///
8841/// @param d the decl to considier.
8842///
8843/// @return true iff @p d is for a type type that has a generic
8844/// anonymous internal type name.
8845static bool
8846has_generic_anonymous_internal_type_name(const decl_base *d)
8847{
8848 return (is_class_or_union_type(d)
8849 || is_enum_type(d)
8850 || is_subrange_type(d));
8851}
8852
8853/// Return the generic internal name of an anonymous type.
8854///
8855/// For internal purposes, we want to define a generic name for all
8856/// anonymous types of a certain kind. For instance, all anonymous
8857/// structs will be have a generic name of "__anonymous_struct__", all
8858/// anonymous unions will have a generic name of
8859/// "__anonymous_union__", etc.
8860///
8861/// That generic name can be used as a hash to put all anonymous types
8862/// of a certain kind in the same hash table bucket, for instance.
8863static interned_string
8864get_generic_anonymous_internal_type_name(const decl_base *d)
8865{
8866 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8867
8868 const environment&env = d->get_environment();
8869
8870 interned_string result;
8871 if (is_class_type(d))
8872 result =
8874 else if (is_union_type(d))
8875 result =
8877 else if (is_enum_type(d))
8878 result =
8880 else if (is_subrange_type(d))
8881 result =
8883 else
8885
8886 return result;
8887}
8888
8889/// Get the internal name for a given real type.
8890///
8891/// All real types that have the modifiers 'short, long or long
8892/// long' have the same internal name. This is so that they can all
8893/// have the same canonical type if they are of the same size.
8894/// Otherwise, 'long int' and 'long long int' would have different
8895/// canonical types even though they are equivalent from an ABI point
8896/// of view.
8897///
8898/// @param t the real type to consider
8899///
8900/// @return the internal name for @p t if it's an integral type, or
8901/// the empty string if @p t is not a real type.
8902static string
8903get_internal_real_type_name(const type_base* t)
8904{
8905 string name;
8906 type_decl *type = is_real_type(t);
8907
8908 if (!type)
8909 return name;
8910
8911 real_type int_type;
8912 if (parse_real_type(type->get_name(), int_type))
8913 name = int_type.to_string(/*internal=*/true);
8914
8915 return name;
8916}
8917
8918/// Get the name of a given type and return a copy of it.
8919///
8920/// @param t the type to consider.
8921///
8922/// @param qualified if true then return the qualified name of the
8923/// type.
8924///
8925/// @param internal set to true if the call is intended for an
8926/// internal use (for technical use inside the library itself), false
8927/// otherwise. If you don't know what this is for, then set it to
8928/// false.
8929///
8930/// @return a copy of the type name if the type has a name, or the
8931/// empty string if it does not.
8932interned_string
8933get_type_name(const type_base* t, bool qualified, bool internal)
8934{
8935 interned_string empty_string;
8936
8937 if (!t)
8938 return empty_string;
8939
8940 const decl_base* d = dynamic_cast<const decl_base*>(t);
8941 if (!d)
8942 {
8943 const function_type* fn_type = is_function_type(t);
8944 if (!fn_type)
8945 return empty_string;
8946 return fn_type->get_cached_name(internal);
8947 }
8948
8949 const environment&env = d->get_environment();
8950
8951 // All anonymous types of a given kind get to have the same internal
8952 // name for internal purpose. This to allow them to be compared
8953 // among themselves during type canonicalization.
8954 if (internal)
8955 {
8956 if (d->get_is_anonymous() && !is_type_decl(t))
8957 {
8958 // Note that anonymous type_decl that are used for
8959 // enumerators are not handled here because they don't have
8960 // generic internal type names.
8961 string r;
8962 r += get_generic_anonymous_internal_type_name(d);
8963 return t->get_environment().intern(r);
8964 }
8965
8966 if (is_typedef(t))
8967 return d->get_name();
8968
8969 if (qualified)
8970 return d->get_qualified_name(internal);
8971
8972 return env.intern(get_internal_real_type_name(t));
8973 }
8974
8975 if (d->get_is_anonymous())
8976 {
8978 return env.intern
8980 /*one_line=*/true,
8981 internal, qualified));
8982 }
8983
8984 if (qualified)
8985 return d->get_qualified_name(internal);
8986 return d->get_name();
8987}
8988
8989/// Get the name of a given type and return a copy of it.
8990///
8991/// @param t the type to consider.
8992///
8993/// @param qualified if true then return the qualified name of the
8994/// type.
8995///
8996/// @param internal set to true if the call is intended for an
8997/// internal use (for technical use inside the library itself), false
8998/// otherwise. If you don't know what this is for, then set it to
8999/// false.
9000///
9001/// @return a copy of the type name if the type has a name, or the
9002/// empty string if it does not.
9004get_type_name(const type_base& t, bool qualified, bool internal)
9005{return get_type_name(&t, qualified, internal);}
9006
9007/// Get the name of the pointer to a given type.
9008///
9009/// @param pointed_to_type the pointed-to-type to consider.
9010///
9011/// @param qualified this is true if the resulting name should be of a
9012/// pointer to a *fully-qualified* pointed-to-type.
9013///
9014/// @param internal true if the name is for libabigail-internal
9015/// purposes.
9016///
9017/// @return the name (string representation) of the pointer.
9020 bool qualified, bool internal)
9021{
9022 const environment& env = pointed_to_type.get_environment();
9023 string tn = get_type_name(pointed_to_type, qualified, internal);
9024 tn = tn + "*";
9025
9026 return env.intern(tn);
9027}
9028
9029/// Get the name of the reference to a given type.
9030///
9031/// @param pointed_to_type the pointed-to-type to consider.
9032///
9033/// @param qualified this is true if the resulting name should be of a
9034/// reference to a *fully-qualified* pointed-to-type.
9035///
9036/// @param internal true if the name is for libabigail-internal
9037/// purposes.
9038///
9039/// @return the name (string representation) of the reference.
9042 bool lvalue_reference,
9043 bool qualified, bool internal)
9044{
9045 const environment& env = pointed_to_type.get_environment();
9046
9047 string name = get_type_name(pointed_to_type, qualified, internal);
9048 if (lvalue_reference)
9049 name = name + "&";
9050 else
9051 name = name + "&&";
9052
9053 return env.intern(name);
9054}
9055
9056/// Get the name of a qualified type, given the underlying type and
9057/// its qualifiers.
9058///
9059/// @param underlying_type the underlying type to consider.
9060///
9061/// @param quals the CV qualifiers of the name.
9062///
9063/// @param qualified true if we should consider the fully qualified
9064/// name of @p underlying_type.
9065///
9066/// @param internal true if the result is to be used for
9067/// libabigail-internal purposes.
9068///
9069/// @return the name (string representation) of the qualified type.
9071get_name_of_qualified_type(const type_base_sptr& underlying_type,
9073 bool qualified, bool internal)
9074{
9075 const environment& env = underlying_type->get_environment();
9076
9077 string quals_repr = get_string_representation_of_cv_quals(quals);
9078 string name = get_type_name(underlying_type, qualified, internal);
9079
9080 if (quals_repr.empty() && internal)
9081 // We are asked to return the internal name, that might be used
9082 // for type canonicalization. For that canonicalization, we need
9083 // to make a difference between a no-op qualified type which
9084 // underlying type is foo (the qualified type is named "none
9085 // foo"), and the name of foo, which is just "foo".
9086 //
9087 // Please remember that this has to be kept in sync with what is
9088 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
9089 // change this code here, please change that code there too.
9090 quals_repr = "";
9091
9092 if (!quals_repr.empty())
9093 {
9094 if (is_pointer_type(peel_qualified_type(underlying_type))
9095 || is_reference_type(peel_qualified_type(underlying_type)))
9096 {
9097 name += " ";
9098 name += quals_repr;
9099 }
9100 else
9101 name = quals_repr + " " + name;
9102 }
9103
9104 return env.intern(name);
9105}
9106
9107/// Get the name of a given function type and return a copy of it.
9108///
9109/// @param fn_type the function type to consider.
9110///
9111/// @param internal set to true if the call is intended for an
9112/// internal use (for technical use inside the library itself), false
9113/// otherwise. If you don't know what this is for, then set it to
9114/// false.
9115///
9116/// @return a copy of the function type name
9119 bool internal)
9120{return get_function_type_name(fn_type.get(), internal);}
9121
9122/// Get the name of a given function type and return a copy of it.
9123///
9124/// @param fn_type the function type to consider.
9125///
9126/// @param internal set to true if the call is intended for an
9127/// internal use (for technical use inside the library itself), false
9128/// otherwise. If you don't know what this is for, then set it to
9129/// false.
9130///
9131/// @return a copy of the function type name
9134 bool internal)
9135{
9136 ABG_ASSERT(fn_type);
9137
9138 if (const method_type* method = is_method_type(fn_type))
9139 return get_method_type_name(method, internal);
9140
9141 return get_function_type_name(*fn_type, internal);
9142}
9143
9144/// Get the name of a given function type and return a copy of it.
9145///
9146/// @param fn_type the function type to consider.
9147///
9148/// @param internal set to true if the call is intended for an
9149/// internal use (for technical use inside the library itself), false
9150/// otherwise. If you don't know what this is for, then set it to
9151/// false.
9152///
9153/// @return a copy of the function type name
9156 bool internal)
9157{
9158 std::ostringstream o;
9159 // When the function name is used for internal purposes (e.g, for
9160 // canonicalization), we want its representation to stay the same,
9161 // regardless of typedefs. So let's strip typedefs from the return
9162 // type.
9163 type_base_sptr return_type = fn_type.get_return_type();
9164 const environment& env = fn_type.get_environment();
9165
9166 o << get_type_name(return_type, /*qualified=*/true, internal) << " ";
9167 stream_pretty_representation_of_fn_parms(fn_type, o,
9168 /*qualified=*/true,
9169 internal);
9170 return env.intern(o.str());
9171}
9172
9173/// Get the ID of a function, or, if the ID can designate several
9174/// different functions, get its pretty representation.
9175///
9176/// @param fn the function to consider
9177///
9178/// @return the function ID of pretty representation of @p fn.
9181{
9182 ABG_ASSERT(fn);
9183
9184 interned_string result = fn->get_environment().intern(fn->get_id());
9185
9186 if (const corpus *c = fn->get_corpus())
9187 {
9189 c->get_exported_decls_builder();
9190 if (b->fn_id_maps_to_several_fns(fn))
9191 result = fn->get_environment().intern(fn->get_pretty_representation());
9192 }
9193
9194 return result;
9195}
9196
9197/// Get the name of a given method type and return a copy of it.
9198///
9199/// @param fn_type the function type to consider.
9200///
9201/// @param internal set to true if the call is intended for an
9202/// internal use (for technical use inside the library itself), false
9203/// otherwise. If you don't know what this is for, then set it to
9204/// false.
9205///
9206/// @return a copy of the function type name
9209 bool internal)
9210{return get_method_type_name(fn_type.get(), internal);}
9211
9212/// Get the name of a given method type and return a copy of it.
9213///
9214/// @param fn_type the function type to consider.
9215///
9216/// @param internal set to true if the call is intended for an
9217/// internal use (for technical use inside the library itself), false
9218/// otherwise. If you don't know what this is for, then set it to
9219/// false.
9220///
9221/// @return a copy of the function type name
9224 bool internal)
9225{
9226 if (fn_type)
9227 return get_method_type_name(*fn_type, internal);
9228
9229 return interned_string();
9230}
9231
9232/// Get the name of a given method type and return a copy of it.
9233///
9234/// @param fn_type the function type to consider.
9235///
9236/// @param internal set to true if the call is intended for an
9237/// internal use (for technical use inside the library itself), false
9238/// otherwise. If you don't know what this is for, then set it to
9239/// false.
9240///
9241/// @return a copy of the function type name
9244 bool internal)
9245{
9246 std::ostringstream o;
9247 // When the function name is used for internal purposes (e.g, for
9248 // canonicalization), we want its representation to stay the same,
9249 // regardless of typedefs. So let's strip typedefs from the return
9250 // type.
9251 type_base_sptr return_type = fn_type.get_return_type();
9252
9253 const environment& env = fn_type.get_environment();
9254
9255 if (return_type)
9256 o << get_type_name(return_type, /*qualified=*/true, internal);
9257 else
9258 // There are still some abixml files out there in which "void"
9259 // can be expressed as an empty type.
9260 o << "void";
9261
9262 class_or_union_sptr class_type = fn_type.get_class_type();
9263 ABG_ASSERT(class_type);
9264
9265 o << " (" << class_type->get_qualified_name(internal) << "::*) ";
9266 stream_pretty_representation_of_fn_parms(fn_type, o,
9267 /*qualified=*/true,
9268 internal);
9269
9270 return env.intern(o.str());
9271}
9272
9273/// Build and return a copy of the pretty representation of an ABI
9274/// artifact that could be either a type of a decl.
9275///
9276/// param tod the ABI artifact to consider.
9277///
9278/// @param internal set to true if the call is intended for an
9279/// internal use (for technical use inside the library itself), false
9280/// otherwise. If you don't know what this is for, then set it to
9281/// false.
9282///
9283/// @return a copy of the pretty representation of an ABI artifact
9284/// that could be either a type of a decl.
9285string
9287{
9288 string result;
9289
9290 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9291 result = get_pretty_representation(t, internal);
9292 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9293 result = get_pretty_representation(d, internal);
9294 else
9295 // We should never reach this point
9296 abort();
9297
9298 return result;
9299}
9300
9301/// Build and return a copy of the pretty representation of an ABI
9302/// artifact that could be either a type of a decl.
9303///
9304/// param tod the ABI artifact to consider.
9305///
9306/// @param internal set to true if the call is intended for an
9307/// internal use (for technical use inside the library itself), false
9308/// otherwise. If you don't know what this is for, then set it to
9309/// false.
9310///
9311/// @return a copy of the pretty representation of an ABI artifact
9312/// that could be either a type of a decl.
9313string
9315{return get_pretty_representation(tod.get(), internal);}
9316
9317/// Get a copy of the pretty representation of a decl.
9318///
9319/// @param d the decl to consider.
9320///
9321/// @param internal set to true if the call is intended for an
9322/// internal use (for technical use inside the library itself), false
9323/// otherwise. If you don't know what this is for, then set it to
9324/// false.
9325///
9326/// @return the pretty representation of the decl.
9327string
9328get_pretty_representation(const decl_base* d, bool internal)
9329{
9330 if (!d)
9331 return "";
9332 return d->get_pretty_representation(internal);
9333}
9334
9335/// Get a copy of the pretty representation of a type.
9336///
9337/// @param d the type to consider.
9338///
9339/// @param internal set to true if the call is intended for an
9340/// internal use (for technical use inside the library itself), false
9341/// otherwise. If you don't know what this is for, then set it to
9342/// false.
9343///
9344/// @return the pretty representation of the type.
9345string
9346get_pretty_representation(const type_base* t, bool internal)
9347{
9348 if (!t)
9349 return "void";
9350 if (const function_type* fn_type = is_function_type(t))
9351 return get_pretty_representation(fn_type, internal);
9352
9353 const decl_base* d = get_type_declaration(t);
9354 ABG_ASSERT(d);
9355 return get_pretty_representation(d, internal);
9356}
9357
9358/// Get a copy of the pretty representation of a decl.
9359///
9360/// @param d the decl to consider.
9361///
9362/// @param internal set to true if the call is intended for an
9363/// internal use (for technical use inside the library itself), false
9364/// otherwise. If you don't know what this is for, then set it to
9365/// false.
9366///
9367/// @return the pretty representation of the decl.
9368string
9369get_pretty_representation(const decl_base_sptr& d, bool internal)
9370{return get_pretty_representation(d.get(), internal);}
9371
9372/// Get a copy of the pretty representation of a type.
9373///
9374/// @param d the type to consider.
9375///
9376/// @param internal set to true if the call is intended for an
9377/// internal use (for technical use inside the library itself), false
9378/// otherwise. If you don't know what this is for, then set it to
9379/// false.
9380///
9381/// @return the pretty representation of the type.
9382string
9383get_pretty_representation(const type_base_sptr& t, bool internal)
9384{return get_pretty_representation(t.get(), internal);}
9385
9386/// Get the pretty representation of a function type.
9387///
9388/// @param fn_type the function type to consider.
9389///
9390/// @param internal set to true if the call is intended for an
9391/// internal use (for technical use inside the library itself), false
9392/// otherwise. If you don't know what this is for, then set it to
9393/// false.
9394///
9395/// @return the string represenation of the function type.
9396string
9398 bool internal)
9399{return get_pretty_representation(fn_type.get(), internal);}
9400
9401/// Get the pretty representation of a function type.
9402///
9403/// @param fn_type the function type to consider.
9404///
9405/// @param internal set to true if the call is intended for an
9406/// internal use (for technical use inside the library itself), false
9407/// otherwise. If you don't know what this is for, then set it to
9408/// false.
9409///
9410/// @return the string represenation of the function type.
9411string
9412get_pretty_representation(const function_type* fn_type, bool internal)
9413{
9414 if (!fn_type)
9415 return "void";
9416
9417 if (const method_type* method = is_method_type(fn_type))
9418 return get_pretty_representation(method, internal);
9419
9420 return get_pretty_representation(*fn_type, internal);
9421}
9422
9423/// Get the pretty representation of a function type.
9424///
9425/// @param fn_type the function type to consider.
9426///
9427/// @param internal set to true if the call is intended for an
9428/// internal use (for technical use inside the library itself), false
9429/// otherwise. If you don't know what this is for, then set it to
9430/// false.
9431///
9432/// @return the string represenation of the function type.
9433string
9434get_pretty_representation(const function_type& fn_type, bool internal)
9435{
9436 std::ostringstream o;
9437 o << "function type " << get_function_type_name(fn_type, internal);
9438 return o.str();
9439}
9440
9441/// Get the pretty representation of a method type.
9442///
9443/// @param method the method type to consider.
9444///
9445/// @param internal set to true if the call is intended for an
9446/// internal use (for technical use inside the library itself), false
9447/// otherwise. If you don't know what this is for, then set it to
9448/// false.
9449///
9450/// @return the string represenation of the method type.
9451string
9452get_pretty_representation(const method_type& method, bool internal)
9453{
9454 std::ostringstream o;
9455 o << "method type " << get_method_type_name(method, internal);
9456 return o.str();
9457}
9458
9459/// Get the pretty representation of a method type.
9460///
9461/// @param method the method type to consider.
9462///
9463/// @param internal set to true if the call is intended for an
9464/// internal use (for technical use inside the library itself), false
9465/// otherwise. If you don't know what this is for, then set it to
9466/// false.
9467///
9468/// @return the string represenation of the method type.
9469string
9470get_pretty_representation(const method_type* method, bool internal)
9471{
9472 if (!method)
9473 return "void";
9474 return get_pretty_representation(*method, internal);
9475}
9476
9477/// Get the pretty representation of a method type.
9478///
9479/// @param method the method type to consider.
9480///
9481/// @param internal set to true if the call is intended for an
9482/// internal use (for technical use inside the library itself), false
9483/// otherwise. If you don't know what this is for, then set it to
9484/// false.
9485///
9486/// @return the string represenation of the method type.
9487string
9489{return get_pretty_representation(method.get(), internal);}
9490
9491/// Get the flat representation of an instance of @ref class_or_union
9492/// type.
9493///
9494/// The flat representation of a given @ref class_or_union type is the
9495/// actual definition of the type, for instance:
9496///
9497/// struct foo {int a; char b;}
9498///
9499///@param cou the instance of @ref class_or_union to consider.
9500///
9501///@param indent the identation spaces to use in the representation.
9502///
9503///@param one_line if true, then the flat representation stands on one
9504///line. Otherwise, it stands on multiple lines.
9505///
9506///@return the resulting flat representation.
9507string
9509 const string& indent,
9510 bool one_line,
9511 bool internal,
9512 bool qualified_names)
9513{
9514 string repr;
9515 string local_indent = " ";
9516
9517 if (class_decl* clazz = is_class_type(&cou))
9518 {
9519 repr = indent;
9520 if (!internal && clazz->is_struct())
9521 repr += "struct";
9522 else
9523 repr += "class";
9524 }
9525 else if (is_union_type(cou))
9526 repr = indent + "union";
9527 else
9528 return "";
9529
9530 repr += " ";
9531
9532 string name = cou.get_qualified_name();
9533
9534 if (!cou.get_is_anonymous())
9535 repr += name;
9536
9537 if (cou.priv_->is_printing_flat_representation())
9538 {
9539 // We have just detected a cycle while walking the sub-tree
9540 // of this class or union type for the purpose of printing
9541 // its flat representation. We need to get out of here
9542 // pronto or else we'll be spinning endlessly.
9543 repr += "{}";
9544 return repr;
9545 }
9546
9547 // Let's mark this class or union type to signify that we started
9548 // walking its sub-tree. This is to detect potential cycles and
9549 // avoid looping endlessly.
9551
9552 repr += "{";
9553
9554 if (!one_line)
9555 repr += "\n";
9556
9557 string real_indent;
9559 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9560 dm != dmems.end();
9561 ++dm)
9562 {
9563 if (dm != dmems.begin())
9564 {
9565 if (one_line)
9566 real_indent = " ";
9567 else
9568 real_indent = "\n" + indent + local_indent;
9569 }
9570
9572 repr +=
9575 real_indent, one_line, internal, qualified_names);
9576 else
9577 {
9578 if (one_line)
9579 {
9580 if (dm != dmems.begin())
9581 repr += real_indent;
9582 repr += (*dm)->get_pretty_representation(internal,
9583 qualified_names);
9584 }
9585 else
9586 repr +=
9587 real_indent+ (*dm)->get_pretty_representation(internal,
9588 qualified_names);
9589 }
9590 repr += ";";
9591 }
9592
9593 if (one_line)
9594 repr += "}";
9595 else
9596 repr += indent + "}";
9597
9598 // Let's unmark this class or union type to signify that we are done
9599 // walking its sub-tree. This was to detect potential cycles and
9600 // avoid looping endlessly.
9602
9603 return repr;
9604}
9605
9606/// Get the flat representation of an instance of @ref class_or_union
9607/// type.
9608///
9609/// The flat representation of a given @ref class_or_union type is the
9610/// actual definition of the type, for instance:
9611///
9612/// struct foo {int a; char b;}
9613///
9614///@param cou the instance of @ref class_or_union to consider.
9615///
9616///@param indent the identation spaces to use in the representation.
9617///
9618///@param one_line if true, then the flat representation stands on one
9619///line. Otherwise, it stands on multiple lines.
9620///
9621///@return the resulting flat representation.
9622string
9624 const string& indent,
9625 bool one_line,
9626 bool internal,
9627 bool qualified_names)
9628{
9629 if (cou)
9630 return get_class_or_union_flat_representation(*cou, indent, one_line,
9631 internal, qualified_names);
9632 return "";
9633}
9634
9635/// Get the flat representation of an instance of @ref class_or_union
9636/// type.
9637///
9638/// The flat representation of a given @ref class_or_union type is the
9639/// actual definition of the type, for instance:
9640///
9641/// struct foo {int a; char b;}
9642///
9643///@param cou the instance of @ref class_or_union to consider.
9644///
9645///@param indent the identation spaces to use in the representation.
9646///
9647///@param one_line if true, then the flat representation stands on one
9648///line. Otherwise, it stands on multiple lines.
9649///
9650///@return the resulting flat representation.
9651string
9652get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9653 const string& indent,
9654 bool one_line,
9655 bool internal,
9656 bool qualified_names)
9658 indent,
9659 one_line,
9660 internal,
9661 qualified_names);}
9662
9663/// Get the flat representation of an instance of @ref enum_type_decl
9664/// type.
9665///
9666/// The flat representation of a given @ref enum_type_decl type is the
9667/// actual definition of the type, for instance:
9668///
9669/// enum {E_0 =0, E_1 = 1}
9670///
9671///@param enum_type the enum type to consider.
9672///
9673///@param indent the identation spaces to use in the representation.
9674///
9675///@param one_line if true, then the flat representation stands on one
9676///line. Otherwise, it stands on multiple lines.
9677///
9678///@param qualified_names use qualified names when applicable.
9679///Typically, if this is true, the name of the enum is going to be
9680///qualified.
9681///
9682///@return the resulting flat representation.
9683string
9685 const string& indent, bool one_line,
9686 bool qualified_names)
9687{
9688 string repr;
9689 std::ostringstream o;
9690 string local_indent = " ";
9691
9692 repr = indent + "enum ";
9693
9694 if (!enum_type.get_is_anonymous())
9695 o << (qualified_names
9696 ? enum_type.get_qualified_name()
9697 : enum_type.get_name()) + " ";
9698
9699 o << "{";
9700
9701 if (!one_line)
9702 o << "\n";
9703
9704 for (const auto &enumerator : enum_type.get_sorted_enumerators())
9705 {
9706 if (!one_line)
9707 o << "\n" + indent;
9708
9709 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
9710 }
9711
9712 if (!one_line)
9713 o << "\n" + indent << "}";
9714 else
9715 o << "}";
9716
9717 repr =o.str();
9718
9719 return repr;
9720}
9721
9722/// Get the flat representation of an instance of @ref enum_type_decl
9723/// type.
9724///
9725/// The flat representation of a given @ref enum_type_decl type is the
9726/// actual definition of the type, for instance:
9727///
9728/// enum {E_0 =0, E_1 = 1}
9729///
9730///@param enum_type the enum type to consider.
9731///
9732///@param indent the identation spaces to use in the representation.
9733///
9734///@param one_line if true, then the flat representation stands on one
9735///line. Otherwise, it stands on multiple lines.
9736///
9737///@param qualified_names use qualified names when applicable.
9738///Typically, if this is true, the name of the enum is going to be
9739///qualified.
9740///
9741///@return the resulting flat representation.
9742string
9744 const string& indent, bool one_line,
9745 bool qualified_names)
9746{
9747 if (!enum_type)
9748 return "";
9749
9750 return get_enum_flat_representation(*enum_type, indent,
9751 one_line, qualified_names);
9752}
9753
9754/// Get the flat representation of an instance of @ref enum_type_decl
9755/// type.
9756///
9757/// The flat representation of a given @ref enum_type_decl type is the
9758/// actual definition of the type, for instance:
9759///
9760/// enum {E_0 =0, E_1 = 1}
9761///
9762///@param enum_type the enum type to consider.
9763///
9764///@param indent the identation spaces to use in the representation.
9765///
9766///@param one_line if true, then the flat representation stands on one
9767///line. Otherwise, it stands on multiple lines.
9768///
9769///@param qualified_names use qualified names when applicable.
9770///Typically, if this is true, the name of the enum is going to be
9771///qualified.
9772///
9773///@return the resulting flat representation.
9774string
9776 const string& indent, bool one_line,
9777 bool qualified_names)
9778{
9779 return get_enum_flat_representation(enum_type.get(),
9780 indent, one_line,
9781 qualified_names);
9782}
9783
9784/// Get the flat representation of an instance of @ref enum_type_decl
9785/// type.
9786///
9787/// The flat representation of a given @ref enum_type_decl type is the
9788/// actual definition of the type, for instance:
9789///
9790/// enum {E_0 =0, E_1 = 1}
9791///
9792///@param enum_type the enum type to consider.
9793///
9794///@param indent the identation spaces to use in the representation.
9795///
9796///@param one_line if true, then the flat representation stands on one
9797///line. Otherwise, it stands on multiple lines.
9798///
9799///@param qualified_names use qualified names when applicable.
9800///Typically, if this is true, the name of the enum is going to be
9801///qualified.
9802///
9803///@return the resulting flat representation.
9804string
9806 const string& indent,
9807 bool one_line,
9808 bool internal,
9809 bool qualified_name)
9810
9811{
9812 string repr;
9813 if (const class_or_union* cou = is_class_or_union_type(&coe))
9814 repr = get_class_or_union_flat_representation(cou, indent, one_line,
9815 internal, qualified_name);
9816 else if (const enum_type_decl* enom = is_enum_type(&coe))
9817 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9818
9819 return repr;
9820}
9821
9822/// Get the textual representation of a type for debugging purposes.
9823///
9824/// If the type is a class/union, this shows the data members, virtual
9825/// member functions, size, pointer value of its canonical type, etc.
9826/// Otherwise, this just shows the name of the artifact as returned by
9827/// type_or_decl_base:get_pretty_representation().
9828///
9829/// @param artifact the artifact to show a debugging representation of.
9830///
9831/// @return a debugging string representation of @p artifact.
9832string
9834{
9835 string nil_str;
9836 if (!artifact)
9837 return nil_str;
9838
9839 class_or_union * c = is_class_or_union_type(artifact);
9840 if (c)
9841 {
9842 class_decl *clazz = is_class_type(c);
9843 string name = c->get_qualified_name();
9844 std::ostringstream o;
9845 if (clazz)
9846 {
9847 if (clazz->is_struct())
9848 o << "struct ";
9849 else
9850 o << "class ";
9851 }
9852 else if (is_union_type(c))
9853 o << "union ";
9854 o << name;
9855
9856 if (clazz)
9857 {
9858 if (!clazz->get_base_specifiers().empty())
9859 o << " :" << std::endl;
9860 for (auto &b : clazz->get_base_specifiers())
9861 {
9862 o << " ";
9863 if (b->get_is_virtual())
9864 o << "virtual ";
9865 o << b->get_base_class()->get_qualified_name()
9866 << " // hash: ";
9867 hash_t h = peek_hash_value(*b->get_base_class());
9868 if (h)
9869 o << std::hex << *h << std::dec;
9870 else
9871 o << "none";
9872 o << std::endl;
9873 }
9874 }
9875 o << std::endl
9876 << "{"
9877 << " // size in bits: " << c->get_size_in_bits() << "\n"
9878 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9879 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9880 << " // translation unit: "
9881 << (c->get_translation_unit()
9883 : nil_str)
9884 << std::endl
9885 << " // @: " << std::hex << is_type(c)
9886 << ", @canonical: " << c->get_canonical_type().get() << std::dec << "\n"
9887 << " // hash: " ;
9888
9889 hash_t h = peek_hash_value(*c);
9890 if (h)
9891 o << std::hex << *h << std::dec;
9892 else
9893 o << "none";
9894 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*c);
9895 o << "\n\n";
9896
9897
9898 for (auto member_type : c->get_sorted_member_types())
9899 {
9900 o << " "
9901 << member_type->get_pretty_representation(/*internal=*/false,
9902 /*qualified=*/false)
9903 << ";";
9904 if (member_type->get_canonical_type())
9905 {
9906 o << " // uses canonical type: '@"
9907 << std::hex << member_type->get_canonical_type().get() << "'";
9908 o << " / h:";
9909 hash_t h = peek_hash_value(*member_type);
9910 o << std::hex << *h << std::dec;
9911 if (get_canonical_type_index(*member_type))
9912 o << "#" << get_canonical_type_index(*member_type);
9913 }
9914 o << "\n";
9915 }
9916
9917 if (!c->get_sorted_member_types().empty())
9918 o << std::endl;
9919
9920 for (auto m : c->get_data_members())
9921 {
9922 type_base_sptr t = m->get_type();
9924
9925 o << " "
9926 << m->get_pretty_representation(/*internal=*/false,
9927 /*qualified=*/false)
9928 << ";";
9929
9930 if (t && t->get_canonical_type())
9931 o << " // uses canonical type '@"
9932 << std::hex << t->get_canonical_type().get() << "'";
9933
9934 o << "/ h:";
9935 hash_t h = peek_hash_value(*m->get_type());
9936 if (h)
9937 o << std::hex << *h << std::dec;
9938 else
9939 o << "none";
9940 o << std::endl;
9941 }
9942
9943 if (!c->get_data_members().empty())
9944 o << std::endl;
9945
9946 if (clazz && clazz->has_vtable())
9947 {
9948 o << " // virtual member functions\n\n";
9949 for (auto f : clazz->get_virtual_mem_fns())
9950 {
9951 o << " " << f->get_pretty_representation(/*internal=*/false,
9952 /*qualified=*/false)
9953 << " // voffset: " << get_member_function_vtable_offset(f)
9954 << ", h: ";
9955 hash_t h = peek_hash_value(*f->get_type());
9956 if (h)
9957 o << std::hex << *h << std::dec;
9958 else
9959 o << "none";
9960 o << ";" << std::endl;
9961 }
9962 }
9963
9964 o << "};" << std::endl;
9965
9966 return o.str();
9967 }
9968 else if (const enum_type_decl* e = is_enum_type(artifact))
9969 {
9970 string name = e->get_qualified_name();
9971 std::ostringstream o;
9972 o << "enum " << name
9973 << " : "
9974 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9975 true)
9976 << "\n"
9977 << "{\n"
9978 << " // size in bits: " << e->get_size_in_bits() << "\n"
9979 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9980 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9981 << " // translation unit: "
9982 << e->get_translation_unit()->get_absolute_path() << "\n"
9983 << " // @: " << std::hex << is_type(e)
9984 << ", @canonical: " << e->get_canonical_type().get() << std::dec << "\n"
9985 << " // hash: ";
9986
9987 hash_t h = peek_hash_value(*e);
9988 if (h)
9989 o << std::hex << *h << std::dec;
9990 else
9991 o << "none";
9992 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*e);
9993 o << "\n\n";
9994
9995 for (const auto &enom : e->get_enumerators())
9996 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9997
9998 o << "};\n";
9999
10000 return o.str();
10001 }
10002 else if (type_base *t = is_type(artifact))
10003 {
10004 std::ostringstream o;
10005 o << t->get_pretty_representation(/*internal=*/true,
10006 /*qualified=*/true)
10007 << " // cti: " << get_canonical_type_index(*t)
10008 << "\n";
10009 return o.str();
10010 }
10011
10012 return artifact->get_pretty_representation(/*internal=*/true,
10013 /*qualified=*/true);
10014}
10015
10016/// Get a given data member, referred to by its name, of a class type.
10017///
10018/// @param clazz the class to consider.
10019///
10020/// @param member_name name of the data member to get.
10021///
10022/// @return the resulting data member or nullptr if none was found.
10024get_data_member(class_or_union *clazz, const char* member_name)
10025{
10026 if (!clazz)
10027 return var_decl_sptr();
10028 return clazz->find_data_member(member_name);
10029}
10030
10031/// Get a given data member, referred to by its name, of a class type.
10032///
10033/// @param clazz the class to consider.
10034///
10035/// @param member_name name of the data member to get.
10036///
10037/// @return the resulting data member or nullptr if none was found.
10039get_data_member(type_base *clazz, const char* member_name)
10040{return get_data_member(is_class_or_union_type(clazz), member_name);}
10041
10042/// Get the non-artificial (natural) location of a decl.
10043///
10044/// If the decl doesn't have a natural location then return its
10045/// artificial one.
10046///
10047/// @param decl the decl to consider.
10048///
10049/// @return the natural location @p decl if it has one; otherwise,
10050/// return its artificial one.
10051const location&
10053{
10054 ABG_ASSERT(decl);
10055
10056 if (decl->get_location())
10057 return decl->get_location();
10058 return decl->get_artificial_location();
10059}
10060
10061/// Get the artificial location of a decl.
10062///
10063/// If the decl doesn't have an artificial location then return its
10064/// natural one.
10065///
10066/// @param decl the decl to consider.
10067///
10068/// @return the artificial location @p decl if it has one; otherwise,
10069/// return its natural one.
10070const location&
10072{
10073 ABG_ASSERT(decl);
10074
10075 if (decl->has_artificial_location())
10076 return decl->get_artificial_location();
10077 return decl->get_location();
10078}
10079
10080/// Emit a textual representation of an artifact to std error stream
10081/// for debugging purposes.
10082///
10083/// This is useful to invoke from within a command line debugger like
10084/// GDB to help make sense of a given ABI artifact.
10085///
10086/// @param artifact the ABI artifact to emit the debugging
10087/// representation for.
10088///
10089/// @return the artifact @p artifact.
10091debug(const type_or_decl_base* artifact)
10092{
10093 std::cerr << get_debug_representation(artifact) << std::endl;
10094 return const_cast<type_or_decl_base*>(artifact);
10095}
10096
10097/// Emit a textual representation of an artifact to std error stream
10098/// for debugging purposes.
10099///
10100/// This is useful to invoke from within a command line debugger like
10101/// GDB to help make sense of a given ABI artifact.
10102///
10103/// @param artifact the ABI artifact to emit the debugging
10104/// representation for.
10105///
10106/// @return the artifact @p artifact.
10107type_base*
10108debug(const type_base* artifact)
10109{
10110 debug(static_cast<const type_or_decl_base*>(artifact));
10111 return const_cast<type_base*>(artifact);
10112}
10113
10114/// Emit a textual representation of an artifact to std error stream
10115/// for debugging purposes.
10116///
10117/// This is useful to invoke from within a command line debugger like
10118/// GDB to help make sense of a given ABI artifact.
10119///
10120/// @param artifact the ABI artifact to emit the debugging
10121/// representation for.
10122///
10123/// @return the artifact @p artifact.
10124decl_base*
10125debug(const decl_base* artifact)
10126{
10127 debug(static_cast<const type_or_decl_base*>(artifact));
10128 return const_cast<decl_base*>(artifact);
10129}
10130
10131/// Test if two ABI artifacts are equal.
10132///
10133/// This can be useful when used from the command line of a debugger
10134/// like GDB.
10135///
10136/// @param l the first ABI artifact to consider in the comparison.
10137///
10138/// @param r the second ABI artifact to consider in the comparison.
10139///
10140/// @return true iff @p l equals @p r.
10141bool
10143{
10144 if (!!l != !!r)
10145 return false;
10146 if (!l && !r)
10147 return true;
10148
10149 return (*l == *r);
10150}
10151
10152/// Emit a trace of a comparison operand stack.
10153///
10154/// @param vect the operand stack to emit the trace for.
10155///
10156/// @param o the output stream to emit the trace to.
10157static void
10158debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
10159{
10160 for (auto t : vect)
10161 {
10162 o << "|" << t->get_pretty_representation()
10163 << "@" << std::hex << t << std::dec;
10164 }
10165 if (!vect.empty())
10166 o << "|";
10167}
10168
10169/// Construct a trace of the two comparison operand stacks.
10170///
10171/// @param the environment in which the comparison operand stacks are.
10172///
10173/// @return a string representing the trace.
10174static string
10175print_comp_stack(const environment& env)
10176{
10177 std::ostringstream o;
10178 o << "left-operands: ";
10179 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
10180 o << "\n" << "right-operands: ";
10181 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10182 o << "\n";
10183 return o.str();
10184}
10185
10186/// Emit a trace of the two comparison operands stack on the standard
10187/// error stream.
10188///
10189/// @param env the environment the comparison operands stack belong
10190/// to.
10191void
10193{
10194 std::cerr << print_comp_stack(env);
10195 std::cerr << std::endl;
10196}
10197
10198/// By looking at the language of the TU a given ABI artifact belongs
10199/// to, test if the ONE Definition Rule should apply.
10200///
10201/// To date, it applies to c++, java and ada.
10202///
10203/// @param artifact the ABI artifact to consider.
10204///
10205/// @return true iff the One Definition Rule should apply.
10206bool
10208{
10209 if (!artifact.get_translation_unit())
10210 return false;
10211
10213 artifact.get_translation_unit()->get_language();
10214
10216 || is_java_language(l)
10217 || is_ada_language(l))
10218 return true;
10219
10220 return false;
10221}
10222
10223/// Get the declaration for a given type.
10224///
10225/// @param t the type to consider.
10226///
10227/// @return the declaration for the type to return.
10228const decl_base*
10230{return dynamic_cast<const decl_base*>(t);}
10231
10232/// Get the declaration for a given type.
10233///
10234/// @param t the type to consider.
10235///
10236/// @return the declaration for the type to return.
10237decl_base*
10239{return dynamic_cast<decl_base*>(t);}
10240
10241/// Get the declaration for a given type.
10242///
10243/// @param t the type to consider.
10244///
10245/// @return the declaration for the type to return.
10246decl_base_sptr
10247get_type_declaration(const type_base_sptr t)
10248{return dynamic_pointer_cast<decl_base>(t);}
10249
10250/// Test if two classes have the same layout.
10251///
10252/// Test if all the types and offsets of the members are equal,
10253/// regardless of their access modifiers.
10254///
10255/// @param f the first class to take into account.
10256///
10257/// @param s the second class to take into account.
10258///
10259/// @return true iff @p s and @p f are class types with the same
10260/// layout.
10261bool
10262classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
10263{
10264#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10265#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10266#endif
10267
10268#ifdef ENSURE_NO_ENDLESS_LOOP
10269#undef ENSURE_NO_ENDLESS_LOOP
10270#endif
10271
10272#define RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(VALUE) \
10273 do \
10274 { \
10275 auto t1 = is_class_or_union_type(f); \
10276 auto t2 = is_class_or_union_type(s); \
10277 t1->priv_->comparing_class_layouts_.erase(t2.get()); \
10278 t2->priv_->comparing_class_layouts_.erase(t1.get()); \
10279 return VALUE; \
10280 } while (false)
10281
10282#define ENSURE_NO_ENDLESS_LOOP \
10283 do \
10284 { \
10285 auto t1 = is_class_or_union_type(f); \
10286 auto t2 = is_class_or_union_type(s); \
10287 const auto& END = t1->priv_->comparing_class_layouts_.end(); \
10288 if (t1->priv_->comparing_class_layouts_.find(t2.get()) != END \
10289 || t2->priv_->comparing_class_layouts_.find(t1.get()) != END) \
10290 return true; \
10291 t1->priv_->comparing_class_layouts_.insert(t2.get()); \
10292 t2->priv_->comparing_class_layouts_.insert(t1.get()); \
10293 } while (false)
10294
10297
10298 if (!fc
10299 || !sc
10300 || (fc->get_qualified_name() != sc->get_qualified_name())
10301 || (fc->get_size_in_bits() != sc->get_size_in_bits())
10302 || (fc->get_data_members().size() != sc->get_data_members().size()))
10303 return false;
10304
10305 if (*fc == *sc)
10306 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
10307
10308 // Compare the types and offsets of data members one by one.
10309 for (auto f_decl_it = fc->get_data_members().begin(),
10310 s_decl_it = sc->get_data_members().begin();
10311 (f_decl_it != fc->get_data_members().end()
10312 && s_decl_it != sc->get_data_members().end());
10313 ++f_decl_it, ++s_decl_it)
10314 {
10315 var_decl_sptr dm1 = *f_decl_it, dm2 = *s_decl_it;
10316 type_base_sptr dm1_type = dm1->get_type(), dm2_type = dm2->get_type();
10317
10318 if (*dm1_type != *dm2_type
10320 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10321 }
10322
10323 // Compare the layout of base types
10324 for (auto f_bs_it = fc->get_base_specifiers().begin(),
10325 s_bs_it = sc->get_base_specifiers().end();
10326 (f_bs_it != fc->get_base_specifiers().end()
10327 && s_bs_it != sc->get_base_specifiers().end());
10328 ++f_bs_it, ++s_bs_it)
10329 {
10330 class_decl::base_spec_sptr f_bs = *f_bs_it, s_bs = *s_bs_it;
10331 if ((f_bs->get_is_virtual() != s_bs->get_is_virtual())
10332 || (f_bs->get_offset_in_bits() != s_bs->get_offset_in_bits()))
10333 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10334
10335 class_decl_sptr fb = f_bs->get_base_class(), sb = s_bs->get_base_class();
10336 if (!classes_have_same_layout(fb, sb))
10337 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10338 }
10339
10340 if (fc->has_vtable() != sc->has_vtable())
10341 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10342
10343 // Compare virtual function types
10344 ENSURE_NO_ENDLESS_LOOP;
10345 if (fc->has_vtable())
10346 {
10347 if (fc->get_virtual_mem_fns().size() > sc->get_virtual_mem_fns().size())
10348 // Some virtual member function got removed. Bad.
10349 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10350
10351 for (auto it1 = fc->get_virtual_mem_fns().begin(),
10352 it2 = sc->get_virtual_mem_fns().begin();
10353 (it1 != fc->get_virtual_mem_fns().end()
10354 && it2 != sc->get_virtual_mem_fns().end());
10355 ++it1, ++it2)
10356 {
10357 method_decl_sptr method1 = *it1;
10358 method_decl_sptr method2 = *it2;
10359
10362 || !types_are_compatible(method1->get_type(),
10363 method2->get_type()))
10364 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10365 }
10366 }
10367
10368 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
10369
10370#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10371#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10372#endif
10373
10374#ifdef ENSURE_NO_ENDLESS_LOOP
10375#undef ENSURE_NO_ENDLESS_LOOP
10376#endif
10377}
10378
10379/// Test if two types are equal modulo a typedef or CV qualifiers.
10380///
10381/// Type A and B are compatible if
10382///
10383/// - A and B are equal
10384/// - or A and B are integral types with harmless name change
10385/// - or if one type is a typedef of the other one.
10386/// - or if one type is the CV qualified version of the other
10387/// - or if A and B are classes with the same layout.
10388/// - or if A and B are pointers, references or arrays of
10389/// compatible types
10390///
10391/// @param type1 the first type to consider.
10392///
10393/// @param type2 the second type to consider.
10394///
10395/// @return true iff @p type1 and @p type2 are compatible.
10396bool
10397types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
10398{
10399 if (!type1 || !type2)
10400 return false;
10401
10402 if (type1 == type2 || *type1 == *type2)
10403 return true;
10404
10405 type_base_sptr t1 = peel_qualified_or_typedef_type(type1);
10406 type_base_sptr t2 = peel_qualified_or_typedef_type(type2);
10407
10408 if (t1 && t2 && *t1 == *t2)
10409 return true;
10410
10412 return true;
10413
10414 if (is_pointer_type(t1) && is_pointer_type(t2))
10415 {
10416 t1 = is_pointer_type(t1)->get_pointed_to_type();
10417 t2 = is_pointer_type(t2)->get_pointed_to_type();
10418 return types_are_compatible(t1, t2);
10419 }
10420
10421 if (is_reference_type(t1) && is_reference_type(t2))
10422 {
10423 t1 = is_reference_type(t1)->get_pointed_to_type();
10424 t2 = is_reference_type(t2)->get_pointed_to_type();
10425 return types_are_compatible(t1, t2);
10426 }
10427
10428 if (is_array_type(t1) && is_array_type(t2))
10429 {
10432 type_base_sptr e1 = a1->get_element_type();
10433 type_base_sptr e2 = a2->get_element_type();
10436
10437 if ((a1->get_size_in_bits() != a2->get_size_in_bits())
10438 || (a1->get_dimension_count() != a2->get_dimension_count())
10439 || !types_are_compatible(e1, e2))
10440 return false;
10441
10442 return true;
10443 }
10444
10445 if (function_type_sptr fn_type1 = is_function_type(t1))
10446 if (function_type_sptr fn_type2 = is_function_type(t2))
10447 {
10448 // Compare return types
10449 if (!types_are_compatible(fn_type1->get_return_type(),
10450 fn_type2->get_return_type()))
10451 return false;
10452
10453 // Compare parameter types, omitting the implicit parameter to
10454 // avoid infinite recursion when we are being called from
10455 // classes_have_same_layout on classes with virtual member
10456 // functions.
10457 if (fn_type1->get_parameters().size()
10458 != fn_type2->get_parameters().size())
10459 return false;
10460
10461 for (auto p1 = fn_type1->get_first_non_implicit_parm(),
10462 p2 = fn_type2->get_first_non_implicit_parm();
10463 (p1 != fn_type1->get_parameters().end()
10464 && p2 != fn_type2->get_parameters().end());
10465 ++p1, ++p2)
10466 if (!types_are_compatible((*p1)->get_type(),
10467 (*p2)->get_type()))
10468 return false;
10469
10470 return true;
10471 }
10472
10473 if (classes_have_same_layout(t1, t2))
10474 return true;
10475
10476 return false;
10477}
10478
10479/// Test if two types are equal modulo a typedef.
10480///
10481/// Type A and B are compatible if
10482///
10483/// - A and B are equal
10484/// - or if one type is a typedef of the other one.
10485///
10486/// @param type1 the declaration of the first type to consider.
10487///
10488/// @param type2 the declaration of the second type to consider.
10489///
10490/// @return true iff @p type1 and @p type2 are compatible.
10491bool
10492types_are_compatible(const decl_base_sptr d1,
10493 const decl_base_sptr d2)
10494{return types_are_compatible(is_type(d1), is_type(d2));}
10495
10496/// Return the translation unit a declaration belongs to.
10497///
10498/// @param decl the declaration to consider.
10499///
10500/// @return the resulting translation unit, or null if the decl is not
10501/// yet added to a translation unit.
10504{
10505 translation_unit* result =
10506 const_cast<translation_unit*>(t.get_translation_unit());
10507
10508 if (result)
10509 return result;
10510
10511 if (decl_base* decl = is_decl(&t))
10512 {
10513 scope_decl* scope = decl->get_scope();
10514 while (scope)
10515 {
10516 result = scope->get_translation_unit();
10517 if (result)
10518 break;
10519 scope = scope->get_scope();
10520 }
10521 }
10522
10523 return result;
10524}
10525
10526/// Return the translation unit a declaration belongs to.
10527///
10528/// @param decl the declaration to consider.
10529///
10530/// @return the resulting translation unit, or null if the decl is not
10531/// yet added to a translation unit.
10534{return decl ? get_translation_unit(*decl) : nullptr;}
10535
10536/// Return the translation unit a declaration belongs to.
10537///
10538/// @param decl the declaration to consider.
10539///
10540/// @return the resulting translation unit, or null if the decl is not
10541/// yet added to a translation unit.
10544{return get_translation_unit(decl.get());}
10545
10546/// Tests whether if a given scope is the global scope.
10547///
10548/// @param scope the scope to consider.
10549///
10550/// @return true iff the current scope is the global one.
10551bool
10553{return !!dynamic_cast<const global_scope*>(&scope);}
10554
10555/// Tests whether if a given scope is the global scope.
10556///
10557/// @param scope the scope to consider.
10558///
10559/// @return the @ref global_scope* representing the scope @p scope or
10560/// 0 if @p scope is not a global scope.
10561const global_scope*
10563{return dynamic_cast<const global_scope*>(scope);}
10564
10565/// Tests whether if a given scope is the global scope.
10566///
10567/// @param scope the scope to consider.
10568///
10569/// @return true iff the current scope is the global one.
10570bool
10571is_global_scope(const shared_ptr<scope_decl>scope)
10572{return is_global_scope(scope.get());}
10573
10574/// Tests whether a given declaration is at global scope.
10575///
10576/// @param decl the decl to consider.
10577///
10578/// @return true iff decl is at global scope.
10579bool
10581{return (is_global_scope(decl.get_scope()));}
10582
10583/// Tests whether a given declaration is at global scope.
10584///
10585/// @param decl the decl to consider.
10586///
10587/// @return true iff decl is at global scope.
10588bool
10589is_at_global_scope(const decl_base_sptr decl)
10590{return (decl && is_global_scope(decl->get_scope()));}
10591
10592/// Tests whether a given declaration is at global scope.
10593///
10594/// @param decl the decl to consider.
10595///
10596/// @return true iff decl is at global scope.
10597bool
10599{return is_at_global_scope(*decl);}
10600
10601/// Tests whether a given decl is at class scope.
10602///
10603/// @param decl the decl to consider.
10604///
10605/// @return true iff decl is at class scope.
10607is_at_class_scope(const decl_base_sptr decl)
10608{return is_at_class_scope(decl.get());}
10609
10610/// Tests whether a given decl is at class scope.
10611///
10612/// @param decl the decl to consider.
10613///
10614/// @return true iff decl is at class scope.
10617{
10618 if (!decl)
10619 return 0;
10620
10621 return is_at_class_scope(*decl);
10622}
10623
10624/// Tests whether a given decl is at class scope.
10625///
10626/// @param decl the decl to consider.
10627///
10628/// @return true iff decl is at class scope.
10631{
10632 scope_decl* scope = decl.get_scope();
10633 if (class_or_union* cl = is_class_type(scope))
10634 return cl;
10635 if (class_or_union* cl = is_union_type(scope))
10636 return cl;
10637 return 0;
10638}
10639
10640/// Find a data member inside an anonymous data member.
10641///
10642/// An anonymous data member has a type which is a class or union.
10643/// This function looks for a data member inside the type of that
10644/// anonymous data member.
10645///
10646/// @param anon_dm the anonymous data member to consider.
10647///
10648/// @param name the name of the data member to look for.
10651 const string& name)
10652{
10653 const class_or_union* containing_class_or_union =
10655
10656 if (!containing_class_or_union)
10657 return var_decl_sptr();
10658
10659 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10660 return result;
10661}
10662
10663/// Tests whether a given decl is at template scope.
10664///
10665/// Note that only template parameters , types that are compositions,
10666/// and template patterns (function or class) can be at template scope.
10667///
10668/// @param decl the decl to consider.
10669///
10670/// @return true iff the decl is at template scope.
10671bool
10672is_at_template_scope(const shared_ptr<decl_base> decl)
10673{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10674
10675/// Tests whether a decl is a template parameter.
10676///
10677/// @param decl the decl to consider.
10678///
10679/// @return true iff decl is a template parameter.
10680bool
10681is_template_parameter(const shared_ptr<decl_base> decl)
10682{
10683 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10684 || dynamic_pointer_cast<non_type_tparameter>(decl)
10685 || dynamic_pointer_cast<template_tparameter>(decl)));
10686}
10687
10688/// Test whether a declaration is a @ref function_decl.
10689///
10690/// @param d the declaration to test for.
10691///
10692/// @return a shared pointer to @ref function_decl if @p d is a @ref
10693/// function_decl. Otherwise, a nil shared pointer.
10696{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10697
10698/// Test whether a declaration is a @ref function_decl.
10699///
10700/// @param d the declaration to test for.
10701///
10702/// @return true if @p d is a function_decl.
10703bool
10705{return is_function_decl(&d);}
10706
10707/// Test whether a declaration is a @ref function_decl.
10708///
10709/// @param d the declaration to test for.
10710///
10711/// @return a shared pointer to @ref function_decl if @p d is a @ref
10712/// function_decl. Otherwise, a nil shared pointer.
10715{return dynamic_pointer_cast<function_decl>(d);}
10716
10717/// Test whether a declaration is a @ref function_decl.
10718///
10719/// @param d the declaration to test for.
10720///
10721/// @return a pointer to @ref function_decl if @p d is a @ref
10722/// function_decl. Otherwise, a nil shared pointer.
10725{
10726 return dynamic_cast<function_decl::parameter*>
10727 (const_cast<type_or_decl_base*>(tod));
10728}
10729
10730/// Test whether an ABI artifact is a @ref function_decl.
10731///
10732/// @param tod the declaration to test for.
10733///
10734/// @return a pointer to @ref function_decl if @p d is a @ref
10735/// function_decl. Otherwise, a nil shared pointer.
10738{return dynamic_pointer_cast<function_decl::parameter>(tod);}
10739
10740/// Test if an ABI artifact is a declaration.
10741///
10742/// @param d the artifact to consider.
10743///
10744/// @param return the declaration sub-object of @p d if it's a
10745/// declaration, or NULL if it is not.
10746decl_base*
10748{
10749 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10750 {
10751 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10752 // The artifact is a decl-only (like a function or a
10753 // variable). That is, it's not a type that also has a
10754 // declaration. In this case, we are in the fast path and we
10755 // have a pointer to the decl sub-object handy. Just return
10756 // it ...
10757 return reinterpret_cast<decl_base*>
10758 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10759
10760 // ... Otherwise, we are in the slow path, which is that the
10761 // artifact is a type which has a declaration. In that case,
10762 // let's use the slow dynamic_cast because we don't have the
10763 // pointer to the decl sub-object handily present.
10764 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10765 }
10766 return 0;
10767}
10768
10769/// Test if an ABI artifact is a declaration.
10770///
10771/// @param d the artifact to consider.
10772///
10773/// @param return the declaration sub-object of @p d if it's a
10774/// declaration, or NULL if it is not.
10775decl_base_sptr
10777{return dynamic_pointer_cast<decl_base>(d);}
10778
10779/// Test if an ABI artifact is a declaration.
10780///
10781/// This is done using a slow path that uses dynamic_cast.
10782///
10783/// @param d the artifact to consider.
10784///
10785/// @param return the declaration sub-object of @p d if it's a
10786decl_base*
10788{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10789
10790/// Test if an ABI artifact is a declaration.
10791///
10792/// This is done using a slow path that uses dynamic_cast.
10793///
10794/// @param d the artifact to consider.
10795///
10796/// @param return the declaration sub-object of @p d if it's a
10797decl_base_sptr
10799{return dynamic_pointer_cast<decl_base>(t);}
10800
10801/// Test whether a declaration is a type.
10802///
10803/// @param d the IR artefact to test for.
10804///
10805/// @return true if the artifact is a type, false otherwise.
10806bool
10808{
10809 if (dynamic_cast<const type_base*>(&tod))
10810 return true;
10811 return false;
10812}
10813
10814/// Test whether a declaration is a type.
10815///
10816/// @param d the IR artefact to test for.
10817///
10818/// @return true if the artifact is a type, false otherwise.
10819type_base*
10821{
10822 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10823 return reinterpret_cast<type_base*>
10824 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10825
10826 return 0;
10827}
10828
10829/// Test whether a declaration is a type.
10830///
10831/// @param d the IR artefact to test for.
10832///
10833/// @return true if the artifact is a type, false otherwise.
10834type_base_sptr
10836{return dynamic_pointer_cast<type_base>(tod);}
10837
10838/// Test whether a declaration is a type.
10839///
10840/// @param d the declaration to test for.
10841///
10842/// @return true if the declaration is a type, false otherwise.
10843
10844/// Test if a given type is anonymous.
10845///
10846/// Note that this function considers that an anonymous class that is
10847/// named by a typedef is not anonymous anymore. This is the C idiom:
10848///
10849/// typedef struct {int member;} s_type;
10850///
10851/// The typedef s_type becomes the name of the originally anonymous
10852/// struct.
10853///
10854/// @param t the type to consider.
10855///
10856/// @return true iff @p t is anonymous.
10857bool
10859{
10860 const decl_base* d = get_type_declaration(t);
10861 if (d)
10862 if (d->get_is_anonymous())
10863 {
10865 {
10866 // An anonymous class that is named by a typedef is not
10867 // considered anonymous anymore.
10868 if (!cou->get_naming_typedef())
10869 return true;
10870 }
10871 else
10872 return true;
10873 }
10874 return false;
10875}
10876
10877/// Test if a given type is anonymous.
10878///
10879/// @param t the type to consider.
10880///
10881/// @return true iff @p t is anonymous.
10882bool
10883is_anonymous_type(const type_base_sptr& t)
10884{return is_anonymous_type(t.get());}
10885
10886/// Test if a type is a neither a pointer, an array nor a function
10887/// type.
10888///
10889/// @param t the type to consider.
10890///
10891/// @return true if the @p t is NOT a pointer, an array nor a
10892/// function.
10893bool
10894is_npaf_type(const type_base_sptr& t)
10895{
10896 if (!(is_pointer_type(t)
10897 || is_array_type(t)
10898 || is_function_type(t)
10899 || is_ptr_to_mbr_type(t)))
10900 return true;
10901 return false;
10902}
10903
10904/// Test whether a type is a type_decl (a builtin type).
10905///
10906/// @return the type_decl* for @t if it's type_decl, otherwise, return
10907/// nil.
10908const type_decl*
10910{return dynamic_cast<const type_decl*>(t);}
10911
10912/// Test whether a type is a type_decl (a builtin type).
10913///
10914/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10915/// return nil.
10918{return dynamic_pointer_cast<type_decl>(t);}
10919
10920/// Test if a type is a real type.
10921///
10922/// @param t the type to test.
10923///
10924/// @return the real type @p t can be converted to, or nil if @p
10925/// is not a real type.
10926type_decl*
10928{
10929 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10930 if (!type)
10931 return nullptr;
10932
10933 real_type int_type;
10934 if (!parse_real_type(type->get_name(), int_type))
10935 return nullptr;
10936
10937 return type;
10938}
10939
10940/// Test if a type is a real type.
10941///
10942/// @param t the type to test.
10943///
10944/// @return the real type @p t can be converted to, or nil if @p is
10945/// not a real type.
10948{
10949 const type_decl_sptr type = is_type_decl(t);
10950 if (!type)
10951 return type_decl_sptr();
10952
10953 real_type int_type;
10954 if (!parse_real_type(type->get_name(), int_type))
10955 return type_decl_sptr();
10956
10957 return type;
10958}
10959
10960/// Test if a type is an integral type.
10961///
10962/// @param t the type to test.
10963///
10964/// @return the integral type @p t can be converted to, or nil if @p
10965/// is not an integral type.
10966type_decl*
10968{
10969 type_decl* type = is_real_type(t);
10970 if (!type)
10971 return nullptr;
10972
10973 real_type rt;
10974 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10977 return nullptr;
10978
10979 return type;
10980}
10981
10982/// Test if a type is an integral type.
10983///
10984/// @param t the type to test.
10985///
10986/// @return the integral type @p t can be converted to, or nil if @p
10987/// is not an integral type.
10990{
10991 type_decl_sptr type = is_real_type(t);
10992 if (!type)
10993 return type;
10994
10995 real_type rt;
10996 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10999 return type_decl_sptr();
11000
11001 return type;
11002}
11003
11004/// Test whether a type is a typedef.
11005///
11006/// @param t the type to test for.
11007///
11008/// @return the typedef declaration of the @p t, or NULL if it's not a
11009/// typedef.
11012{return dynamic_pointer_cast<typedef_decl>(t);}
11013
11014/// Test whether a type is a typedef.
11015///
11016/// @param t the declaration of the type to test for.
11017///
11018/// @return the typedef declaration of the @p t, or NULL if it's not a
11019/// typedef.
11020const typedef_decl*
11022{return dynamic_cast<const typedef_decl*>(t);}
11023
11024/// Test whether a type is a typedef.
11025///
11026/// @param t the declaration of the type to test for.
11027///
11028/// @return the typedef declaration of the @p t, or NULL if it's not a
11029/// typedef.
11032{return dynamic_cast<typedef_decl*>(t);}
11033
11034/// Test whether a type is a typedef.
11035///
11036/// @param t the declaration of the type to test for.
11037///
11038/// @return the typedef declaration of the @p t, or NULL if it's not a
11039/// typedef.
11040const typedef_decl*
11042{return dynamic_cast<const typedef_decl*>(t);}
11043
11044/// Test if a type is an enum. This function looks through typedefs.
11045///
11046/// @parm t the type to consider.
11047///
11048/// @return the enum_decl if @p t is an @ref enum_decl or null
11049/// otherwise.
11050const enum_type_decl*
11052{
11053 if (!t)
11054 return nullptr;
11055
11056 type_base* ty = const_cast<type_base*>(peel_typedef_type(t));
11057 return is_enum_type(ty);
11058}
11059
11060/// Test if a type is an enum. This function looks through typedefs.
11061///
11062/// @parm t the type to consider.
11063///
11064/// @return the enum_decl if @p t is an @ref enum_decl or null
11065/// otherwise.
11067is_compatible_with_enum_type(const type_base_sptr& t)
11068{
11069 if (!t)
11070 return enum_type_decl_sptr();
11071
11072 // Normally we should strip typedefs entirely, but this is
11073 // potentially costly, especially on binaries with huge changesets
11074 // like the Linux Kernel. So we just get the leaf types for now.
11075 //
11076 // Maybe there should be an option by which users accepts to pay the
11077 // CPU usage toll in exchange for finer filtering?
11078
11079 // type_base_sptr ty = strip_typedef(t);
11080 type_base_sptr ty = peel_typedef_type(t);;
11081 return is_enum_type(ty);
11082}
11083
11084/// Test if a type is an enum. This function looks through typedefs.
11085///
11086/// @parm t the type to consider.
11087///
11088/// @return the enum_decl if @p t is an @ref enum_decl or null
11089/// otherwise.
11091is_compatible_with_enum_type(const decl_base_sptr& t)
11093
11094/// Test if a decl is an enum_type_decl
11095///
11096/// @param d the decl to test for.
11097///
11098/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
11099const enum_type_decl*
11101{return dynamic_cast<const enum_type_decl*>(d);}
11102
11103/// Test if a decl is an enum_type_decl
11104///
11105/// @param d the decl to test for.
11106///
11107/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
11110{return dynamic_pointer_cast<enum_type_decl>(d);}
11111
11112/// Test if a type is a class. This function looks through typedefs.
11113///
11114/// @parm t the type to consider.
11115///
11116/// @return the class_decl if @p t is a class_decl or null otherwise.
11117const class_decl*
11119{
11120 if(!t)
11121 return nullptr;
11122
11123 const type_base* ty = peel_typedef_type(t);
11124 return is_class_type(ty);
11125}
11126
11127/// Test if a type is a class. This function looks through typedefs.
11128///
11129/// @parm t the type to consider.
11130///
11131/// @return the class_decl if @p t is a class_decl or null otherwise.
11133is_compatible_with_class_type(const type_base_sptr& t)
11134{
11135 if (!t)
11136 return class_decl_sptr();
11137
11138 // Normally we should strip typedefs entirely, but this is
11139 // potentially costly, especially on binaries with huge changesets
11140 // like the Linux Kernel. So we just get the leaf types for now.
11141 //
11142 // Maybe there should be an option by which users accepts to pay the
11143 // CPU usage toll in exchange for finer filtering?
11144
11145 // type_base_sptr ty = strip_typedef(t);
11146 type_base_sptr ty = peel_typedef_type(t);
11147 return is_class_type(ty);
11148}
11149
11150/// Test if a type is a class. This function looks through typedefs.
11151///
11152/// @parm t the type to consider.
11153///
11154/// @return the class_decl if @p t is a class_decl or null otherwise.
11156is_compatible_with_class_type(const decl_base_sptr& t)
11158
11159/// Test whether a type is a class.
11160///
11161/// @parm t the type to consider.
11162///
11163/// @return true iff @p t is a class_decl.
11164bool
11166{return is_class_type(&t);}
11167
11168/// Test whether a type is a class.
11169///
11170/// @parm t the type to consider.
11171///
11172/// @return the class_decl if @p t is a class_decl or null otherwise.
11175{
11176 if (!t)
11177 return 0;
11178
11179 if (t->kind() & type_or_decl_base::CLASS_TYPE)
11180 return reinterpret_cast<class_decl*>
11181 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
11182
11183 return 0;
11184}
11185
11186/// Test whether a type is a class.
11187///
11188/// @parm t the type to consider.
11189///
11190/// @return the class_decl if @p t is a class_decl or null otherwise.
11193{return dynamic_pointer_cast<class_decl>(d);}
11194
11195/// Test if the last data member of a class is an array with
11196/// non-finite data member.
11197///
11198/// The flexible data member idiom is a well known C idiom:
11199/// https://en.wikipedia.org/wiki/Flexible_array_member.
11200///
11201/// @param klass the class to consider.
11202///
11203/// @return the data member which type is a flexible array, if any, or
11204/// nil.
11207{
11208 var_decl_sptr nil;
11210 if (dms.empty())
11211 return nil;
11212
11213 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11214 {// The type of the last data member is an array.
11215 if (array->is_non_finite())
11216 // The array has a non-finite size. We are thus looking at a
11217 // flexible array data member. Let's return it.
11218 return dms.back();
11219 }
11220
11221 return nil;
11222}
11223
11224/// Test if the last data member of a class is an array with
11225/// non-finite data member.
11226///
11227/// The flexible data member idiom is a well known C idiom:
11228/// https://en.wikipedia.org/wiki/Flexible_array_member.
11229///
11230/// @param klass the class to consider.
11231///
11232/// @return the data member which type is a flexible array, if any, or
11233/// nil.
11236{
11237 if (!klass)
11238 return var_decl_sptr();
11239
11240 return has_flexible_array_data_member(*klass);
11241}
11242
11243/// Test if the last data member of a class is an array with
11244/// non-finite data member.
11245///
11246/// The flexible data member idiom is a well known C idiom:
11247/// https://en.wikipedia.org/wiki/Flexible_array_member.
11248///
11249/// @param klass the class to consider.
11250///
11251/// @return the data member which type is a flexible array, if any, or
11252/// nil.
11255{return has_flexible_array_data_member(klass.get());}
11256
11257/// Test if the last data member of a class is an array with
11258/// one element.
11259///
11260/// An array with one element is a way to mimic the flexible data
11261/// member idiom that was later standardized in C99.
11262///
11263/// To learn more about the flexible data member idiom, please
11264/// consider reading :
11265/// https://en.wikipedia.org/wiki/Flexible_array_member.
11266///
11267/// The various ways of representing that idiom pre-standardization
11268/// are presented in this article:
11269/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11270///
11271/// @param klass the class to consider.
11272///
11273/// @return the data member which type is a fake flexible array, if
11274/// any, or nil.
11277{
11278 var_decl_sptr nil;
11280 if (dms.empty())
11281 return nil;
11282
11283 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11284 {// The type of the last data member is an array.
11285 if (array->get_subranges().size() == 1
11286 && array->get_subranges()[0]->get_length() == 1)
11287 // The array has a size of one. We are thus looking at a
11288 // "fake" flexible array data member. Let's return it.
11289 return dms.back();
11290 }
11291
11292 return nil;
11293}
11294
11295/// Test if the last data member of a class is an array with
11296/// one element.
11297///
11298/// An array with one element is a way to mimic the flexible data
11299/// member idiom that was later standardized in C99.
11300///
11301/// To learn more about the flexible data member idiom, please
11302/// consider reading :
11303/// https://en.wikipedia.org/wiki/Flexible_array_member.
11304///
11305/// The various ways of representing that idiom pre-standardization
11306/// are presented in this article:
11307/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11308///
11309/// @param klass the class to consider.
11310///
11311/// @return the data member which type is a fake flexible array, if
11312/// any, or nil.
11316
11317/// Test if the last data member of a class is an array with
11318/// one element.
11319///
11320/// An array with one element is a way to mimic the flexible data
11321/// member idiom that was later standardized in C99.
11322///
11323/// To learn more about the flexible data member idiom, please
11324/// consider reading :
11325/// https://en.wikipedia.org/wiki/Flexible_array_member.
11326///
11327/// The various ways of representing that idiom pre-standardization
11328/// are presented in this article:
11329/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11330///
11331/// @param klass the class to consider.
11332///
11333/// @return the data member which type is a fake flexible array, if
11334/// any, or nil.
11337{return has_fake_flexible_array_data_member(klass.get());}
11338
11339/// Test wheter a type is a declaration-only class.
11340///
11341/// @param t the type to considier.
11342///
11343/// @param look_through_decl_only if true, then look through the
11344/// decl-only class to see if it actually has a class definition in
11345/// the same ABI corpus.
11346///
11347/// @return true iff @p t is a declaration-only class.
11348bool
11351{
11352 if (class_or_union *klass = is_class_or_union_type(t))
11353 {
11355 klass = look_through_decl_only_class(klass);
11356 return klass->get_is_declaration_only();
11357 }
11358 return false;
11359}
11360
11361/// Test wheter a type is a declaration-only class.
11362///
11363/// @param t the type to considier.
11364///
11365/// @param look_through_decl_only if true, then look through the
11366/// decl-only class to see if it actually has a class definition in
11367/// the same ABI corpus.
11368///
11369/// @return true iff @p t is a declaration-only class.
11370bool
11374
11375/// Test wheter a type is a declaration-only class.
11376///
11377/// @param t the type to considier.
11378///
11379/// @param look_through_decl_only if true, then look through the
11380/// decl-only class to see if it actually has a class definition in
11381/// the same ABI corpus.
11382///
11383/// @return true iff @p t is a declaration-only class.
11384bool
11385is_declaration_only_class_type(const type_base_sptr& t,
11388
11389/// Test if a type is a @ref class_or_union.
11390///
11391/// @param t the type to consider.
11392///
11393/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11394/// nil otherwise.
11397{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
11398
11399/// Test if a type is a @ref class_or_union.
11400///
11401/// @param t the type to consider.
11402///
11403/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11404/// nil otherwise.
11405shared_ptr<class_or_union>
11406is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
11407{return dynamic_pointer_cast<class_or_union>(t);}
11408
11409/// Test if two class or union types are of the same kind.
11410///
11411/// @param first the first type to consider.
11412///
11413/// @param second the second type to consider.
11414///
11415/// @return true iff @p first is of the same kind as @p second.
11416bool
11418 const class_or_union* second)
11419{
11420 if ((is_class_type(first) && is_class_type(second))
11421 || (is_union_type(first) && is_union_type(second)))
11422 return true;
11423
11424 return false;
11425}
11426
11427/// Test if two class or union types are of the same kind.
11428///
11429/// @param first the first type to consider.
11430///
11431/// @param second the second type to consider.
11432///
11433/// @return true iff @p first is of the same kind as @p second.
11434bool
11435class_or_union_types_of_same_kind(const class_or_union_sptr& first,
11436 const class_or_union_sptr& second)
11437{return class_or_union_types_of_same_kind(first.get(), second.get());}
11438
11439/// Test if a type is a @ref union_decl.
11440///
11441/// @param t the type to consider.
11442///
11443/// @return true iff @p t is a union_decl.
11444bool
11446{return is_union_type(&t);}
11447
11448/// Test if a type is a @ref union_decl.
11449///
11450/// @param t the type to consider.
11451///
11452/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11453/// otherwise.
11456{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
11457
11458/// Test if a type is a @ref union_decl.
11459///
11460/// @param t the type to consider.
11461///
11462/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11463/// otherwise.
11464union_decl_sptr
11465is_union_type(const shared_ptr<type_or_decl_base>& t)
11466{return dynamic_pointer_cast<union_decl>(t);}
11467
11468/// Test whether a type is a pointer_type_def.
11469///
11470/// @param t the type to test.
11471///
11472/// @param look_through_decl_only if this is true, then look through
11473/// qualified types to see if the underlying type is a
11474/// pointer_type_def.
11475///
11476/// @return the @ref pointer_type_def_sptr if @p t is a
11477/// pointer_type_def, null otherwise.
11478const pointer_type_def*
11480 bool look_through_qualifiers)
11481{
11482 if (!t)
11483 return 0;
11484
11485 const type_base* type = is_type(t);
11486 if (look_through_qualifiers)
11487 type = peel_qualified_type(is_type(t));
11488
11489 return dynamic_cast<pointer_type_def*>(const_cast<type_base*>(type));
11490}
11491
11492/// Test whether a type is a pointer_type_def.
11493///
11494/// @param t the type to test.
11495///
11496/// @param look_through_decl_only if this is true, then look through
11497/// qualified types to see if the underlying type is a
11498/// pointer_type_def.
11499///
11500/// @return the @ref pointer_type_def_sptr if @p t is a
11501/// pointer_type_def, null otherwise.
11504 bool look_through_qualifiers)
11505{
11506 type_base_sptr type = is_type(t);
11507 if (look_through_qualifiers)
11508 type = peel_qualified_type(type);
11509 return dynamic_pointer_cast<pointer_type_def>(type);
11510}
11511
11512/// Test if a type is a pointer to function type.
11513///
11514/// @param t the type to consider.
11515///
11516/// @return the @ref pointer_type_def_sptr iff @p t is a pointer to
11517/// function type.
11519is_pointer_to_function_type(const type_base_sptr& t)
11520{
11522 {
11523 if (is_function_type(p->get_pointed_to_type()))
11524 return p;
11525 }
11526 return pointer_type_def_sptr();
11527}
11528
11529/// Test if a type is a pointer to array type.
11530///
11531/// @param t the type to consider.
11532///
11533/// @return the pointer_type_def_sptr iff @p t is a pointer to array
11534/// type.
11536is_pointer_to_array_type(const type_base_sptr& t)
11537{
11539 {
11540 if (is_array_type(p->get_pointed_to_type()))
11541 return p;
11542 }
11543 return pointer_type_def_sptr();
11544}
11545
11546/// Test if we are looking at a pointer to a
11547/// neither-a-pointer-to-an-array-nor-a-function type.
11548///
11549/// @param t the type to consider.
11550///
11551/// @return the @ref pointer_type_def_sptr type iff @p t is a
11552/// neither-a-pointer-an-array-nor-a-function type.
11554is_pointer_to_npaf_type(const type_base_sptr& t)
11555{
11557 {
11558 if (is_npaf_type(p->get_pointed_to_type()))
11559 return p;
11560 }
11561 return pointer_type_def_sptr();
11562}
11563
11564/// Test if we are looking at a pointer to pointer to member type.
11565///
11566/// @param t the type to consider.
11567///
11568/// @return the @ref pointer_type_def_sptr type iff @p t is a pointer
11569/// to pointer to member type.
11571is_pointer_to_ptr_to_mbr_type(const type_base_sptr& t)
11572{
11574 {
11575 if (is_ptr_to_mbr_type(p->get_pointed_to_type()))
11576 return p;
11577 }
11578 return pointer_type_def_sptr();
11579}
11580
11581/// Test if a type is a typedef, pointer or reference to a decl-only
11582/// class/union.
11583///
11584/// This looks into qualified types too.
11585///
11586/// @param t the type to consider.
11587///
11588/// @return true iff @p t is a type is a typedef, pointer or reference
11589/// to a decl-only class/union.
11590bool
11592{
11593 const type_base * type =
11594 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11595
11597 /*look_through_decl_only=*/true))
11598 return true;
11599
11600 return false;
11601}
11602
11603/// Test if a type is a typedef of a class or union type, or a typedef
11604/// of a qualified class or union type.
11605///
11606/// Note that if the type is directly a class or union type, the
11607/// function returns true as well.
11608///
11609/// @param t the type to consider.
11610///
11611/// @return true iff @p t is a typedef of a class or union type, or a
11612/// typedef of a qualified class or union type.
11613bool
11615{
11616 if (!t)
11617 return false;
11618
11621 return true;
11622
11623return false;
11624}
11625
11626/// Test if a type is a typedef of a class or union type, or a typedef
11627/// of a qualified class or union type.
11628///
11629/// Note that if the type is directly a class or union type, the
11630/// function returns true as well.
11631///
11632/// @param t the type to consider.
11633///
11634/// @return true iff @p t is a typedef of a class or union type, or a
11635/// typedef of a qualified class or union type.
11636bool
11639
11640/// Test whether a type is a reference_type_def.
11641///
11642/// @param t the type to test.
11643///
11644/// @param look_through_decl_only if this is true, then look through
11645/// qualified types to see if the underlying type is a
11646/// reference_type_def.
11647///
11648/// @return the @ref reference_type_def_sptr if @p t is a
11649/// reference_type_def, null otherwise.
11652 bool look_through_qualifiers)
11653{
11654 const type_base* type = is_type(t);
11655 if (!type)
11656 return nullptr;
11657
11658 if (look_through_qualifiers)
11659 type = peel_qualified_type(type);
11660 return dynamic_cast<reference_type_def*>(const_cast<type_base*>(type));
11661}
11662
11663/// Test whether a type is a reference_type_def.
11664///
11665/// @param t the type to test.
11666///
11667/// @param look_through_decl_only if this is true, then look through
11668/// qualified types to see if the underlying type is a
11669/// reference_type_def.
11670///
11671/// @return the @ref reference_type_def_sptr if @p t is a
11672/// reference_type_def, null otherwise.
11673const reference_type_def*
11675 bool look_through_qualifiers)
11676{
11677 const type_base* type = is_type(t);
11678
11679 if (look_through_qualifiers)
11680 type = peel_qualified_type(type);
11681 return dynamic_cast<const reference_type_def*>(type);
11682}
11683
11684/// Test whether a type is a reference_type_def.
11685///
11686/// @param t the type to test.
11687///
11688/// @param look_through_decl_only if this is true, then look through
11689/// qualified types to see if the underlying type is a
11690/// reference_type_def.
11691///
11692/// @return the @ref reference_type_def_sptr if @p t is a
11693/// reference_type_def, null otherwise.
11696 bool look_through_qualifiers)
11697{
11698 type_base_sptr type = is_type(t);
11699 if (look_through_qualifiers)
11700 type = peel_qualified_type(type);
11701 return dynamic_pointer_cast<reference_type_def>(type);
11702}
11703
11704/// Test whether a type is a @ref ptr_to_mbr_type.
11705///
11706/// @param t the type to test.
11707///
11708/// @return the @ref ptr_to_mbr_type* if @p t is a @ref
11709/// ptr_to_mbr_type type, null otherwise.
11710const ptr_to_mbr_type*
11712 bool look_through_qualifiers)
11713{
11714 const type_base* type = is_type(t);
11715 if (look_through_qualifiers)
11716 type = peel_qualified_type(type);
11717 return dynamic_cast<const ptr_to_mbr_type*>(type);
11718}
11719
11720/// Test whether a type is a @ref ptr_to_mbr_type_sptr.
11721///
11722/// @param t the type to test.
11723///
11724/// @param look_through_decl_only if this is true, then look through
11725/// qualified types to see if the underlying type is a
11726/// ptr_to_mbr_type..
11727///
11728/// @return the @ref ptr_to_mbr_type_sptr if @p t is a @ref
11729/// ptr_to_mbr_type type, null otherwise.
11732 bool look_through_qualifiers)
11733{
11734 type_base_sptr type = is_type(t);
11735 if (look_through_qualifiers)
11736 type = peel_qualified_type(type);
11737 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
11738}
11739
11740/// Test if a type is equivalent to a pointer to void type.
11741///
11742/// Note that this looks trough typedefs or CV qualifiers to look for
11743/// the void pointer.
11744///
11745/// @param type the type to consider.
11746///
11747/// @return the actual void pointer if @p is eqivalent to a void
11748/// pointer or NULL if it's not.
11749const type_base*
11751{
11752 type = peel_qualified_or_typedef_type(type);
11753
11754 const pointer_type_def * t = is_pointer_type(type);
11755 if (!t)
11756 return 0;
11757
11758 // Look through typedefs in the pointed-to type as well.
11759 type_base * ty = t->get_pointed_to_type().get();
11761 if (ty && ty->get_environment().is_void_type(ty))
11762 return ty;
11763
11764 return 0;
11765}
11766
11767/// Test if a type is equivalent to a pointer to void type.
11768///
11769/// Note that this looks trough typedefs or CV qualifiers to look for
11770/// the void pointer.
11771///
11772/// @param type the type to consider.
11773///
11774/// @return the actual void pointer if @p is eqivalent to a void
11775/// pointer or NULL if it's not.
11776const type_base*
11778{return is_void_pointer_type_equivalent(&type);}
11779
11780/// Test if a type is a pointer to void type.
11781///
11782/// @param type the type to consider.
11783///
11784/// @return the actual void pointer if @p is a void pointer or NULL if
11785/// it's not.
11786const type_base*
11788{
11789 if (!t)
11790 return nullptr;
11791
11792 if (t->get_environment().get_void_pointer_type().get() == t)
11793 return t;
11794
11795 const pointer_type_def* ptr = is_pointer_type(t);
11796 if (!ptr)
11797 return nullptr;
11798
11800 return t;
11801
11802 return nullptr;
11803}
11804
11805/// Test if a type is a pointer to void type.
11806///
11807/// @param type the type to consider.
11808///
11809/// @return the actual void pointer if @p is a void pointer or NULL if
11810/// it's not.
11811const type_base_sptr
11812is_void_pointer_type(const type_base_sptr& t)
11813{
11814 type_base_sptr nil;
11815 if (!t)
11816 return nil;
11817
11818 if (t->get_environment().get_void_pointer_type().get() == t.get())
11819 return t;
11820
11821 const pointer_type_def* ptr = is_pointer_type(t.get());
11822 if (!ptr)
11823 return nil;
11824
11825 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11826 return t;
11827
11828 return nil;
11829}
11830
11831/// Test whether a type is a reference_type_def.
11832///
11833/// @param t the type to test.
11834///
11835/// @return the @ref reference_type_def_sptr if @p t is a
11836/// reference_type_def, null otherwise.
11839{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11840
11841/// Test whether a type is a qualified_type_def.
11842///
11843/// @param t the type to test.
11844///
11845/// @return the @ref qualified_type_def_sptr if @p t is a
11846/// qualified_type_def, null otherwise.
11847qualified_type_def_sptr
11849{return dynamic_pointer_cast<qualified_type_def>(t);}
11850
11851/// Test whether a type is a function_type.
11852///
11853/// @param t the type to test.
11854///
11855/// @return the @ref function_type_sptr if @p t is a
11856/// function_type, null otherwise.
11859{return dynamic_pointer_cast<function_type>(t);}
11860
11861/// Test whether a type is a function_type.
11862///
11863/// @param t the type to test.
11864///
11865/// @return the @ref function_type_sptr if @p t is a
11866/// function_type, null otherwise.
11869{return dynamic_cast<function_type*>(t);}
11870
11871/// Test whether a type is a function_type.
11872///
11873/// @param t the type to test.
11874///
11875/// @return the @ref function_type_sptr if @p t is a
11876/// function_type, null otherwise.
11877const function_type*
11879{return dynamic_cast<const function_type*>(t);}
11880
11881/// Test whether a type is a method_type.
11882///
11883/// @param t the type to test.
11884///
11885/// @return the @ref method_type_sptr if @p t is a
11886/// method_type, null otherwise.
11889{return dynamic_pointer_cast<method_type>(t);}
11890
11891/// Test whether a type is a method_type.
11892///
11893/// @param t the type to test.
11894///
11895/// @return the @ref method_type_sptr if @p t is a
11896/// method_type, null otherwise.
11897const method_type*
11899{return dynamic_cast<const method_type*>(t);}
11900
11901/// Test whether a type is a method_type.
11902///
11903/// @param t the type to test.
11904///
11905/// @return the @ref method_type_sptr if @p t is a
11906/// method_type, null otherwise.
11909{return dynamic_cast<method_type*>(t);}
11910
11911/// If a class (or union) is a decl-only class, get its definition.
11912/// Otherwise, just return the initial class.
11913///
11914/// @param the_class the class (or union) to consider.
11915///
11916/// @return either the definition of the class, or the class itself.
11920
11921/// If a class (or union) is a decl-only class, get its definition.
11922/// Otherwise, just return the initial class.
11923///
11924/// @param the_class the class (or union) to consider.
11925///
11926/// @return either the definition of the class, or the class itself.
11927class_or_union_sptr
11930
11931/// If a class (or union) is a decl-only class, get its definition.
11932/// Otherwise, just return the initial class.
11933///
11934/// @param klass the class (or union) to consider.
11935///
11936/// @return either the definition of the class, or the class itself.
11937class_or_union_sptr
11938look_through_decl_only_class(class_or_union_sptr klass)
11940
11941/// If an enum is a decl-only enum, get its definition.
11942/// Otherwise, just return the initial enum.
11943///
11944/// @param the_enum the enum to consider.
11945///
11946/// @return either the definition of the enum, or the enum itself.
11949{return is_enum_type(look_through_decl_only(the_enum));}
11950
11951/// If an enum is a decl-only enum, get its definition.
11952/// Otherwise, just return the initial enum.
11953///
11954/// @param enom the enum to consider.
11955///
11956/// @return either the definition of the enum, or the enum itself.
11959{return is_enum_type(look_through_decl_only(enom));}
11960
11961/// If a decl is decl-only get its definition. Otherwise, just return nil.
11962///
11963/// @param d the decl to consider.
11964///
11965/// @return either the definition of the decl, or nil.
11966decl_base_sptr
11968{
11969 decl_base_sptr decl;
11972
11973 if (!decl)
11974 return decl;
11975
11976 while (decl->get_is_declaration_only()
11977 && decl->get_definition_of_declaration())
11978 decl = decl->get_definition_of_declaration();
11979
11980 return decl;
11981}
11982
11983/// If a decl is decl-only enum, get its definition. Otherwise, just
11984/// return the initial decl.
11985///
11986/// @param d the decl to consider.
11987///
11988/// @return either the definition of the enum, or the decl itself.
11989decl_base*
11991{
11992 if (!d)
11993 return d;
11994
11995 decl_base* result = look_through_decl_only(*d).get();
11996 if (!result)
11997 result = d;
11998
11999 return result;
12000}
12001
12002/// If a decl is decl-only get its definition. Otherwise, just return nil.
12003///
12004/// @param d the decl to consider.
12005///
12006/// @return either the definition of the decl, or nil.
12007decl_base_sptr
12008look_through_decl_only(const decl_base_sptr& d)
12009{
12010 if (!d)
12011 return d;
12012
12013 decl_base_sptr result = look_through_decl_only(*d);
12014 if (!result)
12015 result = d;
12016
12017 return result;
12018}
12019
12020/// If a type is is decl-only, then get its definition. Otherwise,
12021/// just return the initial type.
12022///
12023/// @param d the decl to consider.
12024///
12025/// @return either the definition of the decl, or the initial type.
12026type_base*
12028{
12029 decl_base* d = is_decl(t);
12030 if (!d)
12031 return t;
12033 return is_type(d);
12034}
12035
12036/// If a type is is decl-only, then get its definition. Otherwise,
12037/// just return the initial type.
12038///
12039/// @param d the decl to consider.
12040///
12041/// @return either the definition of the decl, or the initial type.
12042type_base_sptr
12043look_through_decl_only_type(const type_base_sptr& t)
12044{
12045 decl_base_sptr d = is_decl(t);
12046 if (!d)
12047 return t;
12049 return is_type(d);
12050}
12051
12052/// Tests if a declaration is a variable declaration.
12053///
12054/// @param decl the decl to test.
12055///
12056/// @return the var_decl_sptr iff decl is a variable declaration; nil
12057/// otherwise.
12058var_decl*
12060{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
12061
12062/// Tests if a declaration is a variable declaration.
12063///
12064/// @param decl the decl to test.
12065///
12066/// @return the var_decl_sptr iff decl is a variable declaration; nil
12067/// otherwise.
12070{return dynamic_pointer_cast<var_decl>(decl);}
12071
12072/// Tests if a declaration is a namespace declaration.
12073///
12074/// @param d the decalration to consider.
12075///
12076/// @return the namespace declaration if @p d is a namespace.
12078is_namespace(const decl_base_sptr& d)
12079{return dynamic_pointer_cast<namespace_decl>(d);}
12080
12081/// Tests if a declaration is a namespace declaration.
12082///
12083/// @param d the decalration to consider.
12084///
12085/// @return the namespace declaration if @p d is a namespace.
12088{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
12089
12090/// Tests whether a decl is a template parameter composition type.
12091///
12092/// @param decl the declaration to consider.
12093///
12094/// @return true iff decl is a template parameter composition type.
12095bool
12096is_template_parm_composition_type(const shared_ptr<decl_base> decl)
12097{
12098 return (decl
12099 && is_at_template_scope(decl)
12100 && is_type(decl)
12101 && !is_template_parameter(decl));
12102}
12103
12104/// Test whether a decl is the pattern of a function template.
12105///
12106/// @param decl the decl to consider.
12107///
12108/// @return true iff decl is the pattern of a function template.
12109bool
12110is_function_template_pattern(const shared_ptr<decl_base> decl)
12111{
12112 return (decl
12113 && dynamic_pointer_cast<function_decl>(decl)
12114 && dynamic_cast<template_decl*>(decl->get_scope()));
12115}
12116
12117/// Test if a type is an array_type_def.
12118///
12119/// @param type the type to consider.
12120///
12121/// @return true iff @p type is an array_type_def.
12124 bool look_through_qualifiers)
12125{
12126 const type_base* t = is_type(type);
12127
12128 if (look_through_qualifiers)
12129 t = peel_qualified_type(t);
12130 return dynamic_cast<array_type_def*>(const_cast<type_base*>(t));
12131}
12132
12133/// Test if a type is an array_type_def.
12134///
12135/// @param type the type to consider.
12136///
12137/// @return true iff @p type is an array_type_def.
12140 bool look_through_qualifiers)
12141{
12142 type_base_sptr t = is_type(type);
12143
12144 if (look_through_qualifiers)
12145 t = peel_qualified_type(t);
12146 return dynamic_pointer_cast<array_type_def>(t);
12147}
12148
12149/// Tests if the element of a given array is a qualified type.
12150///
12151/// @param array the array type to consider.
12152///
12153/// @return the qualified element of the array iff it's a qualified
12154/// type. Otherwise, return a nil object.
12155qualified_type_def_sptr
12157{
12158 if (!array)
12159 return qualified_type_def_sptr();
12160
12161 return is_qualified_type(array->get_element_type());
12162}
12163
12164/// Test if an array type is an array to a qualified element type.
12165///
12166/// @param type the array type to consider.
12167///
12168/// @return true the array @p type iff it's an array to a qualified
12169/// element type.
12171is_array_of_qualified_element(const type_base_sptr& type)
12172{
12173 if (array_type_def_sptr array = is_array_type(type))
12175 return array;
12176
12177 return array_type_def_sptr();
12178}
12179
12180/// Test if a type is a typedef of an array.
12181///
12182/// Note that the function looks through qualified and typedefs types
12183/// of the underlying type of the current typedef. In other words, if
12184/// we are looking at a typedef of a CV-qualified array, or at a
12185/// typedef of a CV-qualified typedef of an array, this function will
12186/// still return TRUE.
12187///
12188/// @param t the type to consider.
12189///
12190/// @return true if t is a typedef which underlying type is an array.
12191/// That array might be either cv-qualified array or a typedef'ed
12192/// array, or a combination of both.
12194is_typedef_of_array(const type_base_sptr& t)
12195{
12196 array_type_def_sptr result;
12197
12198 if (typedef_decl_sptr typdef = is_typedef(t))
12199 {
12200 type_base_sptr u =
12201 peel_qualified_or_typedef_type(typdef->get_underlying_type());
12202 result = is_array_type(u);
12203 }
12204
12205 return result;
12206}
12207
12208/// Test if a type is an array_type_def::subrange_type.
12209///
12210/// @param type the type to consider.
12211///
12212/// @return the array_type_def::subrange_type which @p type is a type
12213/// of, or nil if it's not of that type.
12216{
12217 return dynamic_cast<array_type_def::subrange_type*>
12218 (const_cast<type_or_decl_base*>(type));
12219}
12220
12221/// Test if a type is an array_type_def::subrange_type.
12222///
12223/// @param type the type to consider.
12224///
12225/// @return the array_type_def::subrange_type which @p type is a type
12226/// of, or nil if it's not of that type.
12229{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
12230
12231/// Tests whether a decl is a template.
12232///
12233/// @param decl the decl to consider.
12234///
12235/// @return true iff decl is a function template, class template, or
12236/// template template parameter.
12237bool
12238is_template_decl(const decl_base_sptr& decl)
12239{return decl && dynamic_pointer_cast<template_decl>(decl);}
12240
12241/// This enum describe the kind of entity to lookup, while using the
12242/// lookup API.
12244{
12245 LOOKUP_ENTITY_TYPE,
12246 LOOKUP_ENTITY_VAR,
12247};
12248
12249/// Find the first relevant delimiter (the "::" string) in a fully
12250/// qualified C++ type name, starting from a given position. The
12251/// delimiter returned separates a type name from the name of its
12252/// context.
12253///
12254/// This is supposed to work correctly on names in cases like this:
12255///
12256/// foo<ns1::name1, ns2::name2>
12257///
12258/// In that case when called with with parameter @p begin set to 0, no
12259/// delimiter is returned, because the type name in this case is:
12260/// 'foo<ns1::name1, ns2::name2>'.
12261///
12262/// But in this case:
12263///
12264/// foo<p1, bar::name>::some_type
12265///
12266/// The "::" returned is the one right before 'some_type'.
12267///
12268/// @param fqn the fully qualified name of the type to consider.
12269///
12270/// @param begin the position from which to look for the delimiter.
12271///
12272/// @param delim_pos out parameter. Is set to the position of the
12273/// delimiter iff the function returned true.
12274///
12275/// @return true iff the function found and returned the delimiter.
12276static bool
12277find_next_delim_in_cplus_type(const string& fqn,
12278 size_t begin,
12279 size_t& delim_pos)
12280{
12281 int angle_count = 0;
12282 bool found = false;
12283 size_t i = begin;
12284 for (; i < fqn.size(); ++i)
12285 {
12286 if (fqn[i] == '<')
12287 ++angle_count;
12288 else if (fqn[i] == '>')
12289 --angle_count;
12290 else if (i + 1 < fqn.size()
12291 && !angle_count
12292 && fqn[i] == ':'
12293 && fqn[i+1] == ':')
12294 {
12295 delim_pos = i;
12296 found = true;
12297 break;
12298 }
12299 }
12300 return found;
12301}
12302
12303/// Decompose a fully qualified name into the list of its components.
12304///
12305/// @param fqn the fully qualified name to decompose.
12306///
12307/// @param comps the resulting list of component to fill.
12308void
12309fqn_to_components(const string& fqn,
12310 list<string>& comps)
12311{
12312 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
12313 do
12314 {
12315 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
12316 comp_end = fqn_size;
12317
12318 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
12319 comps.push_back(comp);
12320
12321 comp_begin = comp_end + 2;
12322 if (comp_begin >= fqn_size)
12323 break;
12324 } while (true);
12325}
12326
12327/// Turn a set of qualified name components (that name a type) into a
12328/// qualified name string.
12329///
12330/// @param comps the name components
12331///
12332/// @return the resulting string, which would be the qualified name of
12333/// a type.
12334string
12335components_to_type_name(const list<string>& comps)
12336{
12337 string result;
12338 for (list<string>::const_iterator c = comps.begin();
12339 c != comps.end();
12340 ++c)
12341 if (c == comps.begin())
12342 result = *c;
12343 else
12344 result += "::" + *c;
12345 return result;
12346}
12347
12348/// This predicate returns true if a given container iterator points
12349/// to the last element of the container, false otherwise.
12350///
12351/// @tparam T the type of the container of the iterator.
12352///
12353/// @param container the container the iterator points into.
12354///
12355/// @param i the iterator to consider.
12356///
12357/// @return true iff the iterator points to the last element of @p
12358/// container.
12359template<typename T>
12360static bool
12361iterator_is_last(T& container,
12362 typename T::const_iterator i)
12363{
12364 typename T::const_iterator next = i;
12365 ++next;
12366 return (next == container.end());
12367}
12368
12369//--------------------------------
12370// <type and decls lookup stuff>
12371// ------------------------------
12372
12373/// Lookup all the type*s* that have a given fully qualified name.
12374///
12375/// @param type_name the fully qualified name of the type to
12376/// lookup.
12377///
12378/// @param type_map the map to look into.
12379///
12380/// @return the vector containing the types named @p type_name. If
12381/// the lookup didn't yield any type, then this function returns nil.
12382static const type_base_wptrs_type*
12383lookup_types_in_map(const interned_string& type_name,
12384 const istring_type_base_wptrs_map_type& type_map)
12385{
12386 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12387 if (i != type_map.end())
12388 return &i->second;
12389 return 0;
12390}
12391
12392/// Lookup a type (with a given name) in a map that associates a type
12393/// name to a type. If there are several types with a given name,
12394/// then try to return the first one that is not decl-only.
12395/// Otherwise, return the last of such types, that is, the last one
12396/// that got registered.
12397///
12398/// @tparam TypeKind the type of the type this function is supposed to
12399/// return.
12400///
12401/// @param type_name the name of the type to lookup.
12402///
12403/// @param type_map the map in which to look.
12404///
12405/// @return a shared_ptr to the type found. If no type was found or
12406/// if the type found was not of type @p TypeKind then the function
12407/// returns nil.
12408template <class TypeKind>
12409static shared_ptr<TypeKind>
12410lookup_type_in_map(const interned_string& type_name,
12411 const istring_type_base_wptrs_map_type& type_map)
12412{
12413 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12414 if (i != type_map.end())
12415 {
12416 // Walk the types that have the name "type_name" and return the
12417 // first one that is not declaration-only ...
12418 for (auto j : i->second)
12419 {
12420 type_base_sptr t(j);
12421 decl_base_sptr d = is_decl(t);
12422 if (d && !d->get_is_declaration_only())
12423 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
12424 }
12425 // ... or return the last type with the name "type_name" that
12426 // was recorded. It's likely to be declaration-only if we
12427 // reached this point.
12428 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
12429 }
12430 return shared_ptr<TypeKind>();
12431}
12432
12433/// Lookup a basic type from a translation unit.
12434///
12435/// This is done by looking the type up in the type map that is
12436/// maintained in the translation unit. So this is as fast as
12437/// possible.
12438///
12439/// @param type_name the name of the basic type to look for.
12440///
12441/// @param tu the translation unit to look into.
12442///
12443/// @return the basic type found or nil if no basic type was found.
12446{
12447 return lookup_type_in_map<type_decl>(type_name,
12448 tu.get_types().basic_types());
12449}
12450
12451/// Lookup a basic type from a translation unit.
12452///
12453/// This is done by looking the type up in the type map that is
12454/// maintained in the translation unit. So this is as fast as
12455/// possible.
12456///
12457/// @param type_name the name of the basic type to look for.
12458///
12459/// @param tu the translation unit to look into.
12460///
12461/// @return the basic type found or nil if no basic type was found.
12463lookup_basic_type(const string& type_name, const translation_unit& tu)
12464{
12465 const environment& env = tu.get_environment();
12466
12467 interned_string s = env.intern(type_name);
12468 return lookup_basic_type(s, tu);
12469}
12470
12471/// Lookup a class type from a translation unit.
12472///
12473/// This is done by looking the type up in the type map that is
12474/// maintained in the translation unit. So this is as fast as
12475/// possible.
12476///
12477/// @param fqn the fully qualified name of the class type node to look
12478/// up.
12479///
12480/// @param tu the translation unit to perform lookup from.
12481///
12482/// @return the declaration of the class type IR node found, NULL
12483/// otherwise.
12485lookup_class_type(const string& fqn, const translation_unit& tu)
12486{
12487 const environment& env = tu.get_environment();
12488 interned_string s = env.intern(fqn);
12489 return lookup_class_type(s, tu);
12490}
12491
12492/// Lookup a class type from a translation unit.
12493///
12494/// This is done by looking the type up in the type map that is
12495/// maintained in the translation unit. So this is as fast as
12496/// possible.
12497///
12498/// @param type_name the name of the class type to look for.
12499///
12500/// @param tu the translation unit to look into.
12501///
12502/// @return the class type found or nil if no class type was found.
12505{
12506 return lookup_type_in_map<class_decl>(type_name,
12507 tu.get_types().class_types());
12508}
12509
12510/// Lookup a union type from a translation unit.
12511///
12512/// This is done by looking the type up in the type map that is
12513/// maintained in the translation unit. So this is as fast as
12514/// possible.
12515///
12516/// @param type_name the name of the union type to look for.
12517///
12518/// @param tu the translation unit to look into.
12519///
12520/// @return the union type found or nil if no union type was found.
12521union_decl_sptr
12523{
12524 return lookup_type_in_map<union_decl>(type_name,
12525 tu.get_types().union_types());
12526}
12527
12528/// Lookup a union type from a translation unit.
12529///
12530/// This is done by looking the type up in the type map that is
12531/// maintained in the translation unit. So this is as fast as
12532/// possible.
12533///
12534/// @param fqn the fully qualified name of the type to lookup.
12535///
12536/// @param tu the translation unit to look into.
12537///
12538/// @return the union type found or nil if no union type was found.
12539union_decl_sptr
12540lookup_union_type(const string& fqn, const translation_unit& tu)
12541{
12542 const environment& env = tu.get_environment();
12543 interned_string s = env.intern(fqn);
12544 return lookup_union_type(s, tu);
12545}
12546
12547/// Lookup a union type in a given corpus, from its location.
12548///
12549/// @param loc the location of the union type to look for.
12550///
12551/// @param corp the corpus to look it from.
12552///
12553/// @return the resulting union_decl.
12554union_decl_sptr
12556{
12559 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
12560
12561 return result;
12562}
12563
12564/// Lookup a union type in a given corpus, from its location.
12565///
12566/// @param loc the location of the union type to look for.
12567///
12568/// @param corp the corpus to look it from.
12569///
12570/// @return the resulting union_decl.
12571union_decl_sptr
12572lookup_union_type_per_location(const string& loc, const corpus& corp)
12573{
12574 const environment& env = corp.get_environment();
12575 return lookup_union_type_per_location(env.intern(loc), corp);
12576}
12577
12578/// Lookup an enum type from a translation unit.
12579///
12580/// This is done by looking the type up in the type map that is
12581/// maintained in the translation unit. So this is as fast as
12582/// possible.
12583///
12584/// @param type_name the name of the enum type to look for.
12585///
12586/// @param tu the translation unit to look into.
12587///
12588/// @return the enum type found or nil if no enum type was found.
12591{
12592 return lookup_type_in_map<enum_type_decl>(type_name,
12593 tu.get_types().enum_types());
12594}
12595
12596/// Lookup an enum type from a translation unit.
12597///
12598/// This is done by looking the type up in the type map that is
12599/// maintained in the translation unit. So this is as fast as
12600/// possible.
12601///
12602/// @param type_name the name of the enum type to look for.
12603///
12604/// @param tu the translation unit to look into.
12605///
12606/// @return the enum type found or nil if no enum type was found.
12608lookup_enum_type(const string& type_name, const translation_unit& tu)
12609{
12610 const environment& env = tu.get_environment();
12611 interned_string s = env.intern(type_name);
12612 return lookup_enum_type(s, tu);
12613}
12614
12615/// Lookup a typedef type from a translation unit.
12616///
12617/// This is done by looking the type up in the type map that is
12618/// maintained in the translation unit. So this is as fast as
12619/// possible.
12620///
12621/// @param type_name the name of the typedef type to look for.
12622///
12623/// @param tu the translation unit to look into.
12624///
12625/// @return the typedef type found or nil if no typedef type was
12626/// found.
12629 const translation_unit& tu)
12630{
12631 return lookup_type_in_map<typedef_decl>(type_name,
12632 tu.get_types().typedef_types());
12633}
12634
12635/// Lookup a typedef type from a translation unit.
12636///
12637/// This is done by looking the type up in the type map that is
12638/// maintained in the translation unit. So this is as fast as
12639/// possible.
12640///
12641/// @param type_name the name of the typedef type to look for.
12642///
12643/// @param tu the translation unit to look into.
12644///
12645/// @return the typedef type found or nil if no typedef type was
12646/// found.
12648lookup_typedef_type(const string& type_name, const translation_unit& tu)
12649{
12650 const environment& env = tu.get_environment();
12651 interned_string s = env.intern(type_name);
12652 return lookup_typedef_type(s, tu);
12653}
12654
12655/// Lookup a qualified type from a translation unit.
12656///
12657/// This is done by looking the type up in the type map that is
12658/// maintained in the translation unit. So this is as fast as
12659/// possible.
12660///
12661/// @param type_name the name of the qualified type to look for.
12662///
12663/// @param tu the translation unit to look into.
12664///
12665/// @return the qualified type found or nil if no qualified type was
12666/// found.
12667qualified_type_def_sptr
12669 const translation_unit& tu)
12670{
12671 const type_maps& m = tu.get_types();
12672 return lookup_type_in_map<qualified_type_def>(type_name,
12673 m.qualified_types());
12674}
12675
12676/// Lookup a qualified type from a translation unit.
12677///
12678/// This is done by looking the type up in the type map that is
12679/// maintained in the translation unit. So this is as fast as
12680/// possible.
12681///
12682/// @param underlying_type the underying type of the qualified type to
12683/// look up.
12684///
12685/// @param quals the CV-qualifiers of the qualified type to look for.
12686///
12687/// @param tu the translation unit to look into.
12688///
12689/// @return the qualified type found or nil if no qualified type was
12690/// found.
12691qualified_type_def_sptr
12692lookup_qualified_type(const type_base_sptr& underlying_type,
12694 const translation_unit& tu)
12695{
12696 interned_string type_name = get_name_of_qualified_type(underlying_type,
12697 quals);
12698 return lookup_qualified_type(type_name, tu);
12699}
12700
12701/// Lookup a pointer type from a translation unit.
12702///
12703/// This is done by looking the type up in the type map that is
12704/// maintained in the translation unit. So this is as fast as
12705/// possible.
12706///
12707/// @param type_name the name of the pointer type to look for.
12708///
12709/// @param tu the translation unit to look into.
12710///
12711/// @return the pointer type found or nil if no pointer type was
12712/// found.
12715 const translation_unit& tu)
12716{
12717 const type_maps& m = tu.get_types();
12718 return lookup_type_in_map<pointer_type_def>(type_name,
12719 m.pointer_types());
12720}
12721
12722/// Lookup a pointer type from a translation unit.
12723///
12724/// This is done by looking the type up in the type map that is
12725/// maintained in the translation unit. So this is as fast as
12726/// possible.
12727///
12728/// @param type_name the name of the pointer type to look for.
12729///
12730/// @param tu the translation unit to look into.
12731///
12732/// @return the pointer type found or nil if no pointer type was
12733/// found.
12735lookup_pointer_type(const string& type_name, const translation_unit& tu)
12736{
12737 const environment& env = tu.get_environment();
12738 interned_string s = env.intern(type_name);
12739 return lookup_pointer_type(s, tu);
12740}
12741
12742/// Lookup a pointer type from a translation unit.
12743///
12744/// This is done by looking the type up in the type map that is
12745/// maintained in the translation unit. So this is as fast as
12746/// possible.
12747///
12748/// @param pointed_to_type the pointed-to-type of the pointer to look for.
12749///
12750/// @param tu the translation unit to look into.
12751///
12752/// @return the pointer type found or nil if no pointer type was
12753/// found.
12755lookup_pointer_type(const type_base_sptr& pointed_to_type,
12756 const translation_unit& tu)
12757{
12758 type_base_sptr t = look_through_decl_only_type(pointed_to_type);
12760 return lookup_pointer_type(type_name, tu);
12761}
12762
12763/// Lookup a reference type from a translation unit.
12764///
12765/// This is done by looking the type up in the type map that is
12766/// maintained in the translation unit. So this is as fast as
12767/// possible.
12768///
12769/// @param type_name the name of the reference type to look for.
12770///
12771/// @param tu the translation unit to look into.
12772///
12773/// @return the reference type found or nil if no reference type was
12774/// found.
12777 const translation_unit& tu)
12778{
12779 const type_maps& m = tu.get_types();
12780 return lookup_type_in_map<reference_type_def>(type_name,
12781 m.reference_types());
12782}
12783
12784/// Lookup a reference type from a translation unit.
12785///
12786/// This is done by looking the type up in the type map that is
12787/// maintained in the translation unit. So this is as fast as
12788/// possible.
12789///
12790/// @param pointed_to_type the pointed-to-type of the reference to
12791/// look up.
12792///
12793/// @param tu the translation unit to look into.
12794///
12795/// @return the reference type found or nil if no reference type was
12796/// found.
12798lookup_reference_type(const type_base_sptr& pointed_to_type,
12799 bool lvalue_reference,
12800 const translation_unit& tu)
12801{
12802 interned_string type_name =
12804 lvalue_reference);
12805 return lookup_reference_type(type_name, tu);
12806}
12807
12808/// Lookup an array type from a translation unit.
12809///
12810/// This is done by looking the type up in the type map that is
12811/// maintained in the translation unit. So this is as fast as
12812/// possible.
12813///
12814/// @param type_name the name of the array type to look for.
12815///
12816/// @param tu the translation unit to look into.
12817///
12818/// @return the array type found or nil if no array type was found.
12821 const translation_unit& tu)
12822{
12823 const type_maps& m = tu.get_types();
12824 return lookup_type_in_map<array_type_def>(type_name,
12825 m.array_types());
12826}
12827
12828/// Lookup a function type from a translation unit.
12829///
12830/// This is done by looking the type up in the type map that is
12831/// maintained in the translation unit. So this is as fast as
12832/// possible.
12833///
12834/// @param type_name the name of the type to lookup.
12835///
12836/// @param tu the translation unit to look into.
12837///
12838/// @return the function type found, or NULL of none was found.
12841 const translation_unit& tu)
12842{
12843 const type_maps& m = tu.get_types();
12844 return lookup_type_in_map<function_type>(type_name,
12845 m.function_types());
12846}
12847
12848/// Lookup a function type from a translation unit.
12849///
12850/// This walks all the function types held by the translation unit and
12851/// compare their sub-type *names*. If the names match then return
12852/// the function type found in the translation unit.
12853///
12854/// @param t the function type to look for.
12855///
12856/// @param tu the translation unit to look into.
12857///
12858/// @return the function type found, or NULL of none was found.
12861 const translation_unit& tu)
12862{
12863 interned_string type_name = get_type_name(t);
12864 return lookup_function_type(type_name, tu);
12865}
12866
12867/// Lookup a function type from a translation unit.
12868///
12869/// This is done by looking the type up in the type map that is
12870/// maintained in the translation unit. So this is as fast as
12871/// possible.
12872///
12873/// @param t the function type to look for.
12874///
12875/// @param tu the translation unit to look into.
12876///
12877/// @return the function type found, or NULL of none was found.
12880 const translation_unit& tu)
12881{return lookup_function_type(*t, tu);}
12882
12883/// Lookup a type in a translation unit.
12884///
12885/// @param fqn the fully qualified name of the type to lookup.
12886///
12887/// @param tu the translation unit to consider.
12888///
12889/// @return the declaration of the type if found, NULL otherwise.
12890const type_base_sptr
12892 const translation_unit& tu)
12893{
12894 type_base_sptr result;
12895 ((result = lookup_typedef_type(fqn, tu))
12896 || (result = lookup_class_type(fqn, tu))
12897 || (result = lookup_union_type(fqn, tu))
12898 || (result = lookup_enum_type(fqn, tu))
12899 || (result = lookup_qualified_type(fqn, tu))
12900 || (result = lookup_pointer_type(fqn, tu))
12901 || (result = lookup_reference_type(fqn, tu))
12902 || (result = lookup_array_type(fqn, tu))
12903 || (result = lookup_function_type(fqn, tu))
12904 || (result = lookup_basic_type(fqn, tu)));
12905
12906 return result;
12907}
12908
12909/// Lookup a type in a translation unit, starting from the global
12910/// namespace.
12911///
12912/// @param fqn the fully qualified name of the type to lookup.
12913///
12914/// @param tu the translation unit to consider.
12915///
12916/// @return the declaration of the type if found, NULL otherwise.
12917type_base_sptr
12918lookup_type(const string& fqn, const translation_unit& tu)
12919{
12920 const environment&env = tu.get_environment();
12921 interned_string ifqn = env.intern(fqn);
12922 return lookup_type(ifqn, tu);
12923}
12924
12925/// Lookup a type from a translation unit.
12926///
12927/// @param fqn the components of the fully qualified name of the node
12928/// to look up.
12929///
12930/// @param tu the translation unit to perform lookup from.
12931///
12932/// @return the declaration of the IR node found, NULL otherwise.
12933const type_base_sptr
12934lookup_type(const type_base_sptr type,
12935 const translation_unit& tu)
12936{
12937 interned_string type_name = get_type_name(type);
12938 return lookup_type(type_name, tu);
12939}
12940
12941/// Lookup a type in a scope.
12942///
12943/// This is really slow as it walks the member types of the scope in
12944/// sequence to find the type with a given name.
12945///
12946/// If possible, users should prefer looking up types from the
12947/// enclosing translation unit or even ABI corpus because both the
12948/// translation unit and the corpus have a map of type, indexed by
12949/// their name. Looking up a type from those maps is thus much
12950/// faster.
12951///
12952/// @param fqn the fully qualified name of the type to lookup.
12953///
12954/// @param skope the scope to look into.
12955///
12956/// @return the declaration of the type if found, NULL otherwise.
12957const type_base_sptr
12958lookup_type_in_scope(const string& fqn,
12959 const scope_decl_sptr& skope)
12960{
12961 list<string> comps;
12962 fqn_to_components(fqn, comps);
12963 return lookup_type_in_scope(comps, skope);
12964}
12965
12966/// Lookup a @ref var_decl in a scope.
12967///
12968/// @param fqn the fuly qualified name of the @var_decl to lookup.
12969///
12970/// @param skope the scope to look into.
12971///
12972/// @return the declaration of the @ref var_decl if found, NULL
12973/// otherwise.
12974const decl_base_sptr
12976 const scope_decl_sptr& skope)
12977{
12978 list<string> comps;
12979 fqn_to_components(fqn, comps);
12980 return lookup_var_decl_in_scope(comps, skope);
12981}
12982
12983/// A generic function (template) to get the name of a node, whatever
12984/// node it is. This has to be specialized for the kind of node we
12985/// want.
12986///
12987/// Note that a node is a member of a scope.
12988///
12989/// @tparam NodeKind the kind of node to consider.
12990///
12991/// @param node the node to get the name from.
12992///
12993/// @return the name of the node.
12994template<typename NodeKind>
12995static const interned_string&
12996get_node_name(shared_ptr<NodeKind> node);
12997
12998/// Gets the name of a class_decl node.
12999///
13000/// @param node the decl_base node to get the name from.
13001///
13002/// @return the name of the node.
13003template<>
13004const interned_string&
13006{return node->get_name();}
13007
13008/// Gets the name of a type_base node.
13009///
13010/// @param node the type_base node to get the name from.
13011///
13012/// @return the name of the node.
13013template<>
13014const interned_string&
13015get_node_name(type_base_sptr node)
13016{return get_type_declaration(node)->get_name();}
13017
13018/// Gets the name of a var_decl node.
13019///
13020/// @param node the var_decl node to get the name from.
13021///
13022/// @return the name of the node.
13023template<>
13024const interned_string&
13026{return node->get_name();}
13027
13028/// Generic function to get the declaration of a given node, whatever
13029/// it is. There has to be specializations for the kind of the nodes
13030/// we want to support.
13031///
13032/// @tparam NodeKind the type of the node we are looking at.
13033///
13034/// @return the declaration.
13035template<typename NodeKind>
13036static decl_base_sptr
13037convert_node_to_decl(shared_ptr<NodeKind> node);
13038
13039/// Lookup a node in a given scope.
13040///
13041/// @tparam the type of the node to lookup.
13042///
13043/// @param fqn the components of the fully qualified name of the node
13044/// to lookup.
13045///
13046/// @param skope the scope to look into.
13047///
13048/// @return the declaration of the looked up node, or NULL if it
13049/// wasn't found.
13050template<typename NodeKind>
13051static const type_or_decl_base_sptr
13052lookup_node_in_scope(const list<string>& fqn,
13053 const scope_decl_sptr& skope)
13054{
13055 type_or_decl_base_sptr resulting_decl;
13056 shared_ptr<NodeKind> node;
13057 bool it_is_last = false;
13058 scope_decl_sptr cur_scope = skope, new_scope, scope;
13059
13060 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
13061 {
13062 new_scope.reset();
13063 it_is_last = iterator_is_last(fqn, c);
13064 for (scope_decl::declarations::const_iterator m =
13065 cur_scope->get_member_decls().begin();
13066 m != cur_scope->get_member_decls().end();
13067 ++m)
13068 {
13069 if (!it_is_last)
13070 {
13071 // looking for a scope
13072 scope = dynamic_pointer_cast<scope_decl>(*m);
13073 if (scope && scope->get_name() == *c)
13074 {
13075 new_scope = scope;
13076 break;
13077 }
13078 }
13079 else
13080 {
13081 //looking for a final type.
13082 node = dynamic_pointer_cast<NodeKind>(*m);
13083 if (node && get_node_name(node) == *c)
13084 {
13085 if (class_decl_sptr cl =
13086 dynamic_pointer_cast<class_decl>(node))
13087 if (cl->get_is_declaration_only()
13088 && !cl->get_definition_of_declaration())
13089 continue;
13090 resulting_decl = node;
13091 break;
13092 }
13093 }
13094 }
13095 if (!new_scope && !resulting_decl)
13096 return decl_base_sptr();
13097 cur_scope = new_scope;
13098 }
13099 ABG_ASSERT(resulting_decl);
13100 return resulting_decl;
13101}
13102
13103/// lookup a type in a scope.
13104///
13105///
13106/// This is really slow as it walks the member types of the scope in
13107/// sequence to find the type with a given name.
13108///
13109/// If possible, users should prefer looking up types from the
13110/// enclosing translation unit or even ABI corpus because both the
13111/// translation unit and the corpus have a map of type, indexed by
13112/// their name. Looking up a type from those maps is thus much
13113/// faster.
13114///
13115/// @param comps the components of the fully qualified name of the
13116/// type to lookup.
13117///
13118/// @param skope the scope to look into.
13119///
13120/// @return the declaration of the type found.
13121const type_base_sptr
13122lookup_type_in_scope(const list<string>& comps,
13123 const scope_decl_sptr& scope)
13124{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
13125
13126/// lookup a type in a scope.
13127///
13128/// This is really slow as it walks the member types of the scope in
13129/// sequence to find the type with a given name.
13130///
13131/// If possible, users should prefer looking up types from the
13132/// enclosing translation unit or even ABI corpus because both the
13133/// translation unit and the corpus have a map of type, indexed by
13134/// their name. Looking up a type from those maps is thus much
13135/// faster.
13136///
13137/// @param type the type to look for.
13138///
13139/// @param access_path a vector of scopes the path of scopes to follow
13140/// before reaching the scope into which to look for @p type. Note
13141/// that the deepest scope (the one immediately containing @p type) is
13142/// at index 0 of this vector, and the top-most scope is the last
13143/// element of the vector.
13144///
13145/// @param scope the top-most scope into which to look for @p type.
13146///
13147/// @return the scope found in @p scope, or NULL if it wasn't found.
13148static const type_base_sptr
13150 const vector<scope_decl*>& access_path,
13151 const scope_decl* scope)
13152{
13153 vector<scope_decl*> a = access_path;
13154 type_base_sptr result;
13155
13156 scope_decl* first_scope = 0;
13157 if (!a.empty())
13158 {
13159 first_scope = a.back();
13160 ABG_ASSERT(first_scope->get_name() == scope->get_name());
13161 a.pop_back();
13162 }
13163
13164 if (a.empty())
13165 {
13166 interned_string n = get_type_name(type, false);
13167 for (scope_decl::declarations::const_iterator i =
13168 scope->get_member_decls().begin();
13169 i != scope->get_member_decls().end();
13170 ++i)
13171 if (is_type(*i) && (*i)->get_name() == n)
13172 {
13173 result = is_type(*i);
13174 break;
13175 }
13176 }
13177 else
13178 {
13179 first_scope = a.back();
13180 interned_string scope_name, cur_scope_name = first_scope->get_name();
13181 for (scope_decl::scopes::const_iterator i =
13182 scope->get_member_scopes().begin();
13183 i != scope->get_member_scopes().end();
13184 ++i)
13185 {
13186 scope_name = (*i)->get_name();
13187 if (scope_name == cur_scope_name)
13188 {
13189 result = lookup_type_in_scope(type, a, (*i).get());
13190 break;
13191 }
13192 }
13193 }
13194 return result;
13195}
13196
13197/// lookup a type in a scope.
13198///
13199/// This is really slow as it walks the member types of the scope in
13200/// sequence to find the type with a given name.
13201///
13202/// If possible, users should prefer looking up types from the
13203/// enclosing translation unit or even ABI corpus because both the
13204/// translation unit and the corpus have a map of type, indexed by
13205/// their name. Looking up a type from those maps is thus much
13206/// faster.
13207///
13208/// @param type the type to look for.
13209///
13210/// @param scope the top-most scope into which to look for @p type.
13211///
13212/// @return the scope found in @p scope, or NULL if it wasn't found.
13213static const type_base_sptr
13214lookup_type_in_scope(const type_base_sptr type,
13215 const scope_decl* scope)
13216{
13217 if (!type || is_function_type(type))
13218 return type_base_sptr();
13219
13220 decl_base_sptr type_decl = get_type_declaration(type);
13221 ABG_ASSERT(type_decl);
13222 vector<scope_decl*> access_path;
13223 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
13224 {
13225 access_path.push_back(s);
13226 if (is_global_scope(s))
13227 break;
13228 }
13229 return lookup_type_in_scope(*type, access_path, scope);
13230}
13231
13232/// Lookup a type from a translation unit by walking the scopes of the
13233/// translation unit in sequence and looking into them.
13234///
13235/// This is really slow as it walks the member types of the scopes in
13236/// sequence to find the type with a given name.
13237///
13238/// If possible, users should prefer looking up types from the
13239/// translation unit or even ABI corpus in a more direct way, by using
13240/// the lookup_type() functins.
13241///
13242///
13243/// This is because both the translation unit and the corpus have a
13244/// map of types, indexed by their name. Looking up a type from those
13245/// maps is thus much faster. @param fqn the components of the fully
13246/// qualified name of the node to look up.
13247///
13248/// @param tu the translation unit to perform lookup from.
13249///
13250/// @return the declaration of the IR node found, NULL otherwise.
13251const type_base_sptr
13252lookup_type_through_scopes(const type_base_sptr type,
13253 const translation_unit& tu)
13254{
13255 if (function_type_sptr fn_type = is_function_type(type))
13256 return lookup_function_type(fn_type, tu);
13257 return lookup_type_in_scope(type, tu.get_global_scope().get());
13258}
13259
13260/// lookup a var_decl in a scope.
13261///
13262/// @param comps the components of the fully qualified name of the
13263/// var_decl to lookup.
13264///
13265/// @param skope the scope to look into.
13266const decl_base_sptr
13267lookup_var_decl_in_scope(const std::list<string>& comps,
13268 const scope_decl_sptr& skope)
13269{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
13270
13271/// Lookup an IR node from a translation unit.
13272///
13273/// @tparam NodeKind the type of the IR node to lookup from the
13274/// translation unit.
13275///
13276/// @param fqn the components of the fully qualified name of the node
13277/// to look up.
13278///
13279/// @param tu the translation unit to perform lookup from.
13280///
13281/// @return the declaration of the IR node found, NULL otherwise.
13282template<typename NodeKind>
13283static const type_or_decl_base_sptr
13284lookup_node_in_translation_unit(const list<string>& fqn,
13285 const translation_unit& tu)
13286{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
13287
13288/// Lookup a type from a translation unit by walking its scopes in
13289/// sequence and by looking into them.
13290///
13291/// This is much slower than using the lookup_type() function.
13292///
13293/// @param fqn the components of the fully qualified name of the node
13294/// to look up.
13295///
13296/// @param tu the translation unit to perform lookup from.
13297///
13298/// @return the declaration of the IR node found, NULL otherwise.
13299type_base_sptr
13300lookup_type_through_scopes(const list<string>& fqn,
13301 const translation_unit& tu)
13302{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
13303
13304
13305/// Lookup a class type from a translation unit by walking its scopes
13306/// in sequence and by looking into them.
13307///
13308/// This is much slower than using the lookup_class_type() function
13309/// because it walks all the scopes of the translation unit in
13310/// sequence and lookup the types to find one that has a given name.
13311///
13312/// @param fqn the components of the fully qualified name of the class
13313/// type node to look up.
13314///
13315/// @param tu the translation unit to perform lookup from.
13316///
13317/// @return the declaration of the class type IR node found, NULL
13318/// otherwise.
13320lookup_class_type_through_scopes(const list<string>& fqn,
13321 const translation_unit& tu)
13322{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
13323
13324/// Lookup a basic type from all the translation units of a given
13325/// corpus.
13326///
13327/// @param fqn the components of the fully qualified name of the basic
13328/// type node to look up.
13329///
13330/// @param tu the translation unit to perform lookup from.
13331///
13332/// @return the declaration of the basic type IR node found, NULL
13333/// otherwise.
13334static type_decl_sptr
13335lookup_basic_type_through_translation_units(const interned_string& type_name,
13336 const corpus& abi_corpus)
13337{
13338 type_decl_sptr result;
13339
13340 for (translation_units::const_iterator tu =
13341 abi_corpus.get_translation_units().begin();
13342 tu != abi_corpus.get_translation_units().end();
13343 ++tu)
13344 if ((result = lookup_basic_type(type_name, **tu)))
13345 break;
13346
13347 return result;
13348}
13349
13350/// Lookup a union type from all the translation units of a given
13351/// corpus.
13352///
13353/// @param fqn the components of the fully qualified name of the union
13354/// type node to look up.
13355///
13356/// @param tu the translation unit to perform lookup from.
13357///
13358/// @return the declaration of the union type IR node found, NULL
13359/// otherwise.
13360static union_decl_sptr
13361lookup_union_type_through_translation_units(const interned_string& type_name,
13362 const corpus & abi_corpus)
13363{
13364 union_decl_sptr result;
13365
13366 for (translation_units::const_iterator tu =
13367 abi_corpus.get_translation_units().begin();
13368 tu != abi_corpus.get_translation_units().end();
13369 ++tu)
13370 if ((result = lookup_union_type(type_name, **tu)))
13371 break;
13372
13373 return result;
13374}
13375
13376/// Lookup an enum type from all the translation units of a given
13377/// corpus.
13378///
13379/// @param fqn the components of the fully qualified name of the enum
13380/// type node to look up.
13381///
13382/// @param tu the translation unit to perform lookup from.
13383///
13384/// @return the declaration of the enum type IR node found, NULL
13385/// otherwise.
13387lookup_enum_type_through_translation_units(const interned_string& type_name,
13388 const corpus & abi_corpus)
13389{
13390 enum_type_decl_sptr result;
13391
13392 for (translation_units::const_iterator tu =
13393 abi_corpus.get_translation_units().begin();
13394 tu != abi_corpus.get_translation_units().end();
13395 ++tu)
13396 if ((result = lookup_enum_type(type_name, **tu)))
13397 break;
13398
13399 return result;
13400}
13401
13402/// Lookup a typedef type definition in all the translation units of a
13403/// given ABI corpus.
13404///
13405/// @param @param qn the fully qualified name of the typedef type to lookup.
13406///
13407/// @param abi_corpus the ABI corpus which to look the type up in.
13408///
13409/// @return the type definition if any was found, or a NULL pointer.
13410static typedef_decl_sptr
13411lookup_typedef_type_through_translation_units(const interned_string& type_name,
13412 const corpus & abi_corpus)
13413{
13414 typedef_decl_sptr result;
13415
13416 for (translation_units::const_iterator tu =
13417 abi_corpus.get_translation_units().begin();
13418 tu != abi_corpus.get_translation_units().end();
13419 ++tu)
13420 if ((result = lookup_typedef_type(type_name, **tu)))
13421 break;
13422
13423 return result;
13424}
13425
13426/// Lookup a qualified type definition in all the translation units of a
13427/// given ABI corpus.
13428///
13429/// @param @param qn the fully qualified name of the qualified type to
13430/// lookup.
13431///
13432/// @param abi_corpus the ABI corpus which to look the type up in.
13433///
13434/// @return the type definition if any was found, or a NULL pointer.
13435static qualified_type_def_sptr
13436lookup_qualified_type_through_translation_units(const interned_string& t_name,
13437 const corpus & abi_corpus)
13438{
13439 qualified_type_def_sptr result;
13440
13441 for (translation_units::const_iterator tu =
13442 abi_corpus.get_translation_units().begin();
13443 tu != abi_corpus.get_translation_units().end();
13444 ++tu)
13445 if ((result = lookup_qualified_type(t_name, **tu)))
13446 break;
13447
13448 return result;
13449}
13450
13451/// Lookup a pointer type definition in all the translation units of a
13452/// given ABI corpus.
13453///
13454/// @param @param qn the fully qualified name of the pointer type to
13455/// lookup.
13456///
13457/// @param abi_corpus the ABI corpus which to look the type up in.
13458///
13459/// @return the type definition if any was found, or a NULL pointer.
13461lookup_pointer_type_through_translation_units(const interned_string& type_name,
13462 const corpus & abi_corpus)
13463{
13464 pointer_type_def_sptr result;
13465
13466 for (translation_units::const_iterator tu =
13467 abi_corpus.get_translation_units().begin();
13468 tu != abi_corpus.get_translation_units().end();
13469 ++tu)
13470 if ((result = lookup_pointer_type(type_name, **tu)))
13471 break;
13472
13473 return result;
13474}
13475
13476/// Lookup a reference type definition in all the translation units of a
13477/// given ABI corpus.
13478///
13479/// @param @param qn the fully qualified name of the reference type to
13480/// lookup.
13481///
13482/// @param abi_corpus the ABI corpus which to look the type up in.
13483///
13484/// @return the type definition if any was found, or a NULL pointer.
13486lookup_reference_type_through_translation_units(const interned_string& t_name,
13487 const corpus & abi_corpus)
13488{
13490
13491 for (translation_units::const_iterator tu =
13492 abi_corpus.get_translation_units().begin();
13493 tu != abi_corpus.get_translation_units().end();
13494 ++tu)
13495 if ((result = lookup_reference_type(t_name, **tu)))
13496 break;
13497
13498 return result;
13499}
13500
13501/// Lookup a array type definition in all the translation units of a
13502/// given ABI corpus.
13503///
13504/// @param @param qn the fully qualified name of the array type to
13505/// lookup.
13506///
13507/// @param abi_corpus the ABI corpus which to look the type up in.
13508///
13509/// @return the type definition if any was found, or a NULL pointer.
13511lookup_array_type_through_translation_units(const interned_string& type_name,
13512 const corpus & abi_corpus)
13513{
13514 array_type_def_sptr result;
13515
13516 for (translation_units::const_iterator tu =
13517 abi_corpus.get_translation_units().begin();
13518 tu != abi_corpus.get_translation_units().end();
13519 ++tu)
13520 if ((result = lookup_array_type(type_name, **tu)))
13521 break;
13522
13523 return result;
13524}
13525
13526/// Lookup a function type definition in all the translation units of
13527/// a given ABI corpus.
13528///
13529/// @param @param qn the fully qualified name of the function type to
13530/// lookup.
13531///
13532/// @param abi_corpus the ABI corpus which to look the type up in.
13533///
13534/// @return the type definition if any was found, or a NULL pointer.
13535static function_type_sptr
13536lookup_function_type_through_translation_units(const interned_string& type_name,
13537 const corpus & abi_corpus)
13538{
13539 function_type_sptr result;
13540
13541 for (translation_units::const_iterator tu =
13542 abi_corpus.get_translation_units().begin();
13543 tu != abi_corpus.get_translation_units().end();
13544 ++tu)
13545 if ((result = lookup_function_type(type_name, **tu)))
13546 break;
13547
13548 return result;
13549}
13550
13551/// Lookup a type definition in all the translation units of a given
13552/// ABI corpus.
13553///
13554/// @param @param qn the fully qualified name of the type to lookup.
13555///
13556/// @param abi_corpus the ABI corpus which to look the type up in.
13557///
13558/// @return the type definition if any was found, or a NULL pointer.
13559type_base_sptr
13561 const corpus& abi_corpus)
13562{
13563 type_base_sptr result;
13564
13565 for (translation_units::const_iterator tu =
13566 abi_corpus.get_translation_units().begin();
13567 tu != abi_corpus.get_translation_units().end();
13568 ++tu)
13569 if ((result = lookup_type(qn, **tu)))
13570 break;
13571
13572 return result;
13573}
13574
13575/// Lookup a type from a given translation unit present in a give corpus.
13576///
13577/// @param type_name the name of the type to look for.
13578///
13579/// @parm tu_path the path of the translation unit to consider.
13580///
13581/// @param corp the corpus to consider.
13582///
13583/// @return the resulting type, if any.
13584type_base_sptr
13586 const string& tu_path,
13587 const corpus& corp)
13588{
13589 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
13590 if (i == corp.priv_->path_tu_map.end())
13591 return type_base_sptr();
13592
13593 translation_unit_sptr tu = i->second;
13594 ABG_ASSERT(tu);
13595
13596 type_base_sptr t = lookup_type(type_name, *tu);
13597 return t;
13598}
13599
13600/// Look into an ABI corpus for a function type.
13601///
13602/// @param fn_type the function type to be looked for in the ABI
13603/// corpus.
13604///
13605/// @param corpus the ABI corpus into which to look for the function
13606/// type.
13607///
13608/// @return the function type found in the corpus.
13611 const corpus& corpus)
13612{
13613 ABG_ASSERT(fn_t);
13614
13615 function_type_sptr result;
13616
13617 if ((result = lookup_function_type(fn_t, corpus)))
13618 return result;
13619
13620 for (translation_units::const_iterator i =
13621 corpus.get_translation_units().begin();
13622 i != corpus.get_translation_units().end();
13623 ++i)
13625 **i)))
13626 return result;
13627
13628 return result;
13629}
13630
13631/// Look into a given corpus to find a type which has the same
13632/// qualified name as a giventype.
13633///
13634/// If the per-corpus type map is non-empty (because the corpus allows
13635/// the One Definition Rule) then the type islooked up in that
13636/// per-corpus type map. Otherwise, the type is looked-up in each
13637/// translation unit.
13638///
13639/// @param t the type which has the same qualified name as the type we
13640/// are looking for.
13641///
13642/// @param corp the ABI corpus to look into for the type.
13644lookup_basic_type(const type_decl& t, const corpus& corp)
13645{return lookup_basic_type(t.get_name(), corp);}
13646
13647/// Look into a given corpus to find a basic type which has a given
13648/// qualified name.
13649///
13650/// If the per-corpus type map is non-empty (because the corpus allows
13651/// the One Definition Rule) then the type islooked up in that
13652/// per-corpus type map. Otherwise, the type is looked-up in each
13653/// translation unit.
13654///
13655/// @param qualified_name the qualified name of the basic type to look
13656/// for.
13657///
13658/// @param corp the corpus to look into.
13660lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
13661{
13663 type_decl_sptr result;
13664
13665 if (!m.empty())
13666 result = lookup_type_in_map<type_decl>(qualified_name, m);
13667 else
13668 result = lookup_basic_type_through_translation_units(qualified_name, corp);
13669
13670 return result;
13671}
13672
13673/// Lookup a @ref type_decl type from a given corpus, by its location.
13674///
13675/// @param loc the location to consider.
13676///
13677/// @param corp the corpus to consider.
13678///
13679/// @return the resulting basic type, if any.
13682 const corpus &corp)
13683{
13686 type_decl_sptr result;
13687
13688 result = lookup_type_in_map<type_decl>(loc, m);
13689
13690 return result;
13691}
13692
13693/// Lookup a @ref type_decl type from a given corpus, by its location.
13694///
13695/// @param loc the location to consider.
13696///
13697/// @param corp the corpus to consider.
13698///
13699/// @return the resulting basic type, if any.
13701lookup_basic_type_per_location(const string &loc, const corpus &corp)
13702{
13703 const environment& env = corp.get_environment();
13704 return lookup_basic_type_per_location(env.intern(loc), corp);
13705}
13706
13707/// Look into a given corpus to find a basic type which has a given
13708/// qualified name.
13709///
13710/// If the per-corpus type map is non-empty (because the corpus allows
13711/// the One Definition Rule) then the type islooked up in that
13712/// per-corpus type map. Otherwise, the type is looked-up in each
13713/// translation unit.
13714///
13715/// @param qualified_name the qualified name of the basic type to look
13716/// for.
13717///
13718/// @param corp the corpus to look into.
13720lookup_basic_type(const string& qualified_name, const corpus& corp)
13721{
13722 return lookup_basic_type(corp.get_environment().intern(qualified_name),
13723 corp);
13724}
13725
13726/// Look into a given corpus to find a class type which has the same
13727/// qualified name as a given type.
13728///
13729/// If the per-corpus type map is non-empty (because the corpus allows
13730/// the One Definition Rule) then the type islooked up in that
13731/// per-corpus type map. Otherwise, the type is looked-up in each
13732/// translation unit.
13733///
13734/// @param t the class decl type which has the same qualified name as
13735/// the type we are looking for.
13736///
13737/// @param corp the corpus to look into.
13740{
13742 return lookup_class_type(s, corp);
13743}
13744
13745/// Look into a given corpus to find a class type which has a given
13746/// qualified name.
13747///
13748/// If the per-corpus type map is non-empty (because the corpus allows
13749/// the One Definition Rule) then the type islooked up in that
13750/// per-corpus type map. Otherwise, the type is looked-up in each
13751/// translation unit.
13752///
13753/// @param qualified_name the qualified name of the type to look for.
13754///
13755/// @param corp the corpus to look into.
13757lookup_class_type(const string& qualified_name, const corpus& corp)
13758{
13759 interned_string s = corp.get_environment().intern(qualified_name);
13760 return lookup_class_type(s, corp);
13761}
13762
13763/// Look into a given corpus to find a class type which has a given
13764/// qualified name.
13765///
13766/// If the per-corpus type map is non-empty (because the corpus allows
13767/// the One Definition Rule) then the type islooked up in that
13768/// per-corpus type map. Otherwise, the type is looked-up in each
13769/// translation unit.
13770///
13771/// @param qualified_name the qualified name of the type to look for.
13772///
13773/// @param corp the corpus to look into.
13775lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13776{
13778
13779 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13780
13781 return result;
13782}
13783
13784/// Look into a given corpus to find the class type*s* that have a
13785/// given qualified name.
13786///
13787/// @param qualified_name the qualified name of the type to look for.
13788///
13789/// @param corp the corpus to look into.
13790///
13791/// @return the vector of class types named @p qualified_name.
13793lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13794{
13796
13797 return lookup_types_in_map(qualified_name, m);
13798}
13799
13800/// Look into a given corpus to find the class type*s* that have a
13801/// given qualified name and that are declaration-only.
13802///
13803/// @param qualified_name the qualified name of the type to look for.
13804///
13805/// @param corp the corpus to look into.
13806///
13807/// @param result the vector of decl-only class types named @p
13808/// qualified_name. This is populated iff the function returns true.
13809///
13810/// @return true iff @p result was populated with the decl-only
13811/// classes named @p qualified_name.
13812bool
13814 const corpus& corp,
13815 type_base_wptrs_type& result)
13816{
13818
13819 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13820 if (!v)
13821 return false;
13822
13823 for (auto type : *v)
13824 {
13825 type_base_sptr t(type);
13827 if (c->get_is_declaration_only()
13828 && !c->get_definition_of_declaration())
13829 result.push_back(type);
13830 }
13831
13832 return !result.empty();
13833}
13834
13835/// Look into a given corpus to find the union type*s* that have a
13836/// given qualified name.
13837///
13838/// @param qualified_name the qualified name of the type to look for.
13839///
13840/// @param corp the corpus to look into.
13841///
13842/// @return the vector of union types named @p qualified_name.
13844lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13845{
13847
13848 return lookup_types_in_map(qualified_name, m);
13849}
13850
13851/// Look into a given corpus to find the class type*s* that have a
13852/// given qualified name.
13853///
13854/// @param qualified_name the qualified name of the type to look for.
13855///
13856/// @param corp the corpus to look into.
13857///
13858/// @return the vector of class types which name is @p qualified_name.
13860lookup_class_types(const string& qualified_name, const corpus& corp)
13861{
13862 interned_string s = corp.get_environment().intern(qualified_name);
13863 return lookup_class_types(s, corp);
13864}
13865
13866/// Look into a given corpus to find the union types that have a given
13867/// qualified name.
13868///
13869/// @param qualified_name the qualified name of the type to look for.
13870///
13871/// @param corp the corpus to look into.
13872///
13873/// @return the vector of union types which name is @p qualified_name.
13875lookup_union_types(const string& qualified_name, const corpus& corp)
13876{
13877 interned_string s = corp.get_environment().intern(qualified_name);
13878 return lookup_union_types(s, corp);
13879}
13880
13881/// Look up a @ref class_decl from a given corpus by its location.
13882///
13883/// @param loc the location to consider.
13884///
13885/// @param corp the corpus to consider.
13886///
13887/// @return the resulting class decl, if any.
13890 const corpus& corp)
13891{
13894 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13895
13896 return result;
13897}
13898
13899/// Look up a @ref class_decl from a given corpus by its location.
13900///
13901/// @param loc the location to consider.
13902///
13903/// @param corp the corpus to consider.
13904///
13905/// @return the resulting class decl, if any.
13907lookup_class_type_per_location(const string &loc, const corpus &corp)
13908{
13909 const environment& env = corp.get_environment();
13910 return lookup_class_type_per_location(env.intern(loc), corp);
13911}
13912
13913/// Look into a given corpus to find a union type which has a given
13914/// qualified name.
13915///
13916/// If the per-corpus type map is non-empty (because the corpus allows
13917/// the One Definition Rule) then the type islooked up in that
13918/// per-corpus type map. Otherwise, the type is looked-up in each
13919/// translation unit.
13920///
13921/// @param qualified_name the qualified name of the type to look for.
13922///
13923/// @param corp the corpus to look into.
13924union_decl_sptr
13925lookup_union_type(const interned_string& type_name, const corpus& corp)
13926{
13928
13929 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13930 if (!result)
13931 result = lookup_union_type_through_translation_units(type_name, corp);
13932
13933 return result;
13934}
13935
13936/// Look into a given corpus to find a union type which has a given
13937/// qualified name.
13938///
13939/// If the per-corpus type map is non-empty (because the corpus allows
13940/// the One Definition Rule) then the type islooked up in that
13941/// per-corpus type map. Otherwise, the type is looked-up in each
13942/// translation unit.
13943///
13944/// @param qualified_name the qualified name of the type to look for.
13945///
13946/// @param corp the corpus to look into.
13947union_decl_sptr
13948lookup_union_type(const string& type_name, const corpus& corp)
13949{
13950 interned_string s = corp.get_environment().intern(type_name);
13951 return lookup_union_type(s, corp);
13952}
13953
13954/// Look into a given corpus to find an enum type which has the same
13955/// qualified name as a given enum type.
13956///
13957/// If the per-corpus type map is non-empty (because the corpus allows
13958/// the One Definition Rule) then the type islooked up in that
13959/// per-corpus type map. Otherwise, the type is looked-up in each
13960/// translation unit.
13961///
13962/// @param t the enum type which has the same qualified name as the
13963/// type we are looking for.
13964///
13965/// @param corp the corpus to look into.
13968{
13970 return lookup_enum_type(s, corp);
13971}
13972
13973/// Look into a given corpus to find an enum type which has a given
13974/// qualified name.
13975///
13976/// If the per-corpus type map is non-empty (because the corpus allows
13977/// the One Definition Rule) then the type islooked up in that
13978/// per-corpus type map. Otherwise, the type is looked-up in each
13979/// translation unit.
13980///
13981/// @param qualified_name the qualified name of the enum type to look
13982/// for.
13983///
13984/// @param corp the corpus to look into.
13986lookup_enum_type(const string& qualified_name, const corpus& corp)
13987{
13988 interned_string s = corp.get_environment().intern(qualified_name);
13989 return lookup_enum_type(s, corp);
13990}
13991
13992/// Look into a given corpus to find an enum type which has a given
13993/// qualified name.
13994///
13995/// If the per-corpus type map is non-empty (because the corpus allows
13996/// the One Definition Rule) then the type islooked up in that
13997/// per-corpus type map. Otherwise, the type is looked-up in each
13998/// translation unit.
13999///
14000/// @param qualified_name the qualified name of the enum type to look
14001/// for.
14002///
14003/// @param corp the corpus to look into.
14005lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
14006{
14008
14009 enum_type_decl_sptr result =
14010 lookup_type_in_map<enum_type_decl>(qualified_name, m);
14011 if (!result)
14012 result = lookup_enum_type_through_translation_units(qualified_name, corp);
14013
14014 return result;
14015}
14016
14017/// Look into a given corpus to find the enum type*s* that have a
14018/// given qualified name.
14019///
14020/// @param qualified_name the qualified name of the type to look for.
14021///
14022/// @param corp the corpus to look into.
14023///
14024/// @return the vector of enum types that which name is @p qualified_name.
14026lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
14027{
14029
14030 return lookup_types_in_map(qualified_name, m);
14031}
14032
14033/// Look into a given corpus to find the enum type*s* that have a
14034/// given qualified name.
14035///
14036/// @param qualified_name the qualified name of the type to look for.
14037///
14038/// @param corp the corpus to look into.
14039///
14040/// @return the vector of enum types that which name is @p qualified_name.
14042lookup_enum_types(const string& qualified_name, const corpus& corp)
14043{
14044 interned_string s = corp.get_environment().intern(qualified_name);
14045 return lookup_enum_types(s, corp);
14046}
14047
14048/// Look up an @ref enum_type_decl from a given corpus, by its location.
14049///
14050/// @param loc the location to consider.
14051///
14052/// @param corp the corpus to look the type from.
14053///
14054/// @return the resulting enum type, if any.
14057{
14060 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
14061
14062 return result;
14063}
14064
14065/// Look up an @ref enum_type_decl from a given corpus, by its location.
14066///
14067/// @param loc the location to consider.
14068///
14069/// @param corp the corpus to look the type from.
14070///
14071/// @return the resulting enum type, if any.
14073lookup_enum_type_per_location(const string &loc, const corpus &corp)
14074{
14075 const environment& env = corp.get_environment();
14076 return lookup_enum_type_per_location(env.intern(loc), corp);
14077}
14078
14079/// Look into a given corpus to find a typedef type which has the
14080/// same qualified name as a given typedef type.
14081///
14082/// If the per-corpus type map is non-empty (because the corpus allows
14083/// the One Definition Rule) then the type islooked up in that
14084/// per-corpus type map. Otherwise, the type is looked-up in each
14085/// translation unit.
14086///
14087/// @param t the typedef type which has the same qualified name as the
14088/// typedef type we are looking for.
14089///
14090/// @param corp the corpus to look into.
14093{
14095 return lookup_typedef_type(s, corp);
14096}
14097
14098/// Look into a given corpus to find a typedef type which has the
14099/// same qualified name as a given typedef type.
14100///
14101/// If the per-corpus type map is non-empty (because the corpus allows
14102/// the One Definition Rule) then the type islooked up in that
14103/// per-corpus type map. Otherwise, the type is looked-up in each
14104/// translation unit.
14105///
14106/// @param t the typedef type which has the same qualified name as the
14107/// typedef type we are looking for.
14108///
14109/// @param corp the corpus to look into.
14111lookup_typedef_type(const string& qualified_name, const corpus& corp)
14112{
14113 interned_string s = corp.get_environment().intern(qualified_name);
14114 return lookup_typedef_type(s, corp);
14115}
14116
14117/// Look into a given corpus to find a typedef type which has a
14118/// given qualified name.
14119///
14120/// If the per-corpus type map is non-empty (because the corpus allows
14121/// the One Definition Rule) then the type islooked up in that
14122/// per-corpus type map. Otherwise, the type is looked-up in each
14123/// translation unit.
14124///
14125/// @param qualified_name the qualified name of the typedef type to
14126/// look for.
14127///
14128/// @param corp the corpus to look into.
14130lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
14131{
14133
14134 typedef_decl_sptr result =
14135 lookup_type_in_map<typedef_decl>(qualified_name, m);
14136 if (!result)
14137 result = lookup_typedef_type_through_translation_units(qualified_name,
14138 corp);
14139
14140 return result;
14141}
14142
14143/// Lookup a @ref typedef_decl from a corpus, by its location.
14144///
14145/// @param loc the location to consider.
14146///
14147/// @param corp the corpus to consider.
14148///
14149/// @return the typedef_decl found, if any.
14152{
14155 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
14156
14157 return result;
14158}
14159
14160/// Lookup a @ref typedef_decl from a corpus, by its location.
14161///
14162/// @param loc the location to consider.
14163///
14164/// @param corp the corpus to consider.
14165///
14166/// @return the typedef_decl found, if any.
14168lookup_typedef_type_per_location(const string &loc, const corpus &corp)
14169{
14170 const environment& env = corp.get_environment();
14171 return lookup_typedef_type_per_location(env.intern(loc), corp);
14172}
14173
14174/// Look into a corpus to find a class, union or typedef type which
14175/// has a given qualified name.
14176///
14177/// If the per-corpus type map is non-empty (because the corpus allows
14178/// the One Definition Rule) then the type islooked up in that
14179/// per-corpus type map. Otherwise, the type is looked-up in each
14180/// translation unit.
14181///
14182/// @param qualified_name the name of the type to find.
14183///
14184/// @param corp the corpus to look into.
14185///
14186/// @return the typedef or class type found.
14187type_base_sptr
14188lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
14189{
14190 type_base_sptr result = lookup_class_type(qualified_name, corp);
14191 if (!result)
14192 result = lookup_union_type(qualified_name, corp);
14193
14194 if (!result)
14195 result = lookup_typedef_type(qualified_name, corp);
14196 return result;
14197}
14198
14199/// Look into a corpus to find a class, typedef or enum type which has
14200/// a given qualified name.
14201///
14202/// If the per-corpus type map is non-empty (because the corpus allows
14203/// the One Definition Rule) then the type islooked up in that
14204/// per-corpus type map. Otherwise, the type is looked-up in each
14205/// translation unit.
14206///
14207/// @param qualified_name the qualified name of the type to look for.
14208///
14209/// @param corp the corpus to look into.
14210///
14211/// @return the typedef, class or enum type found.
14212type_base_sptr
14213lookup_class_typedef_or_enum_type(const string& qualified_name,
14214 const corpus& corp)
14215{
14216 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
14217 if (!result)
14218 result = lookup_enum_type(qualified_name, corp);
14219
14220 return result;
14221}
14222
14223/// Look into a given corpus to find a qualified type which has the
14224/// same qualified name as a given type.
14225///
14226/// @param t the type which has the same qualified name as the
14227/// qualified type we are looking for.
14228///
14229/// @param corp the corpus to look into.
14230///
14231/// @return the qualified type found.
14232qualified_type_def_sptr
14234{
14236 return lookup_qualified_type(s, corp);
14237}
14238
14239/// Look into a given corpus to find a qualified type which has a
14240/// given qualified name.
14241///
14242/// @param qualified_name the qualified name of the type to look for.
14243///
14244/// @param corp the corpus to look into.
14245///
14246/// @return the type found.
14247qualified_type_def_sptr
14248lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
14249{
14251 corp.get_types().qualified_types();
14252
14253 qualified_type_def_sptr result =
14254 lookup_type_in_map<qualified_type_def>(qualified_name, m);
14255
14256 if (!result)
14257 result = lookup_qualified_type_through_translation_units(qualified_name,
14258 corp);
14259
14260 return result;
14261}
14262
14263/// Look into a given corpus to find a pointer type which has the same
14264/// qualified name as a given pointer type.
14265///
14266/// @param t the pointer type which has the same qualified name as the
14267/// type we are looking for.
14268///
14269/// @param corp the corpus to look into.
14270///
14271/// @return the pointer type found.
14274{
14276 return lookup_pointer_type(s, corp);
14277}
14278
14279/// Look into a given corpus to find a pointer type which has a given
14280/// qualified name.
14281///
14282/// If the per-corpus type map is non-empty (because the corpus allows
14283/// the One Definition Rule) then the type islooked up in that
14284/// per-corpus type map. Otherwise, the type is looked-up in each
14285/// translation unit.
14286///
14287/// @param qualified_name the qualified name of the pointer type to
14288/// look for.
14289///
14290/// @param corp the corpus to look into.
14291///
14292/// @return the pointer type found.
14294lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
14295{
14297
14298 pointer_type_def_sptr result =
14299 lookup_type_in_map<pointer_type_def>(qualified_name, m);
14300 if (!result)
14301 result = lookup_pointer_type_through_translation_units(qualified_name,
14302 corp);
14303
14304 return result;
14305}
14306
14307/// Look into a given corpus to find a reference type which has the
14308/// same qualified name as a given reference type.
14309///
14310/// If the per-corpus type map is non-empty (because the corpus allows
14311/// the One Definition Rule) then the type islooked up in that
14312/// per-corpus type map. Otherwise, the type is looked-up in each
14313/// translation unit.
14314///
14315/// @param t the reference type which has the same qualified name as
14316/// the reference type we are looking for.
14317///
14318/// @param corp the corpus to look into.
14319///
14320/// @return the reference type found.
14323{
14325 return lookup_reference_type(s, corp);
14326}
14327
14328/// Look into a given corpus to find a reference type which has a
14329/// given qualified name.
14330///
14331/// If the per-corpus type map is non-empty (because the corpus allows
14332/// the One Definition Rule) then the type islooked up in that
14333/// per-corpus type map. Otherwise, the type is looked-up in each
14334/// translation unit.
14335///
14336/// @param qualified_name the qualified name of the reference type to
14337/// look for.
14338///
14339/// @param corp the corpus to look into.
14340///
14341/// @return the reference type found.
14343lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
14344{
14346 corp.get_types().reference_types();
14347
14349 lookup_type_in_map<reference_type_def>(qualified_name, m);
14350 if (!result)
14351 result = lookup_reference_type_through_translation_units(qualified_name,
14352 corp);
14353
14354 return result;
14355}
14356
14357/// Look into a given corpus to find an array type which has a given
14358/// qualified name.
14359///
14360/// If the per-corpus type map is non-empty (because the corpus allows
14361/// the One Definition Rule) then the type islooked up in that
14362/// per-corpus type map. Otherwise, the type is looked-up in each
14363/// translation unit.
14364///
14365/// @param qualified_name the qualified name of the array type to look
14366/// for.
14367///
14368/// @param corp the corpus to look into.
14369///
14370/// @return the array type found.
14373{
14375 return lookup_array_type(s, corp);
14376}
14377
14378/// Look into a given corpus to find an array type which has the same
14379/// qualified name as a given array type.
14380///
14381/// If the per-corpus type map is non-empty (because the corpus allows
14382/// the One Definition Rule) then the type islooked up in that
14383/// per-corpus type map. Otherwise, the type is looked-up in each
14384/// translation unit.
14385///
14386/// @param t the type which has the same qualified name as the type we
14387/// are looking for.
14388///
14389/// @param corp the corpus to look into.
14390///
14391/// @return the type found.
14393lookup_array_type(const interned_string& qualified_name, const corpus& corp)
14394{
14396
14397 array_type_def_sptr result =
14398 lookup_type_in_map<array_type_def>(qualified_name, m);
14399 if (!result)
14400 result = lookup_array_type_through_translation_units(qualified_name, corp);
14401
14402 return result;
14403}
14404
14405/// Look into a given corpus to find a function type which has the same
14406/// qualified name as a given function type.
14407///
14408/// If the per-corpus type map is non-empty (because the corpus allows
14409/// the One Definition Rule) then the type islooked up in that
14410/// per-corpus type map. Otherwise, the type is looked-up in each
14411/// translation unit.
14412///
14413/// @param t the function type which has the same qualified name as
14414/// the function type we are looking for.
14415///
14416/// @param corp the corpus to look into.
14417///
14418/// @return the function type found.
14421{
14422 interned_string type_name = get_type_name(t);
14423 return lookup_function_type(type_name, corp);
14424}
14425
14426/// Look into a given corpus to find a function type which has the same
14427/// qualified name as a given function type.
14428///
14429/// If the per-corpus type map is non-empty (because the corpus allows
14430/// the One Definition Rule) then the type islooked up in that
14431/// per-corpus type map. Otherwise, the type is looked-up in each
14432/// translation unit.
14433///
14434/// @param t the function type which has the same qualified name as
14435/// the function type we are looking for.
14436///
14437/// @param corp the corpus to look into.
14438///
14439/// @return the function type found.
14442 const corpus& corpus)
14443{
14444 if (fn_t)
14445 return lookup_function_type(*fn_t, corpus);
14446 return function_type_sptr();
14447}
14448
14449/// Look into a given corpus to find a function type which has a given
14450/// qualified name.
14451///
14452/// If the per-corpus type map is non-empty (because the corpus allows
14453/// the One Definition Rule) then the type islooked up in that
14454/// per-corpus type map. Otherwise, the type is looked-up in each
14455/// translation unit.
14456///
14457/// @param qualified_name the qualified name of the function type to
14458/// look for.
14459///
14460/// @param corp the corpus to look into.
14461///
14462/// @return the function type found.
14464lookup_function_type(const interned_string& qualified_name, const corpus& corp)
14465{
14467
14468 function_type_sptr result =
14469 lookup_type_in_map<function_type>(qualified_name, m);
14470 if (!result)
14471 result = lookup_function_type_through_translation_units(qualified_name,
14472 corp);
14473
14474 return result;
14475}
14476
14477/// Look into a given corpus to find a type which has a given
14478/// qualified name.
14479///
14480/// If the per-corpus type map is non-empty (because the corpus allows
14481/// the One Definition Rule) then the type islooked up in that
14482/// per-corpus type map. Otherwise, the type is looked-up in each
14483/// translation unit.
14484///
14485/// @param qualified_name the qualified name of the function type to
14486/// look for.
14487///
14488/// @param corp the corpus to look into.
14489///
14490/// @return the function type found.
14491type_base_sptr
14492lookup_type(const interned_string& n, const corpus& corp)
14493{
14494 type_base_sptr result;
14495
14496 ((result = lookup_basic_type(n, corp))
14497 || (result = lookup_class_type(n, corp))
14498 || (result = lookup_union_type(n, corp))
14499 || (result = lookup_enum_type(n, corp))
14500 || (result = lookup_typedef_type(n, corp))
14501 || (result = lookup_qualified_type(n, corp))
14502 || (result = lookup_pointer_type(n, corp))
14503 || (result = lookup_reference_type(n, corp))
14504 || (result = lookup_array_type(n, corp))
14505 || (result= lookup_function_type(n, corp)));
14506
14507 return result;
14508}
14509
14510/// Lookup a type from a corpus, by its location.
14511///
14512/// @param loc the location to consider.
14513///
14514/// @param corp the corpus to look the type from.
14515///
14516/// @return the resulting type, if any found.
14517type_base_sptr
14519{
14520 // TODO: finish this.
14521
14522 //TODO: when we fully support types indexed by their location, this
14523 //function should return a vector of types because at each location,
14524 //there can be several types that are defined (yay, C and C++,
14525 //*sigh*).
14526
14527 type_base_sptr result;
14528 ((result = lookup_basic_type_per_location(loc, corp))
14529 || (result = lookup_class_type_per_location(loc, corp))
14530 || (result = lookup_union_type_per_location(loc, corp))
14531 || (result = lookup_enum_type_per_location(loc, corp))
14532 || (result = lookup_typedef_type_per_location(loc, corp)));
14533
14534 return result;
14535}
14536
14537/// Look into a given corpus to find a type
14538///
14539/// If the per-corpus type map is non-empty (because the corpus allows
14540/// the One Definition Rule) then the type islooked up in that
14541/// per-corpus type map. Otherwise, the type is looked-up in each
14542/// translation unit.
14543///
14544/// @param qualified_name the qualified name of the function type to
14545/// look for.
14546///
14547/// @param corp the corpus to look into.
14548///
14549/// @return the function type found.
14550type_base_sptr
14551lookup_type(const type_base&t, const corpus& corp)
14552{
14554 return lookup_type(n, corp);
14555}
14556
14557/// Look into a given corpus to find a type
14558///
14559/// If the per-corpus type map is non-empty (because the corpus allows
14560/// the One Definition Rule) then the type islooked up in that
14561/// per-corpus type map. Otherwise, the type is looked-up in each
14562/// translation unit.
14563///
14564/// @param qualified_name the qualified name of the function type to
14565/// look for.
14566///
14567/// @param corp the corpus to look into.
14568///
14569/// @return the function type found.
14570type_base_sptr
14571lookup_type(const type_base_sptr&t, const corpus& corp)
14572{
14573 if (t)
14574 return lookup_type(*t, corp);
14575 return type_base_sptr();
14576}
14577
14578/// Update the map that associates a fully qualified name of a given
14579/// type to that type.
14580///
14581///
14582/// @param type the type we are considering.
14583///
14584/// @param types_map the map to update. It's a map that assciates a
14585/// fully qualified name of a type to the type itself.
14586///
14587/// @param use_type_name_as_key if true, use the name of the type as
14588/// the key to look it up later. If false, then use the location of
14589/// the type as a key to look it up later.
14590///
14591/// @return true iff the type was added to the map.
14592template<typename TypeKind>
14593bool
14594maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
14596 bool use_type_name_as_key = true)
14597{
14599
14600 if (use_type_name_as_key)
14601 s = get_type_name(type);
14602 else if (location l = type->get_location())
14603 {
14604 string str = l.expand();
14605 s = type->get_environment().intern(str);
14606 }
14607
14608 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14609 bool result = false;
14610
14611 if (i == types_map.end())
14612 {
14613 types_map[s].push_back(type);
14614 result = true;
14615 }
14616 else
14617 i->second.push_back(type);
14618
14619 return result;
14620}
14621
14622/// This is the specialization for type @ref class_decl of the
14623/// function template:
14624///
14625/// maybe_update_types_lookup_map<T>(scope_decl*,
14626/// const shared_ptr<T>&,
14627/// istring_type_base_wptrs_map_type&)
14628///
14629/// @param class_type the type to consider.
14630///
14631/// @param types_map the type map to update.
14632///
14633/// @return true iff the type was added to the map.
14634template<>
14635bool
14638 bool use_type_name_as_key)
14639{
14640 class_decl_sptr type = class_type;
14641
14642 bool update_qname_map = true;
14643 if (type->get_is_declaration_only())
14644 {
14645 // Let's try to look through decl-only classes to get their
14646 // definition. But if the class doesn't have a definition then
14647 // we'll keep it.
14648 if (class_decl_sptr def =
14649 is_class_type(class_type->get_definition_of_declaration()))
14650 type = def;
14651 }
14652
14653 if (!update_qname_map)
14654 return false;
14655
14657 if (use_type_name_as_key)
14658 {
14659 string qname = type->get_qualified_name();
14660 s = type->get_environment().intern(qname);
14661 }
14662 else if (location l = type->get_location())
14663 {
14664 string str = l.expand();
14665 s = type->get_environment().intern(str);
14666 }
14667
14668 bool result = false;
14669 istring_type_base_wptrs_map_type::iterator i = map.find(s);
14670 if (i == map.end())
14671 {
14672 map[s].push_back(type);
14673 result = true;
14674 }
14675 else
14676 i->second.push_back(type);
14677
14678 return result;
14679}
14680
14681/// This is the specialization for type @ref function_type of the
14682/// function template:
14683///
14684/// maybe_update_types_lookup_map<T>(scope_decl*,
14685/// const shared_ptr<T>&,
14686/// istring_type_base_wptrs_map_type&)
14687///
14688/// @param scope the scope of the type to consider.
14689///
14690/// @param class_type the type to consider.
14691///
14692/// @param types_map the type map to update.
14693///
14694/// @return true iff the type was added to the map.
14695template<>
14696bool
14698(const function_type_sptr& type,
14700 bool /*use_type_name_as_key*/)
14701{
14702 bool result = false;
14704 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14705 if (i == types_map.end())
14706 {
14707 types_map[s].push_back(type);
14708 result = true;
14709 }
14710 else
14711 i->second.push_back(type);
14712
14713 return result;
14714}
14715
14716/// Update the map that associates the fully qualified name of a basic
14717/// type with the type itself.
14718///
14719/// The per-translation unit type map is updated if no type with this
14720/// name was already existing in that map.
14721///
14722/// If no type with this name did already exist in the per-corpus type
14723/// map, then that per-corpus type map is updated. Otherwise, that
14724/// type is erased from that per-corpus map.
14725///
14726/// @param basic_type the basic type to consider.
14727void
14729{
14730 if (translation_unit *tu = basic_type->get_translation_unit())
14731 maybe_update_types_lookup_map<type_decl>
14732 (basic_type, tu->get_types().basic_types());
14733
14734 if (corpus *type_corpus = basic_type->get_corpus())
14735 {
14736 maybe_update_types_lookup_map<type_decl>
14737 (basic_type,
14738 type_corpus->priv_->get_types().basic_types());
14739
14740 maybe_update_types_lookup_map<type_decl>
14741 (basic_type,
14742 type_corpus->get_type_per_loc_map().basic_types(),
14743 /*use_type_name_as_key*/false);
14744
14745 if (corpus *group = type_corpus->get_group())
14746 {
14747 maybe_update_types_lookup_map<type_decl>
14748 (basic_type,
14749 group->priv_->get_types().basic_types());
14750
14751 maybe_update_types_lookup_map<type_decl>
14752 (basic_type,
14753 group->get_type_per_loc_map().basic_types(),
14754 /*use_type_name_as_key*/false);
14755 }
14756 }
14757
14758}
14759
14760/// Update the map that associates the fully qualified name of a class
14761/// type with the type itself.
14762///
14763/// The per-translation unit type map is updated if no type with this
14764/// name was already existing in that map.
14765///
14766/// If no type with this name did already exist in the per-corpus type
14767/// map, then that per-corpus type map is updated. Otherwise, that
14768/// type is erased from that per-corpus map.
14769///
14770/// @param class_type the class type to consider.
14771void
14773{
14774 if (translation_unit *tu = class_type->get_translation_unit())
14776 (class_type, tu->get_types().class_types());
14777
14778 if (corpus *type_corpus = class_type->get_corpus())
14779 {
14781 (class_type,
14782 type_corpus->priv_->get_types().class_types());
14783
14785 (class_type,
14786 type_corpus->get_type_per_loc_map().class_types(),
14787 /*use_type_name_as_key*/false);
14788
14789 if (corpus *group = type_corpus->get_group())
14790 {
14792 (class_type,
14793 group->priv_->get_types().class_types());
14794
14796 (class_type,
14797 group->get_type_per_loc_map().class_types(),
14798 /*use_type_name_as_key*/false);
14799 }
14800 }
14801}
14802
14803/// Update the map that associates the fully qualified name of a union
14804/// type with the type itself.
14805///
14806/// The per-translation unit type map is updated if no type with this
14807/// name was already existing in that map.
14808///
14809/// If no type with this name did already exist in the per-corpus type
14810/// map, then that per-corpus type map is updated. Otherwise, that
14811/// type is erased from that per-corpus map.
14812///
14813/// @param union_type the union type to consider.
14814void
14815maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14816{
14817 if (translation_unit *tu = union_type->get_translation_unit())
14818 maybe_update_types_lookup_map<union_decl>
14819 (union_type, tu->get_types().union_types());
14820
14821 if (corpus *type_corpus = union_type->get_corpus())
14822 {
14823 maybe_update_types_lookup_map<union_decl>
14824 (union_type,
14825 type_corpus->priv_->get_types().union_types());
14826
14827 maybe_update_types_lookup_map<union_decl>
14828 (union_type,
14829 type_corpus->get_type_per_loc_map().union_types(),
14830 /*use_type_name_as_key*/false);
14831
14832 if (corpus *group = type_corpus->get_group())
14833 {
14834 maybe_update_types_lookup_map<union_decl>
14835 (union_type,
14836 group->priv_->get_types().union_types());
14837
14838 maybe_update_types_lookup_map<union_decl>
14839 (union_type,
14840 group->get_type_per_loc_map().union_types(),
14841 /*use_type_name_as_key*/false);
14842 }
14843 }
14844}
14845
14846/// Update the map that associates the fully qualified name of an enum
14847/// type with the type itself.
14848///
14849/// The per-translation unit type map is updated if no type with this
14850/// name was already existing in that map.
14851///
14852/// If no type with this name did already exist in the per-corpus type
14853/// map, then that per-corpus type map is updated. Otherwise, that
14854/// type is erased from that per-corpus map.
14855///
14856/// @param enum_type the type to consider.
14857void
14859{
14860 if (translation_unit *tu = enum_type->get_translation_unit())
14861 maybe_update_types_lookup_map<enum_type_decl>
14862 (enum_type, tu->get_types().enum_types());
14863
14864 if (corpus *type_corpus = enum_type->get_corpus())
14865 {
14866 maybe_update_types_lookup_map<enum_type_decl>
14867 (enum_type,
14868 type_corpus->priv_->get_types().enum_types());
14869
14870 maybe_update_types_lookup_map<enum_type_decl>
14871 (enum_type,
14872 type_corpus->get_type_per_loc_map().enum_types(),
14873 /*use_type_name_as_key*/false);
14874
14875 if (corpus *group = type_corpus->get_group())
14876 {
14877 maybe_update_types_lookup_map<enum_type_decl>
14878 (enum_type,
14879 group->priv_->get_types().enum_types());
14880
14881 maybe_update_types_lookup_map<enum_type_decl>
14882 (enum_type,
14883 group->get_type_per_loc_map().enum_types(),
14884 /*use_type_name_as_key*/false);
14885 }
14886 }
14887
14888}
14889
14890/// Update the map that associates the fully qualified name of a
14891/// typedef type with the type itself.
14892///
14893/// The per-translation unit type map is updated if no type with this
14894/// name was already existing in that map.
14895///
14896/// If no type with this name did already exist in the per-corpus type
14897/// map, then that per-corpus type map is updated. Otherwise, that
14898/// type is erased from that per-corpus map.
14899///
14900/// @param typedef_type the type to consider.
14901void
14903{
14904 if (translation_unit *tu = typedef_type->get_translation_unit())
14905 maybe_update_types_lookup_map<typedef_decl>
14906 (typedef_type, tu->get_types().typedef_types());
14907
14908 if (corpus *type_corpus = typedef_type->get_corpus())
14909 {
14910 maybe_update_types_lookup_map<typedef_decl>
14911 (typedef_type,
14912 type_corpus->priv_->get_types().typedef_types());
14913
14914 maybe_update_types_lookup_map<typedef_decl>
14915 (typedef_type,
14916 type_corpus->get_type_per_loc_map().typedef_types(),
14917 /*use_type_name_as_key*/false);
14918
14919 if (corpus *group = type_corpus->get_group())
14920 {
14921 maybe_update_types_lookup_map<typedef_decl>
14922 (typedef_type,
14923 group->priv_->get_types().typedef_types());
14924
14925 maybe_update_types_lookup_map<typedef_decl>
14926 (typedef_type,
14927 group->get_type_per_loc_map().typedef_types(),
14928 /*use_type_name_as_key*/false);
14929 }
14930 }
14931}
14932
14933/// Update the map that associates the fully qualified name of a
14934/// qualified type with the type itself.
14935///
14936/// The per-translation unit type map is updated if no type with this
14937/// name was already existing in that map.
14938///
14939/// If no type with this name did already exist in the per-corpus type
14940/// map, then that per-corpus type map is updated. Otherwise, that
14941/// type is erased from that per-corpus map.
14942///
14943/// @param qualified_type the type to consider.
14944void
14945maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14946{
14947 if (translation_unit *tu = qualified_type->get_translation_unit())
14948 maybe_update_types_lookup_map<qualified_type_def>
14949 (qualified_type, tu->get_types().qualified_types());
14950
14951 if (corpus *type_corpus = qualified_type->get_corpus())
14952 {
14953 maybe_update_types_lookup_map<qualified_type_def>
14954 (qualified_type,
14955 type_corpus->priv_->get_types().qualified_types());
14956
14957 if (corpus *group = type_corpus->get_group())
14958 {
14959 maybe_update_types_lookup_map<qualified_type_def>
14960 (qualified_type,
14961 group->priv_->get_types().qualified_types());
14962 }
14963 }
14964}
14965
14966/// Update the map that associates the fully qualified name of a
14967/// pointer type with the type itself.
14968///
14969/// The per-translation unit type map is updated if no type with this
14970/// name was already existing in that map.
14971///
14972/// If no type with this name did already exist in the per-corpus type
14973/// map, then that per-corpus type map is updated. Otherwise, that
14974/// type is erased from that per-corpus map.
14975///
14976/// @param pointer_type the type to consider.
14977void
14979{
14980 if (translation_unit *tu = pointer_type->get_translation_unit())
14981 maybe_update_types_lookup_map<pointer_type_def>
14982 (pointer_type, tu->get_types().pointer_types());
14983
14984 if (corpus *type_corpus = pointer_type->get_corpus())
14985 {
14986 maybe_update_types_lookup_map<pointer_type_def>
14987 (pointer_type,
14988 type_corpus->priv_->get_types().pointer_types());
14989
14990 if (corpus *group = type_corpus->get_group())
14991 {
14992 maybe_update_types_lookup_map<pointer_type_def>
14993 (pointer_type,
14994 group->priv_->get_types().pointer_types());
14995 }
14996 }
14997}
14998
14999/// Update the map that associates the fully qualified name of a
15000/// pointer-to-member type with the type itself.
15001///
15002/// The per-translation unit type map is updated if no type with this
15003/// name was already existing in that map.
15004///
15005/// If no type with this name did already exist in the per-corpus type
15006/// map, then that per-corpus type map is updated. Otherwise, that
15007/// type is erased from that per-corpus map.
15008///
15009/// @param ptr_to_mbr_type the type to consider.
15010void
15012{
15013 if (translation_unit *tu = ptr_to_member->get_translation_unit())
15014 maybe_update_types_lookup_map<ptr_to_mbr_type>
15015 (ptr_to_member, tu->get_types().ptr_to_mbr_types());
15016
15017 if (corpus *type_corpus = ptr_to_member->get_corpus())
15018 {
15019 maybe_update_types_lookup_map<ptr_to_mbr_type>
15020 (ptr_to_member,
15021 type_corpus->priv_->get_types().ptr_to_mbr_types());
15022
15023 if (corpus *group = type_corpus->get_group())
15024 {
15025 maybe_update_types_lookup_map<ptr_to_mbr_type>
15026 (ptr_to_member,
15027 group->priv_->get_types().ptr_to_mbr_types());
15028 }
15029 }
15030}
15031
15032/// Update the map that associates the fully qualified name of a
15033/// reference type with the type itself.
15034///
15035/// The per-translation unit type map is updated if no type with this
15036/// name was already existing in that map.
15037///
15038/// If no type with this name did already exist in the per-corpus type
15039/// map, then that per-corpus type map is updated. Otherwise, that
15040/// type is erased from that per-corpus map.
15041///
15042/// @param reference_type the type to consider.
15043void
15045{
15046 if (translation_unit *tu = reference_type->get_translation_unit())
15047 maybe_update_types_lookup_map<reference_type_def>
15048 (reference_type, tu->get_types().reference_types());
15049
15050 if (corpus *type_corpus = reference_type->get_corpus())
15051 {
15052 maybe_update_types_lookup_map<reference_type_def>
15053 (reference_type,
15054 type_corpus->priv_->get_types().reference_types());
15055
15056 if (corpus *group = type_corpus->get_group())
15057 {
15058 maybe_update_types_lookup_map<reference_type_def>
15059 (reference_type,
15060 group->priv_->get_types().reference_types());
15061 }
15062 }
15063}
15064
15065/// Update the map that associates the fully qualified name of a type
15066/// with the type itself.
15067///
15068/// The per-translation unit type map is updated if no type with this
15069/// name was already existing in that map.
15070///
15071/// If no type with this name did already exist in the per-corpus type
15072/// map, then that per-corpus type map is updated. Otherwise, that
15073/// type is erased from that per-corpus map.
15074///
15075/// @param array_type the type to consider.
15076void
15078{
15079 if (translation_unit *tu = array_type->get_translation_unit())
15080 maybe_update_types_lookup_map<array_type_def>
15081 (array_type, tu->get_types().array_types());
15082
15083 if (corpus *type_corpus = array_type->get_corpus())
15084 {
15085 maybe_update_types_lookup_map<array_type_def>
15086 (array_type,
15087 type_corpus->priv_->get_types().array_types());
15088
15089 maybe_update_types_lookup_map<array_type_def>
15090 (array_type,
15091 type_corpus->get_type_per_loc_map().array_types(),
15092 /*use_type_name_as_key*/false);
15093
15094 if (corpus *group = type_corpus->get_group())
15095 {
15096 maybe_update_types_lookup_map<array_type_def>
15097 (array_type,
15098 group->priv_->get_types().array_types());
15099
15100 maybe_update_types_lookup_map<array_type_def>
15101 (array_type,
15102 group->get_type_per_loc_map().array_types(),
15103 /*use_type_name_as_key*/false);
15104 }
15105 }
15106}
15107
15108/// Update the map that associates the fully qualified name of a type
15109/// with the type itself.
15110///
15111/// The per-translation unit type map is updated if no type with this
15112/// name was already existing in that map.
15113///
15114/// If no type with this name did already exist in the per-corpus type
15115/// map, then that per-corpus type map is updated. Otherwise, that
15116/// type is erased from that per-corpus map.
15117///
15118/// @param subrange_type the type to consider.
15119void
15121(const array_type_def::subrange_sptr& subrange_type)
15122{
15123 if (translation_unit *tu = subrange_type->get_translation_unit())
15124 maybe_update_types_lookup_map<array_type_def::subrange_type>
15125 (subrange_type, tu->get_types().subrange_types());
15126
15127 if (corpus *type_corpus = subrange_type->get_corpus())
15128 {
15129 maybe_update_types_lookup_map<array_type_def::subrange_type>
15130 (subrange_type,
15131 type_corpus->priv_->get_types().subrange_types());
15132
15133 maybe_update_types_lookup_map<array_type_def::subrange_type>
15134 (subrange_type,
15135 type_corpus->get_type_per_loc_map().subrange_types(),
15136 /*use_type_name_as_key*/false);
15137
15138 if (corpus *group = subrange_type->get_corpus())
15139 {
15140 maybe_update_types_lookup_map<array_type_def::subrange_type>
15141 (subrange_type,
15142 group->priv_->get_types().subrange_types());
15143
15144 maybe_update_types_lookup_map<array_type_def::subrange_type>
15145 (subrange_type,
15146 group->get_type_per_loc_map().subrange_types(),
15147 /*use_type_name_as_key*/false);
15148 }
15149 }
15150}
15151
15152/// Update the map that associates the fully qualified name of a
15153/// function type with the type itself.
15154///
15155/// The per-translation unit type map is updated if no type with this
15156/// name was already existing in that map.
15157///
15158/// If no type with this name did already exist in the per-corpus type
15159/// map, then that per-corpus type map is updated. Otherwise, that
15160/// type is erased from that per-corpus map.
15161///
15162/// @param scope the scope of the function type.
15163/// @param fn_type the type to consider.
15164void
15166{
15167 if (translation_unit *tu = fn_type->get_translation_unit())
15169 (fn_type, tu->get_types().function_types());
15170
15171 if (corpus *type_corpus = fn_type->get_corpus())
15172 {
15174 (fn_type,
15175 type_corpus->priv_->get_types().function_types());
15176
15177 if (corpus *group = fn_type->get_corpus())
15178 {
15180 (fn_type,
15181 group->priv_->get_types().function_types());
15182 }
15183 }
15184}
15185
15186/// Update the map that associates the fully qualified name of a type
15187/// declaration with the type itself.
15188///
15189/// The per-translation unit type map is updated if no type with this
15190/// name was already existing in that map.
15191///
15192/// If no type with this name did already exist in the per-corpus type
15193/// map, then that per-corpus type map is updated. Otherwise, that
15194/// type is erased from that per-corpus map.
15195///
15196/// @param decl the declaration of the type to consider.
15197void
15198maybe_update_types_lookup_map(const decl_base_sptr& decl)
15199{
15200 if (!is_type(decl))
15201 return;
15202
15203 if (type_decl_sptr basic_type = is_type_decl(decl))
15205 else if (class_decl_sptr class_type = is_class_type(decl))
15207 else if (union_decl_sptr union_type = is_union_type(decl))
15209 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
15211 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
15212 maybe_update_types_lookup_map(typedef_type);
15213 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
15214 maybe_update_types_lookup_map(qualified_type);
15215 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
15216 maybe_update_types_lookup_map(pointer_type);
15217 else if (ptr_to_mbr_type_sptr ptr_to_member = is_ptr_to_mbr_type(decl))
15218 maybe_update_types_lookup_map(ptr_to_member);
15219 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
15220 maybe_update_types_lookup_map(reference_type);
15221 else if (array_type_def_sptr array_type = is_array_type(decl))
15223 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
15224 maybe_update_types_lookup_map(subrange_type);
15225 else if (function_type_sptr fn_type = is_function_type(decl))
15227 else
15229}
15230
15231/// Update the map that associates the fully qualified name of a type
15232/// with the type itself.
15233///
15234/// The per-translation unit type map is updated if no type with this
15235/// name was already existing in that map.
15236///
15237/// If no type with this name did already exist in the per-corpus type
15238/// map, then that per-corpus type map is updated. Otherwise, that
15239/// type is erased from that per-corpus map.
15240///
15241/// @param type the type to consider.
15242void
15243maybe_update_types_lookup_map(const type_base_sptr& type)
15244{
15245 if (decl_base_sptr decl = get_type_declaration(type))
15247 else if (function_type_sptr fn_type = is_function_type(type))
15249 else
15251}
15252
15253//--------------------------------
15254// </type and decls lookup stuff>
15255// ------------------------------
15256
15257/// In a translation unit, lookup a given type or synthesize it if
15258/// it's a qualified type.
15259///
15260/// So this function first looks the type up in the translation unit.
15261/// If it's found, then OK, it's returned. Otherwise, if it's a
15262/// qualified, reference or pointer or function type (a composite
15263/// type), lookup the underlying type, synthesize the type we want
15264/// from it and return it.
15265///
15266/// If the underlying types is not not found, then give up and return
15267/// nil.
15268///
15269/// @return the type that was found or the synthesized type.
15270type_base_sptr
15271synthesize_type_from_translation_unit(const type_base_sptr& type,
15272 translation_unit& tu)
15273{
15274 type_base_sptr result;
15275
15276 result = lookup_type(type, tu);
15277
15278 if (!result)
15279 {
15280 if (qualified_type_def_sptr qual = is_qualified_type(type))
15281 {
15282 type_base_sptr underlying_type =
15283 synthesize_type_from_translation_unit(qual->get_underlying_type(),
15284 tu);
15285 if (underlying_type)
15286 {
15287 result.reset(new qualified_type_def(underlying_type,
15288 qual->get_cv_quals(),
15289 qual->get_location()));
15290 }
15291 }
15292 else if (pointer_type_def_sptr p = is_pointer_type(type))
15293 {
15294 type_base_sptr pointed_to_type =
15295 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
15296 tu);
15297 if (pointed_to_type)
15298 {
15299 result.reset(new pointer_type_def(pointed_to_type,
15300 p->get_size_in_bits(),
15301 p->get_alignment_in_bits(),
15302 p->get_location()));
15303 }
15304 }
15305 else if (reference_type_def_sptr r = is_reference_type(type))
15306 {
15307 type_base_sptr pointed_to_type =
15308 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
15309 if (pointed_to_type)
15310 {
15311 result.reset(new reference_type_def(pointed_to_type,
15312 r->is_lvalue(),
15313 r->get_size_in_bits(),
15314 r->get_alignment_in_bits(),
15315 r->get_location()));
15316 }
15317 }
15318 else if (function_type_sptr f = is_function_type(type))
15320
15321 if (result)
15322 {
15324 canonicalize(result);
15325 }
15326 }
15327
15328 if (result)
15329 tu.priv_->synthesized_types_.push_back(result);
15330
15331 return result;
15332}
15333
15334/// In a translation unit, lookup the sub-types that make up a given
15335/// function type and if the sub-types are all found, synthesize and
15336/// return a function_type with them.
15337///
15338/// This function is like lookup_function_type_in_translation_unit()
15339/// execept that it constructs the function type from the sub-types
15340/// found in the translation, rather than just looking for the
15341/// function types held by the translation unit. This can be useful
15342/// if the translation unit doesnt hold the function type we are
15343/// looking for (i.e, lookup_function_type_in_translation_unit()
15344/// returned NULL) but we still want to see if the sub-types of the
15345/// function types are present in the translation unit.
15346///
15347/// @param fn_type the function type to consider.
15348///
15349/// @param tu the translation unit to look into.
15350///
15351/// @return the resulting synthesized function type if all its
15352/// sub-types have been found, NULL otherwise.
15355 translation_unit& tu)
15356{
15358
15359 const environment& env = tu.get_environment();
15360
15361 type_base_sptr return_type = fn_type.get_return_type();
15362 type_base_sptr result_return_type;
15363 if (!return_type || env.is_void_type(return_type))
15364 result_return_type = env.get_void_type();
15365 else
15366 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
15367 if (!result_return_type)
15368 return nil;
15369
15371 type_base_sptr parm_type;
15373 for (function_type::parameters::const_iterator i =
15374 fn_type.get_parameters().begin();
15375 i != fn_type.get_parameters().end();
15376 ++i)
15377 {
15378 type_base_sptr t = (*i)->get_type();
15379 parm_type = synthesize_type_from_translation_unit(t, tu);
15380 if (!parm_type)
15381 return nil;
15382 parm.reset(new function_decl::parameter(parm_type,
15383 (*i)->get_index(),
15384 (*i)->get_name(),
15385 (*i)->get_location(),
15386 (*i)->get_variadic_marker(),
15387 (*i)->get_is_artificial()));
15388 parms.push_back(parm);
15389 }
15390
15391 class_or_union_sptr class_type;
15392 const method_type* method = is_method_type(&fn_type);
15393 if (method)
15394 {
15395 class_type = is_class_or_union_type
15397 ABG_ASSERT(class_type);
15398 }
15399
15400 function_type_sptr result_fn_type;
15401
15402 if (class_type)
15403 result_fn_type.reset(new method_type(result_return_type,
15404 class_type,
15405 parms,
15406 method->get_is_const(),
15407 fn_type.get_size_in_bits(),
15408 fn_type.get_alignment_in_bits()));
15409 else
15410 result_fn_type.reset(new function_type(result_return_type,
15411 parms,
15412 fn_type.get_size_in_bits(),
15413 fn_type.get_alignment_in_bits()));
15414
15415 tu.priv_->synthesized_types_.push_back(result_fn_type);
15416 tu.bind_function_type_life_time(result_fn_type);
15417
15418 canonicalize(result_fn_type);
15419 return result_fn_type;
15420}
15421
15422/// Demangle a C++ mangled name and return the resulting string
15423///
15424/// @param mangled_name the C++ mangled name to demangle.
15425///
15426/// @return the resulting mangled name.
15427string
15428demangle_cplus_mangled_name(const string& mangled_name)
15429{
15430 if (mangled_name.empty())
15431 return "";
15432
15433 size_t l = 0;
15434 int status = 0;
15435 char * str = abi::__cxa_demangle(mangled_name.c_str(),
15436 NULL, &l, &status);
15437 string demangled_name = mangled_name;
15438 if (str)
15439 {
15440 ABG_ASSERT(status == 0);
15441 demangled_name = str;
15442 free(str);
15443 str = 0;
15444 }
15445 return demangled_name;
15446}
15447
15448/// Return either the type given in parameter if it's non-null, or the
15449/// void type.
15450///
15451/// @param t the type to consider.
15452///
15453/// @param env the environment to use. If NULL, just abort the
15454/// process.
15455///
15456/// @return either @p t if it is non-null, or the void type.
15457type_base_sptr
15458type_or_void(const type_base_sptr t, const environment& env)
15459{
15460 type_base_sptr r;
15461
15462 if (t)
15463 r = t;
15464 else
15465 r = type_base_sptr(env.get_void_type());
15466
15467 return r;
15468}
15469
15470global_scope::~global_scope()
15471{
15472}
15473
15474/// Test if two types are eligible to the "Linux Kernel Fast Type
15475/// Comparison Optimization", a.k.a LKFTCO.
15476///
15477/// Two types T1 and T2 (who are presumably of the same name and kind)
15478/// are eligible to the LKFTCO if they fulfill the following criteria/
15479///
15480/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
15481/// either class, union or enums.
15482///
15483/// 2/ They are defined in the same translation unit.
15484///
15485/// @param t1 the first type to consider.
15486///
15487/// @param t2 the second type to consider.
15488///
15489/// @return true iff t1 and t2 are eligible to the LKFTCO.
15490static bool
15491types_defined_same_linux_kernel_corpus_public(const type_base& t1,
15492 const type_base& t2)
15493{
15494 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
15495 string t1_file_path, t2_file_path;
15496
15497 /// If the t1 (and t2) are classes/unions/enums from the same linux
15498 /// kernel corpus, let's move on. Otherwise bail out.
15499 if (!(t1_corpus && t2_corpus
15500 && t1_corpus == t2_corpus
15501 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
15502 && (is_class_or_union_type(&t1)
15503 || is_enum_type(&t1))))
15504 return false;
15505
15506 class_or_union *c1 = 0, *c2 = 0;
15507 c1 = is_class_or_union_type(&t1);
15508 c2 = is_class_or_union_type(&t2);
15509
15510 // Two anonymous class types with no naming typedefs cannot be
15511 // eligible to this optimization.
15512 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
15513 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
15514 return false;
15515
15516 // Two anonymous classes with naming typedefs should have the same
15517 // typedef name.
15518 if (c1
15519 && c2
15520 && c1->get_is_anonymous() && c1->get_naming_typedef()
15521 && c2->get_is_anonymous() && c2->get_naming_typedef())
15522 if (c1->get_naming_typedef()->get_name()
15523 != c2->get_naming_typedef()->get_name())
15524 return false;
15525
15526 // Two anonymous enum types cannot be eligible to this optimization.
15527 if (const enum_type_decl *e1 = is_enum_type(&t1))
15528 if (const enum_type_decl *e2 = is_enum_type(&t2))
15529 if (e1->get_is_anonymous() || e2->get_is_anonymous())
15530 return false;
15531
15532 // Look through declaration-only types. That is, get the associated
15533 // definition type.
15536
15537 if (c1 && c2)
15538 {
15539 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
15540 {
15541 if (c1->get_environment().decl_only_class_equals_definition())
15542 // At least one of classes/union is declaration-only.
15543 // Because we are in a context in which a declaration-only
15544 // class/union is equal to all definitions of that
15545 // class/union, we can assume that the two types are
15546 // equal.
15547 return true;
15548 }
15549 }
15550
15551 if (t1.get_size_in_bits() != t2.get_size_in_bits())
15552 return false;
15553
15554 // Look at the file names of the locations of t1 and t2. If they
15555 // are equal, then t1 and t2 are defined in the same file.
15556 {
15557 location l;
15558
15559 if (c1)
15560 l = c1->get_location();
15561 else
15562 l = dynamic_cast<const decl_base&>(t1).get_location();
15563
15564 unsigned line = 0, col = 0;
15565 if (l)
15566 l.expand(t1_file_path, line, col);
15567 if (c2)
15568 l = c2->get_location();
15569 else
15570 l = dynamic_cast<const decl_base&>(t2).get_location();
15571 if (l)
15572 l.expand(t2_file_path, line, col);
15573 }
15574
15575 if (t1_file_path.empty() || t2_file_path.empty())
15576 return false;
15577
15578 if (t1_file_path == t2_file_path)
15579 return true;
15580
15581 return false;
15582}
15583
15584
15585/// Compare a type T against a canonical type.
15586///
15587/// This function is called during the canonicalization process of the
15588/// type T. T is called the "candidate type" because it's in the
15589/// process of being canonicalized. Meaning, it's going to be
15590/// compared to a canonical type C. If T equals C, then the canonical
15591/// type of T is C.
15592///
15593/// The purpose of this function is to allow the debugging of the
15594/// canonicalization of T, if that debugging is activated by
15595/// configuring the libabigail package with
15596/// --enable-debug-type-canonicalization and by running "abidw
15597/// --debug-tc". In that case, T is going to be compared to C twice:
15598/// once with canonical equality and once with structural equality.
15599/// The two comparisons must be equal. Otherwise, the
15600/// canonicalization process is said to be faulty and this function
15601/// aborts.
15602///
15603/// This is a sub-routine of type_base::get_canonical_type_for.
15604///
15605/// @param canonical_type the canonical type to compare the candidate
15606/// type against.
15607///
15608/// @param candidate_type the candidate type to compare against the
15609/// canonical type.
15610///
15611/// @return true iff @p canonical_type equals @p candidate_type.
15612///
15613static bool
15614compare_types_during_canonicalization(const type_base& canonical_type,
15615 const type_base& candidate_type)
15616{
15617#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
15618 const environment& env = canonical_type.get_environment();
15619 if (env.debug_type_canonicalization_is_on())
15620 {
15621 bool canonical_equality = false, structural_equality = false;
15622 env.priv_->allow_type_comparison_results_caching(false);
15623 env.priv_->use_canonical_type_comparison_ = false;
15624 structural_equality = canonical_type == candidate_type;
15625 env.priv_->use_canonical_type_comparison_ = true;
15626 canonical_equality = canonical_type == candidate_type;
15627 env.priv_->allow_type_comparison_results_caching(true);
15628 if (canonical_equality != structural_equality)
15629 {
15630 std::cerr << "structural & canonical equality different for type: "
15631 << canonical_type.get_pretty_representation(true, true)
15632 << std::endl;
15634 }
15635 return structural_equality;
15636 }
15637#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
15638 return canonical_type == candidate_type;
15639}
15640
15641/// Compare a canonical type against a candidate canonical type.
15642///
15643/// This is ultimately a sub-routine of the
15644/// type_base::get_canonical_type_for().
15645///
15646/// The goal of this function is to ease debugging because it can be
15647/// called from within type_base::get_canonical_type_for() from the
15648/// prompt of the debugger (with some breakpoint appropriately set) to
15649/// debug the comparison that happens during type canonicalization,
15650/// between a candidate type being canonicalized, and an existing
15651/// canonical type that is registered in the system, in as returned by
15652/// environment::get_canonical_types()
15653///
15654/// @param canonical_type the canonical type to consider.
15655///
15656/// @param candidate_type the candidate type that is being
15657/// canonicalized, and thus compared to @p canonical_type.
15658///
15659/// @return true iff @p canonical_type compares equal to @p
15660/// candidate_type.
15661static bool
15662compare_canonical_type_against_candidate(const type_base& canonical_type,
15663 const type_base& candidate_type)
15664{
15665 environment& env = const_cast<environment&>(canonical_type.get_environment());
15666
15667 // Before the "*it == it" comparison below is done, let's
15668 // perform on-the-fly-canonicalization. For C types, let's
15669 // consider that an unresolved struct declaration 'struct S'
15670 // is different from a definition 'struct S'. This is
15671 // because normally, at this point all the declarations of
15672 // struct S that are compatible with the definition of
15673 // struct S have already been resolved to that definition,
15674 // during the DWARF parsing. The remaining unresolved
15675 // declaration are thus considered different. With this
15676 // setup we can properly handle cases of two *different*
15677 // struct S being defined in the same binary (in different
15678 // translation units), and a third struct S being only
15679 // declared as an opaque type in a third translation unit of
15680 // its own, with no definition in there. In that case, the
15681 // declaration-only struct S should be left alone and not
15682 // resolved to any of the two definitions of struct S.
15683 bool saved_decl_only_class_equals_definition =
15684 env.decl_only_class_equals_definition();
15685
15686 // Compare types by considering that decl-only classes don't
15687 // equal their definition.
15688 env.decl_only_class_equals_definition(false);
15689 env.priv_->allow_type_comparison_results_caching(true);
15690 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
15691 candidate_type)
15692 || compare_types_during_canonicalization(canonical_type,
15693 candidate_type));
15694 // Restore the state of the on-the-fly-canonicalization and
15695 // the decl-only-class-being-equal-to-a-matching-definition
15696 // flags.
15697 env.priv_->clear_type_comparison_results_cache();
15698 env.priv_->allow_type_comparison_results_caching(false);
15699 env.decl_only_class_equals_definition
15700 (saved_decl_only_class_equals_definition);
15701 return equal;
15702}
15703
15704/// Compare a canonical type against a candidate canonical type.
15705///
15706/// This is ultimately a sub-routine of the
15707/// type_base::get_canonical_type_for().
15708///
15709/// The goal of this function is to ease debugging because it can be
15710/// called from within type_base::get_canonical_type_for() from the
15711/// prompt of the debugger (with some breakpoint appropriately set) to
15712/// debug the comparison that happens during type canonicalization,
15713/// between a candidate type being canonicalized, and an existing
15714/// canonical type that is registered in the system, in as returned by
15715/// environment::get_canonical_types()
15716///
15717/// @param canonical_type the canonical type to consider.
15718///
15719/// @param candidate_type the candidate type that is being
15720/// canonicalized, and thus compared to @p canonical_type.
15721///
15722/// @return true iff @p canonical_type compares equal to @p
15723/// candidate_type.
15724static bool
15725compare_canonical_type_against_candidate(const type_base* canonical_type,
15726 const type_base* candidate_type)
15727{
15728 return compare_canonical_type_against_candidate(*canonical_type,
15729 *candidate_type);
15730}
15731
15732/// Compare a canonical type against a candidate canonical type.
15733///
15734/// This is ultimately a sub-routine of the
15735/// type_base::get_canonical_type_for().
15736///
15737/// The goal of this function is to ease debugging because it can be
15738/// called from within type_base::get_canonical_type_for() from the
15739/// prompt of the debugger (with some breakpoint appropriately set) to
15740/// debug the comparison that happens during type canonicalization,
15741/// between a candidate type being canonicalized, and an existing
15742/// canonical type that is registered in the system, in as returned by
15743/// environment::get_canonical_types()
15744///
15745/// @param canonical_type the canonical type to consider.
15746///
15747/// @param candidate_type the candidate type that is being
15748/// canonicalized, and thus compared to @p canonical_type.
15749///
15750/// @return true iff @p canonical_type compares equal to @p
15751/// candidate_type.
15752static bool
15753compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15754 const type_base_sptr& candidate_type)
15755{
15756 return compare_canonical_type_against_candidate(canonical_type.get(),
15757 candidate_type.get());
15758}
15759
15760/// Test if a candidate for type canonicalization coming from ABIXML
15761/// matches a canonical type by first looking at their hash values.
15762///
15763/// If the two hash values are equal then the candidate is
15764/// structurally compared to the canonical type. If the two hashes
15765/// are different then the two types are considered different and the
15766/// function returns nullptr.
15767///
15768/// If the candidate doesn't come from ABIXML then the function
15769/// returns nullptr.
15770///
15771/// @param cncls the vector of canonical types to consider.
15772///
15773/// @param type the candidate to consider for canonicalization.
15774///
15775/// @return the canonical type from @p cncls that matches the
15776/// candidate @p type.
15777static type_base_sptr
15778candidate_matches_a_canonical_type_hash(const vector<type_base_sptr>& cncls,
15779 type_base& type)
15780{
15781 if (type.get_corpus()
15782 && type.get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
15783 && peek_hash_value(type))
15784 {
15785 // The candidate type comes from ABIXML and does have a stashed
15786 // hash value coming from the ABIXML.
15787
15788 // Let's see if we find a potential canonical type whose hash
15789 // matches the stashed hash and whose canonical type index
15790 // matches it too.
15791 for (const auto& c : cncls)
15792 if (peek_hash_value(type) == peek_hash_value(*c))
15794 // We found a potential canonical type which hash matches the
15795 // stashed hash of the candidate type. Let's compare them to
15796 // see if they match.
15797 if (compare_canonical_type_against_candidate(*c, type))
15798 return c;
15799
15800 // Let's do the same things, but just consideing hash values.
15801 for (const auto& c : cncls)
15802 if (peek_hash_value(type) == peek_hash_value(*c))
15803 // We found a potential canonical type which hash matches the
15804 // stashed hash of the candidate type. Let's compare them to
15805 // see if they match.
15806 if (compare_canonical_type_against_candidate(*c, type))
15807 return c;
15808 }
15809
15810 return nullptr;
15811}
15812
15813/// Test if we should attempt to compute a hash value for a given
15814/// type.
15815///
15816/// For now this function returns true only for types originating from
15817/// ELF. For types originating from ABIXML, for instance, the
15818/// function return false, meaning that types originating from ABIXML
15819/// should NOT be hashed.
15820///
15821/// @param t the type to consider.
15822///
15823/// @return true iff @p type should be considered for hashing.
15824bool
15826{
15827 if (t.get_corpus()
15828 && (t.get_corpus()->get_origin() & corpus::ELF_ORIGIN))
15829 return true;
15830 return false;
15831}
15832
15833/// Compute the canonical type for a given instance of @ref type_base.
15834///
15835/// Consider two types T and T'. The canonical type of T, denoted
15836/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
15837/// otherwise, to compare two types, one just needs to compare their
15838/// canonical types using pointer equality. That makes type
15839/// comparison faster than the structural comparison performed by the
15840/// abigail::ir::equals() overloads.
15841///
15842/// If there is not yet any canonical type for @p t, then @p t is its
15843/// own canonical type. Otherwise, this function returns the
15844/// canonical type of @p t which is the canonical type that has the
15845/// same hash value as @p t and that structurally equals @p t. Note
15846/// that after invoking this function, the life time of the returned
15847/// canonical time is then equals to the life time of the current
15848/// process.
15849///
15850/// @param t a smart pointer to instance of @ref type_base we want to
15851/// compute a canonical type for.
15852///
15853/// @return the canonical type for the current instance of @ref
15854/// type_base.
15855type_base_sptr
15856type_base::get_canonical_type_for(type_base_sptr t)
15857{
15858 if (!t)
15859 return t;
15860
15861 environment& env = const_cast<environment&>(t->get_environment());
15862
15864 // This type should not be canonicalized!
15865 return type_base_sptr();
15866
15867 if (is_decl(t))
15869
15870 // Look through decl-only types (classes, unions and enums)
15871 bool decl_only_class_equals_definition =
15873
15874 class_or_union_sptr class_or_union = is_class_or_union_type(t);
15875
15876 // In the context of types from C++ or languages where we assume the
15877 // "One Definition Rule", we assume that a declaration-only
15878 // non-anonymous class equals all fully defined classes of the same
15879 // name.
15880 //
15881 // Otherwise, all classes, including declaration-only classes are
15882 // canonicalized and only canonical comparison is going to be used
15883 // in the system.
15884 if (decl_only_class_equals_definition)
15885 if (class_or_union)
15887 return type_base_sptr();
15888
15889 class_decl_sptr is_class = is_class_type(t);
15890 if (t->get_canonical_type())
15891 return t->get_canonical_type();
15892
15893 // For classes and union, ensure that an anonymous class doesn't
15894 // have a linkage name. If it does in the future, then me must be
15895 // mindful that the linkage name respects the type identity
15896 // constraints which states that "if two linkage names are different
15897 // then the two types are different".
15901
15902 // We want the pretty representation of the type, but for an
15903 // internal use, not for a user-facing purpose.
15904 //
15905 // If two classe types Foo are declared, one as a class and the
15906 // other as a struct, but are otherwise equivalent, we want their
15907 // pretty representation to be the same. Hence the 'internal'
15908 // argument of ir::get_pretty_representation() is set to true here.
15909 // So in this case, the pretty representation of Foo is going to be
15910 // "class Foo", regardless of its struct-ness. This also applies to
15911 // composite types which would have "class Foo" as a sub-type.
15912 string repr = t->get_cached_pretty_representation(/*internal=*/true);
15913
15914 // If 't' already has a canonical type 'inside' its corpus
15915 // (t_corpus), then this variable is going to contain that canonical
15916 // type.
15917 type_base_sptr canonical_type_present_in_corpus;
15920
15921 type_base_sptr result;
15922 environment::canonical_types_map_type::iterator i = types.find(repr);
15923
15924 if (i == types.end())
15925 {
15926 vector<type_base_sptr> v;
15927 v.push_back(t);
15928 types[repr] = v;
15929 result = t;
15930 }
15931 else
15932 {
15933 vector<type_base_sptr> &v = i->second;
15934 // Look at the canonical types and if the current candidate type
15935 // coming from abixml has the same hash as one of the canonical
15936 // types, then compare the current candidate with the one with a
15937 // matching hash.
15938 result = candidate_matches_a_canonical_type_hash(v, *t);
15939
15940 // Let's compare 't' structurally (i.e, compare its sub-types
15941 // recursively) against the canonical types of the system. If it
15942 // equals a given canonical type C, then it means C is the
15943 // canonical type of 't'. Otherwise, if 't' is different from
15944 // all the canonical types of the system, then it means 't' is a
15945 // canonical type itself.
15946 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15947 !result && it != v.rend();
15948 ++it)
15949 {
15950 bool equal = compare_canonical_type_against_candidate(*it, t);
15951 if (equal)
15952 {
15953 result = *it;
15954 break;
15955 }
15956 }
15957#ifdef WITH_DEBUG_SELF_COMPARISON
15958 if (env.self_comparison_debug_is_on())
15959 {
15960 // So we are debugging the canonicalization process,
15961 // possibly via the use of 'abidw --debug-abidiff <binary>'.
15962 corpus_sptr corp1, corp2;
15963 env.get_self_comparison_debug_inputs(corp1, corp2);
15964 if (corp1 && corp2 && type_originates_from_corpus(t, corp2)
15965 && corp1->get_origin() != corp2->get_origin()
15966 && corp2->get_origin() & corpus::NATIVE_XML_ORIGIN)
15967 {
15968 // If 't' comes from the second corpus, then it *must*
15969 // be equal to its matching canonical type coming from
15970 // the first corpus because the second corpus is the
15971 // abixml representation of the first corpus. In other
15972 // words, all types coming from the second corpus must
15973 // have canonical types coming from the first corpus.
15974 if (result)
15975 {
15976 if (!env.priv_->
15977 check_canonical_type_from_abixml_during_self_comp(t,
15978 result))
15979 {
15980 // The canonical type of the type re-read from abixml
15981 // type doesn't match the canonical type that was
15982 // initially serialized down.
15983 uintptr_t should_have_canonical_type = 0;
15984 string type_id = env.get_type_id_from_type(t.get());
15985 if (type_id.empty())
15986 type_id = "type-id-<not-found>";
15987 else
15988 should_have_canonical_type =
15989 env.get_canonical_type_from_type_id(type_id.c_str());
15990 std::cerr << "error: wrong canonical type for '"
15991 << repr
15992 << "' / type: @"
15993 << std::hex
15994 << t.get()
15995 << "/ canon: @"
15996 << result.get()
15997 << ", type-id: '"
15998 << type_id
15999 << "'. Should have had canonical type: "
16000 << std::hex
16001 << should_have_canonical_type
16002 << std::dec
16003 << std::endl;
16004 }
16005 }
16006 else //!result
16007 {
16008 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
16009 string type_id = env.get_type_id_from_pointer(ptr_val);
16010 if (type_id.empty())
16011 type_id = "type-id-<not-found>";
16012 // We are in the case where 't' is different from all
16013 // the canonical types of the same name that come from
16014 // the first corpus.
16015 //
16016 // If 't' indeed comes from the second corpus then this
16017 // clearly is a canonicalization failure.
16018 //
16019 // There was a problem either during the serialization
16020 // of 't' into abixml, or during the de-serialization
16021 // from abixml into abigail::ir. Further debugging is
16022 // needed to determine what that root cause problem is.
16023 //
16024 // Note that the first canonicalization problem of this
16025 // kind must be fixed before looking at the subsequent
16026 // ones, because the later might well just be
16027 // consequences of the former.
16028 std::cerr << "error: wrong induced canonical type for '"
16029 << repr
16030 << "' from second corpus"
16031 << ", ptr: " << std::hex << t.get()
16032 << " type-id: " << type_id
16033 << " /hash="
16034 << *t->hash_value()
16035 << std::dec
16036 << std::endl;
16037 }
16038 }
16039 if (result)
16040 {
16041 if (!is_type_decl(t))
16042 if (hash_t t_hash = peek_hash_value(*t))
16043 if (hash_t result_hash = peek_hash_value(*result))
16044 if (t_hash != result_hash)
16045 {
16046 std::cerr << "error: type hash mismatch"
16047 << " between type: '"
16048 << repr
16049 << "' @ "
16050 << std::hex
16051 << t.get()
16052 << "/hash="
16053 << *t->hash_value()
16054 << " and its computed canonical type @"
16055 << std::hex
16056 << result.get()
16057 << "/hash="
16058 << std::hex
16059 << *result->hash_value()
16060 << std::dec
16061 << std::endl;
16062 }
16063 }
16064 }
16065#endif //WITH_DEBUG_SELF_COMPARISON
16066
16067 if (!result)
16068 {
16069 v.push_back(t);
16070 result = t;
16071 // we need to generate a canonical type index to sort these
16072 // types that have the same representation and potentially
16073 // same hash value but are canonically different.
16074 t->priv_->canonical_type_index = v.size();
16075 }
16076 }
16077
16078 return result;
16079}
16080
16081/// This method is invoked automatically right after the current
16082/// instance of @ref class_decl has been canonicalized.
16083void
16085{}
16086
16087/// This is a subroutine of the canonicalize() function.
16088///
16089/// When the canonical type C of type T has just been computed, there
16090/// can be cases where T has member functions that C doesn't have.
16091///
16092/// This is possible because non virtual member functions are not
16093/// taken in account when comparing two types.
16094///
16095/// In that case, this function updates C so that it contains the
16096/// member functions.
16097///
16098/// There can also be cases where C has a method M which is not linked
16099/// to any underlying symbol, whereas in T, M is to link to an
16100/// underlying symbol. In that case, this function updates M in C so
16101/// that it's linked to the same underlying symbol as for M in T.
16102static void
16103maybe_adjust_canonical_type(const type_base_sptr& canonical,
16104 const type_base_sptr& type)
16105{
16106 if (type->get_naked_canonical_type())
16107 return;
16108
16109 class_decl_sptr canonical_class = is_class_type(canonical);
16110
16111 if (class_decl_sptr cl = is_class_type(type))
16112 {
16114 if (canonical_class
16115 && canonical_class.get() != cl.get())
16116 {
16117 // Set symbols of member functions that might be missing
16118 // theirs.
16119 for (class_decl::member_functions::const_iterator i =
16120 cl->get_member_functions().begin();
16121 i != cl->get_member_functions().end();
16122 ++i)
16123 if ((*i)->get_symbol())
16124 {
16125 if (method_decl *m = canonical_class->
16126 find_member_function((*i)->get_linkage_name()))
16127 {
16128 elf_symbol_sptr s1 = (*i)->get_symbol();
16129 if (s1 && !m->get_symbol())
16130 // Method 'm' in the canonical type is not
16131 // linked to the underlying symbol of '*i'.
16132 // Let's link it now. have th
16133 m->set_symbol(s1);
16134 }
16135 else
16136 if (canonical_class->get_corpus()
16137 && cl->get_corpus()
16138 && (cl->get_corpus() == canonical_class->get_corpus()))
16139 // There is a member function defined and publicly
16140 // exported in the other class and the canonical
16141 // class doesn't have that member function. This
16142 // should not have happened! For instance, the
16143 // DWARF reader does merge the member functions of
16144 // classes having the same name so that all of them
16145 // end-up having the same member functions. What's
16146 // going on here?
16148 }
16149
16150 // Set symbols of static data members that might be missing
16151 // theirs.
16152 for (const auto& data_member : cl->get_data_members())
16153 {
16154 if (!get_member_is_static(data_member))
16155 continue;
16156 elf_symbol_sptr sym = data_member->get_symbol();
16157 if (!sym)
16158 continue;
16159 const auto& canonical_data_member =
16160 canonical_class->find_data_member(data_member->get_name());
16161 if (!canonical_data_member)
16162 // Hmmh, maybe we
16163 // should consider
16164 // static data members
16165 // when comparing two
16166 // classes for the
16167 // purpose of type
16168 // canonicalization?
16169 continue;
16170 if (!canonical_data_member->get_symbol())
16171 canonical_data_member->set_symbol(sym);
16172 }
16173 }
16174 }
16175
16176 // Make sure the virtual member functions with exported symbols are
16177 // all added to the set of exported functions of the corpus.
16178
16179 // If we are looking at a non-canonicalized class (for instance, a
16180 // decl-only class that has virtual member functions), let's pretend
16181 // it does have a canonical class so that we can perform the
16182 // necessary virtual member function adjustments
16183 if (class_decl_sptr cl = is_class_type(type))
16185 {
16186 ABG_ASSERT(!canonical_class);
16187 canonical_class = cl;
16188 }
16189
16190 if (canonical_class)
16191 {
16192 if (auto abi_corpus = canonical_class->get_corpus())
16193 {
16194 for (auto& fn : canonical_class->get_member_functions())
16195 {
16196 if (elf_symbol_sptr sym = fn->get_symbol())
16197 {
16198 if (sym->is_defined() && sym->is_public())
16199 {
16200 fn->set_is_in_public_symbol_table(true);
16201 auto b = abi_corpus->get_exported_decls_builder();
16202 b->maybe_add_fn_to_exported_fns(fn.get());
16203 }
16204 else if (!sym->is_defined())
16205 abi_corpus->get_undefined_functions().insert(fn.get());
16206 }
16207 }
16208 }
16209 }
16210
16211 // If an artificial function type equals a non-artfificial one in
16212 // the system, then the canonical type of both should be deemed
16213 // non-artificial. This is important because only non-artificial
16214 // canonical function types are emitted out into abixml, so if don't
16215 // do this we risk missing to emit some function types.
16216 if (is_function_type(type))
16217 if (type->get_is_artificial() != canonical->get_is_artificial())
16218 canonical->set_is_artificial(false);
16219}
16220
16221/// Compute the canonical type of a given type.
16222///
16223/// It means that after invoking this function, comparing the intance
16224/// instance @ref type_base and another one (on which
16225/// type_base::enable_canonical_equality() would have been invoked as
16226/// well) is performed by just comparing the pointer values of the
16227/// canonical types of both types. That equality comparison is
16228/// supposedly faster than structural comparison of the types.
16229///
16230/// @param t a smart pointer to the instance of @ref type_base for
16231/// which to compute the canonical type. After this call,
16232/// t->get_canonical_type() will return the newly computed canonical
16233/// type.
16234///
16235/// @param do_log if true then logs are emitted about canonicalization
16236/// progress.
16237///
16238/// @param show_stats if true and if @p do_log is true as well, then
16239/// more detailed logs are emitted about canonicalization.
16240///
16241/// @return the canonical type computed for @p t.
16242type_base_sptr
16243canonicalize(type_base_sptr t, bool do_log, bool show_stats)
16244{
16245 if (!t)
16246 return t;
16247
16248 if (t->get_canonical_type())
16249 return t->get_canonical_type();
16250
16251 if (do_log && show_stats)
16252 std::cerr << "Canonicalization of type '"
16253 << t->get_pretty_representation(true, true)
16254 << "/@#" << std::hex << t.get() << ": ";
16255
16257
16258 if (do_log && show_stats)
16259 tmr.start();
16260 type_base_sptr canonical = type_base::get_canonical_type_for(t);
16261
16262 if (do_log && show_stats)
16263 tmr.stop();
16264
16265 if (do_log && show_stats)
16266 std::cerr << tmr << "\n";
16267
16268 maybe_adjust_canonical_type(canonical, t);
16269
16270 t->priv_->canonical_type = canonical;
16271 t->priv_->naked_canonical_type = canonical.get();
16272
16273 if (canonical)
16274 if (!t->priv_->canonical_type_index)
16275 t->priv_->canonical_type_index = canonical->priv_->canonical_type_index;
16276
16277 if (class_decl_sptr cl = is_class_type(t))
16278 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
16279 if ((canonical = d->get_canonical_type()))
16280 {
16281 d->priv_->canonical_type = canonical;
16282 d->priv_->naked_canonical_type = canonical.get();
16283 }
16284
16285 if (canonical)
16286 {
16287 if (decl_base_sptr d = is_decl_slow(canonical))
16288 {
16289 scope_decl *scope = d->get_scope();
16290 // Add the canonical type to the set of canonical types
16291 // belonging to its scope.
16292 if (scope)
16293 {
16294 if (is_type(scope))
16295 // The scope in question is itself a type (e.g, a class
16296 // or union). Let's call that type ST. We want to add
16297 // 'canonical' to the set of canonical types belonging
16298 // to ST.
16299 if (type_base_sptr c = is_type(scope)->get_canonical_type())
16300 // We want to add 'canonical' to the set of
16301 // canonical types belonging to the canonical type
16302 // of ST. That way, just looking at the canonical
16303 // type of ST is enough to get the types that belong
16304 // to the scope of the class of equivalence of ST.
16305 scope = is_scope_decl(is_decl(c)).get();
16306 scope->get_canonical_types().insert(canonical);
16307 }
16308 // else, if the type doesn't have a scope, it's not meant to be
16309 // emitted. This can be the case for the result of the
16310 // function strip_typedef, for instance.
16311 }
16312 }
16313
16314 t->on_canonical_type_set();
16315 return canonical;
16316}
16317
16318/// Set the definition of this declaration-only @ref decl_base.
16319///
16320/// @param d the new definition to set.
16321void
16323{
16325 priv_->definition_of_declaration_ = d;
16326 if (type_base *t = is_type(this))
16327 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
16328 t->priv_->canonical_type = canonical_type;
16329
16330 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
16331}
16332
16333/// The constructor of @ref type_base.
16334///
16335/// @param s the size of the type, in bits.
16336///
16337/// @param a the alignment of the type, in bits.
16338type_base::type_base(const environment& e, size_t s, size_t a)
16339 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
16340 priv_(new priv(s, a))
16341{}
16342
16343/// Return the hash value of the current IR node.
16344///
16345/// Note that upon the first invocation, this member functions
16346/// computes the hash value and returns it. Subsequent invocations
16347/// just return the hash value that was previously calculated.
16348///
16349/// @return the hash value of the current IR node.
16350hash_t
16352{
16353 type_base::hash do_hash;
16354 return do_hash(this);
16355}
16356
16357/// Getter of the canonical type of the current instance of @ref
16358/// type_base.
16359///
16360/// @return a smart pointer to the canonical type of the current
16361/// intance of @ref type_base, or an empty smart pointer if the
16362/// current instance of @ref type_base doesn't have any canonical
16363/// type.
16364type_base_sptr
16366{return priv_->canonical_type.lock();}
16367
16368/// Getter of the canonical type pointer.
16369///
16370/// Note that this function doesn't return a smart pointer, but rather
16371/// the underlying pointer managed by the smart pointer. So it's as
16372/// fast as possible. This getter is to be used in code paths that
16373/// are proven to be performance hot spots; especially, when comparing
16374/// sensitive types like class, function, pointers and reference
16375/// types. Those are compared extremely frequently and thus, their
16376/// accessing the canonical type must be fast.
16377///
16378/// @return the canonical type pointer, not managed by a smart
16379/// pointer.
16380type_base*
16382{return priv_->naked_canonical_type;}
16383
16384/// Get the pretty representation of the current type.
16385///
16386/// The pretty representation is retrieved from a cache. If the cache
16387/// is empty, this function computes the pretty representation, put it
16388/// in the cache and returns it.
16389///
16390/// Please note that if this function is called too early in the life
16391/// cycle of the type (before the type is fully constructed), then the
16392/// pretty representation that is cached is going to represent a
16393/// non-complete (and thus wrong) representation of the type. Thus
16394/// this function must be called only once the type is fully
16395/// constructed.
16396///
16397/// @param internal if true, then the pretty representation is to be
16398/// used for purpuses that are internal to the libabigail library
16399/// itself. If you don't know what this means, then you probably
16400/// should set this parameter to "false".
16401///
16402/// @return a reference to a cached @ref interned_string holding the
16403/// pretty representation of the current type.
16404const interned_string&
16406{
16407 if (internal)
16408 {
16409 if (priv_->internal_cached_repr_.empty())
16410 {
16411 string r = ir::get_pretty_representation(this, internal);
16412 priv_->internal_cached_repr_ = get_environment().intern(r);
16413 }
16414 return priv_->internal_cached_repr_;
16415 }
16416
16417 if (priv_->cached_repr_.empty())
16418 {
16419 string r = ir::get_pretty_representation(this, internal);
16420 priv_->cached_repr_ = get_environment().intern(r);
16421 }
16422
16423 return priv_->cached_repr_;
16424}
16425
16426/// Compares two instances of @ref type_base.
16427///
16428/// If the two intances are different, set a bitfield to give some
16429/// insight about the kind of differences there are.
16430///
16431/// @param l the first artifact of the comparison.
16432///
16433/// @param r the second artifact of the comparison.
16434///
16435/// @param k a pointer to a bitfield that gives information about the
16436/// kind of changes there are between @p l and @p r. This one is set
16437/// iff @p is non-null and if the function returns false.
16438///
16439/// Please note that setting k to a non-null value does have a
16440/// negative performance impact because even if @p l and @p r are not
16441/// equal, the function keeps up the comparison in order to determine
16442/// the different kinds of ways in which they are different.
16443///
16444/// @return true if @p l equals @p r, false otherwise.
16445bool
16446equals(const type_base& l, const type_base& r, change_kind* k)
16447{
16448 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
16450 if (!result)
16451 if (k)
16453 ABG_RETURN(result);
16454}
16455
16456/// Return true iff both type declarations are equal.
16457///
16458/// Note that this doesn't test if the scopes of both types are equal.
16459bool
16461{return equals(*this, other, 0);}
16462
16463/// Inequality operator.
16464///
16465///@param other the instance of @ref type_base to compare the current
16466/// instance against.
16467///
16468/// @return true iff the current instance is different from @p other.
16469bool
16471{return !operator==(other);}
16472
16473/// Setter for the size of the type.
16474///
16475/// @param s the new size -- in bits.
16476void
16478{priv_->size_in_bits = s;}
16479
16480/// Getter for the size of the type.
16481///
16482/// @return the size in bits of the type.
16483size_t
16485{return priv_->size_in_bits;}
16486
16487/// Setter for the alignment of the type.
16488///
16489/// @param a the new alignment -- in bits.
16490void
16492{priv_->alignment_in_bits = a;}
16493
16494/// Getter for the alignment of the type.
16495///
16496/// @return the alignment of the type in bits.
16497size_t
16499{return priv_->alignment_in_bits;}
16500
16501/// Default implementation of traversal for types. This function does
16502/// nothing. It must be implemented by every single new type that is
16503/// written.
16504///
16505/// Please look at e.g, class_decl::traverse() for an example of how
16506/// to implement this.
16507///
16508/// @param v the visitor used to visit the type.
16509bool
16511{
16512 if (v.type_node_has_been_visited(this))
16513 return true;
16514
16515 v.visit_begin(this);
16516 bool result = v.visit_end(this);
16518
16519 return result;
16520}
16521
16522type_base::~type_base()
16523{delete priv_;}
16524
16525// </type_base definitions>
16526
16527// <real_type definitions>
16528
16529/// Bitwise OR operator for real_type::modifiers_type.
16530///
16531/// @param l the left-hand side operand.
16532///
16533/// @param r the right-hand side operand.
16534///
16535/// @return the result of the bitwise OR.
16538{
16539 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16540 |
16541 static_cast<unsigned>(r));
16542}
16543
16544/// Bitwise AND 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 AND.
16553{
16554 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16555 &
16556 static_cast<unsigned>(r));
16557}
16558
16559/// Bitwise one's complement 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 one's complement operator.
16568{
16569 return static_cast<real_type::modifiers_type>(~static_cast<unsigned>(l));
16570}
16571
16572/// Bitwise |= operator for real_type::modifiers_type.
16573///
16574/// @param l the left-hand side operand.
16575///
16576/// @param r the right-hand side operand.
16577///
16578/// @return the result of the bitwise |=.
16581{
16582 l = l | r;
16583 return l;
16584}
16585
16586/// Bitwise &= operator for real_type::modifiers_type.
16587///
16588/// @param l the left-hand side operand.
16589///
16590/// @param r the right-hand side operand.
16591///
16592/// @return the result of the bitwise &=.
16595{
16596 l = l & r;
16597 return l;
16598}
16599
16600/// Parse a word containing one real type modifier.
16601///
16602/// A word is considered to be a string of characters that doesn't
16603/// contain any white space.
16604///
16605/// @param word the word to parse. It is considered to be a string of
16606/// characters that doesn't contain any white space.
16607///
16608/// @param modifiers out parameter. It's set by this function to the
16609/// parsed modifier iff the function returned true.
16610///
16611/// @return true iff @word was successfully parsed.
16612static bool
16613parse_real_type_modifier(const string& word,
16614 real_type::modifiers_type &modifiers)
16615{
16616 if (word == "signed")
16617 modifiers |= real_type::SIGNED_MODIFIER;
16618 else if (word == "unsigned")
16619 modifiers |= real_type::UNSIGNED_MODIFIER;
16620 else if (word == "short")
16621 modifiers |= real_type::SHORT_MODIFIER;
16622 else if (word == "long")
16623 modifiers |= real_type::LONG_MODIFIER;
16624 else if (word == "long long")
16625 modifiers |= real_type::LONG_LONG_MODIFIER;
16626 else
16627 return false;
16628
16629 return true;
16630}
16631
16632/// Parse a base type of a real type from a string.
16633///
16634/// @param type_name the type name to parse.
16635///
16636/// @param base out parameter. This is set to the resulting base type
16637/// parsed, iff the function returned true.
16638///
16639/// @return true iff the function could successfully parse the base
16640/// type.
16641static bool
16642parse_base_real_type(const string& type_name,
16644{
16645 if (type_name == "int")
16647 else if (type_name == "char")
16649 else if (type_name == "bool" || type_name == "_Bool")
16651 else if (type_name == "double")
16653 else if (type_name =="float")
16655 else if (type_name == "char16_t")
16657 else if (type_name == "char32_t")
16659 else if (type_name == "wchar_t")
16661 else if (type_name == "__ARRAY_SIZE_TYPE__")
16663 else if (type_name == "sizetype")
16664 base = real_type::SIZE_BASE_TYPE;
16665 else if (type_name == "ssizetype")
16666 base = real_type::SSIZE_BASE_TYPE;
16667 else if (type_name == "bitsizetype")
16668 base = real_type::BIT_SIZE_BASE_TYPE;
16669 else if (type_name == "sbitsizetype")
16670 base = real_type::SBIT_SIZE_BASE_TYPE;
16671 else
16672 return false;
16673
16674 return true;
16675}
16676
16677/// Parse a real type from a string.
16678///
16679/// @param type_name the string containing the real type to parse.
16680///
16681/// @param base out parameter. Is set by this function to the base
16682/// type of the real type, iff the function returned true.
16683///
16684/// @param modifiers out parameter If set by this function to the
16685/// modifier of the real type, iff the function returned true.
16686///
16687/// @return true iff the function could parse a real type from @p
16688/// type_name.
16689static bool
16690parse_real_type(const string& type_name,
16692 real_type::modifiers_type& modifiers)
16693{
16694 string input = type_name;
16695 string::size_type len = input.length();
16696 string::size_type cur_pos = 0, prev_pos = 0;
16697 string cur_word, prev_word;
16698 bool ok = false;
16699
16700 while (cur_pos < len)
16701 {
16702 if (cur_pos < len && isspace(input[cur_pos]))
16703 do
16704 ++cur_pos;
16705 while (cur_pos < len && isspace(input[cur_pos]));
16706
16707 prev_pos = cur_pos;
16708 cur_pos = input.find(' ', prev_pos);
16709 prev_word = cur_word;
16710 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16711
16712 if (cur_pos < len
16713 && cur_word == "long"
16714 && prev_word != "long")
16715 {
16716 if (cur_pos < len && isspace(input[cur_pos]))
16717 do
16718 ++cur_pos;
16719 while (cur_pos < len && isspace(input[cur_pos]));
16720 prev_pos = cur_pos;
16721
16722 cur_pos = input.find(' ', prev_pos);
16723 string saved_prev_word = prev_word;
16724 prev_word = cur_word;
16725 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16726 if (cur_word == "long")
16727 cur_word = "long long";
16728 else
16729 {
16730 cur_pos = prev_pos;
16731 cur_word = prev_word;
16732 prev_word = saved_prev_word;
16733 }
16734 }
16735
16736 if (!parse_real_type_modifier(cur_word, modifiers))
16737 {
16738 if (!parse_base_real_type(cur_word, base))
16739 return false;
16740 else
16741 ok = true;
16742 }
16743 else
16744 ok = true;
16745 }
16746
16747 return ok;
16748}
16749
16750/// Parse a real type from a string.
16751///
16752/// @param str the string containing the real type to parse.
16753///
16754///@param type the resulting @ref real_type. Is set to the result
16755///of the parse, iff the function returns true.
16756///
16757/// @return true iff the function could parse a real type from @p
16758/// str.
16759bool
16760parse_real_type(const string& str, real_type& type)
16761{
16763 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16764
16765 if (!parse_real_type(str, base_type, modifiers))
16766 return false;
16767
16768 // So this is a real type.
16769 real_type int_type(base_type, modifiers);
16770 type = int_type;
16771 return true;
16772}
16773
16774/// Default constructor of the @ref real_type.
16776 : base_(INT_BASE_TYPE),
16777 modifiers_(NO_MODIFIER)
16778{}
16779
16780/// Constructor of the @ref real_type.
16781///
16782/// @param b the base type of the real type.
16783///
16784/// @param m the modifiers of the real type.
16786 : base_(b), modifiers_(m)
16787{}
16788
16789/// Constructor of the @ref real_type.
16790///
16791/// @param the name of the real type to parse to initialize the
16792/// current instance of @ref real_type.
16793real_type::real_type(const string& type_name)
16794 : base_(INT_BASE_TYPE),
16795 modifiers_(NO_MODIFIER)
16796{
16797 bool could_parse = parse_real_type(type_name, base_, modifiers_);
16798 ABG_ASSERT(could_parse);
16799}
16800
16801/// Getter of the base type of the @ref real_type.
16802///
16803/// @return the base type of the @ref real_type.
16806{return base_;}
16807
16808/// Getter of the modifiers bitmap of the @ref real_type.
16809///
16810/// @return the modifiers bitmap of the @ref real_type.
16813{return modifiers_;}
16814
16815/// Setter of the modifiers bitmap of the @ref real_type.
16816///
16817/// @param m the new modifiers.
16818void
16820{modifiers_ = m;}
16821
16822/// Equality operator for the @ref real_type.
16823///
16824/// @param other the other real type to compare against.
16825///
16826/// @return true iff @p other equals the current instance of @ref
16827/// real_type.
16828bool
16830{return base_ == other.base_ && modifiers_ == other.modifiers_;}
16831
16832/// Return the string representation of the current instance of @ref
16833/// real_type.
16834///
16835/// @param internal if true the string representation is to be used
16836/// for internal purposes. In general, it means it's for type
16837/// canonicalization purposes.
16838///
16839/// @return the string representation of the current instance of @ref
16840/// real_type.
16841string
16842real_type::to_string(bool internal) const
16843{
16844 string result;
16845
16846 // Look at modifiers ...
16847 if (modifiers_ & SIGNED_MODIFIER)
16848 result += "signed ";
16849 if (modifiers_ & UNSIGNED_MODIFIER)
16850 result += "unsigned ";
16851 if (!internal)
16852 {
16853 // For canonicalization purposes, we won't emit the "short, long, or
16854 // long long" modifiers. This is because on some platforms, "long
16855 // int" and "long long int" might have the same size. In those
16856 // cases, we want the two types to be equivalent if they have the
16857 // same size. If they don't have the same internal string
16858 // representation, they'd automatically have different canonical
16859 // types and thus be canonically different.
16860 if (modifiers_ & SHORT_MODIFIER)
16861 result += "short ";
16862 if (modifiers_ & LONG_MODIFIER)
16863 result += "long ";
16864 if (modifiers_ & LONG_LONG_MODIFIER)
16865 result += "long long ";
16866 }
16867
16868 // ... and look at base types.
16869 if (base_ == INT_BASE_TYPE)
16870 result += "int";
16871 else if (base_ == CHAR_BASE_TYPE)
16872 result += "char";
16873 else if (base_ == BOOL_BASE_TYPE)
16874 result += "bool";
16875 else if (base_ == DOUBLE_BASE_TYPE)
16876 result += "double";
16877 else if (base_ == FLOAT_BASE_TYPE)
16878 result += "float";
16879 else if (base_ == CHAR16_T_BASE_TYPE)
16880 result += "char16_t";
16881 else if (base_ == CHAR32_T_BASE_TYPE)
16882 result += "char32_t";
16883 else if (base_ == WCHAR_T_BASE_TYPE)
16884 result += "wchar_t";
16885 else if (base_ == ARRAY_SIZE_BASE_TYPE)
16886 result += "__ARRAY_SIZE_TYPE__";
16887 else if (base_ == SIZE_BASE_TYPE)
16888 result += "sizetype";
16889 else if (base_ == SSIZE_BASE_TYPE)
16890 result += "ssizetype";
16891 else if (base_ == BIT_SIZE_BASE_TYPE)
16892 result += "bitsizetype";
16893 else if (base_ == SBIT_SIZE_BASE_TYPE)
16894 result += "sbitsizetype";
16895 return result;
16896}
16897
16898/// Convert the current instance of @ref real_type into its string
16899/// representation.
16900///
16901/// @return the string representation of the current instance of @ref
16902/// real_type.
16903real_type::operator string() const
16904{return to_string();}
16905
16906// </real_type definitions>
16907
16908//<type_decl definitions>
16909
16910/// Constructor.
16911///
16912/// @param env the environment we are operating from.
16913///
16914/// @param name the name of the type declaration.
16915///
16916/// @param size_in_bits the size of the current type_decl, in bits.
16917///
16918/// @param alignment_in_bits the alignment of the current typ, in
16919/// bits.
16920///
16921/// @param locus the source location of the current type declaration.
16922///
16923/// @param linkage_name the linkage_name of the current type declaration.
16924///
16925/// @param vis the visibility of the type declaration.
16926type_decl::type_decl(const environment& env,
16927 const string& name,
16928 size_t size_in_bits,
16929 size_t alignment_in_bits,
16930 const location& locus,
16931 const string& linkage_name,
16932 visibility vis)
16933
16934 : type_or_decl_base(env,
16935 BASIC_TYPE
16936 | ABSTRACT_TYPE_BASE
16937 | ABSTRACT_DECL_BASE),
16938 decl_base(env, name, locus, linkage_name, vis),
16939 type_base(env, size_in_bits, alignment_in_bits)
16940{
16942
16944 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16945 real_type int_type(base_type, modifiers);
16946 if (parse_real_type(name, int_type))
16947 {
16948 // Convert the real_type into its canonical string
16949 // representation.
16950 string real_type_name = int_type;
16951
16952 // Set the name of this type_decl to the canonical string
16953 // representation above
16954 set_name(real_type_name);
16956
16957 if (!get_linkage_name().empty())
16958 set_linkage_name(real_type_name);
16959 }
16960}
16961
16962/// Return the hash value of the current IR node.
16963///
16964/// Note that upon the first invocation, this member functions
16965/// computes the hash value and returns it. Subsequent invocations
16966/// just return the hash value that was previously calculated.
16967///
16968/// @return the hash value of the current IR node.
16969hash_t
16971{
16973 return h;
16974}
16975
16976/// Compares two instances of @ref type_decl.
16977///
16978/// If the two intances are different, set a bitfield to give some
16979/// insight about the kind of differences there are.
16980///
16981/// @param l the first artifact of the comparison.
16982///
16983/// @param r the second artifact of the comparison.
16984///
16985/// @param k a pointer to a bitfield that gives information about the
16986/// kind of changes there are between @p l and @p r. This one is set
16987/// iff @p k is non-null and the function returns false.
16988///
16989/// Please note that setting k to a non-null value does have a
16990/// negative performance impact because even if @p l and @p r are not
16991/// equal, the function keeps up the comparison in order to determine
16992/// the different kinds of ways in which they are different.
16993///
16994/// @return true if @p l equals @p r, false otherwise.
16995bool
16996equals(const type_decl& l, const type_decl& r, change_kind* k)
16997{
16998 bool result = false;
16999
17000 // Consider the types as decls to compare their decls-related
17001 // properties.
17002 result = equals(static_cast<const decl_base&>(l),
17003 static_cast<const decl_base&>(r),
17004 k);
17005 if (!k && !result)
17007
17008 // Now consider the types a "types' to compare their size-related
17009 // properties.
17010 result &= equals(static_cast<const type_base&>(l),
17011 static_cast<const type_base&>(r),
17012 k);
17013 ABG_RETURN(result);
17014}
17015
17016/// Return true if both types equals.
17017///
17018/// This operator re-uses the overload that takes a decl_base.
17019///
17020/// Note that this does not check the scopes of any of the types.
17021///
17022/// @param o the other type_decl to check agains.
17023bool
17025{
17026 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17027 if (!other)
17028 return false;
17029 return *this == *other;
17030}
17031
17032/// Return true if both types equals.
17033///
17034/// Note that this does not check the scopes of any of the types.
17035///
17036/// @param o the other type_decl to check against.
17037bool
17039{
17040 const type_decl* other = dynamic_cast<const type_decl*>(&o);
17041 if (!other)
17042 return false;
17043 return try_canonical_compare(this, other);
17044}
17045
17046/// Return true if both types equals.
17047///
17048/// Note that this does not check the scopes of any of the types.
17049///
17050/// @param o the other type_decl to check against.
17051///
17052/// @return true iff the current isntance equals @p o
17053bool
17055{
17056 const decl_base& other = o;
17057 return *this == other;
17058}
17059
17060/// Return true if both types equals.
17061///
17062/// Note that this does not check the scopes of any of the types.
17063///
17064/// @param o the other type_decl to check against.
17065///
17066/// @return true iff the current isntance equals @p o
17067bool
17069{return !operator==(o);}
17070
17071/// Return true if both types equals.
17072///
17073/// Note that this does not check the scopes of any of the types.
17074///
17075/// @param o the other type_decl to check against.
17076///
17077/// @return true iff the current isntance equals @p o
17078bool
17080{return !operator==(o);}
17081
17082/// Inequality operator.
17083///
17084/// @param o the other type to compare against.
17085///
17086/// @return true iff the current instance is different from @p o.
17087bool
17089{return !operator==(o);}
17090
17091/// Equality operator for @ref type_decl_sptr.
17092///
17093/// @param l the first operand to compare.
17094///
17095/// @param r the second operand to compare.
17096///
17097/// @return true iff @p l equals @p r.
17098bool
17100{
17101 if (!!l != !!r)
17102 return false;
17103 if (l.get() == r.get())
17104 return true;
17105 return *l == *r;
17106}
17107
17108/// Inequality operator for @ref type_decl_sptr.
17109///
17110/// @param l the first operand to compare.
17111///
17112/// @param r the second operand to compare.
17113///
17114/// @return true iff @p l is different from @p r.
17115bool
17117{return !operator==(l, r);}
17118
17119/// Implementation for the virtual qualified name builder for @ref
17120/// type_decl.
17121///
17122/// @param qualified_name the output parameter to hold the resulting
17123/// qualified name.
17124///
17125/// @param internal set to true if the call is intended for an
17126/// internal use (for technical use inside the library itself), false
17127/// otherwise. If you don't know what this is for, then set it to
17128/// false.
17129void
17131 bool internal) const
17132{qualified_name = get_qualified_name(internal);}
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.
17144const interned_string&
17146{
17147 const environment& env = get_environment();
17148
17149
17150 if (internal)
17151 if (is_real_type(this))
17152 {
17154 {
17155 if (decl_base::priv_->internal_qualified_name_.empty())
17156 decl_base::priv_->internal_qualified_name_ =
17157 env.intern(get_internal_real_type_name(this));
17158 return decl_base::priv_->internal_qualified_name_;
17159 }
17160 else
17161 {
17162 decl_base::priv_->temporary_internal_qualified_name_ =
17163 env.intern(get_internal_real_type_name(this));
17164 return decl_base::priv_->temporary_internal_qualified_name_;
17165 }
17166 }
17167
17168 return decl_base::get_qualified_name(/*internal=*/false);
17169}
17170
17171/// Get the pretty representation of the current instance of @ref
17172/// type_decl.
17173///
17174/// @param internal set to true if the call is intended to get a
17175/// representation of the decl (or type) for the purpose of canonical
17176/// type comparison. This is mainly used in the function
17177/// type_base::get_canonical_type_for().
17178///
17179/// In other words if the argument for this parameter is true then the
17180/// call is meant for internal use (for technical use inside the
17181/// library itself), false otherwise. If you don't know what this is
17182/// for, then set it to false.
17183///
17184/// @param qualified_name if true, names emitted in the pretty
17185/// representation are fully qualified.
17186///
17187/// @return the pretty representatin of the @ref type_decl.
17188string
17190 bool qualified_name) const
17191{
17192 if (internal)
17193 if (is_real_type(this))
17194 return get_internal_real_type_name(this);
17195
17196 if (qualified_name)
17197 return get_qualified_name(internal);
17198 return get_name();
17199}
17200
17201/// This implements the ir_traversable_base::traverse pure virtual
17202/// function.
17203///
17204/// @param v the visitor used on the current instance.
17205///
17206/// @return true if the entire IR node tree got traversed, false
17207/// otherwise.
17208bool
17210{
17211 if (v.type_node_has_been_visited(this))
17212 return true;
17213
17214 v.visit_begin(this);
17215 bool result = v.visit_end(this);
17217
17218 return result;
17219}
17220
17221type_decl::~type_decl()
17222{}
17223//</type_decl definitions>
17224
17225// <scope_type_decl definitions>
17226
17227/// Constructor.
17228///
17229/// @param env the environment we are operating from.
17230///
17231/// @param name the name of the type.
17232///
17233/// @param size_in_bits the size of the type, in bits.
17234///
17235/// @param alignment_in_bits the alignment of the type, in bits.
17236///
17237/// @param locus the source location where the type is defined.
17238///
17239/// @param vis the visibility of the type.
17240scope_type_decl::scope_type_decl(const environment& env,
17241 const string& name,
17242 size_t size_in_bits,
17243 size_t alignment_in_bits,
17244 const location& locus,
17245 visibility vis)
17246 : type_or_decl_base(env,
17247 ABSTRACT_SCOPE_TYPE_DECL
17248 | ABSTRACT_TYPE_BASE
17249 | ABSTRACT_DECL_BASE),
17250 decl_base(env, name, locus, "", vis),
17251 type_base(env, size_in_bits, alignment_in_bits),
17252 scope_decl(env, name, locus)
17253{}
17254
17255/// Compares two instances of @ref scope_type_decl.
17256///
17257/// If the two intances are different, set a bitfield to give some
17258/// insight about the kind of differences there are.
17259///
17260/// @param l the first artifact of the comparison.
17261///
17262/// @param r the second artifact of the comparison.
17263///
17264/// @param k a pointer to a bitfield that gives information about the
17265/// kind of changes there are between @p l and @p r. This one is set
17266/// iff @p k is non-null and the function returns false.
17267///
17268/// Please note that setting k to a non-null value does have a
17269/// negative performance impact because even if @p l and @p r are not
17270/// equal, the function keeps up the comparison in order to determine
17271/// the different kinds of ways in which they are different.
17272///
17273/// @return true if @p l equals @p r, false otherwise.
17274bool
17276{
17277 bool result = equals(static_cast<const scope_decl&>(l),
17278 static_cast<const scope_decl&>(r),
17279 k);
17280
17281 if (!k && !result)
17283
17284 result &= equals(static_cast<const type_base&>(l),
17285 static_cast<const type_base&>(r),
17286 k);
17287
17288 ABG_RETURN(result);
17289}
17290
17291/// Equality operator between two scope_type_decl.
17292///
17293/// Note that this function does not consider the scope of the scope
17294/// types themselves.
17295///
17296/// @return true iff both scope types are equal.
17297bool
17299{
17300 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
17301 if (!other)
17302 return false;
17303 return try_canonical_compare(this, other);
17304}
17305
17306/// Equality operator between two scope_type_decl.
17307///
17308/// This re-uses the equality operator that takes a decl_base.
17309///
17310/// @param o the other scope_type_decl to compare against.
17311///
17312/// @return true iff both scope types are equal.
17313bool
17315{
17316 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17317 if (!other)
17318 return false;
17319
17320 return *this == *other;
17321}
17322
17323/// Traverses an instance of @ref scope_type_decl, visiting all the
17324/// sub-types and decls that it might contain.
17325///
17326/// @param v the visitor that is used to visit every IR sub-node of
17327/// the current node.
17328///
17329/// @return true if either
17330/// - all the children nodes of the current IR node were traversed
17331/// and the calling code should keep going with the traversing.
17332/// - or the current IR node is already being traversed.
17333/// Otherwise, returning false means that the calling code should not
17334/// keep traversing the tree.
17335bool
17337{
17338 if (visiting())
17339 return true;
17340
17341 if (v.type_node_has_been_visited(this))
17342 return true;
17343
17344 if (v.visit_begin(this))
17345 {
17346 visiting(true);
17347 for (scope_decl::declarations::const_iterator i =
17348 get_member_decls().begin();
17349 i != get_member_decls ().end();
17350 ++i)
17351 if (!(*i)->traverse(v))
17352 break;
17353 visiting(false);
17354 }
17355
17356 bool result = v.visit_end(this);
17358
17359 return result;
17360}
17361
17362scope_type_decl::~scope_type_decl()
17363{}
17364// </scope_type_decl definitions>
17365
17366// <namespace_decl>
17367
17368/// Constructor.
17369///
17370/// @param the environment we are operatin from.
17371///
17372/// @param name the name of the namespace.
17373///
17374/// @param locus the source location where the namespace is defined.
17375///
17376/// @param vis the visibility of the namespace.
17378 const string& name,
17379 const location& locus,
17380 visibility vis)
17381 // We need to call the constructor of decl_base directly here
17382 // because it is virtually inherited by scope_decl. Note that we
17383 // just implicitely call the default constructor for scope_decl
17384 // here, as what we really want is to initialize the decl_base
17385 // subobject. Wow, virtual inheritance is useful, but setting it
17386 // up is ugly.
17387 : type_or_decl_base(env,
17388 NAMESPACE_DECL
17389 | ABSTRACT_DECL_BASE
17390 | ABSTRACT_SCOPE_DECL),
17391 decl_base(env, name, locus, "", vis),
17392 scope_decl(env, name, locus)
17393{
17395}
17396
17397/// Build and return a copy of the pretty representation of the
17398/// namespace.
17399///
17400/// @param internal set to true if the call is intended to get a
17401/// representation of the decl (or type) for the purpose of canonical
17402/// type comparison. This is mainly used in the function
17403/// type_base::get_canonical_type_for().
17404///
17405/// In other words if the argument for this parameter is true then the
17406/// call is meant for internal use (for technical use inside the
17407/// library itself), false otherwise. If you don't know what this is
17408/// for, then set it to false.
17409///
17410/// @param qualified_name if true, names emitted in the pretty
17411/// representation are fully qualified.
17412///
17413/// @return a copy of the pretty representation of the namespace.
17414string
17416 bool qualified_name) const
17417{
17418 string r =
17419 "namespace " + scope_decl::get_pretty_representation(internal,
17420 qualified_name);
17421 return r;
17422}
17423
17424/// Return true iff both namespaces and their members are equal.
17425///
17426/// Note that this function does not check if the scope of these
17427/// namespaces are equal.
17428bool
17430{
17431 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
17432 if (!other)
17433 return false;
17434 return scope_decl::operator==(*other);
17435}
17436
17437/// Test if the current namespace_decl is empty or contains empty
17438/// namespaces itself.
17439///
17440/// @return true iff the current namespace_decl is empty or contains
17441/// empty itself.
17442bool
17444{
17445 if (is_empty())
17446 return true;
17447
17448 for (declarations::const_iterator i = get_member_decls().begin();
17449 i != get_member_decls().end();
17450 ++i)
17451 {
17452 if (!is_namespace(*i))
17453 return false;
17454
17456 ABG_ASSERT(ns);
17457
17458 if (!ns->is_empty_or_has_empty_sub_namespaces())
17459 return false;
17460 }
17461
17462 return true;
17463}
17464
17465/// This implements the ir_traversable_base::traverse pure virtual
17466/// function.
17467///
17468/// @param v the visitor used on the current instance and on its
17469/// member nodes.
17470///
17471/// @return true if the entire IR node tree got traversed, false
17472/// otherwise.
17473bool
17475{
17476 if (visiting())
17477 return true;
17478
17479 if (v.visit_begin(this))
17480 {
17481 visiting(true);
17482 scope_decl::declarations::const_iterator i;
17483 for (i = get_member_decls().begin();
17484 i != get_member_decls ().end();
17485 ++i)
17486 {
17488 dynamic_pointer_cast<ir_traversable_base>(*i);
17489 if (t)
17490 if (!t->traverse (v))
17491 break;
17492 }
17493 visiting(false);
17494 }
17495 return v.visit_end(this);
17496}
17497
17498namespace_decl::~namespace_decl()
17499{
17500}
17501
17502// </namespace_decl>
17503
17504// <qualified_type_def>
17505
17506/// Type of the private data of qualified_type_def.
17507class qualified_type_def::priv
17508{
17509 friend class qualified_type_def;
17510
17511 qualified_type_def::CV cv_quals_;
17512 // Before the type is canonicalized, this is used as a temporary
17513 // internal name.
17514 interned_string temporary_internal_name_;
17515 // Once the type is canonicalized, this is used as the internal
17516 // name.
17517 interned_string internal_name_;
17518 weak_ptr<type_base> underlying_type_;
17519
17520 priv()
17521 : cv_quals_(CV_NONE)
17522 {}
17523
17524 priv(qualified_type_def::CV quals,
17525 type_base_sptr t)
17526 : cv_quals_(quals),
17527 underlying_type_(t)
17528 {}
17529
17530 priv(qualified_type_def::CV quals)
17531 : cv_quals_(quals)
17532 {}
17533};// end class qualified_type_def::priv
17534
17535/// Build the name of the current instance of qualified type.
17536///
17537/// @param fully_qualified if true, build a fully qualified name.
17538///
17539/// @param internal set to true if the call is intended for an
17540/// internal use (for technical use inside the library itself), false
17541/// otherwise. If you don't know what this is for, then set it to
17542/// false.
17543///
17544/// @return a copy of the newly-built name.
17545string
17546qualified_type_def::build_name(bool fully_qualified, bool internal) const
17547{
17548 type_base_sptr t = get_underlying_type();
17549 if (!t)
17550 // The qualified type might temporarily have no underlying type,
17551 // especially during the construction of the type, while the
17552 // underlying type is not yet constructed. In that case, let's do
17553 // like if the underlying type is the 'void' type.
17555
17557 fully_qualified,
17558 internal);
17559}
17560
17561/// This function is automatically invoked whenever an instance of
17562/// this type is canonicalized.
17563///
17564/// It's an overload of the virtual type_base::on_canonical_type_set.
17565///
17566/// We put here what is thus meant to be executed only at the point of
17567/// type canonicalization.
17568void
17571
17572/// Constructor of the qualified_type_def
17573///
17574/// @param type the underlying type
17575///
17576/// @param quals a bitfield representing the const/volatile qualifiers
17577///
17578/// @param locus the location of the qualified type definition
17579qualified_type_def::qualified_type_def(type_base_sptr type,
17580 CV quals,
17581 const location& locus)
17582 : type_or_decl_base(type->get_environment(),
17583 QUALIFIED_TYPE
17584 | ABSTRACT_TYPE_BASE
17585 | ABSTRACT_DECL_BASE),
17586 type_base(type->get_environment(), type->get_size_in_bits(),
17587 type->get_alignment_in_bits()),
17588 decl_base(type->get_environment(), "", locus, "",
17589 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
17590 priv_(new priv(quals, type))
17591{
17593 interned_string name = type->get_environment().intern(build_name(false));
17594 set_name(name);
17595}
17596
17597/// Constructor of the qualified_type_def
17598///
17599/// @param env the environment of the type.
17600///
17601/// @param quals a bitfield representing the const/volatile qualifiers
17602///
17603/// @param locus the location of the qualified type definition
17604qualified_type_def::qualified_type_def(const environment& env,
17605 CV quals,
17606 const location& locus)
17607 : type_or_decl_base(env,
17608 QUALIFIED_TYPE
17609 | ABSTRACT_TYPE_BASE
17610 | ABSTRACT_DECL_BASE),
17611 type_base(env, /*size_in_bits=*/0,
17612 /*alignment_in_bits=*/0),
17613 decl_base(env, "", locus, ""),
17614 priv_(new priv(quals))
17615{
17617 // We don't yet have an underlying type. So for naming purpose,
17618 // let's temporarily pretend the underlying type is 'void'.
17619 interned_string name = env.intern("void");
17620 set_name(name);
17621}
17622
17623/// Return the hash value of the current IR node.
17624///
17625/// Note that upon the first invocation, this member functions
17626/// computes the hash value and returns it. Subsequent invocations
17627/// just return the hash value that was previously calculated.
17628///
17629/// @return the hash value of the current IR node.
17630hash_t
17632{
17634 return h;
17635}
17636
17637/// Get the size of the qualified type def.
17638///
17639/// This is an overload for type_base::get_size_in_bits().
17640///
17641/// @return the size of the qualified type.
17642size_t
17644{
17645 size_t s = 0;
17646 if (type_base_sptr ut = get_underlying_type())
17647 {
17648 // We do have the underlying type properly set, so let's make
17649 // the size of the qualified type match the size of its
17650 // underlying type.
17651 s = ut->get_size_in_bits();
17652 if (s != type_base::get_size_in_bits())
17653 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
17654 }
17656}
17657
17658/// Compares two instances of @ref qualified_type_def.
17659///
17660/// If the two intances are different, set a bitfield to give some
17661/// insight about the kind of differences there are.
17662///
17663/// @param l the first artifact of the comparison.
17664///
17665/// @param r the second artifact of the comparison.
17666///
17667/// @param k a pointer to a bitfield that gives information about the
17668/// kind of changes there are between @p l and @p r. This one is set
17669/// iff @p k is non-null and the function returns false.
17670///
17671/// Please note that setting k to a non-null value does have a
17672/// negative performance impact because even if @p l and @p r are not
17673/// equal, the function keeps up the comparison in order to determine
17674/// the different kinds of ways in which they are different.
17675///
17676/// @return true if @p l equals @p r, false otherwise.
17677bool
17679{
17680 bool result = true;
17681 if (l.get_cv_quals() != r.get_cv_quals())
17682 {
17683 result = false;
17684 if (k)
17686 else
17688 }
17689
17691 {
17692 result = false;
17693 if (k)
17694 {
17696 r.get_underlying_type().get()))
17697 // Underlying type changes in which the structure of the
17698 // type changed are considered local changes to the
17699 // qualified type.
17701 else
17702 *k |= SUBTYPE_CHANGE_KIND;
17703 }
17704 else
17705 // okay strictly speaking this is not necessary, but I am
17706 // putting it here to maintenance; that is, so that adding
17707 // subsequent clauses needed to compare two qualified types
17708 // later still works.
17710 }
17711
17712 ABG_RETURN(result);
17713}
17714
17715/// Equality operator for qualified types.
17716///
17717/// Note that this function does not check for equality of the scopes.
17718///
17719///@param o the other qualified type to compare against.
17720///
17721/// @return true iff both qualified types are equal.
17722bool
17724{
17725 const qualified_type_def* other =
17726 dynamic_cast<const qualified_type_def*>(&o);
17727 if (!other)
17728 return false;
17729 return try_canonical_compare(this, other);
17730}
17731
17732/// Equality operator for qualified types.
17733///
17734/// Note that this function does not check for equality of the scopes.
17735/// Also, this re-uses the equality operator above that takes a
17736/// decl_base.
17737///
17738///@param o the other qualified type to compare against.
17739///
17740/// @return true iff both qualified types are equal.
17741bool
17743{
17744 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17745 if (!other)
17746 return false;
17747 return *this == *other;
17748}
17749
17750/// Equality operator for qualified types.
17751///
17752/// Note that this function does not check for equality of the scopes.
17753/// Also, this re-uses the equality operator above that takes a
17754/// decl_base.
17755///
17756///@param o the other qualified type to compare against.
17757///
17758/// @return true iff both qualified types are equal.
17759bool
17761{
17762 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17763 if (!other)
17764 return false;
17765 return *this == *other;
17766}
17767
17768/// Implementation for the virtual qualified name builder for @ref
17769/// qualified_type_def.
17770///
17771/// @param qualified_name the output parameter to hold the resulting
17772/// qualified name.
17773///
17774/// @param internal set to true if the call is intended for an
17775/// internal use (for technical use inside the library itself), false
17776/// otherwise. If you don't know what this is for, then set it to
17777/// false.
17778void
17780 bool internal) const
17781{qualified_name = get_qualified_name(internal);}
17782
17783/// Implementation of the virtual qualified name builder/getter.
17784///
17785/// @param internal set to true if the call is intended for an
17786/// internal use (for technical use inside the library itself), false
17787/// otherwise. If you don't know what this is for, then set it to
17788/// false.
17789///
17790/// @return the resulting qualified name.
17791const interned_string&
17793{
17794 const environment& env = get_environment();
17795
17796
17797 if (!get_canonical_type())
17798 {
17799 // The type hasn't been canonicalized yet. We want to return a
17800 // temporary name that is not cached because the structure of
17801 // this type (and so its name) can change until its
17802 // canonicalized.
17803 if (internal)
17804 {
17805 // We are asked to return a temporary *internal* name.
17806 // Lets compute it and return a reference to where it's
17807 // stored.
17808 if (priv_->temporary_internal_name_.empty())
17809 priv_->temporary_internal_name_ =
17810 env.intern(build_name(true, /*internal=*/true));
17811 return priv_->temporary_internal_name_;
17812 }
17813 else
17814 {
17815 // We are asked to return a temporary non-internal name.
17817 (env.intern(build_name(true, /*internal=*/false)));
17819 }
17820 }
17821 else
17822 {
17823 // The type has already been canonicalized. We want to return
17824 // the definitive name and cache it.
17825 if (internal)
17826 {
17827 if (priv_->internal_name_.empty())
17828 priv_->internal_name_ =
17829 env.intern(build_name(/*qualified=*/true,
17830 /*internal=*/true));
17831 return priv_->internal_name_;
17832 }
17833 else
17834 {
17835 if (peek_qualified_name().empty())
17837 (env.intern(build_name(/*qualified=*/true,
17838 /*internal=*/false)));
17839 return peek_qualified_name();
17840 }
17841 }
17842}
17843
17844/// This implements the ir_traversable_base::traverse pure virtual
17845/// function.
17846///
17847/// @param v the visitor used on the current instance.
17848///
17849/// @return true if the entire IR node tree got traversed, false
17850/// otherwise.
17851bool
17853{
17854 if (v.type_node_has_been_visited(this))
17855 return true;
17856
17857 if (visiting())
17858 return true;
17859
17860 if (v.visit_begin(this))
17861 {
17862 visiting(true);
17863 if (type_base_sptr t = get_underlying_type())
17864 t->traverse(v);
17865 visiting(false);
17866 }
17867 bool result = v.visit_end(this);
17869 return result;
17870}
17871
17872qualified_type_def::~qualified_type_def()
17873{
17874}
17875
17876/// Getter of the const/volatile qualifier bit field
17879{return priv_->cv_quals_;}
17880
17881/// Setter of the const/value qualifiers bit field
17882void
17884{priv_->cv_quals_ = cv_quals;}
17885
17886/// Compute and return the string prefix or suffix representing the
17887/// qualifiers hold by the current instance of @ref
17888/// qualified_type_def.
17889///
17890/// @return the newly-built cv string.
17891string
17893{return get_string_representation_of_cv_quals(priv_->cv_quals_);}
17894
17895/// Getter of the underlying type
17896type_base_sptr
17898{return priv_->underlying_type_.lock();}
17899
17900/// Setter of the underlying type.
17901///
17902/// @param t the new underlying type.
17903void
17905{
17906 ABG_ASSERT(t);
17907 priv_->underlying_type_ = t;
17908 // Now we need to update other properties that depend on the new underlying type.
17909 set_size_in_bits(t->get_size_in_bits());
17910 set_alignment_in_bits(t->get_alignment_in_bits());
17912 set_name(name);
17913 if (scope_decl* s = get_scope())
17914 {
17915 // Now that the name has been updated, we need to update the
17916 // lookup maps accordingly.
17917 scope_decl::declarations::iterator i;
17918 if (s->find_iterator_for_member(this, i))
17920 else
17922 }
17923}
17924
17925/// Non-member equality operator for @ref qualified_type_def
17926///
17927/// @param l the left-hand side of the equality operator
17928///
17929/// @param r the right-hand side of the equality operator
17930///
17931/// @return true iff @p l and @p r equals.
17932bool
17933operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17934{
17935 if (l.get() == r.get())
17936 return true;
17937 if (!!l != !!r)
17938 return false;
17939
17940 return *l == *r;
17941}
17942
17943/// Non-member inequality operator for @ref qualified_type_def
17944///
17945/// @param l the left-hand side of the equality operator
17946///
17947/// @param r the right-hand side of the equality operator
17948///
17949/// @return true iff @p l and @p r equals.
17950bool
17951operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17952{return ! operator==(l, r);}
17953
17954/// Overloaded bitwise OR operator for cv qualifiers.
17957{
17958 return static_cast<qualified_type_def::CV>
17959 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
17960}
17961
17962/// Overloaded bitwise |= operator for cv qualifiers.
17965{
17966 l = l | r;
17967 return l;
17968}
17969
17970/// Overloaded bitwise &= operator for cv qualifiers.
17973{
17974 l = l & r;
17975 return l;
17976}
17977
17978/// Overloaded bitwise AND operator for CV qualifiers.
17981{
17982 return static_cast<qualified_type_def::CV>
17983 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
17984}
17985
17986/// Overloaded bitwise inverting operator for CV qualifiers.
17989{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
17990
17991/// Streaming operator for qualified_type_decl::CV
17992///
17993/// @param o the output stream to serialize the cv qualifier to.
17994///
17995/// @param cv the cv qualifier to serialize.
17996///
17997/// @return the output stream used.
17998std::ostream&
17999operator<<(std::ostream& o, qualified_type_def::CV cv)
18000{
18001 string str;
18002
18003 switch (cv)
18004 {
18005 case qualified_type_def::CV_NONE:
18006 str = "none";
18007 break;
18008 case qualified_type_def::CV_CONST:
18009 str = "const";
18010 break;
18011 case qualified_type_def::CV_VOLATILE:
18012 str = "volatile";
18013 break;
18014 case qualified_type_def::CV_RESTRICT:
18015 str = "restrict";
18016 break;
18017 }
18018
18019 o << str;
18020 return o;
18021}
18022
18023// </qualified_type_def>
18024
18025//<pointer_type_def definitions>
18026
18027/// Private data structure of the @ref pointer_type_def.
18028struct pointer_type_def::priv
18029{
18030 type_base_wptr pointed_to_type_;
18031 type_base* naked_pointed_to_type_;
18032 interned_string internal_qualified_name_;
18033 interned_string temp_internal_qualified_name_;
18034
18035 priv(const type_base_sptr& t)
18036 : pointed_to_type_(type_or_void(t, t->get_environment())),
18037 naked_pointed_to_type_(t.get())
18038 {}
18039
18040 priv()
18041 : naked_pointed_to_type_()
18042 {}
18043}; //end struct pointer_type_def
18044
18045/// This function is automatically invoked whenever an instance of
18046/// this type is canonicalized.
18047///
18048/// It's an overload of the virtual type_base::on_canonical_type_set.
18049///
18050/// We put here what is thus meant to be executed only at the point of
18051/// type canonicalization.
18052void
18055
18056
18057///Constructor of @ref pointer_type_def.
18058///
18059/// @param pointed_to the pointed-to type.
18060///
18061/// @param size_in_bits the size of the type, in bits.
18062///
18063/// @param align_in_bits the alignment of the type, in bits.
18064///
18065/// @param locus the source location where the type was defined.
18066pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
18067 size_t size_in_bits,
18068 size_t align_in_bits,
18069 const location& locus)
18070 : type_or_decl_base(pointed_to->get_environment(),
18071 POINTER_TYPE
18072 | ABSTRACT_TYPE_BASE
18073 | ABSTRACT_DECL_BASE),
18074 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18075 decl_base(pointed_to->get_environment(), "", locus, ""),
18076 priv_(new priv(pointed_to))
18077{
18079 try
18080 {
18081 ABG_ASSERT(pointed_to);
18082 const environment& env = pointed_to->get_environment();
18083 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18084 string name = (pto ? pto->get_name() : string("void")) + "*";
18085 set_name(env.intern(name));
18086 if (pto)
18087 set_visibility(pto->get_visibility());
18088 }
18089 catch (...)
18090 {}
18091}
18092
18093///Constructor of @ref pointer_type_def.
18094///
18095/// @param env the environment of the type.
18096///
18097/// @param size_in_bits the size of the type, in bits.
18098///
18099/// @param align_in_bits the alignment of the type, in bits.
18100///
18101/// @param locus the source location where the type was defined.
18102pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
18103 size_t alignment_in_bits,
18104 const location& locus)
18105 : type_or_decl_base(env,
18106 POINTER_TYPE
18107 | ABSTRACT_TYPE_BASE
18108 | ABSTRACT_DECL_BASE),
18109 type_base(env, size_in_bits, alignment_in_bits),
18110 decl_base(env, "", locus, ""),
18111 priv_(new priv())
18112{
18114 string name = string("void") + "*";
18115 set_name(env.intern(name));
18116}
18117
18118/// Return the hash value of the current IR node.
18119///
18120/// Note that upon the first invocation, this member functions
18121/// computes the hash value and returns it. Subsequent invocations
18122/// just return the hash value that was previously calculated.
18123///
18124/// @return the hash value of the current IR node.
18125hash_t
18127{
18129 return h;
18130}
18131
18132/// Set the pointed-to type of the pointer.
18133///
18134/// @param t the new pointed-to type.
18135void
18137{
18138 ABG_ASSERT(t);
18139 priv_->pointed_to_type_ = t;
18140 priv_->naked_pointed_to_type_ = t.get();
18141
18142 try
18143 {
18144 const environment& env = t->get_environment();
18145 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
18146 string name = (pto ? pto->get_name() : string("void")) + "*";
18147 set_name(env.intern(name));
18148 if (pto)
18149 set_visibility(pto->get_visibility());
18150 }
18151 catch (...)
18152 {}
18153}
18154
18155/// Compares two instances of @ref pointer_type_def.
18156///
18157/// If the two intances are different, set a bitfield to give some
18158/// insight about the kind of differences there are.
18159///
18160/// @param l the first artifact of the comparison.
18161///
18162/// @param r the second artifact of the comparison.
18163///
18164/// @param k a pointer to a bitfield that gives information about the
18165/// kind of changes there are between @p l and @p r. This one is set
18166/// iff @p k is non-null and the function returns false.
18167///
18168/// Please note that setting k to a non-null value does have a
18169/// negative performance impact because even if @p l and @p r are not
18170/// equal, the function keeps up the comparison in order to determine
18171/// the different kinds of ways in which they are different.
18172///
18173/// @return true if @p l equals @p r, false otherwise.
18174bool
18176{
18177 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18178 bool result = p1 == p2;
18179 if (!result)
18180 if (k)
18181 {
18182 if (!types_have_similar_structure(&l, &r))
18183 // pointed-to type changes in which the structure of the
18184 // type changed are considered local changes to the pointer
18185 // type.
18187 *k |= SUBTYPE_CHANGE_KIND;
18188 }
18189
18190 ABG_RETURN(result);
18191}
18192
18193/// Return true iff both instances of pointer_type_def are equal.
18194///
18195/// Note that this function does not check for the scopes of the this
18196/// types.
18197bool
18199{
18200 const pointer_type_def* other = is_pointer_type(&o);
18201 if (!other)
18202 return false;
18203 return try_canonical_compare(this, other);
18204}
18205
18206/// Return true iff both instances of pointer_type_def are equal.
18207///
18208/// Note that this function does not check for the scopes of the
18209/// types.
18210///
18211/// @param other the other type to compare against.
18212///
18213/// @return true iff @p other equals the current instance.
18214bool
18216{
18217 const decl_base* o = is_decl(&other);
18218 if (!o)
18219 return false;
18220 return *this == *o;
18221}
18222
18223/// Return true iff both instances of pointer_type_def are equal.
18224///
18225/// Note that this function does not check for the scopes of the
18226/// types.
18227///
18228/// @param other the other type to compare against.
18229///
18230/// @return true iff @p other equals the current instance.
18231bool
18233{
18234 const decl_base& o = other;
18235 return *this == o;
18236}
18237
18238/// Getter of the pointed-to type.
18239///
18240/// @return the pointed-to type.
18241const type_base_sptr
18243{return priv_->pointed_to_type_.lock();}
18244
18245/// Getter of a naked pointer to the pointed-to type.
18246///
18247/// @return a naked pointed to the pointed-to type.
18248type_base*
18250{return priv_->naked_pointed_to_type_;}
18251
18252/// Build and return the qualified name of the current instance of
18253/// @ref pointer_type_def.
18254///
18255/// @param qn output parameter. The resulting qualified name.
18256///
18257/// @param internal set to true if the call is intended for an
18258/// internal use (for technical use inside the library itself), false
18259/// otherwise. If you don't know what this is for, then set it to
18260/// false.
18261void
18263{qn = get_qualified_name(internal);}
18264
18265/// Build, cache and return the qualified name of the current instance
18266/// of @ref pointer_type_def. Subsequent invocations of this function
18267/// return the cached value.
18268///
18269/// Note that this function should work even if the underlying type is
18270/// momentarily empty.
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.
18276///
18277/// @return the resulting qualified name.
18278const interned_string&
18280{
18281 type_base* pointed_to_type = get_naked_pointed_to_type();
18282 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18283
18284 if (internal)
18285 {
18286 if (get_canonical_type())
18287 {
18288 if (priv_->internal_qualified_name_.empty())
18289 if (pointed_to_type)
18290 priv_->internal_qualified_name_ =
18291 pointer_declaration_name(this,
18292 /*variable_name=*/"",
18293 /*qualified_name=*/
18294 is_typedef(pointed_to_type)
18295 ? false
18296 : true,
18297 /*internal=*/true);
18298 return priv_->internal_qualified_name_;
18299 }
18300 else
18301 {
18302 // As the type hasn't yet been canonicalized, its structure
18303 // (and so its name) can change. So let's invalidate the
18304 // cache where we store its name at each invocation of this
18305 // function.
18306 if (pointed_to_type)
18307 if (priv_->temp_internal_qualified_name_.empty())
18308 priv_->temp_internal_qualified_name_ =
18309 pointer_declaration_name(this,
18310 /*variable_name=*/"",
18311 /*qualified_name=*/
18312 is_typedef(pointed_to_type)
18313 ? false
18314 : true,
18315 /*internal=*/true);
18316 return priv_->temp_internal_qualified_name_;
18317 }
18318 }
18319 else
18320 {
18322 {
18323 if (decl_base::peek_qualified_name().empty())
18325 (pointer_declaration_name(this,
18326 /*variable_name=*/"",
18327 /*qualified_name=*/true,
18328 /*internal=*/false));
18330 }
18331 else
18332 {
18333 // As the type hasn't yet been canonicalized, its structure
18334 // (and so its name) can change. So let's invalidate the
18335 // cache where we store its name at each invocation of this
18336 // function.
18337 if (pointed_to_type)
18339 (pointer_declaration_name(this,
18340 /*variable_name=*/"",
18341 /*qualified_name=*/true,
18342 /*internal=*/false));
18344 }
18345 }
18346}
18347
18348/// This implements the ir_traversable_base::traverse pure virtual
18349/// function.
18350///
18351/// @param v the visitor used on the current instance.
18352///
18353/// @return true if the entire IR node tree got traversed, false
18354/// otherwise.
18355bool
18357{
18358 if (v.type_node_has_been_visited(this))
18359 return true;
18360
18361 if (visiting())
18362 return true;
18363
18364 if (v.visit_begin(this))
18365 {
18366 visiting(true);
18367 if (type_base_sptr t = get_pointed_to_type())
18368 t->traverse(v);
18369 visiting(false);
18370 }
18371
18372 bool result = v.visit_end(this);
18374 return result;
18375}
18376
18377pointer_type_def::~pointer_type_def()
18378{}
18379
18380/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
18381/// equality; that is, make it compare the pointed to objects too.
18382///
18383/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18384/// of the equality.
18385///
18386/// @param r the shared_ptr of @ref pointer_type_def on
18387/// right-hand-side of the equality.
18388///
18389/// @return true if the @ref pointer_type_def pointed to by the
18390/// shared_ptrs are equal, false otherwise.
18391bool
18393{
18394 if (l.get() == r.get())
18395 return true;
18396 if (!!l != !!r)
18397 return false;
18398
18399 return *l == *r;
18400}
18401
18402/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
18403/// equality; that is, make it compare the pointed to objects too.
18404///
18405/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18406/// of the equality.
18407///
18408/// @param r the shared_ptr of @ref pointer_type_def on
18409/// right-hand-side of the equality.
18410///
18411/// @return true iff the @ref pointer_type_def pointed to by the
18412/// shared_ptrs are different.
18413bool
18415{return !operator==(l, r);}
18416
18417// </pointer_type_def definitions>
18418
18419// <reference_type_def definitions>
18420
18421/// Private data structure of the @ref reference_type_def type.
18422struct reference_type_def::priv
18423{
18424
18425 type_base_wptr pointed_to_type_;
18426 bool is_lvalue_;
18427 interned_string internal_qualified_name_;
18428 interned_string temp_internal_qualified_name_;
18429
18430 priv(const type_base_sptr& t, bool is_lvalue)
18431 : pointed_to_type_(type_or_void(t, t->get_environment())),
18432 is_lvalue_(is_lvalue)
18433 {}
18434
18435 priv(bool is_lvalue)
18436 : is_lvalue_(is_lvalue)
18437 {}
18438
18439 priv() = delete;
18440};
18441
18442/// This function is automatically invoked whenever an instance of
18443/// this type is canonicalized.
18444///
18445/// It's an overload of the virtual type_base::on_canonical_type_set.
18446///
18447/// We put here what is thus meant to be executed only at the point of
18448/// type canonicalization.
18449void
18452
18453/// Constructor of the reference_type_def type.
18454///
18455/// @param pointed_to the pointed to type.
18456///
18457/// @param lvalue wether the reference is an lvalue reference. If
18458/// false, the reference is an rvalue one.
18459///
18460/// @param size_in_bits the size of the type, in bits.
18461///
18462/// @param align_in_bits the alignment of the type, in bits.
18463///
18464/// @param locus the source location of the type.
18465reference_type_def::reference_type_def(const type_base_sptr pointed_to,
18466 bool lvalue,
18467 size_t size_in_bits,
18468 size_t align_in_bits,
18469 const location& locus)
18470 : type_or_decl_base(pointed_to->get_environment(),
18471 REFERENCE_TYPE
18472 | ABSTRACT_TYPE_BASE
18473 | ABSTRACT_DECL_BASE),
18474 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18475 decl_base(pointed_to->get_environment(), "", locus, ""),
18476 priv_(new priv(pointed_to, lvalue))
18477{
18479
18480 try
18481 {
18482 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18483 string name;
18484 if (pto)
18485 {
18486 set_visibility(pto->get_visibility());
18487 name = string(pto->get_name()) + "&";
18488 }
18489 else
18490 name = string(get_type_name(is_function_type(pointed_to),
18491 /*qualified_name=*/true)) + "&";
18492
18493 if (!is_lvalue())
18494 name += "&";
18495 const environment& env = pointed_to->get_environment();
18496 set_name(env.intern(name));
18497 }
18498 catch (...)
18499 {}
18500}
18501
18502/// Constructor of the reference_type_def type.
18503///
18504/// This one creates a type that has no pointed-to type, temporarily.
18505/// This is useful for cases where the underlying type is not yet
18506/// available. It can be set later using
18507/// reference_type_def::set_pointed_to_type().
18508///
18509/// @param env the environment of the type.
18510///
18511/// @param lvalue wether the reference is an lvalue reference. If
18512/// false, the reference is an rvalue one.
18513///
18514/// @param size_in_bits the size of the type, in bits.
18515///
18516/// @param align_in_bits the alignment of the type, in bits.
18517///
18518/// @param locus the source location of the type.
18519reference_type_def::reference_type_def(const environment& env, bool lvalue,
18520 size_t size_in_bits,
18521 size_t alignment_in_bits,
18522 const location& locus)
18523 : type_or_decl_base(env,
18524 REFERENCE_TYPE
18525 | ABSTRACT_TYPE_BASE
18526 | ABSTRACT_DECL_BASE),
18527 type_base(env, size_in_bits, alignment_in_bits),
18528 decl_base(env, "", locus, ""),
18529 priv_(new priv(lvalue))
18530{
18532 string name = "void&";
18533 if (!is_lvalue())
18534 name += "&";
18535
18536 set_name(env.intern(name));
18537 priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
18538}
18539
18540/// Return the hash value of the current IR node.
18541///
18542/// Note that upon the first invocation, this member functions
18543/// computes the hash value and returns it. Subsequent invocations
18544/// just return the hash value that was previously calculated.
18545///
18546/// @return the hash value of the current IR node.
18547hash_t
18549{
18551 return h;
18552}
18553
18554/// Setter of the pointed_to type of the current reference type.
18555///
18556/// @param pointed_to the new pointed to type.
18557void
18558reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
18559{
18560 ABG_ASSERT(pointed_to_type);
18561 priv_->pointed_to_type_ = pointed_to_type;
18562
18563 decl_base_sptr pto;
18564 try
18565 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
18566 catch (...)
18567 {}
18568
18569 if (pto)
18570 {
18571 set_visibility(pto->get_visibility());
18572 string name = string(pto->get_name()) + "&";
18573 if (!is_lvalue())
18574 name += "&";
18575 const environment& env = pto->get_environment();
18576 set_name(env.intern(name));
18577 }
18578}
18579
18580/// Compares two instances of @ref reference_type_def.
18581///
18582/// If the two intances are different, set a bitfield to give some
18583/// insight about the kind of differences there are.
18584///
18585/// @param l the first artifact of the comparison.
18586///
18587/// @param r the second artifact of the comparison.
18588///
18589/// @param k a pointer to a bitfield that gives information about the
18590/// kind of changes there are between @p l and @p r. This one is set
18591/// iff @p k is non-null and the function returns false.
18592///
18593/// Please note that setting k to a non-null value does have a
18594/// negative performance impact because even if @p l and @p r are not
18595/// equal, the function keeps up the comparison in order to determine
18596/// the different kinds of ways in which they are different.
18597///
18598/// @return true if @p l equals @p r, false otherwise.
18599bool
18601{
18602 if (l.is_lvalue() != r.is_lvalue())
18603 {
18604 if (k)
18607 }
18608 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18609 bool result = p1 == p2;
18610 if (!result)
18611 if (k)
18612 {
18613 if (!types_have_similar_structure(&l, &r))
18615 *k |= SUBTYPE_CHANGE_KIND;
18616 }
18617 ABG_RETURN(result);
18618}
18619
18620/// Equality operator of the @ref reference_type_def type.
18621///
18622/// @param o the other instance of @ref reference_type_def to compare
18623/// against.
18624///
18625/// @return true iff the two instances are equal.
18626bool
18628{
18629 const reference_type_def* other =
18630 dynamic_cast<const reference_type_def*>(&o);
18631 if (!other)
18632 return false;
18633 return try_canonical_compare(this, other);
18634}
18635
18636/// Equality operator of the @ref reference_type_def type.
18637///
18638/// @param o the other instance of @ref reference_type_def to compare
18639/// against.
18640///
18641/// @return true iff the two instances are equal.
18642bool
18644{
18645 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18646 if (!other)
18647 return false;
18648 return *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
18666type_base_sptr
18667reference_type_def::get_pointed_to_type() const
18668{return priv_->pointed_to_type_.lock();}
18669
18670bool
18671reference_type_def::is_lvalue() const
18672{return priv_->is_lvalue_;}
18673
18674/// Build and return the qualified name of the current instance of the
18675/// @ref reference_type_def.
18676///
18677/// @param qn output parameter. Is set to the newly-built qualified
18678/// name of the current instance of @ref reference_type_def.
18679///
18680/// @param internal set to true if the call is intended for an
18681/// internal use (for technical use inside the library itself), false
18682/// otherwise. If you don't know what this is for, then set it to
18683/// false.
18684void
18686{qn = get_qualified_name(internal);}
18687
18688/// Build, cache and return the qualified name of the current instance
18689/// of the @ref reference_type_def. Subsequent invocations of this
18690/// function return the cached value.
18691///
18692/// @param internal set to true if the call is intended for an
18693/// internal use (for technical use inside the library itself), false
18694/// otherwise. If you don't know what this is for, then set it to
18695/// false.
18696///
18697/// @return the newly-built qualified name of the current instance of
18698/// @ref reference_type_def.
18699const interned_string&
18701{
18702 type_base_sptr pointed_to_type = get_pointed_to_type();
18703 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18704
18705 if (internal)
18706 {
18707 if (get_canonical_type())
18708 {
18709 if (priv_->internal_qualified_name_.empty())
18710 if (pointed_to_type)
18711 priv_->internal_qualified_name_ =
18712 get_name_of_reference_to_type(*pointed_to_type,
18713 is_lvalue(),
18714 /*qualified_name=*/
18715 is_typedef(pointed_to_type)
18716 ? false
18717 : true,
18718 /*internal=*/true);
18719 return priv_->internal_qualified_name_;
18720 }
18721 else
18722 {
18723 // As the type hasn't yet been canonicalized, its structure
18724 // (and so its name) can change. So let's invalidate the
18725 // cache where we store its name at each invocation of this
18726 // function.
18727 if (pointed_to_type)
18728 if (priv_->temp_internal_qualified_name_.empty())
18729 priv_->temp_internal_qualified_name_ =
18730 get_name_of_reference_to_type(*pointed_to_type,
18731 is_lvalue(),
18732 /*qualified_name=*/
18733 is_typedef(pointed_to_type)
18734 ? false
18735 : true,
18736 /*internal=*/true);
18737 return priv_->temp_internal_qualified_name_;
18738 }
18739 }
18740 else
18741 {
18743 {
18745 (get_name_of_reference_to_type(*pointed_to_type,
18746 is_lvalue(),
18747 /*qualified_name=*/true,
18748 /*internal=*/false));
18750 }
18751 else
18752 {
18753 // As the type hasn't yet been canonicalized, its structure
18754 // (and so its name) can change. So let's invalidate the
18755 // cache where we store its name at each invocation of this
18756 // function.
18757 if (pointed_to_type)
18759 (get_name_of_reference_to_type(*pointed_to_type,
18760 is_lvalue(),
18761 /*qualified_name=*/true,
18762 /*internal=*/false));
18764 }
18765 }
18766}
18767
18768/// Get the pretty representation of the current instance of @ref
18769/// reference_type_def.
18770///
18771/// @param internal set to true if the call is intended to get a
18772/// representation of the decl (or type) for the purpose of canonical
18773/// type comparison. This is mainly used in the function
18774/// type_base::get_canonical_type_for().
18775///
18776/// In other words if the argument for this parameter is true then the
18777/// call is meant for internal use (for technical use inside the
18778/// library itself), false otherwise. If you don't know what this is
18779/// for, then set it to false.
18780///
18781/// @param qualified_name if true, names emitted in the pretty
18782/// representation are fully qualified.
18783///
18784/// @return the pretty representatin of the @ref reference_type_def.
18785string
18787 bool qualified_name) const
18788{
18789 string result =
18791 (get_pointed_to_type()),
18792 is_lvalue(),
18793 qualified_name,
18794 internal);
18795
18796 return result;
18797}
18798
18799/// This implements the ir_traversable_base::traverse pure virtual
18800/// function.
18801///
18802/// @param v the visitor used on the current instance.
18803///
18804/// @return true if the entire IR node tree got traversed, false
18805/// otherwise.
18806bool
18808{
18809 if (v.type_node_has_been_visited(this))
18810 return true;
18811
18812 if (visiting())
18813 return true;
18814
18815 if (v.visit_begin(this))
18816 {
18817 visiting(true);
18818 if (type_base_sptr t = get_pointed_to_type())
18819 t->traverse(v);
18820 visiting(false);
18821 }
18822
18823 bool result = v.visit_end(this);
18825 return result;
18826}
18827
18828reference_type_def::~reference_type_def()
18829{}
18830
18831/// Turn equality of shared_ptr of @ref reference_type_def into a deep
18832/// equality; that is, make it compare the pointed to objects too.
18833///
18834/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18835/// of the equality.
18836///
18837/// @param r the shared_ptr of @ref reference_type_def on
18838/// right-hand-side of the equality.
18839///
18840/// @return true if the @ref reference_type_def pointed to by the
18841/// shared_ptrs are equal, false otherwise.
18842bool
18844{
18845 if (l.get() == r.get())
18846 return true;
18847 if (!!l != !!r)
18848 return false;
18849
18850 return *l == *r;
18851}
18852
18853/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
18854/// equality; that is, make it compare the pointed to objects too.
18855///
18856/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18857/// of the equality.
18858///
18859/// @param r the shared_ptr of @ref reference_type_def on
18860/// right-hand-side of the equality.
18861///
18862/// @return true iff the @ref reference_type_def pointed to by the
18863/// shared_ptrs are different.
18864bool
18866{return !operator==(l, r);}
18867
18868// </reference_type_def definitions>
18869
18870// <ptr_to_mbr_type definitions>
18871
18872/// The private data type of @ref ptr_to_mbr_type.
18873struct ptr_to_mbr_type::priv
18874{
18875 // The type of the data member this pointer-to-member-type
18876 // designates.
18877 type_base_sptr dm_type_;
18878 // The class (or typedef to potentially qualified class) containing
18879 // the data member this pointer-to-member-type designates.
18880 type_base_sptr containing_type_;
18881 interned_string internal_qualified_name_;
18882 interned_string temp_internal_qualified_name_;
18883
18884 priv()
18885 {}
18886
18887 priv(const type_base_sptr& dm_type, const type_base_sptr& containing_type)
18888 : dm_type_(dm_type),
18889 containing_type_(containing_type)
18890 {}
18891};// end struct ptr_to_mbr_type::priv
18892
18893/// A constructor for a @ref ptr_to_mbr_type type.
18894///
18895/// @param env the environment to construct the @ref ptr_to_mbr_type in.
18896///
18897/// @param member_type the member type of the of the @ref
18898/// ptr_to_mbr_type to construct.
18899///
18900/// @param containing_type the containing type of the @ref
18901/// ptr_to_mbr_type to construct.
18902///
18903/// @param size_in_bits the size (in bits) of the resulting type.
18904///
18905/// @param alignment_in_bits the alignment (in bits) of the resulting
18906/// type.
18907///
18908/// @param locus the source location of the definition of the
18909/// resulting type.
18910ptr_to_mbr_type::ptr_to_mbr_type(const environment& env,
18911 const type_base_sptr& member_type,
18912 const type_base_sptr& containing_type,
18913 size_t size_in_bits,
18914 size_t alignment_in_bits,
18915 const location& locus)
18916 : type_or_decl_base(env,
18917 POINTER_TO_MEMBER_TYPE
18918 | ABSTRACT_TYPE_BASE
18919 | ABSTRACT_DECL_BASE),
18920 type_base(env, size_in_bits, alignment_in_bits),
18921 decl_base(env, "", locus, ""),
18922 priv_(new priv(member_type, containing_type))
18923{
18925 ABG_ASSERT(member_type);
18926 ABG_ASSERT(containing_type);
18927 set_is_anonymous(false);
18928}
18929
18930/// Getter of the name of the current ptr-to-mbr-type.
18931///
18932/// This just returns the qualified name.
18933///
18934/// @return the (qualified) name of the the type.
18935const interned_string&
18937{
18938 return get_qualified_name(/*internal=*/false);
18939}
18940
18941/// Return the hash value of the current IR node.
18942///
18943/// Note that upon the first invocation, this member functions
18944/// computes the hash value and returns it. Subsequent invocations
18945/// just return the hash value that was previously calculated.
18946///
18947/// @return the hash value of the current IR node.
18948hash_t
18950{
18952 return h;
18953}
18954
18955/// Getter of the member type of the current @ref ptr_to_mbr_type.
18956///
18957/// @return the type of the member referred to by the current
18958/// @ptr_to_mbr_type.
18959const type_base_sptr&
18961{return priv_->dm_type_;}
18962
18963/// Getter of the type containing the member pointed-to by the current
18964/// @ref ptr_to_mbr_type.
18965///
18966/// @return the type containing the member pointed-to by the current
18967/// @ref ptr_to_mbr_type.
18968const type_base_sptr&
18970{return priv_->containing_type_;}
18971
18972/// Equality operator for the current @ref ptr_to_mbr_type.
18973///
18974///@param o the other instance of @ref ptr_to_mbr_type to compare the
18975///current instance to.
18976///
18977/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18978bool
18980{
18981 const ptr_to_mbr_type* other =
18982 dynamic_cast<const ptr_to_mbr_type*>(&o);
18983 if (!other)
18984 return false;
18985 return try_canonical_compare(this, other);
18986}
18987
18988/// Equality operator for the current @ref ptr_to_mbr_type.
18989///
18990///@param o the other instance of @ref ptr_to_mbr_type to compare the
18991///current instance to.
18992///
18993/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18994bool
18996{
18997 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18998 if (!other)
18999 return false;
19000 return *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/// Get the qualified name for the current @ref ptr_to_mbr_type.
19019///
19020/// @param qualified_name out parameter. This is set to the name of
19021/// the current @ref ptr_to_mbr_type.
19022///
19023/// @param internal if this is true, then the qualified name is for
19024/// the purpose of type canoicalization.
19025void
19027 bool internal) const
19028{qualified_name = get_qualified_name(internal);}
19029
19030/// Get the qualified name for the current @ref ptr_to_mbr_type.
19031///
19032/// @param internal if this is true, then the qualified name is for
19033/// the purpose of type canoicalization.
19034///
19035/// @return the qualified name for the current @ref ptr_to_mbr_type.
19036const interned_string&
19038{
19039 type_base_sptr member_type = get_member_type();
19040 type_base_sptr containing_type = get_containing_type();
19041
19042 if (internal)
19043 {
19044 if (get_canonical_type())
19045 {
19046 if (priv_->internal_qualified_name_.empty())
19047 priv_->internal_qualified_name_ =
19048 ptr_to_mbr_declaration_name(this, "",
19049 /*qualified=*/true,
19050 internal);
19051 return priv_->internal_qualified_name_;
19052 }
19053 else
19054 {
19055 priv_->temp_internal_qualified_name_ =
19056 ptr_to_mbr_declaration_name(this, "", /*qualified=*/true, internal);
19057 return priv_->temp_internal_qualified_name_;
19058 }
19059 }
19060 else
19061 {
19063 (ptr_to_mbr_declaration_name(this, "", /*qualified=*/true,
19064 /*internal=*/false));
19066 }
19067}
19068
19069/// This implements the ir_traversable_base::traverse pure virtual
19070/// function for @ref ptr_to_mbr_type.
19071///
19072/// @param v the visitor used on the current instance.
19073///
19074/// @return true if the entire IR node tree got traversed, false
19075/// otherwise.
19076bool
19078{
19079 if (v.type_node_has_been_visited(this))
19080 return true;
19081
19082 if (visiting())
19083 return true;
19084
19085 if (v.visit_begin(this))
19086 {
19087 visiting(true);
19088 if (type_base_sptr t = get_member_type())
19089 t->traverse(v);
19090
19091 if (type_base_sptr t = get_containing_type())
19092 t->traverse(v);
19093 visiting(false);
19094 }
19095
19096 bool result = v.visit_end(this);
19098 return result;
19099}
19100
19101/// Desctructor for @ref ptr_to_mbr_type.
19103{}
19104
19105
19106/// Compares two instances of @ref ptr_to_mbr_type.
19107///
19108/// If the two intances are different, set a bitfield to give some
19109/// insight about the kind of differences there are.
19110///
19111/// @param l the first artifact of the comparison.
19112///
19113/// @param r the second artifact of the comparison.
19114///
19115/// @param k a pointer to a bitfield that gives information about the
19116/// kind of changes there are between @p l and @p r. This one is set
19117/// iff @p k is non-null and the function returns false.
19118///
19119/// Please note that setting k to a non-null value does have a
19120/// negative performance impact because even if @p l and @p r are not
19121/// equal, the function keeps up the comparison in order to determine
19122/// the different kinds of ways in which they are different.
19123///
19124/// @return true if @p l equals @p r, false otherwise.
19125bool
19127{
19128 bool result = true;
19129
19130 if (!(l.decl_base::operator==(r)))
19131 {
19132 result = false;
19133 if (k)
19135 else
19136 result = false;
19137 }
19138
19139 if (l.get_member_type() != r.get_member_type())
19140 {
19141 if (k)
19142 {
19143 if (!types_have_similar_structure(&l, &r))
19145 *k |= SUBTYPE_CHANGE_KIND;
19146 }
19147 result = false;
19148 }
19149
19151 {
19152 if (k)
19153 {
19154 if (!types_have_similar_structure(&l, &r))
19156 *k |= SUBTYPE_CHANGE_KIND;
19157 }
19158 result = false;
19159 }
19160
19161 ABG_RETURN(result);
19162}
19163
19164// </ptr_to_mbr_type definitions>
19165
19166// <array_type_def definitions>
19167
19168// <array_type_def::subrange_type>
19169array_type_def::subrange_type::~subrange_type() = default;
19170
19171// <array_type_def::subrante_type::bound_value>
19172
19173/// Default constructor of the @ref
19174/// array_type_def::subrange_type::bound_value class.
19175///
19176/// Constructs an unsigned bound_value of value zero.
19178 : s_(UNSIGNED_SIGNEDNESS)
19179{
19180 v_.unsigned_ = 0;
19181}
19182
19183/// Initialize an unsigned bound_value with a given value.
19184///
19185/// @param v the initial bound value.
19187 : s_(UNSIGNED_SIGNEDNESS)
19188{
19189 v_.unsigned_ = v;
19190}
19191
19192/// Initialize a signed bound_value with a given value.
19193///
19194/// @param v the initial bound value.
19196 : s_(SIGNED_SIGNEDNESS)
19197{
19198 v_.signed_ = v;
19199}
19200
19201/// Getter of the signedness (unsigned VS signed) of the bound value.
19202///
19203/// @return the signedness of the bound value.
19204enum array_type_def::subrange_type::bound_value::signedness
19206{return s_;}
19207
19208/// Setter of the signedness (unsigned VS signed) of the bound value.
19209///
19210/// @param s the new signedness of the bound value.
19211void
19213{ s_ = s;}
19214
19215/// Getter of the bound value as a signed value.
19216///
19217/// @return the bound value as signed.
19218int64_t
19220{return v_.signed_;
19221}
19222
19223/// Getter of the bound value as an unsigned value.
19224///
19225/// @return the bound value as unsigned.
19226uint64_t
19228{return v_.unsigned_;}
19229
19230/// Setter of the bound value as unsigned.
19231///
19232/// @param v the new unsigned value.
19233void
19235{
19236 s_ = UNSIGNED_SIGNEDNESS;
19237 v_.unsigned_ = v;
19238}
19239
19240/// Setter of the bound value as signed.
19241///
19242/// @param v the new signed value.
19243void
19245{
19246 s_ = SIGNED_SIGNEDNESS;
19247 v_.signed_ = v;
19248}
19249
19250/// Equality operator of the bound value.
19251///
19252/// @param v the other bound value to compare with.
19253///
19254/// @return true iff the current bound value equals @p v.
19255bool
19257{
19258 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
19259}
19260
19261// </array_type_def::subrante_type::bound_value>
19262
19263struct array_type_def::subrange_type::priv
19264{
19265 bound_value lower_bound_;
19266 bound_value upper_bound_;
19267 type_base_wptr underlying_type_;
19269 bool infinite_;
19270
19271 priv(bound_value ub,
19272 translation_unit::language l = translation_unit::LANG_C11)
19273 : upper_bound_(ub), language_(l), infinite_(false)
19274 {}
19275
19276 priv(bound_value lb, bound_value ub,
19277 translation_unit::language l = translation_unit::LANG_C11)
19278 : lower_bound_(lb), upper_bound_(ub),
19279 language_(l), infinite_(false)
19280 {}
19281
19282 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
19283 translation_unit::language l = translation_unit::LANG_C11)
19284 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
19285 language_(l), infinite_(false)
19286 {}
19287};
19288
19289/// Constructor of an array_type_def::subrange_type type.
19290///
19291/// @param env the environment this type was created from.
19292///
19293/// @param name the name of the subrange type.
19294///
19295/// @param lower_bound the lower bound of the array. This is
19296/// generally zero (at least for C and C++).
19297///
19298/// @param upper_bound the upper bound of the array.
19299///
19300/// @param underlying_type the underlying type of the subrange type.
19301///
19302/// @param loc the source location where the type is defined.
19303array_type_def::subrange_type::subrange_type(const environment& env,
19304 const string& name,
19305 bound_value lower_bound,
19306 bound_value upper_bound,
19307 const type_base_sptr& utype,
19308 const location& loc,
19310 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19311 type_base(env,
19312 utype
19313 ? utype->get_size_in_bits()
19314 : 0,
19315 0),
19316 decl_base(env, name, loc, ""),
19317 priv_(new priv(lower_bound, upper_bound, utype, l))
19318{
19320}
19321
19322/// Constructor of the array_type_def::subrange_type type.
19323///
19324/// @param env the environment this type is being created in.
19325///
19326/// @param name the name of the subrange type.
19327///
19328/// @param lower_bound the lower bound of the array. This is
19329/// generally zero (at least for C and C++).
19330///
19331/// @param upper_bound the upper bound of the array.
19332///
19333/// @param loc the source location where the type is defined.
19334///
19335/// @param l the language that generated this subrange.
19336array_type_def::subrange_type::subrange_type(const environment& env,
19337 const string& name,
19338 bound_value lower_bound,
19339 bound_value upper_bound,
19340 const location& loc,
19342 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19343 type_base(env, /*size-in-bits=*/0, /*alignment=*/0),
19344 decl_base(env, name, loc, ""),
19345 priv_(new priv(lower_bound, upper_bound, l))
19346{
19348}
19349
19350/// Constructor of the array_type_def::subrange_type type.
19351///
19352/// @param env the environment this type is being created from.
19353///
19354/// @param name of the name of type.
19355///
19356/// @param upper_bound the upper bound of the array. The lower bound
19357/// is considered to be zero.
19358///
19359/// @param loc the source location of the type.
19360///
19361/// @param the language that generated this type.
19362array_type_def::subrange_type::subrange_type(const environment& env,
19363 const string& name,
19364 bound_value upper_bound,
19365 const location& loc,
19367 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19368 type_base(env, upper_bound.get_unsigned_value(), 0),
19369 decl_base(env, name, loc, ""),
19370 priv_(new priv(upper_bound, l))
19371{
19373}
19374
19375/// Return the hash value of the current IR node.
19376///
19377/// Note that upon the first invocation, this member functions
19378/// computes the hash value and returns it. Subsequent invocations
19379/// just return the hash value that was previously calculated.
19380///
19381/// @return the hash value of the current IR node.
19382hash_t
19384{
19386 return h;
19387}
19388
19389/// Getter of the underlying type of the subrange, that is, the type
19390/// that defines the range.
19391///
19392/// @return the underlying type.
19393type_base_sptr
19395{return priv_->underlying_type_.lock();}
19396
19397/// Setter of the underlying type of the subrange, that is, the type
19398/// that defines the range.
19399///
19400/// @param u the new underlying type.
19401void
19403{
19404 ABG_ASSERT(priv_->underlying_type_.expired());
19405 priv_->underlying_type_ = u;
19406 if (u)
19407 set_size_in_bits(u->get_size_in_bits());
19408}
19409
19410/// Getter of the upper bound of the subrange type.
19411///
19412/// @return the upper bound of the subrange type.
19413int64_t
19415{return priv_->upper_bound_.get_signed_value();}
19416
19417/// Getter of the lower bound of the subrange type.
19418///
19419/// @return the lower bound of the subrange type.
19420int64_t
19422{return priv_->lower_bound_.get_signed_value();}
19423
19424/// Setter of the upper bound of the subrange type.
19425///
19426/// @param ub the new value of the upper bound.
19427void
19429{priv_->upper_bound_ = ub;}
19430
19431/// Setter of the lower bound.
19432///
19433/// @param lb the new value of the lower bound.
19434void
19436{priv_->lower_bound_ = lb;}
19437
19438/// Getter of the length of the subrange type.
19439///
19440/// Note that a length of zero means the array has an infinite (or
19441/// rather a non-known) size.
19442///
19443/// @return the length of the subrange type.
19444uint64_t
19446{
19447 if (is_non_finite())
19448 return 0;
19449
19450 // A subrange can have an upper bound that is lower than its lower
19451 // bound. This is possible in Ada for instance. In that case, the
19452 // length of the subrange is considered to be zero.
19453 if (get_upper_bound() >= get_lower_bound())
19454 return get_upper_bound() - get_lower_bound() + 1;
19455 return 0;
19456}
19457
19458/// Test if the length of the subrange type is infinite.
19459///
19460/// @return true iff the length of the subrange type is infinite.
19461bool
19463{return priv_->infinite_;}
19464
19465/// Set the infinite-ness status of the subrange type.
19466///
19467/// @param f true iff the length of the subrange type should be set to
19468/// being infinite.
19469void
19471{priv_->infinite_ = f;}
19472
19473/// Getter of the language that generated this type.
19474///
19475/// @return the language of this type.
19478{return priv_->language_;}
19479
19480/// Return a string representation of the sub range.
19481///
19482/// @return the string representation of the sub range.
19483string
19485{
19486 std::ostringstream o;
19487
19489 {
19490 type_base_sptr underlying_type = get_underlying_type();
19491 if (underlying_type)
19492 o << ir::get_pretty_representation(underlying_type, false) << " ";
19493 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
19494 }
19495 else if (is_non_finite())
19496 o << "[]";
19497 else
19498 o << "[" << get_length() << "]";
19499
19500 return o.str();
19501}
19502
19503/// Return a string representation of a vector of subranges
19504///
19505/// @return the string representation of a vector of sub ranges.
19506string
19508{
19509 if (v.empty())
19510 return "[]";
19511
19512 string r;
19513 for (vector<subrange_sptr>::const_iterator i = v.begin();
19514 i != v.end();
19515 ++i)
19516 r += (*i)->as_string();
19517
19518 return r;
19519}
19520
19521/// Compares two isntances of @ref array_type_def::subrange_type.
19522///
19523/// If the two intances are different, set a bitfield to give some
19524/// insight about the kind of differences there are.
19525///
19526/// @param l the first artifact of the comparison.
19527///
19528/// @param r the second artifact of the comparison.
19529///
19530/// @param k a pointer to a bitfield that gives information about the
19531/// kind of changes there are between @p l and @p r. This one is set
19532/// iff @p k is non-null and the function returns false.
19533///
19534/// Please note that setting k to a non-null value does have a
19535/// negative performance impact because even if @p l and @p r are not
19536/// equal, the function keeps up the comparison in order to determine
19537/// the different kinds of ways in which they are different.
19538///
19539/// @return true if @p l equals @p r, false otherwise.
19540bool
19543 change_kind* k)
19544{
19545 bool result = true;
19546
19547 if (l.get_lower_bound() != r.get_lower_bound()
19548 || l.get_upper_bound() != r.get_upper_bound()
19549 || l.get_name() != r.get_name())
19550 {
19551 result = false;
19552 if (k)
19554 else
19555 ABG_RETURN(result);
19556 }
19557
19558 if (l.get_underlying_type()
19559 && r.get_underlying_type()
19560 && (*l.get_underlying_type() != *r.get_underlying_type()))
19561 {
19562 result = false;
19563 if (k)
19564 *k |= SUBTYPE_CHANGE_KIND;
19565 else
19566 ABG_RETURN(result);
19567 }
19568
19569 ABG_RETURN(result);
19570}
19571
19572/// Equality operator.
19573///
19574/// @param o the other subrange to test against.
19575///
19576/// @return true iff @p o equals the current instance of
19577/// array_type_def::subrange_type.
19578bool
19580{
19581 const subrange_type* other =
19582 dynamic_cast<const subrange_type*>(&o);
19583 if (!other)
19584 return false;
19585 return try_canonical_compare(this, other);
19586}
19587
19588/// Equality operator.
19589///
19590/// @param o the other subrange to test against.
19591///
19592/// @return true iff @p o equals the current instance of
19593/// array_type_def::subrange_type.
19594bool
19596{
19597 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19598 if (!other)
19599 return false;
19600 return *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 type_base &t = o;
19613 return operator==(t);
19614}
19615
19616/// Equality operator.
19617///
19618/// @param o the other subrange to test against.
19619///
19620/// @return true iff @p o equals the current instance of
19621/// array_type_def::subrange_type.
19622bool
19624{return !operator==(o);}
19625
19626/// Equality operator.
19627///
19628/// @param o the other subrange to test against.
19629///
19630/// @return true iff @p o equals the current instance of
19631/// array_type_def::subrange_type.
19632bool
19634{return !operator==(o);}
19635
19636/// Inequality operator.
19637///
19638/// @param o the other subrange to test against.
19639///
19640/// @return true iff @p o is different from the current instance of
19641/// array_type_def::subrange_type.
19642bool
19644{return !operator==(o);}
19645
19646/// Build a pretty representation for an
19647/// array_type_def::subrange_type.
19648///
19649/// @param internal set to true if the call is intended to get a
19650/// representation of the decl (or type) for the purpose of canonical
19651/// type comparison. This is mainly used in the function
19652/// type_base::get_canonical_type_for().
19653///
19654/// In other words if the argument for this parameter is true then the
19655/// call is meant for internal use (for technical use inside the
19656/// library itself), false otherwise. If you don't know what this is
19657/// for, then set it to false.
19658///
19659/// @return a copy of the pretty representation of the current
19660/// instance of typedef_decl.
19661string
19663{
19664 string name = get_name();
19665 string repr;
19666
19667 if (name.empty())
19668 repr += "<anonymous range>";
19669 else
19670 repr += "<range " + get_name() + ">";
19671 repr += as_string();
19672
19673 return repr;
19674}
19675
19676/// This implements the ir_traversable_base::traverse pure virtual
19677/// function.
19678///
19679/// @param v the visitor used on the current instance.
19680///
19681/// @return true if the entire IR node tree got traversed, false
19682/// otherwise.
19683bool
19685{
19686 if (v.type_node_has_been_visited(this))
19687 return true;
19688
19689 if (v.visit_begin(this))
19690 {
19691 visiting(true);
19692 if (type_base_sptr u = get_underlying_type())
19693 u->traverse(v);
19694 visiting(false);
19695 }
19696
19697 bool result = v.visit_end(this);
19699 return result;
19700}
19701
19702// </array_type_def::subrange_type>
19703
19704struct array_type_def::priv
19705{
19706 type_base_wptr element_type_;
19707 subranges_type subranges_;
19708 interned_string temp_internal_qualified_name_;
19709 interned_string internal_qualified_name_;
19710
19711 priv(type_base_sptr t)
19712 : element_type_(t)
19713 {}
19714
19715 priv(type_base_sptr t, subranges_type subs)
19716 : element_type_(t), subranges_(subs)
19717 {}
19718
19719 priv()
19720 {}
19721};
19722
19723/// Constructor for the type array_type_def
19724///
19725/// Note how the constructor expects a vector of subrange
19726/// objects. Parsing of the array information always entails
19727/// parsing the subrange info as well, thus the class subrange_type
19728/// is defined inside class array_type_def and also parsed
19729/// simultaneously.
19730///
19731/// @param e_type the type of the elements contained in the array
19732///
19733/// @param subs a vector of the array's subranges(dimensions)
19734///
19735/// @param locus the source location of the array type definition.
19736array_type_def::array_type_def(const type_base_sptr e_type,
19737 const std::vector<subrange_sptr>& subs,
19738 const location& locus)
19740 ARRAY_TYPE
19741 | ABSTRACT_TYPE_BASE
19742 | ABSTRACT_DECL_BASE),
19743 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
19744 decl_base(e_type->get_environment(), locus),
19745 priv_(new priv(e_type))
19746{
19748 append_subranges(subs);
19749}
19750
19751/// Constructor for the type array_type_def
19752///
19753/// This constructor builds a temporary array that has no element type
19754/// associated. Later when the element type is available, it be set
19755/// with the array_type_def::set_element_type() member function.
19756///
19757/// Note how the constructor expects a vector of subrange
19758/// objects. Parsing of the array information always entails
19759/// parsing the subrange info as well, thus the class subrange_type
19760/// is defined inside class array_type_def and also parsed
19761/// simultaneously.
19762///
19763/// @param env the environment of the array type.
19764///
19765/// @param subs a vector of the array's subranges(dimensions)
19766///
19767/// @param locus the source location of the array type definition.
19768array_type_def::array_type_def(const environment& env,
19769 const std::vector<subrange_sptr>& subs,
19770 const location& locus)
19771 : type_or_decl_base(env,
19772 ARRAY_TYPE
19773 | ABSTRACT_TYPE_BASE
19774 | ABSTRACT_DECL_BASE),
19775 type_base(env, 0, 0),
19776 decl_base(env, locus),
19777 priv_(new priv)
19778{
19780 append_subranges(subs);
19781}
19782
19783/// Return the hash value of the current IR node.
19784///
19785/// Note that upon the first invocation, this member functions
19786/// computes the hash value and returns it. Subsequent invocations
19787/// just return the hash value that was previously calculated.
19788///
19789/// @return the hash value of the current IR node.
19790hash_t
19792{
19794 return h;
19795}
19796
19797/// Update the size of the array.
19798///
19799/// This function computes the size of the array and sets it using
19800/// type_base::set_size_in_bits().
19801void
19802array_type_def::update_size()
19803{
19804 type_base_sptr e = priv_->element_type_.lock();
19805 if (e)
19806 {
19807 size_t s = e->get_size_in_bits();
19808 if (s)
19809 {
19810 for (const auto &sub : get_subranges())
19811 s *= sub->get_length();
19813 }
19814 set_alignment_in_bits(e->get_alignment_in_bits());
19815 }
19816}
19817
19818string
19819array_type_def::get_subrange_representation() const
19820{
19822 return r;
19823}
19824
19825/// Get the pretty representation of the current instance of @ref
19826/// array_type_def.
19827///
19828/// @param internal set to true if the call is intended to get a
19829/// representation of the decl (or type) for the purpose of canonical
19830/// type comparison. This is mainly used in the function
19831/// type_base::get_canonical_type_for().
19832///
19833/// In other words if the argument for this parameter is true then the
19834/// call is meant for internal use (for technical use inside the
19835/// library itself), false otherwise. If you don't know what this is
19836/// for, then set it to false.
19837/// @param internal set to true if the call is intended for an
19838/// internal use (for technical use inside the library itself), false
19839/// otherwise. If you don't know what this is for, then set it to
19840/// false.
19841///
19842/// @return the pretty representation of the ABI artifact.
19843string
19845 bool qualified_name) const
19846{
19847 return array_declaration_name(this, /*variable_name=*/"",
19848 qualified_name, internal);
19849}
19850
19851/// Compares two instances of @ref array_type_def.
19852///
19853/// If the two intances are different, set a bitfield to give some
19854/// insight about the kind of differences there are.
19855///
19856/// @param l the first artifact of the comparison.
19857///
19858/// @param r the second artifact of the comparison.
19859///
19860/// @param k a pointer to a bitfield that gives information about the
19861/// kind of changes there are between @p l and @p r. This one is set
19862/// iff @p k is non-null and the function returns false.
19863///
19864/// Please note that setting k to a non-null value does have a
19865/// negative performance impact because even if @p l and @p r are not
19866/// equal, the function keeps up the comparison in order to determine
19867/// the different kinds of ways in which they are different.
19868///
19869/// @return true if @p l equals @p r, false otherwise.
19870bool
19872{
19873 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
19874 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
19875
19876 bool result = true;
19877 if (this_subs.size() != other_subs.size())
19878 {
19879 result = false;
19880 if (k)
19882 else
19884 }
19885
19886 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19887 for (i = this_subs.begin(), j = other_subs.begin();
19888 i != this_subs.end() && j != other_subs.end();
19889 ++i, ++j)
19890 if (**i != **j)
19891 {
19892 result = false;
19893 if (k)
19894 {
19896 break;
19897 }
19898 else
19900 }
19901
19902 // Compare the element types modulo the typedefs they might have
19903 if (l.get_element_type() != r.get_element_type())
19904 {
19905 result = false;
19906 if (k)
19907 *k |= SUBTYPE_CHANGE_KIND;
19908 else
19910 }
19911
19912 ABG_RETURN(result);
19913}
19914
19915/// Test if two array types are equals modulo CV qualifiers.
19916///
19917/// @param l the first array of the comparison.
19918///
19919/// @param r the second array of the comparison.
19920///
19921/// @return true iff @p l equals @p r or, if they are different, the
19922/// difference between the too is just a matter of CV qualifiers.
19923bool
19925{
19926 if (l == r)
19927 return true;
19928
19929 if (!l || !r)
19931
19934
19935 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
19936 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
19937
19938 if (this_subs.size() != other_subs.size())
19940
19941 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19942 for (i = this_subs.begin(), j = other_subs.begin();
19943 i != this_subs.end() && j != other_subs.end();
19944 ++i, ++j)
19945 if (**i != **j)
19947
19948 type_base *first_element_type =
19950 type_base *second_element_type =
19952
19953 if (*first_element_type != *second_element_type)
19955
19956 return true;
19957}
19958
19959/// Test if two array types are equals modulo CV qualifiers.
19960///
19961/// @param l the first array of the comparison.
19962///
19963/// @param r the second array of the comparison.
19964///
19965/// @return true iff @p l equals @p r or, if they are different, the
19966/// difference between the too is just a matter of CV qualifiers.
19967bool
19969 const array_type_def_sptr& r)
19970{return equals_modulo_cv_qualifier(l.get(), r.get());}
19971
19972/// Test if two pointer types are equals modulo CV qualifiers.
19973///
19974/// @param l the first pointer of the comparison.
19975///
19976/// @param r the second pointer of the comparison.
19977///
19978/// @return true iff @p l equals @p r or, if they are different, the
19979/// difference between the too is just a matter of CV qualifiers.
19980bool
19982{
19983 if (l == r)
19984 return true;
19985
19986 if (!l || !r)
19988
19989 type_base_sptr l_ptt = l->get_pointed_to_type(),
19990 r_ptt = r->get_pointed_to_type();
19991
19992 do
19993 {
19994 l_ptt = peel_qualified_or_typedef_type(l_ptt);
19995 r_ptt = peel_qualified_or_typedef_type(r_ptt);
19996
19997 l_ptt = is_pointer_type(l_ptt)
19999 : l_ptt;
20000
20001 r_ptt = is_pointer_type(r_ptt)
20003 : r_ptt;
20004 } while (is_pointer_type(l_ptt) && is_pointer_type(r_ptt));
20005
20006 l_ptt = peel_qualified_or_typedef_type(l_ptt);
20007 r_ptt = peel_qualified_or_typedef_type(r_ptt);
20008
20009 return *l_ptt == *r_ptt;
20010}
20011
20012/// Test if two pointer types are equals modulo CV qualifiers.
20013///
20014/// @param l the first pointer of the comparison.
20015///
20016/// @param r the second pointer of the comparison.
20017///
20018/// @return true iff @p l equals @p r or, if they are different, the
20019/// difference between the too is just a matter of CV qualifiers.
20020bool
20022 const pointer_type_def_sptr& r)
20023{return equals_modulo_cv_qualifier(l.get(), r.get());}
20024
20025/// Get the language of the array.
20026///
20027/// @return the language of the array.
20030{
20031 const std::vector<subrange_sptr>& subranges =
20032 get_subranges();
20033
20034 if (subranges.empty())
20035 return translation_unit::LANG_C11;
20036 return subranges.front()->get_language();
20037}
20038
20039bool
20041{
20042 const array_type_def* other =
20043 dynamic_cast<const array_type_def*>(&o);
20044 if (!other)
20045 return false;
20046 return try_canonical_compare(this, other);
20047}
20048
20049bool
20051{
20052 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20053 if (!other)
20054 return false;
20055 return *this == *other;
20056}
20057
20058/// Getter of the type of an array element.
20059///
20060/// @return the type of an array element.
20061const type_base_sptr
20063{return priv_->element_type_.lock();}
20064
20065/// Setter of the type of array element.
20066///
20067/// Beware that after using this function, one might want to
20068/// re-compute the canonical type of the array, if one has already
20069/// been computed.
20070///
20071/// The intended use of this method is to permit in-place adjustment
20072/// of the element type's qualifiers. In particular, the size of the
20073/// element type should not be changed.
20074///
20075/// @param element_type the new element type to set.
20076void
20077array_type_def::set_element_type(const type_base_sptr& element_type)
20078{
20079 priv_->element_type_ = element_type;
20080 update_size();
20082}
20083
20084/// Append subranges from the vector @param subs to the current
20085/// vector of subranges.
20086void
20087array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
20088{
20089
20090 for (const auto &sub : subs)
20091 priv_->subranges_.push_back(sub);
20092
20093 update_size();
20095}
20096
20097/// @return true if one of the sub-ranges of the array is infinite, or
20098/// if the array has no sub-range at all, also meaning that the size
20099/// of the array is infinite.
20100bool
20102{
20103 if (priv_->subranges_.empty())
20104 return true;
20105
20106 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
20107 priv_->subranges_.begin();
20108 i != priv_->subranges_.end();
20109 ++i)
20110 if ((*i)->is_non_finite())
20111 return true;
20112
20113 return false;
20114}
20115
20116int
20117array_type_def::get_dimension_count() const
20118{return priv_->subranges_.size();}
20119
20120/// Build and return the qualified name of the current instance of the
20121/// @ref array_type_def.
20122///
20123/// @param qn output parameter. Is set to the newly-built qualified
20124/// name of the current instance of @ref array_type_def.
20125///
20126/// @param internal set to true if the call is intended for an
20127/// internal use (for technical use inside the library itself), false
20128/// otherwise. If you don't know what this is for, then set it to
20129/// false.
20130void
20132{qn = get_qualified_name(internal);}
20133
20134/// Compute the qualified name of the array.
20135///
20136/// @param internal set to true if the call is intended for an
20137/// internal use (for technical use inside the library itself), false
20138/// otherwise. If you don't know what this is for, then set it to
20139/// false.
20140///
20141/// @return the resulting qualified name.
20142const interned_string&
20144{
20145 if (internal)
20146 {
20147 if (get_canonical_type())
20148 {
20149 if (priv_->internal_qualified_name_.empty())
20150 priv_->internal_qualified_name_ =
20151 array_declaration_name(this, /*variable_name=*/"",
20152 /*qualified=*/false,
20153 /*internal=*/true);
20154 return priv_->internal_qualified_name_;
20155 }
20156 else
20157 {
20158 priv_->temp_internal_qualified_name_ =
20159 array_declaration_name(this, /*variable_name=*/"",
20160 /*qualified*/false, /*internal*/true);
20161 return priv_->temp_internal_qualified_name_;
20162 }
20163 }
20164 else
20165 {
20166 if (get_canonical_type())
20167 {
20168 if (decl_base::peek_qualified_name().empty())
20169 set_qualified_name(array_declaration_name(this,
20170 /*variable_name=*/"",
20171 /*qualified=*/false,
20172 /*internal=*/false));
20174 }
20175 else
20176 {
20178 (array_declaration_name(this, /*variable_name=*/"",
20179 /*qualified=*/false,
20180 /*internal=*/false));
20182 }
20183 }
20184}
20185
20186/// This implements the ir_traversable_base::traverse pure virtual
20187/// function.
20188///
20189/// @param v the visitor used on the current instance.
20190///
20191/// @return true if the entire IR node tree got traversed, false
20192/// otherwise.
20193bool
20195{
20196 if (v.type_node_has_been_visited(this))
20197 return true;
20198
20199 if (visiting())
20200 return true;
20201
20202 if (v.visit_begin(this))
20203 {
20204 visiting(true);
20205 if (type_base_sptr t = get_element_type())
20206 t->traverse(v);
20207 visiting(false);
20208 }
20209
20210 bool result = v.visit_end(this);
20212 return result;
20213}
20214
20215const location&
20216array_type_def::get_location() const
20217{return decl_base::get_location();}
20218
20219/// Get the array's subranges
20220const std::vector<array_type_def::subrange_sptr>&
20222{return priv_->subranges_;}
20223
20224array_type_def::~array_type_def()
20225{}
20226
20227// </array_type_def definitions>
20228
20229// <enum_type_decl definitions>
20230
20231class enum_type_decl::priv
20232{
20233 type_base_sptr underlying_type_;
20234 enumerators enumerators_;
20235 mutable enumerators sorted_enumerators_;
20236
20237 friend class enum_type_decl;
20238
20239 priv();
20240
20241public:
20242 priv(type_base_sptr underlying_type,
20244 : underlying_type_(underlying_type),
20245 enumerators_(enumerators)
20246 {}
20247}; // end class enum_type_decl::priv
20248
20249/// Constructor.
20250///
20251/// @param name the name of the type declaration.
20252///
20253/// @param locus the source location where the type was defined.
20254///
20255/// @param underlying_type the underlying type of the enum.
20256///
20257/// @param enums the enumerators of this enum type.
20258///
20259/// @param linkage_name the linkage name of the enum.
20260///
20261/// @param vis the visibility of the enum type.
20262enum_type_decl::enum_type_decl(const string& name,
20263 const location& locus,
20264 type_base_sptr underlying_type,
20265 enumerators& enums,
20266 const string& linkage_name,
20267 visibility vis)
20268 : type_or_decl_base(underlying_type->get_environment(),
20269 ENUM_TYPE
20270 | ABSTRACT_TYPE_BASE
20271 | ABSTRACT_DECL_BASE),
20272 type_base(underlying_type->get_environment(),
20273 underlying_type->get_size_in_bits(),
20274 underlying_type->get_alignment_in_bits()),
20275 decl_base(underlying_type->get_environment(),
20276 name, locus, linkage_name, vis),
20277 priv_(new priv(underlying_type, enums))
20278{
20280 for (enumerators::iterator e = get_enumerators().begin();
20281 e != get_enumerators().end();
20282 ++e)
20283 e->set_enum_type(this);
20284}
20285
20286/// Return the hash value of the current IR node.
20287///
20288/// Note that upon the first invocation, this member functions
20289/// computes the hash value and returns it. Subsequent invocations
20290/// just return the hash value that was previously calculated.
20291///
20292/// @return the hash value of the current IR node.
20293hash_t
20295{
20297 return h;
20298}
20299
20300/// Return the underlying type of the enum.
20301type_base_sptr
20303{return priv_->underlying_type_;}
20304
20305/// @return the list of enumerators of the enum.
20308{return priv_->enumerators_;}
20309
20310/// @return the list of enumerators of the enum.
20313{return priv_->enumerators_;}
20314
20315/// Get the lexicographically sorted vector of enumerators.
20316///
20317/// @return the lexicographically sorted vector of enumerators.
20320{
20321 if (priv_->sorted_enumerators_.empty())
20322 {
20323 for (auto e = get_enumerators().rbegin();
20324 e != get_enumerators().rend();
20325 ++e)
20326 priv_->sorted_enumerators_.push_back(*e);
20327
20328 std::sort(priv_->sorted_enumerators_.begin(),
20329 priv_->sorted_enumerators_.end(),
20330 [](const enum_type_decl::enumerator& l,
20332 {
20333 if (l.get_name() == r.get_name())
20334 return l.get_value() < r.get_value();
20335 return (l.get_name() < r.get_name());
20336 });
20337 }
20338
20339 return priv_->sorted_enumerators_;
20340}
20341
20342/// Find an enumerator by its value.
20343///
20344/// @param value the enumerator value to look for.
20345///
20346/// @param result output parameter. This is set to the enumerator
20347/// which value is @p value, if found. This is set iff the function
20348/// returns true.
20349///
20350/// @return true iff an enumerator with value @p value was found and
20351/// returned by argument via @p result.
20352bool
20355{
20356 for (auto& e : get_enumerators())
20357 if (e.get_value() == value)
20358 {
20359 result = e;
20360 return true;
20361 }
20362
20363 return false;
20364}
20365
20366/// Find an enumerator by its name
20367///
20368/// @param name the enumerator name to look for.
20369///
20370/// @param result output parameter. This is set to the enumerator
20371/// which name is @p name, if found. This is set iff the function
20372/// returns true.
20373///
20374/// @return true iff an enumerator with name @p name was found and
20375/// returned by argument via @p result.
20376bool
20379{
20380 for (auto& e : get_enumerators())
20381 if (e.get_name() == name)
20382 {
20383 result = e;
20384 return true;
20385 }
20386
20387 return false;
20388}
20389
20390/// Get the pretty representation of the current instance of @ref
20391/// enum_type_decl.
20392///
20393/// @param internal set to true if the call is intended to get a
20394/// representation of the decl (or type) for the purpose of canonical
20395/// type comparison. This is mainly used in the function
20396/// type_base::get_canonical_type_for().
20397///
20398/// In other words if the argument for this parameter is true then the
20399/// call is meant for internal use (for technical use inside the
20400/// library itself), false otherwise. If you don't know what this is
20401/// for, then set it to false.
20402///
20403/// @param qualified_name if true, names emitted in the pretty
20404/// representation are fully qualified.
20405///
20406/// @return the pretty representation of the enum type.
20407string
20409 bool qualified_name) const
20410{
20411 string r = "enum ";
20412
20413 if (internal && get_is_anonymous())
20414 r += get_type_name(this, qualified_name, /*internal=*/true);
20415 else if (get_is_anonymous())
20416 r += get_enum_flat_representation(*this, "",
20417 /*one_line=*/true,
20418 qualified_name);
20419 else
20421 qualified_name);
20422 return r;
20423}
20424
20425/// This implements the ir_traversable_base::traverse pure virtual
20426/// function.
20427///
20428/// @param v the visitor used on the current instance.
20429///
20430/// @return true if the entire IR node tree got traversed, false
20431/// otherwise.
20432bool
20434{
20435 if (v.type_node_has_been_visited(this))
20436 return true;
20437
20438 if (visiting())
20439 return true;
20440
20441 if (v.visit_begin(this))
20442 {
20443 visiting(true);
20444 if (type_base_sptr t = get_underlying_type())
20445 t->traverse(v);
20446 visiting(false);
20447 }
20448
20449 bool result = v.visit_end(this);
20451 return result;
20452}
20453
20454/// Destructor for the enum type declaration.
20456{}
20457
20458/// Test if two enums differ, but not by a name change.
20459///
20460/// @param l the first enum to consider.
20461///
20462/// @param r the second enum to consider.
20463///
20464/// @return true iff @p l differs from @p r by anything but a name
20465/// change.
20466bool
20468 const enum_type_decl& r,
20469 change_kind* k)
20470{
20471 bool result = false;
20473 {
20474 result = true;
20475 if (k)
20476 *k |= SUBTYPE_CHANGE_KIND;
20477 else
20478 return true;
20479 }
20480
20481 enum_type_decl::enumerators::const_iterator i, j;
20482 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
20483 i != l.get_enumerators().end() && j != r.get_enumerators().end();
20484 ++i, ++j)
20485 if (*i != *j)
20486 {
20487 result = true;
20488 if (k)
20489 {
20491 break;
20492 }
20493 else
20494 return true;
20495 }
20496
20497 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
20498 {
20499 result = true;
20500 if (k)
20502 else
20503 return true;
20504 }
20505
20506 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
20509 string n_l = l.get_name();
20510 string n_r = r.get_name();
20511 local_r.set_qualified_name(qn_l);
20512 local_r.set_name(n_l);
20513
20514 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
20515 {
20516 result = true;
20517 if (k)
20518 {
20519 if (!l.decl_base::operator==(r))
20521 if (!l.type_base::operator==(r))
20523 }
20524 else
20525 {
20526 local_r.set_name(n_r);
20527 local_r.set_qualified_name(qn_r);
20528 return true;
20529 }
20530 }
20531 local_r.set_qualified_name(qn_r);
20532 local_r.set_name(n_r);
20533
20534 return result;
20535}
20536
20537/// Test if a given enumerator is found present in an enum.
20538///
20539/// This is a subroutine of the equals function for enums.
20540///
20541/// @param enr the enumerator to consider.
20542///
20543/// @param enom the enum to consider.
20544///
20545/// @return true iff the enumerator @p enr is present in the enum @p
20546/// enom.
20547bool
20549 const enum_type_decl &enom)
20550{
20551 for (const auto &e : enom.get_enumerators())
20552 if (e == enr)
20553 return true;
20554 return false;
20555}
20556
20557/// Check if two enumerators values are equal.
20558///
20559/// This function doesn't check if the names of the enumerators are
20560/// equal or not.
20561///
20562/// @param enr the first enumerator to consider.
20563///
20564/// @param enl the second enumerator to consider.
20565///
20566/// @return true iff @p enr has the same value as @p enl.
20567static bool
20568enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
20569 const enum_type_decl::enumerator &enl)
20570{return enr.get_value() == enl.get_value();}
20571
20572/// Detect if a given enumerator value is present in an enum.
20573///
20574/// This function looks inside the enumerators of a given enum and
20575/// detect if the enum contains at least one enumerator or a given
20576/// value. The function also detects if the enumerator value we are
20577/// looking at is present in the enum with a different name. An
20578/// enumerator with the same value but with a different name is named
20579/// a "redundant enumerator". The function returns the set of
20580/// enumerators that are redundant with the value we are looking at.
20581///
20582/// @param enr the enumerator to consider.
20583///
20584/// @param enom the enum to consider.
20585///
20586/// @param redundant_enrs if the function returns true, then this
20587/// vector is filled with enumerators that are redundant with the
20588/// value of @p enr.
20589///
20590/// @return true iff the function detects that @p enom contains
20591/// enumerators with the same value as @p enr.
20592static bool
20593is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
20594 const enum_type_decl &enom,
20595 vector<enum_type_decl::enumerator>& redundant_enrs)
20596{
20597 bool found = false;
20598 for (const auto &e : enom.get_enumerators())
20599 if (enumerators_values_are_equal(e, enr))
20600 {
20601 found = true;
20602 if (e != enr)
20603 redundant_enrs.push_back(e);
20604 }
20605
20606 return found;
20607}
20608
20609/// Check if an enumerator value is redundant in a given enum.
20610///
20611/// Given an enumerator value, this function detects if an enum
20612/// contains at least one enumerator with the the same value but with
20613/// a different name.
20614///
20615/// @param enr the enumerator to consider.
20616///
20617/// @param enom the enum to consider.
20618///
20619/// @return true iff @p enr is a redundant enumerator in enom.
20620static bool
20621is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
20622 const enum_type_decl &enom)
20623{
20624 vector<enum_type_decl::enumerator> redundant_enrs;
20625 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
20626 {
20627 if (!redundant_enrs.empty())
20628 return true;
20629 }
20630 return false;
20631}
20632
20633/// Compares two instances of @ref enum_type_decl.
20634///
20635/// If the two intances are different, set a bitfield to give some
20636/// insight about the kind of differences there are.
20637///
20638/// @param l the first artifact of the comparison.
20639///
20640/// @param r the second artifact of the comparison.
20641///
20642/// @param k a pointer to a bitfield that gives information about the
20643/// kind of changes there are between @p l and @p r. This one is set
20644/// iff @p k is non-null and the function returns false.
20645///
20646/// Please note that setting k to a non-null value does have a
20647/// negative performance impact because even if @p l and @p r are not
20648/// equal, the function keeps up the comparison in order to determine
20649/// the different kinds of ways in which they are different.
20650///
20651/// @return true if @p l equals @p r, false otherwise.
20652bool
20654{
20655 bool result = true;
20656
20657 //
20658 // Look through decl-only-enum.
20659 //
20660
20661 const enum_type_decl *def1 =
20664 : &l;
20665
20666 const enum_type_decl *def2 =
20669 : &r;
20670
20671 if (!!def1 != !!def2)
20672 {
20673 // One enum is decl-only while the other is not.
20674 // So the two enums are different.
20675 result = false;
20676 if (k)
20677 *k |= SUBTYPE_CHANGE_KIND;
20678 else
20680 }
20681
20682 //
20683 // At this point, both enums have the same state of decl-only-ness.
20684 // So we can compare oranges to oranges.
20685 //
20686
20687 if (!def1)
20688 def1 = &l;
20689 if (!def2)
20690 def2 = &r;
20691
20692 if (def1->get_underlying_type() != def2->get_underlying_type())
20693 {
20694 result = false;
20695 if (k)
20696 *k |= SUBTYPE_CHANGE_KIND;
20697 else
20699 }
20700
20701 if (!(def1->decl_base::operator==(*def2)
20702 && def1->type_base::operator==(*def2)))
20703 {
20704 result = false;
20705 if (k)
20706 {
20707 if (!def1->decl_base::operator==(*def2))
20709 if (!def1->type_base::operator==(*def2))
20711 }
20712 else
20714 }
20715
20716 // Now compare the enumerators.
20717
20718 // First in a naive (but potentially fast) way in case both enums
20719 // are equal in a naive manner.
20720
20721 if (def1->get_enumerators().size() == def2->get_enumerators().size())
20722 {
20723 bool equals = true;
20724 for (auto e1 = def1->get_enumerators().begin(),
20725 e2 = def2->get_enumerators().begin();
20726 (e1 != def1->get_enumerators().end()
20727 && e2 != def2->get_enumerators().end());
20728 ++e1, ++e2)
20729 {
20730 if (*e1 != *e2)
20731 {
20732 equals = false;
20733 break;
20734 }
20735 }
20736 if (equals)
20737 ABG_RETURN(result);
20738 }
20739
20740 // If the two enums where not naively equals, let's try a more
20741 // clever (and slow) way.
20742
20743 // Note that the order of declaration
20744 // of enumerators should not matter in the comparison.
20745 //
20746 // Also if an enumerator value is redundant, that shouldn't impact
20747 // the comparison.
20748 //
20749 // In that case, note that the two enums below are considered equal:
20750 //
20751 // enum foo
20752 // {
20753 // e0 = 0;
20754 // e1 = 1;
20755 // e2 = 2;
20756 // };
20757 //
20758 // enum foo
20759 // {
20760 // e0 = 0;
20761 // e1 = 1;
20762 // e2 = 2;
20763 // e_added = 1; // <-- this value is redundant with the value
20764 // // of the enumerator e1.
20765 // };
20766 //
20767 // Note however that in the case below, the enums are different.
20768 //
20769 // enum foo
20770 // {
20771 // e0 = 0;
20772 // e1 = 1;
20773 // };
20774 //
20775 // enum foo
20776 // {
20777 // e0 = 0;
20778 // e2 = 1; // <-- this enum value is present in the first version
20779 // // of foo, but is not redundant with any enumerator
20780 // // in the second version of of enum foo.
20781 // };
20782 //
20783 // These two enums are considered equal.
20784
20785 for(const auto &e : def1->get_enumerators())
20786 if (!is_enumerator_present_in_enum(e, *def2)
20787 && (!is_enumerator_value_redundant(e, *def2)
20788 || !is_enumerator_value_redundant(e, *def1)))
20789 {
20790 result = false;
20791 if (k)
20792 {
20794 break;
20795 }
20796 else
20798 }
20799
20800 for(const auto &e : def2->get_enumerators())
20801 if (!is_enumerator_present_in_enum(e, *def1)
20802 && (!is_enumerator_value_redundant(e, *def1)
20803 || !is_enumerator_value_redundant(e, *def2)))
20804 {
20805 result = false;
20806 if (k)
20807 {
20809 break;
20810 }
20811 else
20813 }
20814
20815 ABG_RETURN(result);
20816}
20817
20818/// Equality operator.
20819///
20820/// @param o the other enum to test against.
20821///
20822/// @return true iff @p o equals the current instance of enum type
20823/// decl.
20824bool
20826{
20827 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
20828 if (!op)
20829 return false;
20830 return try_canonical_compare(this, op);
20831}
20832
20833/// Equality operator.
20834///
20835/// @param o the other enum to test against.
20836///
20837/// @return true iff @p o is equals the current instance of enum type
20838/// decl.
20839bool
20841{
20842 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20843 if (!other)
20844 return false;
20845 return *this == *other;
20846}
20847
20848/// Equality operator for @ref enum_type_decl_sptr.
20849///
20850/// @param l the first operand to compare.
20851///
20852/// @param r the second operand to compare.
20853///
20854/// @return true iff @p l equals @p r.
20855bool
20857{
20858 if (!!l != !!r)
20859 return false;
20860 if (l.get() == r.get())
20861 return true;
20862 decl_base_sptr o = r;
20863 return *l == *o;
20864}
20865
20866/// Inequality operator for @ref enum_type_decl_sptr.
20867///
20868/// @param l the first operand to compare.
20869///
20870/// @param r the second operand to compare.
20871///
20872/// @return true iff @p l equals @p r.
20873bool
20875{return !operator==(l, r);}
20876
20877/// The type of the private data of an @ref
20878/// enum_type_decl::enumerator.
20879class enum_type_decl::enumerator::priv
20880{
20881 string name_;
20882 int64_t value_;
20883 string qualified_name_;
20884 enum_type_decl* enum_type_;
20885
20886 friend class enum_type_decl::enumerator;
20887
20888public:
20889
20890 priv()
20891 : enum_type_()
20892 {}
20893
20894 priv(const string& name,
20895 int64_t value,
20896 enum_type_decl* e = 0)
20897 : name_(name),
20898 value_(value),
20899 enum_type_(e)
20900 {}
20901}; // end class enum_type_def::enumerator::priv
20902
20903/// Default constructor of the @ref enum_type_decl::enumerator type.
20905 : priv_(new priv)
20906{}
20907
20908enum_type_decl::enumerator::~enumerator() = default;
20909
20910/// Constructor of the @ref enum_type_decl::enumerator type.
20911///
20912/// @param env the environment we are operating from.
20913///
20914/// @param name the name of the enumerator.
20915///
20916/// @param value the value of the enumerator.
20918 int64_t value)
20919 : priv_(new priv(name, value))
20920{}
20921
20922/// Copy constructor of the @ref enum_type_decl::enumerator type.
20923///
20924/// @param other enumerator to copy.
20926 : priv_(new priv(other.get_name(),
20927 other.get_value(),
20928 other.get_enum_type()))
20929{}
20930
20931/// Assignment operator of the @ref enum_type_decl::enumerator type.
20932///
20933/// @param o
20936{
20937 priv_->name_ = o.get_name();
20938 priv_->value_ = o.get_value();
20939 priv_->enum_type_ = o.get_enum_type();
20940 return *this;
20941}
20942
20943/// Equality operator
20944///
20945/// @param other the enumerator to compare to the current
20946/// instance of enum_type_decl::enumerator.
20947///
20948/// @return true if @p other equals the current instance of
20949/// enum_type_decl::enumerator.
20950bool
20952{
20953 bool names_equal = true;
20954 names_equal = (get_name() == other.get_name());
20955 return names_equal && (get_value() == other.get_value());
20956}
20957
20958/// Inequality operator.
20959///
20960/// @param other the other instance to compare against.
20961///
20962/// @return true iff @p other is different from the current instance.
20963bool
20965{return !operator==(other);}
20966
20967/// Getter for the name of the current instance of
20968/// enum_type_decl::enumerator.
20969///
20970/// @return a reference to the name of the current instance of
20971/// enum_type_decl::enumerator.
20972const string&
20974{return priv_->name_;}
20975
20976/// Getter for the qualified name of the current instance of
20977/// enum_type_decl::enumerator. The first invocation of the method
20978/// builds the qualified name, caches it and return a reference to the
20979/// cached qualified name. Subsequent invocations just return the
20980/// cached value.
20981///
20982/// @param internal set to true if the call is intended for an
20983/// internal use (for technical use inside the library itself), false
20984/// otherwise. If you don't know what this is for, then set it to
20985/// false.
20986///
20987/// @return the qualified name of the current instance of
20988/// enum_type_decl::enumerator.
20989const string&
20991{
20992 if (priv_->qualified_name_.empty())
20993 {
20994 priv_->qualified_name_ =
20995 get_enum_type()->get_qualified_name(internal)
20996 + "::"
20997 + get_name();
20998 }
20999 return priv_->qualified_name_;
21000}
21001
21002/// Setter for the name of @ref enum_type_decl::enumerator.
21003///
21004/// @param n the new name.
21005void
21007{priv_->name_ = n;}
21008
21009/// Getter for the value of @ref enum_type_decl::enumerator.
21010///
21011/// @return the value of the current instance of
21012/// enum_type_decl::enumerator.
21013int64_t
21015{return priv_->value_;}
21016
21017/// Setter for the value of @ref enum_type_decl::enumerator.
21018///
21019/// @param v the new value of the enum_type_decl::enumerator.
21020void
21022{priv_->value_= v;}
21023
21024/// Getter for the enum type that this enumerator is for.
21025///
21026/// @return the enum type that this enumerator is for.
21029{return priv_->enum_type_;}
21030
21031/// Setter for the enum type that this enumerator is for.
21032///
21033/// @param e the new enum type.
21034void
21036{priv_->enum_type_ = e;}
21037// </enum_type_decl definitions>
21038
21039// <typedef_decl definitions>
21040
21041/// Private data structure of the @ref typedef_decl.
21042struct typedef_decl::priv
21043{
21044 type_base_wptr underlying_type_;
21045
21046 priv(const type_base_sptr& t)
21047 : underlying_type_(t)
21048 {}
21049}; // end struct typedef_decl::priv
21050
21051/// Constructor of the typedef_decl type.
21052///
21053/// @param name the name of the typedef.
21054///
21055/// @param underlying_type the underlying type of the typedef.
21056///
21057/// @param locus the source location of the typedef declaration.
21058///
21059/// @param linkage_name the mangled name of the typedef.
21060///
21061/// @param vis the visibility of the typedef type.
21062typedef_decl::typedef_decl(const string& name,
21063 const type_base_sptr underlying_type,
21064 const location& locus,
21065 const string& linkage_name,
21066 visibility vis)
21067 : type_or_decl_base(underlying_type->get_environment(),
21068 TYPEDEF_TYPE
21069 | ABSTRACT_TYPE_BASE
21070 | ABSTRACT_DECL_BASE),
21071 type_base(underlying_type->get_environment(),
21072 underlying_type->get_size_in_bits(),
21073 underlying_type->get_alignment_in_bits()),
21074 decl_base(underlying_type->get_environment(),
21075 name, locus, linkage_name, vis),
21076 priv_(new priv(underlying_type))
21077{
21079}
21080
21081/// Constructor of the typedef_decl type.
21082///
21083/// @param name the name of the typedef.
21084///
21085/// @param env the environment of the current typedef.
21086///
21087/// @param locus the source location of the typedef declaration.
21088///
21089/// @param mangled_name the mangled name of the typedef.
21090///
21091/// @param vis the visibility of the typedef type.
21092typedef_decl::typedef_decl(const string& name,
21093 const environment& env,
21094 const location& locus,
21095 const string& mangled_name,
21096 visibility vis)
21097 : type_or_decl_base(env,
21098 TYPEDEF_TYPE
21099 | ABSTRACT_TYPE_BASE
21100 | ABSTRACT_DECL_BASE),
21101 type_base(env, /*size_in_bits=*/0,
21102 /*alignment_in_bits=*/0),
21103 decl_base(env, name, locus, mangled_name, vis),
21104 priv_(new priv(nullptr))
21105{
21107}
21108
21109/// Return the hash value of the current IR node.
21110///
21111/// Note that upon the first invocation, this member functions
21112/// computes the hash value and returns it. Subsequent invocations
21113/// just return the hash value that was previously calculated.
21114///
21115/// @return the hash value of the current IR node.
21116hash_t
21118{
21120 return h;
21121}
21122
21123/// Return the size of the typedef.
21124///
21125/// This function looks at the size of the underlying type and ensures
21126/// that it's the same as the size of the typedef.
21127///
21128/// @return the size of the typedef.
21129size_t
21131{
21132 if (!get_underlying_type())
21133 return 0;
21134 size_t s = get_underlying_type()->get_size_in_bits();
21135 if (s != type_base::get_size_in_bits())
21136 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
21138}
21139
21140/// Return the alignment of the typedef.
21141///
21142/// This function looks at the alignment of the underlying type and
21143/// ensures that it's the same as the alignment of the typedef.
21144///
21145/// @return the size of the typedef.
21146size_t
21148{
21149 if (!get_underlying_type())
21150 return 0;
21151 size_t s = get_underlying_type()->get_alignment_in_bits();
21153 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
21155}
21156
21157/// Compares two instances of @ref typedef_decl.
21158///
21159/// If the two intances are different, set a bitfield to give some
21160/// insight about the kind of differences there are.
21161///
21162/// @param l the first artifact of the comparison.
21163///
21164/// @param r the second artifact of the comparison.
21165///
21166/// @param k a pointer to a bitfield that gives information about the
21167/// kind of changes there are between @p l and @p r. This one is set
21168/// iff @p k is non-null and the function returns false.
21169///
21170/// Please note that setting k to a non-null value does have a
21171/// negative performance impact because even if @p l and @p r are not
21172/// equal, the function keeps up the comparison in order to determine
21173/// the different kinds of ways in which they are different.
21174///
21175/// @return true if @p l equals @p r, false otherwise.
21176bool
21178{
21179 bool result = true;
21180
21181 // No need to go further if the types have different names or
21182 // different size / alignment.
21183 if (!(l.decl_base::operator==(r)))
21184 {
21185 result = false;
21186 if (k)
21188 else
21190 }
21191
21193 {
21194 // Changes to the underlying type of a typedef are considered
21195 // local, a bit like for pointers.
21196 result = false;
21197 if (k)
21199 else
21201 }
21202
21203 ABG_RETURN(result);
21204}
21205
21206/// Equality operator
21207///
21208/// @param o the other typedef_decl to test against.
21209bool
21211{
21212 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
21213 if (!other)
21214 return false;
21215 return try_canonical_compare(this, other);
21216}
21217
21218/// Equality operator
21219///
21220/// @param o the other typedef_decl to test against.
21221///
21222/// @return true if the current instance of @ref typedef_decl equals
21223/// @p o.
21224bool
21226{
21227 const decl_base* other = dynamic_cast<const decl_base*>(&o);
21228 if (!other)
21229 return false;
21230 return *this == *other;
21231}
21232
21233/// Build a pretty representation for a typedef_decl.
21234///
21235/// @param internal set to true if the call is intended to get a
21236/// representation of the decl (or type) for the purpose of canonical
21237/// type comparison. This is mainly used in the function
21238/// type_base::get_canonical_type_for().
21239///
21240/// In other words if the argument for this parameter is true then the
21241/// call is meant for internal use (for technical use inside the
21242/// library itself), false otherwise. If you don't know what this is
21243/// for, then set it to false.
21244
21245/// @param qualified_name if true, names emitted in the pretty
21246/// representation are fully qualified.
21247///
21248/// @return a copy of the pretty representation of the current
21249/// instance of typedef_decl.
21250string
21252 bool qualified_name) const
21253{
21254
21255 string result = "typedef ";
21256 if (qualified_name)
21257 result += get_qualified_name(internal);
21258 else
21259 result += get_name();
21260
21261 return result;
21262}
21263
21264/// Getter of the underlying type of the typedef.
21265///
21266/// @return the underlying_type.
21267type_base_sptr
21269{return priv_->underlying_type_.lock();}
21270
21271/// Setter ofthe underlying type of the typedef.
21272///
21273/// @param t the new underlying type of the typedef.
21274void
21276{
21277 priv_->underlying_type_ = t;
21278 set_size_in_bits(t->get_size_in_bits());
21279 set_alignment_in_bits(t->get_alignment_in_bits());
21280}
21281
21282/// Implementation of the virtual "get_qualified_name" method.
21283///
21284/// @param qualified_name the resuling qualified name of the typedef type.
21285///
21286/// @param internal if true, then it means the qualified name is for
21287/// "internal" purposes, meaning mainly for type canonicalization
21288/// purposes.
21289void
21291 bool internal) const
21292{qualified_name = get_qualified_name(internal);}
21293
21294/// Implementation of the virtual "get_qualified_name" method.
21295///
21296/// @param internal if true, then it means the qualified name is for
21297/// "internal" purposes, meaning mainly for type canonicalization
21298/// purposes.
21299///
21300/// @return the qualified name.
21301const interned_string&
21303{
21304 // Note that the qualified name has been already set by
21305 // qualified_name_setter::do_update, which is invoked by
21306 // update_qualified_name. The latter is itself invoked whenever the
21307 // typedef is added to its scope, in scope_decl::add_member_decl.
21308 if (internal)
21309 return decl_base::priv_->internal_qualified_name_;
21310 else
21311 return decl_base::priv_->qualified_name_;
21312}
21313
21314/// This implements the ir_traversable_base::traverse pure virtual
21315/// function.
21316///
21317/// @param v the visitor used on the current instance.
21318///
21319/// @return true if the entire IR node tree got traversed, false
21320/// otherwise.
21321bool
21323{
21324 if (v.type_node_has_been_visited(this))
21325 return true;
21326
21327 if (visiting())
21328 return true;
21329
21330 if (v.visit_begin(this))
21331 {
21332 visiting(true);
21333 if (type_base_sptr t = get_underlying_type())
21334 t->traverse(v);
21335 visiting(false);
21336 }
21337
21338 bool result = v.visit_end(this);
21340 return result;
21341}
21342
21343typedef_decl::~typedef_decl()
21344{}
21345// </typedef_decl definitions>
21346
21347// <var_decl definitions>
21348
21349struct var_decl::priv
21350{
21351 type_base_wptr type_;
21352 type_base* naked_type_;
21353 decl_base::binding binding_;
21354 elf_symbol_sptr symbol_;
21355 interned_string id_;
21356
21357 priv()
21358 : naked_type_(),
21359 binding_(decl_base::BINDING_GLOBAL)
21360 {}
21361
21362 priv(type_base_sptr t,
21364 : type_(t),
21365 naked_type_(t.get()),
21366 binding_(b)
21367 {}
21368
21369 /// Setter of the type of the variable.
21370 ///
21371 /// @param t the new variable type.
21372 void
21373 set_type(type_base_sptr t)
21374 {
21375 type_ = t;
21376 naked_type_ = t.get();
21377 }
21378}; // end struct var_decl::priv
21379
21380/// Constructor of the @ref var_decl type.
21381///
21382/// @param name the name of the variable declaration
21383///
21384/// @param type the type of the variable declaration
21385///
21386/// @param locus the source location where the variable was defined.
21387///
21388/// @param linkage_name the linkage name of the variable.
21389///
21390/// @param vis the visibility of of the variable.
21391///
21392/// @param bind the binding kind of the variable.
21393var_decl::var_decl(const string& name,
21394 type_base_sptr type,
21395 const location& locus,
21396 const string& linkage_name,
21397 visibility vis,
21398 binding bind)
21399 : type_or_decl_base(type->get_environment(),
21400 VAR_DECL | ABSTRACT_DECL_BASE),
21401 decl_base(type->get_environment(), name, locus, linkage_name, vis),
21402 priv_(new priv(type, bind))
21403{
21405}
21406
21407/// Getter of the type of the variable.
21408///
21409/// @return the type of the variable.
21410const type_base_sptr
21412{return priv_->type_.lock();}
21413
21414/// Setter of the type of the variable.
21415///
21416/// @param the new type of the variable.
21417void
21418var_decl::set_type(type_base_sptr& t)
21419{priv_->set_type(t);}
21420
21421/// Getter of the type of the variable.
21422///
21423/// This getter returns a bare pointer, as opposed to a smart pointer.
21424/// It's to be used on performance sensitive code paths identified by
21425/// careful profiling.
21426///
21427/// @return the type of the variable, as a bare pointer.
21428const type_base*
21430{return priv_->naked_type_;}
21431
21432/// Getter of the binding of the variable.
21433///
21434/// @return the biding of the variable.
21437{return priv_->binding_;}
21438
21439/// Setter of the binding of the variable.
21440///
21441/// @param b the new binding value.
21442void
21444{priv_->binding_ = b;}
21445
21446/// Sets the underlying ELF symbol for the current variable.
21447///
21448/// And underlyin$g ELF symbol for the current variable might exist
21449/// only if the corpus that this variable originates from was
21450/// constructed from an ELF binary file.
21451///
21452/// Note that comparing two variables that have underlying ELF symbols
21453/// involves comparing their underlying elf symbols. The decl name
21454/// for the variable thus becomes irrelevant in the comparison.
21455///
21456/// @param sym the new ELF symbol for this variable decl.
21457void
21459{
21460 priv_->symbol_ = sym;
21461 // The variable id cache that depends on the symbol must be
21462 // invalidated because the symbol changed.
21463 priv_->id_ = get_environment().intern("");
21464}
21465
21466/// Gets the the underlying ELF symbol for the current variable,
21467/// that was set using var_decl::set_symbol(). Please read the
21468/// documentation for that member function for more information about
21469/// "underlying ELF symbols".
21470///
21471/// @return sym the underlying ELF symbol for this variable decl, if
21472/// one exists.
21473const elf_symbol_sptr&
21475{return priv_->symbol_;}
21476
21477/// Create a new var_decl that is a clone of the current one.
21478///
21479/// @return the cloned var_decl.
21482{
21484 get_type(),
21485 get_location(),
21488 get_binding()));
21489
21490 v->set_symbol(get_symbol());
21491
21492 if (is_member_decl(*this))
21493 {
21497 get_member_is_static(*this),
21498 get_data_member_offset(*this));
21499 }
21500 else
21502
21503 return v;
21504}
21505/// Setter of the scope of the current var_decl.
21506///
21507/// Note that the decl won't hold a reference on the scope. It's
21508/// rather the scope that holds a reference on its members.
21509///
21510/// @param scope the new scope.
21511void
21512var_decl::set_scope(scope_decl* scope)
21513{
21514 if (!get_context_rel())
21515 set_context_rel(new dm_context_rel(scope));
21516 else
21517 get_context_rel()->set_scope(scope);
21518}
21519
21520/// Compares two instances of @ref var_decl without taking their type
21521/// into account.
21522///
21523/// If the two intances are different modulo their type, set a
21524/// bitfield to give some insight about the kind of differences there
21525/// are.
21526///
21527/// @param l the first artifact of the comparison.
21528///
21529/// @param r the second artifact of the comparison.
21530///
21531/// @param k a pointer to a bitfield that gives information about the
21532/// kind of changes there are between @p l and @p r. This one is set
21533/// iff @p k is non-null and the function returns false.
21534///
21535/// Please note that setting k to a non-null value does have a
21536/// negative performance impact because even if @p l and @p r are not
21537/// equal, the function keeps up the comparison in order to determine
21538/// the different kinds of ways in which they are different.
21539///
21540/// @return true if @p l equals @p r, false otherwise.
21541bool
21543{
21544 bool result = true;
21545
21546 // If there are underlying elf symbols for these variables,
21547 // compare them. And then compare the other parts.
21548 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
21549 if (!!s0 != !!s1)
21550 {
21551 result = false;
21552 if (k)
21554 else
21556 }
21557 else if (s0 && !textually_equals(*s0, *s1, k))
21558 {
21559 result = false;
21560 if (!k)
21562 }
21563 bool symbols_are_equal = (s0 && s1 && result);
21564
21565 if (symbols_are_equal)
21566 {
21567 // The variables have underlying elf symbols that are equal, so
21568 // now, let's compare the decl_base part of the variables w/o
21569 // considering their decl names.
21570 const environment& env = l.get_environment();
21571 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
21572 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
21573 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
21574 bool decl_bases_different = !l.decl_base::operator==(r);
21575 const_cast<var_decl&>(l).set_qualified_name(n1);
21576 const_cast<var_decl&>(r).set_qualified_name(n2);
21577
21578 if (decl_bases_different)
21579 {
21580 result = false;
21581 if (k)
21583 else
21585 }
21586 }
21587 else
21588 if (!l.decl_base::operator==(r))
21589 {
21590 result = false;
21591 if (k)
21593 else
21595 }
21596
21597 const dm_context_rel* c0 =
21598 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
21599 const dm_context_rel* c1 =
21600 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
21601 ABG_ASSERT(c0 && c1);
21602
21603 if (*c0 != *c1)
21604 {
21605 result = false;
21606 if (k)
21608 else
21610 }
21611
21612 ABG_RETURN(result);
21613}
21614
21615/// Compares two instances of @ref var_decl.
21616///
21617/// If the two intances are different, set a bitfield to give some
21618/// insight about the kind of differences there are.
21619///
21620/// @param l the first artifact of the comparison.
21621///
21622/// @param r the second artifact of the comparison.
21623///
21624/// @param k a pointer to a bitfield that gives information about the
21625/// kind of changes there are between @p l and @p r. This one is set
21626/// iff @p k is non-null and the function returns false.
21627///
21628/// Please note that setting k to a non-null value does have a
21629/// negative performance impact because even if @p l and @p r are not
21630/// equal, the function keeps up the comparison in order to determine
21631/// the different kinds of ways in which they are different.
21632///
21633/// @return true if @p l equals @p r, false otherwise.
21634bool
21635equals(const var_decl& l, const var_decl& r, change_kind* k)
21636{
21637 bool result = true;
21638
21639 // First test types of variables. This should be fast because in
21640 // the general case, most types should be canonicalized.
21641 if (*l.get_naked_type() != *r.get_naked_type())
21642 {
21643 result = false;
21644 if (k)
21645 {
21647 r.get_naked_type()))
21648 *k |= (LOCAL_TYPE_CHANGE_KIND);
21649 else
21650 *k |= SUBTYPE_CHANGE_KIND;
21651 }
21652 else
21654 }
21655
21656 result &= var_equals_modulo_types(l, r, k);
21657
21658 ABG_RETURN(result);
21659}
21660
21661/// Comparison operator of @ref var_decl.
21662///
21663/// @param o the instance of @ref var_decl to compare against.
21664///
21665/// @return true iff the current instance of @ref var_decl equals @p o.
21666bool
21668{
21669 const var_decl* other = dynamic_cast<const var_decl*>(&o);
21670 if (!other)
21671 return false;
21672
21673 return equals(*this, *other, 0);
21674}
21675
21676/// Return an ID that tries to uniquely identify the variable inside a
21677/// program or a library.
21678///
21679/// So if the variable has an underlying elf symbol, the ID is the
21680/// concatenation of the symbol name and its version. Otherwise, the
21681/// ID is the linkage name if its non-null. Otherwise, it's the
21682/// pretty representation of the variable.
21683///
21684/// @return the ID.
21687{
21688 if (priv_->id_.empty())
21689 {
21690 string repr = get_name();
21691 string sym_str;
21692 if (elf_symbol_sptr s = get_symbol())
21693 sym_str = s->get_id_string();
21694 else if (!get_linkage_name().empty())
21695 sym_str = get_linkage_name();
21696
21697 const environment& env = get_type()->get_environment();
21698 priv_->id_ = env.intern(repr);
21699 if (!sym_str.empty())
21700 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
21701 }
21702 return priv_->id_;
21703}
21704
21705/// Get the qualified name of a given variable or data member.
21706///
21707///
21708/// Note that if the current instance of @ref var_decl is an anonymous
21709/// data member, then the qualified name is actually the flat
21710/// representation (the definition) of the type of the anonymous data
21711/// member. We chose the flat representation because otherwise, the
21712/// name of an *anonymous* data member is empty, by construction, e.g:
21713///
21714/// struct foo {
21715/// int a;
21716/// union {
21717/// char b;
21718/// char c;
21719/// }; // <---- this data member is anonymous.
21720/// int d;
21721/// }
21722///
21723/// The string returned for the anonymous member here is going to be:
21724///
21725/// "union {char b; char c}"
21726///
21727/// @param internal if true then this is for a purpose to the library,
21728/// otherwise, it's for being displayed to users.
21729///
21730/// @return the resulting qualified name.
21731const interned_string&
21733{
21734 if (is_anonymous_data_member(this)
21735 && decl_base::get_qualified_name().empty())
21736 {
21737 // Display the anonymous data member in a way that makes sense.
21738 string r = get_pretty_representation(internal);
21740 }
21741
21742 return decl_base::get_qualified_name(internal);
21743}
21744
21745/// Build and return the pretty representation of this variable.
21746///
21747/// @param internal set to true if the call is intended to get a
21748/// representation of the decl (or type) for the purpose of canonical
21749/// type comparison. This is mainly used in the function
21750/// type_base::get_canonical_type_for().
21751///
21752/// In other words if the argument for this parameter is true then the
21753/// call is meant for internal use (for technical use inside the
21754/// library itself), false otherwise. If you don't know what this is
21755/// for, then set it to false.
21756///
21757/// @param qualified_name if true, names emitted in the pretty
21758/// representation are fully qualified.
21759///
21760/// @return a copy of the pretty representation of this variable.
21761string
21762var_decl::get_pretty_representation(bool internal, bool qualified_name) const
21763{
21764 string result;
21765
21766 if (is_member_decl(this) && get_member_is_static(this))
21767 result = "static ";
21768
21769 // Detect if the current instance of var_decl is a member of
21770 // an anonymous class or union.
21771 bool member_of_anonymous_class = false;
21772 if (class_or_union* scope = is_at_class_scope(this))
21773 if (scope->get_is_anonymous())
21774 member_of_anonymous_class = true;
21775
21776 type_base_sptr type = get_type();
21777 if (is_array_type(type, /*look_through_qualifiers=*/true)
21778 || is_pointer_type(type, /*look_through_qualifiers=*/true)
21779 || is_reference_type(type, /*look_through_qualifiers=*/true)
21780 || is_ptr_to_mbr_type(type, /*look_through_qualifiers=*/true))
21781 {
21782 string name;
21783 if (member_of_anonymous_class || !qualified_name)
21784 name = get_name();
21785 else
21786 name = get_qualified_name(internal);
21787
21788 if (qualified_type_def_sptr q = is_qualified_type(type))
21789 {
21790 string quals_repr =
21791 get_string_representation_of_cv_quals(q->get_cv_quals());
21792 if (!quals_repr.empty())
21793 name = quals_repr + " " + name;
21794 type = peel_qualified_type(type);
21795 }
21796
21797 name = string(" ") + name;
21798 if (array_type_def_sptr t = is_array_type(type))
21799 result += array_declaration_name(t, name, qualified_name, internal);
21800 else if (pointer_type_def_sptr t = is_pointer_type(type))
21801 result += pointer_declaration_name(t, name, qualified_name, internal);
21802 else if (reference_type_def_sptr t = is_reference_type(type))
21803 result += pointer_declaration_name(t, name, qualified_name, internal);
21804 else if (ptr_to_mbr_type_sptr t = is_ptr_to_mbr_type(type))
21805 result += ptr_to_mbr_declaration_name(t, name,
21806 qualified_name,
21807 internal);
21808 }
21809 else
21810 {
21811 if (/*The current var_decl is to be used as an anonymous data
21812 member. */
21813 get_name().empty())
21814 {
21815 // Display the anonymous data member in a way that
21816 // makes sense.
21817 result +=
21820 "", /*one_line=*/true, internal);
21821 }
21822 else if (data_member_has_anonymous_type(this))
21823 {
21826 "", /*one_line=*/true, internal);
21827 result += " ";
21828 if (!internal
21829 && (member_of_anonymous_class || !qualified_name))
21830 // It doesn't make sense to name the member of an
21831 // anonymous class or union like:
21832 // "__anonymous__::data_member_name". So let's just use
21833 // its non-qualified name.
21834 result += get_name();
21835 else
21836 result += get_qualified_name(internal);
21837 }
21838 else
21839 {
21840 result +=
21842 + " ";
21843
21844 if (!internal
21845 && (member_of_anonymous_class || !qualified_name))
21846 // It doesn't make sense to name the member of an
21847 // anonymous class or union like:
21848 // "__anonymous__::data_member_name". So let's just use
21849 // its non-qualified name.
21850 result += get_name();
21851 else
21852 result += get_qualified_name(internal);
21853 }
21854 }
21855 return result;
21856}
21857
21858/// Get a name that is valid even for an anonymous data member.
21859///
21860/// If the current @ref var_decl is an anonymous data member, then
21861/// return its pretty representation. As of now, that pretty
21862/// representation is actually its flat representation as returned by
21863/// get_class_or_union_flat_representation().
21864///
21865/// Otherwise, just return the name of the current @ref var_decl.
21866///
21867/// @param qualified if true, return the qualified name. This doesn't
21868/// have an effet if the current @ref var_decl represents an anonymous
21869/// data member.
21870string
21872{
21873 string name;
21874 if (is_anonymous_data_member(this))
21875 // This function is used in the comparison engine to determine
21876 // which anonymous data member was deleted. So it's not involved
21877 // in type comparison or canonicalization. We don't want to use
21878 // the 'internal' version of the pretty presentation.
21879 name = get_pretty_representation(/*internal=*/false, qualified);
21880 else
21881 name = get_name();
21882
21883 return name;
21884}
21885
21886/// This implements the ir_traversable_base::traverse pure virtual
21887/// function.
21888///
21889/// @param v the visitor used on the current instance.
21890///
21891/// @return true if the entire IR node tree got traversed, false
21892/// otherwise.
21893bool
21895{
21896 if (visiting())
21897 return true;
21898
21899 if (v.visit_begin(this))
21900 {
21901 visiting(true);
21902 if (type_base_sptr t = get_type())
21903 t->traverse(v);
21904 visiting(false);
21905 }
21906 return v.visit_end(this);
21907}
21908
21909var_decl::~var_decl()
21910{}
21911
21912// </var_decl definitions>
21913
21914/// This function is automatically invoked whenever an instance of
21915/// this type is canonicalized.
21916///
21917/// It's an overload of the virtual type_base::on_canonical_type_set.
21918///
21919/// We put here what is thus meant to be executed only at the point of
21920/// type canonicalization.
21921void
21923{
21924 priv_->cached_name_.clear();
21925 priv_->internal_cached_name_.clear();
21926}
21927
21928/// The most straightforward constructor for the function_type class.
21929///
21930/// @param return_type the return type of the function type.
21931///
21932/// @param parms the list of parameters of the function type.
21933/// Stricto sensu, we just need a list of types; we are using a list
21934/// of parameters (where each parameter also carries the name of the
21935/// parameter and its source location) to try and provide better
21936/// diagnostics whenever it makes sense. If it appears that this
21937/// wasts too many resources, we can fall back to taking just a
21938/// vector of types here.
21939///
21940/// @param size_in_bits the size of this type, in bits.
21941///
21942/// @param alignment_in_bits the alignment of this type, in bits.
21943///
21944/// @param size_in_bits the size of this type.
21945function_type::function_type(type_base_sptr return_type,
21946 const parameters& parms,
21947 size_t size_in_bits,
21948 size_t alignment_in_bits)
21949 : type_or_decl_base(return_type->get_environment(),
21950 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21951 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21952 priv_(new priv(parms, return_type))
21953{
21955
21956 for (parameters::size_type i = 0, j = 1;
21957 i < priv_->parms_.size();
21958 ++i, ++j)
21959 {
21960 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21961 // If the first parameter is artificial, then it certainly
21962 // means that this is a member function, and the first
21963 // parameter is the implicit this pointer. In that case, set
21964 // the index of that implicit parameter to zero. Otherwise,
21965 // the index of the first parameter starts at one.
21966 j = 0;
21967 priv_->parms_[i]->set_index(j);
21968 }
21969}
21970
21971/// A constructor for a function_type that takes no parameters.
21972///
21973/// @param return_type the return type of this function_type.
21974///
21975/// @param size_in_bits the size of this type, in bits.
21976///
21977/// @param alignment_in_bits the alignment of this type, in bits.
21978function_type::function_type(type_base_sptr return_type,
21979 size_t size_in_bits, size_t alignment_in_bits)
21980 : type_or_decl_base(return_type->get_environment(),
21981 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21982 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21983 priv_(new priv(return_type))
21984{
21986}
21987
21988/// A constructor for a function_type that takes no parameter and
21989/// that has no return_type yet. These missing parts can (and must)
21990/// be added later.
21991///
21992/// @param env the environment we are operating from.
21993///
21994/// @param size_in_bits the size of this type, in bits.
21995///
21996/// @param alignment_in_bits the alignment of this type, in bits.
21997function_type::function_type(const environment& env,
21998 size_t size_in_bits,
21999 size_t alignment_in_bits)
22000 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
22001 type_base(env, size_in_bits, alignment_in_bits),
22002 priv_(new priv)
22003{
22005}
22006
22007/// Return the hash value of the current IR node.
22008///
22009/// Note that upon the first invocation, this member functions
22010/// computes the hash value and returns it. Subsequent invocations
22011/// just return the hash value that was previously calculated.
22012///
22013/// @return the hash value of the current IR node.
22014hash_t
22016{
22018 return h;
22019}
22020
22021/// Getter for the return type of the current instance of @ref
22022/// function_type.
22023///
22024/// @return the return type.
22025type_base_sptr
22027{return priv_->return_type_.lock();}
22028
22029/// Setter of the return type of the current instance of @ref
22030/// function_type.
22031///
22032/// @param t the new return type to set.
22033void
22035{priv_->return_type_ = t;}
22036
22037/// Getter for the set of parameters of the current intance of @ref
22038/// function_type.
22039///
22040/// @return the parameters of the current instance of @ref
22041/// function_type.
22044{return priv_->parms_;}
22045
22046/// Get the Ith parameter of the vector of parameters of the current
22047/// instance of @ref function_type.
22048///
22049/// Note that the first parameter is at index 0. That parameter is
22050/// the first parameter that comes after the possible implicit "this"
22051/// parameter, when the current instance @ref function_type is for a
22052/// member function. Otherwise, if the current instance of @ref
22053/// function_type is for a non-member function, the parameter at index
22054/// 0 is the first parameter of the function.
22055///
22056///
22057/// @param i the index of the parameter to return. If i is greater
22058/// than the index of the last parameter, then this function returns
22059/// an empty parameter (smart) pointer.
22060///
22061/// @return the @p i th parameter that is not implicit.
22064{
22065 parameter_sptr result;
22066 if (dynamic_cast<const method_type*>(this))
22067 {
22068 if (i + 1 < get_parameters().size())
22069 result = get_parameters()[i + 1];
22070 }
22071 else
22072 {
22073 if (i < get_parameters().size())
22074 result = get_parameters()[i];
22075 }
22076 return result;
22077}
22078
22079/// Setter for the parameters of the current instance of @ref
22080/// function_type.
22081///
22082/// @param p the new vector of parameters to set.
22083void
22085{
22086 priv_->parms_ = p;
22087 for (parameters::size_type i = 0, j = 1;
22088 i < priv_->parms_.size();
22089 ++i, ++j)
22090 {
22091 if (i == 0 && priv_->parms_[i]->get_is_artificial())
22092 // If the first parameter is artificial, then it certainly
22093 // means that this is a member function, and the first
22094 // parameter is the implicit this pointer. In that case, set
22095 // the index of that implicit parameter to zero. Otherwise,
22096 // the index of the first parameter starts at one.
22097 j = 0;
22098 priv_->parms_[i]->set_index(j);
22099 }
22100}
22101
22102/// Append a new parameter to the vector of parameters of the current
22103/// instance of @ref function_type.
22104///
22105/// @param parm the parameter to append.
22106void
22108{
22109 parm->set_index(priv_->parms_.size());
22110 priv_->parms_.push_back(parm);
22111}
22112
22113/// Test if the current instance of @ref function_type is for a
22114/// variadic function.
22115///
22116/// A variadic function is a function that takes a variable number of
22117/// arguments.
22118///
22119/// @return true iff the current instance of @ref function_type is for
22120/// a variadic function.
22121bool
22123{
22124 return (!priv_->parms_.empty()
22125 && priv_->parms_.back()->get_variadic_marker());
22126}
22127
22128/// Compare two function types.
22129///
22130/// In case these function types are actually method types, this
22131/// function avoids comparing two parameters (of the function types)
22132/// if the types of the parameters are actually the types of the
22133/// classes of the method types. This prevents infinite recursion
22134/// during the comparison of two classes that are structurally
22135/// identical.
22136///
22137/// This is a subroutine of the equality operator of function_type.
22138///
22139/// @param lhs the first function type to consider
22140///
22141/// @param rhs the second function type to consider
22142///
22143/// @param k a pointer to a bitfield set by the function to give
22144/// information about the kind of changes carried by @p lhs and @p
22145/// rhs. It is set iff @p k is non-null and the function returns
22146/// false.
22147///
22148/// Please note that setting k to a non-null value does have a
22149/// negative performance impact because even if @p l and @p r are not
22150/// equal, the function keeps up the comparison in order to determine
22151/// the different kinds of ways in which they are different.
22152///
22153///@return true if lhs == rhs, false otherwise.
22154bool
22156{
22157#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
22158
22160
22161 {
22162 // First of all, let's see if these two function types haven't
22163 // already been compared. If so, and if the result of the
22164 // comparison has been cached, let's just re-use it, rather than
22165 // comparing them all over again.
22166 bool cached_result = false;
22167 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
22168 cached_result))
22169 ABG_RETURN(cached_result);
22170 }
22171
22173
22174 bool result = true;
22175
22176 if (!l.type_base::operator==(r))
22177 {
22178 result = false;
22179 if (k)
22181 else
22182 RETURN(result);
22183 }
22184
22185 class_or_union* l_class = 0, *r_class = 0;
22186 if (const method_type* m = dynamic_cast<const method_type*>(&l))
22187 l_class = m->get_class_type().get();
22188
22189 if (const method_type* m = dynamic_cast<const method_type*>(&r))
22190 r_class = m->get_class_type().get();
22191
22192 // Compare the names of the class of the method
22193
22194 if (!!l_class != !!r_class)
22195 {
22196 result = false;
22197 if (k)
22199 else
22200 RETURN(result);
22201 }
22202 else if (l_class
22203 && (l_class->get_qualified_name()
22204 != r_class->get_qualified_name()))
22205 {
22206 result = false;
22207 if (k)
22209 else
22210 RETURN(result);
22211 }
22212
22213 // Then compare the return type; Beware if it's t's a class type
22214 // that is the same as the method class name; we can recurse for
22215 // ever in that case.
22216
22217 decl_base* l_return_type_decl =
22219 decl_base* r_return_type_decl =
22221 bool compare_result_types = true;
22222 string l_rt_name = l_return_type_decl
22223 ? l_return_type_decl->get_qualified_name()
22224 : string();
22225 string r_rt_name = r_return_type_decl
22226 ? r_return_type_decl->get_qualified_name()
22227 : string();
22228
22229 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
22230 ||
22231 (r_class && (r_class->get_qualified_name() == r_rt_name)))
22232 compare_result_types = false;
22233
22234 if (compare_result_types)
22235 {
22236 // Let's not consider typedefs when comparing return types to
22237 // avoid spurious changes.
22238 //
22239 // TODO: We should also do this for parameter types, or rather,
22240 // we should teach the equality operators in the IR, at some
22241 // point, to peel typedefs off.
22242 if (l.get_return_type() != r.get_return_type())
22243 {
22244 result = false;
22245 if (k)
22246 {
22248 r.get_return_type()))
22250 else
22251 *k |= SUBTYPE_CHANGE_KIND;
22252 }
22253 else
22254 RETURN(result);
22255 }
22256 }
22257 else
22258 if (l_rt_name != r_rt_name)
22259 {
22260 result = false;
22261 if (k)
22262 *k |= SUBTYPE_CHANGE_KIND;
22263 else
22264 RETURN(result);
22265 }
22266
22267 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
22268 for (i = l.get_first_parm(), j = r.get_first_parm();
22269 i != l.get_parameters().end() && j != r.get_parameters().end();
22270 ++i, ++j)
22271 {
22272 if (**i != **j)
22273 {
22274 result = false;
22275 if (k)
22276 {
22277 if (!types_have_similar_structure((*i)->get_type(),
22278 (*j)->get_type()))
22280 else
22281 *k |= SUBTYPE_CHANGE_KIND;
22282 }
22283 else
22284 RETURN(result);
22285 }
22286 }
22287
22288 if ((i != l.get_parameters().end()
22289 || j != r.get_parameters().end()))
22290 {
22291 result = false;
22292 if (k)
22294 else
22295 RETURN(result);
22296 }
22297
22298 RETURN(result);
22299#undef RETURN
22300}
22301
22302/// Get the first parameter of the function.
22303///
22304/// If the function is a non-static member function, the parameter
22305/// returned is the first one following the implicit 'this' parameter.
22306///
22307/// @return the first non implicit parameter of the function.
22308function_type::parameters::const_iterator
22310{
22311 if (get_parameters().empty())
22312 return get_parameters().end();
22313
22314 bool is_method = dynamic_cast<const method_type*>(this);
22315
22316 parameters::const_iterator i = get_parameters().begin();
22317
22318 if (is_method && (*i)->get_is_artificial())
22319 ++i;
22320
22321 return i;
22322}
22323
22324/// Get the first parameter of the function.
22325///
22326/// Note that if the function is a non-static member function, the
22327/// parameter returned is the implicit 'this' parameter.
22328///
22329/// @return the first parameter of the function.
22330function_type::parameters::const_iterator
22332{return get_parameters().begin();}
22333
22334/// Get the name of the current @ref function_type.
22335///
22336/// The name is retrieved from a cache. If the cache is empty, this
22337/// function computes the name of the type, stores it in the cache and
22338/// returns it. Subsequent invocation of the function are going to
22339/// just hit the cache.
22340///
22341/// Note that if the type is *NOT* canonicalized then function type
22342/// name is never cached.
22343///
22344/// @param internal if true then it means the function type name is
22345/// going to be used for purposes that are internal to libabigail
22346/// itself. If you don't know what this is then you probably should
22347/// set this parameter to 'false'.
22348///
22349/// @return the name of the function type.
22350const interned_string&
22352{
22353 if (internal)
22354 {
22356 {
22357 if (priv_->internal_cached_name_.empty())
22358 priv_->internal_cached_name_ =
22359 get_function_type_name(this, /*internal=*/true);
22360 return priv_->internal_cached_name_;
22361 }
22362 else
22363 {
22364 priv_->temp_internal_cached_name_ =
22365 get_function_type_name(this, /*internal=*/true);
22366 return priv_->temp_internal_cached_name_;
22367 }
22368 }
22369 else
22370 {
22372 {
22373 if (priv_->cached_name_.empty())
22374 priv_->cached_name_ =
22375 get_function_type_name(this, /*internal=*/false);
22376 return priv_->cached_name_;
22377 }
22378 else
22379 {
22380 priv_->cached_name_ =
22381 get_function_type_name(this, /*internal=*/false);
22382 return priv_->cached_name_;
22383 }
22384 }
22385}
22386
22387/// Equality operator for function_type.
22388///
22389/// @param o the other function_type to compare against.
22390///
22391/// @return true iff the two function_type are equal.
22392bool
22394{
22395 const function_type* o = dynamic_cast<const function_type*>(&other);
22396 if (!o)
22397 return false;
22398 return try_canonical_compare(this, o);
22399}
22400
22401/// Return a copy of the pretty representation of the current @ref
22402/// function_type.
22403///
22404/// @param internal set to true if the call is intended to get a
22405/// representation of the decl (or type) for the purpose of canonical
22406/// type comparison. This is mainly used in the function
22407/// type_base::get_canonical_type_for().
22408///
22409/// In other words if the argument for this parameter is true then the
22410/// call is meant for internal use (for technical use inside the
22411/// library itself), false otherwise. If you don't know what this is
22412/// for, then set it to false.
22413///
22414/// @return a copy of the pretty representation of the current @ref
22415/// function_type.
22416string
22418 bool /*qualified_name*/) const
22419{return ir::get_pretty_representation(this, internal);}
22420
22421/// Traverses an instance of @ref function_type, visiting all the
22422/// sub-types and decls that it might contain.
22423///
22424/// @param v the visitor that is used to visit every IR sub-node of
22425/// the current node.
22426///
22427/// @return true if either
22428/// - all the children nodes of the current IR node were traversed
22429/// and the calling code should keep going with the traversing.
22430/// - or the current IR node is already being traversed.
22431/// Otherwise, returning false means that the calling code should not
22432/// keep traversing the tree.
22433bool
22435{
22436 // TODO: should we allow the walker to avoid visiting function type
22437 // twice? I think that if we do, then ir_node_visitor needs an
22438 // option to specifically disallow this feature for function types.
22439
22440 if (visiting())
22441 return true;
22442
22443 if (v.visit_begin(this))
22444 {
22445 visiting(true);
22446 bool keep_going = true;
22447
22448 if (type_base_sptr t = get_return_type())
22449 {
22450 if (!t->traverse(v))
22451 keep_going = false;
22452 }
22453
22454 if (keep_going)
22455 for (parameters::const_iterator i = get_parameters().begin();
22456 i != get_parameters().end();
22457 ++i)
22458 if (type_base_sptr parm_type = (*i)->get_type())
22459 if (!parm_type->traverse(v))
22460 break;
22461
22462 visiting(false);
22463 }
22464 return v.visit_end(this);
22465}
22466
22467function_type::~function_type()
22468{}
22469// </function_type>
22470
22471// <method_type>
22472
22473struct method_type::priv
22474{
22475 class_or_union_wptr class_type_;
22476 bool is_const;
22477
22478 priv()
22479 : is_const()
22480 {}
22481}; // end struct method_type::priv
22482
22483/// Constructor for instances of method_type.
22484///
22485/// Instances of method_decl must be of type method_type.
22486///
22487/// @param return_type the type of the return value of the method.
22488///
22489/// @param class_type the base type of the method type. That is, the
22490/// type of the class the method belongs to.
22491///
22492/// @param p the vector of the parameters of the method.
22493///
22494/// @param is_const whether this method type is for a const method.
22495/// Note that const-ness is a property of the method *type* and of the
22496/// relationship between a method *declaration* and its scope.
22497///
22498/// @param size_in_bits the size of an instance of method_type,
22499/// expressed in bits.
22500///
22501/// @param alignment_in_bits the alignment of an instance of
22502/// method_type, expressed in bits.
22503method_type::method_type (type_base_sptr return_type,
22504 class_or_union_sptr class_type,
22505 const std::vector<function_decl::parameter_sptr>& p,
22506 bool is_const,
22507 size_t size_in_bits,
22508 size_t alignment_in_bits)
22509 : type_or_decl_base(class_type->get_environment(),
22510 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22511 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22512 function_type(return_type, p, size_in_bits, alignment_in_bits),
22513 priv_(new priv)
22514{
22516 set_class_type(class_type);
22517 set_is_const(is_const);
22518}
22519
22520/// Constructor of instances of method_type.
22521///
22522///Instances of method_decl must be of type method_type.
22523///
22524/// @param return_type the type of the return value of the method.
22525///
22526/// @param class_type the type of the class the method belongs to.
22527/// The actual (dynamic) type of class_type must be a pointer
22528/// class_type. We are setting it to pointer to type_base here to
22529/// help client code that is compiled without rtti and thus cannot
22530/// perform dynamic casts.
22531///
22532/// @param p the vector of the parameters of the method type.
22533///
22534/// @param is_const whether this method type is for a const method.
22535/// Note that const-ness is a property of the method *type* and of the
22536/// relationship between a method *declaration* and its scope.
22537///
22538/// @param size_in_bits the size of an instance of method_type,
22539/// expressed in bits.
22540///
22541/// @param alignment_in_bits the alignment of an instance of
22542/// method_type, expressed in bits.
22543method_type::method_type(type_base_sptr return_type,
22544 type_base_sptr class_type,
22545 const std::vector<function_decl::parameter_sptr>& p,
22546 bool is_const,
22547 size_t size_in_bits,
22548 size_t alignment_in_bits)
22549 : type_or_decl_base(class_type->get_environment(),
22550 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22551 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22552 function_type(return_type, p, size_in_bits, alignment_in_bits),
22553 priv_(new priv)
22554{
22556 set_class_type(is_class_type(class_type));
22557 set_is_const(is_const);
22558}
22559
22560/// Constructor of the qualified_type_def
22561///
22562/// @param env the environment we are operating from.
22563///
22564/// @param size_in_bits the size of the type, expressed in bits.
22565///
22566/// @param alignment_in_bits the alignment of the type, expressed in bits
22567method_type::method_type(const environment& env,
22568 size_t size_in_bits,
22569 size_t alignment_in_bits)
22570 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22571 type_base(env, size_in_bits, alignment_in_bits),
22572 function_type(env, size_in_bits, alignment_in_bits),
22573 priv_(new priv)
22574{
22576}
22577
22578/// Constructor of instances of method_type.
22579///
22580/// When constructed with this constructor, and instane of method_type
22581/// must set a return type using method_type::set_return_type
22582///
22583/// @param class_typ the base type of the method type. That is, the
22584/// type of the class (or union) the method belongs to.
22585///
22586/// @param size_in_bits the size of an instance of method_type,
22587/// expressed in bits.
22588///
22589/// @param alignment_in_bits the alignment of an instance of
22590/// method_type, expressed in bits.
22591method_type::method_type(class_or_union_sptr class_type,
22592 bool is_const,
22593 size_t size_in_bits,
22594 size_t alignment_in_bits)
22595 : type_or_decl_base(class_type->get_environment(),
22596 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22597 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22598 function_type(class_type->get_environment(),
22599 size_in_bits,
22600 alignment_in_bits),
22601 priv_(new priv)
22602{
22604 set_class_type(class_type);
22605 set_is_const(is_const);
22606}
22607
22608/// Return the hash value of the current IR node.
22609///
22610/// Note that upon the first invocation, this member functions
22611/// computes the hash value and returns it. Subsequent invocations
22612/// just return the hash value that was previously calculated.
22613///
22614/// @return the hash value of the current IR node.
22615hash_t
22617{
22619 return h;
22620}
22621
22622/// Get the class type this method belongs to.
22623///
22624/// @return the class type.
22625class_or_union_sptr
22627{return class_or_union_sptr(priv_->class_type_);}
22628
22629/// Sets the class type of the current instance of method_type.
22630///
22631/// The class type is the type of the class the method belongs to.
22632///
22633/// @param t the new class type to set.
22634void
22635method_type::set_class_type(const class_or_union_sptr& t)
22636{
22637 if (!t)
22638 return;
22639
22640 priv_->class_type_ = t;
22641}
22642
22643/// Return a copy of the pretty representation of the current @ref
22644/// method_type.
22645///
22646/// @param internal set to true if the call is intended to get a
22647/// representation of the decl (or type) for the purpose of canonical
22648/// type comparison. This is mainly used in the function
22649/// type_base::get_canonical_type_for().
22650///
22651/// In other words if the argument for this parameter is true then the
22652/// call is meant for internal use (for technical use inside the
22653/// library itself), false otherwise. If you don't know what this is
22654/// for, then set it to false.
22655///
22656/// @return a copy of the pretty representation of the current @ref
22657/// method_type.
22658string
22660 bool /*qualified_name*/) const
22661{return ir::get_pretty_representation(*this, internal);}
22662
22663/// Setter of the "is-const" property of @ref method_type.
22664///
22665/// @param the new value of the "is-const" property.
22666void
22668{priv_->is_const = f;}
22669
22670/// Getter of the "is-const" property of @ref method_type.
22671///
22672/// @return true iff the "is-const" property was set.
22673bool
22675{return priv_->is_const;}
22676
22677/// Test if the current method type is for a static method or not.
22678///
22679/// @return true iff the current method_type denotes a the type of a
22680/// static method.
22681bool
22683{
22684 // Let's see if the first parameter is artificial and is a pointer
22685 // to an instance of the same class type as the current class.
22687 if (!get_parameters().empty())
22688 first_parm = get_parameters()[0];
22689 if (!first_parm)
22690 return true;
22691 if (!first_parm->get_is_artificial())
22692 return true;
22693
22694 type_base_sptr this_ptr_type = first_parm->get_type();
22695 // Sometimes, the type of the "this" pointer is "const class_type*
22696 // const". Meaning that the "this pointer" itself is const
22697 // qualified. So let's get the underlying non-qualified pointer.
22698 this_ptr_type = peel_qualified_type(this_ptr_type);
22699 if (!is_pointer_type(this_ptr_type))
22700 return true;
22701
22702 type_base_sptr candidate_class_type =
22703 is_pointer_type(this_ptr_type)->get_pointed_to_type();
22704 candidate_class_type = peel_qualified_type(candidate_class_type);
22705 if (is_class_type(candidate_class_type)
22706 && get_type_name(candidate_class_type) == get_type_name(get_class_type()))
22707 // At this point, we are sure we are looking at a *non-static*
22708 // method.
22709 return false;
22710
22711 return true;
22712}
22713
22714/// The destructor of method_type
22716{}
22717
22718// </method_type>
22719
22720// <function_decl definitions>
22721
22722struct function_decl::priv
22723{
22724 bool declared_inline_;
22725 decl_base::binding binding_;
22726 function_type_wptr type_;
22727 function_type* naked_type_;
22728 elf_symbol_sptr symbol_;
22729 interned_string id_;
22730
22731 priv()
22732 : declared_inline_(false),
22733 binding_(decl_base::BINDING_GLOBAL),
22734 naked_type_()
22735 {}
22736
22737 priv(function_type_sptr t,
22738 bool declared_inline,
22740 : declared_inline_(declared_inline),
22741 binding_(binding),
22742 type_(t),
22743 naked_type_(t.get())
22744 {}
22745
22746 priv(function_type_sptr t,
22747 bool declared_inline,
22750 : declared_inline_(declared_inline),
22751 binding_(binding),
22752 type_(t),
22753 naked_type_(t.get()),
22754 symbol_(s)
22755 {}
22756}; // end sruct function_decl::priv
22757
22758/// Constructor of the @ref function_decl.
22759///
22760/// @param name the name of the function.
22761///
22762/// @param function_type the type of the function.
22763///
22764/// @param declared_inline wether the function is declared inline.
22765///
22766/// @param locus the source location of the function.
22767///
22768/// @param mangled_name the linkage name of the function.
22769///
22770/// @param vis the visibility of the function.
22771///
22772/// @param bind the binding of the function.
22775 bool declared_inline,
22776 const location& locus,
22777 const string& mangled_name,
22778 visibility vis,
22779 binding bind)
22780 : type_or_decl_base(function_type->get_environment(),
22781 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22782 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
22783 priv_(new priv(function_type, declared_inline, bind))
22784{
22786}
22787
22788/// Constructor of the function_decl type.
22789///
22790/// This flavour of constructor is for when the pointer to the
22791/// instance of function_type that the client code has is presented as
22792/// a pointer to type_base. In that case, this constructor saves the
22793/// client code from doing a dynamic_cast to get the function_type
22794/// pointer.
22795///
22796/// @param name the name of the function declaration.
22797///
22798/// @param fn_type the type of the function declaration. The dynamic
22799/// type of this parameter should be 'pointer to function_type'
22800///
22801/// @param declared_inline whether this function was declared inline
22802///
22803/// @param locus the source location of the function declaration.
22804///
22805/// @param linkage_name the mangled name of the function declaration.
22806///
22807/// @param vis the visibility of the function declaration.
22808///
22809/// @param bind the kind of the binding of the function
22810/// declaration.
22812 type_base_sptr fn_type,
22813 bool declared_inline,
22814 const location& locus,
22815 const string& linkage_name,
22816 visibility vis,
22817 binding bind)
22818 : type_or_decl_base(fn_type->get_environment(),
22819 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22820 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
22821 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
22822 declared_inline,
22823 bind))
22824{
22826}
22827
22828/// Get the pretty representation of the current instance of @ref function_decl.
22829///
22830/// @param internal set to true if the call is intended to get a
22831/// representation of the decl (or type) for the purpose of canonical
22832/// type comparison. This is mainly used in the function
22833/// type_base::get_canonical_type_for().
22834///
22835/// In other words if the argument for this parameter is true then the
22836/// call is meant for internal use (for technical use inside the
22837/// library itself), false otherwise. If you don't know what this is
22838/// for, then set it to false.
22839///
22840/// @return the pretty representation for a function.
22841string
22843 bool qualified_name) const
22844{
22845 const method_decl* mem_fn =
22846 dynamic_cast<const method_decl*>(this);
22847
22848 string fn_prefix = mem_fn ? "method ": "function ";
22849 string result;
22850
22851 if (mem_fn
22852 && is_member_function(mem_fn)
22854 fn_prefix += "virtual ";
22855
22856 decl_base_sptr return_type;
22857 if ((mem_fn
22858 && is_member_function(mem_fn)
22859 && (get_member_function_is_dtor(*mem_fn)
22860 || get_member_function_is_ctor(*mem_fn))))
22861 /*cdtors do not have return types. */;
22862 else
22863 return_type = mem_fn
22864 ? get_type_declaration(mem_fn->get_type()->get_return_type())
22866
22867 result = get_pretty_representation_of_declarator(internal);
22868 if (return_type)
22869 {
22870 if (is_npaf_type(is_type(return_type))
22871 || !(is_pointer_to_function_type(is_type(return_type))
22872 || is_pointer_to_array_type(is_type(return_type))))
22873 result = get_type_name(is_type(return_type).get(), qualified_name,
22874 internal) + " " + result;
22875 else if (pointer_type_def_sptr p =
22877 result = add_outer_pointer_to_fn_type_expr(p, result,
22878 /*qualified=*/true,
22879 internal);
22880 else if(pointer_type_def_sptr p =
22881 is_pointer_to_array_type(is_type(return_type)))
22882 result = add_outer_pointer_to_array_type_expr(p, result,
22883 qualified_name,
22884 internal);
22885 else
22887 }
22888
22889 return fn_prefix + result;
22890}
22891
22892/// Compute and return the pretty representation for the part of the
22893/// function declaration that starts at the declarator. That is, the
22894/// return type and the other specifiers of the beginning of the
22895/// function's declaration ar omitted.
22896///
22897/// @param internal set to true if the call is intended to get a
22898/// representation of the decl (or type) for the purpose of canonical
22899/// type comparison. This is mainly used in the function
22900/// type_base::get_canonical_type_for().
22901///
22902/// In other words if the argument for this parameter is true then the
22903/// call is meant for internal use (for technical use inside the
22904/// library itself), false otherwise. If you don't know what this is
22905/// for, then set it to false.
22906///
22907/// @return the pretty representation for the part of the function
22908/// declaration that starts at the declarator.
22909string
22911{
22912 const method_decl* mem_fn =
22913 dynamic_cast<const method_decl*>(this);
22914
22915 string result;
22916
22917 if (mem_fn)
22918 {
22919 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
22920 + "::" + mem_fn->get_name();
22921 }
22922 else
22923 result += get_qualified_name();
22924
22925 std::ostringstream fn_parms;
22926 stream_pretty_representation_of_fn_parms(*get_type(),
22927 fn_parms,
22928 /*qualified=*/true,
22929 internal);
22930 result += fn_parms.str();
22931
22932 if (mem_fn
22933 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
22934 || is_method_type(mem_fn->get_type())->get_is_const()))
22935 result += " const";
22936
22937 return result;
22938}
22939
22940/// Getter for the first non-implicit parameter of a function decl.
22941///
22942/// If the function is a non-static member function, the parameter
22943/// returned is the first one following the implicit 'this' parameter.
22944///
22945/// @return the first non implicit parm.
22946function_decl::parameters::const_iterator
22948{
22949 if (get_parameters().empty())
22950 return get_parameters().end();
22951
22952 bool is_method = dynamic_cast<const method_decl*>(this);
22953
22954 parameters::const_iterator i = get_parameters().begin();
22955 if (is_method)
22956 ++i;
22957
22958 return i;
22959}
22960
22961/// Return the type of the current instance of @ref function_decl.
22962///
22963/// It's either a function_type or method_type.
22964/// @return the type of the current instance of @ref function_decl.
22965const shared_ptr<function_type>
22967{return priv_->type_.lock();}
22968
22969/// Fast getter of the type of the current instance of @ref function_decl.
22970///
22971/// Note that this function returns the underlying pointer managed by
22972/// the smart pointer returned by function_decl::get_type(). It's
22973/// faster than function_decl::get_type(). This getter is to be used
22974/// in code paths that are proven to be performance hot spots;
22975/// especially (for instance) when comparing function types. Those
22976/// are compared extremely frequently when libabigail is used to
22977/// handle huge binaries with a lot of functions.
22978///
22979/// @return the type of the current instance of @ref function_decl.
22980const function_type*
22982{return priv_->naked_type_;}
22983
22984void
22985function_decl::set_type(const function_type_sptr& fn_type)
22986{
22987 priv_->type_ = fn_type;
22988 priv_->naked_type_ = fn_type.get();
22989}
22990
22991/// This sets the underlying ELF symbol for the current function decl.
22992///
22993/// And underlyin$g ELF symbol for the current function decl might
22994/// exist only if the corpus that this function decl originates from
22995/// was constructed from an ELF binary file.
22996///
22997/// Note that comparing two function decls that have underlying ELF
22998/// symbols involves comparing their underlying elf symbols. The decl
22999/// name for the function thus becomes irrelevant in the comparison.
23000///
23001/// @param sym the new ELF symbol for this function decl.
23002void
23004{
23005 priv_->symbol_ = sym;
23006 // The function id cache that depends on the symbol must be
23007 // invalidated because the symbol changed.
23008 priv_->id_ = get_environment().intern("");
23009}
23010
23011/// Gets the the underlying ELF symbol for the current variable,
23012/// that was set using function_decl::set_symbol(). Please read the
23013/// documentation for that member function for more information about
23014/// "underlying ELF symbols".
23015///
23016/// @return sym the underlying ELF symbol for this function decl, if
23017/// one exists.
23018const elf_symbol_sptr&
23020{return priv_->symbol_;}
23021
23022/// Test if the function was declared inline.
23023///
23024/// @return true iff the function was declared inline.
23025bool
23027{return priv_->declared_inline_;}
23028
23029/// Set the property of the function being declared inline.
23030///
23031/// @param value true iff the function was declared inline.
23032void
23034{priv_->declared_inline_ = value;}
23035
23037function_decl::get_binding() const
23038{return priv_->binding_;}
23039
23040/// @return the return type of the current instance of function_decl.
23041const shared_ptr<type_base>
23043{return get_type()->get_return_type();}
23044
23045/// @return the parameters of the function.
23046const std::vector<shared_ptr<function_decl::parameter> >&
23048{return get_type()->get_parameters();}
23049
23050/// Append a parameter to the type of this function.
23051///
23052/// @param parm the parameter to append.
23053void
23054function_decl::append_parameter(shared_ptr<parameter> parm)
23055{get_type()->append_parameter(parm);}
23056
23057/// Append a vector of parameters to the type of this function.
23058///
23059/// @param parms the vector of parameters to append.
23060void
23061function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
23062{
23063 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
23064 i != parms.end();
23065 ++i)
23066 get_type()->append_parameter(*i);
23067}
23068
23069/// Create a new instance of function_decl that is a clone of the
23070/// current one.
23071///
23072/// @return the new clone.
23075{
23077 if (is_member_function(*this))
23078 {
23079 method_decl_sptr
23080 m(new method_decl(get_name(),
23081 get_type(),
23083 get_location(),
23086 get_binding()));
23088 ABG_ASSERT(scope);
23092 get_member_is_static(*this),
23096 f = m;
23097 }
23098 else
23099 {
23100 f.reset(new function_decl(get_name(),
23101 get_type(),
23103 get_location(),
23106 get_binding()));
23108 }
23109 f->set_symbol(get_symbol());
23110
23111 return f;
23112}
23113
23114/// Compares two instances of @ref function_decl.
23115///
23116/// If the two intances are different, set a bitfield to give some
23117/// insight about the kind of differences there are.
23118///
23119/// @param l the first artifact of the comparison.
23120///
23121/// @param r the second artifact of the comparison.
23122///
23123/// @param k a pointer to a bitfield that gives information about the
23124/// kind of changes there are between @p l and @p r. This one is set
23125/// iff @p k is non-null and the function returns false.
23126///
23127/// Please note that setting k to a non-null value does have a
23128/// negative performance impact because even if @p l and @p r are not
23129/// equal, the function keeps up the comparison in order to determine
23130/// the different kinds of ways in which they are different.
23131///
23132/// @return true if @p l equals @p r, false otherwise.
23133bool
23135{
23136 bool result = true;
23137
23138 // Compare function types
23139 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
23140 if (t0 == t1 || *t0 == *t1)
23141 ; // the types are equal, let's move on to compare the other
23142 // properties of the functions.
23143 else
23144 {
23145 result = false;
23146 if (k)
23147 {
23148 if (!types_have_similar_structure(t0, t1))
23150 else
23151 *k |= SUBTYPE_CHANGE_KIND;
23152 }
23153 else
23155 }
23156
23157 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
23158 if (!!s0 != !!s1)
23159 {
23160 result = false;
23161 if (k)
23163 else
23165 }
23166 else if (s0 && s0 != s1)
23167 {
23168 if (!elf_symbols_alias(s0, s1))
23169 {
23170 result = false;
23171 if (k)
23173 else
23175 }
23176 }
23177 bool symbols_are_equal = (s0 && s1 && result);
23178
23179 if (symbols_are_equal)
23180 {
23181 // The functions have underlying elf symbols that are equal,
23182 // so now, let's compare the decl_base part of the functions
23183 // w/o considering their decl names.
23184 interned_string n1 = l.get_name(), n2 = r.get_name();
23186 const_cast<function_decl&>(l).set_name("");
23187 const_cast<function_decl&>(l).set_linkage_name("");
23188 const_cast<function_decl&>(r).set_name("");
23189 const_cast<function_decl&>(r).set_linkage_name("");
23190
23191 bool decl_bases_different = !l.decl_base::operator==(r);
23192
23193 const_cast<function_decl&>(l).set_name(n1);
23194 const_cast<function_decl&>(l).set_linkage_name(ln1);
23195 const_cast<function_decl&>(r).set_name(n2);
23196 const_cast<function_decl&>(r).set_linkage_name(ln2);
23197
23198 if (decl_bases_different)
23199 {
23200 result = false;
23201 if (k)
23203 else
23205 }
23206 }
23207 else
23208 if (!l.decl_base::operator==(r))
23209 {
23210 result = false;
23211 if (k)
23213 else
23215 }
23216
23217 // Compare the remaining properties. Note that we don't take into
23218 // account the fact that the function was declared inline or not as
23219 // that doesn't have any impact on the final ABI.
23220 if (l.get_binding() != r.get_binding())
23221 {
23222 result = false;
23223 if (k)
23225 else
23227 }
23228
23230 {
23231 result = false;
23232 if (k)
23234 else
23236 }
23237
23239 {
23252 {
23253 result = false;
23254 if (k)
23256 else
23258 }
23259 }
23260
23261 ABG_RETURN(result);
23262}
23263
23264/// Comparison operator for @ref function_decl.
23265///
23266/// @param other the other instance of @ref function_decl to compare
23267/// against.
23268///
23269/// @return true iff the current instance of @ref function_decl equals
23270/// @p other.
23271bool
23273{
23274 const function_decl* o = dynamic_cast<const function_decl*>(&other);
23275 if (!o)
23276 return false;
23277 return equals(*this, *o, 0);
23278}
23279
23280/// Return true iff the function takes a variable number of
23281/// parameters.
23282///
23283/// @return true if the function taks a variable number
23284/// of parameters.
23285bool
23287{
23288 return (!get_parameters().empty()
23289 && get_parameters().back()->get_variadic_marker());
23290}
23291
23292/// Return an ID that tries to uniquely identify the function inside a
23293/// program or a library.
23294///
23295/// So if the function has an underlying elf symbol, the ID is the
23296/// concatenation of the symbol name and its version. Otherwise, the
23297/// ID is the linkage name if its non-null. Otherwise, it's the
23298/// pretty representation of the function.
23299///
23300/// @return the ID.
23303{
23304 if (priv_->id_.empty())
23305 {
23306 const environment& env = get_type()->get_environment();
23307 if (elf_symbol_sptr s = get_symbol())
23308 {
23309 string virtual_member_suffix;
23310 if (is_member_function(this))
23311 {
23312 method_decl* m = is_method_decl(this);
23313 ABG_ASSERT(m);
23315 {
23317 (m->get_type()->get_class_type(),
23318 /*look_through_decl_only=*/true))
23319 virtual_member_suffix += "/o";
23320 }
23321 }
23322 if (s->has_aliases())
23323 // The symbol has several aliases, so let's use a scheme
23324 // that allows all aliased functions to have different
23325 // IDs.
23326 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
23327 else
23328 // Let's use the full symbol name with its version as ID.
23329 priv_->id_ = env.intern(s->get_id_string());
23330
23331 if (!virtual_member_suffix.empty())
23332 priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
23333 }
23334 else if (!get_linkage_name().empty())
23335 priv_->id_= env.intern(get_linkage_name());
23336 else
23337 priv_->id_ = env.intern(get_pretty_representation());
23338 }
23339 return priv_->id_;
23340}
23341
23342/// Test if two function declarations are aliases.
23343///
23344/// Two functions declarations are aliases if their symbols are
23345/// aliases, in the ELF sense.
23346///
23347/// @param f1 the first function to consider.
23348///
23349/// @param f2 the second function to consider.
23350///
23351/// @return true iff @p f1 is an alias of @p f2
23352bool
23354{
23355 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
23356
23357 if (!s1 || !s2)
23358 return false;
23359
23360 return elf_symbols_alias(s1, s2);
23361}
23362
23363/// This implements the ir_traversable_base::traverse pure virtual
23364/// function.
23365///
23366/// @param v the visitor used on the current instance.
23367///
23368/// @return true if the entire IR node tree got traversed, false
23369/// otherwise.
23370bool
23372{
23373 if (visiting())
23374 return true;
23375
23376 if (v.visit_begin(this))
23377 {
23378 visiting(true);
23379 if (type_base_sptr t = get_type())
23380 t->traverse(v);
23381 visiting(false);
23382 }
23383 return v.visit_end(this);
23384}
23385
23386/// Destructor of the @ref function_decl type.
23388{delete priv_;}
23389
23390/// A deep comparison operator for a shared pointer to @ref function_decl
23391///
23392/// This function compares to shared pointers to @ref function_decl by
23393/// looking at the pointed-to instances of @ref function_dec
23394/// comparing them too. If the two pointed-to objects are equal then
23395/// this function returns true.
23396///
23397/// @param l the left-hand side argument of the equality operator.
23398///
23399/// @param r the right-hand side argument of the equality operator.
23400///
23401/// @return true iff @p l equals @p r.
23402bool
23404{
23405 if (l.get() == r.get())
23406 return true;
23407 if (!!l != !!r)
23408 return false;
23409
23410 return *l == *r;
23411}
23412
23413/// A deep inequality operator for smart pointers to functions.
23414///
23415/// @param l the left-hand side argument of the inequality operator.
23416///
23417/// @pram r the right-hand side argument of the inequality operator.
23418///
23419/// @return true iff @p is not equal to @p r.
23420bool
23422{return !operator==(l, r);}
23423
23424// <function_decl definitions>
23425
23426// <function_decl::parameter definitions>
23427
23428struct function_decl::parameter::priv
23429{
23430 type_base_wptr type_;
23431 unsigned index_;
23432 bool variadic_marker_;
23433
23434 priv()
23435 : index_(),
23436 variadic_marker_()
23437 {}
23438
23439 priv(type_base_sptr type,
23440 unsigned index,
23441 bool variadic_marker)
23442 : type_(type),
23443 index_(index),
23444 variadic_marker_(variadic_marker)
23445 {}
23446};// end struct function_decl::parameter::priv
23447
23448function_decl::parameter::parameter(const type_base_sptr type,
23449 unsigned index,
23450 const string& name,
23451 const location& loc,
23452 bool is_variadic)
23453 : type_or_decl_base(type->get_environment(),
23454 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23455 decl_base(type->get_environment(), name, loc),
23456 priv_(new priv(type, index, is_variadic))
23457{
23458 runtime_type_instance(this);
23459}
23460
23461function_decl::parameter::parameter(const type_base_sptr type,
23462 unsigned index,
23463 const string& name,
23464 const location& loc,
23465 bool is_variadic,
23466 bool is_artificial)
23467 : type_or_decl_base(type->get_environment(),
23468 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23469 decl_base(type->get_environment(), name, loc),
23470 priv_(new priv(type, index, is_variadic))
23471{
23472 runtime_type_instance(this);
23473 set_is_artificial(is_artificial);
23474}
23475
23476function_decl::parameter::parameter(const type_base_sptr type,
23477 const string& name,
23478 const location& loc,
23479 bool is_variadic,
23480 bool is_artificial)
23481 : type_or_decl_base(type->get_environment(),
23482 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23483 decl_base(type->get_environment(), name, loc),
23484 priv_(new priv(type, 0, is_variadic))
23485{
23486 runtime_type_instance(this);
23487 set_is_artificial(is_artificial);
23488}
23489
23490function_decl::parameter::parameter(const type_base_sptr type,
23491 unsigned index,
23492 bool variad)
23493 : type_or_decl_base(type->get_environment(),
23494 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23495 decl_base(type->get_environment(), "", location()),
23496 priv_(new priv(type, index, variad))
23497{
23498 runtime_type_instance(this);
23499}
23500
23501function_decl::parameter::~parameter() = default;
23502
23503const type_base_sptr
23504function_decl::parameter::get_type()const
23505{return priv_->type_.lock();}
23506
23507/// @return a copy of the type name of the parameter.
23508interned_string
23510{
23511 const environment& env = get_environment();
23512
23513 type_base_sptr t = get_type();
23514 string str;
23515 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
23516 str = "...";
23517 else
23518 {
23519 ABG_ASSERT(t);
23521 }
23522 return env.intern(str);
23523}
23524
23525/// @return a copy of the pretty representation of the type of the
23526/// parameter.
23527const string
23529{
23530 type_base_sptr t = get_type();
23531 string str;
23532 if (get_variadic_marker()
23533 || get_environment().is_variadic_parameter_type(t))
23534 str = "...";
23535 else
23536 {
23537 ABG_ASSERT(t);
23539 }
23540 return str;
23541}
23542
23543/// Get a name uniquely identifying the parameter in the function.
23544///
23545///@return the unique parm name id.
23548{
23549 const environment& env = get_environment();
23550
23551
23552 std::ostringstream o;
23553 o << "parameter-" << get_index();
23554
23555 return env.intern(o.str());
23556}
23557
23558unsigned
23559function_decl::parameter::get_index() const
23560{return priv_->index_;}
23561
23562void
23563function_decl::parameter::set_index(unsigned i)
23564{priv_->index_ = i;}
23565
23566
23567bool
23568function_decl::parameter::get_variadic_marker() const
23569{return priv_->variadic_marker_;}
23570
23571/// Compares two instances of @ref function_decl::parameter.
23572///
23573/// If the two intances are different, set a bitfield to give some
23574/// insight about the kind of differences there are.
23575///
23576/// @param l the first artifact of the comparison.
23577///
23578/// @param r the second artifact of the comparison.
23579///
23580/// @param k a pointer to a bitfield that gives information about the
23581/// kind of changes there are between @p l and @p r. This one is set
23582/// iff @p k is non-null and the function returns false.
23583///
23584/// Please note that setting k to a non-null value does have a
23585/// negative performance impact because even if @p l and @p r are not
23586/// equal, the function keeps up the comparison in order to determine
23587/// the different kinds of ways in which they are different.
23588///
23589/// @return true if @p l equals @p r, false otherwise.
23590bool
23592 const function_decl::parameter& r,
23593 change_kind* k)
23594{
23595 bool result = true;
23596
23597 if ((l.get_variadic_marker() != r.get_variadic_marker())
23598 || (l.get_index() != r.get_index())
23599 || (!!l.get_type() != !!r.get_type()))
23600 {
23601 result = false;
23602 if (k)
23603 {
23604 if (l.get_index() != r.get_index())
23606 if (l.get_variadic_marker() != r.get_variadic_marker()
23607 || !!l.get_type() != !!r.get_type())
23609 }
23610 else
23612 }
23613
23614 type_base_sptr l_type = l.get_type();
23615 type_base_sptr r_type = r.get_type();
23616
23617 if (l_type != r_type)
23618 {
23619 result = false;
23620 if (k)
23621 {
23622 if (!types_have_similar_structure(l_type, r_type))
23624 else
23625 *k |= SUBTYPE_CHANGE_KIND;
23626 }
23627 else
23629 }
23630
23631 ABG_RETURN(result);
23632}
23633
23634bool
23635function_decl::parameter::operator==(const parameter& o) const
23636{return equals(*this, o, 0);}
23637
23638bool
23639function_decl::parameter::operator==(const decl_base& o) const
23640{
23641 const function_decl::parameter* p =
23642 dynamic_cast<const function_decl::parameter*>(&o);
23643 if (!p)
23644 return false;
23645 return function_decl::parameter::operator==(*p);
23646}
23647
23648/// Non-member equality operator for @ref function_decl::parameter.
23649///
23650/// @param l the left-hand side of the equality operator
23651///
23652/// @param r the right-hand side of the equality operator
23653///
23654/// @return true iff @p l and @p r equals.
23655bool
23658{
23659 if (!!l != !!r)
23660 return false;
23661 if (!l)
23662 return true;
23663 return *l == *r;
23664}
23665
23666/// Non-member inequality operator for @ref function_decl::parameter.
23667///
23668/// @param l the left-hand side of the equality operator
23669///
23670/// @param r the right-hand side of the equality operator
23671///
23672/// @return true iff @p l and @p r different.
23673bool
23676{return !operator==(l, r);}
23677
23678/// Traverse the diff sub-tree under the current instance
23679/// function_decl.
23680///
23681/// @param v the visitor to invoke on each diff node of the sub-tree.
23682///
23683/// @return true if the traversing has to keep going on, false
23684/// otherwise.
23685bool
23687{
23688 if (visiting())
23689 return true;
23690
23691 if (v.visit_begin(this))
23692 {
23693 visiting(true);
23694 if (type_base_sptr t = get_type())
23695 t->traverse(v);
23696 visiting(false);
23697 }
23698 return v.visit_end(this);
23699}
23700
23701/// Compute the qualified name of the parameter.
23702///
23703/// @param internal set to true if the call is intended for an
23704/// internal use (for technical use inside the library itself), false
23705/// otherwise. If you don't know what this is for, then set it to
23706/// false.
23707///
23708/// @param qn the resulting qualified name.
23709void
23711 bool /*internal*/) const
23712{qualified_name = get_name();}
23713
23714/// Compute and return a copy of the pretty representation of the
23715/// current function parameter.
23716///
23717/// @param internal set to true if the call is intended to get a
23718/// representation of the decl (or type) for the purpose of canonical
23719/// type comparison. This is mainly used in the function
23720/// type_base::get_canonical_type_for().
23721///
23722/// In other words if the argument for this parameter is true then the
23723/// call is meant for internal use (for technical use inside the
23724/// library itself), false otherwise. If you don't know what this is
23725/// for, then set it to false.
23726///
23727/// @return a copy of the textual representation of the current
23728/// function parameter.
23729string
23731 bool qualified_name) const
23732{
23733 const environment& env = get_environment();
23734
23735 string type_repr;
23736 type_base_sptr t = get_type();
23737 if (!t)
23738 type_repr = "void";
23739 else if (env.is_variadic_parameter_type(t))
23740 type_repr = "...";
23741 else
23742 type_repr = ir::get_type_name(t, qualified_name, internal);
23743
23744 string result = type_repr;
23745 string parm_name = get_name_id();
23746
23747 if (!parm_name.empty())
23748 result += " " + parm_name;
23749
23750 return result;
23751}
23752
23753// </function_decl::parameter definitions>
23754
23755// <class_or_union definitions>
23756
23757/// A Constructor for instances of @ref class_or_union
23758///
23759/// @param env the environment we are operating from.
23760///
23761/// @param name the identifier of the class.
23762///
23763/// @param size_in_bits the size of an instance of @ref
23764/// class_or_union, expressed in bits
23765///
23766/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23767/// expressed in bits.
23768///
23769/// @param locus the source location of declaration point this class.
23770///
23771/// @param vis the visibility of instances of @ref class_or_union.
23772///
23773/// @param mem_types the vector of member types of this instance of
23774/// @ref class_or_union.
23775///
23776/// @param data_members the vector of data members of this instance of
23777/// @ref class_or_union.
23778///
23779/// @param member_fns the vector of member functions of this instance
23780/// of @ref class_or_union.
23781class_or_union::class_or_union(const environment& env, const string& name,
23782 size_t size_in_bits, size_t align_in_bits,
23783 const location& locus, visibility vis,
23784 member_types& mem_types,
23786 member_functions& member_fns)
23787 : type_or_decl_base(env,
23788 ABSTRACT_TYPE_BASE
23789 | ABSTRACT_DECL_BASE
23790 | ABSTRACT_SCOPE_TYPE_DECL
23791 | ABSTRACT_SCOPE_DECL),
23792 decl_base(env, name, locus, name, vis),
23793 type_base(env, size_in_bits, align_in_bits),
23794 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23795 priv_(new priv(data_members, member_fns))
23796{
23797 for (member_types::iterator i = mem_types.begin();
23798 i != mem_types.end();
23799 ++i)
23802
23803 for (data_members::iterator i = data_members.begin();
23804 i != data_members.end();
23805 ++i)
23806 if (!has_scope(*i))
23807 add_decl_to_scope(*i, this);
23808
23809 for (member_functions::iterator i = member_fns.begin();
23810 i != member_fns.end();
23811 ++i)
23812 if (!has_scope(static_pointer_cast<decl_base>(*i)))
23813 add_decl_to_scope(*i, this);
23814}
23815
23816/// A constructor for instances of @ref class_or_union.
23817///
23818/// @param env the environment we are operating from.
23819///
23820/// @param name the name of the class.
23821///
23822/// @param size_in_bits the size of an instance of @ref
23823/// class_or_union, expressed in bits
23824///
23825/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23826/// expressed in bits.
23827///
23828/// @param locus the source location of declaration point this class.
23829///
23830/// @param vis the visibility of instances of @ref class_or_union.
23831class_or_union::class_or_union(const environment& env, const string& name,
23832 size_t size_in_bits, size_t align_in_bits,
23833 const location& locus, visibility vis)
23834 : type_or_decl_base(env,
23835 ABSTRACT_TYPE_BASE
23836 | ABSTRACT_DECL_BASE
23837 | ABSTRACT_SCOPE_TYPE_DECL
23838 | ABSTRACT_SCOPE_DECL),
23839 decl_base(env, name, locus, name, vis),
23840 type_base(env, size_in_bits, align_in_bits),
23841 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23842 priv_(new priv)
23843{}
23844
23845/// Constructor of the @ref class_or_union type.
23846///
23847/// @param env the @ref environment we are operating from.
23848///
23849/// @param name the name of the @ref class_or_union.
23850///
23851/// @param is_declaration_only a boolean saying whether the instance
23852/// represents a declaration only, or not.
23853class_or_union::class_or_union(const environment& env, const string& name,
23854 bool is_declaration_only)
23855 : type_or_decl_base(env,
23856 ABSTRACT_TYPE_BASE
23857 | ABSTRACT_DECL_BASE
23858 | ABSTRACT_SCOPE_TYPE_DECL
23859 | ABSTRACT_SCOPE_DECL),
23860 decl_base(env, name, location(), name),
23861 type_base(env, 0, 0),
23862 scope_type_decl(env, name, 0, 0, location()),
23863 priv_(new priv)
23864{
23865 set_is_declaration_only(is_declaration_only);
23866}
23867
23868/// Return the hash value of the current IR node.
23869///
23870/// Note that upon the first invocation, this member functions
23871/// computes the hash value and returns it. Subsequent invocations
23872/// just return the hash value that was previously calculated.
23873///
23874/// @return the hash value of the current IR node.
23875hash_t
23877{
23878 class_or_union::hash do_hash;
23879 hash_t h = do_hash(this);
23880 return h;
23881}
23882
23883/// This implements the ir_traversable_base::traverse pure virtual
23884/// function.
23885///
23886/// @param v the visitor used on the member nodes of the translation
23887/// unit during the traversal.
23888///
23889/// @return true if the entire IR node tree got traversed, false
23890/// otherwise.
23891bool
23893{
23894 if (v.type_node_has_been_visited(this))
23895 return true;
23896
23897 if (visiting())
23898 return true;
23899
23900 if (v.visit_begin(this))
23901 {
23902 visiting(true);
23903 bool stop = false;
23904
23905 if (!stop)
23906 for (data_members::const_iterator i = get_data_members().begin();
23907 i != get_data_members().end();
23908 ++i)
23909 if (!(*i)->traverse(v))
23910 {
23911 stop = true;
23912 break;
23913 }
23914
23915 if (!stop)
23916 for (member_functions::const_iterator i= get_member_functions().begin();
23917 i != get_member_functions().end();
23918 ++i)
23919 if (!(*i)->traverse(v))
23920 {
23921 stop = true;
23922 break;
23923 }
23924
23925 if (!stop)
23926 for (member_types::const_iterator i = get_member_types().begin();
23927 i != get_member_types().end();
23928 ++i)
23929 if (!(*i)->traverse(v))
23930 {
23931 stop = true;
23932 break;
23933 }
23934
23935 if (!stop)
23936 for (member_function_templates::const_iterator i =
23938 i != get_member_function_templates().end();
23939 ++i)
23940 if (!(*i)->traverse(v))
23941 {
23942 stop = true;
23943 break;
23944 }
23945
23946 if (!stop)
23947 for (member_class_templates::const_iterator i =
23949 i != get_member_class_templates().end();
23950 ++i)
23951 if (!(*i)->traverse(v))
23952 {
23953 stop = true;
23954 break;
23955 }
23956 visiting(false);
23957 }
23958
23959 bool result = v.visit_end(this);
23961 return result;
23962}
23963
23964/// Destrcutor of the @ref class_or_union type.
23966{delete priv_;}
23967
23968/// Add a member declaration to the current instance of class_or_union.
23969/// The member declaration can be either a member type, data member,
23970/// member function, or member template.
23971///
23972/// @param d the member declaration to add.
23973decl_base_sptr
23974class_or_union::add_member_decl(const decl_base_sptr& d)
23975{return insert_member_decl(d);}
23976
23977/// Remove a given decl from the current @ref class_or_union scope.
23978///
23979/// Note that only type declarations are supported by this method for
23980/// now. Support for the other kinds of declaration is left as an
23981/// exercise for the interested reader of the code.
23982///
23983/// @param decl the declaration to remove from this @ref
23984/// class_or_union scope.
23985void
23987{
23988 type_base_sptr t = is_type(decl);
23989
23990 // For now we want to support just removing types from classes. For
23991 // other kinds of IR node, we need more work.
23992 ABG_ASSERT(t);
23993
23995}
23996
23997/// Fixup the members of the type of an anonymous data member.
23998///
23999/// Walk all data members of (the type of) a given anonymous data
24000/// member and set a particular property of the relationship between
24001/// each data member and its containing type.
24002///
24003/// That property records the fact that the data member belongs to the
24004/// anonymous data member we consider.
24005///
24006/// In the future, if there are other properties of this relationship
24007/// to set in this manner, they ought to be added here.
24008///
24009/// @param anon_dm the anonymous data member to consider.
24010void
24012{
24013 class_or_union * anon_dm_type =
24015 if (!anon_dm_type)
24016 return;
24017
24018 for (class_or_union::data_members::const_iterator it =
24019 anon_dm_type->get_non_static_data_members().begin();
24020 it != anon_dm_type->get_non_static_data_members().end();
24021 ++it)
24022 {
24023 dm_context_rel *rel =
24024 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
24025 ABG_ASSERT(rel);
24026 rel->set_anonymous_data_member(anon_dm.get());
24027 }
24028}
24029
24030/// Getter of the alignment of the @ref class_or_union type.
24031///
24032/// If this @ref class_or_union is a declaration of a definition that
24033/// is elsewhere, then the size of the definition is returned.
24034///
24035/// @return the alignment of the @ref class_or_union type.
24036size_t
24038{
24042
24044}
24045
24046/// Setter of the alignment of the class type.
24047///
24048/// If this class is a declaration of a definition that is elsewhere,
24049/// then the new alignment is set to the definition.
24050///
24051/// @param s the new alignment.
24052void
24054{
24058 else
24060}
24061
24062/// Setter of the size of the @ref class_or_union type.
24063///
24064/// If this @ref class_or_union is a declaration of a definition that
24065/// is elsewhere, then the new size is set to the definition.
24066///
24067/// @param s the new size.
24068void
24070{
24074 else
24076}
24077
24078/// Getter of the size of the @ref class_or_union type.
24079///
24080/// If this @ref class_or_union is a declaration of a definition that
24081/// is elsewhere, then the size of the definition is returned.
24082///
24083/// @return the size of the @ref class_or_union type.
24084size_t
24086{
24090
24092}
24093
24094/// Get the number of anonymous member classes contained in this
24095/// class.
24096///
24097/// @return the number of anonymous member classes contained in this
24098/// class.
24099size_t
24101{
24102 int result = 0;
24103 for (member_types::const_iterator it = get_member_types().begin();
24104 it != get_member_types().end();
24105 ++it)
24106 if (class_decl_sptr t = is_class_type(*it))
24107 if (t->get_is_anonymous())
24108 ++result;
24109
24110 return result;
24111}
24112
24113/// Get the number of anonymous member unions contained in this class.
24114///
24115/// @return the number of anonymous member unions contained in this
24116/// class.
24117size_t
24119{
24120 int result = 0;
24121 for (member_types::const_iterator it = get_member_types().begin();
24122 it != get_member_types().end();
24123 ++it)
24124 if (union_decl_sptr t = is_union_type(*it))
24125 if (t->get_is_anonymous())
24126 ++result;
24127
24128 return result;
24129}
24130
24131/// Get the number of anonymous member enums contained in this class.
24132///
24133/// @return the number of anonymous member enums contained in this
24134/// class.
24135size_t
24137{
24138 int result = 0;
24139 for (member_types::const_iterator it = get_member_types().begin();
24140 it != get_member_types().end();
24141 ++it)
24142 if (enum_type_decl_sptr t = is_enum_type(*it))
24143 if (t->get_is_anonymous())
24144 ++result;
24145
24146 return result;
24147}
24148
24149/// Add a data member to the current instance of class_or_union.
24150///
24151/// @param v a var_decl to add as a data member. A proper
24152/// class_or_union::data_member is created from @p v and added to the
24153/// class_or_union. This var_decl should not have been already added
24154/// to a scope.
24155///
24156/// @param access the access specifier for the data member.
24157///
24158/// @param is_laid_out whether the data member was laid out. That is,
24159/// if its offset has been computed. In the pattern of a class
24160/// template for instance, this would be set to false.
24161///
24162/// @param is_static whether the data memer is static.
24163///
24164/// @param offset_in_bits if @p is_laid_out is true, this is the
24165/// offset of the data member, expressed (oh, surprise) in bits.
24166void
24168 bool is_laid_out, bool is_static,
24169 size_t offset_in_bits)
24170{
24171 ABG_ASSERT(!has_scope(v));
24172
24173 priv_->data_members_.push_back(v);
24175 set_data_member_is_laid_out(v, is_laid_out);
24176 set_data_member_offset(v, offset_in_bits);
24177 set_member_access_specifier(v, access);
24178 set_member_is_static(v, is_static);
24179
24180 // Add the variable to the set of static or non-static data members,
24181 // if it's not already in there.
24182 bool is_already_in = false;
24183 if (is_static)
24184 {
24185 for (const auto& s_dm: priv_->static_data_members_)
24186 {
24187 if (s_dm == v)
24188 {
24189 is_already_in = true;
24190 break;
24191 }
24192 }
24193 if (!is_already_in)
24194 priv_->static_data_members_.push_back(v);
24195 }
24196 else
24197 {
24198 // If this is a non-static variable, add it to the set of
24199 // non-static variables, if it's not already in there.
24200 for (data_members::const_iterator i =
24201 priv_->non_static_data_members_.begin();
24202 i != priv_->non_static_data_members_.end();
24203 ++i)
24204 if (*i == v)
24205 {
24206 is_already_in = true;
24207 break;
24208 }
24209 if (!is_already_in)
24210 priv_->non_static_data_members_.push_back(v);
24211 }
24212
24213 // If v is an anonymous data member, then fixup its data members.
24214 // For now, the only thing the fixup does is to make the data
24215 // members of the anonymous data member be aware of their containing
24216 // anonymous data member. That is helpful to compute the absolute
24217 // bit offset of each of the members of the anonymous data member.
24219}
24220
24221/// Get the data members of this @ref class_or_union.
24222///
24223/// @return a vector of the data members of this @ref class_or_union.
24226{return priv_->data_members_;}
24227
24228/// Find a data member of a given name in the current @ref class_or_union.
24229///
24230/// @param name the name of the data member to find in the current
24231/// @ref class_or_union.
24232///
24233/// @return a pointer to the @ref var_decl that represents the data
24234/// member to find inside the current @ref class_or_union.
24235const var_decl_sptr
24236class_or_union::find_data_member(const string& name) const
24237{
24238 for (data_members::const_iterator i = get_data_members().begin();
24239 i != get_data_members().end();
24240 ++i)
24241 if ((*i)->get_name() == name)
24242 return *i;
24243
24244 // We haven't found a data member with the name 'name'. Let's look
24245 // closer again, this time in our anonymous data members.
24246 for (data_members::const_iterator i = get_data_members().begin();
24247 i != get_data_members().end();
24248 ++i)
24250 {
24251 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
24252 ABG_ASSERT(type);
24253 if (var_decl_sptr data_member = type->find_data_member(name))
24254 return data_member;
24255 }
24256
24257 return var_decl_sptr();
24258}
24259
24260/// Find an anonymous data member in the class.
24261///
24262/// @param v the anonymous data member to find.
24263///
24264/// @return the anonymous data member found, or nil if none was found.
24265const var_decl_sptr
24267{
24268 if (!v->get_name().empty())
24269 return var_decl_sptr();
24270
24271 for (data_members::const_iterator it = get_non_static_data_members().begin();
24272 it != get_non_static_data_members().end();
24273 ++it)
24274 {
24275 if (is_anonymous_data_member(*it))
24276 if ((*it)->get_pretty_representation(/*internal=*/false, true)
24277 == v->get_pretty_representation(/*internal=*/false, true))
24278 return *it;
24279 }
24280
24281 return var_decl_sptr();
24282}
24283
24284/// Find a given data member.
24285///
24286/// This function takes a @ref var_decl as an argument. If it has a
24287/// non-empty name, then it tries to find a data member which has the
24288/// same name as the argument.
24289///
24290/// If it has an empty name, then the @ref var_decl is considered as
24291/// an anonymous data member. In that case, this function tries to
24292/// find an anonymous data member which type equals that of the @ref
24293/// var_decl argument.
24294///
24295/// @param v this carries either the name of the data member we need
24296/// to look for, or the type of the anonymous data member we are
24297/// looking for.
24298const var_decl_sptr
24300{
24301 if (!v)
24302 return var_decl_sptr();
24303
24304 if (v->get_name().empty())
24306
24307 return find_data_member(v->get_name());
24308}
24309
24310
24311/// Get the non-static data members of this @ref class_or_union.
24312///
24313/// @return a vector of the non-static data members of this @ref
24314/// class_or_union.
24317{return priv_->non_static_data_members_;}
24318
24319/// Get the static data memebers of this @ref class_or_union.
24320///
24321/// @return a vector of the static data members of this @ref
24322/// class_or_union.
24325{return priv_->static_data_members_;}
24326
24327/// Add a member function.
24328///
24329/// @param f the new member function to add.
24330///
24331/// @param a the access specifier to use for the new member function.
24332///
24333/// @param is_static whether the new member function is static.
24334///
24335/// @param is_ctor whether the new member function is a constructor.
24336///
24337/// @param is_dtor whether the new member function is a destructor.
24338///
24339/// @param is_const whether the new member function is const.
24340void
24343 bool is_static, bool is_ctor,
24344 bool is_dtor, bool is_const)
24345{
24346 ABG_ASSERT(!has_scope(f));
24347
24349
24350 set_member_function_is_ctor(f, is_ctor);
24351 set_member_function_is_dtor(f, is_dtor);
24353 set_member_is_static(f, is_static);
24354 set_member_function_is_const(f, is_const);
24355
24356 priv_->member_functions_.push_back(f);
24357
24358 // Update the map of linkage name -> member functions. It's useful,
24359 // so that class_or_union::find_member_function() can function.
24360 if (!f->get_linkage_name().empty())
24361 priv_->mem_fns_map_[f->get_linkage_name()] = f;
24362}
24363
24364/// Get the member functions of this @ref class_or_union.
24365///
24366/// @return a vector of the member functions of this @ref
24367/// class_or_union.
24370{return priv_->member_functions_;}
24371
24372/// Find a method, using its linkage name as a key.
24373///
24374/// @param linkage_name the linkage name of the method to find.
24375///
24376/// @return the method found, or nil if none was found.
24377const method_decl*
24378class_or_union::find_member_function(const string& linkage_name) const
24379{
24380 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
24381}
24382
24383/// Find a method, using its linkage name as a key.
24384///
24385/// @param linkage_name the linkage name of the method to find.
24386///
24387/// @return the method found, or nil if none was found.
24389class_or_union::find_member_function(const string& linkage_name)
24390{
24391 string_mem_fn_sptr_map_type::const_iterator i =
24392 priv_->mem_fns_map_.find(linkage_name);
24393 if (i == priv_->mem_fns_map_.end())
24394 return 0;
24395 return i->second.get();
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.
24403method_decl_sptr
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;
24411}
24412
24413/// Find a method (member function) using its signature (pretty
24414/// representation) as a key.
24415///
24416/// @param s the signature of the method.
24417///
24418/// @return the method found, or nil if none was found.
24419const method_decl*
24421{
24422 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
24423}
24424
24425/// Find a method (member function) using its signature (pretty
24426/// representation) as a key.
24427///
24428/// @param s the signature of the method.
24429///
24430/// @return the method found, or nil if none was found.
24433{
24434 string_mem_fn_ptr_map_type::const_iterator i =
24435 priv_->signature_2_mem_fn_map_.find(s);
24436 if (i == priv_->signature_2_mem_fn_map_.end())
24437 return 0;
24438 return i->second;
24439}
24440
24441/// Get the member function templates of this class.
24442///
24443/// @return a vector of the member function templates of this class.
24444const member_function_templates&
24446{return priv_->member_function_templates_;}
24447
24448/// Get the member class templates of this class.
24449///
24450/// @return a vector of the member class templates of this class.
24451const member_class_templates&
24453{return priv_->member_class_templates_;}
24454
24455/// Append a member function template to the @ref class_or_union.
24456///
24457/// @param m the member function template to append.
24458void
24459class_or_union::add_member_function_template(member_function_template_sptr m)
24460{
24461 decl_base* c = m->as_function_tdecl()->get_scope();
24462 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24463 /// error message or something like a structured error.
24464 priv_->member_function_templates_.push_back(m);
24465 if (!c)
24466 scope_decl::add_member_decl(m->as_function_tdecl());
24467}
24468
24469/// Append a member class template to the @ref class_or_union.
24470///
24471/// @param m the member function template to append.
24472void
24474{
24475 decl_base* c = m->as_class_tdecl()->get_scope();
24476 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24477 /// error message or something like a structured error.
24478 m->set_scope(this);
24479 priv_->member_class_templates_.push_back(m);
24480 if (!c)
24481 scope_decl::add_member_decl(m->as_class_tdecl());
24482}
24483
24484///@return true iff the current instance has no member.
24485bool
24487{
24488 return (get_member_types().empty()
24489 && priv_->data_members_.empty()
24490 && priv_->member_functions_.empty()
24491 && priv_->member_function_templates_.empty()
24492 && priv_->member_class_templates_.empty());
24493}
24494
24495/// Insert a data member to this @ref class_or_union type.
24496///
24497/// @param d the data member to insert.
24498///
24499/// @return the decl @p that got inserted.
24500decl_base_sptr
24502{
24503 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
24504 {
24505 add_data_member(v, public_access,
24506 /*is_laid_out=*/false,
24507 /*is_static=*/true,
24508 /*offset_in_bits=*/0);
24509 d = v;
24510 }
24511 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24512 add_member_function(f, public_access,
24513 /*is_static=*/false,
24514 /*is_ctor=*/false,
24515 /*is_dtor=*/false,
24516 /*is_const=*/false);
24517 else if (member_function_template_sptr f =
24518 dynamic_pointer_cast<member_function_template>(d))
24520 else if (member_class_template_sptr c =
24521 dynamic_pointer_cast<member_class_template>(d))
24523 else
24525
24526 return d;
24527}
24528
24529/// Equality operator.
24530///
24531/// @param other the other @ref class_or_union to compare against.
24532///
24533/// @return true iff @p other equals the current @ref class_or_union.
24534bool
24536{
24537 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
24538 if (!op)
24539 return false;
24540
24541 // If this is a decl-only type (and thus with no canonical type),
24542 // use the canonical type of the definition, if any.
24543 const class_or_union *l = 0;
24545 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
24546 if (l == 0)
24547 l = this;
24548
24549 // Likewise for the other class.
24550 const class_or_union *r = 0;
24551 if (op->get_is_declaration_only())
24552 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
24553 if (r == 0)
24554 r = op;
24555
24556 return try_canonical_compare(l, r);
24557}
24558
24559/// Equality operator.
24560///
24561/// @param other the other @ref class_or_union to compare against.
24562///
24563/// @return true iff @p other equals the current @ref class_or_union.
24564bool
24566{
24567 const decl_base* o = dynamic_cast<const decl_base*>(&other);
24568 if (!o)
24569 return false;
24570 return *this == *o;
24571}
24572
24573/// Equality operator.
24574///
24575/// @param other the other @ref class_or_union to compare against.
24576///
24577/// @return true iff @p other equals the current @ref class_or_union.
24578bool
24580{
24581 const decl_base& o = other;
24583}
24584
24585/// Compares two instances of @ref class_or_union.
24586///
24587/// If the two intances are different, set a bitfield to give some
24588/// insight about the kind of differences there are.
24589///
24590/// @param l the first artifact of the comparison.
24591///
24592/// @param r the second artifact of the comparison.
24593///
24594/// @param k a pointer to a bitfield that gives information about the
24595/// kind of changes there are between @p l and @p r. This one is set
24596/// iff it's non-null and if the function returns false.
24597///
24598/// Please note that setting k to a non-null value does have a
24599/// negative performance impact because even if @p l and @p r are not
24600/// equal, the function keeps up the comparison in order to determine
24601/// the different kinds of ways in which they are different.
24602///
24603/// @return true if @p l equals @p r, false otherwise.
24604bool
24606{
24607 // if one of the classes is declaration-only, look through it to
24608 // get its definition.
24609 bool l_is_decl_only = l.get_is_declaration_only();
24610 bool r_is_decl_only = r.get_is_declaration_only();
24611 if (l_is_decl_only || r_is_decl_only)
24612 {
24613 const class_or_union* def1 = l_is_decl_only
24615 : &l;
24616
24617 const class_or_union* def2 = r_is_decl_only
24619 : &r;
24620
24621 if (!def1 || !def2)
24622 {
24623 if (!l.get_is_anonymous()
24624 && !r.get_is_anonymous()
24625 && l_is_decl_only && r_is_decl_only
24627 // The two decl-only classes differ from their size. A
24628 // true decl-only class should not have a size property to
24629 // begin with. This comes from a DWARF oddity and can
24630 // results in a false positive, so let's not consider that
24631 // change.
24632 return true;
24633
24637 {
24638 const interned_string& q1 = l.get_scoped_name();
24639 const interned_string& q2 = r.get_scoped_name();
24640 if (q1 == q2)
24641 // Not using RETURN(true) here, because that causes
24642 // performance issues. We don't need to do
24643 // l.priv_->unmark_as_being_compared({l,r}) here because
24644 // we haven't marked l or r as being compared yet, and
24645 // doing so has a peformance cost that shows up on
24646 // performance profiles for *big* libraries.
24647 return true;
24648 else
24649 {
24650 if (k)
24652 // Not using RETURN(true) here, because that causes
24653 // performance issues. We don't need to do
24654 // l.priv_->unmark_as_being_compared({l,r}) here because
24655 // we haven't marked l or r as being compared yet, and
24656 // doing so has a peformance cost that shows up on
24657 // performance profiles for *big* libraries.
24659 }
24660 }
24661 else // A decl-only class is considered different from a
24662 // class definition of the same name.
24663 {
24664 if (!!def1 != !!def2)
24665 {
24666 if (k)
24669 }
24670
24671 // both definitions are empty
24672 if (!(l.decl_base::operator==(r)
24673 && l.type_base::operator==(r)))
24674 {
24675 if (k)
24678 }
24679
24680 return true;
24681 }
24682 }
24683
24684 bool val = *def1 == *def2;
24685 if (!val)
24686 if (k)
24688 ABG_RETURN(val);
24689 }
24690
24691 // No need to go further if the classes have different names or
24692 // different size / alignment.
24693 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
24694 {
24695 if (k)
24698 }
24699
24700 if (types_defined_same_linux_kernel_corpus_public(l, r))
24701 return true;
24702
24703 //TODO: Maybe remove this (cycle detection and canonical type
24704 //propagation handling) from here and have it only in the equal
24705 //overload for class_decl and union_decl because this one ( the
24706 //equal overload for class_or_union) is just a sub-routine of these
24707 //two above.
24708#define RETURN(value) \
24709 return return_comparison_result(l, r, value);
24710
24712
24714
24715 bool result = true;
24716
24717 //compare data_members
24718 {
24719 if (l.get_non_static_data_members().size()
24720 != r.get_non_static_data_members().size())
24721 {
24722 result = false;
24723 if (k)
24725 else
24726 RETURN(result);
24727 }
24728
24729 for (class_or_union::data_members::const_iterator
24730 d0 = l.get_non_static_data_members().begin(),
24731 d1 = r.get_non_static_data_members().begin();
24732 (d0 != l.get_non_static_data_members().end()
24733 && d1 != r.get_non_static_data_members().end());
24734 ++d0, ++d1)
24735 if (**d0 != **d1)
24736 {
24737 result = false;
24738 if (k)
24739 {
24740 // Report any representation change as being local.
24741 if (!types_have_similar_structure((*d0)->get_type(),
24742 (*d1)->get_type())
24743 || (*d0)->get_type() == (*d1)->get_type())
24745 else
24746 *k |= SUBTYPE_CHANGE_KIND;
24747 }
24748 else
24749 RETURN(result);
24750 }
24751 }
24752
24753 // Do not compare member functions. DWARF does not necessarily
24754 // all the member functions, be they virtual or not, in all
24755 // translation units. So we cannot have a clear view of them, per
24756 // class
24757
24758 // compare member function templates
24759 {
24760 if (l.get_member_function_templates().size()
24761 != r.get_member_function_templates().size())
24762 {
24763 result = false;
24764 if (k)
24766 else
24767 RETURN(result);
24768 }
24769
24770 for (member_function_templates::const_iterator
24771 fn_tmpl_it0 = l.get_member_function_templates().begin(),
24772 fn_tmpl_it1 = r.get_member_function_templates().begin();
24773 fn_tmpl_it0 != l.get_member_function_templates().end()
24774 && fn_tmpl_it1 != r.get_member_function_templates().end();
24775 ++fn_tmpl_it0, ++fn_tmpl_it1)
24776 if (**fn_tmpl_it0 != **fn_tmpl_it1)
24777 {
24778 result = false;
24779 if (k)
24780 {
24782 break;
24783 }
24784 else
24785 RETURN(result);
24786 }
24787 }
24788
24789 // compare member class templates
24790 {
24791 if (l.get_member_class_templates().size()
24792 != r.get_member_class_templates().size())
24793 {
24794 result = false;
24795 if (k)
24797 else
24798 RETURN(result);
24799 }
24800
24801 for (member_class_templates::const_iterator
24802 cl_tmpl_it0 = l.get_member_class_templates().begin(),
24803 cl_tmpl_it1 = r.get_member_class_templates().begin();
24804 cl_tmpl_it0 != l.get_member_class_templates().end()
24805 && cl_tmpl_it1 != r.get_member_class_templates().end();
24806 ++cl_tmpl_it0, ++cl_tmpl_it1)
24807 if (**cl_tmpl_it0 != **cl_tmpl_it1)
24808 {
24809 result = false;
24810 if (k)
24811 {
24813 break;
24814 }
24815 else
24816 RETURN(result);
24817 }
24818 }
24819
24820 RETURN(result);
24821#undef RETURN
24822}
24823
24824
24825/// Copy a method of a @ref class_or_union into a new @ref
24826/// class_or_union.
24827///
24828/// @param t the @ref class_or_union into which the method is to be copied.
24829///
24830/// @param method the method to copy into @p t.
24831///
24832/// @return the resulting newly copied method.
24833method_decl_sptr
24834copy_member_function(const class_or_union_sptr& t,
24835 const method_decl_sptr& method)
24836{return copy_member_function(t, method.get());}
24837
24838
24839/// Copy a method of a @ref class_or_union into a new @ref
24840/// class_or_union.
24841///
24842/// @param t the @ref class_or_union into which the method is to be copied.
24843///
24844/// @param method the method to copy into @p t.
24845///
24846/// @return the resulting newly copied method.
24847method_decl_sptr
24848copy_member_function(const class_or_union_sptr& t, const method_decl* method)
24849{
24850 ABG_ASSERT(t);
24851 ABG_ASSERT(method);
24852
24853 method_type_sptr old_type = method->get_type();
24854 ABG_ASSERT(old_type);
24855 method_type_sptr new_type(new method_type(old_type->get_return_type(),
24856 t,
24857 old_type->get_parameters(),
24858 old_type->get_is_const(),
24859 old_type->get_size_in_bits(),
24860 old_type->get_alignment_in_bits()));
24861 t->get_translation_unit()->bind_function_type_life_time(new_type);
24862
24863 method_decl_sptr
24864 new_method(new method_decl(method->get_name(),
24865 new_type,
24866 method->is_declared_inline(),
24867 method->get_location(),
24868 method->get_linkage_name(),
24869 method->get_visibility(),
24870 method->get_binding()));
24871 new_method->set_symbol(method->get_symbol());
24872
24873 if (class_decl_sptr class_type = is_class_type(t))
24874 class_type->add_member_function(new_method,
24878 get_member_is_static(*method),
24882 else
24883 t->add_member_function(new_method,
24885 get_member_is_static(*method),
24889 return new_method;
24890}
24891
24892// </class_or_union definitions>
24893
24894// <class_decl definitions>
24895
24896static void
24897sort_virtual_member_functions(class_decl::member_functions& mem_fns);
24898
24899/// The private data for the class_decl type.
24900struct class_decl::priv
24901{
24902 base_specs bases_;
24903 unordered_map<string, base_spec_sptr> bases_map_;
24904 member_functions virtual_mem_fns_;
24905 virtual_mem_fn_map_type virtual_mem_fns_map_;
24906 bool is_struct_;
24907
24908 priv()
24909 : is_struct_(false)
24910 {}
24911
24912 priv(bool is_struct, class_decl::base_specs& bases)
24913 : bases_(bases),
24914 is_struct_(is_struct)
24915 {
24916 }
24917
24918 priv(bool is_struct)
24919 : is_struct_(is_struct)
24920 {}
24921};// end struct class_decl::priv
24922
24923/// A Constructor for instances of \ref class_decl
24924///
24925/// @param env the environment we are operating from.
24926///
24927/// @param name the identifier of the class.
24928///
24929/// @param size_in_bits the size of an instance of class_decl, expressed
24930/// in bits
24931///
24932/// @param align_in_bits the alignment of an instance of class_decl,
24933/// expressed in bits.
24934///
24935/// @param locus the source location of declaration point this class.
24936///
24937/// @param vis the visibility of instances of class_decl.
24938///
24939/// @param bases the vector of base classes for this instance of class_decl.
24940///
24941/// @param mbrs the vector of member types of this instance of
24942/// class_decl.
24943///
24944/// @param data_mbrs the vector of data members of this instance of
24945/// class_decl.
24946///
24947/// @param mbr_fns the vector of member functions of this instance of
24948/// class_decl.
24949class_decl::class_decl(const environment& env, const string& name,
24950 size_t size_in_bits, size_t align_in_bits,
24951 bool is_struct, const location& locus,
24952 visibility vis, base_specs& bases,
24953 member_types& mbr_types,
24954 data_members& data_mbrs,
24955 member_functions& mbr_fns)
24956 : type_or_decl_base(env,
24957 CLASS_TYPE
24958 | ABSTRACT_TYPE_BASE
24959 | ABSTRACT_DECL_BASE
24960 | ABSTRACT_SCOPE_TYPE_DECL
24961 | ABSTRACT_SCOPE_DECL),
24962 decl_base(env, name, locus, name, vis),
24963 type_base(env, size_in_bits, align_in_bits),
24964 class_or_union(env, name, size_in_bits, align_in_bits,
24965 locus, vis, mbr_types, data_mbrs, mbr_fns),
24966 priv_(new priv(is_struct, bases))
24967{
24969}
24970
24971/// A Constructor for instances of @ref class_decl
24972///
24973/// @param env the environment we are operating from.
24974///
24975/// @param name the identifier of the class.
24976///
24977/// @param size_in_bits the size of an instance of class_decl, expressed
24978/// in bits
24979///
24980/// @param align_in_bits the alignment of an instance of class_decl,
24981/// expressed in bits.
24982///
24983/// @param locus the source location of declaration point this class.
24984///
24985/// @param vis the visibility of instances of class_decl.
24986///
24987/// @param bases the vector of base classes for this instance of class_decl.
24988///
24989/// @param mbrs the vector of member types of this instance of
24990/// class_decl.
24991///
24992/// @param data_mbrs the vector of data members of this instance of
24993/// class_decl.
24994///
24995/// @param mbr_fns the vector of member functions of this instance of
24996/// class_decl.
24997///
24998/// @param is_anonymous whether the newly created instance is
24999/// anonymous.
25000class_decl::class_decl(const environment& env, const string& name,
25001 size_t size_in_bits, size_t align_in_bits,
25002 bool is_struct, const location& locus,
25003 visibility vis, base_specs& bases,
25004 member_types& mbr_types, data_members& data_mbrs,
25005 member_functions& mbr_fns, bool is_anonymous)
25006 : type_or_decl_base(env,
25007 CLASS_TYPE
25008 | ABSTRACT_TYPE_BASE
25009 | ABSTRACT_DECL_BASE
25010 | ABSTRACT_SCOPE_TYPE_DECL
25011 | ABSTRACT_SCOPE_DECL),
25012 decl_base(env, name, locus,
25013 // If the class is anonymous then by default it won't
25014 // have a linkage name. Also, the anonymous class does
25015 // have an internal-only unique name that is generally
25016 // not taken into account when comparing classes; such a
25017 // unique internal-only name, when used as a linkage
25018 // name might introduce spurious comparison false
25019 // negatives.
25020 /*linkage_name=*/is_anonymous ? string() : name,
25021 vis),
25022 type_base(env, size_in_bits, align_in_bits),
25023 class_or_union(env, name, size_in_bits, align_in_bits,
25024 locus, vis, mbr_types, data_mbrs, mbr_fns),
25025 priv_(new priv(is_struct, bases))
25026{
25028 set_is_anonymous(is_anonymous);
25029}
25030
25031/// A constructor for instances of class_decl.
25032///
25033/// @param env the environment we are operating from.
25034///
25035/// @param name the name of the class.
25036///
25037/// @param size_in_bits the size of an instance of class_decl, expressed
25038/// in bits
25039///
25040/// @param align_in_bits the alignment of an instance of class_decl,
25041/// expressed in bits.
25042///
25043/// @param locus the source location of declaration point this class.
25044///
25045/// @param vis the visibility of instances of class_decl.
25046class_decl::class_decl(const environment& env, const string& name,
25047 size_t size_in_bits, size_t align_in_bits,
25048 bool is_struct, const location& locus,
25049 visibility vis)
25050 : type_or_decl_base(env,
25051 CLASS_TYPE
25052 | ABSTRACT_TYPE_BASE
25053 | ABSTRACT_DECL_BASE
25054 | ABSTRACT_SCOPE_TYPE_DECL
25055 | ABSTRACT_SCOPE_DECL),
25056 decl_base(env, name, locus, name, vis),
25057 type_base(env, size_in_bits, align_in_bits),
25058 class_or_union(env, name, size_in_bits, align_in_bits,
25059 locus, vis),
25060 priv_(new priv(is_struct))
25061{
25063}
25064
25065/// A constructor for instances of @ref class_decl.
25066///
25067/// @param env the environment we are operating from.
25068///
25069/// @param name the name of the class.
25070///
25071/// @param size_in_bits the size of an instance of class_decl, expressed
25072/// in bits
25073///
25074/// @param align_in_bits the alignment of an instance of class_decl,
25075/// expressed in bits.
25076///
25077/// @param locus the source location of declaration point this class.
25078///
25079/// @param vis the visibility of instances of class_decl.
25080///
25081/// @param is_anonymous whether the newly created instance is
25082/// anonymous.
25083class_decl:: class_decl(const environment& env, const string& name,
25084 size_t size_in_bits, size_t align_in_bits,
25085 bool is_struct, const location& locus,
25086 visibility vis, bool is_anonymous)
25087 : type_or_decl_base(env,
25088 CLASS_TYPE
25089 | ABSTRACT_TYPE_BASE
25090 | ABSTRACT_DECL_BASE
25091 | ABSTRACT_SCOPE_TYPE_DECL
25092 | ABSTRACT_SCOPE_DECL),
25093 decl_base(env, name, locus,
25094 // If the class is anonymous then by default it won't
25095 // have a linkage name. Also, the anonymous class does
25096 // have an internal-only unique name that is generally
25097 // not taken into account when comparing classes; such a
25098 // unique internal-only name, when used as a linkage
25099 // name might introduce spurious comparison false
25100 // negatives.
25101 /*linkage_name=*/ is_anonymous ? string() : name,
25102 vis),
25103 type_base(env, size_in_bits, align_in_bits),
25104 class_or_union(env, name, size_in_bits, align_in_bits,
25105 locus, vis),
25106 priv_(new priv(is_struct))
25107{
25109 set_is_anonymous(is_anonymous);
25110}
25111
25112/// A constuctor for instances of class_decl that represent a
25113/// declaration without definition.
25114///
25115/// @param env the environment we are operating from.
25116///
25117/// @param name the name of the class.
25118///
25119/// @param is_declaration_only a boolean saying whether the instance
25120/// represents a declaration only, or not.
25121class_decl::class_decl(const environment& env, const string& name,
25122 bool is_struct, bool is_declaration_only)
25123 : type_or_decl_base(env,
25124 CLASS_TYPE
25125 | ABSTRACT_TYPE_BASE
25126 | ABSTRACT_DECL_BASE
25127 | ABSTRACT_SCOPE_TYPE_DECL
25128 | ABSTRACT_SCOPE_DECL),
25129 decl_base(env, name, location(), name),
25130 type_base(env, 0, 0),
25131 class_or_union(env, name, is_declaration_only),
25132 priv_(new priv(is_struct))
25133{
25135}
25136
25137/// This method is invoked automatically right after the current
25138/// instance of @ref class_decl has been canonicalized.
25139///
25140/// Currently, the only thing it does is to sort the virtual member
25141/// functions vector.
25142void
25144{
25146
25147 for (class_decl::virtual_mem_fn_map_type::iterator i =
25148 priv_->virtual_mem_fns_map_.begin();
25149 i != priv_->virtual_mem_fns_map_.end();
25150 ++i)
25151 sort_virtual_member_functions(i->second);
25152}
25153
25154/// Set the "is-struct" flag of the class.
25155///
25156/// @param f the new value of the flag.
25157void
25159{priv_->is_struct_ = f;}
25160
25161/// Test if the class is a struct.
25162///
25163/// @return true iff the class is a struct.
25164bool
25166{return priv_->is_struct_;}
25167
25168/// Add a base specifier to this class.
25169///
25170/// @param b the new base specifier.
25171void
25173{
25174 priv_->bases_.push_back(b);
25175 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
25176}
25177
25178/// Get the base specifiers for this class.
25179///
25180/// @return a vector of the base specifiers.
25183{return priv_->bases_;}
25184
25185/// Find a base class of a given qualified name for the current class.
25186///
25187/// @param qualified_name the qualified name of the base class to look for.
25188///
25189/// @return a pointer to the @ref class_decl that represents the base
25190/// class of name @p qualified_name, if found.
25192class_decl::find_base_class(const string& qualified_name) const
25193{
25194 unordered_map<string, base_spec_sptr>::iterator i =
25195 priv_->bases_map_.find(qualified_name);
25196
25197 if (i != priv_->bases_map_.end())
25198 return i->second->get_base_class();
25199
25200 return class_decl_sptr();
25201}
25202
25203/// Get the virtual member functions of this class.
25204///
25205/// @param return a vector of the virtual member functions of this
25206/// class.
25209{return priv_->virtual_mem_fns_;}
25210
25211/// Get the map that associates a virtual table offset to the virtual
25212/// member functions with that virtual table offset.
25213///
25214/// Usually, there should be a 1:1 mapping between a given vtable
25215/// offset and virtual member functions of that vtable offset. But
25216/// because of some implementation details, there can be several C++
25217/// destructor functions that are *generated* by compilers, for a
25218/// given destructor that is defined in the source code. If the
25219/// destructor is virtual then those generated functions have some
25220/// DWARF attributes in common with the constructor that the user
25221/// actually defined in its source code. Among those attributes are
25222/// the vtable offset of the destructor.
25223///
25224/// @return the map that associates a virtual table offset to the
25225/// virtual member functions with that virtual table offset.
25228{return priv_->virtual_mem_fns_map_;}
25229
25230/// Sort the virtual member functions by their virtual index.
25231void
25233{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
25234
25235/// Getter of the pretty representation of the current instance of
25236/// @ref class_decl.
25237///
25238/// @param internal set to true if the call is intended to get a
25239/// representation of the decl (or type) for the purpose of canonical
25240/// type comparison. This is mainly used in the function
25241/// type_base::get_canonical_type_for().
25242///
25243/// In other words if the argument for this parameter is true then the
25244/// call is meant for internal use (for technical use inside the
25245/// library itself), false otherwise. If you don't know what this is
25246/// for, then set it to false.
25247///
25248/// @param qualified_name if true, names emitted in the pretty
25249/// representation are fully qualified.
25250///
25251/// @return the pretty representaion for a class_decl.
25252string
25254 bool qualified_name) const
25255{
25256 string cl = "class ";
25257 if (!internal && is_struct())
25258 cl = "struct ";
25259
25260 // When computing the pretty representation for internal purposes,
25261 // if an anonymous class is named by a typedef, then consider that
25262 // it has a name, which is the typedef name.
25263 if (get_is_anonymous())
25264 {
25265 if (internal && !get_name().empty())
25266 return cl + get_type_name(this, qualified_name, /*internal=*/true);
25268 /*one_line=*/true,
25269 internal);
25270
25271 }
25272
25273 string result = cl;
25274 if (qualified_name)
25275 result += get_qualified_name(internal);
25276 else
25277 result += get_name();
25278
25279 return result;
25280}
25281
25282decl_base_sptr
25283class_decl::insert_member_decl(decl_base_sptr d)
25284{
25285 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
25286 add_member_function(f, public_access,
25287 /*is_virtual=*/false,
25288 /*vtable_offset=*/0,
25289 /*is_static=*/false,
25290 /*is_ctor=*/false,
25291 /*is_dtor=*/false,
25292 /*is_const=*/false);
25293 else
25295
25296 return d;
25297}
25298
25299/// The private data structure of class_decl::base_spec.
25300struct class_decl::base_spec::priv
25301{
25302 class_decl_wptr base_class_;
25303 long offset_in_bits_;
25304 bool is_virtual_;
25305
25306 priv(const class_decl_sptr& cl,
25307 long offset_in_bits,
25308 bool is_virtual)
25309 : base_class_(cl),
25310 offset_in_bits_(offset_in_bits),
25311 is_virtual_(is_virtual)
25312 {}
25313};
25314
25315/// Constructor for base_spec instances.
25316///
25317/// @param base the base class to consider
25318///
25319/// @param a the access specifier of the base class.
25320///
25321/// @param offset_in_bits if positive or null, represents the offset
25322/// of the base in the layout of its containing type.. If negative,
25323/// means that the current base is not laid out in its containing type.
25324///
25325/// @param is_virtual if true, means that the current base class is
25326/// virtual in it's containing type.
25327class_decl::base_spec::base_spec(const class_decl_sptr& base,
25329 long offset_in_bits,
25330 bool is_virtual)
25331 : type_or_decl_base(base->get_environment(),
25332 ABSTRACT_DECL_BASE),
25333 decl_base(base->get_environment(), base->get_name(), base->get_location(),
25334 base->get_linkage_name(), base->get_visibility()),
25335 member_base(a),
25336 priv_(new priv(base, offset_in_bits, is_virtual))
25337{
25339 set_qualified_name(base->get_qualified_name());
25340}
25341
25342/// Return the hash value of the current IR node.
25343///
25344/// Note that upon the first invocation, this member functions
25345/// computes the hash value and returns it. Subsequent invocations
25346/// just return the hash value that was previously calculated.
25347///
25348/// @return the hash value of the current IR node.
25349hash_t
25351{
25353 return h;
25354}
25355
25356/// Get the base class referred to by the current base class
25357/// specifier.
25358///
25359/// @return the base class.
25362{return priv_->base_class_.lock();}
25363
25364/// Getter of the "is-virtual" proprerty of the base class specifier.
25365///
25366/// @return true iff this specifies a virtual base class.
25367bool
25369{return priv_->is_virtual_;}
25370
25371/// Getter of the offset of the base.
25372///
25373/// @return the offset of the base.
25374long
25376{return priv_->offset_in_bits_;}
25377
25378/// Traverses an instance of @ref class_decl::base_spec, visiting all
25379/// the sub-types and decls that it might contain.
25380///
25381/// @param v the visitor that is used to visit every IR sub-node of
25382/// the current node.
25383///
25384/// @return true if either
25385/// - all the children nodes of the current IR node were traversed
25386/// and the calling code should keep going with the traversing.
25387/// - or the current IR node is already being traversed.
25388/// Otherwise, returning false means that the calling code should not
25389/// keep traversing the tree.
25390bool
25392{
25393 if (visiting())
25394 return true;
25395
25396 if (v.visit_begin(this))
25397 {
25398 visiting(true);
25399 get_base_class()->traverse(v);
25400 visiting(false);
25401 }
25402
25403 return v.visit_end(this);
25404}
25405
25406/// Constructor for base_spec instances.
25407///
25408/// Note that this constructor is for clients that don't support RTTI
25409/// and that have a base class of type_base, but of dynamic type
25410/// class_decl.
25411///
25412/// @param base the base class to consider. Must be a pointer to an
25413/// instance of class_decl
25414///
25415/// @param a the access specifier of the base class.
25416///
25417/// @param offset_in_bits if positive or null, represents the offset
25418/// of the base in the layout of its containing type.. If negative,
25419/// means that the current base is not laid out in its containing type.
25420///
25421/// @param is_virtual if true, means that the current base class is
25422/// virtual in it's containing type.
25423class_decl::base_spec::base_spec(const type_base_sptr& base,
25425 long offset_in_bits,
25426 bool is_virtual)
25428 ABSTRACT_DECL_BASE),
25433 member_base(a),
25434 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
25435 offset_in_bits,
25436 is_virtual))
25437{
25439}
25440
25441class_decl::base_spec::~base_spec() = default;
25442
25443/// Compares two instances of @ref class_decl::base_spec.
25444///
25445/// If the two intances are different, set a bitfield to give some
25446/// insight about the kind of differences there are.
25447///
25448/// @param l the first artifact of the comparison.
25449///
25450/// @param r the second artifact of the comparison.
25451///
25452/// @param k a pointer to a bitfield that gives information about the
25453/// kind of changes there are between @p l and @p r. This one is set
25454/// iff @p k is non-null and the function returns false.
25455///
25456/// Please note that setting k to a non-null value does have a
25457/// negative performance impact because even if @p l and @p r are not
25458/// equal, the function keeps up the comparison in order to determine
25459/// the different kinds of ways in which they are different.
25460///
25461/// @return true if @p l equals @p r, false otherwise.
25462bool
25464 const class_decl::base_spec& r,
25465 change_kind* k)
25466{
25467 if (!l.member_base::operator==(r))
25468 {
25469 if (k)
25472 }
25473
25475}
25476
25477/// Comparison operator for @ref class_decl::base_spec.
25478///
25479/// @param other the instance of @ref class_decl::base_spec to compare
25480/// against.
25481///
25482/// @return true if the current instance of @ref class_decl::base_spec
25483/// equals @p other.
25484bool
25486{
25487 const class_decl::base_spec* o =
25488 dynamic_cast<const class_decl::base_spec*>(&other);
25489
25490 if (!o)
25491 return false;
25492
25493 return equals(*this, *o, 0);
25494}
25495
25496/// Comparison operator for @ref class_decl::base_spec.
25497///
25498/// @param other the instance of @ref class_decl::base_spec to compare
25499/// against.
25500///
25501/// @return true if the current instance of @ref class_decl::base_spec
25502/// equals @p other.
25503bool
25505{
25506 const class_decl::base_spec* o =
25507 dynamic_cast<const class_decl::base_spec*>(&other);
25508 if (!o)
25509 return false;
25510
25511 return operator==(static_cast<const decl_base&>(*o));
25512}
25513
25514mem_fn_context_rel::~mem_fn_context_rel()
25515{
25516}
25517
25518/// A constructor for instances of method_decl.
25519///
25520/// @param name the name of the method.
25521///
25522/// @param type the type of the method.
25523///
25524/// @param declared_inline whether the method was
25525/// declared inline or not.
25526///
25527/// @param locus the source location of the method.
25528///
25529/// @param linkage_name the mangled name of the method.
25530///
25531/// @param vis the visibility of the method.
25532///
25533/// @param bind the binding of the method.
25534method_decl::method_decl(const string& name,
25535 method_type_sptr type,
25536 bool declared_inline,
25537 const location& locus,
25538 const string& linkage_name,
25539 visibility vis,
25540 binding bind)
25542 METHOD_DECL
25543 | ABSTRACT_DECL_BASE
25544 |FUNCTION_DECL),
25545 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25546 function_decl(name, static_pointer_cast<function_type>(type),
25547 declared_inline, locus, linkage_name, vis, bind)
25548{
25550 set_context_rel(new mem_fn_context_rel(0));
25551 set_member_function_is_const(*this, type->get_is_const());
25552}
25553
25554/// A constructor for instances of method_decl.
25555///
25556/// @param name the name of the method.
25557///
25558/// @param type the type of the method. Must be an instance of
25559/// method_type.
25560///
25561/// @param declared_inline whether the method was
25562/// declared inline or not.
25563///
25564/// @param locus the source location of the method.
25565///
25566/// @param linkage_name the mangled name of the method.
25567///
25568/// @param vis the visibility of the method.
25569///
25570/// @param bind the binding of the method.
25571method_decl::method_decl(const string& name,
25572 function_type_sptr type,
25573 bool declared_inline,
25574 const location& locus,
25575 const string& linkage_name,
25576 visibility vis,
25577 binding bind)
25578 : type_or_decl_base(type->get_environment(),
25579 METHOD_DECL
25580 | ABSTRACT_DECL_BASE
25581 | FUNCTION_DECL),
25582 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25583 function_decl(name, static_pointer_cast<function_type>
25584 (dynamic_pointer_cast<method_type>(type)),
25585 declared_inline, locus, linkage_name, vis, bind)
25586{
25588 set_context_rel(new mem_fn_context_rel(0));
25589}
25590
25591/// A constructor for instances of method_decl.
25592///
25593/// @param name the name of the method.
25594///
25595/// @param type the type of the method. Must be an instance of
25596/// method_type.
25597///
25598/// @param declared_inline whether the method was
25599/// declared inline or not.
25600///
25601/// @param locus the source location of the method.
25602///
25603/// @param linkage_name the mangled name of the method.
25604///
25605/// @param vis the visibility of the method.
25606///
25607/// @param bind the binding of the method.
25608method_decl::method_decl(const string& name,
25609 type_base_sptr type,
25610 bool declared_inline,
25611 const location& locus,
25612 const string& linkage_name,
25613 visibility vis,
25614 binding bind)
25615 : type_or_decl_base(type->get_environment(),
25616 METHOD_DECL
25617 | ABSTRACT_DECL_BASE
25618 | FUNCTION_DECL),
25619 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25620 function_decl(name, static_pointer_cast<function_type>
25621 (dynamic_pointer_cast<method_type>(type)),
25622 declared_inline, locus, linkage_name, vis, bind)
25623{
25625 set_context_rel(new mem_fn_context_rel(0));
25626}
25627
25628/// Set the linkage name of the method.
25629///
25630/// @param l the new linkage name of the method.
25631void
25633{
25634 string old_lname = get_linkage_name();
25636 // Update the linkage_name -> member function map of the containing
25637 // class declaration.
25638 if (!l.empty())
25639 {
25641 class_or_union_sptr cl = t->get_class_type();
25642 method_decl_sptr m(this, sptr_utils::noop_deleter());
25643 cl->priv_->mem_fns_map_[l] = m;
25644 if (!old_lname.empty() && l != old_lname)
25645 {
25646 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
25647 {
25648 ABG_ASSERT(m.get() == this);
25649 cl->priv_->mem_fns_map_.erase(old_lname);
25650 }
25651 }
25652 }
25653}
25654
25655method_decl::~method_decl()
25656{}
25657
25658const method_type_sptr
25660{
25661 method_type_sptr result;
25663 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
25664 return result;
25665}
25666
25667/// Set the containing class of a method_decl.
25668///
25669/// @param scope the new containing class_decl.
25670void
25671method_decl::set_scope(scope_decl* scope)
25672{
25673 if (!get_context_rel())
25674 set_context_rel(new mem_fn_context_rel(scope));
25675 else
25676 get_context_rel()->set_scope(scope);
25677}
25678
25679/// Equality operator for @ref method_decl_sptr.
25680///
25681/// This is a deep equality operator, as it compares the @ref
25682/// method_decl that is pointed-to by the smart pointer.
25683///
25684/// @param l the left-hand side argument of the equality operator.
25685///
25686/// @param r the righ-hand side argument of the equality operator.
25687///
25688/// @return true iff @p l equals @p r.
25689bool
25690operator==(const method_decl_sptr& l, const method_decl_sptr& r)
25691{
25692 if (l.get() == r.get())
25693 return true;
25694 if (!!l != !!r)
25695 return false;
25696
25697 return *l == *r;
25698}
25699
25700/// Inequality operator for @ref method_decl_sptr.
25701///
25702/// This is a deep equality operator, as it compares the @ref
25703/// method_decl that is pointed-to by the smart pointer.
25704///
25705/// @param l the left-hand side argument of the equality operator.
25706///
25707/// @param r the righ-hand side argument of the equality operator.
25708///
25709/// @return true iff @p l differs from @p r.
25710bool
25711operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
25712{return !operator==(l, r);}
25713
25714/// Test if a function_decl is actually a method_decl.
25715///
25716///@param d the @ref function_decl to consider.
25717///
25718/// @return the method_decl sub-object of @p d if inherits
25719/// a method_decl type.
25722{
25723 return dynamic_cast<method_decl*>
25724 (const_cast<type_or_decl_base*>(d));
25725}
25726
25727/// Test if a function_decl is actually a method_decl.
25728///
25729///@param d the @ref function_decl to consider.
25730///
25731/// @return the method_decl sub-object of @p d if inherits
25732/// a method_decl type.
25735{return is_method_decl(&d);}
25736
25737/// Test if a function_decl is actually a method_decl.
25738///
25739///@param d the @ref function_decl to consider.
25740///
25741/// @return the method_decl sub-object of @p d if inherits
25742/// a method_decl type.
25743method_decl_sptr
25745{return dynamic_pointer_cast<method_decl>(d);}
25746
25747/// A "less than" functor to sort a vector of instances of
25748/// method_decl that are virtual.
25749struct virtual_member_function_less_than
25750{
25751 /// The less than operator. First, it sorts the methods by their
25752 /// vtable index. If they have the same vtable index, it sorts them
25753 /// by the name of their ELF symbol. If they don't have elf
25754 /// symbols, it sorts them by considering their pretty
25755 /// representation.
25756 ///
25757 /// Note that this method expects virtual methods.
25758 ///
25759 /// @param f the first method to consider.
25760 ///
25761 /// @param s the second method to consider.
25762 ///
25763 /// @return true if method @p is less than method @s.
25764 bool
25765 operator()(const method_decl& f,
25766 const method_decl& s)
25767 {
25770
25771 ssize_t f_offset = get_member_function_vtable_offset(f);
25772 ssize_t s_offset = get_member_function_vtable_offset(s);
25773 if (f_offset != s_offset) return f_offset < s_offset;
25774
25775 string fn, sn;
25776 // Try the linkage names (important for destructors).
25777 fn = f.get_linkage_name();
25778 sn = s.get_linkage_name();
25779 if (fn != sn) return fn < sn;
25780
25781 // If the functions have symbols, then compare their symbol-id
25782 // string.
25783 elf_symbol_sptr f_sym = f.get_symbol();
25784 elf_symbol_sptr s_sym = s.get_symbol();
25785 if ((!f_sym) != (!s_sym)) return !f_sym;
25786 if (f_sym && s_sym)
25787 {
25788 fn = f_sym->get_id_string();
25789 sn = s_sym->get_id_string();
25790 if (fn != sn) return fn < sn;
25791 }
25792
25793 // None of the functions have symbols or linkage names that
25794 // distinguish them, so compare their pretty representation.
25797 if (fn != sn) return fn < sn;
25798
25799 /// If it's just the file paths that are different then sort them
25800 /// too.
25801 string fn_filepath, sn_filepath;
25802 unsigned line = 0, column = 0;
25803 location fn_loc = f.get_location(), sn_loc = s.get_location();
25804 if (fn_loc)
25805 fn_loc.expand(fn_filepath, line, column);
25806 if (sn_loc)
25807 sn_loc.expand(sn_filepath, line, column);
25808 return fn_filepath < sn_filepath;
25809 }
25810
25811 /// The less than operator. First, it sorts the methods by their
25812 /// vtable index. If they have the same vtable index, it sorts them
25813 /// by the name of their ELF symbol. If they don't have elf
25814 /// symbols, it sorts them by considering their pretty
25815 /// representation.
25816 ///
25817 /// Note that this method expects to take virtual methods.
25818 ///
25819 /// @param f the first method to consider.
25820 ///
25821 /// @param s the second method to consider.
25822 bool
25823 operator()(const method_decl_sptr f,
25824 const method_decl_sptr s)
25825 {return operator()(*f, *s);}
25826}; // end struct virtual_member_function_less_than
25827
25828/// Sort a vector of instances of virtual member functions.
25829///
25830/// @param mem_fns the vector of member functions to sort.
25831static void
25832sort_virtual_member_functions(class_decl::member_functions& mem_fns)
25833{
25834 virtual_member_function_less_than lt;
25835 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25836}
25837
25838/// Add a member function to the current instance of @ref class_or_union.
25839///
25840/// @param f a method_decl to add to the current class. This function
25841/// should not have been already added to a scope.
25842///
25843/// @param access the access specifier for the member function to add.
25844///
25845/// @param is_virtual if this is true then it means the function @p f
25846/// is a virtual function. That also means that the current instance
25847/// of @ref class_or_union is actually an instance of @ref class_decl.
25848///
25849/// @param vtable_offset the offset of the member function in the
25850/// virtual table. This parameter is taken into account only if @p
25851/// is_virtual is true.
25852///
25853/// @param is_static whether the member function is static.
25854///
25855/// @param is_ctor whether the member function is a constructor.
25856///
25857/// @param is_dtor whether the member function is a destructor.
25858///
25859/// @param is_const whether the member function is const.
25860void
25863 bool is_virtual,
25864 size_t vtable_offset,
25865 bool is_static, bool is_ctor,
25866 bool is_dtor, bool is_const)
25867{
25868 add_member_function(f, a, is_static, is_ctor,
25869 is_dtor, is_const);
25870
25871 if (class_decl* klass = is_class_type(this))
25872 {
25873 if (is_virtual)
25874 {
25875 set_member_function_virtuality(f, is_virtual, vtable_offset);
25876 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
25877 }
25878 }
25879}
25880
25881/// When a virtual member function has seen its virtualness set by
25882/// set_member_function_is_virtual(), this function ensures that the
25883/// member function is added to the specific vectors and maps of
25884/// virtual member function of its class.
25885///
25886/// @param method the method to fixup.
25887void
25888fixup_virtual_member_function(method_decl_sptr method)
25889{
25890 if (!method || !get_member_function_is_virtual(method))
25891 return;
25892
25893 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
25894
25895 class_decl::member_functions::const_iterator m;
25896 for (m = klass->priv_->virtual_mem_fns_.begin();
25897 m != klass->priv_->virtual_mem_fns_.end();
25898 ++m)
25899 if (m->get() == method.get()
25900 || (*m)->get_linkage_name() == method->get_linkage_name())
25901 break;
25902 if (m == klass->priv_->virtual_mem_fns_.end())
25903 klass->priv_->virtual_mem_fns_.push_back(method);
25904
25905 // Build or udpate the map that associates a vtable offset to the
25906 // number of virtual member functions that "point" to it.
25907 ssize_t voffset = get_member_function_vtable_offset(method);
25908 if (voffset == -1)
25909 return;
25910
25911 class_decl::virtual_mem_fn_map_type::iterator i =
25912 klass->priv_->virtual_mem_fns_map_.find(voffset);
25913 if (i == klass->priv_->virtual_mem_fns_map_.end())
25914 {
25915 class_decl::member_functions virtual_mem_fns_at_voffset;
25916 virtual_mem_fns_at_voffset.push_back(method);
25917 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
25918 }
25919 else
25920 {
25921 for (m = i->second.begin() ; m != i->second.end(); ++m)
25922 if (m->get() == method.get()
25923 || (*m)->get_linkage_name() == method->get_linkage_name())
25924 break;
25925 if (m == i->second.end())
25926 i->second.push_back(method);
25927 }
25928}
25929
25930/// Return true iff the class has no entity in its scope.
25931bool
25933{return priv_->bases_.empty() && has_no_member();}
25934
25935/// Test if the current instance of @ref class_decl has virtual member
25936/// functions.
25937///
25938/// @return true iff the current instance of @ref class_decl has
25939/// virtual member functions.
25940bool
25942{return !get_virtual_mem_fns().empty();}
25943
25944/// Test if the current instance of @ref class_decl has at least one
25945/// virtual base.
25946///
25947/// @return true iff the current instance of @ref class_decl has a
25948/// virtual member function.
25949bool
25951{
25952 for (base_specs::const_iterator b = get_base_specifiers().begin();
25953 b != get_base_specifiers().end();
25954 ++b)
25955 if ((*b)->get_is_virtual()
25956 || (*b)->get_base_class()->has_virtual_bases())
25957 return true;
25958
25959 return false;
25960}
25961
25962/// Test if the current instance has a vtable.
25963///
25964/// This is only valid for a C++ program.
25965///
25966/// Basically this function checks if the class has either virtual
25967/// functions, or virtual bases.
25968bool
25970{
25972 || has_virtual_bases())
25973 return true;
25974 return false;
25975}
25976
25977/// Get the highest vtable offset of all the virtual methods of the
25978/// class.
25979///
25980/// @return the highest vtable offset of all the virtual methods of
25981/// the class.
25982ssize_t
25984{
25985 ssize_t offset = -1;
25986 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
25987 get_virtual_mem_fns_map().begin();
25988 e != get_virtual_mem_fns_map().end();
25989 ++e)
25990 if (e->first > offset)
25991 offset = e->first;
25992
25993 return offset;
25994}
25995
25996/// Return the hash value of the current IR node.
25997///
25998/// Note that upon the first invocation, this member functions
25999/// computes the hash value and returns it. Subsequent invocations
26000/// just return the hash value that was previously calculated.
26001///
26002/// @return the hash value of the current IR node.
26003hash_t
26005{
26007 return h;
26008}
26009
26010/// Test if two methods are equal without taking their symbol or
26011/// linkage name into account.
26012///
26013/// @param f the first method.
26014///
26015/// @param s the second method.
26016///
26017/// @return true iff @p f equals @p s without taking their linkage
26018/// name or symbol into account.
26019static bool
26020methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
26021 const method_decl_sptr& s)
26022{
26023 method_decl_sptr first = f, second = s;
26024 elf_symbol_sptr saved_first_elf_symbol =
26025 first->get_symbol();
26026 elf_symbol_sptr saved_second_elf_symbol =
26027 second->get_symbol();
26028 interned_string saved_first_linkage_name =
26029 first->get_linkage_name();
26030 interned_string saved_second_linkage_name =
26031 second->get_linkage_name();
26032
26033 first->set_symbol(elf_symbol_sptr());
26034 first->set_linkage_name("");
26035 second->set_symbol(elf_symbol_sptr());
26036 second->set_linkage_name("");
26037
26038 bool equal = *first == *second;
26039
26040 first->set_symbol(saved_first_elf_symbol);
26041 first->set_linkage_name(saved_first_linkage_name);
26042 second->set_symbol(saved_second_elf_symbol);
26043 second->set_linkage_name(saved_second_linkage_name);
26044
26045 return equal;
26046}
26047
26048/// Test if a given method is equivalent to at least of other method
26049/// that is in a vector of methods.
26050///
26051/// Note that "equivalent" here means being equal without taking the
26052/// linkage name or the symbol of the methods into account.
26053///
26054/// This is a sub-routine of the 'equals' function that compares @ref
26055/// class_decl.
26056///
26057/// @param method the method to compare.
26058///
26059/// @param fns the vector of functions to compare @p method against.
26060///
26061/// @return true iff @p is equivalent to at least one method in @p
26062/// fns.
26063static bool
26064method_matches_at_least_one_in_vector(const method_decl_sptr& method,
26066{
26067 for (class_decl::member_functions::const_iterator i = fns.begin();
26068 i != fns.end();
26069 ++i)
26070 // Note that the comparison must be done in this order: method ==
26071 // *i This is to keep the consistency of the comparison. It's
26072 // important especially when doing type canonicalization. The
26073 // already canonicalize type is the left operand, and the type
26074 // being canonicalized is the right operand. This comes from the
26075 // code in type_base::get_canonical_type_for().
26076 if (methods_equal_modulo_elf_symbol(method, *i))
26077 return true;
26078
26079 return false;
26080}
26081
26082/// Compares two instances of @ref class_decl.
26083///
26084/// If the two intances are different, set a bitfield to give some
26085/// insight about the kind of differences there are.
26086///
26087/// @param l the first artifact of the comparison.
26088///
26089/// @param r the second artifact of the comparison.
26090///
26091/// @param k a pointer to a bitfield that gives information about the
26092/// kind of changes there are between @p l and @p r. This one is set
26093/// iff @p k is non-null and the function returns false.
26094///
26095/// Please note that setting k to a non-null value does have a
26096/// negative performance impact because even if @p l and @p r are not
26097/// equal, the function keeps up the comparison in order to determine
26098/// the different kinds of ways in which they are different.
26099///
26100/// @return true if @p l equals @p r, false otherwise.
26101bool
26103{
26104 {
26105 // First of all, let's see if these two types haven't already been
26106 // compared. If so, and if the result of the comparison has been
26107 // cached, let's just re-use it, rather than comparing them all
26108 // over again.
26109 bool result = false;
26110 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
26111 ABG_RETURN(result);
26112 }
26113
26114 // if one of the classes is declaration-only then we take a fast
26115 // path here.
26117 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
26118 static_cast<const class_or_union&>(r),
26119 k));
26120
26121 bool result = true;
26122 if (!equals(static_cast<const class_or_union&>(l),
26123 static_cast<const class_or_union&>(r),
26124 k))
26125 {
26126 result = false;
26127 if (!k)
26128 ABG_RETURN(result);
26129 }
26130
26132
26134
26135#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
26136
26137 // Compare bases.
26138 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
26139 {
26140 result = false;
26141 if (k)
26143 else
26144 RETURN(result);
26145 }
26146
26147 for (class_decl::base_specs::const_iterator
26148 b0 = l.get_base_specifiers().begin(),
26149 b1 = r.get_base_specifiers().begin();
26150 (b0 != l.get_base_specifiers().end()
26151 && b1 != r.get_base_specifiers().end());
26152 ++b0, ++b1)
26153 if (*b0 != *b1)
26154 {
26155 result = false;
26156 if (k)
26157 {
26158 if (!types_have_similar_structure((*b0)->get_base_class().get(),
26159 (*b1)->get_base_class().get()))
26161 else
26162 *k |= SUBTYPE_CHANGE_KIND;
26163 break;
26164 }
26165 RETURN(result);
26166 }
26167
26168 // Compare virtual member functions
26169
26170 // We look at the map that associates a given vtable offset to a
26171 // vector of virtual member functions that point to that offset.
26172 //
26173 // This is because there are cases where several functions can
26174 // point to the same virtual table offset.
26175 //
26176 // This is usually the case for virtual destructors. Even though
26177 // there can be only one virtual destructor declared in source
26178 // code, there are actually potentially up to three generated
26179 // functions for that destructor. Some of these generated
26180 // functions can be clones of other functions that are among those
26181 // generated ones. In any cases, they all have the same
26182 // properties, including the vtable offset property.
26183
26184 // So, there should be the same number of different vtable
26185 // offsets, the size of two maps must be equals.
26186 if (l.get_virtual_mem_fns_map().size()
26187 != r.get_virtual_mem_fns_map().size())
26188 {
26189 result = false;
26190 if (k)
26192 else
26193 RETURN(result);
26194 }
26195
26196 // Then, each virtual member function of a given vtable offset in
26197 // the first class type, must match an equivalent virtual member
26198 // function of a the same vtable offset in the second class type.
26199 //
26200 // By "match", I mean that the two virtual member function should
26201 // be equal if we don't take into account their symbol name or
26202 // their linkage name. This is because two destructor functions
26203 // clones (for instance) might have different linkage name, but
26204 // are still equivalent if their other properties are the same.
26205 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
26206 l.get_virtual_mem_fns_map().begin();
26207 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
26208 ++first_v_fn_entry)
26209 {
26210 unsigned voffset = first_v_fn_entry->first;
26211 const class_decl::member_functions& first_vfns =
26212 first_v_fn_entry->second;
26213
26214 const class_decl::virtual_mem_fn_map_type::const_iterator
26215 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
26216
26217 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
26218 {
26219 result = false;
26220 if (k)
26222 RETURN(result);
26223 }
26224
26225 const class_decl::member_functions& second_vfns =
26226 second_v_fn_entry->second;
26227
26228 bool matches = false;
26229 for (class_decl::member_functions::const_iterator i =
26230 first_vfns.begin();
26231 i != first_vfns.end();
26232 ++i)
26233 if (method_matches_at_least_one_in_vector(*i, second_vfns))
26234 {
26235 matches = true;
26236 break;
26237 }
26238
26239 if (!matches)
26240 {
26241 result = false;
26242 if (k)
26243 *k |= SUBTYPE_CHANGE_KIND;
26244 else
26245 RETURN(result);
26246 }
26247 }
26248
26249 RETURN(result);
26250#undef RETURN
26251}
26252
26253/// Copy a method of a class into a new class.
26254///
26255/// @param klass the class into which the method is to be copied.
26256///
26257/// @param method the method to copy into @p klass.
26258///
26259/// @return the resulting newly copied method.
26260method_decl_sptr
26261copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
26262{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26263
26264/// Copy a method of a class into a new class.
26265///
26266/// @param klass the class into which the method is to be copied.
26267///
26268/// @param method the method to copy into @p klass.
26269///
26270/// @return the resulting newly copied method.
26271method_decl_sptr
26273{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26274
26275/// Comparison operator for @ref class_decl.
26276///
26277/// @param other the instance of @ref class_decl to compare against.
26278///
26279/// @return true iff the current instance of @ref class_decl equals @p
26280/// other.
26281bool
26283{
26284 const class_decl* op = is_class_type(&other);
26285 if (!op)
26286 {
26287 if (class_or_union* cou = is_class_or_union_type(&other))
26288 return class_or_union::operator==(*cou);
26289 return false;
26290 }
26291
26292 // If this is a decl-only type (and thus with no canonical type),
26293 // use the canonical type of the definition, if any.
26294 const class_decl *l = 0;
26296 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
26297 if (l == 0)
26298 l = this;
26299
26300 ABG_ASSERT(l);
26301
26302 // Likewise for the other type.
26303 const class_decl *r = 0;
26304 if (op->get_is_declaration_only())
26305 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
26306 if (r == 0)
26307 r = op;
26308
26309 ABG_ASSERT(r);
26310
26311 return try_canonical_compare(l, r);
26312}
26313
26314/// Equality operator for class_decl.
26315///
26316/// Re-uses the equality operator that takes a decl_base.
26317///
26318/// @param other the other class_decl to compare against.
26319///
26320/// @return true iff the current instance equals the other one.
26321bool
26323{
26324 const decl_base* o = is_decl(&other);
26325 if (!o)
26326 return false;
26327 return *this == *o;
26328}
26329
26330/// Equality operator for class_decl.
26331///
26332/// Re-uses the equality operator that takes a decl_base.
26333///
26334/// @param other the other class_decl to compare against.
26335///
26336/// @return true iff the current instance equals the other one.
26337bool
26339{
26340 const decl_base& o = other;
26341 return *this == o;
26342}
26343
26344/// Comparison operator for @ref class_decl.
26345///
26346/// @param other the instance of @ref class_decl to compare against.
26347///
26348/// @return true iff the current instance of @ref class_decl equals @p
26349/// other.
26350bool
26352{
26353 const decl_base& o = other;
26354 return *this == o;
26355}
26356
26357/// Turn equality of shared_ptr of class_decl into a deep equality;
26358/// that is, make it compare the pointed to objects too.
26359///
26360/// @param l the shared_ptr of class_decl on left-hand-side of the
26361/// equality.
26362///
26363/// @param r the shared_ptr of class_decl on right-hand-side of the
26364/// equality.
26365///
26366/// @return true if the class_decl pointed to by the shared_ptrs are
26367/// equal, false otherwise.
26368bool
26370{
26371 if (l.get() == r.get())
26372 return true;
26373 if (!!l != !!r)
26374 return false;
26375
26376 return *l == *r;
26377}
26378
26379/// Turn inequality of shared_ptr of class_decl into a deep equality;
26380/// that is, make it compare the pointed to objects too.
26381///
26382/// @param l the shared_ptr of class_decl on left-hand-side of the
26383/// equality.
26384///
26385/// @param r the shared_ptr of class_decl on right-hand-side of the
26386/// equality.
26387///
26388/// @return true if the class_decl pointed to by the shared_ptrs are
26389/// different, false otherwise.
26390bool
26392{return !operator==(l, r);}
26393
26394/// Turn equality of shared_ptr of class_or_union into a deep
26395/// equality; that is, make it compare the pointed to objects too.
26396///
26397/// @param l the left-hand-side operand of the operator
26398///
26399/// @param r the right-hand-side operand of the operator.
26400///
26401/// @return true iff @p l equals @p r.
26402bool
26403operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
26404{
26405 if (l.get() == r.get())
26406 return true;
26407 if (!!l != !!r)
26408 return false;
26409
26410 return *l == *r;
26411}
26412
26413/// Turn inequality of shared_ptr of class_or_union into a deep
26414/// equality; that is, make it compare the pointed to objects too.
26415///
26416/// @param l the left-hand-side operand of the operator
26417///
26418/// @param r the right-hand-side operand of the operator.
26419///
26420/// @return true iff @p l is different from @p r.
26421bool
26422operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
26423{return !operator==(l, r);}
26424
26425/// This implements the ir_traversable_base::traverse pure virtual
26426/// function.
26427///
26428/// @param v the visitor used on the current instance and on its
26429/// members.
26430///
26431/// @return true if the entire IR node tree got traversed, false
26432/// otherwise.
26433bool
26435{
26436 if (v.type_node_has_been_visited(this))
26437 return true;
26438
26439 if (visiting())
26440 return true;
26441
26442 if (v.visit_begin(this))
26443 {
26444 visiting(true);
26445 bool stop = false;
26446
26447 for (base_specs::const_iterator i = get_base_specifiers().begin();
26448 i != get_base_specifiers().end();
26449 ++i)
26450 {
26451 if (!(*i)->traverse(v))
26452 {
26453 stop = true;
26454 break;
26455 }
26456 }
26457
26458 if (!stop)
26459 for (data_members::const_iterator i = get_data_members().begin();
26460 i != get_data_members().end();
26461 ++i)
26462 if (!(*i)->traverse(v))
26463 {
26464 stop = true;
26465 break;
26466 }
26467
26468 if (!stop)
26469 for (member_functions::const_iterator i= get_member_functions().begin();
26470 i != get_member_functions().end();
26471 ++i)
26472 if (!(*i)->traverse(v))
26473 {
26474 stop = true;
26475 break;
26476 }
26477
26478 if (!stop)
26479 for (member_types::const_iterator i = get_member_types().begin();
26480 i != get_member_types().end();
26481 ++i)
26482 if (!(*i)->traverse(v))
26483 {
26484 stop = true;
26485 break;
26486 }
26487
26488 if (!stop)
26489 for (member_function_templates::const_iterator i =
26491 i != get_member_function_templates().end();
26492 ++i)
26493 if (!(*i)->traverse(v))
26494 {
26495 stop = true;
26496 break;
26497 }
26498
26499 if (!stop)
26500 for (member_class_templates::const_iterator i =
26502 i != get_member_class_templates().end();
26503 ++i)
26504 if (!(*i)->traverse(v))
26505 {
26506 stop = true;
26507 break;
26508 }
26509 visiting(false);
26510 }
26511
26512 bool result = v.visit_end(this);
26514 return result;
26515}
26516
26517/// Destructor of the @ref class_decl type.
26519{delete priv_;}
26520
26521context_rel::~context_rel()
26522{}
26523
26524bool
26525member_base::operator==(const member_base& o) const
26526{
26528 && get_is_static() == o.get_is_static());
26529}
26530
26531/// Equality operator for smart pointers to @ref
26532/// class_decl::base_specs.
26533///
26534/// This compares the pointed-to objects.
26535///
26536/// @param l the first instance to consider.
26537///
26538/// @param r the second instance to consider.
26539///
26540/// @return true iff @p l equals @p r.
26541bool
26544{
26545 if (l.get() == r.get())
26546 return true;
26547 if (!!l != !!r)
26548 return false;
26549
26550 return *l == static_cast<const decl_base&>(*r);
26551}
26552
26553/// Inequality operator for smart pointers to @ref
26554/// class_decl::base_specs.
26555///
26556/// This compares the pointed-to objects.
26557///
26558/// @param l the first instance to consider.
26559///
26560/// @param r the second instance to consider.
26561///
26562/// @return true iff @p l is different from @p r.
26563bool
26566{return !operator==(l, r);}
26567
26568/// Test if an ABI artifact is a class base specifier.
26569///
26570/// @param tod the ABI artifact to consider.
26571///
26572/// @return a pointer to the @ref class_decl::base_spec sub-object of
26573/// @p tod iff it's a class base specifier.
26576{
26577 return dynamic_cast<class_decl::base_spec*>
26578 (const_cast<type_or_decl_base*>(tod));
26579}
26580
26581/// Test if an ABI artifact is a class base specifier.
26582///
26583/// @param tod the ABI artifact to consider.
26584///
26585/// @return a pointer to the @ref class_decl::base_spec sub-object of
26586/// @p tod iff it's a class base specifier.
26589{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
26590
26591bool
26592member_function_template::operator==(const member_base& other) const
26593{
26594 try
26595 {
26596 const member_function_template& o =
26597 dynamic_cast<const member_function_template&>(other);
26598
26599 if (!(is_constructor() == o.is_constructor()
26600 && is_const() == o.is_const()
26601 && member_base::operator==(o)))
26602 return false;
26603
26604 if (function_tdecl_sptr ftdecl = as_function_tdecl())
26605 {
26606 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
26607 if (other_ftdecl)
26608 return ftdecl->function_tdecl::operator==(*other_ftdecl);
26609 }
26610 }
26611 catch(...)
26612 {}
26613 return false;
26614}
26615
26616/// Equality operator for smart pointers to @ref
26617/// member_function_template. This is compares the
26618/// pointed-to instances.
26619///
26620/// @param l the first instance to consider.
26621///
26622/// @param r the second instance to consider.
26623///
26624/// @return true iff @p l equals @p r.
26625bool
26626operator==(const member_function_template_sptr& l,
26627 const member_function_template_sptr& r)
26628{
26629 if (l.get() == r.get())
26630 return true;
26631 if (!!l != !!r)
26632 return false;
26633
26634 return *l == *r;
26635}
26636
26637/// Inequality operator for smart pointers to @ref
26638/// member_function_template. This is compares the pointed-to
26639/// instances.
26640///
26641/// @param l the first instance to consider.
26642///
26643/// @param r the second instance to consider.
26644///
26645/// @return true iff @p l equals @p r.
26646bool
26647operator!=(const member_function_template_sptr& l,
26648 const member_function_template_sptr& r)
26649{return !operator==(l, r);}
26650
26651/// This implements the ir_traversable_base::traverse pure virtual
26652/// function.
26653///
26654/// @param v the visitor used on the current instance and on its
26655/// underlying function template.
26656///
26657/// @return true if the entire IR node tree got traversed, false
26658/// otherwise.
26659bool
26661{
26662 if (visiting())
26663 return true;
26664
26665 if (v.visit_begin(this))
26666 {
26667 visiting(true);
26668 if (function_tdecl_sptr f = as_function_tdecl())
26669 f->traverse(v);
26670 visiting(false);
26671 }
26672 return v.visit_end(this);
26673}
26674
26675/// Equality operator of the the @ref member_class_template class.
26676///
26677/// @param other the other @ref member_class_template to compare against.
26678///
26679/// @return true iff the current instance equals @p other.
26680bool
26682{
26683 try
26684 {
26685 const member_class_template& o =
26686 dynamic_cast<const member_class_template&>(other);
26687
26688 if (!member_base::operator==(o))
26689 return false;
26690
26691 return as_class_tdecl()->class_tdecl::operator==(o);
26692 }
26693 catch(...)
26694 {return false;}
26695}
26696
26697/// Equality operator of the the @ref member_class_template class.
26698///
26699/// @param other the other @ref member_class_template to compare against.
26700///
26701/// @return true iff the current instance equals @p other.
26702bool
26704{
26705 if (!decl_base::operator==(other))
26706 return false;
26707 return as_class_tdecl()->class_tdecl::operator==(other);
26708}
26709
26710/// Comparison operator for the @ref member_class_template
26711/// type.
26712///
26713/// @param other the other instance of @ref
26714/// member_class_template to compare against.
26715///
26716/// @return true iff the two instances are equal.
26717bool
26719{
26720 const decl_base* o = dynamic_cast<const decl_base*>(&other);
26721 return *this == *o;
26722}
26723
26724/// Comparison operator for the @ref member_class_template
26725/// type.
26726///
26727/// @param l the first argument of the operator.
26728///
26729/// @param r the second argument of the operator.
26730///
26731/// @return true iff the two instances are equal.
26732bool
26733operator==(const member_class_template_sptr& l,
26734 const member_class_template_sptr& r)
26735{
26736 if (l.get() == r.get())
26737 return true;
26738 if (!!l != !!r)
26739 return false;
26740
26741 return *l == *r;
26742}
26743
26744/// Inequality operator for the @ref member_class_template
26745/// type.
26746///
26747/// @param l the first argument of the operator.
26748///
26749/// @param r the second argument of the operator.
26750///
26751/// @return true iff the two instances are equal.
26752bool
26753operator!=(const member_class_template_sptr& l,
26754 const member_class_template_sptr& r)
26755{return !operator==(l, r);}
26756
26757/// This implements the ir_traversable_base::traverse pure virtual
26758/// function.
26759///
26760/// @param v the visitor used on the current instance and on the class
26761/// pattern of the template.
26762///
26763/// @return true if the entire IR node tree got traversed, false
26764/// otherwise.
26765bool
26767{
26768 if (visiting())
26769 return true;
26770
26771 if (v.visit_begin(this))
26772 {
26773 visiting(true);
26774 if (class_tdecl_sptr t = as_class_tdecl())
26775 t->traverse(v);
26776 visiting(false);
26777 }
26778 return v.visit_end(this);
26779}
26780
26781/// Streaming operator for class_decl::access_specifier.
26782///
26783/// @param o the output stream to serialize the access specifier to.
26784///
26785/// @param a the access specifier to serialize.
26786///
26787/// @return the output stream.
26788std::ostream&
26789operator<<(std::ostream& o, access_specifier a)
26790{
26791 string r;
26792
26793 switch (a)
26794 {
26795 case no_access:
26796 r = "none";
26797 break;
26798 case private_access:
26799 r = "private";
26800 break;
26801 case protected_access:
26802 r = "protected";
26803 break;
26804 case public_access:
26805 r= "public";
26806 break;
26807 };
26808 o << r;
26809 return o;
26810}
26811
26812/// Sets the static-ness property of a class member.
26813///
26814/// @param d the class member to set the static-ness property for.
26815/// Note that this must be a class member otherwise the function
26816/// aborts the current process.
26817///
26818/// @param s this must be true if the member is to be static, false
26819/// otherwise.
26820void
26822{
26824
26826 ABG_ASSERT(c);
26827
26828 c->set_is_static(s);
26829
26830 scope_decl* scope = d.get_scope();
26831
26832 if (class_or_union* cl = is_class_or_union_type(scope))
26833 {
26834 if (var_decl* v = is_var_decl(&d))
26835 {
26836 // First, find v in the set of data members.
26837 var_decl_sptr var;
26838 for (const auto& dm : cl->get_data_members())
26839 if (dm->get_name() == v->get_name())
26840 {
26841 var = dm;
26842 break;
26843 }
26844 if (!var)
26845 return;
26846
26847 if (s)
26848 {
26849 // remove from the non-static data members
26850 for (class_decl::data_members::iterator i =
26851 cl->priv_->non_static_data_members_.begin();
26852 i != cl->priv_->non_static_data_members_.end();
26853 ++i)
26854 {
26855 if ((*i)->get_name() == v->get_name())
26856 {
26857 cl->priv_->non_static_data_members_.erase(i);
26858 break;
26859 }
26860 }
26861
26862 // If it's not in the static data members, then add it
26863 // there.
26864 bool already_in_static_dms = false;
26865 for (const auto& s_dm : cl->priv_->static_data_members_)
26866 if (s_dm->get_name() == v->get_name())
26867 {
26868 already_in_static_dms = true;
26869 break;
26870 }
26871 if (!already_in_static_dms)
26872 cl->priv_->static_data_members_.push_back(var);
26873 }
26874 else // is non-static
26875 {
26876 // Remove from the static data members.
26877 for (class_or_union::data_members::iterator i =
26878 cl->priv_->static_data_members_.begin();
26879 i != cl->priv_->static_data_members_.end();
26880 ++i)
26881 if ((*i)->get_name() == v->get_name())
26882 {
26883 cl->priv_->static_data_members_.erase(i);
26884 break;
26885 }
26886
26887 // If it's not already in the non-static data members
26888 // then add it there.
26889 bool is_already_in_non_static_data_members = false;
26890 for (const auto& ns_dm : cl->priv_->non_static_data_members_)
26891 if (ns_dm->get_name() == v->get_name())
26892 {
26893 is_already_in_non_static_data_members = true;
26894 break;
26895 }
26896 if (!is_already_in_non_static_data_members)
26897 cl->priv_->non_static_data_members_.push_back(var);
26898 }
26899 }
26900 }
26901}
26902
26903/// Sets the static-ness property of a class member.
26904///
26905/// @param d the class member to set the static-ness property for.
26906/// Note that this must be a class member otherwise the function
26907/// aborts the current process.
26908///
26909/// @param s this must be true if the member is to be static, false
26910/// otherwise.
26911void
26912set_member_is_static(const decl_base_sptr& d, bool s)
26913{set_member_is_static(*d, s);}
26914
26915// </class_decl>
26916
26917// <union_decl>
26918
26919/// Constructor for the @ref union_decl type.
26920///
26921/// @param env the @ref environment we are operating from.
26922///
26923/// @param name the name of the union type.
26924///
26925/// @param size_in_bits the size of the union, in bits.
26926///
26927/// @param locus the location of the type.
26928///
26929/// @param vis the visibility of instances of @ref union_decl.
26930///
26931/// @param mbr_types the member types of the union.
26932///
26933/// @param data_mbrs the data members of the union.
26934///
26935/// @param member_fns the member functions of the union.
26936union_decl::union_decl(const environment& env, const string& name,
26937 size_t size_in_bits, const location& locus,
26938 visibility vis, member_types& mbr_types,
26939 data_members& data_mbrs, member_functions& member_fns)
26940 : type_or_decl_base(env,
26941 UNION_TYPE
26942 | ABSTRACT_TYPE_BASE
26943 | ABSTRACT_DECL_BASE),
26944 decl_base(env, name, locus, name, vis),
26945 type_base(env, size_in_bits, 0),
26946 class_or_union(env, name, size_in_bits, 0,
26947 locus, vis, mbr_types, data_mbrs, member_fns)
26948{
26950}
26951
26952/// Constructor for the @ref union_decl type.
26953///
26954/// @param env the @ref environment we are operating from.
26955///
26956/// @param name the name of the union type.
26957///
26958/// @param size_in_bits the size of the union, in bits.
26959///
26960/// @param locus the location of the type.
26961///
26962/// @param vis the visibility of instances of @ref union_decl.
26963///
26964/// @param mbr_types the member types of the union.
26965///
26966/// @param data_mbrs the data members of the union.
26967///
26968/// @param member_fns the member functions of the union.
26969///
26970/// @param is_anonymous whether the newly created instance is
26971/// anonymous.
26972union_decl::union_decl(const environment& env, const string& name,
26973 size_t size_in_bits, const location& locus,
26974 visibility vis, member_types& mbr_types,
26975 data_members& data_mbrs, member_functions& member_fns,
26976 bool is_anonymous)
26977 : type_or_decl_base(env,
26978 UNION_TYPE
26979 | ABSTRACT_TYPE_BASE
26980 | ABSTRACT_DECL_BASE),
26981 decl_base(env, name, locus,
26982 // If the class is anonymous then by default it won't
26983 // have a linkage name. Also, the anonymous class does
26984 // have an internal-only unique name that is generally
26985 // not taken into account when comparing classes; such a
26986 // unique internal-only name, when used as a linkage
26987 // name might introduce spurious comparison false
26988 // negatives.
26989 /*linkage_name=*/is_anonymous ? string() : name,
26990 vis),
26991 type_base(env, size_in_bits, 0),
26992 class_or_union(env, name, size_in_bits, 0,
26993 locus, vis, mbr_types, data_mbrs, member_fns)
26994{
26996 set_is_anonymous(is_anonymous);
26997}
26998
26999/// Constructor for the @ref union_decl type.
27000///
27001/// @param env the @ref environment we are operating from.
27002///
27003/// @param name the name of the union type.
27004///
27005/// @param size_in_bits the size of the union, in bits.
27006///
27007/// @param locus the location of the type.
27008///
27009/// @param vis the visibility of instances of @ref union_decl.
27010union_decl::union_decl(const environment& env, const string& name,
27011 size_t size_in_bits, const location& locus,
27012 visibility vis)
27013 : type_or_decl_base(env,
27014 UNION_TYPE
27015 | ABSTRACT_TYPE_BASE
27016 | ABSTRACT_DECL_BASE
27017 | ABSTRACT_SCOPE_TYPE_DECL
27018 | ABSTRACT_SCOPE_DECL),
27019 decl_base(env, name, locus, name, vis),
27020 type_base(env, size_in_bits, 0),
27021 class_or_union(env, name, size_in_bits,
27022 0, locus, vis)
27023{
27025}
27026
27027/// Constructor for the @ref union_decl type.
27028///
27029/// @param env the @ref environment we are operating from.
27030///
27031/// @param name the name of the union type.
27032///
27033/// @param size_in_bits the size of the union, in bits.
27034///
27035/// @param locus the location of the type.
27036///
27037/// @param vis the visibility of instances of @ref union_decl.
27038///
27039/// @param is_anonymous whether the newly created instance is
27040/// anonymous.
27041union_decl::union_decl(const environment& env, const string& name,
27042 size_t size_in_bits, const location& locus,
27043 visibility vis, bool is_anonymous)
27044 : type_or_decl_base(env,
27045 UNION_TYPE
27046 | ABSTRACT_TYPE_BASE
27047 | ABSTRACT_DECL_BASE
27048 | ABSTRACT_SCOPE_TYPE_DECL
27049 | ABSTRACT_SCOPE_DECL),
27050 decl_base(env, name, locus,
27051 // If the class is anonymous then by default it won't
27052 // have a linkage name. Also, the anonymous class does
27053 // have an internal-only unique name that is generally
27054 // not taken into account when comparing classes; such a
27055 // unique internal-only name, when used as a linkage
27056 // name might introduce spurious comparison false
27057 // negatives.
27058 /*linkage_name=*/is_anonymous ? string() : name,
27059 vis),
27060 type_base(env, size_in_bits, 0),
27061 class_or_union(env, name, size_in_bits,
27062 0, locus, vis)
27063{
27065 set_is_anonymous(is_anonymous);
27066}
27067
27068/// Constructor for the @ref union_decl type.
27069///
27070/// @param env the @ref environment we are operating from.
27071///
27072/// @param name the name of the union type.
27073///
27074/// @param is_declaration_only a boolean saying whether the instance
27075/// represents a declaration only, or not.
27076union_decl::union_decl(const environment& env,
27077 const string& name,
27078 bool is_declaration_only)
27079 : type_or_decl_base(env,
27080 UNION_TYPE
27081 | ABSTRACT_TYPE_BASE
27082 | ABSTRACT_DECL_BASE
27083 | ABSTRACT_SCOPE_TYPE_DECL
27084 | ABSTRACT_SCOPE_DECL),
27085 decl_base(env, name, location(), name),
27086 type_base(env, 0, 0),
27087 class_or_union(env, name, is_declaration_only)
27088{
27090}
27091
27092/// Return the hash value of the current IR node.
27093///
27094/// Note that upon the first invocation, this member functions
27095/// computes the hash value and returns it. Subsequent invocations
27096/// just return the hash value that was previously calculated.
27097///
27098/// @return the hash value of the current IR node.
27099hash_t
27101{
27103 return h;
27104}
27105
27106/// Getter of the pretty representation of the current instance of
27107/// @ref union_decl.
27108///
27109/// @param internal set to true if the call is intended to get a
27110/// representation of the decl (or type) for the purpose of canonical
27111/// type comparison. This is mainly used in the function
27112/// type_base::get_canonical_type_for().
27113///
27114/// In other words if the argument for this parameter is true then the
27115/// call is meant for internal use (for technical use inside the
27116/// library itself), false otherwise. If you don't know what this is
27117/// for, then set it to false.
27118///
27119/// @param qualified_name if true, names emitted in the pretty
27120/// representation are fully qualified.
27121///
27122/// @return the pretty representaion for a union_decl.
27123string
27125 bool qualified_name) const
27126{
27127 string repr;
27128 if (get_is_anonymous())
27129 {
27130 if (internal && !get_name().empty())
27131 repr = string("union ") +
27132 get_type_name(this, qualified_name, /*internal=*/true);
27133 else
27135 /*one_line=*/true,
27136 internal);
27137 }
27138 else
27139 {
27140 repr = "union ";
27141 if (qualified_name)
27142 repr += get_qualified_name(internal);
27143 else
27144 repr += get_name();
27145 }
27146
27147 return repr;
27148}
27149
27150/// Comparison operator for @ref union_decl.
27151///
27152/// @param other the instance of @ref union_decl to compare against.
27153///
27154/// @return true iff the current instance of @ref union_decl equals @p
27155/// other.
27156bool
27158{
27159 const union_decl* op = dynamic_cast<const union_decl*>(&other);
27160 if (!op)
27161 return false;
27162 return try_canonical_compare(this, op);
27163}
27164
27165/// Equality operator for union_decl.
27166///
27167/// Re-uses the equality operator that takes a decl_base.
27168///
27169/// @param other the other union_decl to compare against.
27170///
27171/// @return true iff the current instance equals the other one.
27172bool
27174{
27175 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27176 if (!o)
27177 return false;
27178 return *this == *o;
27179}
27180
27181/// Equality operator for union_decl.
27182///
27183/// Re-uses the equality operator that takes a decl_base.
27184///
27185/// @param other the other union_decl to compare against.
27186///
27187/// @return true iff the current instance equals the other one.
27188bool
27190{
27191 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27192 return *this == *o;
27193}
27194
27195/// Comparison operator for @ref union_decl.
27196///
27197/// @param other the instance of @ref union_decl to compare against.
27198///
27199/// @return true iff the current instance of @ref union_decl equals @p
27200/// other.
27201bool
27203{
27204 const decl_base& o = other;
27205 return *this == o;
27206}
27207
27208/// This implements the ir_traversable_base::traverse pure virtual
27209/// function.
27210///
27211/// @param v the visitor used on the current instance and on its
27212/// members.
27213///
27214/// @return true if the entire IR node tree got traversed, false
27215/// otherwise.
27216bool
27218{
27219 if (v.type_node_has_been_visited(this))
27220 return true;
27221
27222 if (visiting())
27223 return true;
27224
27225 if (v.visit_begin(this))
27226 {
27227 visiting(true);
27228 bool stop = false;
27229
27230 if (!stop)
27231 for (data_members::const_iterator i = get_data_members().begin();
27232 i != get_data_members().end();
27233 ++i)
27234 if (!(*i)->traverse(v))
27235 {
27236 stop = true;
27237 break;
27238 }
27239
27240 if (!stop)
27241 for (member_functions::const_iterator i= get_member_functions().begin();
27242 i != get_member_functions().end();
27243 ++i)
27244 if (!(*i)->traverse(v))
27245 {
27246 stop = true;
27247 break;
27248 }
27249
27250 if (!stop)
27251 for (member_types::const_iterator i = get_member_types().begin();
27252 i != get_member_types().end();
27253 ++i)
27254 if (!(*i)->traverse(v))
27255 {
27256 stop = true;
27257 break;
27258 }
27259
27260 if (!stop)
27261 for (member_function_templates::const_iterator i =
27263 i != get_member_function_templates().end();
27264 ++i)
27265 if (!(*i)->traverse(v))
27266 {
27267 stop = true;
27268 break;
27269 }
27270
27271 if (!stop)
27272 for (member_class_templates::const_iterator i =
27274 i != get_member_class_templates().end();
27275 ++i)
27276 if (!(*i)->traverse(v))
27277 {
27278 stop = true;
27279 break;
27280 }
27281 visiting(false);
27282 }
27283
27284 bool result = v.visit_end(this);
27286 return result;
27287}
27288
27289/// Destructor of the @ref union_decl type.
27291{}
27292
27293/// Compares two instances of @ref union_decl.
27294///
27295/// If the two intances are different, set a bitfield to give some
27296/// insight about the kind of differences there are.
27297///
27298/// @param l the first artifact of the comparison.
27299///
27300/// @param r the second artifact of the comparison.
27301///
27302/// @param k a pointer to a bitfield that gives information about the
27303/// kind of changes there are between @p l and @p r. This one is set
27304/// iff @p k is non-null and the function returns false.
27305///
27306/// Please note that setting k to a non-null value does have a
27307/// negative performance impact because even if @p l and @p r are not
27308/// equal, the function keeps up the comparison in order to determine
27309/// the different kinds of ways in which they are different.
27310///
27311/// @return true if @p l equals @p r, false otherwise.
27312bool
27314{
27315
27317
27318 {
27319 // First of all, let's see if these two types haven't already been
27320 // compared. If so, and if the result of the comparison has been
27321 // cached, let's just re-use it, rather than comparing them all
27322 // over again.
27323 bool result = false;
27324 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
27325 ABG_RETURN(result);
27326 }
27327
27328 bool result = equals(static_cast<const class_or_union&>(l),
27329 static_cast<const class_or_union&>(r),
27330 k);
27331
27333}
27334
27335/// Copy a method of a @ref union_decl into a new @ref
27336/// union_decl.
27337///
27338/// @param t the @ref union_decl into which the method is to be copied.
27339///
27340/// @param method the method to copy into @p t.
27341///
27342/// @return the resulting newly copied method.
27343method_decl_sptr
27344copy_member_function(const union_decl_sptr& union_type,
27345 const method_decl_sptr& f)
27346{return copy_member_function(union_type, f.get());}
27347
27348/// Copy a method of a @ref union_decl into a new @ref
27349/// union_decl.
27350///
27351/// @param t the @ref union_decl into which the method is to be copied.
27352///
27353/// @param method the method to copy into @p t.
27354///
27355/// @return the resulting newly copied method.
27356method_decl_sptr
27357copy_member_function(const union_decl_sptr& union_type,
27358 const method_decl* f)
27359{
27360 const class_or_union_sptr t = union_type;
27361 return copy_member_function(t, f);
27362}
27363
27364/// Turn equality of shared_ptr of union_decl into a deep equality;
27365/// that is, make it compare the pointed to objects too.
27366///
27367/// @param l the left-hand-side operand of the operator
27368///
27369/// @param r the right-hand-side operand of the operator.
27370///
27371/// @return true iff @p l equals @p r.
27372bool
27373operator==(const union_decl_sptr& l, const union_decl_sptr& r)
27374{
27375 if (l.get() == r.get())
27376 return true;
27377 if (!!l != !!r)
27378 return false;
27379
27380 return *l == *r;
27381}
27382
27383/// Turn inequality of shared_ptr of union_decl into a deep equality;
27384/// that is, make it compare the pointed to objects too.
27385///
27386/// @param l the left-hand-side operand of the operator
27387///
27388/// @param r the right-hand-side operand of the operator.
27389///
27390/// @return true iff @p l is different from @p r.
27391bool
27392operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
27393{return !operator==(l, r);}
27394// </union_decl>
27395
27396// <template_decl stuff>
27397
27398/// Data type of the private data of the @template_decl type.
27399class template_decl::priv
27400{
27401 friend class template_decl;
27402
27403 std::list<template_parameter_sptr> parms_;
27404public:
27405
27406 priv()
27407 {}
27408}; // end class template_decl::priv
27409
27410/// Add a new template parameter to the current instance of @ref
27411/// template_decl.
27412///
27413/// @param p the new template parameter to add.
27414void
27416{priv_->parms_.push_back(p);}
27417
27418/// Get the list of template parameters of the current instance of
27419/// @ref template_decl.
27420///
27421/// @return the list of template parameters.
27422const std::list<template_parameter_sptr>&
27424{return priv_->parms_;}
27425
27426/// Constructor.
27427///
27428/// @param env the environment we are operating from.
27429///
27430/// @param name the name of the template decl.
27431///
27432/// @param locus the source location where the template declaration is
27433/// defined.
27434///
27435/// @param vis the visibility of the template declaration.
27436template_decl::template_decl(const environment& env,
27437 const string& name,
27438 const location& locus,
27439 visibility vis)
27440 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
27441 decl_base(env, name, locus, /*mangled_name=*/"", vis),
27442 priv_(new priv)
27443{
27445}
27446
27447/// Destructor.
27449{}
27450
27451/// Equality operator.
27452///
27453/// @param o the other instance to compare against.
27454///
27455/// @return true iff @p equals the current instance.
27456bool
27458{
27459 const template_decl* other = dynamic_cast<const template_decl*>(&o);
27460 if (!other)
27461 return false;
27462 return *this == *other;
27463}
27464
27465/// Equality operator.
27466///
27467/// @param o the other instance to compare against.
27468///
27469/// @return true iff @p equals the current instance.
27470bool
27472{
27473 try
27474 {
27475 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
27476 for (t0 = get_template_parameters().begin(),
27477 t1 = o.get_template_parameters().begin();
27478 (t0 != get_template_parameters().end()
27479 && t1 != o.get_template_parameters().end());
27480 ++t0, ++t1)
27481 {
27482 if (**t0 != **t1)
27483 return false;
27484 }
27485
27486 if (t0 != get_template_parameters().end()
27487 || t1 != o.get_template_parameters().end())
27488 return false;
27489
27490 return true;
27491 }
27492 catch(...)
27493 {return false;}
27494}
27495
27496// </template_decl stuff>
27497
27498//<template_parameter>
27499
27500/// The type of the private data of the @ref template_parameter type.
27501class template_parameter::priv
27502{
27503 friend class template_parameter;
27504
27505 unsigned index_;
27506 template_decl_wptr template_decl_;
27507 mutable bool hashing_started_;
27508 mutable bool comparison_started_;
27509
27510 priv();
27511
27512public:
27513
27514 priv(unsigned index, template_decl_sptr enclosing_template_decl)
27515 : index_(index),
27516 template_decl_(enclosing_template_decl),
27517 hashing_started_(),
27518 comparison_started_()
27519 {}
27520}; // end class template_parameter::priv
27521
27522template_parameter::template_parameter(unsigned index,
27523 template_decl_sptr enclosing_template)
27524 : priv_(new priv(index, enclosing_template))
27525 {}
27526
27527unsigned
27528template_parameter::get_index() const
27529{return priv_->index_;}
27530
27532template_parameter::get_enclosing_template_decl() const
27533{return priv_->template_decl_.lock();}
27534
27535
27536bool
27537template_parameter::operator==(const template_parameter& o) const
27538{
27539 if (get_index() != o.get_index())
27540 return false;
27541
27542 if (priv_->comparison_started_)
27543 return true;
27544
27545 bool result = false;
27546
27547 // Avoid inifite loops due to the fact that comparison the enclosing
27548 // template decl might lead to comparing this very same template
27549 // parameter with another one ...
27550 priv_->comparison_started_ = true;
27551
27552 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
27553 ;
27554 else if (get_enclosing_template_decl()
27555 && (*get_enclosing_template_decl()
27556 != *o.get_enclosing_template_decl()))
27557 ;
27558 else
27559 result = true;
27560
27561 priv_->comparison_started_ = false;
27562
27563 return result;
27564}
27565
27566/// Inequality operator.
27567///
27568/// @param other the other instance to compare against.
27569///
27570/// @return true iff the other instance is different from the current
27571/// one.
27572bool
27574{return !operator==(other);}
27575
27576/// Destructor.
27578{}
27579
27580/// The type of the private data of the @ref type_tparameter type.
27581class type_tparameter::priv
27582{
27583 friend class type_tparameter;
27584}; // end class type_tparameter::priv
27585
27586/// Constructor of the @ref type_tparameter type.
27587///
27588/// @param index the index the type template parameter.
27589///
27590/// @param enclosing_tdecl the enclosing template declaration.
27591///
27592/// @param name the name of the template parameter.
27593///
27594/// @param locus the location of the declaration of this type template
27595/// parameter.
27596type_tparameter::type_tparameter(unsigned index,
27597 template_decl_sptr enclosing_tdecl,
27598 const string& name,
27599 const location& locus)
27600 : type_or_decl_base(enclosing_tdecl->get_environment(),
27601 ABSTRACT_DECL_BASE
27602 | ABSTRACT_TYPE_BASE
27603 | BASIC_TYPE),
27604 decl_base(enclosing_tdecl->get_environment(), name, locus),
27605 type_base(enclosing_tdecl->get_environment(), 0, 0),
27606 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
27607 template_parameter(index, enclosing_tdecl),
27608 priv_(new priv)
27609{
27611}
27612
27613/// Equality operator.
27614///
27615/// @param other the other template type parameter to compare against.
27616///
27617/// @return true iff @p other equals the current instance.
27618bool
27620{
27621 if (!type_decl::operator==(other))
27622 return false;
27623
27624 try
27625 {
27626 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27628 }
27629 catch (...)
27630 {return false;}
27631}
27632
27633/// Equality operator.
27634///
27635/// @param other the other template type parameter to compare against.
27636///
27637/// @return true iff @p other equals the current instance.
27638bool
27640{
27641 if (!type_decl::operator==(other))
27642 return false;
27643
27644 try
27645 {
27646 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27648 }
27649 catch (...)
27650 {return false;}
27651}
27652
27653/// Equality operator.
27654///
27655/// @param other the other template type parameter to compare against.
27656///
27657/// @return true iff @p other equals the current instance.
27658bool
27660{
27661 if (!decl_base::operator==(other))
27662 return false;
27663
27664 try
27665 {
27666 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27668 }
27669 catch (...)
27670 {return false;}
27671}
27672
27673/// Equality operator.
27674///
27675/// @param other the other template type parameter to compare against.
27676///
27677/// @return true iff @p other equals the current instance.
27678bool
27680{
27681 try
27682 {
27683 const type_base& o = dynamic_cast<const type_base&>(other);
27684 return *this == o;
27685 }
27686 catch(...)
27687 {return false;}
27688}
27689
27690/// Equality operator.
27691///
27692/// @param other the other template type parameter to compare against.
27693///
27694/// @return true iff @p other equals the current instance.
27695bool
27697{return *this == static_cast<const type_base&>(other);}
27698
27699type_tparameter::~type_tparameter()
27700{}
27701
27702/// The type of the private data of the @ref non_type_tparameter type.
27703class non_type_tparameter::priv
27704{
27705 friend class non_type_tparameter;
27706
27707 type_base_wptr type_;
27708
27709 priv();
27710
27711public:
27712
27713 priv(type_base_sptr type)
27714 : type_(type)
27715 {}
27716}; // end class non_type_tparameter::priv
27717
27718/// The constructor for the @ref non_type_tparameter type.
27719///
27720/// @param index the index of the template parameter.
27721///
27722/// @param enclosing_tdecl the enclosing template declaration that
27723/// holds this parameter parameter.
27724///
27725/// @param name the name of the template parameter.
27726///
27727/// @param type the type of the template parameter.
27728///
27729/// @param locus the location of the declaration of this template
27730/// parameter.
27731non_type_tparameter::non_type_tparameter(unsigned index,
27732 template_decl_sptr enclosing_tdecl,
27733 const string& name,
27734 type_base_sptr type,
27735 const location& locus)
27736 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
27737 decl_base(type->get_environment(), name, locus, ""),
27738 template_parameter(index, enclosing_tdecl),
27739 priv_(new priv(type))
27740{
27742}
27743
27744/// Getter for the type of the template parameter.
27745///
27746/// @return the type of the template parameter.
27747const type_base_sptr
27749{return priv_->type_.lock();}
27750
27751
27752bool
27754{
27755 if (!decl_base::operator==(other))
27756 return false;
27757
27758 try
27759 {
27760 const non_type_tparameter& o =
27761 dynamic_cast<const non_type_tparameter&>(other);
27762 return (template_parameter::operator==(o)
27763 && get_type() == o.get_type());
27764 }
27765 catch(...)
27766 {return false;}
27767}
27768
27769bool
27771{
27772 try
27773 {
27774 const decl_base& o = dynamic_cast<const decl_base&>(other);
27775 return *this == o;
27776 }
27777 catch(...)
27778 {return false;}
27779}
27780
27781non_type_tparameter::~non_type_tparameter()
27782{}
27783
27784// <template_tparameter stuff>
27785
27786/// Type of the private data of the @ref template_tparameter type.
27787class template_tparameter::priv
27788{
27789}; //end class template_tparameter::priv
27790
27791/// Constructor for the @ref template_tparameter.
27792///
27793/// @param index the index of the template parameter.
27794///
27795/// @param enclosing_tdecl the enclosing template declaration.
27796///
27797/// @param name the name of the template parameter.
27798///
27799/// @param locus the location of the declaration of the template
27800/// parameter.
27801template_tparameter::template_tparameter(unsigned index,
27802 template_decl_sptr enclosing_tdecl,
27803 const string& name,
27804 const location& locus)
27805 : type_or_decl_base(enclosing_tdecl->get_environment(),
27806 ABSTRACT_DECL_BASE
27807 | ABSTRACT_TYPE_BASE
27808 | BASIC_TYPE),
27809 decl_base(enclosing_tdecl->get_environment(), name, locus),
27810 type_base(enclosing_tdecl->get_environment(), 0, 0),
27811 type_decl(enclosing_tdecl->get_environment(), name,
27812 0, 0, locus, name, VISIBILITY_DEFAULT),
27813 type_tparameter(index, enclosing_tdecl, name, locus),
27814 template_decl(enclosing_tdecl->get_environment(), name, locus),
27815 priv_(new priv)
27816{
27818}
27819
27820/// Equality operator.
27821///
27822/// @param other the other template parameter to compare against.
27823///
27824/// @return true iff @p other equals the current instance.
27825bool
27827{
27828 try
27829 {
27830 const template_tparameter& o =
27831 dynamic_cast<const template_tparameter&>(other);
27832 return (type_tparameter::operator==(o)
27834 }
27835 catch(...)
27836 {return false;}
27837}
27838
27839/// Equality operator.
27840///
27841/// @param other the other template parameter to compare against.
27842///
27843/// @return true iff @p other equals the current instance.
27844bool
27846{
27847 try
27848 {
27849 const template_tparameter& o =
27850 dynamic_cast<const template_tparameter&>(other);
27851 return (type_tparameter::operator==(o)
27853 }
27854 catch(...)
27855 {return false;}
27856}
27857
27858bool
27860{
27861 try
27862 {
27863 const template_tparameter& other =
27864 dynamic_cast<const template_tparameter&>(o);
27865 return *this == static_cast<const type_base&>(other);
27866 }
27867 catch(...)
27868 {return false;}
27869}
27870
27871bool
27873{
27874 try
27875 {
27876 const template_tparameter& other =
27877 dynamic_cast<const template_tparameter&>(o);
27878 return type_base::operator==(other);
27879 }
27880 catch(...)
27881 {return false;}
27882}
27883
27884template_tparameter::~template_tparameter()
27885{}
27886
27887// </template_tparameter stuff>
27888
27889// <type_composition stuff>
27890
27891/// The type of the private data of the @ref type_composition type.
27892class type_composition::priv
27893{
27894 friend class type_composition;
27895
27896 type_base_wptr type_;
27897
27898 // Forbid this.
27899 priv();
27900
27901public:
27902
27903 priv(type_base_wptr type)
27904 : type_(type)
27905 {}
27906}; //end class type_composition::priv
27907
27908/// Constructor for the @ref type_composition type.
27909///
27910/// @param index the index of the template type composition.
27911///
27912/// @param tdecl the enclosing template parameter that owns the
27913/// composition.
27914///
27915/// @param t the resulting type.
27916type_composition::type_composition(unsigned index,
27917 template_decl_sptr tdecl,
27918 type_base_sptr t)
27919 : type_or_decl_base(tdecl->get_environment(),
27920 ABSTRACT_DECL_BASE),
27921 decl_base(tdecl->get_environment(), "", location()),
27922 template_parameter(index, tdecl),
27923 priv_(new priv(t))
27924{
27926}
27927
27928/// Getter for the resulting composed type.
27929///
27930/// @return the composed type.
27931const type_base_sptr
27933{return priv_->type_.lock();}
27934
27935/// Setter for the resulting composed type.
27936///
27937/// @param t the composed type.
27938void
27940{priv_->type_ = t;}
27941
27942type_composition::~type_composition()
27943{}
27944
27945// </type_composition stuff>
27946
27947//</template_parameter stuff>
27948
27949// <function_template>
27950
27951class function_tdecl::priv
27952{
27953 friend class function_tdecl;
27954
27955 function_decl_sptr pattern_;
27956 binding binding_;
27957
27958 priv();
27959
27960public:
27961
27962 priv(function_decl_sptr pattern, binding bind)
27963 : pattern_(pattern), binding_(bind)
27964 {}
27965
27966 priv(binding bind)
27967 : binding_(bind)
27968 {}
27969}; // end class function_tdecl::priv
27970
27971/// Constructor for a function template declaration.
27972///
27973/// @param env the environment we are operating from.
27974///
27975/// @param locus the location of the declaration.
27976///
27977/// @param vis the visibility of the declaration. This is the
27978/// visibility the functions instantiated from this template are going
27979/// to have.
27980///
27981/// @param bind the binding of the declaration. This is the binding
27982/// the functions instantiated from this template are going to have.
27983function_tdecl::function_tdecl(const environment& env,
27984 const location& locus,
27985 visibility vis,
27986 binding bind)
27987 : type_or_decl_base(env,
27988 ABSTRACT_DECL_BASE
27989 | TEMPLATE_DECL
27990 | ABSTRACT_SCOPE_DECL),
27991 decl_base(env, "", locus, "", vis),
27992 template_decl(env, "", locus, vis),
27993 scope_decl(env, "", locus),
27994 priv_(new priv(bind))
27995{
27997}
27998
27999/// Constructor for a function template declaration.
28000///
28001/// @param pattern the pattern of the template.
28002///
28003/// @param locus the location of the declaration.
28004///
28005/// @param vis the visibility of the declaration. This is the
28006/// visibility the functions instantiated from this template are going
28007/// to have.
28008///
28009/// @param bind the binding of the declaration. This is the binding
28010/// the functions instantiated from this template are going to have.
28011function_tdecl::function_tdecl(function_decl_sptr pattern,
28012 const location& locus,
28013 visibility vis,
28014 binding bind)
28015 : type_or_decl_base(pattern->get_environment(),
28016 ABSTRACT_DECL_BASE
28017 | TEMPLATE_DECL
28018 | ABSTRACT_SCOPE_DECL),
28019 decl_base(pattern->get_environment(), pattern->get_name(), locus,
28020 pattern->get_name(), vis),
28021 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
28022 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
28023 priv_(new priv(pattern, bind))
28024{
28026}
28027
28028/// Set a new pattern to the function template.
28029///
28030/// @param p the new pattern.
28031void
28033{
28034 priv_->pattern_ = p;
28035 add_decl_to_scope(p, this);
28036 set_name(p->get_name());
28037}
28038
28039/// Get the pattern of the function template.
28040///
28041/// @return the pattern.
28044{return priv_->pattern_;}
28045
28046/// Get the binding of the function template.
28047///
28048/// @return the binding
28051{return priv_->binding_;}
28052
28053/// Comparison operator for the @ref function_tdecl type.
28054///
28055/// @param other the other instance of @ref function_tdecl to compare against.
28056///
28057/// @return true iff the two instance are equal.
28058bool
28060{
28061 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
28062 if (o)
28063 return *this == *o;
28064 return false;
28065}
28066
28067/// Comparison operator for the @ref function_tdecl type.
28068///
28069/// @param other the other instance of @ref function_tdecl to compare against.
28070///
28071/// @return true iff the two instance are equal.
28072bool
28074{
28075 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
28076 if (o)
28077 return *this == *o;
28078 return false;
28079}
28080
28081/// Comparison operator for the @ref function_tdecl type.
28082///
28083/// @param o the other instance of @ref function_tdecl to compare against.
28084///
28085/// @return true iff the two instance are equal.
28086bool
28088{
28089 if (!(get_binding() == o.get_binding()
28090 && template_decl::operator==(o)
28091 && scope_decl::operator==(o)
28092 && !!get_pattern() == !!o.get_pattern()))
28093 return false;
28094
28095 if (get_pattern())
28096 return (*get_pattern() == *o.get_pattern());
28097
28098 return true;
28099}
28100
28101/// This implements the ir_traversable_base::traverse pure virtual
28102/// function.
28103///
28104/// @param v the visitor used on the current instance and on the
28105/// function pattern of the template.
28106///
28107/// @return true if the entire IR node tree got traversed, false
28108/// otherwise.
28109bool
28111{
28112 if (visiting())
28113 return true;
28114
28115 if (!v.visit_begin(this))
28116 {
28117 visiting(true);
28118 if (get_pattern())
28119 get_pattern()->traverse(v);
28120 visiting(false);
28121 }
28122 return v.visit_end(this);
28123}
28124
28125function_tdecl::~function_tdecl()
28126{}
28127
28128// </function_template>
28129
28130// <class template>
28131
28132/// Type of the private data of the the @ref class_tdecl type.
28133class class_tdecl::priv
28134{
28135 friend class class_tdecl;
28136 class_decl_sptr pattern_;
28137
28138public:
28139
28140 priv()
28141 {}
28142
28143 priv(class_decl_sptr pattern)
28144 : pattern_(pattern)
28145 {}
28146}; // end class class_tdecl::priv
28147
28148/// Constructor for the @ref class_tdecl type.
28149///
28150/// @param env the environment we are operating from.
28151///
28152/// @param locus the location of the declaration of the class_tdecl
28153/// type.
28154///
28155/// @param vis the visibility of the instance of class instantiated
28156/// from this template.
28157class_tdecl::class_tdecl(const environment& env,
28158 const location& locus,
28159 visibility vis)
28160 : type_or_decl_base(env,
28161 ABSTRACT_DECL_BASE
28162 | TEMPLATE_DECL
28163 | ABSTRACT_SCOPE_DECL),
28164 decl_base(env, "", locus, "", vis),
28165 template_decl(env, "", locus, vis),
28166 scope_decl(env, "", locus),
28167 priv_(new priv)
28168{
28170}
28171
28172/// Constructor for the @ref class_tdecl type.
28173///
28174/// @param pattern The details of the class template. This must NOT be a
28175/// null pointer. If you really this to be null, please use the
28176/// constructor above instead.
28177///
28178/// @param locus the source location of the declaration of the type.
28179///
28180/// @param vis the visibility of the instances of class instantiated
28181/// from this template.
28182class_tdecl::class_tdecl(class_decl_sptr pattern,
28183 const location& locus,
28184 visibility vis)
28185 : type_or_decl_base(pattern->get_environment(),
28186 ABSTRACT_DECL_BASE
28187 | TEMPLATE_DECL
28188 | ABSTRACT_SCOPE_DECL),
28189 decl_base(pattern->get_environment(), pattern->get_name(),
28190 locus, pattern->get_name(), vis),
28191 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
28192 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
28193 priv_(new priv(pattern))
28194{
28196}
28197
28198/// Setter of the pattern of the template.
28199///
28200/// @param p the new template.
28201void
28203{
28204 priv_->pattern_ = p;
28205 add_decl_to_scope(p, this);
28206 set_name(p->get_name());
28207}
28208
28209/// Getter of the pattern of the template.
28210///
28211/// @return p the new template.
28214{return priv_->pattern_;}
28215
28216bool
28218{
28219 try
28220 {
28221 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28222
28223 if (!(template_decl::operator==(o)
28224 && scope_decl::operator==(o)
28225 && !!get_pattern() == !!o.get_pattern()))
28226 return false;
28227
28228 if (!get_pattern() || !o.get_pattern())
28229 return true;
28230
28231 return get_pattern()->decl_base::operator==(*o.get_pattern());
28232 }
28233 catch(...) {}
28234 return false;
28235}
28236
28237bool
28239{
28240 try
28241 {
28242 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28243 return *this == static_cast<const decl_base&>(o);
28244 }
28245 catch(...)
28246 {return false;}
28247}
28248
28249bool
28251{return *this == static_cast<const decl_base&>(o);}
28252
28253/// This implements the ir_traversable_base::traverse pure virtual
28254/// function.
28255///
28256/// @param v the visitor used on the current instance and on the class
28257/// pattern of the template.
28258///
28259/// @return true if the entire IR node tree got traversed, false
28260/// otherwise.
28261bool
28263{
28264 if (visiting())
28265 return true;
28266
28267 if (v.visit_begin(this))
28268 {
28269 visiting(true);
28270 if (class_decl_sptr pattern = get_pattern())
28271 pattern->traverse(v);
28272 visiting(false);
28273 }
28274 return v.visit_end(this);
28275}
28276
28277class_tdecl::~class_tdecl()
28278{}
28279
28280/// This visitor checks if a given type as non-canonicalized sub
28281/// types.
28282class non_canonicalized_subtype_detector : public ir::ir_node_visitor
28283{
28284 type_base* type_;
28285 type_base* has_non_canonical_type_;
28286
28287private:
28288 non_canonicalized_subtype_detector();
28289
28290public:
28291 non_canonicalized_subtype_detector(type_base* type)
28292 : type_(type),
28293 has_non_canonical_type_()
28294 {}
28295
28296 /// Return true if the visitor detected that there is a
28297 /// non-canonicalized sub-type.
28298 ///
28299 /// @return true if the visitor detected that there is a
28300 /// non-canonicalized sub-type.
28301 type_base*
28302 has_non_canonical_type() const
28303 {return has_non_canonical_type_;}
28304
28305 /// The intent of this visitor handler is to avoid looking into
28306 /// sub-types of member functions of the type we are traversing.
28307 bool
28308 visit_begin(function_decl* f)
28309 {
28310 // Do not look at sub-types of non-virtual member functions.
28311 if (is_member_function(f)
28313 return false;
28314 return true;
28315 }
28316
28317 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
28318 /// the 'has_non_canonical_type' flag. And in any case, when
28319 /// visiting a sub-type, do not visit its children nodes. So this
28320 /// function only goes to the level below the level of the top-most
28321 /// type.
28322 ///
28323 /// @return true if we are at the same level as the top-most type,
28324 /// otherwise return false.
28325 bool
28326 visit_begin(type_base* t)
28327 {
28328 if (t != type_)
28329 {
28330 if (!t->get_canonical_type())
28331 // We are looking a sub-type of 'type_' which has no
28332 // canonical type. So tada! we found one! Get out right
28333 // now with the trophy.
28334 has_non_canonical_type_ = t;
28335
28336 return false;
28337 }
28338 return true;
28339 }
28340
28341 /// When we are done visiting a sub-type, if it's been flagged as
28342 /// been non-canonicalized, then stop the traversing.
28343 ///
28344 /// Otherwise, keep going.
28345 ///
28346 /// @return false iff the sub-type that has been visited is
28347 /// non-canonicalized.
28348 bool
28349 visit_end(type_base* )
28350 {
28351 if (has_non_canonical_type_)
28352 return false;
28353 return true;
28354 }
28355}; //end class non_canonicalized_subtype_detector
28356
28357/// Test if a type has sub-types that are non-canonicalized.
28358///
28359/// @param t the type which sub-types to consider.
28360///
28361/// @return true if a type has sub-types that are non-canonicalized.
28362type_base*
28364{
28365 if (!t)
28366 return 0;
28367
28368 non_canonicalized_subtype_detector v(t.get());
28369 t->traverse(v);
28370 return v.has_non_canonical_type();
28371}
28372
28373/// Tests if the change of a given type effectively comes from just
28374/// its sub-types. That is, if the type has changed but its type name
28375/// hasn't changed, then the change of the type mostly likely is a
28376/// sub-type change.
28377///
28378/// @param t_v1 the first version of the type.
28379///
28380/// @param t_v2 the second version of the type.
28381///
28382/// @return true iff the type changed and the change is about its
28383/// sub-types.
28384bool
28385type_has_sub_type_changes(const type_base_sptr t_v1,
28386 const type_base_sptr t_v2)
28387{
28388 type_base_sptr t1 = strip_typedef(t_v1);
28389 type_base_sptr t2 = strip_typedef(t_v2);
28390
28391 string repr1 = get_pretty_representation(t1, /*internal=*/false),
28392 repr2 = get_pretty_representation(t2, /*internal=*/false);
28393 return (t1 != t2 && repr1 == repr2);
28394}
28395
28396/// Make sure that the life time of a given (smart pointer to a) type
28397/// is the same as the life time of the libabigail library.
28398///
28399/// @param t the type to consider.
28400void
28401keep_type_alive(type_base_sptr t)
28402{
28403 const environment& env = t->get_environment();
28404 env.priv_->extra_live_types_.push_back(t);
28405}
28406
28407/// Hash an ABI artifact that is either a type or a decl.
28408///
28409/// This function intends to provides the fastest possible hashing for
28410/// types and decls, while being completely correct.
28411///
28412/// Note that if the artifact is a type and if it has a canonical
28413/// type, the hash value is going to be the pointer value of the
28414/// canonical type. Otherwise, this function computes a hash value
28415/// for the type by recursively walking the type members. This last
28416/// code path is possibly *very* slow and should only be used when
28417/// only handful of types are going to be hashed.
28418///
28419/// If the artifact is a decl, then a combination of the hash of its
28420/// type and the hash of the other properties of the decl is computed.
28421///
28422/// @param tod the type or decl to hash.
28423///
28424/// @return the resulting hash value.
28425size_t
28427{
28428 hash_t result = 0;
28429
28430 if (tod == 0)
28431 ;
28432 else if (const type_base* t = is_type(tod))
28433 result = hash_type(t);
28434 else if (const decl_base* d = is_decl(tod))
28435 {
28436 if (const scope_decl* s = is_scope_decl(d))
28437 {
28438 if (const global_scope* g = is_global_scope(s))
28439 result = reinterpret_cast<size_t>(g);
28440 else
28441 result = reinterpret_cast<size_t>(s);
28442 }
28443 else if (var_decl* v = is_var_decl(d))
28444 {
28445 ABG_ASSERT(v->get_type());
28446 hash_t h = hash_type_or_decl(v->get_type());
28447 string repr = v->get_pretty_representation(/*internal=*/true);
28448 std::hash<string> hash_string;
28449 h = hashing::combine_hashes(h, hash_string(repr));
28450 result = h;
28451 }
28452 else if (function_decl* f = is_function_decl(d))
28453 {
28454 ABG_ASSERT(f->get_type());
28455 hash_t h = hash_type_or_decl(f->get_type());
28456 string repr = f->get_pretty_representation(/*internal=*/true);
28457 std::hash<string> hash_string;
28458 h = hashing::combine_hashes(h, hash_string(repr));
28459 result = h;
28460 }
28462 {
28463 type_base_sptr parm_type = p->get_type();
28464 ABG_ASSERT(parm_type);
28465 std::hash<bool> hash_bool;
28466 std::hash<unsigned> hash_unsigned;
28467 hash_t h = hash_type_or_decl(parm_type);
28468 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
28469 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
28470 result = h;
28471 }
28472 else if (class_decl::base_spec *bs = is_class_base_spec(d))
28473 {
28474 member_base::hash hash_member;
28475 std::hash<size_t> hash_size;
28476 std::hash<bool> hash_bool;
28477 type_base_sptr type = bs->get_base_class();
28478 hash_t h = hash_type_or_decl(type);
28479 h = hashing::combine_hashes(h, hash_member(*bs));
28480 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
28481 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
28482 result = h;
28483 }
28484 else
28485 // This is a *really* *SLOW* path. If it shows up in a
28486 // performance profile, I bet it'd be a good idea to try to
28487 // avoid it altogether.
28488 // TODO: recode this function or get rid of it altogethe.
28489 abort();
28490 }
28491 else
28492 // We should never get here.
28493 abort();
28494 return *result;
28495}
28496
28497/// Hash an ABI artifact that is a type.
28498///
28499/// This function intends to provides the fastest possible hashing for
28500/// types while being completely correct.
28501///
28502/// Note that if the type artifact has a canonical type, the hash
28503/// value is going to be the pointer value of the canonical type.
28504/// Otherwise, this function computes a hash value for the type by
28505/// recursively walking the type members. This last code path is
28506/// possibly *very* slow and should only be used when only handful of
28507/// types are going to be hashed.
28508///
28509/// @param t the type or decl to hash.
28510///
28511/// @return the resulting hash value.
28512size_t
28514{return hash_as_canonical_type_or_constant(t);}
28515
28516/// Hash an ABI artifact that is either a type of a decl.
28517///
28518/// @param tod the ABI artifact to hash.
28519///
28520/// @return the hash value of the ABI artifact.
28521size_t
28523{return hash_type_or_decl(tod.get());}
28524
28525/// Get the hash value associated to an IR node.
28526///
28527/// Unlike type_or_decl_base::hash_value(), if the IR has no
28528/// associated hash value, an empty hash value is returned.
28529///
28530/// @param artefact the IR node to consider.
28531///
28532/// @return the hash value stored on the IR node or an empty hash if
28533/// no hash value is stored in the @p artefact.
28534hash_t
28536{
28537 const type_or_decl_base* artefactp = &artefact;
28538 if (decl_base *d = is_decl(artefactp))
28539 {
28541 if (d->type_or_decl_base::priv_->get_hashing_state()
28543 return d->type_or_decl_base::priv_->hash_value_;
28544 }
28545 else if (artefact.priv_->get_hashing_state() == hashing::HASHING_FINISHED_STATE)
28546 return artefact.priv_->hash_value_;
28547
28548 return hash_t();
28549}
28550
28551/// Test if a given type is allowed to be non canonicalized
28552///
28553/// This is a subroutine of hash_as_canonical_type_or_constant.
28554///
28555/// For now, the only types allowed to be non canonicalized in the
28556/// system are (typedefs & pointers to) decl-only class/union, the
28557/// void type and variadic parameter types.
28558///
28559/// @return true iff @p t is a one of the only types allowed to be
28560/// non-canonicalized in the system.
28561bool
28563{
28564 if (!t)
28565 return true;
28566
28567 return (// The IR nodes for the types below are unique across the
28568 // entire ABI corpus. Thus, no need to canonicalize them.
28569 // Maybe we could say otherwise and canonicalize them once
28570 // for all so that they can be removed from here.
28572
28573 // An IR node for the types below can be equal to several
28574 // other types (i.e, a decl-only type t equals a fully
28575 // defined type of the same name in ODR-supported
28576 // languages). Hence, they can't be given a canonical type.
28577 //
28578 // TODO: Maybe add a mode that would detect ODR violations
28579 // that would make a decl-only type co-exists with several
28580 // different definitions of the type in the ABI corpus.
28583 /*look_through_decl_only=*/true)
28585
28586}
28587
28588/// Test if a type is unique in the entire environment.
28589///
28590/// Examples of unique types are void, void* and variadic parameter
28591/// types.
28592///
28593/// @param t the type to test for.
28594///
28595/// @return true iff the type @p t is unique in the entire
28596/// environment.
28597bool
28598is_unique_type(const type_base_sptr& t)
28599{return is_unique_type(t.get());}
28600
28601/// Test if a type is unique in the entire environment.
28602///
28603/// Examples of unique types are void, void* and variadic parameter
28604/// types.
28605///
28606/// @param t the type to test for.
28607///
28608/// @return true iff the type @p t is unique in the entire
28609/// environment.
28610bool
28612{
28613 if (!t)
28614 return false;
28615
28616 const environment& env = t->get_environment();
28617 return (env.is_void_type(t)
28618 || env.is_void_pointer_type(t)
28619 || env.is_variadic_parameter_type(t));
28620}
28621
28622/// For a given type, return its exemplar type.
28623///
28624/// For a given type, its exemplar type is either its canonical type
28625/// or the canonical type of the definition type of a given
28626/// declaration-only type. If the neither of those two types exist,
28627/// then the exemplar type is the given type itself.
28628///
28629/// @param type the input to consider.
28630///
28631/// @return the exemplar type.
28632type_base*
28634{
28635 if (decl_base * decl = is_decl(type))
28636 {
28637 // Make sure we get the real definition of a decl-only type.
28638 decl = look_through_decl_only(decl);
28639 type = is_type(decl);
28640 ABG_ASSERT(type);
28641 }
28642 type_base *exemplar = type->get_naked_canonical_type();
28643 if (!exemplar)
28644 {
28645 // The type has no canonical type. Let's be sure that it's one
28646 // of those rare types that are allowed to be non canonicalized
28647 // in the system.
28648 exemplar = const_cast<type_base*>(type);
28650 }
28651 return exemplar;
28652}
28653
28654/// Test if a given type is allowed to be non canonicalized
28655///
28656/// This is a subroutine of hash_as_canonical_type_or_constant.
28657///
28658/// For now, the only types allowed to be non canonicalized in the
28659/// system are decl-only class/union and the void type.
28660///
28661/// @return true iff @p t is a one of the only types allowed to be
28662/// non-canonicalized in the system.
28663bool
28664is_non_canonicalized_type(const type_base_sptr& t)
28665{return is_non_canonicalized_type(t.get());}
28666
28667/// Hash a type by either returning the pointer value of its canonical
28668/// type or by returning a constant if the type doesn't have a
28669/// canonical type.
28670///
28671/// This is a subroutine of hash_type.
28672///
28673/// @param t the type to consider.
28674///
28675/// @return the hash value.
28676static size_t
28677hash_as_canonical_type_or_constant(const type_base *t)
28678{
28679 type_base *canonical_type = 0;
28680
28681 if (t)
28682 canonical_type = t->get_naked_canonical_type();
28683
28684 if (!canonical_type)
28685 {
28686 // If the type doesn't have a canonical type, maybe it's because
28687 // it's a declaration-only type? If that's the case, let's try
28688 // to get the canonical type of the definition of this
28689 // declaration.
28690 decl_base *decl = is_decl(t);
28691 if (decl
28692 && decl->get_is_declaration_only()
28694 {
28695 type_base *definition =
28697 ABG_ASSERT(definition);
28698 canonical_type = definition->get_naked_canonical_type();
28699 }
28700 }
28701
28702 if (canonical_type)
28703 return reinterpret_cast<size_t>(canonical_type);
28704
28705 // If we reached this point, it means we are seeing a
28706 // non-canonicalized type. It must be a decl-only class or a void
28707 // type, otherwise it means that for some weird reason, the type
28708 // hasn't been canonicalized. It should be!
28710
28711 return 0xDEADBABE;
28712}
28713
28714/// Test if the pretty representation of a given @ref function_decl is
28715/// lexicographically less then the pretty representation of another
28716/// @ref function_decl.
28717///
28718/// @param f the first @ref function_decl to consider for comparison.
28719///
28720/// @param s the second @ref function_decl to consider for comparison.
28721///
28722/// @return true iff the pretty representation of @p f is
28723/// lexicographically less than the pretty representation of @p s.
28724bool
28726{
28729
28730 if (fr != sr)
28731 return fr < sr;
28732
28733 fr = f.get_pretty_representation(/*internal=*/true),
28734 sr = s.get_pretty_representation(/*internal=*/true);
28735
28736 if (fr != sr)
28737 return fr < sr;
28738
28739 if (f.get_symbol())
28740 fr = f.get_symbol()->get_id_string();
28741 else if (!f.get_linkage_name().empty())
28742 fr = f.get_linkage_name();
28743
28744 if (s.get_symbol())
28745 sr = s.get_symbol()->get_id_string();
28746 else if (!s.get_linkage_name().empty())
28747 sr = s.get_linkage_name();
28748
28749 return fr < sr;
28750}
28751
28752/// Test if two types have similar structures, even though they are
28753/// (or can be) different.
28754///
28755/// const and volatile qualifiers are completely ignored.
28756///
28757/// typedef are resolved to their definitions; their names are ignored.
28758///
28759/// Two indirect types (pointers or references) have similar structure
28760/// if their underlying types are of the same kind and have the same
28761/// name. In the indirect types case, the size of the underlying type
28762/// does not matter.
28763///
28764/// Two direct types (i.e, non indirect) have a similar structure if
28765/// they have the same kind, name and size. Two class types have
28766/// similar structure if they have the same name, size, and if the
28767/// types of their data members have similar types.
28768///
28769/// @param first the first type to consider.
28770///
28771/// @param second the second type to consider.
28772///
28773/// @param indirect_type whether to do an indirect comparison
28774///
28775/// @return true iff @p first and @p second have similar structures.
28776bool
28777types_have_similar_structure(const type_base_sptr& first,
28778 const type_base_sptr& second,
28779 bool indirect_type)
28780{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
28781
28782/// Test if two types have similar structures, even though they are
28783/// (or can be) different.
28784///
28785/// const and volatile qualifiers are completely ignored.
28786///
28787/// typedef are resolved to their definitions; their names are ignored.
28788///
28789/// Two indirect types (pointers, references or arrays) have similar
28790/// structure if their underlying types are of the same kind and have
28791/// the same name. In the indirect types case, the size of the
28792/// underlying type does not matter.
28793///
28794/// Two direct types (i.e, non indirect) have a similar structure if
28795/// they have the same kind, name and size. Two class types have
28796/// similar structure if they have the same name, size, and if the
28797/// types of their data members have similar types.
28798///
28799/// @param first the first type to consider.
28800///
28801/// @param second the second type to consider.
28802///
28803/// @param indirect_type if true, then consider @p first and @p
28804/// second as being underlying types of indirect types. Meaning that
28805/// their size does not matter.
28806///
28807/// @return true iff @p first and @p second have similar structures.
28808bool
28810 const type_base* second,
28811 bool indirect_type)
28812{
28813 if (!!first != !!second)
28814 return false;
28815
28816 if (!first)
28817 return false;
28818
28819 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
28820 first = peel_qualified_or_typedef_type(first);
28821 second = peel_qualified_or_typedef_type(second);
28822
28823 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
28824 // various ty2 below cannot be null.
28825 if (typeid(*first) != typeid(*second))
28826 return false;
28827
28828 // Peel off matching pointers.
28829 if (const pointer_type_def* ty1 = is_pointer_type(first))
28830 {
28831 const pointer_type_def* ty2 = is_pointer_type(second);
28832 return types_have_similar_structure(ty1->get_pointed_to_type(),
28833 ty2->get_pointed_to_type(),
28834 /*indirect_type=*/true);
28835 }
28836
28837 // Peel off matching references.
28838 if (const reference_type_def* ty1 = is_reference_type(first))
28839 {
28840 const reference_type_def* ty2 = is_reference_type(second);
28841 if (ty1->is_lvalue() != ty2->is_lvalue())
28842 return false;
28843 return types_have_similar_structure(ty1->get_pointed_to_type(),
28844 ty2->get_pointed_to_type(),
28845 /*indirect_type=*/true);
28846 }
28847
28848 // Peel off matching pointer-to-member types.
28849 if (const ptr_to_mbr_type* ty1 = is_ptr_to_mbr_type(first))
28850 {
28851 const ptr_to_mbr_type* ty2 = is_ptr_to_mbr_type(second);
28852 return (types_have_similar_structure(ty1->get_member_type(),
28853 ty2->get_member_type(),
28854 /*indirect_type=*/true)
28855 && types_have_similar_structure(ty1->get_containing_type(),
28856 ty2->get_containing_type(),
28857 /*indirect_type=*/true));
28858 }
28859
28860 if (const type_decl* ty1 = is_type_decl(first))
28861 {
28862 const type_decl* ty2 = is_type_decl(second);
28863 if (!indirect_type)
28864 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28865 return false;
28866
28867 return ty1->get_name() == ty2->get_name();
28868 }
28869
28870 if (const enum_type_decl* ty1 = is_enum_type(first))
28871 {
28872 const enum_type_decl* ty2 = is_enum_type(second);
28873 if (!indirect_type)
28874 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28875 return false;
28876
28877 return (get_name(ty1->get_underlying_type())
28878 == get_name(ty2->get_underlying_type()));
28879 }
28880
28881 if (const class_decl* ty1 = is_class_type(first))
28882 {
28883 const class_decl* ty2 = is_class_type(second);
28884 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28885 && ty1->get_name() != ty2->get_name())
28886 return false;
28887
28888 if (!indirect_type)
28889 {
28890 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
28891 || (ty1->get_non_static_data_members().size()
28892 != ty2->get_non_static_data_members().size()))
28893 return false;
28894
28895 for (class_or_union::data_members::const_iterator
28896 i = ty1->get_non_static_data_members().begin(),
28897 j = ty2->get_non_static_data_members().begin();
28898 (i != ty1->get_non_static_data_members().end()
28899 && j != ty2->get_non_static_data_members().end());
28900 ++i, ++j)
28901 {
28902 var_decl_sptr dm1 = *i;
28903 var_decl_sptr dm2 = *j;
28904 if (!types_have_similar_structure(dm1->get_type().get(),
28905 dm2->get_type().get(),
28906 indirect_type))
28907 return false;
28908 }
28909 }
28910
28911 return true;
28912 }
28913
28914 if (const union_decl* ty1 = is_union_type(first))
28915 {
28916 const union_decl* ty2 = is_union_type(second);
28917 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28918 && ty1->get_name() != ty2->get_name())
28919 return false;
28920
28921 if (!indirect_type)
28922 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
28923
28924 return true;
28925 }
28926
28927 if (const array_type_def* ty1 = is_array_type(first))
28928 {
28929 const array_type_def* ty2 = is_array_type(second);
28930 if (!indirect_type)
28931 {
28932 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
28933 || ty1->get_dimension_count() != ty2->get_dimension_count())
28934 return false;
28935
28936 // Handle int[5][2] vs int[2][5] ...
28937 //
28938 // 6.2.5/20 of
28939 // https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
28940 // says:
28941 //
28942 // "Array types are characterized by their element
28943 // type and by the number of elements in the array"
28944 //
28945 // and 6.5.2.1/3 says:
28946 //
28947 // "arrays are stored in row-major order (last subscript
28948 // varies fastest)."
28949 //
28950 // So, let's ensure that all dimensions (sub-ranges) have
28951 // the same length.
28952
28953 for (auto r1 = ty1->get_subranges().begin(),
28954 r2 = ty1->get_subranges().begin();
28955 (r1 != ty1->get_subranges().end()
28956 && r2 != ty2->get_subranges().end());
28957 ++r1, ++r2)
28958 if ((*r1)->get_length() != (*r2)->get_length())
28959 return false;
28960 }
28961
28962 // ... then compare the elements of the arrays.
28963 if (!types_have_similar_structure(ty1->get_element_type(),
28964 ty2->get_element_type(),
28965 /*indirect_type=*/true))
28966 return false;
28967
28968 return true;
28969 }
28970
28971 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
28972 {
28974 if (ty1->get_upper_bound() != ty2->get_upper_bound()
28975 || ty1->get_lower_bound() != ty2->get_lower_bound()
28976 || ty1->get_language() != ty2->get_language()
28977 || !types_have_similar_structure(ty1->get_underlying_type(),
28978 ty2->get_underlying_type(),
28979 indirect_type))
28980 return false;
28981
28982 return true;
28983 }
28984
28985 if (const function_type* ty1 = is_function_type(first))
28986 {
28987 const function_type* ty2 = is_function_type(second);
28988 if (!types_have_similar_structure(ty1->get_return_type(),
28989 ty2->get_return_type(),
28990 indirect_type))
28991 return false;
28992
28993 if (ty1->get_parameters().size() != ty2->get_parameters().size())
28994 return false;
28995
28996 for (function_type::parameters::const_iterator
28997 i = ty1->get_parameters().begin(),
28998 j = ty2->get_parameters().begin();
28999 (i != ty1->get_parameters().end()
29000 && j != ty2->get_parameters().end());
29001 ++i, ++j)
29002 if (!types_have_similar_structure((*i)->get_type(),
29003 (*j)->get_type(),
29004 indirect_type))
29005 return false;
29006
29007 return true;
29008 }
29009
29010 // All kinds of type should have been handled at this point.
29012
29013 return false;
29014}
29015
29016/// Look for a data member of a given class, struct or union type and
29017/// return it.
29018///
29019/// The data member is designated by its name.
29020///
29021/// @param type the class, struct or union type to consider.
29022///
29023/// @param dm_name the name of the data member to lookup.
29024///
29025/// @return the data member iff it was found in @type or NULL if no
29026/// data member with that name was found.
29027const var_decl*
29029 const char* dm_name)
29030
29031{
29033 if (!cou)
29034 return 0;
29035
29036 return cou->find_data_member(dm_name).get();
29037}
29038
29039/// Look for a data member of a given class, struct or union type and
29040/// return it.
29041///
29042/// The data member is designated by its name.
29043///
29044/// @param type the class, struct or union type to consider.
29045///
29046/// @param dm the data member to lookup.
29047///
29048/// @return the data member iff it was found in @type or NULL if no
29049/// data member with that name was found.
29050const var_decl_sptr
29051lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
29052{
29053 class_or_union_sptr cou = is_class_or_union_type(type);
29054 if (!cou)
29055 return var_decl_sptr();
29056
29057 return cou->find_data_member(dm);
29058}
29059
29060/// Get the function parameter designated by its index.
29061///
29062/// Note that the first function parameter has index 0.
29063///
29064/// @param fun the function to consider.
29065///
29066/// @param parm_index the index of the function parameter to get.
29067///
29068/// @return the function parameter designated by its index, of NULL if
29069/// no function parameter with that index was found.
29072 unsigned parm_index)
29073{
29075 if (!fn)
29076 return 0;
29077
29078 const function_decl::parameters &parms = fn->get_type()->get_parameters();
29079 if (parms.size() <= parm_index)
29080 return 0;
29081
29082 return parms[parm_index].get();
29083}
29084
29085/// Build the internal name of the underlying type of an enum.
29086///
29087/// @param base_name the (unqualified) name of the enum the underlying
29088/// type is destined to.
29089///
29090/// @param is_anonymous true if the underlying type of the enum is to
29091/// be anonymous.
29092string
29094 bool is_anonymous,
29095 uint64_t size)
29096{
29097 std::ostringstream o;
29098
29099 if (is_anonymous)
29100 o << "unnamed-enum";
29101 else
29102 o << "enum-" << base_name;
29103
29104 o << "-underlying-type-" << size;
29105
29106 return o.str();
29107}
29108
29109/// Find the first data member of a class or union which name matches
29110/// a regular expression.
29111///
29112/// @param t the class or union to consider.
29113///
29114/// @param r the regular expression to consider.
29115///
29116/// @return the data member matched by @p r or nil if none was found.
29119 const regex::regex_t_sptr& r)
29120{
29121 for (auto data_member : t.get_data_members())
29122 {
29123 if (regex::match(r, data_member->get_name()))
29124 return data_member;
29125 }
29126
29127 return var_decl_sptr();
29128}
29129
29130/// Find the last data member of a class or union which name matches
29131/// a regular expression.
29132///
29133/// @param t the class or union to consider.
29134///
29135/// @param r the regular expression to consider.
29136///
29137/// @return the data member matched by @p r or nil if none was found.
29140 const regex::regex_t_sptr& regex)
29141{
29142 auto d = t.get_data_members().rbegin();
29143 auto e = t.get_data_members().rend();
29144 for (; d != e; ++d)
29145 {
29146 if (regex::match(regex, (*d)->get_name()))
29147 return *d;
29148 }
29149
29150 return var_decl_sptr();
29151}
29152
29153/// Emit the pretty representation of the parameters of a function
29154/// type.
29155///
29156/// @param fn_type the function type to consider.
29157///
29158/// @param o the output stream to emit the pretty representation to.
29159///
29160/// @param qualified if true, emit fully qualified names.
29161///
29162/// @param internal if true, then the result is to be used for the
29163/// purpose of type canonicalization.
29164static void
29165stream_pretty_representation_of_fn_parms(const function_type& fn_type,
29166 ostream& o, bool qualified,
29167 bool internal)
29168{
29169 o << "(";
29170 if (fn_type.get_parameters().empty())
29171 o << "void";
29172 else
29173 {
29174 type_base_sptr type;
29175 auto end = fn_type.get_parameters().end();
29176 auto first_parm = fn_type.get_first_non_implicit_parm();
29178 const environment& env = fn_type.get_environment();
29179 for (auto i = fn_type.get_first_non_implicit_parm(); i != end; ++i)
29180 {
29181 if (i != first_parm)
29182 o << ", ";
29183 parm = *i;
29184 type = parm->get_type();
29185 // If the type is a decl-only class, union or enum that has a
29186 // definition, use the definition instead. That definition
29187 // is what is going to be serialized out in ABIXML anyway,
29188 // so use that for consistency.
29189 if (decl_base_sptr def = look_through_decl_only(is_decl(type)))
29190 type = is_type(def);
29191 if (env.is_variadic_parameter_type(type))
29192 o << "...";
29193 else
29194 o << get_type_name(type, qualified, internal);
29195 }
29196 }
29197 o << ")";
29198}
29199
29200/// When constructing the name of a pointer to function type, add the
29201/// return type to the left of the existing type identifier, and the
29202/// parameters declarator to the right.
29203///
29204/// This function considers the name of the type as an expression.
29205///
29206/// The resulting type expr is going to be made of three parts:
29207/// left_expr inner_expr right_expr.
29208///
29209/// Suppose we want to build the type expression representing:
29210///
29211/// "an array of pointer to function taking a char parameter and
29212/// returning an int".
29213///
29214/// It's going to look like:
29215///
29216/// int(*a[])(char);
29217///
29218/// Suppose the caller of this function started to emit the inner
29219/// "a[]" part of the expression already. It thus calls this
29220/// function with that input "a[]" part. We consider that "a[]" as
29221/// the "type identifier".
29222///
29223/// So the inner_expr is going to be "(*a[])".
29224///
29225/// The left_expr part is "int". The right_expr part is "(char)".
29226///
29227/// In other words, this function adds the left_expr and right_expr to
29228/// the inner_expr. left_expr and right_expr are called "outer
29229/// pointer to function type expression".
29230///
29231/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29232/// array_declaration_name()
29233///
29234/// @param p the pointer to function type to consider.
29235///
29236/// @param input the type-id to use as the inner expression of the
29237/// overall pointer-to-function type expression
29238///
29239/// @param qualified if true then use qualified names in the resulting
29240/// type name.
29241///
29242/// @param internal if true then the resulting type name is going to
29243/// be used for type canonicalization purposes.
29244///
29245/// @return the name of the pointer to function type.
29246static string
29247add_outer_pointer_to_fn_type_expr(const type_base* p,
29248 const string& input,
29249 bool qualified, bool internal)
29250{
29251 if (!p)
29252 return "";
29253
29254 function_type_sptr pointed_to_fn;
29255 string star_or_ref;
29256
29257 if (const pointer_type_def* ptr = is_pointer_type(p))
29258 {
29259 pointed_to_fn = is_function_type(ptr->get_pointed_to_type());
29260 star_or_ref= "*";
29261 }
29262 else if (const reference_type_def* ref = is_reference_type(p))
29263 {
29264 star_or_ref = "&";
29265 pointed_to_fn = is_function_type(ref->get_pointed_to_type());
29266 }
29267
29268 if (!pointed_to_fn)
29269 return "";
29270
29271 if (pointed_to_fn->priv_->is_pretty_printing())
29272 // We have just detected a cycle while walking the sub-tree of
29273 // this function type for the purpose of printing its
29274 // representation. We need to get out of here pronto or else
29275 // we'll be spinning endlessly.
29276 return "";
29277
29278 // Let's mark thie function type to signify that we started walking
29279 // its subtree. This is to detect potential cycles and avoid
29280 // looping endlessly.
29281 pointed_to_fn->priv_->set_is_pretty_printing();
29282
29283 std::ostringstream left, right, inner;
29284
29285 inner << "(" << star_or_ref << input << ")";
29286
29287 type_base_sptr type;
29288 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
29289 qualified, internal);
29290
29291 type_base_sptr return_type = pointed_to_fn->get_return_type();
29292 string result;
29293
29294 if (is_npaf_type(return_type)
29295 || !(is_pointer_to_function_type(return_type)
29296 || is_pointer_to_array_type(return_type)))
29297 {
29298 if (return_type)
29299 left << get_type_name(return_type, qualified, internal);
29300 result = left.str() + " " + inner.str() + right.str();
29301 }
29302 else if (pointer_type_def_sptr p = is_pointer_to_function_type(return_type))
29303 {
29304 string inner_string = inner.str() + right.str();
29305 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
29306 qualified, internal);
29307 }
29308 else if (pointer_type_def_sptr p = is_pointer_to_array_type(return_type))
29309 {
29310 string inner_string = inner.str() + right.str();
29311 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29312 qualified, internal);
29313 }
29314 else
29316
29317 // Lets unmark this function type to signify that we are done
29318 // walking its subtree. This was to detect potential cycles and
29319 // avoid looping endlessly.
29320 pointed_to_fn->priv_->unset_is_pretty_printing();
29321 return result;
29322}
29323
29324/// When constructing the name of a pointer to function type, add the
29325/// return type to the left of the existing type identifier, and the
29326/// parameters declarator to the right.
29327///
29328/// This function considers the name of the type as an expression.
29329///
29330/// The resulting type expr is going to be made of three parts:
29331/// left_expr inner_expr right_expr.
29332///
29333/// Suppose we want to build the type expression representing:
29334///
29335/// "an array of pointer to function taking a char parameter and
29336/// returning an int".
29337///
29338/// It's going to look like:
29339///
29340/// int(*a[])(char);
29341///
29342/// Suppose the caller of this function started to emit the inner
29343/// "a[]" part of the expression already. It thus calls this
29344/// function with that input "a[]" part. We consider that "a[]" as
29345/// the "type identifier".
29346///
29347/// So the inner_expr is going to be "(*a[])".
29348///
29349/// The left_expr part is "int". The right_expr part is "(char)".
29350///
29351/// In other words, this function adds the left_expr and right_expr to
29352/// the inner_expr. left_expr and right_expr are called "outer
29353/// pointer to function type expression".
29354///
29355/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29356/// array_declaration_name()
29357///
29358/// @param p the pointer to function type to consider.
29359///
29360/// @param input the type-id to use as the inner expression of the
29361/// overall pointer-to-function type expression
29362///
29363/// @param qualified if true then use qualified names in the resulting
29364/// type name.
29365///
29366/// @param internal if true then the resulting type name is going to
29367/// be used for type canonicalization purposes.
29368///
29369/// @return the name of the pointer to function type.
29370static string
29371add_outer_pointer_to_fn_type_expr(const type_base_sptr& p,
29372 const string& input,
29373 bool qualified, bool internal)
29374{return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
29375
29376/// When constructing the name of a pointer to array type, add the
29377/// array element type type to the left of the existing type
29378/// identifier, and the array declarator part to the right.
29379///
29380/// This function considers the name of the type as an expression.
29381///
29382/// The resulting type expr is going to be made of three parts:
29383/// left_expr inner_expr right_expr.
29384///
29385/// Suppose we want to build the type expression representing:
29386///
29387/// "a pointer to an array of int".
29388///
29389/// It's going to look like:
29390///
29391/// int(*foo)[];
29392///
29393/// Suppose the caller of this function started to emit the inner
29394/// "foo" part of the expression already. It thus calls this function
29395/// with that input "foo" part. We consider that "foo" as the "type
29396/// identifier".
29397///
29398/// So we are passed an input string that is "foo" and it's going to
29399/// be turned into the inner_expr part, which is going to be "(*foo)".
29400///
29401/// The left_expr part is "int". The right_expr part is "[]".
29402///
29403/// In other words, this function adds the left_expr and right_expr to
29404/// the inner_expr. left_expr and right_expr are called "outer
29405/// pointer to array type expression".
29406///
29407/// The model of this function was taken from the article "Reading C
29408/// type declaration", from Steve Friedl at
29409/// http://unixwiz.net/techtips/reading-cdecl.html.
29410///
29411/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29412/// array_declaration_name()
29413///
29414/// @param p the pointer to array type to consider.
29415///
29416/// @param input the type-id to start from as the inner part of the
29417/// final type name.
29418///
29419/// @param qualified if true then use qualified names in the resulting
29420/// type name.
29421///
29422/// @param internal if true then the resulting type name is going to
29423/// be used for type canonicalization purposes.
29424///
29425/// @return the name of the pointer to array type.
29426static string
29427add_outer_pointer_to_array_type_expr(const type_base* p,
29428 const string& input, bool qualified,
29429 bool internal)
29430{
29431 if (!p)
29432 return "";
29433
29434 string star_or_ref;
29435 type_base_sptr pointed_to_type;
29436
29437 if (const pointer_type_def *ptr = is_pointer_type(p))
29438 {
29439 pointed_to_type = ptr->get_pointed_to_type();
29440 star_or_ref = "*";
29441 }
29442 else if (const reference_type_def *ref = is_reference_type(p))
29443 {
29444 pointed_to_type = ref->get_pointed_to_type();
29445 star_or_ref = "&";
29446 }
29447
29448 array_type_def_sptr array = is_array_type(pointed_to_type);
29449 if (!array)
29450 return "";
29451
29452 std::ostringstream left, right, inner;
29453 inner << "(" << star_or_ref << input << ")";
29454 right << array->get_subrange_representation();
29455 string result;
29456
29457 type_base_sptr array_element_type = array->get_element_type();
29458
29459 if (is_npaf_type(array_element_type)
29460 || !(is_pointer_to_function_type(array_element_type)
29461 || is_pointer_to_array_type(array_element_type)))
29462 {
29463 left << get_type_name(array_element_type, qualified, internal);
29464 result = left.str() + inner.str() + right.str();
29465 }
29466 else if (pointer_type_def_sptr p =
29467 is_pointer_to_function_type(array_element_type))
29468 {
29469 string r = inner.str() + right.str();
29470 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
29471 }
29472 else if (pointer_type_def_sptr p =
29473 is_pointer_to_array_type(array_element_type))
29474 {
29475 string inner_string = inner.str() + right.str();
29476 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29477 qualified, internal);
29478 }
29479 else
29481
29482 return result;
29483}
29484
29485/// When constructing the name of a pointer to array type, add the
29486/// array element type type to the left of the existing type
29487/// identifier, and the array declarator part to the right.
29488///
29489/// This function considers the name of the type as an expression.
29490///
29491/// The resulting type expr is going to be made of three parts:
29492/// left_expr inner_expr right_expr.
29493///
29494/// Suppose we want to build the type expression representing:
29495///
29496/// "a pointer to an array of int".
29497///
29498/// It's going to look like:
29499///
29500/// int(*foo)[];
29501///
29502/// Suppose the caller of this function started to emit the inner
29503/// "foo" part of the expression already. It thus calls this function
29504/// with that input "foo" part. We consider that "foo" as the "type
29505/// identifier".
29506///
29507/// So we are passed an input string that is "foo" and it's going to
29508/// be turned into the inner_expr part, which is going to be "(*foo)".
29509///
29510/// The left_expr part is "int". The right_expr part is "[]".
29511///
29512/// In other words, this function adds the left_expr and right_expr to
29513/// the inner_expr. left_expr and right_expr are called "outer
29514/// pointer to array type expression".
29515///
29516/// The model of this function was taken from the article "Reading C
29517/// type declaration", from Steve Friedl at
29518/// http://unixwiz.net/techtips/reading-cdecl.html.
29519///
29520/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29521/// array_declaration_name()
29522///
29523/// @param p the pointer to array type to consider.
29524///
29525/// @param input the type-id to start from as the inner part of the
29526/// final type name.
29527///
29528/// @param qualified if true then use qualified names in the resulting
29529/// type name.
29530///
29531/// @param internal if true then the resulting type name is going to
29532/// be used for type canonicalization purposes.
29533///
29534/// @return the name of the pointer to array type.
29535static string
29536add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
29537 const string& input, bool qualified,
29538 bool internal)
29539{return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
29540 input, qualified, internal);}
29541
29542/// When constructing the name of a pointer to mebmer type, add the
29543/// return type to the left of the existing type identifier, and the
29544/// parameters declarator to the right.
29545///
29546/// This function considers the name of the type as an expression.
29547///
29548/// The resulting type expr is going to be made of three parts:
29549/// left_expr inner_expr right_expr.
29550///
29551/// Suppose we want to build the type expression representing:
29552///
29553/// "an array of pointer to member function (of a containing struct
29554/// X) taking a char parameter and returning an int".
29555///
29556/// It's going to look like:
29557///
29558/// int (X::* a[])(char);
29559///
29560/// Suppose the caller of this function started to emit the inner
29561/// "a[]" part of the expression already. It thus calls this
29562/// function with that input "a[]" part. We consider that "a[]" as
29563/// the "type identifier".
29564///
29565/// So the inner_expr is going to be "(X::* a[])".
29566///
29567/// The left_expr part is "int". The right_expr part is "(char)".
29568///
29569/// In other words, this function adds the left_expr and right_expr to
29570/// the inner_expr. left_expr and right_expr are called "outer
29571/// pointer to member type expression".
29572///
29573/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29574///
29575/// @param p the pointer to member type to consider.
29576///
29577/// @param input the type-id to use as the inner expression of the
29578/// overall pointer-to-member type expression
29579///
29580/// @param qualified if true then use qualified names in the resulting
29581/// type name.
29582///
29583/// @param internal if true then the resulting type name is going to
29584/// be used for type canonicalization purposes.
29585///
29586/// @return the name of the pointer to member type.
29587static string
29588add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
29589 const string& input, bool qualified,
29590 bool internal)
29591{
29592 if (!p)
29593 return "";
29594
29595 std::ostringstream left, right, inner;
29596 type_base_sptr void_type = p->get_environment().get_void_type();
29597 string containing_type_name = get_type_name(p->get_containing_type(),
29598 qualified, internal);
29599 type_base_sptr mbr_type = p->get_member_type();
29600 string result;
29601 if (function_type_sptr fn_type = is_function_type(mbr_type))
29602 {
29603 inner << "(" << containing_type_name << "::*" << input << ")";
29604 stream_pretty_representation_of_fn_parms(*fn_type, right,
29605 qualified, internal);
29606 type_base_sptr return_type = fn_type->get_return_type();
29607 if (!return_type)
29608 return_type = void_type;
29609 if (is_npaf_type(return_type)
29610 || !(is_pointer_to_function_type(return_type)
29611 || is_pointer_to_array_type(return_type)
29612 || is_pointer_to_ptr_to_mbr_type(return_type)
29613 || is_ptr_to_mbr_type(return_type)))
29614 {
29615 left << get_type_name(return_type, qualified, internal) << " ";;
29616 result = left.str() + inner.str() + right.str();
29617 }
29618 else if (pointer_type_def_sptr p = is_pointer_type(return_type))
29619 {
29620 string inner_str = inner.str() + right.str();
29621 result = pointer_declaration_name(p, inner_str, qualified, internal);
29622 }
29623 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(return_type))
29624 {
29625 string inner_str = inner.str() + right.str();
29626 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
29627 qualified, internal);
29628 }
29629 else
29631 }
29632 else if (ptr_to_mbr_type_sptr ptr_mbr_type = is_ptr_to_mbr_type(mbr_type))
29633 {
29634 inner << "(" << containing_type_name << "::*" << input << ")";
29635 stream_pretty_representation_of_fn_parms(*fn_type, right,
29636 qualified, internal);
29637 string inner_str = inner.str() + right.str();
29638 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
29639 qualified, internal);
29640 }
29641 else
29642 {
29643 left << get_type_name(p->get_member_type(), qualified, internal) << " ";
29644 inner << containing_type_name << "::*" << input;
29645 result = left.str()+ inner.str();
29646 }
29647
29648 return result;
29649}
29650
29651/// Test if two decls have different names.
29652///
29653/// Note that this function takes into account decls whose names are
29654/// relevant from an ABI standpoint. For instance, function parameter
29655/// names are not relevant in that context.
29656///
29657/// @param d1 the first declaration to consider.
29658///
29659/// @param d2 the second declaration to consider.
29660///
29661/// @return true if d1 and d2 have different names.
29662bool
29664{
29665 string d1_name, d2_name;
29666
29667 const decl_base *d1 = dynamic_cast<const decl_base*>(a1);
29668 if (d1 == 0)
29669 return false;
29670
29671 const decl_base *d2 = dynamic_cast<const decl_base*>(a2);
29672 if (d2 == 0)
29673 return false;
29674
29676 // Name changes for fn parms are irrelevant.
29677 return false;
29678
29679 d1_name = d1->get_qualified_name();
29680 d2_name = d2->get_qualified_name();
29681
29682 return d1_name != d2_name;
29683}
29684
29685/// Test if two decls have different names.
29686///
29687/// @param d1 the first declaration to consider.
29688///
29689/// @param d2 the second declaration to consider.
29690///
29691/// @return true if d1 and d2 have different names.
29692bool
29694 const type_or_decl_base_sptr& d2)
29695{return decl_name_changed(d1.get(), d2.get());}
29696
29697/// Test if a diff node carries a change whereby two integral types
29698/// have different names in a harmless way.
29699///
29700/// Basically, if the integral type name change is accompanied by a
29701/// size change then the change is considered harmful. If there are
29702/// modifiers change, the change is considered harmful.
29703bool
29705 const type_base_sptr& s)
29706{
29707 if (is_decl(f)
29708 && is_decl(s)
29709 && ((is_integral_type(f) && is_integral_type(s))
29710 || (is_decl(f)->get_name().empty()
29711 && is_type_decl(f)
29712 && is_integral_type(s))
29713 || (is_decl(s)->get_name().empty()
29714 && is_type_decl(s)
29715 && is_integral_type(f)))
29717 && (f->get_size_in_bits() == s->get_size_in_bits())
29718 && (f->get_alignment_in_bits() == s->get_alignment_in_bits()))
29719 return true;
29720
29721 return false;
29722}
29723
29724/// Test if a diff node carries a change whereby two integral types
29725/// have different names in a harmless way.
29726///
29727/// Basically, if the integral type name change is accompanied by a
29728/// size change then the change is considered harmful. If there are
29729/// modifiers change, the change is considered harmful.
29730bool
29732 const decl_base_sptr& s)
29734
29735
29736/// When constructing the name of a pointer to mebmer type, add the
29737/// return type to the left of the existing type identifier, and the
29738/// parameters declarator to the right.
29739///
29740/// This function considers the name of the type as an expression.
29741///
29742/// The resulting type expr is going to be made of three parts:
29743/// left_expr inner_expr right_expr.
29744///
29745/// Suppose we want to build the type expression representing:
29746///
29747/// "an array of pointer to member function (of a containing struct
29748/// X) taking a char parameter and returning an int".
29749///
29750/// It's going to look like:
29751///
29752/// int (X::* a[])(char);
29753///
29754/// Suppose the caller of this function started to emit the inner
29755/// "a[]" part of the expression already. It thus calls this
29756/// function with that input "a[]" part. We consider that "a[]" as
29757/// the "type identifier".
29758///
29759/// So the inner_expr is going to be "(X::* a[])".
29760///
29761/// The left_expr part is "int". The right_expr part is "(char)".
29762///
29763/// In other words, this function adds the left_expr and right_expr to
29764/// the inner_expr. left_expr and right_expr are called "outer
29765/// pointer to member type expression".
29766///
29767/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29768///
29769/// @param p the pointer to member type to consider.
29770///
29771/// @param input the type-id to use as the inner expression of the
29772/// overall pointer-to-member type expression
29773///
29774/// @param qualified if true then use qualified names in the resulting
29775/// type name.
29776///
29777/// @param internal if true then the resulting type name is going to
29778/// be used for type canonicalization purposes.
29779///
29780/// @return the name of the pointer to member type.
29781static string
29782add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
29783 const string& input, bool qualified,
29784 bool internal)
29785{return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
29786
29787/// This adds the outer parts of a pointer to a pointer-to-member
29788/// expression.
29789///
29790/// Please read the comments of @ref add_outer_ptr_to_mbr_type_expr to
29791/// learn more about this function, which is similar.
29792///
29793/// This is a sub-routine of @ref pointer_declaration_name().
29794///
29795/// @param a pointer (or reference) to a pointer-to-member type.
29796///
29797/// @param input the inner type-id to add the outer parts to.
29798///
29799/// @param qualified if true then use qualified names in the resulting
29800/// type name.
29801///
29802/// @param internal if true then the resulting type name is going to
29803/// be used for type canonicalization purposes.
29804static string
29805add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
29806 const string& input, bool qualified,
29807 bool internal)
29808{
29809 if (!p)
29810 return "";
29811
29812 string star_or_ref;
29813 type_base_sptr pointed_to_type;
29814
29815 if (const pointer_type_def* ptr = is_pointer_type(p))
29816 {
29817 pointed_to_type = ptr->get_pointed_to_type();
29818 star_or_ref = "*";
29819 }
29820 else if (const reference_type_def* ref = is_reference_type(p))
29821 {
29822 pointed_to_type= ref->get_pointed_to_type();
29823 star_or_ref = "&";
29824 }
29825
29826 if (!pointed_to_type)
29827 return "";
29828
29829 ptr_to_mbr_type_sptr pointed_to_ptr_to_mbr =
29830 is_ptr_to_mbr_type(pointed_to_type);
29831 if (!pointed_to_ptr_to_mbr)
29832 return "";
29833
29834 std::ostringstream inner;
29835 inner << star_or_ref << input;
29836 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
29837 inner.str(),
29838 qualified, internal);
29839 return result;
29840}
29841
29842/// Emit the name of a pointer declaration.
29843///
29844/// @param the pointer to consider.
29845///
29846/// @param idname the name of the variable that has @p as a type or
29847/// the id of the type. If it's empty then the resulting name is
29848/// going to be the abstract name of the type.
29849///
29850/// @param qualified if true then the type name is going to be
29851/// fully qualified.
29852///
29853/// @param internal if true then the type name is going to be used for
29854/// type canonicalization purposes.
29855static interned_string
29856pointer_declaration_name(const type_base* ptr,
29857 const string& idname,
29858 bool qualified, bool internal)
29859{
29860 if (!ptr)
29861 return interned_string();
29862
29863 type_base_sptr pointed_to_type;
29864 string star_or_ref;
29865 if (const pointer_type_def* p = is_pointer_type(ptr))
29866 {
29867 pointed_to_type = p->get_pointed_to_type();
29868 star_or_ref = "*";
29869 }
29870 else if (const reference_type_def* p = is_reference_type(ptr))
29871 {
29872 pointed_to_type = p->get_pointed_to_type();
29873 star_or_ref = "&";
29874 }
29875
29876 if (!pointed_to_type)
29877 return interned_string();
29878
29879 string result;
29880 if (is_npaf_type(pointed_to_type)
29881 || !(is_function_type(pointed_to_type)
29882 || is_array_type(pointed_to_type)
29883 || is_ptr_to_mbr_type(pointed_to_type)))
29884 {
29885 result = get_type_name(pointed_to_type,
29886 qualified,
29887 internal)
29888 + star_or_ref;
29889
29890 if (!idname.empty())
29891 result += idname;
29892 }
29893 else
29894 {
29895 // derived type
29896 if (is_function_type(pointed_to_type))
29897 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
29898 qualified, internal);
29899 else if (is_array_type(pointed_to_type))
29900 result = add_outer_pointer_to_array_type_expr(ptr, idname,
29901 qualified, internal);
29902 else if (is_ptr_to_mbr_type(pointed_to_type))
29903 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
29904 qualified, internal);
29905 else
29907 }
29908 return ptr->get_environment().intern(result);
29909}
29910
29911
29912/// Emit the name of a pointer declaration.
29913///
29914/// @param the pointer to consider.
29915///
29916/// @param the name of the variable that has @p as a type. If it's
29917/// empty then the resulting name is going to be the abstract name of
29918/// the type.
29919///
29920/// @param qualified if true then the type name is going to be
29921/// fully qualified.
29922///
29923/// @param internal if true then the type name is going to be used for
29924/// type canonicalization purposes.
29925static interned_string
29926pointer_declaration_name(const type_base_sptr& ptr,
29927 const string& variable_name,
29928 bool qualified, bool internal)
29929{return pointer_declaration_name(ptr.get(), variable_name,
29930 qualified, internal);}
29931
29932/// Emit the name of a array declaration.
29933///
29934/// @param the array to consider.
29935///
29936/// @param the name of the variable that has @p as a type. If it's
29937/// empty then the resulting name is going to be the abstract name of
29938/// the type.
29939///
29940/// @param qualified if true then the type name is going to be
29941/// fully qualified.
29942///
29943/// @param internal if true then the type name is going to be used for
29944/// type canonicalization purposes.
29945static interned_string
29946array_declaration_name(const array_type_def* array,
29947 const string& variable_name,
29948 bool qualified, bool internal)
29949{
29950 if (!array)
29951 return interned_string();
29952
29953 type_base_sptr e_type = array->get_element_type();
29954 string e_type_repr =
29955 (e_type
29956 ? get_type_name(e_type, qualified, internal)
29957 : string("void"));
29958
29959 string result;
29960 if (is_ada_language(array->get_language()))
29961 {
29962 std::ostringstream o;
29963 if (!variable_name.empty())
29964 o << variable_name << " is ";
29965 o << "array ("
29966 << array->get_subrange_representation()
29967 << ") of " << e_type_repr;
29968 result = o.str();
29969 }
29970 else
29971 {
29972 if (is_npaf_type(e_type)
29973 || !(is_pointer_to_function_type(e_type)
29974 || is_pointer_to_array_type(e_type)
29976 || is_ptr_to_mbr_type(e_type)))
29977 {
29978 result = e_type_repr;
29979 if (!variable_name.empty())
29980 result += variable_name;
29981 result += array->get_subrange_representation();
29982 }
29983 else if (pointer_type_def_sptr p = is_pointer_type(e_type))
29984 {
29985 string s = variable_name + array->get_subrange_representation();
29986 result = pointer_declaration_name(p, s, qualified, internal);
29987 }
29988 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(e_type))
29989 {
29990 string s = variable_name + array->get_subrange_representation();
29991 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
29992 }
29993 else
29995 }
29996 return array->get_environment().intern(result);
29997}
29998
29999/// Emit the name of a array declaration.
30000///
30001/// @param the array to consider.
30002///
30003/// @param the name of the variable that has @p as a type. If it's
30004/// empty then the resulting name is going to be the abstract name of
30005/// the type.
30006///
30007/// @param qualified if true then the type name is going to be
30008/// fully qualified.
30009///
30010/// @param internal if true then the type name is going to be used for
30011/// type canonicalization purposes.
30012static interned_string
30013array_declaration_name(const array_type_def_sptr& array,
30014 const string& variable_name,
30015 bool qualified, bool internal)
30016{return array_declaration_name(array.get(), variable_name,
30017 qualified, internal);}
30018
30019/// Emit the name of a pointer-to-member declaration.
30020///
30021/// @param ptr the pointer-to-member to consider.
30022///
30023/// @param variable_name the name of the variable that has @p as a
30024/// type. If it's empty then the resulting name is going to be the
30025/// abstract name of the type.
30026///
30027/// @param qualified if true then the type name is going to be
30028/// fully qualified.
30029///
30030/// @param internal if true then the type name is going to be used for
30031/// type canonicalization purposes.
30032static interned_string
30033ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
30034 const string& variable_name,
30035 bool qualified, bool internal)
30036{
30037 if (!ptr)
30038 return interned_string();
30039
30040 string input = variable_name;
30041 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
30042 qualified, internal);
30043 return ptr->get_environment().intern(result);
30044}
30045
30046/// Emit the name of a pointer-to-member declaration.
30047///
30048/// @param ptr the pointer-to-member to consider.
30049///
30050/// @param variable_name the name of the variable that has @p as a
30051/// type. If it's empty then the resulting name is going to be the
30052/// abstract name of the type.
30053///
30054/// @param qualified if true then the type name is going to be
30055/// fully qualified.
30056///
30057/// @param internal if true then the type name is going to be used for
30058/// type canonicalization purposes.
30059static interned_string
30060ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
30061 const string& variable_name,
30062 bool qualified, bool internal)
30063{
30064 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
30065 qualified, internal);
30066}
30067
30068/// Sort types right before hashing and canonicalizing them.
30069///
30070/// @param types the vector of types to sort.
30071void
30072sort_types_for_hash_computing_and_c14n(vector<type_base_sptr>& types)
30073{
30074 sort_types_for_hash_computing_and_c14n(types.begin(), types.end());
30075}
30076
30077bool
30079{return true;}
30080
30081// <ir_node_visitor stuff>
30082
30083/// The private data structure of the ir_node_visitor type.
30084struct ir_node_visitor::priv
30085{
30086 pointer_set visited_ir_nodes;
30088
30089 priv()
30091 {}
30092}; // end struct ir_node_visitory::priv
30093
30094/// Default Constructor of the ir_node_visitor type.
30096 : priv_(new priv)
30097{}
30098
30099ir_node_visitor::~ir_node_visitor() = default;
30100
30101/// Set if the walker using this visitor is allowed to re-visit a type
30102/// node that was previously visited or not.
30103///
30104/// @param f if true, then the walker using this visitor is allowed to
30105/// re-visit a type node that was previously visited.
30106void
30108{priv_->allow_visiting_already_visited_type_node = f;}
30109
30110/// Get if the walker using this visitor is allowed to re-visit a type
30111/// node that was previously visited or not.
30112///
30113/// @return true iff the walker using this visitor is allowed to
30114/// re-visit a type node that was previously visited.
30115bool
30117{return priv_->allow_visiting_already_visited_type_node;}
30118
30119/// Mark a given type node as having been visited.
30120///
30121/// Note that for this function to work, the type node must have been
30122/// canonicalized. Otherwise the process is aborted.
30123///
30124/// @param p the type to mark as having been visited.
30125void
30127{
30129 return;
30130
30131 if (p == 0 || type_node_has_been_visited(p))
30132 return;
30133
30134 type_base* canonical_type = p->get_naked_canonical_type();
30136 {
30137 ABG_ASSERT(!canonical_type);
30138 canonical_type = p;
30139 }
30140 ABG_ASSERT(canonical_type);
30141
30142 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
30143 priv_->visited_ir_nodes.insert(canonical_ptr_value);
30144}
30145
30146/// Un-mark all visited type nodes.
30147///
30148/// That is, no type node is going to be considered as having been
30149/// visited anymore.
30150///
30151/// In other words, after invoking this funciton,
30152/// ir_node_visitor::type_node_has_been_visited() is going to return
30153/// false on all type nodes.
30154void
30156{priv_->visited_ir_nodes.clear();}
30157
30158/// Test if a given type node has been marked as visited.
30159///
30160/// @param p the type node to consider.
30161///
30162/// @return true iff the type node @p p has been marked as visited by
30163/// the function ir_node_visitor::mark_type_node_as_visited.
30164bool
30166{
30168 return false;
30169
30170 if (p == 0)
30171 return false;
30172
30173 type_base *canonical_type = p->get_naked_canonical_type();
30175 {
30176 ABG_ASSERT(!canonical_type);
30177 canonical_type = p;
30178 }
30179 ABG_ASSERT(canonical_type);
30180
30181 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
30182 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
30183 if (it == priv_->visited_ir_nodes.end())
30184 return false;
30185
30186 return true;
30187}
30188
30189bool
30190ir_node_visitor::visit_begin(decl_base*)
30191{return true;}
30192
30193bool
30194ir_node_visitor::visit_end(decl_base*)
30195{return true;}
30196
30197bool
30198ir_node_visitor::visit_begin(scope_decl*)
30199{return true;}
30200
30201bool
30202ir_node_visitor::visit_end(scope_decl*)
30203{return true;}
30204
30205bool
30206ir_node_visitor::visit_begin(type_base*)
30207{return true;}
30208
30209bool
30210ir_node_visitor::visit_end(type_base*)
30211{return true;}
30212
30213bool
30214ir_node_visitor::visit_begin(scope_type_decl* t)
30215{return visit_begin(static_cast<type_base*>(t));}
30216
30217bool
30218ir_node_visitor::visit_end(scope_type_decl* t)
30219{return visit_end(static_cast<type_base*>(t));}
30220
30221bool
30222ir_node_visitor::visit_begin(type_decl* t)
30223{return visit_begin(static_cast<type_base*>(t));}
30224
30225bool
30226ir_node_visitor::visit_end(type_decl* t)
30227{return visit_end(static_cast<type_base*>(t));}
30228
30229bool
30230ir_node_visitor::visit_begin(namespace_decl* d)
30231{return visit_begin(static_cast<decl_base*>(d));}
30232
30233bool
30234ir_node_visitor::visit_end(namespace_decl* d)
30235{return visit_end(static_cast<decl_base*>(d));}
30236
30237bool
30238ir_node_visitor::visit_begin(qualified_type_def* t)
30239{return visit_begin(static_cast<type_base*>(t));}
30240
30241bool
30242ir_node_visitor::visit_end(qualified_type_def* t)
30243{return visit_end(static_cast<type_base*>(t));}
30244
30245bool
30246ir_node_visitor::visit_begin(pointer_type_def* t)
30247{return visit_begin(static_cast<type_base*>(t));}
30248
30249bool
30250ir_node_visitor::visit_end(pointer_type_def* t)
30251{return visit_end(static_cast<type_base*>(t));}
30252
30253bool
30254ir_node_visitor::visit_begin(reference_type_def* t)
30255{return visit_begin(static_cast<type_base*>(t));}
30256
30257bool
30258ir_node_visitor::visit_end(reference_type_def* t)
30259{return visit_end(static_cast<type_base*>(t));}
30260
30261bool
30262ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
30263{return visit_begin(static_cast<type_base*>(t));}
30264
30265bool
30266ir_node_visitor::visit_end(ptr_to_mbr_type* t)
30267{return visit_end(static_cast<type_base*>(t));}
30268
30269bool
30270ir_node_visitor::visit_begin(array_type_def* t)
30271{return visit_begin(static_cast<type_base*>(t));}
30272
30273bool
30274ir_node_visitor::visit_end(array_type_def* t)
30275{return visit_end(static_cast<type_base*>(t));}
30276
30277bool
30278ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
30279{return visit_begin(static_cast<type_base*>(t));}
30280
30281bool
30282ir_node_visitor::visit_end(array_type_def::subrange_type* t)
30283{return visit_end(static_cast<type_base*>(t));}
30284
30285bool
30286ir_node_visitor::visit_begin(enum_type_decl* t)
30287{return visit_begin(static_cast<type_base*>(t));}
30288
30289bool
30290ir_node_visitor::visit_end(enum_type_decl* t)
30291{return visit_end(static_cast<type_base*>(t));}
30292
30293bool
30294ir_node_visitor::visit_begin(typedef_decl* t)
30295{return visit_begin(static_cast<type_base*>(t));}
30296
30297bool
30298ir_node_visitor::visit_end(typedef_decl* t)
30299{return visit_end(static_cast<type_base*>(t));}
30300
30301bool
30302ir_node_visitor::visit_begin(function_type* t)
30303{return visit_begin(static_cast<type_base*>(t));}
30304
30305bool
30306ir_node_visitor::visit_end(function_type* t)
30307{return visit_end(static_cast<type_base*>(t));}
30308
30309bool
30310ir_node_visitor::visit_begin(var_decl* d)
30311{return visit_begin(static_cast<decl_base*>(d));}
30312
30313bool
30314ir_node_visitor::visit_end(var_decl* d)
30315{return visit_end(static_cast<decl_base*>(d));}
30316
30317bool
30318ir_node_visitor::visit_begin(function_decl* d)
30319{return visit_begin(static_cast<decl_base*>(d));}
30320
30321bool
30322ir_node_visitor::visit_end(function_decl* d)
30323{return visit_end(static_cast<decl_base*>(d));}
30324
30325bool
30326ir_node_visitor::visit_begin(function_decl::parameter* d)
30327{return visit_begin(static_cast<decl_base*>(d));}
30328
30329bool
30330ir_node_visitor::visit_end(function_decl::parameter* d)
30331{return visit_end(static_cast<decl_base*>(d));}
30332
30333bool
30334ir_node_visitor::visit_begin(function_tdecl* d)
30335{return visit_begin(static_cast<decl_base*>(d));}
30336
30337bool
30338ir_node_visitor::visit_end(function_tdecl* d)
30339{return visit_end(static_cast<decl_base*>(d));}
30340
30341bool
30342ir_node_visitor::visit_begin(class_tdecl* d)
30343{return visit_begin(static_cast<decl_base*>(d));}
30344
30345bool
30346ir_node_visitor::visit_end(class_tdecl* d)
30347{return visit_end(static_cast<decl_base*>(d));}
30348
30349bool
30350ir_node_visitor::visit_begin(class_or_union* t)
30351{return visit_begin(static_cast<type_base*>(t));}
30352
30353bool
30354ir_node_visitor::visit_end(class_or_union* t)
30355{return visit_end(static_cast<type_base*>(t));}
30356
30357bool
30358ir_node_visitor::visit_begin(class_decl* t)
30359{return visit_begin(static_cast<type_base*>(t));}
30360
30361bool
30362ir_node_visitor::visit_end(class_decl* t)
30363{return visit_end(static_cast<type_base*>(t));}
30364
30365bool
30366ir_node_visitor::visit_begin(union_decl* t)
30367{return visit_begin(static_cast<type_base*>(t));}
30368
30369bool
30370ir_node_visitor::visit_end(union_decl* t)
30371{return visit_end(static_cast<type_base*>(t));}
30372
30373bool
30374ir_node_visitor::visit_begin(class_decl::base_spec* d)
30375{return visit_begin(static_cast<decl_base*>(d));}
30376
30377bool
30378ir_node_visitor::visit_end(class_decl::base_spec* d)
30379{return visit_end(static_cast<decl_base*>(d));}
30380
30381bool
30382ir_node_visitor::visit_begin(member_function_template* d)
30383{return visit_begin(static_cast<decl_base*>(d));}
30384
30385bool
30386ir_node_visitor::visit_end(member_function_template* d)
30387{return visit_end(static_cast<decl_base*>(d));}
30388
30389bool
30390ir_node_visitor::visit_begin(member_class_template* d)
30391{return visit_begin(static_cast<decl_base*>(d));}
30392
30393bool
30394ir_node_visitor::visit_end(member_class_template* d)
30395{return visit_end(static_cast<decl_base*>(d));}
30396
30397// </ir_node_visitor stuff>
30398
30399// <debugging facilities>
30400
30401/// Generate a different string at each invocation.
30402///
30403/// @return the resulting string.
30404static string
30405get_next_string()
30406{
30407 static __thread size_t counter;
30408 ++counter;
30409 std::ostringstream o;
30410 o << counter;
30411 return o.str();
30412}
30413
30414/// A hashing functor for a @ref function_decl
30415struct function_decl_hash
30416{
30417 size_t operator()(const function_decl* f) const
30418 {return reinterpret_cast<size_t>(f);}
30419
30420 size_t operator()(const function_decl_sptr& f) const
30421 {return operator()(f.get());}
30422};
30423
30424/// Convenience typedef for a hash map of pointer to function_decl and
30425/// string.
30426typedef unordered_map<const function_decl*, string,
30427 function_decl_hash,
30429
30430/// Return a string associated to a given function. Two functions
30431/// that compare equal would yield the same string, as far as this
30432/// routine is concerned. And two functions that are different would
30433/// yield different strings.
30434///
30435/// This is used to debug core diffing issues on functions. The
30436/// sequence of strings can be given to the 'testdiff2' program that
30437/// is in the tests/ directory of the source tree, to reproduce core
30438/// diffing issues on string and thus ease the debugging.
30439///
30440/// @param fn the function to generate a string for.
30441///
30442/// @param m the function_decl* <-> string map to be used by this
30443/// function to generate strings associated to a function.
30444///
30445/// @return the resulting string.
30446static const string&
30447fn_to_str(const function_decl* fn,
30449{
30450 fns_to_str_map_type::const_iterator i = m.find(fn);
30451 if (i != m.end())
30452 return i->second;
30453 string s = get_next_string();
30454 return m[fn]= s;
30455}
30456
30457/// Generate a sequence of string that matches a given sequence of
30458/// function. In the resulting sequence, each function is "uniquely
30459/// representated" by a string. For instance, if the same function "foo"
30460/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
30461/// we don't care about the actual string) would appear at index 1 and 3.
30462///
30463/// @param begin the beginning of the sequence of functions to consider.
30464///
30465/// @param end the end of the sequence of functions. This points to
30466/// one-passed-the-end of the actual sequence.
30467///
30468/// @param m the function_decl* <-> string map to be used by this
30469/// function to generate strings associated to a function.
30470///
30471/// @param o the output stream where to emit the generated list of
30472/// strings to.
30473static void
30474fns_to_str(vector<function_decl*>::const_iterator begin,
30475 vector<function_decl*>::const_iterator end,
30477 std::ostream& o)
30478{
30479 vector<function_decl*>::const_iterator i;
30480 for (i = begin; i != end; ++i)
30481 o << "'" << fn_to_str(*i, m) << "' ";
30482}
30483
30484/// For each sequence of functions given in argument, generate a
30485/// sequence of string that matches a given sequence of function. In
30486/// the resulting sequence, each function is "uniquely representated"
30487/// by a string. For instance, if the same function "foo" appears at
30488/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30489/// care about the actual string) would appear at index 1 and 3.
30490///
30491/// @param a_begin the beginning of the sequence of functions to consider.
30492///
30493/// @param a_end the end of the sequence of functions. This points to
30494/// one-passed-the-end of the actual sequence.
30495///
30496/// @param b_begin the beginning of the second sequence of functions
30497/// to consider.
30498///
30499/// @param b_end the end of the second sequence of functions.
30500///
30501/// @param m the function_decl* <-> string map to be used by this
30502/// function to generate strings associated to a function.
30503///
30504/// @param o the output stream where to emit the generated list of
30505/// strings to.
30506static void
30507fns_to_str(vector<function_decl*>::const_iterator a_begin,
30508 vector<function_decl*>::const_iterator a_end,
30509 vector<function_decl*>::const_iterator b_begin,
30510 vector<function_decl*>::const_iterator b_end,
30512 std::ostream& o)
30513{
30514 fns_to_str(a_begin, a_end, m, o);
30515 o << "->|<- ";
30516 fns_to_str(b_begin, b_end, m, o);
30517 o << "\n";
30518}
30519
30520/// For each sequence of functions given in argument, generate a
30521/// sequence of string that matches a given sequence of function. In
30522/// the resulting sequence, each function is "uniquely representated"
30523/// by a string. For instance, if the same function "foo" appears at
30524/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30525/// care about the actual string) would appear at index 1 and 3.
30526///
30527/// @param a_begin the beginning of the sequence of functions to consider.
30528///
30529/// @param a_end the end of the sequence of functions. This points to
30530/// one-passed-the-end of the actual sequence.
30531///
30532/// @param b_begin the beginning of the second sequence of functions
30533/// to consider.
30534///
30535/// @param b_end the end of the second sequence of functions.
30536///
30537/// @param o the output stream where to emit the generated list of
30538/// strings to.
30539void
30540fns_to_str(vector<function_decl*>::const_iterator a_begin,
30541 vector<function_decl*>::const_iterator a_end,
30542 vector<function_decl*>::const_iterator b_begin,
30543 vector<function_decl*>::const_iterator b_end,
30544 std::ostream& o)
30545{
30547 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
30548}
30549
30550// </debugging facilities>
30551
30552// </class template>
30553
30554}// end namespace ir
30555}//end namespace abigail
30556
30557namespace
30558{
30559
30560/// Update the qualified parent name, qualified name and scoped name
30561/// of a tree decl node.
30562///
30563/// @return true if the tree walking should continue, false otherwise.
30564///
30565/// @param d the tree node to take in account.
30566bool
30567qualified_name_setter::do_update(abigail::ir::decl_base* d)
30568{
30569 std::string parent_qualified_name;
30570 abigail::ir::scope_decl* parent = d->get_scope();
30571 if (parent)
30572 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
30573 else
30574 d->priv_->qualified_parent_name_ = abigail::interned_string();
30575
30576 const abigail::ir::environment& env = d->get_environment();
30577
30578 if (!d->priv_->qualified_parent_name_.empty())
30579 {
30580 if (d->get_name().empty())
30581 d->priv_->qualified_name_ = abigail::interned_string();
30582 else
30583 {
30584 d->priv_->qualified_name_ =
30585 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
30586 d->priv_->internal_qualified_name_ = env.intern(d->get_name());
30587 }
30588 }
30589 // Make sure the internal qualified name (used for type
30590 // canonicalization puroses) is always the qualified name. For
30591 // integral/real types however, only the non qualified type is used.
30592 if (!is_integral_type(d))
30593 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
30594
30595 if (d->priv_->scoped_name_.empty())
30596 {
30597 if (parent
30598 && !parent->get_is_anonymous()
30599 && !parent->get_name().empty())
30600 d->priv_->scoped_name_ =
30601 env.intern(parent->get_name() + "::" + d->get_name());
30602 else
30603 d->priv_->scoped_name_ =
30604 env.intern(d->get_name());
30605 }
30606
30607 if (!is_scope_decl(d))
30608 return false;
30609
30610 return true;
30611}
30612
30613/// This is called when we start visiting a decl node, during the
30614/// udpate of the qualified name of a given sub-tree.
30615///
30616/// @param d the decl node we are visiting.
30617///
30618/// @return true iff the traversal should keep going.
30619bool
30620qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
30621{return do_update(d);}
30622
30623/// This is called when we start visiting a type node, during the
30624/// udpate of the qualified name of a given sub-tree.
30625///
30626/// @param d the decl node we are visiting.
30627///
30628/// @return true iff the traversal should keep going.
30629bool
30630qualified_name_setter::visit_begin(abigail::ir::type_base* t)
30631{
30633 return do_update(d);
30634 return false;
30635}
30636}// 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:19244
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:19212
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:19205
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition: abg-ir.cc:19219
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition: abg-ir.cc:19256
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition: abg-ir.cc:19227
bound_value()
Default constructor of the array_type_def::subrange_type::bound_value class.
Definition: abg-ir.cc:19177
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition: abg-ir.cc:19234
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:19435
bool is_non_finite() const
Test if the length of the subrange type is infinite.
Definition: abg-ir.cc:19462
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition: abg-ir.cc:19428
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:19402
string as_string() const
Return a string representation of the sub range.
Definition: abg-ir.cc:19484
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:19383
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19684
bool operator!=(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:19623
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition: abg-ir.cc:19414
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:19394
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:19579
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition: abg-ir.cc:19421
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:19662
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition: abg-ir.cc:19507
uint64_t get_length() const
Getter of the length of the subrange type.
Definition: abg-ir.cc:19445
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition: abg-ir.cc:19477
The abstraction of an array type.
Definition: abg-ir.h:2548
virtual bool is_non_finite() const
Definition: abg-ir.cc:20101
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:20131
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:19791
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition: abg-ir.cc:20062
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition: abg-ir.cc:20077
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:20194
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition: abg-ir.cc:20221
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:20040
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:19844
translation_unit::language get_language() const
Get the language of the array.
Definition: abg-ir.cc:20029
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition: abg-ir.cc:20087
Abstraction of a base specifier in a class declaration.
Definition: abg-ir.h:4362
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
Definition: abg-ir.cc:25361
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition: abg-ir.cc:25368
long get_offset_in_bits() const
Getter of the offset of the base.
Definition: abg-ir.cc:25375
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:25350
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:25391
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Definition: abg-ir.cc:25485
Abstracts a class declaration.
Definition: abg-ir.h:4175
void is_struct(bool f)
Set the "is-struct" flag of the class.
Definition: abg-ir.cc:25158
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition: abg-ir.cc:25941
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:25227
bool is_struct() const
Test if the class is a struct.
Definition: abg-ir.cc:25165
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:26004
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition: abg-ir.cc:25182
virtual ~class_decl()
Destructor of the class_decl type.
Definition: abg-ir.cc:26518
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:25143
bool has_vtable() const
Test if the current instance has a vtable.
Definition: abg-ir.cc:25969
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition: abg-ir.cc:25983
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition: abg-ir.cc:25950
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26434
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition: abg-ir.h:4193
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
Definition: abg-ir.cc:25172
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition: abg-ir.cc:25208
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition: abg-ir.cc:25232
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition: abg-ir.cc:26102
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition: abg-ir.cc:26282
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:25192
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition: abg-ir.cc:25932
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition: abg-ir.h:4194
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Getter of the pretty representation of the current instance of class_decl.
Definition: abg-ir.cc:25253
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:24100
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:24341
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:24266
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition: abg-ir.cc:24369
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
Definition: abg-ir.cc:23986
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition: abg-ir.cc:24445
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition: abg-ir.cc:24085
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition: abg-ir.cc:24118
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
Definition: abg-ir.cc:24459
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:24225
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:23876
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:24167
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:24420
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:24404
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition: abg-ir.cc:24069
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
Definition: abg-ir.cc:24501
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:23974
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:23892
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition: abg-ir.cc:24473
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
Definition: abg-ir.cc:24316
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:24378
const data_members & get_static_data_members() const
Get the static data memebers of this class_or_union.
Definition: abg-ir.cc:24324
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:24011
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:23965
bool has_no_member() const
Definition: abg-ir.cc:24486
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:24535
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26821
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition: abg-ir.cc:24037
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition: abg-ir.cc:24452
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition: abg-ir.cc:24053
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:24136
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:24236
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:28213
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
Definition: abg-ir.cc:28202
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:28262
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:28217
The abstraction of the relationship between an entity and its containing scope (its context)....
Definition: abg-ir.h:1285
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition: abg-corpus.h:25
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr<exported_decls_builder>.
Definition: abg-corpus.h:45
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
Definition: abg-corpus.cc:745
origin get_origin() const
Getter for the origin of the corpus.
Definition: abg-corpus.cc:930
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
Definition: abg-corpus.cc:777
type_maps & get_type_per_loc_map()
Get the maps that associate a location string to a certain kind of type.
Definition: abg-corpus.cc:886
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
Definition: abg-corpus.cc:894
const environment & get_environment() const
Getter of the enviroment of the corpus.
Definition: abg-corpus.cc:703
The base type of all declarations.
Definition: abg-ir.h:1585
void set_definition_of_declaration(const decl_base_sptr &)
Set the definition of this declaration-only decl_base.
Definition: abg-ir.cc:16322
void set_is_declaration_only(bool f)
Set a flag saying if the enum_type_decl is a declaration-only enum_type_decl.
Definition: abg-ir.cc:5005
virtual bool operator!=(const decl_base &) const
Inequality operator.
Definition: abg-ir.cc:5220
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current decl.
Definition: abg-ir.cc:4894
scope_decl * get_scope() const
Return the type containing the current decl, if any.
Definition: abg-ir.cc:4792
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
Definition: abg-ir.cc:4523
void set_is_in_public_symbol_table(bool)
Set the flag saying if this decl is from a symbol that is in a public symbols table,...
Definition: abg-ir.cc:4585
friend bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
Definition: abg-ir.cc:5575
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
Definition: abg-ir.cc:4953
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
Definition: abg-ir.cc:4767
const decl_base * get_naked_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
Definition: abg-ir.cc:4989
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition: abg-ir.cc:4823
void clear_qualified_name()
Clear the qualified name of this decl.
Definition: abg-ir.cc:4516
virtual void set_name(const string &n)
Setter for the name of the decl.
Definition: abg-ir.cc:4655
const location & get_location() const
Get the location of a given declaration.
Definition: abg-ir.cc:4605
binding
ELF binding.
Definition: abg-ir.h:1636
typedef_decl_sptr get_naming_typedef() const
Getter for the naming typedef of the current decl.
Definition: abg-ir.cc:4715
virtual const interned_string & get_name() const
Getter for the name of the current decl.
Definition: abg-ir.cc:4811
virtual void set_scope(scope_decl *)
Setter of the scope of the current decl.
Definition: abg-ir.cc:5247
const interned_string & peek_qualified_name() const
Getter for the qualified name.
Definition: abg-ir.cc:4507
const context_rel * get_context_rel() const
Getter for the context relationship.
Definition: abg-ir.cc:4557
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Definition: abg-ir.cc:4668
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scpe)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition: abg-ir.cc:8450
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
Definition: abg-ir.cc:4945
const decl_base_sptr get_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
Definition: abg-ir.cc:4973
friend void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5544
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
Definition: abg-ir.cc:4733
void set_location(const location &l)
Set the location for a given declaration.
Definition: abg-ir.cc:4643
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
Definition: abg-ir.cc:4678
void set_visibility(visibility v)
Setter for the visibility of the decl.
Definition: abg-ir.cc:4784
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4550
visibility get_visibility() const
Getter for the visibility of the decl.
Definition: abg-ir.cc:4777
visibility
ELF visibility.
Definition: abg-ir.h:1626
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Definition: abg-ir.cc:4996
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:5236
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition: abg-ir.cc:4961
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition: abg-ir.cc:4760
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5515
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6641
virtual ~decl_base()
Destructor of the decl_base type.
Definition: abg-ir.cc:5224
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:5209
const interned_string & get_qualified_parent_name() const
Return a copy of the qualified name of the parent of the current decl.
Definition: abg-ir.cc:4804
bool get_is_anonymous_or_has_anonymous_parent() const
Definition: abg-ir.cc:4701
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
Definition: abg-ir.cc:4690
bool get_is_in_public_symbol_table() const
Test if the decl is defined in a ELF symbol table as a public symbol.
Definition: abg-ir.cc:4577
friend bool equals(const decl_base &, const decl_base &, change_kind *)
Compares two instances of decl_base.
Definition: abg-ir.cc:5138
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4536
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representatin of the current declaration.
Definition: abg-ir.cc:4846
The abstraction for a data member context relationship. This relates a data member to its parent clas...
Definition: abg-ir.h:3003
const var_decl * get_anonymous_data_member() const
Return a non-nil value if this data member context relationship has an anonymous data member....
Definition: abg-ir.cc:3344
void set_anonymous_data_member(var_decl *)
Set the containing anonymous data member of this data member context relationship....
Definition: abg-ir.cc:3354
The abstraction of the version of an ELF symbol.
Definition: abg-ir.h:1232
version & operator=(const version &o)
Assign a version to the current one.
Definition: abg-ir.cc:3257
bool operator==(const version &o) const
Compares the current version against another one.
Definition: abg-ir.cc:3239
bool is_default() const
Getter for the 'is_default' property of the version.
Definition: abg-ir.cc:3219
const string & str() const
Getter for the version name.
Definition: abg-ir.cc:3205
bool operator!=(const version &o) const
Inequality operator.
Definition: abg-ir.cc:3248
Abstraction of an elf symbol.
Definition: abg-ir.h:961
const abg_compat::optional< std::string > & get_namespace() const
Getter of the 'namespace' property.
Definition: abg-ir.cc:2342
elf_symbol_sptr get_alias_which_equals(const elf_symbol &other) const
In the list of aliases of a given elf symbol, get the alias that equals this current symbol.
Definition: abg-ir.cc:2665
elf_symbol_sptr get_next_common_instance() const
Get the next common instance of the current common symbol.
Definition: abg-ir.cc:2560
type get_type() const
Getter for the type of the current instance of elf_symbol.
Definition: abg-ir.cc:2176
const elf_symbol_sptr get_main_symbol() const
Get the main symbol of an alias chain.
Definition: abg-ir.cc:2397
void set_is_in_ksymtab(bool is_in_ksymtab)
Setter of the 'is-in-ksymtab' property.
Definition: abg-ir.cc:2321
bool has_aliases() const
Check if the current elf_symbol has an alias.
Definition: abg-ir.cc:2426
void set_name(const string &n)
Setter for the name of the current intance of elf_symbol.
Definition: abg-ir.cc:2166
bool is_suppressed() const
Getter for the 'is-suppressed' property.
Definition: abg-ir.cc:2358
binding
The binding of a symbol.
Definition: abg-ir.h:978
int get_number_of_aliases() const
Get the number of aliases to this elf symbol.
Definition: abg-ir.cc:2433
string get_aliases_id_string(const string_elf_symbols_map_type &symtab, bool include_symbol_itself=true) const
Return a comma separated list of the id of the current symbol as well as the id string of its aliases...
Definition: abg-ir.cc:2686
void set_binding(binding b)
Setter for the binding of the current instance of elf_symbol.
Definition: abg-ir.cc:2211
void add_common_instance(const elf_symbol_sptr &)
Add a common instance to the current common elf symbol.
Definition: abg-ir.cc:2571
void add_alias(const elf_symbol_sptr &)
Add an alias to the current elf symbol.
Definition: abg-ir.cc:2450
void set_is_suppressed(bool is_suppressed)
Setter for the 'is-suppressed' property.
Definition: abg-ir.cc:2367
bool is_variable() const
Test if the current instance of elf_symbol is a variable symbol or not.
Definition: abg-ir.cc:2299
elf_symbol_sptr update_main_symbol(const std::string &)
Update the main symbol for a group of aliased symbols.
Definition: abg-ir.cc:2496
void set_size(size_t)
Setter of the size of the symbol.
Definition: abg-ir.cc:2197
const string & get_name() const
Getter for the name of the elf_symbol.
Definition: abg-ir.cc:2159
binding get_binding() const
Getter for the binding of the current instance of elf_symbol.
Definition: abg-ir.cc:2204
static bool get_name_and_version_from_id(const string &id, string &name, string &ver)
Given the ID of a symbol, get the name and the version of said symbol.
Definition: abg-ir.cc:2752
bool is_function() const
Test if the current instance of elf_symbol is a function symbol or not.
Definition: abg-ir.cc:2290
type
The type of a symbol.
Definition: abg-ir.h:965
void set_version(const version &v)
Setter for the version of the current instance of elf_symbol.
Definition: abg-ir.cc:2225
const abg_compat::optional< uint32_t > & get_crc() const
Getter of the 'crc' property.
Definition: abg-ir.cc:2328
void set_visibility(visibility v)
Setter of the visibility of the current instance of elf_symbol.
Definition: abg-ir.cc:2236
bool does_alias(const elf_symbol &) const
Test if the current symbol aliases another one.
Definition: abg-ir.cc:2811
bool is_main_symbol() const
Tests whether this symbol is the main symbol.
Definition: abg-ir.cc:2411
void set_crc(const abg_compat::optional< uint32_t > &crc)
Setter of the 'crc' property.
Definition: abg-ir.cc:2335
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
Definition: abg-ir.cc:2063
visibility
The visibility of the symbol.
Definition: abg-ir.h:987
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition: abg-ir.cc:2218
bool is_common_symbol() const
Return true if the symbol is a common one.
Definition: abg-ir.cc:2529
void set_index(size_t)
Setter for the index.
Definition: abg-ir.cc:2152
visibility get_visibility() const
Getter of the visibility of the current instance of elf_symbol.
Definition: abg-ir.cc:2244
bool has_other_common_instances() const
Return true if this common common symbol has other common instances.
Definition: abg-ir.cc:2545
size_t get_index() const
Getter for the index.
Definition: abg-ir.cc:2145
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
Definition: abg-ir.cc:2616
elf_symbol_sptr get_alias_from_name(const string &name) const
From the aliases of the current symbol, lookup one with a given name.
Definition: abg-ir.cc:2643
const environment & get_environment() const
Getter of the environment used by the current instance of elf_symbol.
Definition: abg-ir.cc:2138
void set_type(type t)
Setter for the type of the current instance of elf_symbol.
Definition: abg-ir.cc:2183
bool is_public() const
Test if the current instance of elf_symbol is public or not.
Definition: abg-ir.cc:2274
bool is_in_ksymtab() const
Getter of the 'is-in-ksymtab' property.
Definition: abg-ir.cc:2313
size_t get_size() const
Getter of the size of the symbol.
Definition: abg-ir.cc:2190
bool is_defined() const
Test if the current instance of elf_symbol is defined or not.
Definition: abg-ir.cc:2252
void set_namespace(const abg_compat::optional< std::string > &ns)
Setter of the 'namespace' property.
Definition: abg-ir.cc:2349
elf_symbol_sptr get_next_alias() const
Get the next alias of the current symbol.
Definition: abg-ir.cc:2418
bool operator==(const elf_symbol &) const
Test if two main symbols are textually equal, or, if they have aliases that are textually equal.
Definition: abg-ir.cc:2797
The abstraction of an enumerator.
Definition: abg-ir.h:2881
enumerator()
Default constructor of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:20904
bool operator!=(const enumerator &other) const
Inequality operator.
Definition: abg-ir.cc:20964
void set_name(const string &n)
Setter for the name of enum_type_decl::enumerator.
Definition: abg-ir.cc:21006
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition: abg-ir.cc:21028
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition: abg-ir.cc:20973
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition: abg-ir.cc:21035
void set_value(int64_t v)
Setter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:21021
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:20990
int64_t get_value() const
Getter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:21014
bool operator==(const enumerator &other) const
Equality operator.
Definition: abg-ir.cc:20951
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:20935
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:20294
virtual ~enum_type_decl()
Destructor for the enum type declaration.
Definition: abg-ir.cc:20455
const enumerators & get_enumerators() const
Definition: abg-ir.cc:20307
bool find_enumerator_by_value(int64_t value, enum_type_decl::enumerator &result)
Find an enumerator by its value.
Definition: abg-ir.cc:20353
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
Definition: abg-ir.cc:20319
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:20433
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition: abg-ir.cc:20302
bool find_enumerator_by_name(const string &name, enum_type_decl::enumerator &result)
Find an enumerator by its name.
Definition: abg-ir.cc:20377
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:20825
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:20408
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition: abg-ir.h:148
bool decl_only_class_equals_definition() const
Getter of the "decl-only-class-equals-definition" flag.
Definition: abg-ir.cc:3591
bool is_void_pointer_type(const type_base_sptr &) const
Test if a given type is the same as the void pointer type of the environment.
Definition: abg-ir.cc:3658
std::unordered_map< string, std::vector< type_base_sptr > > canonical_types_map_type
A convenience typedef for a map of canonical types. The key is the pretty representation string of a ...
Definition: abg-ir.h:158
bool user_set_analyze_exported_interfaces_only() const
Getter for a property that says if the user actually did set the analyze_exported_interfaces_only() p...
Definition: abg-ir.cc:3738
const vector< type_base_sptr > * get_canonical_types(const char *name) const
Get the vector of canonical types which have a given "string representation".
Definition: abg-ir.cc:3875
const type_base_sptr & get_void_type() const
Get the unique type_decl that represents a "void" type for the current environment....
Definition: abg-ir.cc:3468
bool is_variadic_parameter_type(const type_base *) const
Test if a type is a variadic parameter type as defined in the current environment.
Definition: abg-ir.cc:3690
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
Definition: abg-ir.cc:3519
const type_base_sptr & get_void_pointer_type() const
Getter of the "pointer-to-void" IR node that is shared across the ABI corpus. This node must be the o...
Definition: abg-ir.cc:3487
const config & get_config() const
Getter of the general configuration object.
Definition: abg-ir.cc:3728
environment()
Default constructor of the environment type.
Definition: abg-ir.cc:3369
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition: abg-ir.cc:3531
type_base * get_canonical_type(const char *name, unsigned index)
Get a given canonical type which has a given "string representation".
Definition: abg-ir.cc:3898
const type_base_sptr & get_variadic_parameter_type() const
Get a type_decl instance that represents a the type of a variadic function parameter....
Definition: abg-ir.cc:3506
bool is_void_type(const type_base_sptr &) const
Test if a given type is a void type as defined in the current environment.
Definition: abg-ir.cc:3627
virtual ~environment()
Destructor for the environment type.
Definition: abg-ir.cc:3374
bool canonicalization_started() const
Getter of a flag saying if the canonicalization process has started or not.
Definition: abg-ir.cc:3558
interned_string intern(const string &) const
Do intern a string.
Definition: abg-ir.cc:3721
bool analyze_exported_interfaces_only() const
Getter for the property that controls if we are to restrict the analysis to the types that are only r...
Definition: abg-ir.cc:3764
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Definition: abg-ir.cc:3382
Abstraction of a function parameter.
Definition: abg-ir.h:3335
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
Definition: abg-ir.cc:23710
interned_string get_type_name() const
Definition: abg-ir.cc:23509
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition: abg-ir.cc:23547
const string get_type_pretty_representation() const
Definition: abg-ir.cc:23528
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition: abg-ir.cc:23686
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:23730
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:22910
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition: abg-ir.cc:22981
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:23371
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition: abg-ir.cc:23061
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition: abg-ir.cc:23286
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition: abg-ir.cc:22947
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition: abg-ir.cc:22966
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:22773
const type_base_sptr get_return_type() const
Definition: abg-ir.cc:23042
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition: abg-ir.cc:23074
const std::vector< parameter_sptr > & get_parameters() const
Definition: abg-ir.cc:23047
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition: abg-ir.cc:23054
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition: abg-ir.cc:23003
virtual ~function_decl()
Destructor of the function_decl type.
Definition: abg-ir.cc:23387
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:23019
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition: abg-ir.cc:23272
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:23026
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:22842
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:23302
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:28050
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
Definition: abg-ir.cc:28032
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition: abg-ir.cc:28043
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:28110
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition: abg-ir.cc:28059
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:22015
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:22434
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition: abg-ir.cc:22122
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:22331
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:21922
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition: abg-ir.cc:22393
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:22107
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition: abg-ir.cc:22084
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition: abg-ir.cc:22351
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:22063
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition: abg-ir.cc:22026
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition: abg-ir.cc:22034
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:22309
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition: abg-ir.cc:22043
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:22417
This abstracts the global scope of a given translation unit.
Definition: abg-ir.h:1982
The base class for the visitor type hierarchy used for traversing a translation unit.
Definition: abg-ir.h:4809
bool allow_visiting_already_visited_type_node() const
Get if the walker using this visitor is allowed to re-visit a type node that was previously visited o...
Definition: abg-ir.cc:30116
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition: abg-ir.cc:30165
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition: abg-ir.cc:30155
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition: abg-ir.cc:30095
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition: abg-ir.cc:30126
The entry point to manage locations.
Definition: abg-ir.h:449
location create_new_location(const std::string &fle, size_t lne, size_t col)
Insert the triplet representing a source locus into our internal vector of location triplet....
Definition: abg-ir.cc:507
void expand_location(const location &location, std::string &path, unsigned &line, unsigned &column) const
Given an instance of location type, return the triplet {path,line,column} that represents the source ...
Definition: abg-ir.cc:530
The source location of a token.
Definition: abg-ir.h:307
bool get_is_artificial() const
Test if the location is artificial.
Definition: abg-ir.h:348
unsigned get_value() const
Get the value of the location.
Definition: abg-ir.h:395
string expand(void) const
Expand the location into a string.
Definition: abg-ir.cc:472
void expand(std::string &path, unsigned &line, unsigned &column) const
Expand the current location into a tripplet file path, line and column number.
Definition: abg-ir.cc:452
Abstraction of a member function context relationship. This relates a member function to its parent c...
Definition: abg-ir.h:4495
bool is_constructor() const
Getter for the 'is-constructor' property.
Definition: abg-ir.h:4573
bool is_const() const
Getter for the 'is-const' property.
Definition: abg-ir.h:4608
size_t vtable_offset() const
Getter for the vtable offset property.
Definition: abg-ir.h:4553
bool is_destructor() const
Getter for the 'is-destructor' property.
Definition: abg-ir.h:4590
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition: abg-ir.h:3839
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition: abg-ir.h:3859
bool get_is_static() const
Definition: abg-ir.h:3871
Abstracts a member class template template.
Definition: abg-ir.h:4700
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
Definition: abg-ir.cc:26681
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26766
Abstract a member function template.
Definition: abg-ir.h:4645
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26660
Abstraction of the declaration of a method.
Definition: abg-ir.h:3887
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
Definition: abg-ir.cc:6538
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
Definition: abg-ir.cc:25632
const method_type_sptr get_type() const
Definition: abg-ir.cc:25659
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:22635
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:22616
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition: abg-ir.cc:22667
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
Definition: abg-ir.cc:22682
virtual ~method_type()
The destructor of method_type.
Definition: abg-ir.cc:22715
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:22659
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition: abg-ir.cc:22626
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition: abg-ir.cc:22674
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:17443
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17474
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition: abg-ir.cc:17377
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition: abg-ir.cc:17429
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:17415
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:27748
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:27753
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:18136
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:18262
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18126
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:18053
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18356
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition: abg-ir.cc:18198
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition: abg-ir.cc:18242
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition: abg-ir.cc:18249
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:19026
virtual const interned_string & get_name() const
Getter of the name of the current ptr-to-mbr-type.
Definition: abg-ir.cc:18936
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18949
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:18969
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
Definition: abg-ir.cc:19010
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:19077
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
Definition: abg-ir.cc:18960
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
Definition: abg-ir.cc:19102
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:17779
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition: abg-ir.cc:17904
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition: abg-ir.cc:17643
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:17631
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:17892
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:17569
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition: abg-ir.cc:17883
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17852
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition: abg-ir.cc:17878
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition: abg-ir.cc:17897
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition: abg-ir.cc:17723
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition: abg-ir.cc:17546
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:16819
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
Definition: abg-ir.cc:16842
base_type get_base_type() const
Getter of the base type of the real_type.
Definition: abg-ir.cc:16805
bool operator==(const real_type &) const
Equality operator for the real_type.
Definition: abg-ir.cc:16829
real_type()
Default constructor of the real_type.
Definition: abg-ir.cc:16775
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.
Definition: abg-ir-priv.h:100
@ 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:16812
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:18685
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18548
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:18450
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18807
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:18558
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition: abg-ir.cc:18627
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:18786
A declaration that introduces a scope.
Definition: abg-ir.h:1853
virtual size_t get_num_anonymous_member_classes() const
Getter for the number of anonymous classes contained in this scope.
Definition: abg-ir.cc:7921
void remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
Definition: abg-ir.cc:8130
void insert_member_type(type_base_sptr t, declarations::iterator before)
Insert a member type.
Definition: abg-ir.cc:8088
void add_member_type(type_base_sptr t)
Add a member type to the current instance of class_or_union.
Definition: abg-ir.cc:8105
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
Definition: abg-ir.cc:7939
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
Definition: abg-ir.cc:7974
std::vector< scope_decl_sptr > scopes
Convenience typedef for a vector of scope_decl_sptr.
Definition: abg-ir.h:1864
bool is_empty() const
Test if the current scope is empty.
Definition: abg-ir.cc:7988
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:8420
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
Definition: abg-ir.cc:8063
decl_base_sptr insert_member_decl(decl_base_sptr member, declarations::iterator before)
Insert a member decl to this scope, right before an element pointed to by a given iterator....
Definition: abg-ir.cc:8198
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
Definition: abg-ir.h:1860
const type_base_sptrs_type & get_sorted_canonical_types() const
Return a vector of sorted canonical types of the current scope.
Definition: abg-ir.cc:7857
bool find_iterator_for_member(const decl_base *, declarations::iterator &)
Find a member of the current scope and return an iterator on it.
Definition: abg-ir.cc:8372
virtual void remove_member_decl(decl_base_sptr member)
Remove a declaration from the current scope.
Definition: abg-ir.cc:8223
virtual decl_base_sptr add_member_decl(const decl_base_sptr &member)
Add a member decl to this scope. Note that user code should not use this, but rather use add_decl_to_...
Definition: abg-ir.cc:8034
type_base_sptr find_member_type(const string &name) const
Find a member type of a given name, inside the current scope_decl.
Definition: abg-ir.cc:8074
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7881
const canonical_type_sptr_set_type & get_canonical_types() const
@eturn the set of canonical types of the the current scope.
Definition: abg-ir.cc:7845
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
Definition: abg-ir.cc:8149
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition: abg-ir.cc:8450
virtual bool operator==(const decl_base &) const
Return true iff both scopes have the same names and have the same member decls.
Definition: abg-ir.cc:8326
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7899
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
Definition: abg-ir.cc:7957
A type that introduces a scope.
Definition: abg-ir.h:2184
virtual bool traverse(ir_node_visitor &)
Traverses an instance of scope_type_decl, visiting all the sub-types and decls that it might contain.
Definition: abg-ir.cc:17336
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition: abg-ir.cc:17298
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:27423
virtual ~template_decl()
Destructor.
Definition: abg-ir.cc:27448
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:27415
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:27457
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:27577
bool operator!=(const template_parameter &) const
Inequality operator.
Definition: abg-ir.cc:27573
Abstracts a template template parameter.
Definition: abg-ir.h:3695
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:27826
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
Definition: abg-ir.h:695
void set_address_size(char)
Setter of the address size in this translation unit.
Definition: abg-ir.cc:1426
const std::string & get_absolute_path() const
Get the concatenation of the build directory and the relative path of the translation unit.
Definition: abg-ir.cc:1341
void set_is_constructed(bool)
Setter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
Definition: abg-ir.cc:1458
bool operator==(const translation_unit &) const
Compare the current translation unit against another one.
Definition: abg-ir.cc:1468
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
Definition: abg-ir.cc:1384
char get_address_size() const
Getter of the address size in this translation unit.
Definition: abg-ir.cc:1419
const std::string & get_compilation_dir_path() const
Get the path of the directory that was 'current' when the translation unit was compiled.
Definition: abg-ir.cc:1322
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
Definition: abg-ir.cc:1368
void set_language(language l)
Setter of the language of the source code of the translation unit.
Definition: abg-ir.cc:1285
void bind_function_type_life_time(function_type_sptr) const
Ensure that the life time of a function type is bound to the life time of the current translation uni...
Definition: abg-ir.cc:1494
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
Definition: abg-ir.cc:1221
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
Definition: abg-ir.cc:1408
bool is_constructed() const
Getter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
Definition: abg-ir.cc:1442
const std::string & get_path() const
Get the path of the current translation unit.
Definition: abg-ir.cc:1298
void set_compilation_dir_path(const std::string &)
Set the path of the directory that was 'current' when the translation unit was compiled.
Definition: abg-ir.cc:1333
location_manager & get_loc_mgr()
Getter of the location manager for the current translation unit.
Definition: abg-ir.cc:1392
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
Definition: abg-ir.cc:1309
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse virtual function.
Definition: abg-ir.cc:1528
language
The language of the translation unit.
Definition: abg-ir.h:708
bool operator!=(const translation_unit &) const
Inequality operator.
Definition: abg-ir.cc:1483
const vector< function_type_sptr > & get_live_fn_types() const
Get the vector of function types that are used in the current translation unit.
Definition: abg-ir.cc:1264
const environment & get_environment() const
Getter of the environment of the current translation_unit.
Definition: abg-ir.cc:1271
const type_maps & get_types() const
Getter of the types of the current translation_unit.
Definition: abg-ir.cc:1248
language get_language() const
Getter of the language of the source code of the translation unit.
Definition: abg-ir.cc:1278
bool visiting() const
This should returns false before and after the node has been visiting. During the visiting of the nod...
Definition: abg-traverse.cc:48
An abstraction helper for type declarations.
Definition: abg-ir.h:2003
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
Definition: abg-ir.cc:16405
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition: abg-ir.cc:16381
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition: abg-ir.cc:16484
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:16351
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:16510
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:16084
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition: abg-ir.cc:16477
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition: abg-ir.cc:16470
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition: abg-ir.cc:16460
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition: abg-ir.cc:16498
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition: abg-ir.cc:16491
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition: abg-ir.cc:16365
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:27932
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition: abg-ir.cc:27939
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:17130
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:16970
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17209
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:17068
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:17024
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:17189
This is a type that aggregates maps of all the kinds of types that are supported by libabigail.
Definition: abg-ir.h:602
istring_type_base_wptrs_map_type & typedef_types()
Getter for the map that associates the name of a typedef to the vector of instances of typedef_decl_s...
Definition: abg-ir.cc:651
istring_type_base_wptrs_map_type & function_types()
Getter for the map that associates the name of a function type to the vector of instances of function...
Definition: abg-ir.cc:754
istring_type_base_wptrs_map_type & reference_types()
Getter for the map that associates the name of a reference type to the vector of instances of referen...
Definition: abg-ir.cc:705
const istring_type_base_wptrs_map_type & class_types() const
Getter for the map that associates the name of a class type to the vector of instances of class_decl_...
Definition: abg-ir.cc:609
istring_type_base_wptrs_map_type & union_types()
Getter for the map that associates the name of a union type to the vector of instances of union_decl_...
Definition: abg-ir.cc:623
istring_type_base_wptrs_map_type & array_types()
Getter for the map that associates the name of an array type to the vector of instances of array_type...
Definition: abg-ir.cc:719
istring_type_base_wptrs_map_type & enum_types()
Getter for the map that associates the name of an enum type to the vector of instances of enum_type_d...
Definition: abg-ir.cc:637
bool empty() const
Test if the type_maps is empty.
Definition: abg-ir.cc:577
istring_type_base_wptrs_map_type & qualified_types()
Getter for the map that associates the name of a qualified type to the vector of instances of qualifi...
Definition: abg-ir.cc:664
istring_type_base_wptrs_map_type & ptr_to_mbr_types()
Getter for the map that associates the name of a pointer-to-member type to the vector of instances of...
Definition: abg-ir.cc:684
const vector< type_base_wptr > & get_types_sorted_by_name() const
Getter of all types types sorted by their pretty representation.
Definition: abg-ir.cc:1157
istring_type_base_wptrs_map_type & pointer_types()
Getter for the map that associates the name of a pointer type to the vector of instances of pointer_t...
Definition: abg-ir.cc:677
const istring_type_base_wptrs_map_type & basic_types() const
Getter for the map that associates the name of a basic type to the vector instances of type_decl_sptr...
Definition: abg-ir.cc:595
const istring_type_base_wptrs_map_type & subrange_types() const
Getter for the map that associates the name of a subrange type to the vector of instances of array_ty...
Definition: abg-ir.cc:740
The base class of both types and declarations.
Definition: abg-ir.h:1406
void set_translation_unit(translation_unit *)
Set the translation_unit this ABI artifact belongs to.
Definition: abg-ir.cc:4278
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:4091
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
Definition: abg-ir.cc:4080
location & get_artificial_location() const
Getter of the artificial location of the artifact.
Definition: abg-ir.cc:4238
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
Definition: abg-ir.cc:4245
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Definition: abg-ir.cc:4270
friend hash_t set_or_get_cached_hash_value(const T &type_or_decl)
Set the hash value of an IR node and return it.
Definition: abg-ir-priv.h:415
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:4191
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
Definition: abg-ir.cc:4114
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:4103
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
Definition: abg-ir.cc:4303
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
Definition: abg-ir.cc:4134
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition: abg-ir.cc:11174
friend hash_t peek_hash_value(const type_or_decl_base &)
Get the hash value associated to an IR node.
Definition: abg-ir.cc:28535
const void * type_or_decl_base_pointer() const
Getter of the pointer to either the type_base sub-object of the current instance if it's a type,...
Definition: abg-ir.cc:4169
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10747
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
Definition: abg-ir.cc:4220
type_or_decl_kind
This is a bitmap type which instance is meant to contain the runtime type of a given ABI artifact....
Definition: abg-ir.h:1418
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition: abg-ir.cc:4202
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
Definition: abg-ir.cc:10820
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Definition: abg-ir.cc:4295
Abstracts a type template parameter.
Definition: abg-ir.h:3628
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:27619
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:21290
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition: abg-ir.cc:21275
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition: abg-ir.cc:21130
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:21117
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:21322
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition: abg-ir.cc:21268
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:21210
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition: abg-ir.cc:21147
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:21251
Abstracts a union type declaration.
Definition: abg-ir.h:4420
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:27100
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:27217
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition: abg-ir.cc:27157
virtual ~union_decl()
Destructor of the union_decl type.
Definition: abg-ir.cc:27290
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:27124
Abstracts a variable declaration.
Definition: abg-ir.h:3068
binding get_binding() const
Getter of the binding of the variable.
Definition: abg-ir.cc:21436
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition: abg-ir.cc:21418
void set_binding(binding b)
Setter of the binding of the variable.
Definition: abg-ir.cc:21443
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
Definition: abg-ir.cc:6199
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
Definition: abg-ir.cc:21481
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:21732
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:21429
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6344
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:21411
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:21894
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:21871
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition: abg-ir.cc:21458
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:21474
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition: abg-ir.cc:21667
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:21762
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:21686
A type used to time various part of the libabigail system.
bool stop()
Stop the timer.
bool start()
Start the timer.
bool is_decl_only_class_with_size_change(const class_or_union &first, const class_or_union &second)
Test if two classes that are decl-only (have the decl-only flag and carry no data members) but are di...
hash_t combine_hashes(hash_t val1, hash_t val2)
Combine two hash values to produce a third hash value.
Definition: abg-hash.cc:172
hash_t hash(uint64_t v, uint64_t seed)
Hash an integer value and combine it with a hash previously computed.
Definition: abg-hash.cc:196
@ HASHING_FINISHED_STATE
Hashing of given IR node started and is now done. If an ABI artifact is in this state,...
Definition: abg-hash.h:61
const type_base * is_void_pointer_type_equivalent(const type_base &type)
Test if a type is equivalent to a pointer to void type.
Definition: abg-ir.cc:11777
real_type::modifiers_type operator~(real_type::modifiers_type l)
Bitwise one's complement operator for real_type::modifiers_type.
Definition: abg-ir.cc:16567
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
Definition: abg-fwd.h:235
bool is_declaration_only_class_or_union_type(const type_base_sptr &t, bool look_through_decl_only)
Test wheter a type is a declaration-only class.
Definition: abg-ir.cc:11371
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:20467
const type_base_wptrs_type * lookup_class_types(const string &qualified_name, const corpus &corp)
Look into a given corpus to find the class type*s* that have a given qualified name.
Definition: abg-ir.cc:13860
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:12958
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition: abg-ir.cc:28562
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Definition: abg-ir.cc:6454
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
Definition: abg-ir.cc:7264
hash_t peek_hash_value(const type_or_decl_base &artefact)
Get the hash value associated to an IR node.
Definition: abg-ir.cc:28535
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:28513
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:12309
var_decl_sptr get_last_data_member(const class_or_union &klass)
Get the last data member of a class type.
Definition: abg-ir.cc:5781
bool is_anonymous_or_typedef_named(const decl_base &d)
Test if a given decl is anonymous or has a naming typedef.
Definition: abg-ir.cc:6154
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base_sptr &t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
Definition: abg-ir.cc:11637
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr &scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to a scope.
Definition: abg-ir.cc:8468
function_decl_sptr is_function_decl(const type_or_decl_base_sptr &d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10714
class_decl_sptr is_class_type(const type_or_decl_base_sptr &d)
Test whether a type is a class.
Definition: abg-ir.cc:11192
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:12096
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:16243
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
Definition: abg-ir.cc:5575
pointer_type_def_sptr is_pointer_to_npaf_type(const type_base_sptr &t)
Test if we are looking at a pointer to a neither-a-pointer-to-an-array-nor-a-function type.
Definition: abg-ir.cc:11554
bool debug_equals(const type_or_decl_base *l, const type_or_decl_base *r)
Test if two ABI artifacts are equal.
Definition: abg-ir.cc:10142
decl_base * debug(const decl_base *artifact)
Emit a textual representation of an artifact to std error stream for debugging purposes.
Definition: abg-ir.cc:10125
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition: abg-fwd.h:269
access_specifier
Access specifier for class members.
Definition: abg-ir.h:917
size_t get_canonical_type_index(const type_base &t)
Getter of the canonical type index of a given type.
Definition: abg-ir.cc:345
pointer_type_def_sptr lookup_pointer_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a pointer type which has a given qualified name.
Definition: abg-ir.cc:14294
class_decl_sptr lookup_class_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a class type which has a given qualified name.
Definition: abg-ir.cc:13775
interned_string get_type_name(const type_base &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
Definition: abg-ir.cc:9004
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition: abg-ir.cc:23353
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:11536
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:15825
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:14698
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:14188
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition: abg-ir.cc:6578
reference_type_def_sptr lookup_reference_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a reference type which has a given qualified name.
Definition: abg-ir.cc:14343
type_decl_sptr lookup_basic_type_per_location(const string &loc, const corpus &corp)
Lookup a type_decl type from a given corpus, by its location.
Definition: abg-ir.cc:13701
ptr_to_mbr_type_sptr is_ptr_to_mbr_type(const type_or_decl_base_sptr &t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type_sptr.
Definition: abg-ir.cc:11731
class_decl_sptr is_compatible_with_class_type(const decl_base_sptr &t)
Test if a type is a class. This function looks through typedefs.
Definition: abg-ir.cc:11156
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
Definition: abg-corpus.cc:1788
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
Definition: abg-fwd.h:142
const type_base_sptr is_void_pointer_type(const type_base_sptr &t)
Test if a type is a pointer to void type.
Definition: abg-ir.cc:11812
bool operator==(const union_decl_sptr &l, const union_decl_sptr &r)
Turn equality of shared_ptr of union_decl into a deep equality; that is, make it compare the pointed ...
Definition: abg-ir.cc:27373
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:25888
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:19924
const type_base_wptrs_type * lookup_enum_types(const string &qualified_name, const corpus &corp)
Look into a given corpus to find the enum type*s* that have a given qualified name.
Definition: abg-ir.cc:14042
const scope_decl * is_scope_decl(const decl_base *d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5445
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
Definition: abg-ir.cc:7615
string get_class_or_union_flat_representation(const class_or_union_sptr &cou, const string &indent, bool one_line, bool internal, bool qualified_names)
Get the flat representation of an instance of class_or_union type.
Definition: abg-ir.cc:9652
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10807
union_decl_sptr lookup_union_type(const string &type_name, const corpus &corp)
Look into a given corpus to find a union type which has a given qualified name.
Definition: abg-ir.cc:13948
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition: abg-ir.cc:5872
bool is_template_parameter(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter.
Definition: abg-ir.cc:10681
translation_unit * get_translation_unit(const type_or_decl_base_sptr &decl)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:10543
bool is_anonymous_data_member(const var_decl &d)
Test if a var_decl is an anonymous data member.
Definition: abg-ir.cc:5974
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
Definition: abg-ir.cc:1540
weak_ptr< type_base > type_base_wptr
Convenience typedef for a weak pointer on a type_base.
Definition: abg-fwd.h:128
type_decl_sptr is_integral_type(const type_or_decl_base_sptr &t)
Test if a type is an integral type.
Definition: abg-ir.cc:10989
type_base_sptr peel_reference_type(const type_base_sptr &type)
Return the leaf pointed-to type node of a reference_type_def node.
Definition: abg-ir.cc:7173
class_decl::base_spec * is_class_base_spec(const type_or_decl_base *tod)
Test if an ABI artifact is a class base specifier.
Definition: abg-ir.cc:26575
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
Definition: abg-ir.cc:5399
scope_decl * get_type_scope(const type_base_sptr &t)
Get the scope of a given type.
Definition: abg-ir.cc:8817
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
Definition: abg-ir.cc:12215
T * maybe_get_canonical_type(T *t)
Get the canonical type of a given type T* as a T*.
Definition: abg-ir.cc:894
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition: abg-ir.h:926
typedef_decl_sptr lookup_typedef_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a typedef type which has a given qualified name.
Definition: abg-ir.cc:14130
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:13585
var_decl_sptr get_data_member(type_base *clazz, const char *member_name)
Get a given data member, referred to by its name, of a class type.
Definition: abg-ir.cc:10039
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
Definition: abg-ir.cc:28633
type_base_sptr lookup_type_through_scopes(const list< string > &fqn, const translation_unit &tu)
Lookup a type from a translation unit by walking its scopes in sequence and by looking into them.
Definition: abg-ir.cc:13300
location get_location(const decl_base_sptr &decl)
Get the location of a given declaration.
Definition: abg-ir.cc:8779
const typedef_decl * is_typedef(const type_or_decl_base *t)
Test whether a type is a typedef.
Definition: abg-ir.cc:11041
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:16760
type_base_sptr look_through_decl_only_type(const type_base_sptr &t)
If a type is is decl-only, then get its definition. Otherwise, just return the initial type.
Definition: abg-ir.cc:12043
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
Definition: abg-ir.cc:8475
type_base_sptr peel_qualified_or_typedef_type(const type_base_sptr &t)
Return the leaf underlying type of a qualified or typedef type.
Definition: abg-ir.cc:7386
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
Definition: abg-ir.cc:10207
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
Definition: abg-ir.cc:7548
enum_type_decl_sptr lookup_enum_type_per_location(const string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
Definition: abg-ir.cc:14073
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:29139
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:11711
const var_decl_sptr get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
Get the first non-anonymous data member of a given anonymous data member.
Definition: abg-ir.cc:5718
class_decl_sptr lookup_class_type_through_scopes(const list< string > &fqn, const translation_unit &tu)
Lookup a class type from a translation unit by walking its scopes in sequence and by looking into the...
Definition: abg-ir.cc:13320
shared_ptr< class_or_union > is_class_or_union_type(const shared_ptr< type_or_decl_base > &t)
Test if a type is a class_or_union.
Definition: abg-ir.cc:11406
string get_enum_flat_representation(const enum_type_decl &enum_type, const string &indent, bool one_line, bool qualified_names)
Get the flat representation of an instance of enum_type_decl type.
Definition: abg-ir.cc:9684
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
Definition: abg-ir.cc:5479
bool operator==(const translation_unit_sptr &l, const translation_unit_sptr &r)
A deep comparison operator for pointers to translation units.
Definition: abg-ir.cc:1849
class_or_union_sptr anonymous_data_member_to_class_or_union(const var_decl_sptr &d)
Get the class_or_union type of a given anonymous data member.
Definition: abg-ir.cc:6099
weak_ptr< class_decl > class_decl_wptr
Convenience typedef for a weak pointer on a class_decl.
Definition: abg-fwd.h:202
string components_to_type_name(const list< string > &comps)
Turn a set of qualified name components (that name a type) into a qualified name string.
Definition: abg-ir.cc:12335
void unmark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being not compared anymore.
Definition: abg-ir.cc:1085
vector< type_base_sptr > type_base_sptrs_type
Helper typedef for a vector of shared pointer to a type_base.
Definition: abg-ir.h:127
void debug_comp_stack(const environment &env)
Emit a trace of the two comparison operands stack on the standard error stream.
Definition: abg-ir.cc:10192
bool collect_non_anonymous_data_members(const class_or_union *cou, string_decl_base_sptr_map &dms)
Collect all the non-anonymous data members of a class or union type.
Definition: abg-ir.cc:5815
union_decl_sptr is_union_type(const shared_ptr< type_or_decl_base > &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:11465
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition: abg-ir.cc:11165
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:15271
void set_member_function_virtuality(function_decl &fn, bool is_virtual, ssize_t voffset)
Set the virtual-ness of a member fcuntion.
Definition: abg-ir.cc:6715
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition: abg-fwd.h:244
method_type * is_method_type(type_or_decl_base *t)
Test whether a type is a method_type.
Definition: abg-ir.cc:11908
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:13610
qualified_type_def_sptr lookup_qualified_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a qualified type which has a given qualified name.
Definition: abg-ir.cc:14248
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:11349
type_base_sptr lookup_type(const type_base_sptr &t, const corpus &corp)
Look into a given corpus to find a type.
Definition: abg-ir.cc:14571
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
Definition: abg-ir.cc:9286
type_base_sptr lookup_class_typedef_or_enum_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, typedef or enum type which has a given qualified name.
Definition: abg-ir.cc:14213
const type_base_sptr peel_qualified_type(const type_base_sptr &type)
Return the leaf underlying type of a qualified type.
Definition: abg-ir.cc:7286
type_base_sptr peel_const_qualified_type(const qualified_type_def_sptr &q)
If a qualified type is const, then return its underlying type.
Definition: abg-ir.cc:7333
function_type_sptr lookup_function_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a function type which has a given qualified name.
Definition: abg-ir.cc:14464
const class_or_union_sptr data_member_has_anonymous_type(const var_decl &d)
Test if a data member has annonymous type or not.
Definition: abg-ir.cc:6058
type_decl * is_integral_type(const type_or_decl_base *t)
Test if a type is an integral type.
Definition: abg-ir.cc:10967
bool anonymous_data_member_exists_in_class(const var_decl &anon_dm, const class_or_union &clazz)
Test if a given anonymous data member exists in a class or union.
Definition: abg-ir.cc:6114
type_decl_sptr is_real_type(const type_or_decl_base_sptr &t)
Test if a type is a real type.
Definition: abg-ir.cc:10947
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition: abg-ir.cc:6482
const function_type * is_function_type(const type_or_decl_base *t)
Test whether a type is a function_type.
Definition: abg-ir.cc:11878
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
Definition: abg-ir.cc:7222
bool types_have_similar_structure(const type_base_sptr &first, const type_base_sptr &second, bool indirect_type)
Test if two types have similar structures, even though they are (or can be) different.
Definition: abg-ir.cc:28777
corpus_group_sptr is_corpus_group(const corpus_sptr &corpus)
Test if a corpus is a corpus_group.
Definition: abg-corpus.cc:2277
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
Definition: abg-fwd.h:314
enum_type_decl_sptr look_through_decl_only_enum(enum_type_decl_sptr enom)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
Definition: abg-ir.cc:11958
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:11396
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:12027
const var_decl_sptr get_next_data_member(const class_or_union *klass, const var_decl_sptr &data_member)
In the context of a given class or union, this function returns the data member that is located after...
Definition: abg-ir.cc:5742
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition: abg-fwd.h:193
type_base_sptr peel_typedef_pointer_or_reference_type(const type_base_sptr type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def,...
Definition: abg-ir.cc:7409
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
Definition: abg-ir.cc:6538
string get_name(const type_or_decl_base_sptr &tod, bool qualified)
Build and return a copy of the name of an ABI artifact that is either a type of a decl.
Definition: abg-ir.cc:8718
bool is_anonymous_type(const type_base_sptr &t)
Test if a given type is anonymous.
Definition: abg-ir.cc:10883
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
Definition: abg-ir.cc:6915
bool is_comparison_cycle_detected(T &l, T &r)
Detect if a recursive comparison cycle is detected while structurally comparing two types (a....
Definition: abg-ir.cc:989
bool string_to_elf_symbol_type(const string &s, elf_symbol::type &t)
Convert a string representing a symbol type into an elf_symbol::type.
Definition: abg-ir.cc:3064
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:12078
array_type_def_sptr is_array_of_qualified_element(const type_base_sptr &type)
Test if an array type is an array to a qualified element type.
Definition: abg-ir.cc:12171
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:10909
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10787
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:11967
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:11858
scope_decl_sptr is_scope_decl(const decl_base_sptr &d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5455
string get_name(const type_or_decl_base *tod, bool qualified)
Build and return a copy of the name of an ABI artifact that is either a type or a decl.
Definition: abg-ir.cc:8686
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5544
decl_base_sptr look_through_decl_only(const decl_base_sptr &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
Definition: abg-ir.cc:12008
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition: abg-ir.cc:11011
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
Definition: abg-ir.h:105
type_base_sptr is_type(const type_or_decl_base_sptr &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10835
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
Definition: abg-ir.cc:6316
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
Definition: abg-ir.cc:9833
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition: abg-fwd.h:210
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
Definition: abg-fwd.h:167
function_type_sptr synthesize_function_type_from_translation_unit(const function_type &fn_type, translation_unit &tu)
In a translation unit, lookup the sub-types that make up a given function type and if the sub-types a...
Definition: abg-ir.cc:15354
std::ostream & operator<<(std::ostream &o, elf_symbol::type t)
Serialize an instance of symbol_type and stream it to a given output stream.
Definition: abg-ir.cc:2936
type_base_sptr peel_pointer_type(const type_base_sptr &type)
Return the leaf pointed-to type node of a pointer_type_def node.
Definition: abg-ir.cc:7117
bool var_equals_modulo_types(const var_decl &l, const var_decl &r, change_kind *k)
Compares two instances of var_decl without taking their type into account.
Definition: abg-ir.cc:21542
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:13560
void sort_types(const canonical_type_sptr_set_type &types, vector< type_base_sptr > &result)
Sort types in a hopefully stable manner.
Definition: abg-ir.cc:3448
type_base * peel_pointer_or_reference_type(const type_base *type, bool peel_qual_type)
Return the leaf underlying or pointed-to type node of a, pointer_type_def, reference_type_def or qual...
Definition: abg-ir.cc:7511
decl_base_sptr is_decl_slow(const type_or_decl_base_sptr &t)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10798
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:11651
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
Definition: abg-corpus.cc:1774
bool elf_symbol_is_function(elf_symbol::type t)
Test if the type of an ELF symbol denotes a function symbol.
Definition: abg-ir.cc:3145
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
Definition: abg-ir.cc:1808
bool integral_type_has_harmless_name_change(const decl_base_sptr &f, const decl_base_sptr &s)
Test if a diff node carries a change whereby two integral types have different names in a harmless wa...
Definition: abg-ir.cc:29731
enum_type_decl_sptr is_compatible_with_enum_type(const decl_base_sptr &t)
Test if a type is an enum. This function looks through typedefs.
Definition: abg-ir.cc:11091
function_decl::parameter_sptr is_function_parameter(const type_or_decl_base_sptr tod)
Test whether an ABI artifact is a function_decl.
Definition: abg-ir.cc:10737
class_or_union_sptr look_through_decl_only_class(class_or_union_sptr klass)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
Definition: abg-ir.cc:11938
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:13813
bool member_function_has_vtable_offset(const function_decl &f)
Test if a virtual member function has a vtable offset set.
Definition: abg-ir.cc:6567
const type_base * peel_typedef_type(const type_base *type)
Return the leaf underlying type node of a typedef_decl node.
Definition: abg-ir.cc:7090
decl_base_sptr insert_decl_into_scope(decl_base_sptr decl, scope_decl::declarations::iterator before, scope_decl *scope)
Inserts a declaration into a given scope, before a given IR child node of the scope.
Definition: abg-ir.cc:8494
unordered_map< interned_string, bool, hash_interned_string > interned_string_bool_map_type
Convenience typedef for a map of interned_string -> bool.
Definition: abg-ir.cc:3365
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
Definition: abg-ir.cc:11100
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:28725
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:10650
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition: abg-fwd.h:256
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
Definition: abg-fwd.h:239
const location & get_natural_or_artificial_location(const decl_base *decl)
Get the non-artificial (natural) location of a decl.
Definition: abg-ir.cc:10052
string build_qualified_name(const scope_decl *scope, const type_base_sptr &type)
Build and return the qualified name of a type in its scope.
Definition: abg-ir.cc:8755
size_t hash_type_or_decl(const type_or_decl_base *tod)
Hash an ABI artifact that is either a type or a decl.
Definition: abg-ir.cc:28426
array_type_def_sptr is_array_type(const type_or_decl_base_sptr &type, bool look_through_qualifiers)
Test if a type is an array_type_def.
Definition: abg-ir.cc:12139
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
Definition: abg-corpus.cc:1802
bool is_template_decl(const decl_base_sptr &decl)
Tests whether a decl is a template.
Definition: abg-ir.cc:12238
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
Definition: abg-fwd.h:264
class_decl_sptr lookup_class_type_per_location(const string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
Definition: abg-ir.cc:13907
bool string_to_elf_symbol_binding(const string &s, elf_symbol::binding &b)
Convert a string representing a an elf symbol binding into an elf_symbol::binding.
Definition: abg-ir.cc:3097
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
Definition: abg-fwd.h:120
ssize_t get_member_function_vtable_offset(const function_decl_sptr &f)
Get the vtable offset of a member function.
Definition: abg-ir.cc:6600
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition: abg-fwd.h:136
bool is_data_member_of_anonymous_class_or_union(const var_decl &d)
Test if a var_decl is a data member belonging to an anonymous type.
Definition: abg-ir.cc:5990
namespace_decl * is_namespace(const decl_base *d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:12087
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:29704
type_base * peel_typedef_pointer_or_reference_type(const type_base *type, bool peel_qual_type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def or reference_t...
Definition: abg-ir.cc:7472
const type_base * is_void_pointer_type_equivalent(const type_base *type)
Test if a type is equivalent to a pointer to void type.
Definition: abg-ir.cc:11750
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:30428
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition: abg-ir.cc:12244
bool try_canonical_compare(const T *l, const T *r)
Compare two types by comparing their canonical types if present.
Definition: abg-ir.cc:914
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
Definition: abg-ir.cc:28363
unordered_map< string, decl_base_sptr > string_decl_base_sptr_map
Convenience typedef for a map which key is a string and which value is a decl_base_sptr.
Definition: abg-fwd.h:157
void push_composite_type_comparison_operands(const type_base &left, const type_base &right)
Push a pair of operands on the stack of operands of the current type comparison, during type canonica...
Definition: abg-ir.cc:311
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
Definition: abg-ir.cc:1824
function_decl::parameter * is_function_parameter(const type_or_decl_base *tod)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10724
type_decl_sptr lookup_basic_type(const string &qualified_name, const corpus &corp)
Look into a given corpus to find a basic type which has a given qualified name.
Definition: abg-ir.cc:13720
class_or_union * is_at_class_scope(const decl_base &decl)
Tests whether a given decl is at class scope.
Definition: abg-ir.cc:10630
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
Definition: abg-ir.cc:5138
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6344
const decl_base_sptr lookup_var_decl_in_scope(const std::list< string > &comps, const scope_decl_sptr &skope)
lookup a var_decl in a scope.
Definition: abg-ir.cc:13267
bool string_to_elf_symbol_visibility(const string &s, elf_symbol::visibility &v)
Convert a string representing a an elf symbol visibility into an elf_symbol::visibility.
Definition: abg-ir.cc:3122
union_decl_sptr lookup_union_type_per_location(const string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
Definition: abg-ir.cc:12572
weak_ptr< elf_symbol > elf_symbol_wptr
A convenience typedef for a weak pointer to elf_symbol.
Definition: abg-ir.h:929
uint64_t get_data_member_offset(const decl_base_sptr d)
Get the offset of a data member.
Definition: abg-ir.cc:6208
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition: abg-ir.cc:6510
interned_string get_name_of_reference_to_type(const type_base &pointed_to_type, bool lvalue_reference, bool qualified, bool internal)
Get the name of the reference to a given type.
Definition: abg-ir.cc:9041
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
Definition: abg-fwd.h:226
void maybe_update_types_lookup_map(const type_decl_sptr &basic_type)
Update the map that associates the fully qualified name of a basic type with the type itself.
Definition: abg-ir.cc:14728
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:20548
interned_string get_method_type_name(const method_type &fn_type, bool internal)
Get the name of a given method type and return a copy of it.
Definition: abg-ir.cc:9243
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
Definition: abg-ir.cc:7301
translation_unit::language string_to_translation_unit_language(const string &l)
Parse a string representing a language into a translation_unit::language enumerator into a string.
Definition: abg-ir.cc:1670
enum_type_decl_sptr is_enum_type(const type_or_decl_base_sptr &d)
Test if a decl is an enum_type_decl.
Definition: abg-ir.cc:11109
var_decl_sptr has_fake_flexible_array_data_member(const class_decl_sptr &klass)
Test if the last data member of a class is an array with one element.
Definition: abg-ir.cc:11336
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:14518
bool get_next_data_member_offset(const class_or_union *klass, const var_decl_sptr &dm, uint64_t &offset)
Get the offset of the non-static data member that comes after a given one.
Definition: abg-ir.cc:6229
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
Definition: abg-ir.cc:6273
shared_ptr< ir_traversable_base > ir_traversable_base_sptr
Convenience typedef for a shared pointer to ir_traversable_base.
Definition: abg-fwd.h:109
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
Definition: abg-ir.cc:6368
const function_decl::parameter * get_function_parameter(const decl_base *fun, unsigned parm_index)
Get the function parameter designated by its index.
Definition: abg-ir.cc:29071
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:12059
string get_pretty_representation(const method_type_sptr method, bool internal)
Get the pretty representation of a method type.
Definition: abg-ir.cc:9488
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
Definition: abg-ir.cc:1792
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10747
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:28401
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:25721
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition: abg-ir.cc:5464
string get_class_or_union_flat_representation(const class_or_union &cou, const string &indent, bool one_line, bool internal, bool qualified_names)
Get the flat representation of an instance of class_or_union type.
Definition: abg-ir.cc:9508
array_type_def::subrange_sptr is_subrange_type(const type_or_decl_base_sptr &type)
Test if a type is an array_type_def::subrange_type.
Definition: abg-ir.cc:12228
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition: abg-ir.cc:8450
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
Definition: abg-ir.cc:29093
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:10894
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5515
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition: abg-fwd.h:175
void set_data_member_offset(var_decl_sptr m, uint64_t o)
Set the offset of a data member into its containing class.
Definition: abg-ir.cc:6167
const interned_string & get_node_name(var_decl_sptr node)
Gets the name of a var_decl node.
Definition: abg-ir.cc:13025
type_base_sptr strip_typedef(const type_base_sptr type)
Recursively returns the the underlying type of a typedef. The return type should not be a typedef of ...
Definition: abg-ir.cc:6780
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition: abg-ir.cc:6184
unordered_set< uintptr_t > pointer_set
A convenience typedef for an unordered set of pointer values.
Definition: abg-ir.h:99
type_decl_sptr is_type_decl(const type_or_decl_base_sptr &t)
Test whether a type is a type_decl (a builtin type).
Definition: abg-ir.cc:10917
void sort_types_for_hash_computing_and_c14n(IteratorType begin, IteratorType end)
Sort types before hashing (and then canonicalizing) them.
Definition: abg-ir-priv.h:1418
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:10607
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6641
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
Definition: abg-ir.cc:11479
string get_class_or_enum_flat_representation(const type_base &coe, const string &indent, bool one_line, bool internal, bool qualified_name)
Get the flat representation of an instance of enum_type_decl type.
Definition: abg-ir.cc:9805
bool types_are_compatible(const decl_base_sptr d1, const decl_base_sptr d2)
Test if two types are equal modulo a typedef.
Definition: abg-ir.cc:10492
class_or_union * anonymous_data_member_to_class_or_union(const var_decl *d)
Get the class_or_union type of a given anonymous data member.
Definition: abg-ir.cc:6030
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
Definition: abg-ir.cc:8766
pointer_type_def_sptr is_pointer_to_function_type(const type_base_sptr &t)
Test if a type is a pointer to function type.
Definition: abg-ir.cc:11519
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:10503
weak_ptr< decl_base > decl_base_wptr
Convenience typedef for a weak pointer to a decl_base.
Definition: abg-fwd.h:181
interned_string get_function_type_name(const function_type_sptr &fn_type, bool internal)
Get the name of a given function type and return a copy of it.
Definition: abg-ir.cc:9118
bool is_function_template_pattern(const shared_ptr< decl_base > decl)
Test whether a decl is the pattern of a function template.
Definition: abg-ir.cc:12110
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:11918
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:11445
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition: abg-ir.cc:10071
bool is_global_scope(const shared_ptr< scope_decl >scope)
Tests whether if a given scope is the global scope.
Definition: abg-ir.cc:10571
typedef_decl_sptr lookup_typedef_type_per_location(const string &loc, const corpus &corp)
Lookup a typedef_decl from a corpus, by its location.
Definition: abg-ir.cc:14168
type_base_sptr peel_typedef_type(const type_base_sptr &type)
Return the leaf underlying type node of a typedef_decl node.
Definition: abg-ir.cc:7063
interned_string get_name_of_qualified_type(const type_base_sptr &underlying_type, qualified_type_def::CV quals, bool qualified, bool internal)
Get the name of a qualified type, given the underlying type and its qualifiers.
Definition: abg-ir.cc:9071
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
Definition: abg-fwd.h:306
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
Definition: abg-ir.cc:12194
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
Definition: abg-ir.cc:10552
string get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
Get the string representation of a CV qualifier bitmap.
Definition: abg-ir.cc:8656
void set_data_member_is_laid_out(var_decl_sptr m, bool l)
Set a flag saying if a data member is laid out.
Definition: abg-ir.cc:6330
pointer_type_def_sptr is_pointer_to_ptr_to_mbr_type(const type_base_sptr &t)
Test if we are looking at a pointer to pointer to member type.
Definition: abg-ir.cc:11571
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition: abg-ir.cc:5613
var_decl_sptr find_first_data_member_matching_regexp(const class_or_union &t, const regex::regex_t_sptr &r)
Find the first data member of a class or union which name matches a regular expression.
Definition: abg-ir.cc:29118
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition: abg-ir.cc:10229
bool is_at_global_scope(const decl_base *decl)
Tests whether a given declaration is at global scope.
Definition: abg-ir.cc:10598
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26821
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:12123
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:29028
interned_string get_function_id_or_pretty_representation(const function_decl *fn)
Get the ID of a function, or, if the ID can designate several different functions,...
Definition: abg-ir.cc:9180
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition: abg-fwd.h:161
const global_scope * get_global_scope(const shared_ptr< decl_base > decl)
Return the global scope as seen by a given declaration.
Definition: abg-ir.cc:8572
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
Definition: abg-ir.cc:7590
bool compare_using_locations(const decl_base *f, const decl_base *s)
Compare decls using their locations.
Definition: abg-ir.cc:3413
string get_enum_flat_representation(const enum_type_decl_sptr &enum_type, const string &indent, bool one_line, bool qualified_names)
Get the flat representation of an instance of enum_type_decl type.
Definition: abg-ir.cc:9775
bool classes_have_same_layout(const type_base_sptr &f, const type_base_sptr &s)
Test if two classes have the same layout.
Definition: abg-ir.cc:10262
unordered_set< type_base_sptr, canonical_type_hash > canonical_type_sptr_set_type
Helper typedef for an unordered set of type_base_sptr which uses pointer value to tell its members ap...
Definition: abg-ir.h:121
bool return_comparison_result(T &l, T &r, bool value)
Return the result of the comparison of two (sub) types.
Definition: abg-ir.cc:1127
array_type_def_sptr lookup_array_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find an array type which has the same qualified name as a given array typ...
Definition: abg-ir.cc:14393
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
Definition: abg-fwd.h:284
var_decl_sptr is_var_decl(const type_or_decl_base_sptr &decl)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:12069
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:15428
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition: abg-ir.cc:28598
void maybe_update_types_lookup_map(const function_type_sptr &fn_type)
Update the map that associates the fully qualified name of a function type with the type itself.
Definition: abg-ir.cc:15165
void mark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being compared.
Definition: abg-ir.cc:1050
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
Definition: abg-ir.cc:8835
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
Definition: abg-corpus.cc:1816
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
Definition: abg-ir.cc:7668
interned_string get_function_type_name(const function_type &fn_type, bool internal)
Get the name of a given function type and return a copy of it.
Definition: abg-ir.cc:9155
decl_base_sptr is_decl(const type_or_decl_base_sptr &d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10776
bool operator!=(const translation_unit_sptr &l, const translation_unit_sptr &r)
A deep inequality operator for pointers to translation units.
Definition: abg-ir.cc:1868
interned_string get_name_of_pointer_to_type(const type_base &pointed_to_type, bool qualified, bool internal)
Get the name of the pointer to a given type.
Definition: abg-ir.cc:9019
bool decl_name_changed(const type_or_decl_base *a1, const type_or_decl_base *a2)
Test if two decls have different names.
Definition: abg-ir.cc:29663
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
Definition: abg-ir.cc:10672
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10695
bool elf_symbol_is_variable(elf_symbol::type t)
Test if the type of an ELF symbol denotes a function symbol.
Definition: abg-ir.cc:3155
bool type_has_sub_type_changes(const type_base_sptr t_v1, const type_base_sptr t_v2)
Tests if the change of a given type effectively comes from just its sub-types. That is,...
Definition: abg-ir.cc:28385
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:14636
var_decl_sptr has_flexible_array_data_member(const class_decl_sptr &klass)
Test if the last data member of a class is an array with non-finite data member.
Definition: abg-ir.cc:11254
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:11888
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:11838
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:11591
const scope_decl * get_top_most_scope_under(const decl_base_sptr decl, const scope_decl_sptr scope)
Return the a scope S containing a given declaration and that is right under a given scope P.
Definition: abg-ir.cc:8643
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol.
Definition: abg-ir.h:947
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
Definition: abg-ir.cc:8732
bool is_ptr_ref_or_qual_type(const type_base *t)
Helper to detect if a type is either a reference, a pointer, or a qualified type.
Definition: abg-ir.cc:3396
method_decl_sptr copy_member_function(const class_or_union_sptr &t, const method_decl_sptr &method)
Copy a method of a class_or_union into a new class_or_union.
Definition: abg-ir.cc:24834
decl_base_sptr get_type_declaration(const type_base_sptr t)
Get the declaration for a given type.
Definition: abg-ir.cc:10247
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
Definition: abg-fwd.h:294
type_base * peel_qualified_or_typedef_type(const type_base *type)
Return the leaf underlying type of a qualified or typedef type.
Definition: abg-ir.cc:7358
type_base_sptr type_or_void(const type_base_sptr t, const environment &env)
Return either the type given in parameter if it's non-null, or the void type.
Definition: abg-ir.cc:15458
pointer_type_def_sptr is_pointer_type(const type_or_decl_base_sptr &t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
Definition: abg-ir.cc:11503
type_decl * is_real_type(const type_or_decl_base *t)
Test if a type is a real type.
Definition: abg-ir.cc:10927
const type_base_wptrs_type * lookup_union_types(const string &qualified_name, const corpus &corp)
Look into a given corpus to find the union types that have a given qualified name.
Definition: abg-ir.cc:13875
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition: abg-ir.cc:5417
bool maybe_compare_as_member_decls(const decl_base &l, const decl_base &r, change_kind *k)
Compare the properties that belong to the "is-a-member-relation" of a decl.
Definition: abg-ir.cc:5069
qualified_type_def_sptr is_qualified_type(const type_or_decl_base_sptr &t)
Test whether a type is a qualified_type_def.
Definition: abg-ir.cc:11848
bool class_or_union_types_of_same_kind(const class_or_union_sptr &first, const class_or_union_sptr &second)
Test if two class or union types are of the same kind.
Definition: abg-ir.cc:11435
reference_type_def_sptr is_reference_type(const type_or_decl_base_sptr &t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
Definition: abg-ir.cc:11695
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition: abg-ir.cc:6395
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
Definition: abg-ir.cc:6425
bool is_declaration_only_class_type(const type_base_sptr &t, bool look_through_decl_only)
Test wheter a type is a declaration-only class.
Definition: abg-ir.cc:11385
enum_type_decl_sptr lookup_enum_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find an enum type which has a given qualified name.
Definition: abg-ir.cc:14005
bool match(const regex_t_sptr &r, const std::string &str)
See if a string matches a regex.
Definition: abg-regex.cc:127
std::shared_ptr< regex_t > regex_t_sptr
A convenience typedef for a shared pointer of regex_t.
Definition: abg-fwd.h:87
bool base_name(string const &path, string &file_name)
Return the file name part of a file part.
const char * get_anonymous_subrange_internal_name_prefix()
Getter of the prefix for the name of anonymous range.
const char * get_anonymous_enum_internal_name_prefix()
Getter of the prefix for the name of anonymous enums.
const char * get_anonymous_struct_internal_name_prefix()
Getter of the prefix for the name of anonymous structs.
const char * get_anonymous_union_internal_name_prefix()
Getter of the prefix for the name of anonymous unions.
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
Definition: abg-ir.cc:151
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
Definition: abg-ir.cc:185
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
Definition: abg-ir.cc:168
unordered_map< string, string * > pool_map_type
Convenience typedef for a map of string -> string*.
Definition: abg-ir.cc:73
A functor to hash instances of interned_string.
size_t operator()(const type_base_sptr &l) const
Hash a type by returning the pointer value of its canonical type.
Definition: abg-ir.cc:7783
Hasher for the class_or_union type.
Definition: abg-hash.h:250
bool is_printing_flat_representation() const
Getter of the 'is_printing_flat_representation_' boolean.
Definition: abg-ir-priv.h:1796
void unset_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to false.
Definition: abg-ir-priv.h:1786
void set_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to true.
Definition: abg-ir-priv.h:1776
A functor to sort decls somewhat topologically. That is, types are sorted in a way that makes the one...
Definition: abg-ir-priv.h:981
The private data of the environment type.
Definition: abg-ir-priv.h:540
Equality functor for instances of function_decl.
Definition: abg-ir.h:4770
The type of the private data of the function_type type.
Definition: abg-ir-priv.h:1804
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:30078
The hashing functor for member_base.
Definition: abg-hash.h:243
Private type to hold private members of translation_unit.
Definition: abg-ir-priv.h:152
Hash functor for instances of type_base.
Definition: abg-hash.h:111
Definition of the private data of type_base.
Definition: abg-ir-priv.h:463
The private data of type_or_decl_base.
Definition: abg-ir-priv.h:188
A predicate for deep equality of instances of shared_ptr<type_base>
Definition: abg-ir.h:2096
A functor to sort types somewhat topologically. That is, types are sorted in a way that makes the one...
Definition: abg-ir-priv.h:1087
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.