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-2024 Red Hat, Inc.
6//
7//Author: Dodji Seketeli
8
9/// @file
10///
11/// Definitions for the Internal Representation artifacts of libabigail.
12
13#include <cxxabi.h>
14#include <cstdint>
15#include <functional>
16#include <iterator>
17#include <memory>
18#include <sstream>
19#include <typeinfo>
20#include <unordered_map>
21#include <utility>
22#include <vector>
23
24#include "abg-internal.h"
25// <headers defining libabigail's API go under here>
26ABG_BEGIN_EXPORT_DECLARATIONS
27
28#include "abg-interned-str.h"
29#include "abg-ir.h"
30#include "abg-corpus.h"
31#include "abg-regex.h"
32
33ABG_END_EXPORT_DECLARATIONS
34// </headers defining libabigail's API>
35
36#include "abg-corpus-priv.h"
37#include "abg-comp-filter.h"
38#include "abg-ir-priv.h"
39
40namespace
41{
42/// This internal type is a tree walking that is used to set the
43/// qualified name of a tree of decls and types. It used by the
44/// function update_qualified_name().
45class qualified_name_setter : public abigail::ir::ir_node_visitor
46{
47
48public:
49 bool
50 do_update(abigail::ir::decl_base* d);
51
52 bool
53 visit_begin(abigail::ir::decl_base* d);
54
55 bool
56 visit_begin(abigail::ir::type_base* d);
57}; // end class qualified_name_setter
58
59}// end anon namespace
60
61namespace abigail
62{
63
64// Inject.
65using std::string;
66using std::list;
67using std::vector;
68using std::unordered_map;
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
71
72/// Convenience typedef for a map of string -> string*.
73typedef unordered_map<string, string*> pool_map_type;
74
75/// The type of the private data structure of type @ref
76/// intered_string_pool.
77struct interned_string_pool::priv
78{
79 pool_map_type map;
80}; //end struc struct interned_string_pool::priv
81
82/// Default constructor.
84 : priv_(new priv)
85{
86 priv_->map[""] = 0;
87}
88
89/// Test if the interned string pool already contains a string with a
90/// given value.
91///
92/// @param s the string to test for.
93///
94/// @return true if the pool contains a string with the value @p s.
95bool
97{return priv_->map.find(s) != priv_->map.end();}
98
99/// Get a pointer to the interned string which has a given value.
100///
101/// @param s the value of the interned string to look for.
102///
103/// @return a pointer to the raw string of characters which has the
104/// value of @p s. Or null if no string with value @p s was interned.
105const char*
107{
108 unordered_map<string, string*>::const_iterator i =
109 priv_->map.find(s);
110 if (i == priv_->map.end())
111 return 0;
112 if (i->second)
113 return i->second->c_str();
114 return "";
115}
116
117/// Create an interned string with a given value.
118///
119/// @param str_value the value of the interned string to create.
120///
121/// @return the new created instance of @ref interned_string created.
123interned_string_pool::create_string(const std::string& str_value)
124{
125 string*& result = priv_->map[str_value];
126 if (!result && !str_value.empty())
127 result = new string(str_value);
128 return interned_string(result);
129}
130
131/// Destructor.
133{
134 for (pool_map_type::iterator i = priv_->map.begin();
135 i != priv_->map.end();
136 ++i)
137 if (i->second)
138 delete i->second;
139}
140
141/// Equality operator.
142///
143/// @param l the instance of std::string on the left-hand-side of the
144/// equality operator.
145///
146/// @param r the instance of @ref interned_string on the
147/// right-hand-side of the equality operator.
148///
149/// @return true iff the two string are equal.
150bool
151operator==(const std::string& l, const interned_string& r)
152{return r.operator==(l);}
153
154bool
155operator!=(const std::string& l, const interned_string& r)
156{return !(l == r);}
157
158/// Streaming operator.
159///
160/// Streams an instance of @ref interned_string to an output stream.
161///
162/// @param o the destination output stream.
163///
164/// @param s the instance of @ref interned_string to stream out.
165///
166/// @return the output stream this function just streamed to.
167std::ostream&
168operator<<(std::ostream& o, const interned_string& s)
169{
170 o << static_cast<std::string>(s);
171 return o;
172}
173
174/// Concatenation operator.
175///
176/// Concatenate two instances of @ref interned_string, builds an
177/// instance of std::string with the resulting string and return it.
178///
179/// @param s1 the first string to consider.
180///
181/// @param s2 the second string to consider.
182///
183/// @return the resuting concatenated string.
184std::string
185operator+(const interned_string& s1,const std::string& s2)
186{return static_cast<std::string>(s1) + s2;}
187
188/// Concatenation operator.
189///
190/// Concatenate two instances of @ref interned_string, builds an
191/// instance of std::string with the resulting string and return it.
192///
193/// @param s1 the first string to consider.
194///
195/// @param s2 the second string to consider.
196///
197/// @return the resuting concatenated string.
198std::string
199operator+(const std::string& s1, const interned_string& s2)
200{return s1 + static_cast<std::string>(s2);}
201
202namespace ir
203{
204
205static size_t
206hash_as_canonical_type_or_constant(const type_base *t);
207
208static bool
209has_generic_anonymous_internal_type_name(const decl_base *d);
210
211static interned_string
212get_generic_anonymous_internal_type_name(const decl_base *d);
213
214static string
215get_internal_real_type_name(const type_base*);
216
217static void
218update_qualified_name(decl_base * d);
219
220static void
221update_qualified_name(decl_base_sptr d);
222
223static interned_string
224pointer_declaration_name(const type_base* ptr,
225 const string& variable_name,
226 bool qualified, bool internal);
227
228static interned_string
229pointer_declaration_name(const type_base_sptr& ptr,
230 const string& variable_name,
231 bool qualified, bool internal);
232
233static interned_string
234ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
235 const string& variable_name,
236 bool qualified, bool internal);
237
238static interned_string
239ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
240 const string& variable_name,
241 bool qualified, bool internal);
242
243static interned_string
244array_declaration_name(const array_type_def* array,
245 const string& variable_name,
246 bool qualified, bool internal);
247
248static interned_string
249array_declaration_name(const array_type_def_sptr& array,
250 const string& variable_name,
251 bool qualified, bool internal);
252
253static void
254stream_pretty_representation_of_fn_parms(const function_type& fn_type,
255 ostream& o, bool qualified,
256 bool internal);
257static string
258add_outer_pointer_to_fn_type_expr(const type_base* pointer_to_fn,
259 const string& input, bool qualified,
260 bool internal);
261
262static string
263add_outer_pointer_to_fn_type_expr(const type_base_sptr& pointer_to_fn,
264 const string& input, bool qualified,
265 bool internal);
266
267static string
268add_outer_pointer_to_array_type_expr(const type_base* pointer_to_ar,
269 const string& input, bool qualified,
270 bool internal);
271
272static string
273add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
274 const string& input, bool qualified,
275 bool internal);
276
277static string
278add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
279 const string& input, bool qualified,
280 bool internal);
281
282static string
283add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
284 const string& input, bool qualified,
285 bool internal);
286
287static string
288add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
289 const string& input,
290 bool qualified, bool internal);
291
292void
293push_composite_type_comparison_operands(const type_base& left,
294 const type_base& right);
295
296void
297pop_composite_type_comparison_operands(const type_base& left,
298 const type_base& right);
299
300
301/// Push a pair of operands on the stack of operands of the current
302/// type comparison, during type canonicalization.
303///
304/// For more information on this, please look at the description of
305/// the environment::priv::right_type_comp_operands_ data member.
306///
307/// @param left the left-hand-side comparison operand to push.
308///
309/// @param right the right-hand-side comparison operand to push.
310void
312 const type_base& right)
313{
314 const environment& env = left.get_environment();
315 env.priv_->push_composite_type_comparison_operands(&left, &right);
316}
317
318/// Pop a pair of operands from the stack of operands to the current
319/// type comparison.
320///
321/// For more information on this, please look at the description of
322/// the environment::privright_type_comp_operands_ data member.
323///
324/// @param left the left-hand-side comparison operand we expect to
325/// pop from the top of the stack. If this doesn't match the
326/// operand found on the top of the stack, the function aborts.
327///
328/// @param right the right-hand-side comparison operand we expect to
329/// pop from the bottom of the stack. If this doesn't match the
330/// operand found on the top of the stack, the function aborts.
331void
333 const type_base& right)
334{
335 const environment& env = left.get_environment();
336 env.priv_->pop_composite_type_comparison_operands(&left, &right);
337}
338
339/// Getter of the canonical type index of a given type.
340///
341/// @param t the type to consider.
342///
343/// @return the CTI of the type.
344size_t
346{return t.priv_->canonical_type_index;}
347
348/// Getter of the canonical type index of a given type.
349///
350/// @param t the type to consider.
351///
352/// @return the CTI of the type.
353size_t
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/// Compare two types by comparing their canonical types if present.
882///
883/// If the canonical types are not present (because the types have not
884/// yet been canonicalized, for instance) then the types are compared
885/// structurally.
886///
887/// @param l the first type to take into account in the comparison.
888///
889/// @param r the second type to take into account in the comparison.
890template<typename T>
891bool
892try_canonical_compare(const T *l, const T *r)
893{
894#if WITH_DEBUG_TYPE_CANONICALIZATION
895 // We are debugging the canonicalization of a type down the stack.
896 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
897 // type being canonicalized. We are at a point where we can compare
898 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
899 // have canonical types) or structural comparison.
900 //
901 // Because we are debugging the process of type canonicalization, we
902 // want to compare 'l' and 'r' canonically *AND* structurally. Both
903 // kinds of comparison should yield the same result, otherwise type
904 // canonicalization just failed for the subtype 'r' of the type
905 // being canonicalized.
906 //
907 // In concrete terms, this function is going to be called twice with
908 // the same pair {'l', 'r'} to compare: The first time with
909 // environment::priv_->use_canonical_type_comparison_ set to true,
910 // instructing us to compare them canonically, and the second time
911 // with that boolean set to false, instructing us to compare them
912 // structurally.
913 const environment&env = l->get_environment();
914 if (env.priv_->use_canonical_type_comparison_)
915 {
916 if (const type_base *lc = l->get_naked_canonical_type())
917 if (const type_base *rc = r->get_naked_canonical_type())
918 ABG_RETURN_EQUAL(lc, rc);
919 }
920
921 // If the two types have a non-empty hash value, then consider those
922 // hash values. If the hashes are different then the two types are
923 // different. If the hashes are equal then we'll compare then
924 // structurally.
925 if (hash_t l_hash = peek_hash_value(*l))
926 if (hash_t r_hash = peek_hash_value(*r))
927 if (l_hash != r_hash)
929
930 return equals(*l, *r, 0);
931#else
932 if (const type_base *lc = l->get_naked_canonical_type())
933 if (const type_base *rc = r->get_naked_canonical_type())
934 ABG_RETURN_EQUAL(lc, rc);
935
936 // If the two types have a non-empty hash value, then consider those
937 // hash values. If the hashes are different then the two types are
938 // different. If the hashes are equal then we'll compare then
939 // structurally.
940 if (hash_t l_hash = peek_hash_value(*l))
941 if (hash_t r_hash = peek_hash_value(*r))
942 if (l_hash != r_hash)
944 return equals(*l, *r, 0);
945#endif
946}
947
948/// Detect if a recursive comparison cycle is detected while
949/// structurally comparing two types (a.k.a member-wise comparison).
950///
951/// @param l the left-hand-side operand of the current comparison.
952///
953/// @param r the right-hand-side operand of the current comparison.
954///
955/// @return true iff a comparison cycle is detected.
956template<typename T>
957bool
959{
960 bool result = l.priv_->comparison_started(l, r);
961 return result ;
962}
963
964/// Detect if a recursive comparison cycle is detected while
965/// structurally comparing two @ref class_decl types.
966///
967/// @param l the left-hand-side operand of the current comparison.
968///
969/// @param r the right-hand-side operand of the current comparison.
970///
971/// @return true iff a comparison cycle is detected.
972template<>
973bool
975{
976 return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
977 static_cast<const class_or_union&>(r));
978}
979
980/// This macro is to be used while comparing composite types that
981/// might recursively refer to themselves. Comparing two such types
982/// might get us into a cyle.
983///
984/// Practically, if we detect that we are already into comparing 'l'
985/// and 'r'; then, this is a cycle.
986//
987/// To break the cycle, we assume the result of the comparison is true
988/// for now. Comparing the other sub-types of l & r will tell us later
989/// if l & r are actually different or not.
990///
991/// In the mean time, returning true from this macro should not be
992/// used to propagate the canonical type of 'l' onto 'r' as we don't
993/// know yet if l equals r. All the types that depend on l and r
994/// can't (and that are in the comparison stack currently) can't have
995/// their canonical type propagated either. So this macro disallows
996/// canonical type propagation for those types that depend on a
997/// recursively defined sub-type for now.
998///
999/// @param l the left-hand-side operand of the comparison.
1000#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
1001 do \
1002 { \
1003 if (is_comparison_cycle_detected(l, r)) \
1004 return true; \
1005 } \
1006 while(false)
1007
1008
1009/// Mark a pair of types as being compared.
1010///
1011/// This is helpful to later detect recursive cycles in the comparison
1012/// stack.
1013///
1014/// @param l the left-hand-side operand of the comparison.
1015///
1016/// @parm r the right-hand-side operand of the comparison.
1017template<typename T>
1018void
1020{
1021 l.priv_->mark_as_being_compared(l, r);
1023}
1024
1025/// Mark a pair of @ref class_decl types as being compared.
1026///
1027/// This is helpful to later detect recursive cycles in the comparison
1028/// stack.
1029///
1030/// @param l the left-hand-side operand of the comparison.
1031///
1032/// @parm r the right-hand-side operand of the comparison.
1033template<>
1034void
1036{
1037 return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
1038 static_cast<const class_or_union&>(r));
1039}
1040
1041/// Mark a pair of types as being not compared anymore.
1042///
1043/// This is helpful to later detect recursive cycles in the comparison
1044/// stack.
1045///
1046/// Note that the types must have been passed to
1047/// mark_types_as_being_compared prior to calling this function.
1048///
1049/// @param l the left-hand-side operand of the comparison.
1050///
1051/// @parm r the right-hand-side operand of the comparison.
1052template<typename T>
1053void
1055{
1056 l.priv_->unmark_as_being_compared(l, r);
1058}
1059
1060/// Mark a pair of @ref class_decl types as being not compared
1061/// anymore.
1062///
1063/// This is helpful to later detect recursive cycles in the comparison
1064/// stack.
1065///
1066/// Note that the types must have been passed to
1067/// mark_types_as_being_compared prior to calling this function.
1068///
1069/// @param l the left-hand-side operand of the comparison.
1070///
1071/// @parm r the right-hand-side operand of the comparison.
1072template<>
1073void
1075{
1076 return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
1077 static_cast<const class_or_union&>(r));
1078}
1079
1080/// Return the result of the comparison of two (sub) types.
1081///
1082/// The function does the necessary book keeping before returning the
1083/// result of the comparison of two (sub) types.
1084///
1085/// The book-keeping done is essentially about type comparison cycle detection.
1086///
1087/// @param l the left-hand-side operand of the type comparison
1088///
1089/// @param r the right-hand-side operand of the type comparison
1090///
1091/// @param value the result of the comparison of @p l and @p r.
1092///
1093/// @return the value @p value.
1094template<typename T>
1095bool
1096return_comparison_result(T& l, T& r, bool value)
1097{
1099 ABG_RETURN(value);
1100}
1101
1102#define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1103 do \
1104 { \
1105 bool res = return_comparison_result(l, r, value); \
1106 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1107 return res; \
1108 } while (false)
1109
1110/// Cache the result of a comparison between too artifacts (l & r) and
1111/// return immediately.
1112///
1113/// @param value the value to cache.
1114#define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1115 do \
1116 { \
1117 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1118 return value; \
1119 } while (false)
1120
1121/// Getter of all types types sorted by their pretty representation.
1122///
1123/// @return a sorted vector of all types sorted by their pretty
1124/// representation.
1125const vector<type_base_wptr>&
1127{
1128 if (priv_->sorted_types_.empty())
1129 {
1130 istring_type_base_wptrs_map_type::const_iterator i;
1131 vector<type_base_wptr>::const_iterator j;
1132
1133 for (i = basic_types().begin(); i != basic_types().end(); ++i)
1134 for (j = i->second.begin(); j != i->second.end(); ++j)
1135 priv_->sorted_types_.push_back(*j);
1136
1137 for (i = class_types().begin(); i != class_types().end(); ++i)
1138 for (j = i->second.begin(); j != i->second.end(); ++j)
1139 priv_->sorted_types_.push_back(*j);
1140
1141 for (i = union_types().begin(); i != union_types().end(); ++i)
1142 for (j = i->second.begin(); j != i->second.end(); ++j)
1143 priv_->sorted_types_.push_back(*j);
1144
1145 for (i = enum_types().begin(); i != enum_types().end(); ++i)
1146 for (j = i->second.begin(); j != i->second.end(); ++j)
1147 priv_->sorted_types_.push_back(*j);
1148
1149 for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
1150 for (j = i->second.begin(); j != i->second.end(); ++j)
1151 priv_->sorted_types_.push_back(*j);
1152
1153 type_name_comp comp;
1154 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1155 }
1156
1157 return priv_->sorted_types_;
1158}
1159
1160// </type_maps stuff>
1161
1162// <translation_unit stuff>
1163
1164/// Constructor of translation_unit.
1165///
1166/// @param env the environment of this translation unit. Please note
1167/// that the life time of the environment must be greater than the
1168/// life time of the translation unit because the translation uses
1169/// resources that are allocated in the environment.
1170///
1171/// @param path the location of the translation unit.
1172///
1173/// @param address_size the size of addresses in the translation unit,
1174/// in bits.
1175translation_unit::translation_unit(const environment& env,
1176 const std::string& path,
1177 char address_size)
1178 : priv_(new priv(env))
1179{
1180 priv_->path_ = path;
1181 priv_->address_size_ = address_size;
1182}
1183
1184/// Getter of the the global scope of the translation unit.
1185///
1186/// @return the global scope of the current translation unit. If
1187/// there is not global scope allocated yet, this function creates one
1188/// and returns it.
1189const scope_decl_sptr&
1191{
1192 return const_cast<translation_unit*>(this)->get_global_scope();
1193}
1194
1195/// Getter of the global scope of the translation unit.
1196///
1197/// @return the global scope of the current translation unit. If
1198/// there is not allocated yet, this function creates one and returns
1199/// it.
1202{
1203 if (!priv_->global_scope_)
1204 {
1205 priv_->global_scope_.reset
1206 (new global_scope(const_cast<translation_unit*>(this)));
1207 priv_->global_scope_->set_translation_unit
1208 (const_cast<translation_unit*>(this));
1209 }
1210 return priv_->global_scope_;
1211}
1212
1213/// Getter of the types of the current @ref translation_unit.
1214///
1215/// @return the maps of the types of the translation unit.
1216const type_maps&
1218{return priv_->types_;}
1219
1220/// Getter of the types of the current @ref translation_unit.
1221///
1222/// @return the maps of the types of the translation unit.
1223type_maps&
1225{return priv_->types_;}
1226
1227/// Get the vector of function types that are used in the current
1228/// translation unit.
1229///
1230/// @return the vector of function types that are used in the current
1231/// translation unit.
1232const vector<function_type_sptr>&
1234{return priv_->live_fn_types_;}
1235
1236/// Getter of the environment of the current @ref translation_unit.
1237///
1238/// @return the translation unit of the current translation unit.
1239const environment&
1241{return priv_->env_;}
1242
1243/// Getter of the language of the source code of the translation unit.
1244///
1245/// @return the language of the source code.
1248{return priv_->language_;}
1249
1250/// Setter of the language of the source code of the translation unit.
1251///
1252/// @param l the new language.
1253void
1255{priv_->language_ = l;}
1256
1257
1258/// Get the path of the current translation unit.
1259///
1260/// This path is relative to the build directory of the translation
1261/// unit as returned by translation_unit::get_compilation_dir_path.
1262///
1263/// @return the relative path of the compilation unit associated to
1264/// the current instance of translation_unit.
1265//
1266const std::string&
1268{return priv_->path_;}
1269
1270/// Set the path associated to the current instance of
1271/// translation_unit.
1272///
1273/// This path is relative to the build directory of the translation
1274/// unit as returned by translation_unit::get_compilation_dir_path.
1275///
1276/// @param a_path the new relative path to set.
1277void
1278translation_unit::set_path(const string& a_path)
1279{priv_->path_ = a_path;}
1280
1281
1282/// Get the path of the directory that was 'current' when the
1283/// translation unit was compiled.
1284///
1285/// Note that the path returned by translation_unit::get_path is
1286/// relative to the path returned by this function.
1287///
1288/// @return the compilation directory for the current translation
1289/// unit.
1290const std::string&
1292{return priv_->comp_dir_path_;}
1293
1294/// Set the path of the directory that was 'current' when the
1295/// translation unit was compiled.
1296///
1297/// Note that the path returned by translation_unit::get_path is
1298/// relative to the path returned by this function.
1299///
1300/// @param the compilation directory for the current translation unit.
1301void
1303{priv_->comp_dir_path_ = d;}
1304
1305/// Get the concatenation of the build directory and the relative path
1306/// of the translation unit.
1307///
1308/// @return the absolute path of the translation unit.
1309const std::string&
1311{
1312 if (priv_->abs_path_.empty())
1313 {
1314 string path;
1315 if (!priv_->path_.empty())
1316 {
1317 if (!priv_->comp_dir_path_.empty())
1318 {
1319 path = priv_->comp_dir_path_;
1320 path += "/";
1321 }
1322 path += priv_->path_;
1323 }
1324 priv_->abs_path_ = path;
1325 }
1326
1327 return priv_->abs_path_;
1328}
1329
1330/// Set the corpus this translation unit is a member of.
1331///
1332/// Note that adding a translation unit to a @ref corpus automatically
1333/// triggers a call to this member function.
1334///
1335/// @param corpus the corpus.
1336void
1338{priv_->corp = c;}
1339
1340/// Get the corpus this translation unit is a member of.
1341///
1342/// @return the parent corpus, or nil if this doesn't belong to any
1343/// corpus yet.
1344corpus*
1346{return priv_->corp;}
1347
1348/// Get the corpus this translation unit is a member of.
1349///
1350/// @return the parent corpus, or nil if this doesn't belong to any
1351/// corpus yet.
1352const corpus*
1354{return const_cast<translation_unit*>(this)->get_corpus();}
1355
1356/// Getter of the location manager for the current translation unit.
1357///
1358/// @return a reference to the location manager for the current
1359/// translation unit.
1362{return priv_->loc_mgr_;}
1363
1364/// const Getter of the location manager.
1365///
1366/// @return a const reference to the location manager for the current
1367/// translation unit.
1368const location_manager&
1370{return priv_->loc_mgr_;}
1371
1372/// Tests whether if the current translation unit contains ABI
1373/// artifacts or not.
1374///
1375/// @return true iff the current translation unit is empty.
1376bool
1378{
1379 if (!priv_->global_scope_)
1380 return true;
1381 return get_global_scope()->is_empty();
1382}
1383
1384/// Getter of the address size in this translation unit.
1385///
1386/// @return the address size, in bits.
1387char
1389{return priv_->address_size_;}
1390
1391/// Setter of the address size in this translation unit.
1392///
1393/// @param a the new address size in bits.
1394void
1396{priv_->address_size_= a;}
1397
1398/// Getter of the 'is_constructed" flag. It says if the translation
1399/// unit is fully constructed or not.
1400///
1401/// This flag is important for cases when comparison might depend on
1402/// if the translation unit is fully built or not. For instance, when
1403/// reading types from DWARF, the virtual methods of a class are not
1404/// necessarily fully constructed until we have reached the end of the
1405/// translation unit. In that case, before we've reached the end of
1406/// the translation unit, we might not take virtual functions into
1407/// account when comparing classes.
1408///
1409/// @return true if the translation unit is constructed.
1410bool
1412{return priv_->is_constructed_;}
1413
1414/// Setter of the 'is_constructed" flag. It says if the translation
1415/// unit is fully constructed or not.
1416///
1417/// This flag is important for cases when comparison might depend on
1418/// if the translation unit is fully built or not. For instance, when
1419/// reading types from DWARF, the virtual methods of a class are not
1420/// necessarily fully constructed until we have reached the end of the
1421/// translation unit. In that case, before we've reached the end of
1422/// the translation unit, we might not take virtual functions into
1423/// account when comparing classes.
1424///
1425/// @param f true if the translation unit is constructed.
1426void
1428{priv_->is_constructed_ = f;}
1429
1430/// Compare the current translation unit against another one.
1431///
1432/// @param other the other tu to compare against.
1433///
1434/// @return true if the two translation units are equal, false
1435/// otherwise.
1436bool
1438{
1439 if (get_address_size() != other.get_address_size())
1440 return false;
1441
1442 return *get_global_scope() == *other.get_global_scope();
1443}
1444
1445/// Inequality operator.
1446///
1447/// @param o the instance of @ref translation_unit to compare the
1448/// current instance against.
1449///
1450/// @return true iff the current instance is different from @p o.
1451bool
1453{return ! operator==(o);}
1454
1455/// Ensure that the life time of a function type is bound to the life
1456/// time of the current translation unit.
1457///
1458/// @param ftype the function time which life time to bind to the life
1459/// time of the current instance of @ref translation_unit. That is,
1460/// it's onlyh when the translation unit is destroyed that the
1461/// function type can be destroyed to.
1462void
1464{
1465 const environment& env = get_environment();
1466
1467 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1468
1469 interned_string repr = get_type_name(ftype);
1470 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1471 push_back(ftype);
1472
1473 // The function type must be out of the same environment as its
1474 // translation unit.
1475 {
1476 const environment& e = ftype->get_environment();
1477 ABG_ASSERT(&env == &e);
1478 }
1479
1480 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1481 ABG_ASSERT(existing_tu == this);
1482 else
1483 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1484
1486}
1487
1488/// This implements the ir_traversable_base::traverse virtual
1489/// function.
1490///
1491/// @param v the visitor used on the member nodes of the translation
1492/// unit during the traversal.
1493///
1494/// @return true if the entire type IR tree got traversed, false
1495/// otherwise.
1496bool
1498{return get_global_scope()->traverse(v);}
1499
1500translation_unit::~translation_unit()
1501{}
1502
1503/// Converts a translation_unit::language enumerator into a string.
1504///
1505/// @param l the language enumerator to translate.
1506///
1507/// @return the resulting string.
1508string
1510{
1511 switch (l)
1512 {
1513 case translation_unit::LANG_UNKNOWN:
1514 return "LANG_UNKNOWN";
1515 case translation_unit::LANG_Cobol74:
1516 return "LANG_Cobol74";
1517 case translation_unit::LANG_Cobol85:
1518 return "LANG_Cobol85";
1519 case translation_unit::LANG_C89:
1520 return "LANG_C89";
1521 case translation_unit::LANG_C99:
1522 return "LANG_C99";
1523 case translation_unit::LANG_C11:
1524 return "LANG_C11";
1525 case translation_unit::LANG_C:
1526 return "LANG_C";
1527 case translation_unit::LANG_C_plus_plus_11:
1528 return "LANG_C_plus_plus_11";
1529 case translation_unit::LANG_C_plus_plus_14:
1530 return "LANG_C_plus_plus_14";
1531 case translation_unit::LANG_C_plus_plus:
1532 return "LANG_C_plus_plus";
1533 case translation_unit::LANG_ObjC:
1534 return "LANG_ObjC";
1535 case translation_unit::LANG_ObjC_plus_plus:
1536 return "LANG_ObjC_plus_plus";
1537 case translation_unit::LANG_Fortran77:
1538 return "LANG_Fortran77";
1539 case translation_unit::LANG_Fortran90:
1540 return "LANG_Fortran90";
1541 case translation_unit::LANG_Fortran95:
1542 return "LANG_Fortran95";
1543 case translation_unit::LANG_Ada83:
1544 return "LANG_Ada83";
1545 case translation_unit::LANG_Ada95:
1546 return "LANG_Ada95";
1547 case translation_unit::LANG_Pascal83:
1548 return "LANG_Pascal83";
1549 case translation_unit::LANG_Modula2:
1550 return "LANG_Modula2";
1551 case translation_unit::LANG_Java:
1552 return "LANG_Java";
1553 case translation_unit::LANG_PLI:
1554 return "LANG_PLI";
1555 case translation_unit::LANG_UPC:
1556 return "LANG_UPC";
1557 case translation_unit::LANG_D:
1558 return "LANG_D";
1559 case translation_unit::LANG_Python:
1560 return "LANG_Python";
1561 case translation_unit::LANG_Go:
1562 return "LANG_Go";
1563 case translation_unit::LANG_Mips_Assembler:
1564 return "LANG_Mips_Assembler";
1565 default:
1566 return "LANG_UNKNOWN";
1567 }
1568
1569 return "LANG_UNKNOWN";
1570}
1571
1572/// Parse a string representing a language into a
1573/// translation_unit::language enumerator into a string.
1574///
1575/// @param l the string representing the language.
1576///
1577/// @return the resulting translation_unit::language enumerator.
1580{
1581 if (l == "LANG_Cobol74")
1582 return translation_unit::LANG_Cobol74;
1583 else if (l == "LANG_Cobol85")
1584 return translation_unit::LANG_Cobol85;
1585 else if (l == "LANG_C89")
1586 return translation_unit::LANG_C89;
1587 else if (l == "LANG_C99")
1588 return translation_unit::LANG_C99;
1589 else if (l == "LANG_C11")
1590 return translation_unit::LANG_C11;
1591 else if (l == "LANG_C")
1592 return translation_unit::LANG_C;
1593 else if (l == "LANG_C_plus_plus_11")
1594 return translation_unit::LANG_C_plus_plus_11;
1595 else if (l == "LANG_C_plus_plus_14")
1596 return translation_unit::LANG_C_plus_plus_14;
1597 else if (l == "LANG_C_plus_plus")
1598 return translation_unit::LANG_C_plus_plus;
1599 else if (l == "LANG_ObjC")
1600 return translation_unit::LANG_ObjC;
1601 else if (l == "LANG_ObjC_plus_plus")
1602 return translation_unit::LANG_ObjC_plus_plus;
1603 else if (l == "LANG_Fortran77")
1604 return translation_unit::LANG_Fortran77;
1605 else if (l == "LANG_Fortran90")
1606 return translation_unit::LANG_Fortran90;
1607 else if (l == "LANG_Fortran95")
1608 return translation_unit::LANG_Fortran95;
1609 else if (l == "LANG_Ada83")
1610 return translation_unit::LANG_Ada83;
1611 else if (l == "LANG_Ada95")
1612 return translation_unit::LANG_Ada95;
1613 else if (l == "LANG_Pascal83")
1614 return translation_unit::LANG_Pascal83;
1615 else if (l == "LANG_Modula2")
1616 return translation_unit::LANG_Modula2;
1617 else if (l == "LANG_Java")
1618 return translation_unit::LANG_Java;
1619 else if (l == "LANG_PLI")
1620 return translation_unit::LANG_PLI;
1621 else if (l == "LANG_UPC")
1622 return translation_unit::LANG_UPC;
1623 else if (l == "LANG_D")
1624 return translation_unit::LANG_D;
1625 else if (l == "LANG_Python")
1626 return translation_unit::LANG_Python;
1627 else if (l == "LANG_Go")
1628 return translation_unit::LANG_Go;
1629 else if (l == "LANG_Mips_Assembler")
1630 return translation_unit::LANG_Mips_Assembler;
1631
1632 return translation_unit::LANG_UNKNOWN;
1633}
1634
1635/// Test if a language enumerator designates the C language.
1636///
1637/// @param l the language enumerator to consider.
1638///
1639/// @return true iff @p l designates the C language.
1640bool
1642{
1643 return (l == translation_unit::LANG_C89
1644 || l == translation_unit::LANG_C99
1645 || l == translation_unit::LANG_C11
1646 || l == translation_unit::LANG_C);
1647}
1648
1649/// Test if a language enumerator designates the C++ language.
1650///
1651/// @param l the language enumerator to consider.
1652///
1653/// @return true iff @p l designates the C++ language.
1654bool
1656{
1657 return (l == translation_unit::LANG_C_plus_plus_03
1658 || l == translation_unit::LANG_C_plus_plus_11
1659 || l == translation_unit::LANG_C_plus_plus_14
1660 || l == translation_unit::LANG_C_plus_plus);
1661}
1662
1663/// Test if a language enumerator designates the Java language.
1664///
1665/// @param l the language enumerator to consider.
1666///
1667/// @return true iff @p l designates the Java language.
1668bool
1670{return l == translation_unit::LANG_Java;}
1671
1672/// Test if a language enumerator designates the Ada language.
1673///
1674/// @param l the language enumerator to consider.
1675///
1676/// @return true iff @p l designates the Ada language.
1677bool
1679{
1680 return (l == translation_unit::LANG_Ada83
1681 || l == translation_unit::LANG_Ada95);
1682}
1683
1684/// A deep comparison operator for pointers to translation units.
1685///
1686/// @param l the first translation unit to consider for the comparison.
1687///
1688/// @param r the second translation unit to consider for the comparison.
1689///
1690/// @return true if the two translation units are equal, false otherwise.
1691bool
1693{
1694 if (l.get() == r.get())
1695 return true;
1696
1697 if (!!l != !!r)
1698 return false;
1699
1700 return *l == *r;
1701}
1702
1703/// A deep inequality operator for pointers to translation units.
1704///
1705/// @param l the first translation unit to consider for the comparison.
1706///
1707/// @param r the second translation unit to consider for the comparison.
1708///
1709/// @return true iff the two translation units are different.
1710bool
1712{return !operator==(l, r);}
1713
1714// </translation_unit stuff>
1715
1716// <elf_symbol stuff>
1717struct elf_symbol::priv
1718{
1719 const environment& env_;
1720 size_t index_;
1721 size_t size_;
1722 string name_;
1723 elf_symbol::type type_;
1724 elf_symbol::binding binding_;
1725 elf_symbol::version version_;
1726 elf_symbol::visibility visibility_;
1727 bool is_defined_;
1728 // This flag below says if the symbol is a common elf symbol. In
1729 // relocatable files, a common symbol is a symbol defined in a
1730 // section of kind SHN_COMMON.
1731 //
1732 // Note that a symbol of kind STT_COMMON is also considered a common
1733 // symbol. Here is what the gABI says about STT_COMMON and
1734 // SHN_COMMON:
1735 //
1736 // Symbols with type STT_COMMON label uninitialized common
1737 // blocks. In relocatable objects, these symbols are not
1738 // allocated and must have the special section index SHN_COMMON
1739 // (see below). In shared objects and executables these symbols
1740 // must be allocated to some section in the defining object.
1741 //
1742 // In relocatable objects, symbols with type STT_COMMON are
1743 // treated just as other symbols with index SHN_COMMON. If the
1744 // link-editor allocates space for the SHN_COMMON symbol in an
1745 // output section of the object it is producing, it must
1746 // preserve the type of the output symbol as STT_COMMON.
1747 //
1748 // When the dynamic linker encounters a reference to a symbol
1749 // that resolves to a definition of type STT_COMMON, it may (but
1750 // is not required to) change its symbol resolution rules as
1751 // follows: instead of binding the reference to the first symbol
1752 // found with the given name, the dynamic linker searches for
1753 // the first symbol with that name with type other than
1754 // STT_COMMON. If no such symbol is found, it looks for the
1755 // STT_COMMON definition of that name that has the largest size.
1756 bool is_common_;
1757 bool is_in_ksymtab_;
1760 bool is_suppressed_;
1761 elf_symbol_wptr main_symbol_;
1762 elf_symbol_wptr next_alias_;
1763 elf_symbol_wptr next_common_instance_;
1764 string id_string_;
1765
1766 priv(const environment& e)
1767 : env_(e),
1768 index_(),
1769 size_(),
1770 type_(elf_symbol::NOTYPE_TYPE),
1771 binding_(elf_symbol::GLOBAL_BINDING),
1772 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1773 is_defined_(false),
1774 is_common_(false),
1775 is_in_ksymtab_(false),
1776 crc_(),
1777 namespace_(),
1778 is_suppressed_(false)
1779 {}
1780
1781 priv(const environment& e,
1782 size_t i,
1783 size_t s,
1784 const string& n,
1787 bool d,
1788 bool c,
1789 const elf_symbol::version& ve,
1791 bool is_in_ksymtab,
1794 bool is_suppressed)
1795 : env_(e),
1796 index_(i),
1797 size_(s),
1798 name_(n),
1799 type_(t),
1800 binding_(b),
1801 version_(ve),
1802 visibility_(vi),
1803 is_defined_(d),
1804 is_common_(c),
1805 is_in_ksymtab_(is_in_ksymtab),
1806 crc_(crc),
1807 namespace_(ns),
1808 is_suppressed_(is_suppressed)
1809 {
1810 if (!is_common_)
1811 is_common_ = type_ == COMMON_TYPE;
1812 }
1813}; // end struct elf_symbol::priv
1814
1815/// Constructor of the @ref elf_symbol type.
1816///
1817/// Note that this constructor is private, so client code cannot use
1818/// it to create instances of @ref elf_symbol. Rather, client code
1819/// should use the @ref elf_symbol::create() function to create
1820/// instances of @ref elf_symbol instead.
1821///
1822/// @param e the environment we are operating from.
1823///
1824/// @param i the index of the symbol in the (ELF) symbol table.
1825///
1826/// @param s the size of the symbol.
1827///
1828/// @param n the name of the symbol.
1829///
1830/// @param t the type of the symbol.
1831///
1832/// @param b the binding of the symbol.
1833///
1834/// @param d true if the symbol is defined, false otherwise.
1835///
1836/// @param c true if the symbol is a common symbol, false otherwise.
1837///
1838/// @param ve the version of the symbol.
1839///
1840/// @param vi the visibility of the symbol.
1841///
1842/// @param crc the CRC (modversions) value of Linux Kernel symbols
1843///
1844/// @param ns the namespace of Linux Kernel symbols, if any
1845elf_symbol::elf_symbol(const environment& e,
1846 size_t i,
1847 size_t s,
1848 const string& n,
1849 type t,
1850 binding b,
1851 bool d,
1852 bool c,
1853 const version& ve,
1854 visibility vi,
1855 bool is_in_ksymtab,
1858 bool is_suppressed)
1859 : priv_(new priv(e,
1860 i,
1861 s,
1862 n,
1863 t,
1864 b,
1865 d,
1866 c,
1867 ve,
1868 vi,
1869 is_in_ksymtab,
1870 crc,
1871 ns,
1872 is_suppressed))
1873{}
1874
1875/// Factory of instances of @ref elf_symbol.
1876///
1877/// This is the function to use to create instances of @ref elf_symbol.
1878///
1879/// @param e the environment we are operating from.
1880///
1881/// @param i the index of the symbol in the (ELF) symbol table.
1882///
1883/// @param s the size of the symbol.
1884///
1885/// @param n the name of the symbol.
1886///
1887/// @param t the type of the symbol.
1888///
1889/// @param b the binding of the symbol.
1890///
1891/// @param d true if the symbol is defined, false otherwise.
1892///
1893/// @param c true if the symbol is a common symbol.
1894///
1895/// @param ve the version of the symbol.
1896///
1897/// @param vi the visibility of the symbol.
1898///
1899/// @param crc the CRC (modversions) value of Linux Kernel symbols
1900///
1901/// @param ns the namespace of Linux Kernel symbols, if any
1902///
1903/// @return a (smart) pointer to a newly created instance of @ref
1904/// elf_symbol.
1907 size_t i,
1908 size_t s,
1909 const string& n,
1910 type t,
1911 binding b,
1912 bool d,
1913 bool c,
1914 const version& ve,
1915 visibility vi,
1916 bool is_in_ksymtab,
1919 bool is_suppressed)
1920{
1921 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
1922 is_in_ksymtab, crc, ns, is_suppressed));
1923 sym->priv_->main_symbol_ = sym;
1924 return sym;
1925}
1926
1927/// Test textual equality between two symbols.
1928///
1929/// Textual equality means that the aliases of the compared symbols
1930/// are not taken into account. Only the name, type, and version of
1931/// the symbols are compared.
1932///
1933/// @return true iff the two symbols are textually equal.
1934static bool
1935textually_equals(const elf_symbol&l,
1936 const elf_symbol&r)
1937{
1938 bool equals = (l.get_name() == r.get_name()
1939 && l.get_type() == r.get_type()
1940 && l.is_public() == r.is_public()
1941 && l.is_defined() == r.is_defined()
1943 && l.get_version() == r.get_version()
1944 && l.get_crc() == r.get_crc()
1945 && l.get_namespace() == r.get_namespace());
1946
1947 if (equals && l.is_variable())
1948 // These are variable symbols. Let's compare their symbol size.
1949 // The symbol size in this case is the size taken by the storage
1950 // of the variable. If that size changes, then it's an ABI
1951 // change.
1952 equals = l.get_size() == r.get_size();
1953
1954 return equals;
1955}
1956
1957/// Getter of the environment used by the current instance of @ref
1958/// elf_symbol.
1959///
1960/// @return the enviroment used by the current instance of @ref elf_symbol.
1961const environment&
1963{return priv_->env_;}
1964
1965/// Getter for the index
1966///
1967/// @return the index of the symbol.
1968size_t
1970{return priv_->index_;}
1971
1972/// Setter for the index.
1973///
1974/// @param s the new index.
1975void
1977{priv_->index_ = s;}
1978
1979/// Getter for the name of the @ref elf_symbol.
1980///
1981/// @return a reference to the name of the @ref symbol.
1982const string&
1984{return priv_->name_;}
1985
1986/// Setter for the name of the current intance of @ref elf_symbol.
1987///
1988/// @param n the new name.
1989void
1990elf_symbol::set_name(const string& n)
1991{
1992 priv_->name_ = n;
1993 priv_->id_string_.clear();
1994}
1995
1996/// Getter for the type of the current instance of @ref elf_symbol.
1997///
1998/// @return the type of the elf symbol.
2001{return priv_->type_;}
2002
2003/// Setter for the type of the current instance of @ref elf_symbol.
2004///
2005/// @param t the new symbol type.
2006void
2008{priv_->type_ = t;}
2009
2010/// Getter of the size of the symbol.
2011///
2012/// @return the size of the symbol, in bytes.
2013size_t
2015{return priv_->size_;}
2016
2017/// Setter of the size of the symbol.
2018///
2019/// @param size the new size of the symbol, in bytes.
2020void
2022{priv_->size_ = size;}
2023
2024/// Getter for the binding of the current instance of @ref elf_symbol.
2025///
2026/// @return the binding of the symbol.
2029{return priv_->binding_;}
2030
2031/// Setter for the binding of the current instance of @ref elf_symbol.
2032///
2033/// @param b the new binding.
2034void
2036{priv_->binding_ = b;}
2037
2038/// Getter for the version of the current instanc of @ref elf_symbol.
2039///
2040/// @return the version of the elf symbol.
2043{return priv_->version_;}
2044
2045/// Setter for the version of the current instance of @ref elf_symbol.
2046///
2047/// @param v the new version of the elf symbol.
2048void
2050{
2051 priv_->version_ = v;
2052 priv_->id_string_.clear();
2053}
2054
2055/// Setter of the visibility of the current instance of @ref
2056/// elf_symbol.
2057///
2058/// @param v the new visibility of the elf symbol.
2059void
2061{priv_->visibility_ = v;}
2062
2063/// Getter of the visibility of the current instance of @ref
2064/// elf_symbol.
2065///
2066/// @return the visibility of the elf symbol.
2069{return priv_->visibility_;}
2070
2071/// Test if the current instance of @ref elf_symbol is defined or not.
2072///
2073/// @return true if the current instance of @ref elf_symbol is
2074/// defined, false otherwise.
2075bool
2077{return priv_->is_defined_;}
2078
2079/// Sets a flag saying if the current instance of @ref elf_symbol is
2080/// defined
2081///
2082/// @param b the new value of the flag.
2083void
2085{priv_->is_defined_ = d;}
2086
2087/// Test if the current instance of @ref elf_symbol is public or not.
2088///
2089/// This tests if the symbol is defined, has default or protected
2090///visibility, and either:
2091/// - has global binding
2092/// - has weak binding
2093/// - or has a GNU_UNIQUE binding.
2094///
2095/// return true if the current instance of @ref elf_symbol is public,
2096/// false otherwise.
2097bool
2099{
2100 return (is_defined()
2101 && (get_binding() == GLOBAL_BINDING
2102 || get_binding() == WEAK_BINDING
2103 || get_binding() == GNU_UNIQUE_BINDING)
2104 && (get_visibility() == DEFAULT_VISIBILITY
2105 || get_visibility() == PROTECTED_VISIBILITY));
2106}
2107
2108/// Test if the current instance of @ref elf_symbol is a function
2109/// symbol or not.
2110///
2111/// @return true if the current instance of @ref elf_symbol is a
2112/// function symbol, false otherwise.
2113bool
2115{return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2116
2117/// Test if the current instance of @ref elf_symbol is a variable
2118/// symbol or not.
2119///
2120/// @return true if the current instance of @ref elf_symbol is a
2121/// variable symbol, false otherwise.
2122bool
2124{
2125 return (get_type() == OBJECT_TYPE
2126 || get_type() == TLS_TYPE
2127 // It appears that undefined variables have NOTYPE type.
2128 || (get_type() == NOTYPE_TYPE
2129 && !is_defined()));
2130}
2131
2132/// Getter of the 'is-in-ksymtab' property.
2133///
2134/// @return true iff the current symbol is in the Linux Kernel
2135/// specific 'ksymtab' symbol table.
2136bool
2138{return priv_->is_in_ksymtab_;}
2139
2140/// Setter of the 'is-in-ksymtab' property.
2141///
2142/// @param is_in_ksymtab this is true iff the current symbol is in the
2143/// Linux Kernel specific 'ksymtab' symbol table.
2144void
2146{priv_->is_in_ksymtab_ = is_in_ksymtab;}
2147
2148/// Getter of the 'crc' property.
2149///
2150/// @return the CRC (modversions) value for Linux Kernel symbols, if any
2153{return priv_->crc_;}
2154
2155/// Setter of the 'crc' property.
2156///
2157/// @param crc the new CRC (modversions) value for Linux Kernel symbols
2158void
2160{priv_->crc_ = crc;}
2161
2162/// Getter of the 'namespace' property.
2163///
2164/// @return the namespace for Linux Kernel symbols, if any
2167{return priv_->namespace_;}
2168
2169/// Setter of the 'namespace' property.
2170///
2171/// @param ns the new namespace for Linux Kernel symbols, if any
2172void
2174{priv_->namespace_ = ns;}
2175
2176/// Getter for the 'is-suppressed' property.
2177///
2178/// @return true iff the current symbol has been suppressed by a
2179/// suppression specification that was provided in the context that
2180/// led to the creation of the corpus this ELF symbol belongs to.
2181bool
2183{return priv_->is_suppressed_;}
2184
2185/// Setter for the 'is-suppressed' property.
2186///
2187/// @param true iff the current symbol has been suppressed by a
2188/// suppression specification that was provided in the context that
2189/// led to the creation of the corpus this ELF symbol belongs to.
2190void
2192{priv_->is_suppressed_ = is_suppressed;}
2193
2194/// @name Elf symbol aliases
2195///
2196/// An alias A for an elf symbol S is a symbol that is defined at the
2197/// same address as S. S is chained to A through the
2198/// elf_symbol::get_next_alias() method.
2199///
2200/// When there are several aliases to a symbol, the main symbol is the
2201/// the first symbol found in the symbol table for a given address.
2202///
2203/// The alias chain is circular. That means if S is the main symbol
2204/// and A is the alias, S is chained to A and A
2205/// is chained back to the main symbol S. The last alias in an alias
2206///chain is always chained to the main symbol.
2207///
2208/// Thus, when looping over the aliases of an elf_symbol A, detecting
2209/// an alias that is equal to the main symbol should logically be a
2210/// loop exit condition.
2211///
2212/// Accessing and adding aliases for instances of elf_symbol is done
2213/// through the member functions below.
2214
2215/// @{
2216
2217/// Get the main symbol of an alias chain.
2218///
2219///@return the main symbol.
2220const elf_symbol_sptr
2222{return priv_->main_symbol_.lock();}
2223
2224/// Get the main symbol of an alias chain.
2225///
2226///@return the main symbol.
2229{return priv_->main_symbol_.lock();}
2230
2231/// Tests whether this symbol is the main symbol.
2232///
2233/// @return true iff this symbol is the main symbol.
2234bool
2236{return get_main_symbol().get() == this;}
2237
2238/// Get the next alias of the current symbol.
2239///
2240///@return the alias, or NULL if there is no alias.
2243{return priv_->next_alias_.lock();}
2244
2245
2246/// Check if the current elf_symbol has an alias.
2247///
2248///@return true iff the current elf_symbol has an alias.
2249bool
2251{return bool(get_next_alias());}
2252
2253/// Get the number of aliases to this elf symbol
2254///
2255/// @return the number of aliases to this elf symbol.
2256int
2258{
2259 int result = 0;
2260
2262 a && a.get() != get_main_symbol().get();
2263 a = a->get_next_alias())
2264 ++result;
2265
2266 return result;
2267}
2268
2269/// Add an alias to the current elf symbol.
2270///
2271/// @param alias the new alias. Note that this elf_symbol should *NOT*
2272/// have aliases prior to the invocation of this function.
2273void
2275{
2276 if (!alias)
2277 return;
2278
2279 ABG_ASSERT(!alias->has_aliases());
2281
2282 if (has_aliases())
2283 {
2284 elf_symbol_sptr last_alias;
2286 a && !a->is_main_symbol();
2287 a = a->get_next_alias())
2288 {
2289 if (a->get_next_alias()->is_main_symbol())
2290 {
2291 ABG_ASSERT(last_alias == 0);
2292 last_alias = a;
2293 }
2294 }
2295 ABG_ASSERT(last_alias);
2296
2297 last_alias->priv_->next_alias_ = alias;
2298 }
2299 else
2300 priv_->next_alias_ = alias;
2301
2302 alias->priv_->next_alias_ = get_main_symbol();
2303 alias->priv_->main_symbol_ = get_main_symbol();
2304}
2305
2306/// Update the main symbol for a group of aliased symbols
2307///
2308/// If after the construction of the symbols (in order of discovery), the
2309/// actual main symbol can be identified (e.g. as the symbol that actually is
2310/// defined in the code), this method offers a way of updating the main symbol
2311/// through one of the aliased symbols.
2312///
2313/// For that, locate the new main symbol by name and update all references to
2314/// the main symbol among the group of aliased symbols.
2315///
2316/// @param name the name of the main symbol
2317///
2318/// @return the new main elf_symbol
2320elf_symbol::update_main_symbol(const std::string& name)
2321{
2323 if (!has_aliases() || get_name() == name)
2324 return get_main_symbol();
2325
2326 // find the new main symbol
2327 elf_symbol_sptr new_main;
2328 // we've already checked this; check the rest of the aliases
2329 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2330 a = a->get_next_alias())
2331 if (a->get_name() == name)
2332 {
2333 new_main = a;
2334 break;
2335 }
2336
2337 if (!new_main)
2338 return get_main_symbol();
2339
2340 // now update all main symbol references
2341 priv_->main_symbol_ = new_main;
2342 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2343 a = a->get_next_alias())
2344 a->priv_->main_symbol_ = new_main;
2345
2346 return new_main;
2347}
2348
2349/// Return true if the symbol is a common one.
2350///
2351/// @return true iff the symbol is common.
2352bool
2354{return priv_->is_common_;}
2355
2356/// Return true if this common common symbol has other common instances.
2357///
2358/// A common instance of a given common symbol is another common
2359/// symbol with the same name. Those exist in relocatable files. The
2360/// linker normally allocates all the instances into a common block in
2361/// the final output file.
2362///
2363/// Note that the current object must be a common symbol, otherwise,
2364/// this function aborts.
2365///
2366/// @return true iff the current common symbol has other common
2367/// instances.
2368bool
2370{
2372 return bool(get_next_common_instance());
2373}
2374
2375/// Get the next common instance of the current common symbol.
2376///
2377/// A common instance of a given common symbol is another common
2378/// symbol with the same name. Those exist in relocatable files. The
2379/// linker normally allocates all the instances into a common block in
2380/// the final output file.
2381///
2382/// @return the next common instance, or nil if there is not any.
2385{return priv_->next_common_instance_.lock();}
2386
2387/// Add a common instance to the current common elf symbol.
2388///
2389/// Note that this symbol must be the main symbol. Being the main
2390/// symbol means being the first common symbol to appear in the symbol
2391/// table.
2392///
2393/// @param common the other common instance to add.
2394void
2396{
2397 if (!common)
2398 return;
2399
2400 ABG_ASSERT(!common->has_other_common_instances());
2403
2405 {
2406 elf_symbol_sptr last_common_instance;
2408 c && (c.get() != get_main_symbol().get());
2409 c = c->get_next_common_instance())
2410 {
2411 if (c->get_next_common_instance().get() == get_main_symbol().get())
2412 {
2413 ABG_ASSERT(last_common_instance == 0);
2414 last_common_instance = c;
2415 }
2416 }
2417 ABG_ASSERT(last_common_instance);
2418
2419 last_common_instance->priv_->next_common_instance_ = common;
2420 }
2421 else
2422 priv_->next_common_instance_ = common;
2423
2424 common->priv_->next_common_instance_ = get_main_symbol();
2425 common->priv_->main_symbol_ = get_main_symbol();
2426}
2427
2428/// Get a string that is representative of a given elf_symbol.
2429///
2430/// If the symbol has a version, then the ID string is the
2431/// concatenation of the name of the symbol, the '@' character, and
2432/// the version of the symbol. If the version is the default version
2433/// of the symbol then the '@' character is replaced by a "@@" string.
2434///
2435/// Otherwise, if the symbol does not have any version, this function
2436/// returns the name of the symbol.
2437///
2438/// @return a the ID string.
2439const string&
2441{
2442 if (priv_->id_string_.empty())
2443 {
2444 string s = get_name ();
2445
2446 if (!get_version().is_empty())
2447 {
2448 if (get_version().is_default())
2449 s += "@@";
2450 else
2451 s += "@";
2452 s += get_version().str();
2453 }
2454 priv_->id_string_ = s;
2455 }
2456
2457 return priv_->id_string_;
2458}
2459
2460/// From the aliases of the current symbol, lookup one with a given name.
2461///
2462/// @param name the name of symbol alias we are looking for.
2463///
2464/// @return the symbol alias that has the name @p name, or nil if none
2465/// has been found.
2467elf_symbol::get_alias_from_name(const string& name) const
2468{
2469 if (name == get_name())
2470 return elf_symbol_sptr(priv_->main_symbol_);
2471
2473 a && a.get() != get_main_symbol().get();
2474 a = a->get_next_alias())
2475 if (a->get_name() == name)
2476 return a;
2477
2478 return elf_symbol_sptr();
2479}
2480
2481/// In the list of aliases of a given elf symbol, get the alias that
2482/// equals this current symbol.
2483///
2484/// @param other the elf symbol to get the potential aliases from.
2485///
2486/// @return the alias of @p other that texually equals the current
2487/// symbol, or nil if no alias textually equals the current symbol.
2490{
2491 for (elf_symbol_sptr a = other.get_next_alias();
2492 a && a.get() != a->get_main_symbol().get();
2493 a = a->get_next_alias())
2494 if (textually_equals(*this, *a))
2495 return a;
2496 return elf_symbol_sptr();
2497}
2498
2499/// Return a comma separated list of the id of the current symbol as
2500/// well as the id string of its aliases.
2501///
2502/// @param syms a map of all the symbols of the corpus the current
2503/// symbol belongs to.
2504///
2505/// @param include_symbol_itself if set to true, then the name of the
2506/// current symbol is included in the list of alias names that is emitted.
2507///
2508/// @return the string.
2509string
2511 bool include_symbol_itself) const
2512{
2513 string result;
2514
2515 if (include_symbol_itself)
2516 result = get_id_string();
2517
2518 vector<elf_symbol_sptr> aliases;
2519 compute_aliases_for_elf_symbol(*this, syms, aliases);
2520 if (!aliases.empty() && include_symbol_itself)
2521 result += ", ";
2522
2523 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2524 i != aliases.end();
2525 ++i)
2526 {
2527 if (i != aliases.begin())
2528 result += ", ";
2529 result += (*i)->get_id_string();
2530 }
2531 return result;
2532}
2533
2534/// Return a comma separated list of the id of the current symbol as
2535/// well as the id string of its aliases.
2536///
2537/// @param include_symbol_itself if set to true, then the name of the
2538/// current symbol is included in the list of alias names that is emitted.
2539///
2540/// @return the string.
2541string
2542elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2543{
2544 vector<elf_symbol_sptr> aliases;
2545 if (include_symbol_itself)
2546 aliases.push_back(get_main_symbol());
2547
2549 a && a.get() != get_main_symbol().get();
2550 a = a->get_next_alias())
2551 aliases.push_back(a);
2552
2553 string result;
2554 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2555 i != aliases.end();
2556 ++i)
2557 {
2558 if (i != aliases.begin())
2559 result += ", ";
2560 result += (*i)->get_id_string();
2561 }
2562
2563 return result;
2564}
2565
2566/// Given the ID of a symbol, get the name and the version of said
2567/// symbol.
2568///
2569/// @param id the symbol ID to consider.
2570///
2571/// @param name the symbol name extracted from the ID. This is set
2572/// only if the function returned true.
2573///
2574/// @param ver the symbol version extracted from the ID.
2575bool
2577 string& name,
2578 string& ver)
2579{
2580 name.clear(), ver.clear();
2581
2582 string::size_type i = id.find('@');
2583 if (i == string::npos)
2584 {
2585 name = id;
2586 return true;
2587 }
2588
2589 name = id.substr(0, i);
2590 ++i;
2591
2592 if (i >= id.size())
2593 return true;
2594
2595 string::size_type j = id.find('@', i);
2596 if (j == string::npos)
2597 j = i;
2598 else
2599 ++j;
2600
2601 if (j >= id.size())
2602 {
2603 ver = "";
2604 return true;
2605 }
2606
2607 ver = id.substr(j);
2608 return true;
2609}
2610
2611///@}
2612
2613/// Test if two main symbols are textually equal, or, if they have
2614/// aliases that are textually equal.
2615///
2616/// @param other the symbol to compare against.
2617///
2618/// @return true iff the current instance of elf symbol equals the @p
2619/// other.
2620bool
2622{
2623 bool are_equal = textually_equals(*this, other);
2624 if (!are_equal)
2625 are_equal = bool(get_alias_which_equals(other));
2626 return are_equal;
2627}
2628
2629/// Test if the current symbol aliases another one.
2630///
2631/// @param o the other symbol to test against.
2632///
2633/// @return true iff the current symbol aliases @p o.
2634bool
2636{
2637 if (*this == o)
2638 return true;
2639
2640 if (get_main_symbol() == o.get_main_symbol())
2641 return true;
2642
2644 a && !a->is_main_symbol();
2645 a = a->get_next_alias())
2646 {
2647 if (o == *a)
2648 return true;
2649 }
2650 return false;
2651}
2652
2653/// Equality operator for smart pointers to elf_symbol.
2654///
2655/// @param lhs the first elf symbol to consider.
2656///
2657/// @param rhs the second elf symbol to consider.
2658///
2659/// @return true iff @p lhs equals @p rhs.
2660bool
2662{
2663 if (!!lhs != !!rhs)
2664 return false;
2665
2666 if (!lhs)
2667 return true;
2668
2669 return *lhs == *rhs;
2670}
2671
2672/// Inequality operator for smart pointers to elf_symbol.
2673///
2674/// @param lhs the first elf symbol to consider.
2675///
2676/// @param rhs the second elf symbol to consider.
2677///
2678/// @return true iff @p lhs is different from @p rhs.
2679bool
2681{return !operator==(lhs, rhs);}
2682
2683/// Test if two symbols alias.
2684///
2685/// @param s1 the first symbol to consider.
2686///
2687/// @param s2 the second symbol to consider.
2688///
2689/// @return true if @p s1 aliases @p s2.
2690bool
2692{return s1.does_alias(s2) || s2.does_alias(s1);}
2693
2694void
2695compute_aliases_for_elf_symbol(const elf_symbol& sym,
2696 const string_elf_symbols_map_type& symtab,
2697 vector<elf_symbol_sptr>& aliases)
2698{
2699
2700 if (elf_symbol_sptr a = sym.get_next_alias())
2701 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2702 aliases.push_back(a);
2703 else
2704 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2705 i != symtab.end();
2706 ++i)
2707 for (elf_symbols::const_iterator j = i->second.begin();
2708 j != i->second.end();
2709 ++j)
2710 {
2711 if (**j == sym)
2712 for (elf_symbol_sptr s = (*j)->get_next_alias();
2713 s && !s->is_main_symbol();
2714 s = s->get_next_alias())
2715 aliases.push_back(s);
2716 else
2717 for (elf_symbol_sptr s = (*j)->get_next_alias();
2718 s && !s->is_main_symbol();
2719 s = s->get_next_alias())
2720 if (*s == sym)
2721 aliases.push_back(*j);
2722 }
2723}
2724
2725/// Test if two symbols alias.
2726///
2727/// @param s1 the first symbol to consider.
2728///
2729/// @param s2 the second symbol to consider.
2730///
2731/// @return true if @p s1 aliases @p s2.
2732bool
2734{
2735 if (!!s1 != !!s2)
2736 return false;
2737 if (s1 == s2)
2738 return true;
2739 return elf_symbols_alias(*s1, *s2);
2740}
2741
2742/// Test if two symbols alias.
2743///
2744/// @param s1 the first symbol to consider.
2745///
2746/// @param s2 the second symbol to consider.
2747///
2748/// @return true if @p s1 aliases @p s2.
2749bool
2751{return elf_symbols_alias(s1.get(), s2.get());}
2752
2753/// Serialize an instance of @ref symbol_type and stream it to a given
2754/// output stream.
2755///
2756/// @param o the output stream to serialize the symbole type to.
2757///
2758/// @param t the symbol type to serialize.
2759std::ostream&
2760operator<<(std::ostream& o, elf_symbol::type t)
2761{
2762 string repr;
2763
2764 switch (t)
2765 {
2766 case elf_symbol::NOTYPE_TYPE:
2767 repr = "unspecified symbol type";
2768 break;
2769 case elf_symbol::OBJECT_TYPE:
2770 repr = "variable symbol type";
2771 break;
2772 case elf_symbol::FUNC_TYPE:
2773 repr = "function symbol type";
2774 break;
2775 case elf_symbol::SECTION_TYPE:
2776 repr = "section symbol type";
2777 break;
2778 case elf_symbol::FILE_TYPE:
2779 repr = "file symbol type";
2780 break;
2781 case elf_symbol::COMMON_TYPE:
2782 repr = "common data object symbol type";
2783 break;
2784 case elf_symbol::TLS_TYPE:
2785 repr = "thread local data object symbol type";
2786 break;
2787 case elf_symbol::GNU_IFUNC_TYPE:
2788 repr = "indirect function symbol type";
2789 break;
2790 default:
2791 {
2792 std::ostringstream s;
2793 s << "unknown symbol type (" << (char)t << ')';
2794 repr = s.str();
2795 }
2796 break;
2797 }
2798
2799 o << repr;
2800 return o;
2801}
2802
2803/// Serialize an instance of @ref symbol_binding and stream it to a
2804/// given output stream.
2805///
2806/// @param o the output stream to serialize the symbole type to.
2807///
2808/// @param b the symbol binding to serialize.
2809std::ostream&
2810operator<<(std::ostream& o, elf_symbol::binding b)
2811{
2812 string repr;
2813
2814 switch (b)
2815 {
2816 case elf_symbol::LOCAL_BINDING:
2817 repr = "local binding";
2818 break;
2819 case elf_symbol::GLOBAL_BINDING:
2820 repr = "global binding";
2821 break;
2822 case elf_symbol::WEAK_BINDING:
2823 repr = "weak binding";
2824 break;
2825 case elf_symbol::GNU_UNIQUE_BINDING:
2826 repr = "GNU unique binding";
2827 break;
2828 default:
2829 {
2830 std::ostringstream s;
2831 s << "unknown binding (" << (unsigned char) b << ")";
2832 repr = s.str();
2833 }
2834 break;
2835 }
2836
2837 o << repr;
2838 return o;
2839}
2840
2841/// Serialize an instance of @ref elf_symbol::visibility and stream it
2842/// to a given output stream.
2843///
2844/// @param o the output stream to serialize the symbole type to.
2845///
2846/// @param v the symbol visibility to serialize.
2847std::ostream&
2848operator<<(std::ostream& o, elf_symbol::visibility v)
2849{
2850 string repr;
2851
2852 switch (v)
2853 {
2854 case elf_symbol::DEFAULT_VISIBILITY:
2855 repr = "default visibility";
2856 break;
2857 case elf_symbol::PROTECTED_VISIBILITY:
2858 repr = "protected visibility";
2859 break;
2860 case elf_symbol::HIDDEN_VISIBILITY:
2861 repr = "hidden visibility";
2862 break;
2863 case elf_symbol::INTERNAL_VISIBILITY:
2864 repr = "internal visibility";
2865 break;
2866 default:
2867 {
2868 std::ostringstream s;
2869 s << "unknown visibility (" << (unsigned char) v << ")";
2870 repr = s.str();
2871 }
2872 break;
2873 }
2874
2875 o << repr;
2876 return o;
2877}
2878
2879/// Convert a string representing a symbol type into an
2880/// elf_symbol::type.
2881///
2882///@param s the string to convert.
2883///
2884///@param t the resulting elf_symbol::type.
2885///
2886/// @return true iff the conversion completed successfully.
2887bool
2889{
2890 if (s == "no-type")
2891 t = elf_symbol::NOTYPE_TYPE;
2892 else if (s == "object-type")
2893 t = elf_symbol::OBJECT_TYPE;
2894 else if (s == "func-type")
2895 t = elf_symbol::FUNC_TYPE;
2896 else if (s == "section-type")
2897 t = elf_symbol::SECTION_TYPE;
2898 else if (s == "file-type")
2899 t = elf_symbol::FILE_TYPE;
2900 else if (s == "common-type")
2901 t = elf_symbol::COMMON_TYPE;
2902 else if (s == "tls-type")
2903 t = elf_symbol::TLS_TYPE;
2904 else if (s == "gnu-ifunc-type")
2905 t = elf_symbol::GNU_IFUNC_TYPE;
2906 else
2907 return false;
2908
2909 return true;
2910}
2911
2912/// Convert a string representing a an elf symbol binding into an
2913/// elf_symbol::binding.
2914///
2915/// @param s the string to convert.
2916///
2917/// @param b the resulting elf_symbol::binding.
2918///
2919/// @return true iff the conversion completed successfully.
2920bool
2922{
2923 if (s == "local-binding")
2924 b = elf_symbol::LOCAL_BINDING;
2925 else if (s == "global-binding")
2926 b = elf_symbol::GLOBAL_BINDING;
2927 else if (s == "weak-binding")
2928 b = elf_symbol::WEAK_BINDING;
2929 else if (s == "gnu-unique-binding")
2930 b = elf_symbol::GNU_UNIQUE_BINDING;
2931 else
2932 return false;
2933
2934 return true;
2935}
2936
2937/// Convert a string representing a an elf symbol visibility into an
2938/// elf_symbol::visibility.
2939///
2940/// @param s the string to convert.
2941///
2942/// @param b the resulting elf_symbol::visibility.
2943///
2944/// @return true iff the conversion completed successfully.
2945bool
2947{
2948 if (s == "default-visibility")
2949 v = elf_symbol::DEFAULT_VISIBILITY;
2950 else if (s == "protected-visibility")
2951 v = elf_symbol::PROTECTED_VISIBILITY;
2952 else if (s == "hidden-visibility")
2953 v = elf_symbol::HIDDEN_VISIBILITY;
2954 else if (s == "internal-visibility")
2955 v = elf_symbol::INTERNAL_VISIBILITY;
2956 else
2957 return false;
2958
2959 return true;
2960}
2961
2962/// Test if the type of an ELF symbol denotes a function symbol.
2963///
2964/// @param t the type of the ELF symbol.
2965///
2966/// @return true iff elf symbol type @p t denotes a function symbol
2967/// type.
2968bool
2970{return t == elf_symbol::FUNC_TYPE;}
2971
2972/// Test if the type of an ELF symbol denotes a function symbol.
2973///
2974/// @param t the type of the ELF symbol.
2975///
2976/// @return true iff elf symbol type @p t denotes a function symbol
2977/// type.
2978bool
2980{return t == elf_symbol::OBJECT_TYPE;}
2981
2982// <elf_symbol::version stuff>
2983
2984struct elf_symbol::version::priv
2985{
2986 string version_;
2987 bool is_default_;
2988
2989 priv()
2990 : is_default_(false)
2991 {}
2992
2993 priv(const string& v,
2994 bool d)
2995 : version_(v),
2996 is_default_(d)
2997 {}
2998}; // end struct elf_symbol::version::priv
2999
3000elf_symbol::version::version()
3001 : priv_(new priv)
3002{}
3003
3004/// @param v the name of the version.
3005///
3006/// @param is_default true if this is a default version.
3007elf_symbol::version::version(const string& v,
3008 bool is_default)
3009 : priv_(new priv(v, is_default))
3010{}
3011
3012elf_symbol::version::version(const elf_symbol::version& v)
3013 : priv_(new priv(v.str(), v.is_default()))
3014{
3015}
3016
3017elf_symbol::version::~version() = default;
3018
3019/// Cast the version_type into a string that is its name.
3020///
3021/// @return the name of the version.
3022elf_symbol::version::operator const string&() const
3023{return priv_->version_;}
3024
3025/// Getter for the version name.
3026///
3027/// @return the version name.
3028const string&
3030{return priv_->version_;}
3031
3032/// Setter for the version name.
3033///
3034/// @param s the version name.
3035void
3037{priv_->version_ = s;}
3038
3039/// Getter for the 'is_default' property of the version.
3040///
3041/// @return true iff this is a default version.
3042bool
3044{return priv_->is_default_;}
3045
3046/// Setter for the 'is_default' property of the version.
3047///
3048/// @param f true if this is the default version.
3049void
3051{priv_->is_default_ = f;}
3052
3053bool
3054elf_symbol::version::is_empty() const
3055{return str().empty();}
3056
3057/// Compares the current version against another one.
3058///
3059/// @param o the other version to compare the current one to.
3060///
3061/// @return true iff the current version equals @p o.
3062bool
3064{return str() == o.str();}
3065
3066/// Inequality operator.
3067///
3068/// @param o the version to compare against the current one.
3069///
3070/// @return true iff both versions are different.
3071bool
3073{return !operator==(o);}
3074
3075/// Assign a version to the current one.
3076///
3077/// @param o the other version to assign to this one.
3078///
3079/// @return a reference to the assigned version.
3082{
3083 str(o.str());
3084 is_default(o.is_default());
3085 return *this;
3086}
3087
3088// </elf_symbol::version stuff>
3089
3090// </elf_symbol stuff>
3091
3092// <class dm_context_rel stuff>
3093struct dm_context_rel::priv
3094{
3095 bool is_laid_out_;
3096 size_t offset_in_bits_;
3097 var_decl* anonymous_data_member_;
3098
3099 priv(bool is_static = false)
3100 : is_laid_out_(!is_static),
3101 offset_in_bits_(0),
3102 anonymous_data_member_()
3103 {}
3104
3105 priv(bool is_laid_out, size_t offset_in_bits)
3106 : is_laid_out_(is_laid_out),
3107 offset_in_bits_(offset_in_bits),
3108 anonymous_data_member_()
3109 {}
3110}; //end struct dm_context_rel::priv
3111
3112dm_context_rel::dm_context_rel()
3113 : context_rel(),
3114 priv_(new priv)
3115{}
3116
3117dm_context_rel::dm_context_rel(scope_decl* s,
3118 bool is_laid_out,
3119 size_t offset_in_bits,
3121 bool is_static)
3122 : context_rel(s, a, is_static),
3123 priv_(new priv(is_laid_out, offset_in_bits))
3124{}
3125
3126dm_context_rel::dm_context_rel(scope_decl* s)
3127 : context_rel(s),
3128 priv_(new priv())
3129{}
3130
3131bool
3132dm_context_rel::get_is_laid_out() const
3133{return priv_->is_laid_out_;}
3134
3135void
3136dm_context_rel::set_is_laid_out(bool f)
3137{priv_->is_laid_out_ = f;}
3138
3139size_t
3140dm_context_rel::get_offset_in_bits() const
3141{return priv_->offset_in_bits_;}
3142
3143void
3144dm_context_rel::set_offset_in_bits(size_t o)
3145{priv_->offset_in_bits_ = o;}
3146
3147bool
3148dm_context_rel::operator==(const dm_context_rel& o) const
3149{
3150 if (!context_rel::operator==(o))
3151 return false;
3152
3153 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3154 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3155}
3156
3157bool
3158dm_context_rel::operator!=(const dm_context_rel& o) const
3159{return !operator==(o);}
3160
3161/// Return a non-nil value if this data member context relationship
3162/// has an anonymous data member. That means, if the data member this
3163/// relation belongs to is part of an anonymous data member.
3164///
3165/// @return the containing anonymous data member of this data member
3166/// relationship. Nil if there is none.
3167const var_decl*
3169{return priv_->anonymous_data_member_;}
3170
3171/// Set the containing anonymous data member of this data member
3172/// context relationship. That means that the data member this
3173/// relation belongs to is part of an anonymous data member.
3174///
3175/// @param anon_dm the containing anonymous data member of this data
3176/// member relationship. Nil if there is none.
3177void
3179{priv_->anonymous_data_member_ = anon_dm;}
3180
3181dm_context_rel::~dm_context_rel()
3182{}
3183// </class dm_context_rel stuff>
3184
3185// <environment stuff>
3186
3187/// Convenience typedef for a map of interned_string -> bool.
3188typedef unordered_map<interned_string,
3190
3191
3192/// Default constructor of the @ref environment type.
3194 :priv_(new priv)
3195{}
3196
3197/// Destructor for the @ref environment type.
3199{}
3200
3201/// Getter the map of canonical types.
3202///
3203/// @return the map of canonical types. The key of the map is the
3204/// hash of the canonical type and its value if the canonical type.
3207{return priv_->canonical_types_;}
3208
3209/// Getter the map of canonical types.
3210///
3211/// @return the map of canonical types. The key of the map is the
3212/// hash of the canonical type and its value if the canonical type.
3215{return const_cast<environment*>(this)->get_canonical_types_map();}
3216
3217/// Helper to detect if a type is either a reference, a pointer, or a
3218/// qualified type.
3219bool
3221{
3222 if (is_pointer_type(t)
3223 || is_reference_type(t)
3224 || is_qualified_type(t))
3225 return true;
3226 return false;
3227}
3228
3229/// Compare decls using their locations.
3230///
3231/// @param f the first decl to compare.
3232///
3233/// @param s the second decl to compare.
3234///
3235/// @return true if @p f compares less than @p s.
3236bool
3238 const decl_base *s)
3239{
3240 // If a decl has artificial location, then use that one over the
3241 // natural one.
3244
3245 ABG_ASSERT(fl.get_value() && sl.get_value());
3246 if (fl.get_is_artificial() == sl.get_is_artificial())
3247 {
3248 // The locations of the two artfifacts have the same
3249 // artificial-ness so they can be compared.
3250 string p1, p2;
3251 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3252 fl.expand(p1, l1, c1);
3253 sl.expand(p2, l2, c2);
3254 if (p1 != p2)
3255 return p1 < p2;
3256 if (l1 != l2)
3257 return l1 < l2;
3258 if (c1 != c2)
3259 return c1 < c2;
3260 }
3261
3262 return (get_pretty_representation(f, /*internal=*/false)
3263 < get_pretty_representation(s, /*internal=*/false));
3264}
3265
3266/// Sort types in a hopefully stable manner.
3267///
3268/// @param types a set of types with canonical types to sort.
3269///
3270/// @param result the resulting sorted vector.
3271void
3273 vector<type_base_sptr>& result)
3274{
3275 for (auto t: types)
3276 result.push_back(t);
3277
3278 type_topo_comp comp;
3279 std::stable_sort(result.begin(), result.end(), comp);
3280}
3281
3282/// Get the unique @ref type_decl that represents a "void" type for
3283/// the current environment. This node must be the only one
3284/// representing a void type in the system.
3285///
3286/// Note that upon first use of this IR node (by the relevant
3287/// front-end, for instance) it must be added to a scope using e.g,
3288/// the @ref add_decl_to_scope() function.
3289///
3290/// @return the @ref type_decl that represents a "void" type.
3291const type_base_sptr&
3293{
3294 if (!priv_->void_type_)
3295 priv_->void_type_.reset(new type_decl(*this,
3296 intern("void"),
3297 0, 0, location()));
3298 return priv_->void_type_;
3299}
3300
3301/// Getter of the "pointer-to-void" IR node that is shared across the
3302/// ABI corpus. This node must be the only one representing a void
3303/// pointer type in the system.
3304///
3305/// Note that upon first use of this IR node (by the relevant
3306/// front-end, for instance) it must be added to a scope using e.g,
3307/// the @ref add_decl_to_scope() function.
3308///
3309/// @return the "pointer-to-void" IR node.
3310const type_base_sptr&
3312{
3313 if (!priv_->void_pointer_type_)
3314 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3315 0, 0, location()));
3316 return priv_->void_pointer_type_;
3317}
3318
3319/// Get a @ref type_decl instance that represents a the type of a
3320/// variadic function parameter. This node must be the only one
3321/// representing a variadic parameter type in the system.
3322///
3323/// Note that upon first use of this IR node (by the relevant
3324/// front-end, for instance) it must be added to a scope using e.g,
3325/// the @ref add_decl_to_scope() function.
3326///
3327/// @return the Get a @ref type_decl instance that represents a the
3328/// type of a variadic function parameter.
3329const type_base_sptr&
3331{
3332 if (!priv_->variadic_marker_type_)
3333 priv_->variadic_marker_type_.
3335 0, 0, location()));
3336 return priv_->variadic_marker_type_;
3337}
3338
3339/// Getter of the name of the variadic parameter type.
3340///
3341/// @return the name of the variadic parameter type.
3342string&
3344{
3345 static string variadic_parameter_type_name = "variadic parameter type";
3346 return variadic_parameter_type_name;
3347}
3348
3349/// Test if the canonicalization of types created out of the current
3350/// environment is done.
3351///
3352/// @return true iff the canonicalization of types created out of the current
3353/// environment is done.
3354bool
3356{return priv_->canonicalization_is_done_;}
3357
3358/// Set a flag saying if the canonicalization of types created out of
3359/// the current environment is done or not.
3360///
3361/// Note that this function must only be called by internal code of
3362/// the library that creates ABI artifacts (e.g, read an abi corpus
3363/// from elf or from our own xml format and creates representations of
3364/// types out of it) and thus needs to canonicalize types to speed-up
3365/// further type comparison.
3366///
3367/// @param f the new value of the flag.
3368void
3370{
3371 priv_->canonicalization_is_done_ = f;
3372 if (priv_->canonicalization_is_done_)
3374}
3375
3376/// Getter of a flag saying if the canonicalization process has
3377/// started or not.
3378///
3379/// @return the flag saying if the canonicalization process has
3380/// started or not.
3381bool
3383{return priv_->canonicalization_started_;}
3384
3385/// Setter of a flag saying if the canonicalization process has
3386/// started or not.
3387///
3388/// @param f the new value of the flag saying if the canonicalization
3389/// process has started or not.
3390void
3392{priv_->canonicalization_started_ = f;}
3393
3394/// Getter of the "decl-only-class-equals-definition" flag.
3395///
3396/// Usually, a declaration-only class named 'struct foo' compares
3397/// equal to any class definition named "struct foo'. This is at
3398/// least true for C++.
3399///
3400/// In C, though, because there can be multiple definitions of 'struct
3401/// foo' in the binary, a declaration-only "struct foo" might be
3402/// considered to *NOT* resolve to any of the struct foo defined. In
3403/// that case, the declaration-only "struct foo" is considered
3404/// different from the definitions.
3405///
3406/// This flag controls the behaviour of the comparison of an
3407/// unresolved decl-only class against a definition of the same name.
3408///
3409/// If set to false, the the declaration equals the definition. If
3410/// set to false, then the decalration is considered different from
3411/// the declaration.
3412///
3413/// @return the value of the "decl-only-class-equals-definition" flag.
3414bool
3416{return priv_->decl_only_class_equals_definition_;}
3417
3418/// Setter of the "decl-only-class-equals-definition" flag.
3419///
3420/// Usually, a declaration-only class named 'struct foo' compares
3421/// equal to any class definition named "struct foo'. This is at
3422/// least true for C++.
3423///
3424/// In C, though, because there can be multiple definitions of 'struct
3425/// foo' in the binary, a declaration-only "struct foo" might be
3426/// considered to *NOT* resolve to any of the struct foo defined. In
3427/// that case, the declaration-only "struct foo" is considered
3428/// different from the definitions.
3429///
3430/// This flag controls the behaviour of the comparison of an
3431/// unresolved decl-only class against a definition of the same name.
3432///
3433/// If set to false, the the declaration equals the definition. If
3434/// set to false, then the decalration is considered different from
3435/// the declaration.
3436///
3437/// @param the new value of the "decl-only-class-equals-definition"
3438/// flag.
3439void
3441{priv_->decl_only_class_equals_definition_ = f;}
3442
3443/// Test if a given type is a void type as defined in the current
3444/// environment.
3445///
3446/// @param t the type to consider.
3447///
3448/// @return true iff @p t is a void type as defined in the current
3449/// environment.
3450bool
3451environment::is_void_type(const type_base_sptr& t) const
3452{
3453 if (!t)
3454 return false;
3455 return is_void_type(t.get());
3456}
3457
3458/// Test if a given type is a void type as defined in the current
3459/// environment.
3460///
3461/// @param t the type to consider.
3462///
3463/// @return true iff @p t is a void type as defined in the current
3464/// environment.
3465bool
3467{
3468 if (!t)
3469 return false;
3470 return (t == get_void_type().get()
3471 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3472}
3473
3474/// Test if a given type is the same as the void pointer type of the
3475/// environment.
3476///
3477/// @param t the IR type to test.
3478///
3479/// @return true iff @p t is the void pointer returned by
3480/// environment::get_void_pointer_type().
3481bool
3482environment::is_void_pointer_type(const type_base_sptr& t) const
3483{
3484 if (!t)
3485 return false;
3486
3487 return t.get() == get_void_pointer_type().get();
3488}
3489
3490/// Test if a given type is the same as the void pointer type of the
3491/// environment.
3492///
3493/// @param t the IR type to test.
3494///
3495/// @return true iff @p t is the void pointer returned by
3496/// environment::get_void_pointer_type().
3497bool
3499{
3500 if (!t)
3501 return false;
3502
3503 return t == get_void_pointer_type().get();
3504}
3505
3506/// Test if a type is a variadic parameter type as defined in the
3507/// current environment.
3508///
3509/// @param t the type to consider.
3510///
3511/// @return true iff @p t is a variadic parameter type as defined in
3512/// the current environment.
3513bool
3515{
3516 if (!t)
3517 return false;
3518 return t == get_variadic_parameter_type().get();
3519}
3520
3521/// Test if a type is a variadic parameter type as defined in the
3522/// current environment.
3523///
3524/// @param t the type to consider.
3525///
3526/// @return true iff @p t is a variadic parameter type as defined in
3527/// the current environment.
3528bool
3529environment::is_variadic_parameter_type(const type_base_sptr& t) const
3530{return is_variadic_parameter_type(t.get());}
3531
3532/// Do intern a string.
3533///
3534/// If a value of this string already exists in the interned string
3535/// pool of the current environment, then this function returns a new
3536/// interned_string pointing to that already existing string.
3537/// Otherwise, a new string is created, stored in the interned string
3538/// pool and a new interned_string instance is created to point to
3539/// that new intrerned string, and it's return.
3540///
3541/// @param s the value of the string to intern.
3542///
3543/// @return the interned string.
3545environment::intern(const string& s) const
3546{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3547
3548/// Getter of the general configuration object.
3549///
3550/// @return the configuration object.
3551const config&
3553{return priv_->config_;}
3554
3555/// Getter for a property that says if the user actually did set the
3556/// analyze_exported_interfaces_only() property. If not, it means
3557/// the default behaviour prevails.
3558///
3559/// @return tru iff the user did set the
3560/// analyze_exported_interfaces_only() property.
3561bool
3563{return priv_->analyze_exported_interfaces_only_.has_value();}
3564
3565/// Setter for the property that controls if we are to restrict the
3566/// analysis to the types that are only reachable from the exported
3567/// interfaces only, or if the set of types should be more broad than
3568/// that. Typically, we'd restrict the analysis to types reachable
3569/// from exported interfaces only (stricto sensu, that would really be
3570/// only the types that are part of the ABI of well designed
3571/// libraries) for performance reasons.
3572///
3573/// @param f the value of the flag.
3574void
3576{priv_->analyze_exported_interfaces_only_ = f;}
3577
3578/// Getter for the property that controls if we are to restrict the
3579/// analysis to the types that are only reachable from the exported
3580/// interfaces only, or if the set of types should be more broad than
3581/// that. Typically, we'd restrict the analysis to types reachable
3582/// from exported interfaces only (stricto sensu, that would really be
3583/// only the types that are part of the ABI of well designed
3584/// libraries) for performance reasons.
3585///
3586/// @param f the value of the flag.
3587bool
3589{return priv_->analyze_exported_interfaces_only_.value_or(false);}
3590
3591#ifdef WITH_DEBUG_SELF_COMPARISON
3592/// Setter of the corpus of the input corpus of the self comparison
3593/// that takes place when doing "abidw --debug-abidiff <binary>".
3594///
3595/// The first invocation of this function sets the first corpus of the
3596/// self comparison. The second invocation of this very same function
3597/// sets the second corpus of the self comparison. That second corpus
3598/// is supposed to come from the abixml serialization of the first
3599/// corpus.
3600///
3601/// @param c the corpus of the input binary or the corpus of the
3602/// abixml serialization of the initial binary input.
3603void
3604environment::set_self_comparison_debug_input(const corpus_sptr& c)
3605{
3606 self_comparison_debug_is_on(true);
3607 if (priv_->first_self_comparison_corpus_.expired())
3608 priv_->first_self_comparison_corpus_ = c;
3609 else if (priv_->second_self_comparison_corpus_.expired()
3610 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3611 priv_->second_self_comparison_corpus_ = c;
3612}
3613
3614/// Getter for the corpora of the input binary and the intermediate
3615/// abixml of the self comparison that takes place when doing
3616/// 'abidw --debug-abidiff <binary>'.
3617///
3618/// @param first_corpus output parameter that is set to the corpus of
3619/// the input corpus.
3620///
3621/// @param second_corpus output parameter that is set to the corpus of
3622/// the second corpus.
3623void
3624environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3625 corpus_sptr& second_corpus)
3626{
3627 first_corpus = priv_->first_self_comparison_corpus_.lock();
3628 second_corpus = priv_->second_self_comparison_corpus_.lock();
3629}
3630
3631/// Turn on/off the self comparison debug mode.
3632///
3633/// @param f true iff the self comparison debug mode is turned on.
3634void
3635environment::self_comparison_debug_is_on(bool f)
3636{priv_->self_comparison_debug_on_ = f;}
3637
3638/// Test if we are in the process of the 'self-comparison
3639/// debugging' as triggered by 'abidw --debug-abidiff' command.
3640///
3641/// @return true if self comparison debug is on.
3642bool
3643environment::self_comparison_debug_is_on() const
3644{return priv_->self_comparison_debug_on_;}
3645#endif
3646
3647#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3648/// Set the "type canonicalization debugging" mode, triggered by using
3649/// the command: "abidw --debug-tc".
3650///
3651/// @param flag if true then the type canonicalization debugging mode
3652/// is enabled.
3653void
3654environment::debug_type_canonicalization_is_on(bool flag)
3655{priv_->debug_type_canonicalization_ = flag;}
3656
3657/// Getter of the "type canonicalization debugging" mode, triggered by
3658/// using the command: "abidw --debug-tc".
3659///
3660/// @return true iff the type canonicalization debugging mode is
3661/// enabled.
3662bool
3663environment::debug_type_canonicalization_is_on() const
3664{return priv_->debug_type_canonicalization_;}
3665
3666/// Setter of the "DIE canonicalization debugging" mode, triggered by
3667/// using the command: "abidw --debug-dc".
3668///
3669/// @param flag true iff the DIE canonicalization debugging mode is
3670/// enabled.
3671void
3672environment::debug_die_canonicalization_is_on(bool flag)
3673{priv_->debug_die_canonicalization_ = flag;}
3674
3675/// Getter of the "DIE canonicalization debugging" mode, triggered by
3676/// using the command: "abidw --debug-dc".
3677///
3678/// @return true iff the DIE canonicalization debugging mode is
3679/// enabled.
3680bool
3681environment::debug_die_canonicalization_is_on() const
3682{return priv_->debug_die_canonicalization_;}
3683#endif // WITH_DEBUG_TYPE_CANONICALIZATION
3684
3685/// Get the vector of canonical types which have a given "string
3686/// representation".
3687///
3688/// @param 'name', the textual representation of the type as returned
3689/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3690/// /*qualified=*/true)
3691///
3692/// This is useful to for debugging purposes as it's handy to use from
3693/// inside a debugger like GDB.
3694///
3695/// @return a pointer to the vector of canonical types having the
3696/// representation @p name, or nullptr if no type with that
3697/// representation exists.
3698const vector<type_base_sptr>*
3700{
3701 auto ti = get_canonical_types_map().find(name);
3702 if (ti == get_canonical_types_map().end())
3703 return nullptr;
3704 return &ti->second;
3705}
3706
3707/// Get a given canonical type which has a given "string
3708/// representation".
3709///
3710/// @param 'name', the textual representation of the type as returned
3711/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3712/// /*qualified=*/true).
3713///
3714/// @param index, the index of the type in the vector of types that
3715/// all have the same textual representation @p 'name'. That vector
3716/// is returned by the function environment::get_canonical_types().
3717///
3718/// @return the canonical type which has the representation @p name,
3719/// and which is at index @p index in the vector of canonical types
3720/// having that same textual representation.
3721type_base*
3722environment::get_canonical_type(const char* name, unsigned index)
3723{
3724 const vector<type_base_sptr> *types = get_canonical_types(name);
3725 if (!types ||index >= types->size())
3726 return nullptr;
3727 return (*types)[index].get();
3728}
3729
3730#ifdef WITH_DEBUG_SELF_COMPARISON
3731/// Get the set of abixml type-id and the pointer value of the
3732/// (canonical) type it's associated to.
3733///
3734/// This is useful for debugging purposes, especially in the context
3735/// of the use of the command:
3736/// 'abidw --debug-abidiff <binary>'.
3737///
3738/// @return the set of abixml type-id and the pointer value of the
3739/// (canonical) type it's associated to.
3740const unordered_map<string, uintptr_t>&
3741environment::get_type_id_canonical_type_map() const
3742{return priv_->get_type_id_canonical_type_map();}
3743
3744/// Get the set of abixml type-id and the pointer value of the
3745/// (canonical) type it's associated to.
3746///
3747/// This is useful for debugging purposes, especially in the context
3748/// of the use of the command:
3749/// 'abidw --debug-abidiff <binary>'.
3750///
3751/// @return the set of abixml type-id and the pointer value of the
3752/// (canonical) type it's associated to.
3753unordered_map<string, uintptr_t>&
3754environment::get_type_id_canonical_type_map()
3755{return priv_->get_type_id_canonical_type_map();}
3756
3757/// Getter of the map that associates the values of type pointers to
3758/// their type-id strings.
3759///
3760/// Note that this map is populated at abixml reading time, (by
3761/// build_type()) when a given XML element representing a type is
3762/// read into a corresponding abigail::ir::type_base.
3763///
3764/// This is used only for the purpose of debugging the
3765/// self-comparison process. That is, when invoking "abidw
3766/// --debug-abidiff".
3767///
3768/// @return the map that associates the values of type pointers to
3769/// their type-id strings.
3770const unordered_map<uintptr_t, string>&
3771environment::get_pointer_type_id_map() const
3772{return priv_->get_pointer_type_id_map();}
3773
3774/// Getter of the map that associates the values of type pointers to
3775/// their type-id strings.
3776///
3777/// Note that this map is populated at abixml reading time, (by
3778/// build_type()) when a given XML element representing a type is
3779/// read into a corresponding abigail::ir::type_base.
3780///
3781/// This is used only for the purpose of debugging the
3782/// self-comparison process. That is, when invoking "abidw
3783/// --debug-abidiff".
3784///
3785/// @return the map that associates the values of type pointers to
3786/// their type-id strings.
3787unordered_map<uintptr_t, string>&
3788environment::get_pointer_type_id_map()
3789{return priv_->get_pointer_type_id_map();}
3790
3791/// Getter of the type-id that corresponds to the value of a pointer
3792/// to abigail::ir::type_base that was created from the abixml reader.
3793///
3794/// That value is retrieved from the map returned from
3795/// environment::get_pointer_type_id_map().
3796///
3797/// That map is populated at abixml reading time, (by build_type())
3798/// when a given XML element representing a type is read into a
3799/// corresponding abigail::ir::type_base.
3800///
3801/// This is used only for the purpose of debugging the
3802/// self-comparison process. That is, when invoking "abidw
3803/// --debug-abidiff".
3804///
3805/// @return the type-id strings that corresponds
3806string
3807environment::get_type_id_from_pointer(uintptr_t ptr) const
3808{return priv_->get_type_id_from_pointer(ptr);}
3809
3810/// Getter of the type-id that corresponds to the value of an
3811/// abigail::ir::type_base that was created from the abixml reader.
3812///
3813/// That value is retrieved from the map returned from
3814/// environment::get_pointer_type_id_map().
3815///
3816/// That map is populated at abixml reading time, (by build_type())
3817/// when a given XML element representing a type is read into a
3818/// corresponding abigail::ir::type_base.
3819///
3820/// This is used only for the purpose of debugging the
3821/// self-comparison process. That is, when invoking "abidw
3822/// --debug-abidiff".
3823///
3824/// @return the type-id strings that corresponds
3825string
3826environment::get_type_id_from_type(const type_base *t) const
3827{return priv_->get_type_id_from_type(t);}
3828
3829/// Getter of the canonical type of the artifact designated by a
3830/// type-id.
3831///
3832/// That type-id was generated by the abixml writer at the emitting
3833/// time of the abixml file. The corresponding canonical type was
3834/// stored in the map returned by
3835/// environment::get_type_id_canonical_type_map().
3836///
3837/// This is useful for debugging purposes, especially in the context
3838/// of the use of the command:
3839/// 'abidw --debug-abidiff <binary>'.
3840///
3841/// @return the set of abixml type-id and the pointer value of the
3842/// (canonical) type it's associated to.
3843uintptr_t
3844environment::get_canonical_type_from_type_id(const char* type_id) const
3845{return priv_->get_canonical_type_from_type_id(type_id);}
3846#endif
3847
3848// </environment stuff>
3849
3850// <type_or_decl_base stuff>
3851
3852/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
3853/// bitmap type.
3857{
3858 return static_cast<type_or_decl_base::type_or_decl_kind>
3859 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
3860}
3861
3862/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
3863/// bitmap type.
3867{
3868 l = l | r;
3869 return l;
3870}
3871
3872/// bitwise "AND" operator for the
3873/// type_or_decl_base::type_or_decl_kind bitmap type.
3877{
3878 return static_cast<type_or_decl_base::type_or_decl_kind>
3879 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
3880}
3881
3882/// bitwise "A&=" operator for the
3883/// type_or_decl_base::type_or_decl_kind bitmap type.
3887{
3888 l = l & r;
3889 return l;
3890}
3891
3892/// Constructor of @ref type_or_decl_base.
3893///
3894/// @param the environment the current ABI artifact is constructed
3895/// from.
3896///
3897/// @param k the runtime identifier bitmap of the type being built.
3898type_or_decl_base::type_or_decl_base(const environment& e,
3899 enum type_or_decl_kind k)
3900 :priv_(new priv(e, k))
3901{}
3902
3903/// The destructor of the @ref type_or_decl_base type.
3905{}
3906
3907/// Getter of the flag that says if the artefact is artificial.
3908///
3909/// Being artificial means it was not explicitely mentionned in the
3910/// source code, but was rather artificially created by the compiler
3911/// or libabigail.
3912///
3913/// @return true iff the declaration is artificial.
3914bool
3916{return priv_->is_artificial_;}
3917
3918/// Setter of the flag that says if the artefact is artificial.
3919///
3920/// Being artificial means the artefact was not explicitely
3921/// mentionned in the source code, but was rather artificially created
3922/// by the compiler or by libabigail.
3923///
3924/// @param f the new value of the flag that says if the artefact is
3925/// artificial.
3926void
3928{priv_->is_artificial_ = f;}
3929
3930/// Getter for the "kind" property of @ref type_or_decl_base type.
3931///
3932/// This property holds the identifier bitmap of the runtime type of
3933/// an ABI artifact.
3934///
3935/// @return the runtime type identifier bitmap of the current ABI
3936/// artifact.
3939{return priv_->kind();}
3940
3941/// Setter for the "kind" property of @ref type_or_decl_base type.
3942///
3943/// This property holds the identifier bitmap of the runtime type of
3944/// an ABI artifact.
3945///
3946/// @param the runtime type identifier bitmap of the current ABI
3947/// artifact.
3948void
3950{priv_->kind(k);}
3951
3952/// Getter of the pointer to the runtime type sub-object of the
3953/// current instance.
3954///
3955/// @return the pointer to the runtime type sub-object of the current
3956/// instance.
3957const void*
3959{return priv_->rtti_;}
3960
3961/// Getter of the pointer to the runtime type sub-object of the
3962/// current instance.
3963///
3964/// @return the pointer to the runtime type sub-object of the current
3965/// instance.
3966void*
3968{return priv_->rtti_;}
3969
3970/// Setter of the pointer to the runtime type sub-object of the
3971/// current instance.
3972///
3973/// @param i the new pointer to the runtime type sub-object of the
3974/// current instance.
3975void
3977{
3978 priv_->rtti_ = i;
3979 if (type_base* t = dynamic_cast<type_base*>(this))
3980 priv_->type_or_decl_ptr_ = t;
3981 else if (decl_base *d = dynamic_cast<decl_base*>(this))
3982 priv_->type_or_decl_ptr_ = d;
3983}
3984
3985/// Getter of the pointer to either the type_base sub-object of the
3986/// current instance if it's a type, or to the decl_base sub-object of
3987/// the current instance if it's a decl.
3988///
3989/// @return the pointer to either the type_base sub-object of the
3990/// current instance if it's a type, or to the decl_base sub-object of
3991/// the current instance if it's a decl.
3992const void*
3994{return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
3995
3996/// Getter of the pointer to either the type_base sub-object of the
3997/// current instance if it's a type, or to the decl_base sub-object of
3998/// the current instance if it's a decl.
3999///
4000/// @return the pointer to either the type_base sub-object of the
4001/// current instance if it's a type, or to the decl_base sub-object of
4002/// the current instance if it's a decl.
4003void*
4005{return priv_->type_or_decl_ptr_;}
4006
4007/// Return the hash value of the current IR node.
4008///
4009/// Note that upon the first invocation, this member functions
4010/// computes the hash value and returns it. Subsequent invocations
4011/// just return the hash value that was previously calculated.
4012///
4013/// @return the hash value of the current IR node.
4014hash_t
4016{return priv_->hash_value_;}
4017
4018void
4019type_or_decl_base::set_hash_value(hash_t h) const
4020{priv_->set_hash_value(h);}
4021
4022/// Getter of the environment of the current ABI artifact.
4023///
4024/// @return the environment of the artifact.
4025const environment&
4027{return priv_->env_;}
4028
4029/// Setter of the artificial location of the artificat.
4030///
4031/// The artificial location is a location that was artificially
4032/// generated by libabigail, not generated by the original emitter of
4033/// the ABI meta-data. For instance, when reading an XML element from
4034/// an abixml file, the artificial location is the source location of
4035/// the XML element within the file, not the value of the
4036/// 'location'property that might be carried by the element.
4037///
4038/// Artificial locations might be useful to ensure that abixml emitted
4039/// by the abixml writer are sorted the same way as the input abixml
4040/// read by the reader.
4041///
4042/// @param l the new artificial location.
4043void
4045{priv_->artificial_location_ = l;}
4046
4047/// Getter of the artificial location of the artifact.
4048///
4049/// The artificial location is a location that was artificially
4050/// generated by libabigail, not generated by the original emitter of
4051/// the ABI meta-data. For instance, when reading an XML element from
4052/// an abixml file, the artificial location is the source location of
4053/// the XML element within the file, not the value of the
4054/// 'location'property that might be carried by the element.
4055///
4056/// Artificial locations might be useful to ensure that the abixml
4057/// emitted by the abixml writer is sorted the same way as the input
4058/// abixml read by the reader.
4059///
4060/// @return the new artificial location.
4061location&
4063{return priv_->artificial_location_;}
4064
4065/// Test if the current ABI artifact carries an artificial location.
4066///
4067/// @return true iff the current ABI artifact carries an artificial location.
4068bool
4070{
4071 return (priv_->artificial_location_
4072 && priv_->artificial_location_.get_is_artificial());
4073}
4074
4075/// Get the @ref corpus this ABI artifact belongs to.
4076///
4077/// @return the corpus this ABI artifact belongs to, or nil if it
4078/// belongs to none for now.
4079corpus*
4081{
4083 if (!tu)
4084 return 0;
4085 return tu->get_corpus();
4086}
4087
4088
4089/// Get the @ref corpus this ABI artifact belongs to.
4090///
4091/// @return the corpus this ABI artifact belongs to, or nil if it
4092/// belongs to none for now.
4093const corpus*
4095{return const_cast<type_or_decl_base*>(this)->get_corpus();}
4096
4097/// Set the @ref translation_unit this ABI artifact belongs to.
4098///
4099/// Note that adding an ABI artifact to a containining on should
4100/// invoke this member function.
4101void
4103{priv_->translation_unit_ = tu;}
4104
4105
4106/// Get the @ref translation_unit this ABI artifact belongs to.
4107///
4108/// @return the translation unit this ABI artifact belongs to, or nil
4109/// if belongs to none for now.
4112{return priv_->translation_unit_;}
4113
4114/// Get the @ref translation_unit this ABI artifact belongs to.
4115///
4116/// @return the translation unit this ABI artifact belongs to, or nil
4117/// if belongs to none for now.
4118const translation_unit*
4120{return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
4121
4122/// Traverse the the ABI artifact.
4123///
4124/// @param v the visitor used to traverse the sub-tree nodes of the
4125/// artifact.
4126bool
4128{return true;}
4129
4130/// Non-member equality operator for the @type_or_decl_base type.
4131///
4132/// @param lr the left-hand operand of the equality.
4133///
4134/// @param rr the right-hand operatnr of the equality.
4135///
4136/// @return true iff @p lr equals @p rr.
4137bool
4139{
4140 const type_or_decl_base* l = &lr;
4141 const type_or_decl_base* r = &rr;
4142
4143 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4144 *dr = dynamic_cast<const decl_base*>(r);
4145
4146 if (!!dl != !!dr)
4147 return false;
4148
4149 if (dl && dr)
4150 return *dl == *dr;
4151
4152 const type_base* tl = dynamic_cast<const type_base*>(l),
4153 *tr = dynamic_cast<const type_base*>(r);
4154
4155 if (!!tl != !!tr)
4156 return false;
4157
4158 if (tl && tr)
4159 return *tl == *tr;
4160
4161 return false;
4162}
4163
4164/// Non-member equality operator for the @type_or_decl_base type.
4165///
4166/// @param l the left-hand operand of the equality.
4167///
4168/// @param r the right-hand operatnr of the equality.
4169///
4170/// @return true iff @p l equals @p r.
4171bool
4173{
4174 if (!! l != !!r)
4175 return false;
4176
4177 if (!l)
4178 return true;
4179
4180 return *r == *l;
4181}
4182
4183/// Non-member inequality operator for the @type_or_decl_base type.
4184///
4185/// @param l the left-hand operand of the equality.
4186///
4187/// @param r the right-hand operator of the equality.
4188///
4189/// @return true iff @p l is different from @p r.
4190bool
4192{return !operator==(l, r);}
4193
4194// </type_or_decl_base stuff>
4195
4196// <Decl definition>
4197
4198struct decl_base::priv
4199{
4200 bool in_pub_sym_tab_;
4201 bool is_anonymous_;
4202 location location_;
4203 context_rel *context_;
4204 interned_string name_;
4205 interned_string qualified_parent_name_;
4206 // This temporary qualified name is the cache used for the qualified
4207 // name before the type associated to this decl (if applicable) is
4208 // canonicalized. Once the type is canonicalized, the cached use is
4209 // the data member qualified_parent_name_ above.
4210 interned_string temporary_qualified_name_;
4211 // This is the fully qualified name of the decl. It contains the
4212 // name of the decl and the qualified name of its scope. So if in
4213 // the parent scopes of the decl, there is one anonymous struct,
4214 // somewhere in the name, there is going to by an
4215 // __anonymous_struct__ string, even if the anonymous struct is not
4216 // the direct containing scope of this decl.
4217 interned_string qualified_name_;
4218 interned_string temporary_internal_qualified_name_;
4219 interned_string internal_qualified_name_;
4220 interned_string internal_cached_repr_;
4221 interned_string cached_repr_;
4222 // Unline qualified_name_, scoped_name_ contains the name of the
4223 // decl and the name of its scope; not the qualified name of the
4224 // scope.
4225 interned_string scoped_name_;
4226 interned_string linkage_name_;
4227 visibility visibility_;
4228 decl_base_sptr declaration_;
4229 decl_base_wptr definition_of_declaration_;
4230 decl_base* naked_definition_of_declaration_;
4231 bool is_declaration_only_;
4232 typedef_decl_sptr naming_typedef_;
4233
4234 priv()
4235 : in_pub_sym_tab_(false),
4236 is_anonymous_(true),
4237 context_(),
4238 visibility_(VISIBILITY_DEFAULT),
4239 naked_definition_of_declaration_(),
4240 is_declaration_only_(false)
4241 {}
4242
4243 priv(interned_string name, interned_string linkage_name, visibility vis)
4244 : in_pub_sym_tab_(false),
4245 context_(),
4246 name_(name),
4247 qualified_name_(name),
4248 linkage_name_(linkage_name),
4249 visibility_(vis),
4250 naked_definition_of_declaration_(),
4251 is_declaration_only_(false)
4252 {
4253 is_anonymous_ = name_.empty();
4254 }
4255
4256 ~priv()
4257 {
4258 delete context_;
4259 }
4260};// end struct decl_base::priv
4261
4262/// Constructor for the @ref decl_base type.
4263///
4264/// @param e the environment the current @ref decl_base is being
4265/// created in.
4266///
4267/// @param name the name of the declaration.
4268///
4269/// @param locus the location where to find the declaration in the
4270/// source code.
4271///
4272/// @param linkage_name the linkage name of the declaration.
4273///
4274/// @param vis the visibility of the declaration.
4275decl_base::decl_base(const environment& e,
4276 const string& name,
4277 const location& locus,
4278 const string& linkage_name,
4279 visibility vis)
4280 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4281 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4282{
4283 set_location(locus);
4284}
4285
4286/// Constructor.
4287///
4288/// @param e the environment this instance of @ref decl_base is
4289/// created in.
4290///
4291/// @param name the name of the declaration being constructed.
4292///
4293/// @param locus the source location of the declaration being constructed.
4294///
4295/// @param linkage_name the linkage name of the declaration being
4296/// constructed.
4297///
4298/// @param vis the visibility of the declaration being constructed.
4299decl_base::decl_base(const environment& e,
4300 const interned_string& name,
4301 const location& locus,
4302 const interned_string& linkage_name,
4303 visibility vis)
4304 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4305 priv_(new priv(name, linkage_name, vis))
4306{
4307 set_location(locus);
4308}
4309
4310/// Constructor for the @ref decl_base type.
4311///
4312///@param environment the environment this instance of @ref decl_base
4313/// is being constructed in.
4314///
4315/// @param l the location where to find the declaration in the source
4316/// code.
4317decl_base::decl_base(const environment& e, const location& l)
4318 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4319 priv_(new priv())
4320{
4321 set_location(l);
4322}
4323
4324/// Getter for the qualified name.
4325///
4326/// Unlike decl_base::get_qualified_name() this doesn't try to update
4327/// the qualified name.
4328///
4329/// @return the qualified name.
4330const interned_string&
4332{return priv_->qualified_name_;}
4333
4334/// Clear the qualified name of this decl.
4335///
4336/// This is useful to ensure that the cache for the qualified name of
4337/// the decl is refreshed right after type canonicalization, for
4338/// instance.
4339void
4341{priv_->qualified_name_.clear();}
4342
4343/// Setter for the qualified name.
4344///
4345/// @param n the new qualified name.
4346void
4348{priv_->qualified_name_ = n;}
4349
4350/// Getter of the temporary qualified name of the current declaration.
4351///
4352/// This temporary qualified name is used as a qualified name cache by
4353/// the type for which this is the declaration (when applicable)
4354/// before the type is canonicalized. Once the type is canonicalized,
4355/// it's the result of decl_base::peek_qualified_name() that becomes
4356/// the qualified name cached.
4357///
4358/// @return the temporary qualified name.
4359const interned_string&
4361{return priv_->temporary_qualified_name_;}
4362
4363/// Setter for the temporary qualified name of the current
4364/// declaration.
4365///
4366///@param n the new temporary qualified name.
4367///
4368/// This temporary qualified name is used as a qualified name cache by
4369/// the type for which this is the declaration (when applicable)
4370/// before the type is canonicalized. Once the type is canonicalized,
4371/// it's the result of decl_base::peek_qualified_name() that becomes
4372/// the qualified name cached.
4373void
4375{priv_->temporary_qualified_name_ = n;}
4376
4377///Getter for the context relationship.
4378///
4379///@return the context relationship for the current decl_base.
4380const context_rel*
4382{return priv_->context_;}
4383
4384///Getter for the context relationship.
4385///
4386///@return the context relationship for the current decl_base.
4389{return priv_->context_;}
4390
4391void
4392decl_base::set_context_rel(context_rel *c)
4393{priv_->context_ = c;}
4394
4395/// Test if the decl is defined in a ELF symbol table as a public
4396/// symbol.
4397///
4398/// @return true iff the decl is defined in a ELF symbol table as a
4399/// public symbol.
4400bool
4402{return priv_->in_pub_sym_tab_;}
4403
4404/// Set the flag saying if this decl is from a symbol that is in
4405/// a public symbols table, defined as public (global or weak).
4406///
4407/// @param f the new flag value.
4408void
4410{priv_->in_pub_sym_tab_ = f;}
4411
4412/// Get the location of a given declaration.
4413///
4414/// The location is an abstraction for the tripplet {file path,
4415/// line, column} that defines where the declaration appeared in the
4416/// source code.
4417///
4418/// To get the value of the tripplet {file path, line, column} from
4419/// the @ref location, you need to use the
4420/// location_manager::expand_location() method.
4421///
4422/// The instance of @ref location_manager that you want is
4423/// accessible from the instance of @ref translation_unit that the
4424/// current instance of @ref decl_base belongs to, via a call to
4425/// translation_unit::get_loc_mgr().
4426///
4427/// @return the location of the current instance of @ref decl_base.
4428const location&
4430{return priv_->location_;}
4431
4432/// Set the location for a given declaration.
4433///
4434/// The location is an abstraction for the tripplet {file path,
4435/// line, column} that defines where the declaration appeared in the
4436/// source code.
4437///
4438/// To create a location from a tripplet {file path, line, column},
4439/// you need to use the method @ref
4440/// location_manager::create_new_location().
4441///
4442/// Note that there can be two kinds of location. An artificial
4443/// location and a non-artificial one. The non-artificial location is
4444/// the one emitted by the original emitter of the ABI artifact, for
4445/// instance, if the ABI artifact comes from debug info, then the
4446/// source location that is present in the debug info represent a
4447/// non-artificial location. When looking at an abixml file on the
4448/// other hand, the value of the 'location' attribute of an XML
4449/// element describing an artifact is the non-artificial location.
4450/// The artificial location is the location (line number from the
4451/// beginning of the file) of the XML element within the abixml file.
4452///
4453/// So, if the location that is being set is artificial, note that the
4454/// type_or_decl_base::has_artificial_location() method of this decl will
4455/// subsequently return true and that artificial location will have to
4456/// be retrieved using type_or_decl_base::get_artificial_location().
4457/// If the location is non-artificial however,
4458/// type_or_decl_base::has_artificial_location() will subsequently
4459/// return false and the non-artificial location will have to be
4460/// retrieved using decl_base::get_location().
4461///
4462/// The instance of @ref location_manager that you want is
4463/// accessible from the instance of @ref translation_unit that the
4464/// current instance of @ref decl_base belongs to, via a call to
4465/// translation_unit::get_loc_mgr().
4466void
4468{
4469 if (l.get_is_artificial())
4471 else
4472 priv_->location_ = l;
4473}
4474
4475/// Setter for the name of the decl.
4476///
4477/// @param n the new name to set.
4478void
4479decl_base::set_name(const string& n)
4480{
4481 priv_->name_ = get_environment().intern(n);
4482 priv_->is_anonymous_ = n.empty();
4483}
4484
4485/// Test if the current declaration is anonymous.
4486///
4487/// Being anonymous means that the declaration was created without a
4488/// name. This can usually happen for enum or struct types.
4489///
4490/// @return true iff the type is anonymous.
4491bool
4493{return priv_->is_anonymous_;}
4494
4495/// Set the "is_anonymous" flag of the current declaration.
4496///
4497/// Being anonymous means that the declaration was created without a
4498/// name. This can usually happen for enum or struct types.
4499///
4500/// @param f the new value of the flag.
4501void
4503{priv_->is_anonymous_ = f;}
4504
4505
4506/// Get the "has_anonymous_parent" flag of the current declaration.
4507///
4508/// Having an anoymous parent means having a anonymous parent scope
4509/// (containing type or namespace) which is either direct or indirect.
4510///
4511/// @return true iff the current decl has a direct or indirect scope
4512/// which is anonymous.
4513bool
4515{
4516 scope_decl *scope = get_scope();
4517 if (!scope)
4518 return false;
4519 return scope->get_is_anonymous();
4520}
4521
4522/// @return the logical "OR" of decl_base::get_is_anonymous() and
4523/// decl_base::get_has_anonymous_parent().
4524bool
4527
4528/// Getter for the naming typedef of the current decl.
4529///
4530/// Consider the C idiom:
4531///
4532/// typedef struct {int member;} foo_type;
4533///
4534/// In that idiom, foo_type is the naming typedef of the anonymous
4535/// struct that is declared.
4536///
4537/// @return the naming typedef, if any. Otherwise, returns nil.
4540{return priv_->naming_typedef_;}
4541
4542/// Set the naming typedef of the current instance of @ref decl_base.
4543///
4544/// Consider the C idiom:
4545///
4546/// typedef struct {int member;} foo_type;
4547///
4548/// In that idiom, foo_type is the naming typedef of the anonymous
4549/// struct that is declared.
4550///
4551/// After completion of this function, the decl will not be considered
4552/// anonymous anymore. It's name is going to be the name of the
4553/// naming typedef.
4554///
4555/// @param typedef_type the new naming typedef.
4556void
4558{
4559 // A naming typedef is usually for an anonymous type.
4561 // Whe the typedef-named decl is saved into abixml, it's
4562 // not anonymous anymore. Its name is the typedef name.
4563 // So when we read it back, we must still be able to
4564 // apply the naming typedef to the decl.
4565 || t->get_name() == get_name());
4566 // Only non canonicalized types can be edited this way.
4567 ABG_ASSERT(is_type(this)
4568 && is_type(this)->get_naked_canonical_type() == nullptr);
4569
4570 priv_->naming_typedef_ = t;
4571 set_name(t->get_name());
4572 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4573 set_qualified_name(get_environment().intern(qualified_name));
4574 set_is_anonymous(false);
4575 // Now that the qualified type of the decl has changed, let's update
4576 // the qualified names of the member types of this decls.
4577 update_qualified_name(this);
4578}
4579
4580/// Getter for the mangled name.
4581///
4582/// @return the new mangled name.
4583const interned_string&
4585{return priv_->linkage_name_;}
4586
4587/// Setter for the linkage name.
4588///
4589/// @param m the new linkage name.
4590void
4592{
4593 const environment& env = get_environment();
4594 priv_->linkage_name_ = env.intern(m);
4595}
4596
4597/// Getter for the visibility of the decl.
4598///
4599/// @return the new visibility.
4602{return priv_->visibility_;}
4603
4604/// Setter for the visibility of the decl.
4605///
4606/// @param v the new visibility.
4607void
4609{priv_->visibility_ = v;}
4610
4611/// Return the type containing the current decl, if any.
4612///
4613/// @return the type that contains the current decl, or NULL if there
4614/// is none.
4617{
4618 if (priv_->context_)
4619 return priv_->context_->get_scope();
4620 return 0;
4621}
4622
4623/// Return a copy of the qualified name of the parent of the current
4624/// decl.
4625///
4626/// @return the newly-built qualified name of the of the current decl.
4627const interned_string&
4629{return priv_->qualified_parent_name_;}
4630
4631/// Getter for the name of the current decl.
4632///
4633/// @return the name of the current decl.
4634const interned_string&
4636{return priv_->name_;}
4637
4638/// Compute the qualified name of the decl.
4639///
4640/// @param qn the resulting qualified name.
4641///
4642/// @param internal set to true if the call is intended for an
4643/// internal use (for technical use inside the library itself), false
4644/// otherwise. If you don't know what this is for, then set it to
4645/// false.
4646void
4648{qn = get_qualified_name(internal);}
4649
4650/// Get the pretty representatin of the current declaration.
4651///
4652///
4653/// @param internal set to true if the call is intended to get a
4654/// representation of the decl (or type) for the purpose of canonical
4655/// type comparison. This is mainly used in the function
4656/// type_base::get_canonical_type_for().
4657///
4658/// In other words if the argument for this parameter is true then the
4659/// call is meant for internal use (for technical use inside the
4660/// library itself), false otherwise. If you don't know what this is
4661/// for, then set it to false.
4662///
4663/// @param qualified_name if true, names emitted in the pretty
4664/// representation are fully qualified.
4665///
4666/// @return the default pretty representation for a decl. This is
4667/// basically the fully qualified name of the decl optionally prefixed
4668/// with a meaningful string to add context for the user.
4669string
4671 bool qualified_name) const
4672{
4673 if (internal
4674 && get_is_anonymous()
4675 && has_generic_anonymous_internal_type_name(this))
4676 {
4677 // We are looking at an anonymous enum, union or class and we
4678 // want an *internal* pretty representation for it. All
4679 // anonymous types of this kind in the same namespace must have
4680 // the same internal representation for type canonicalization to
4681 // work properly.
4682 //
4683 // OK, in practise, we are certainly looking at an enum because
4684 // classes and unions should have their own overloaded virtual
4685 // member function for this.
4686 string name = get_generic_anonymous_internal_type_name(this);
4687 if (qualified_name && !get_qualified_parent_name().empty())
4688 name = get_qualified_parent_name() + "::" + name;
4689 return name;
4690 }
4691
4692 if (qualified_name)
4693 return get_qualified_name(internal);
4694 return get_name();
4695}
4696
4697/// Get the pretty representation of the current decl.
4698///
4699/// The pretty representation is retrieved from a cache. If the cache
4700/// is empty, this function computes the pretty representation, put it
4701/// in the cache and returns it.
4702///
4703/// Please note that if this function is called too early in the life
4704/// cycle of the decl (before it is fully constructed), then the
4705/// pretty representation that is cached is going to represent a
4706/// non-complete (and thus wrong) representation of the decl. Thus
4707/// this function must be called only once the decl is fully
4708/// constructed.
4709///
4710/// @param internal if true, then the pretty representation is to be
4711/// used for purpuses that are internal to the libabigail library
4712/// itself. If you don't know what this means, then you probably
4713/// should set this parameter to "false".
4714///
4715/// @return a reference to a cached @ref interned_string holding the
4716/// pretty representation of the current decl.
4717const interned_string&
4719{
4720 if (internal)
4721 {
4722 if (priv_->internal_cached_repr_.empty())
4723 {
4724 string r = ir::get_pretty_representation(this, internal);
4725 priv_->internal_cached_repr_ = get_environment().intern(r);
4726 }
4727 return priv_->internal_cached_repr_;
4728 }
4729
4730 if (priv_->cached_repr_.empty())
4731 {
4732 string r = ir::get_pretty_representation(this, internal);
4733 priv_->cached_repr_ = get_environment().intern(r);
4734 }
4735
4736 return priv_->cached_repr_;
4737}
4738
4739/// Return the qualified name of the decl.
4740///
4741/// This is the fully qualified name of the decl. It's made of the
4742/// concatenation of the name of the decl with the qualified name of
4743/// its scope.
4744///
4745/// Note that the value returned by this function is computed by @ref
4746/// update_qualified_name when the decl is added to its scope.
4747///
4748/// @param internal set to true if the call is intended for an
4749/// internal use (for technical use inside the library itself), false
4750/// otherwise. If you don't know what this is for, then set it to
4751/// false.
4752///
4753/// @return the resulting qualified name.
4754const interned_string&
4755decl_base::get_qualified_name(bool /*internal*/) const
4756{return priv_->qualified_name_;}
4757
4758/// Return the scoped name of the decl.
4759///
4760/// This is made of the concatenation of the name of the decl with the
4761/// name of its scope. It doesn't contain the qualified name of its
4762/// scope, unlike what is returned by decl_base::get_qualified_name.
4763///
4764/// Note that the value returned by this function is computed by @ref
4765/// update_qualified_name when the decl is added to its scope.
4766///
4767/// @return the scoped name of the decl.
4768const interned_string&
4770{return priv_->scoped_name_;}
4771
4772/// If this @ref decl_base is a definition, get its earlier
4773/// declaration.
4774///
4775/// @return the earlier declaration of the class, if any.
4776const decl_base_sptr
4778{return priv_->declaration_;}
4779
4780/// set the earlier declaration of this @ref decl_base definition.
4781///
4782/// @param d the earlier declaration to set. Note that it's set only
4783/// if it's a pure declaration.
4784void
4786{
4787 if (d && d->get_is_declaration_only())
4788 priv_->declaration_ = d;
4789}
4790
4791
4792/// If this @ref decl_base is declaration-only, get its definition, if
4793/// any.
4794///
4795/// @return the definition of this decl-only @ref decl_base.
4796const decl_base_sptr
4798{return priv_->definition_of_declaration_.lock();}
4799
4800/// If this @ref decl_base is declaration-only, get its definition,
4801/// if any.
4802///
4803/// Note that this function doesn't return a smart pointer, but rather
4804/// the underlying pointer managed by the smart pointer. So it's as
4805/// fast as possible. This getter is to be used in code paths that
4806/// are proven to be performance hot spots; especially, when comparing
4807/// sensitive types like enums, classes or unions. Those are compared
4808/// extremely frequently and thus, their access to the definition of
4809/// declaration must be fast.
4810///
4811/// @return the definition of the declaration.
4812const decl_base*
4814{return priv_->naked_definition_of_declaration_;}
4815
4816/// Test if a @ref decl_base is a declaration-only decl.
4817///
4818/// @return true iff the current @ref decl_base is declaration-only.
4819bool
4821{return priv_->is_declaration_only_;}
4822
4823/// Set a flag saying if the @ref enum_type_decl is a declaration-only
4824/// @ref enum_type_decl.
4825///
4826/// @param f true if the @ref enum_type_decl is a declaration-only
4827/// @ref enum_type_decl.
4828void
4830{
4831 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
4832
4833 priv_->is_declaration_only_ = f;
4834
4835 if (update_types_lookup_map)
4836 if (scope_decl* s = get_scope())
4837 {
4838 scope_decl::declarations::iterator i;
4839 if (s->find_iterator_for_member(this, i))
4841 else
4843 }
4844}
4845
4848{
4849 return static_cast<change_kind>(static_cast<unsigned>(l)
4850 | static_cast<unsigned>(r));
4851}
4852
4855{
4856 return static_cast<change_kind>(static_cast<unsigned>(l)
4857 & static_cast<unsigned>(r));
4858}
4859
4862{
4863 l = l | r;
4864 return l;
4865}
4866
4869{
4870 l = l & r;
4871 return l;
4872}
4873
4874/// Compare the properties that belong to the "is-a-member-relation"
4875/// of a decl.
4876///
4877/// For instance, access specifiers are part of the
4878/// "is-a-member-relation" of a decl.
4879///
4880/// This comparison however doesn't take decl names into account. So
4881/// typedefs for instance are decls that we want to compare with this
4882/// function.
4883///
4884/// This function is a sub-routine of the more general 'equals'
4885/// overload for instances of decl_base.
4886///
4887/// @param l the left-hand side operand of the comparison.
4888///
4889/// @param r the right-hand side operand of the comparison.
4890///
4891/// @return true iff @p l compare equals, as a member decl, to @p r.
4892bool
4894 const decl_base& r,
4895 change_kind* k)
4896{
4897 bool result = true;
4898 if (is_member_decl(l) && is_member_decl(r))
4899 {
4900 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
4901 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
4902
4903 access_specifier la = no_access, ra = no_access;
4904 bool member_types_or_functions =
4905 ((is_type(l) && is_type(r))
4906 || (is_function_decl(l) && is_function_decl(r)));
4907
4908 if (member_types_or_functions)
4909 {
4910 // Access specifiers on member types in DWARF is not
4911 // reliable; in the same DSO, the same struct can be either
4912 // a class or a struct, and the access specifiers of its
4913 // member types are not necessarily given, so they
4914 // effectively can be considered differently, again, in the
4915 // same DSO. So, here, let's avoid considering those!
4916 // during comparison.
4917 la = r1->get_access_specifier();
4918 ra = r2->get_access_specifier();
4919 r1->set_access_specifier(no_access);
4920 r2->set_access_specifier(no_access);
4921 }
4922
4923 bool rels_are_different = *r1 != *r2;
4924
4925 if (member_types_or_functions)
4926 {
4927 // restore the access specifiers.
4928 r1->set_access_specifier(la);
4929 r2->set_access_specifier(ra);
4930 }
4931
4932 if (rels_are_different)
4933 {
4934 result = false;
4935 if (k)
4937 }
4938 }
4939 ABG_RETURN(result);
4940}
4941
4942/// Compares two instances of @ref decl_base.
4943///
4944/// If the two intances are different, set a bitfield to give some
4945/// insight about the kind of differences there are.
4946///
4947/// @param l the first artifact of the comparison.
4948///
4949/// @param r the second artifact of the comparison.
4950///
4951/// @param k a pointer to a bitfield that gives information about the
4952/// kind of changes there are between @p l and @p r. This one is set
4953/// iff it's non-null and if the function returns false.
4954///
4955/// Please note that setting k to a non-null value does have a
4956/// negative performance impact because even if @p l and @p r are not
4957/// equal, the function keeps up the comparison in order to determine
4958/// the different kinds of ways in which they are different.
4959///
4960/// @return true if @p l equals @p r, false otherwise.
4961bool
4962equals(const decl_base& l, const decl_base& r, change_kind* k)
4963{
4964 bool result = true;
4965 const interned_string &l_linkage_name = l.get_linkage_name();
4966 const interned_string &r_linkage_name = r.get_linkage_name();
4967 if (!l_linkage_name.empty() && !r_linkage_name.empty())
4968 {
4969 if (l_linkage_name != r_linkage_name)
4970 {
4971 // Linkage names are different. That usually means the two
4972 // decls are different, unless we are looking at two
4973 // function declarations which have two different symbols
4974 // that are aliases of each other.
4975 const function_decl *f1 = is_function_decl(&l),
4976 *f2 = is_function_decl(&r);
4977 if (f1 && f2 && function_decls_alias(*f1, *f2))
4978 ;// The two functions are aliases, so they are not
4979 // different.
4980 else
4981 {
4982 result = false;
4983 if (k)
4985 else
4987 }
4988 }
4989 }
4990
4991 if (r.get_is_anonymous() && l.get_is_anonymous())
4992 // We are looking at too anonymous types (or two members of
4993 // anonymous types) with one not yet been added to the IR. That
4994 // means we want to compare just the object part of the
4995 // anonymous type and not their qualified names. This is used
4996 // when looking up an anonymous type inside a class type.
4997 ABG_RETURN(result);
4998
4999 // This is the name of the decls that we want to compare.
5000 interned_string ln = l.get_name(), rn = r.get_name();
5001
5002 /// If both of the current decls have an anonymous scope then let's
5003 /// compare their name component by component by properly handling
5004 /// anonymous scopes. That's the slow path.
5005 ///
5006 /// Otherwise, let's just compare their name, the obvious way.
5007 /// That's the fast path because in that case the names are
5008 /// interned_string and comparing them is much faster.
5009 bool decls_are_same = (ln == rn);
5010
5011 if (!decls_are_same)
5012 {
5013 result = false;
5014 if (k)
5016 else
5018 }
5019
5020 result &= maybe_compare_as_member_decls(l, r, k);
5021
5022 ABG_RETURN(result);
5023}
5024
5025/// Return true iff the two decls have the same name.
5026///
5027/// This function doesn't test if the scopes of the the two decls are
5028/// equal.
5029///
5030/// Note that this virtual function is to be implemented by classes
5031/// that extend the \p decl_base class.
5032bool
5034{return equals(*this, other, 0);}
5035
5036/// Inequality operator.
5037///
5038/// @param other to other instance of @ref decl_base to compare the
5039/// current instance to.
5040///
5041/// @return true iff the current instance of @ref decl_base is
5042/// different from @p other.
5043bool
5045{return !operator==(other);}
5046
5047/// Destructor of the @ref decl_base type.
5049{delete priv_;}
5050
5051/// This implements the ir_traversable_base::traverse pure virtual
5052/// function.
5053///
5054/// @param v the visitor used on the member nodes of the translation
5055/// unit during the traversal.
5056///
5057/// @return true if the entire IR node tree got traversed, false
5058/// otherwise.
5059bool
5061{
5062 // Do nothing in the base class.
5063 return true;
5064}
5065
5066/// Setter of the scope of the current decl.
5067///
5068/// Note that the decl won't hold a reference on the scope. It's
5069/// rather the scope that holds a reference on its members.
5070void
5072{
5073 if (!priv_->context_)
5074 priv_->context_ = new context_rel(scope);
5075 else
5076 priv_->context_->set_scope(scope);
5077}
5078
5079// </decl_base definition>
5080
5081/// Streaming operator for the decl_base::visibility.
5082///
5083/// @param o the output stream to serialize the visibility to.
5084///
5085/// @param v the visibility to serialize.
5086///
5087/// @return the output stream.
5088std::ostream&
5089operator<<(std::ostream& o, decl_base::visibility v)
5090{
5091 string r;
5092 switch (v)
5093 {
5094 case decl_base::VISIBILITY_NONE:
5095 r = "none";
5096 break;
5097 case decl_base::VISIBILITY_DEFAULT:
5098 r = "default";
5099 break;
5100 case decl_base::VISIBILITY_PROTECTED:
5101 r = "protected";
5102 break;
5103 case decl_base::VISIBILITY_HIDDEN:
5104 r = "hidden";
5105 break;
5106 case decl_base::VISIBILITY_INTERNAL:
5107 r = "internal";
5108 break;
5109 }
5110 return o;
5111}
5112
5113/// Streaming operator for decl_base::binding.
5114///
5115/// @param o the output stream to serialize the visibility to.
5116///
5117/// @param b the binding to serialize.
5118///
5119/// @return the output stream.
5120std::ostream&
5121operator<<(std::ostream& o, decl_base::binding b)
5122{
5123 string r;
5124 switch (b)
5125 {
5126 case decl_base::BINDING_NONE:
5127 r = "none";
5128 break;
5129 case decl_base::BINDING_LOCAL:
5130 r = "local";
5131 break;
5132 case decl_base::BINDING_GLOBAL:
5133 r = "global";
5134 break;
5135 case decl_base::BINDING_WEAK:
5136 r = "weak";
5137 break;
5138 }
5139 o << r;
5140 return o;
5141}
5142
5143/// Turn equality of shared_ptr of decl_base into a deep equality;
5144/// that is, make it compare the pointed to objects, not just the
5145/// pointers.
5146///
5147/// @param l the shared_ptr of decl_base on left-hand-side of the
5148/// equality.
5149///
5150/// @param r the shared_ptr of decl_base on right-hand-side of the
5151/// equality.
5152///
5153/// @return true if the decl_base pointed to by the shared_ptrs are
5154/// equal, false otherwise.
5155bool
5156operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5157{
5158 if (l.get() == r.get())
5159 return true;
5160 if (!!l != !!r)
5161 return false;
5162
5163 return *l == *r;
5164}
5165
5166/// Inequality operator of shared_ptr of @ref decl_base.
5167///
5168/// This is a deep equality operator, that is, it compares the
5169/// pointed-to objects, rather than just the pointers.
5170///
5171/// @param l the left-hand-side operand.
5172///
5173/// @param r the right-hand-side operand.
5174///
5175/// @return true iff @p l is different from @p r.
5176bool
5177operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5178{return !operator==(l, r);}
5179
5180/// Turn equality of shared_ptr of type_base into a deep equality;
5181/// that is, make it compare the pointed to objects too.
5182///
5183/// @param l the shared_ptr of type_base on left-hand-side of the
5184/// equality.
5185///
5186/// @param r the shared_ptr of type_base on right-hand-side of the
5187/// equality.
5188///
5189/// @return true if the type_base pointed to by the shared_ptrs are
5190/// equal, false otherwise.
5191bool
5192operator==(const type_base_sptr& l, const type_base_sptr& r)
5193{
5194 if (l.get() == r.get())
5195 return true;
5196 if (!!l != !!r)
5197 return false;
5198
5199 return *l == *r;
5200}
5201
5202/// Turn inequality of shared_ptr of type_base into a deep equality;
5203/// that is, make it compare the pointed to objects..
5204///
5205/// @param l the shared_ptr of type_base on left-hand-side of the
5206/// equality.
5207///
5208/// @param r the shared_ptr of type_base on right-hand-side of the
5209/// equality.
5210///
5211/// @return true iff the type_base pointed to by the shared_ptrs are
5212/// different.
5213bool
5214operator!=(const type_base_sptr& l, const type_base_sptr& r)
5215{return !operator==(l, r);}
5216
5217/// Tests if a declaration has got a scope.
5218///
5219/// @param d the declaration to consider.
5220///
5221/// @return true if the declaration has got a scope, false otherwise.
5222bool
5224{return (d.get_scope());}
5225
5226/// Tests if a declaration has got a scope.
5227///
5228/// @param d the declaration to consider.
5229///
5230/// @return true if the declaration has got a scope, false otherwise.
5231bool
5232has_scope(const decl_base_sptr d)
5233{return has_scope(*d.get());}
5234
5235/// Tests if a declaration is a class member.
5236///
5237/// @param d the declaration to consider.
5238///
5239/// @return true if @p d is a class member, false otherwise.
5240bool
5241is_member_decl(const decl_base_sptr d)
5242{return is_at_class_scope(d) || is_method_decl(d);}
5243
5244/// Tests if a declaration is a class member.
5245///
5246/// @param d the declaration to consider.
5247///
5248/// @return true if @p d is a class member, false otherwise.
5249bool
5251{return is_at_class_scope(d) || is_method_decl(d);}
5252
5253/// Tests if a declaration is a class member.
5254///
5255/// @param d the declaration to consider.
5256///
5257/// @return true if @p d is a class member, false otherwise.
5258bool
5260{return is_at_class_scope(d) || is_method_decl(d);}
5261
5262/// Test if a declaration is a @ref scope_decl.
5263///
5264/// @param d the declaration to take in account.
5265///
5266/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5267/// if d is a @ref scope_decl.
5268const scope_decl*
5270{return dynamic_cast<const scope_decl*>(d);}
5271
5272/// Test if a declaration is a @ref scope_decl.
5273///
5274/// @param d the declaration to take in account.
5275///
5276/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5277/// if d is a @ref scope_decl.
5279is_scope_decl(const decl_base_sptr& d)
5280{return dynamic_pointer_cast<scope_decl>(d);}
5281
5282/// Tests if a type is a class member.
5283///
5284/// @param t the type to consider.
5285///
5286/// @return true if @p t is a class member type, false otherwise.
5287bool
5288is_member_type(const type_base_sptr& t)
5289{
5290 decl_base_sptr d = get_type_declaration(t);
5291 return is_member_decl(d);
5292}
5293
5294/// Test if a type is user-defined.
5295///
5296/// A type is considered user-defined if it's a
5297/// struct/class/union/enum that is *NOT* artificial.
5298///
5299/// @param t the type to consider.
5300///
5301/// @return true iff the type @p t is user-defined.
5302bool
5304{
5305 if (t == 0)
5306 return false;
5307
5309 decl_base *d = is_decl(t);
5310
5312 && d && !d->get_is_artificial())
5313 return true;
5314
5315 return false;
5316}
5317
5318/// Test if a type is user-defined.
5319///
5320/// A type is considered user-defined if it's a
5321/// struct/class/union/enum.
5322///
5323///
5324/// @param t the type to consider.
5325///
5326/// @return true iff the type @p t is user-defined.
5327bool
5328is_user_defined_type(const type_base_sptr& t)
5329{return is_user_defined_type(t.get());}
5330
5331/// Gets the access specifier for a class member.
5332///
5333/// @param d the declaration of the class member to consider. Note
5334/// that this must be a class member otherwise the function aborts the
5335/// current process.
5336///
5337/// @return the access specifier for the class member @p d.
5340{
5342
5343 const context_rel* c = d.get_context_rel();
5344 ABG_ASSERT(c);
5345
5346 return c->get_access_specifier();
5347}
5348
5349/// Gets the access specifier for a class member.
5350///
5351/// @param d the declaration of the class member to consider. Note
5352/// that this must be a class member otherwise the function aborts the
5353/// current process.
5354///
5355/// @return the access specifier for the class member @p d.
5357get_member_access_specifier(const decl_base_sptr& d)
5358{return get_member_access_specifier(*d);}
5359
5360/// Sets the access specifier for a class member.
5361///
5362/// @param d the class member to set the access specifier for. Note
5363/// that this must be a class member otherwise the function aborts the
5364/// current process.
5365///
5366/// @param a the new access specifier to set the class member to.
5367void
5370{
5372
5374 ABG_ASSERT(c);
5375
5376 c->set_access_specifier(a);
5377}
5378
5379/// Sets the access specifier for a class member.
5380///
5381/// @param d the class member to set the access specifier for. Note
5382/// that this must be a class member otherwise the function aborts the
5383/// current process.
5384///
5385/// @param a the new access specifier to set the class member to.
5386void
5387set_member_access_specifier(const decl_base_sptr& d,
5390
5391/// Gets a flag saying if a class member is static or not.
5392///
5393/// @param d the declaration for the class member to consider. Note
5394/// that this must be a class member otherwise the function aborts the
5395/// current process.
5396///
5397/// @return true if the class member @p d is static, false otherwise.
5398bool
5400{
5402
5403 const context_rel* c = d.get_context_rel();
5404 ABG_ASSERT(c);
5405
5406 return c->get_is_static();
5407}
5408
5409/// Gets a flag saying if a class member is static or not.
5410///
5411/// @param d the declaration for the class member to consider. Note
5412/// that this must be a class member otherwise the function aborts the
5413/// current process.
5414///
5415/// @return true if the class member @p d is static, false otherwise.
5416bool
5418{return get_member_is_static(*d);}
5419
5420/// Gets a flag saying if a class member is static or not.
5421///
5422/// @param d the declaration for the class member to consider. Note
5423/// that this must be a class member otherwise the function aborts the
5424/// current process.
5425///
5426/// @return true if the class member @p d is static, false otherwise.
5427bool
5428get_member_is_static(const decl_base_sptr& d)
5429{return get_member_is_static(*d);}
5430
5431/// Test if a var_decl is a data member.
5432///
5433/// @param v the var_decl to consider.
5434///
5435/// @return true if @p v is data member, false otherwise.
5436bool
5438{return is_at_class_scope(v);}
5439
5440/// Test if a var_decl is a data member.
5441///
5442/// @param v the var_decl to consider.
5443///
5444/// @return true if @p v is data member, false otherwise.
5445bool
5447{return is_data_member(*v);}
5448
5449/// Test if a var_decl is a data member.
5450///
5451/// @param v the var_decl to consider.
5452///
5453/// @return true if @p v is data member, false otherwise.
5454bool
5456{return is_at_class_scope(d);}
5457
5458/// Test if a decl is a data member.
5459///
5460/// @param d the decl to consider.
5461///
5462/// @return a pointer to the data member iff @p d is a data member, or
5463/// a null pointer.
5465is_data_member(const decl_base_sptr& d)
5466{
5467 if (var_decl_sptr v = is_var_decl(d))
5468 {
5469 if (is_data_member(v))
5470 return v;
5471 }
5472 return var_decl_sptr();
5473}
5474
5475/// Test if a decl is a data member.
5476///
5477/// @param d the decl to consider.
5478///
5479/// @return a pointer to the data member iff @p d is a data member, or
5480/// a null pointer.
5483{
5484 if (var_decl_sptr v = is_var_decl(d))
5485 {
5486 if (is_data_member(v))
5487 return v;
5488 }
5489 return var_decl_sptr();
5490}
5491
5492/// Test if a decl is a data member.
5493///
5494/// @param d the decl to consider.
5495///
5496/// @return a pointer to the data member iff @p d is a data member, or
5497/// a null pointer.
5498var_decl*
5500{
5501 if (var_decl *v = is_var_decl(d))
5502 if (is_data_member(v))
5503 return v;
5504 return 0;
5505}
5506
5507/// Test if a decl is a data member.
5508///
5509/// @param d the decl to consider.
5510///
5511/// @return a pointer to the data member iff @p d is a data member, or
5512/// a null pointer.
5513var_decl*
5515{
5516 if (var_decl *v = is_var_decl(d))
5517 if (is_data_member(v))
5518 return v;
5519 return 0;
5520}
5521
5522/// Get the first non-anonymous data member of a given anonymous data
5523/// member.
5524///
5525/// E.g:
5526///
5527/// struct S
5528/// {
5529/// union // <-- for this anonymous data member, the function
5530/// // returns a.
5531/// {
5532/// int a;
5533/// charb;
5534/// };
5535/// };
5536///
5537/// @return anon_dm the anonymous data member to consider.
5538///
5539/// @return the first non-anonymous data member of @p anon_dm. If no
5540/// data member was found then this function returns @p anon_dm.
5541const var_decl_sptr
5543{
5544 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5545 return anon_dm;
5546
5547 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5548 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5549
5550 if (is_anonymous_data_member(first))
5552
5553 return first;
5554}
5555
5556/// In the context of a given class or union, this function returns
5557/// the data member that is located after a given data member.
5558///
5559/// @param klass the class or union to consider.
5560///
5561/// @param the data member to consider.
5562///
5563/// @return the data member that is located right after @p
5564/// data_member.
5565const var_decl_sptr
5567 const var_decl_sptr &data_member)
5568{
5569 if (!klass ||!data_member)
5570 return var_decl_sptr();
5571
5572 for (class_or_union::data_members::const_iterator it =
5573 klass->get_non_static_data_members().begin();
5574 it != klass->get_non_static_data_members().end();
5575 ++it)
5576 if (**it == *data_member)
5577 {
5578 ++it;
5579 if (it != klass->get_non_static_data_members().end())
5581 break;
5582 }
5583
5584 return var_decl_sptr();
5585}
5586
5587/// In the context of a given class or union, this function returns
5588/// the data member that is located after a given data member.
5589///
5590/// @param klass the class or union to consider.
5591///
5592/// @param the data member to consider.
5593///
5594/// @return the data member that is located right after @p
5595/// data_member.
5596const var_decl_sptr
5597get_next_data_member(const class_or_union_sptr& klass,
5598 const var_decl_sptr &data_member)
5599{return get_next_data_member(klass.get(), data_member);}
5600
5601/// Get the last data member of a class type.
5602///
5603/// @param klass the class type to consider.
5606{return klass.get_non_static_data_members().back();}
5607
5608/// Get the last data member of a class type.
5609///
5610/// @param klass the class type to consider.
5613{return get_last_data_member(*klass);}
5614
5615/// Get the last data member of a class type.
5616///
5617/// @param klass the class type to consider.
5619get_last_data_member(const class_or_union_sptr &klass)
5620{return get_last_data_member(klass.get());}
5621
5622/// Collect all the non-anonymous data members of a class or union type.
5623///
5624/// If the class contains any anonymous data member, this function
5625/// looks through it to collect the non-anonymous data members that it
5626/// contains. The function also also looks through the base classes
5627/// of the current type.
5628///
5629/// @param cou the class or union type to consider.
5630///
5631/// @param dms output parameter. This is populated by the function
5632/// with a map containing the non-anonymous data members that were
5633/// collected. The key of the map is the name of the data member.
5634/// This is set iff the function returns true.
5635///
5636/// @return true iff at least one non-anonymous data member was
5637/// collected.
5638bool
5641{
5642 if (!cou)
5643 return false;
5644
5645 bool result = false;
5646 class_decl* klass = is_class_type(cou);
5647 if (klass)
5648 // First look into base classes for data members.
5650 result |= collect_non_anonymous_data_members(base->get_base_class().get(), dms);
5651
5652 // Then look into our data members
5653 for (var_decl_sptr member : cou->get_non_static_data_members())
5654 {
5655 if (is_anonymous_data_member(member))
5656 {
5657 class_or_union_sptr cl = anonymous_data_member_to_class_or_union(member);
5658 ABG_ASSERT(cl);
5659 result |= collect_non_anonymous_data_members(cl.get(), dms);
5660 }
5661 else
5662 {
5663 dms[member->get_name()] = member;
5664 result = true;
5665 }
5666 }
5667 return true;
5668}
5669
5670/// Collect all the non-anonymous data members of a class or union type.
5671///
5672/// If the class contains any anonymous data member, this function
5673/// looks through it to collect the non-anonymous data members that it
5674/// contains. The function also also looks through the base classes
5675/// of the current type.
5676///
5677/// @param cou the class or union type to consider.
5678///
5679/// @param dms output parameter. This is populated by the function
5680/// with a map containing the non-anonymous data members that were
5681/// collected. The key of the map is the name of the data member.
5682/// This is set iff the function returns true.
5683///
5684/// @return true iff at least one non-anonymous data member was
5685/// collected.
5686bool
5688{return collect_non_anonymous_data_members(cou.get(), dms);}
5689
5690/// Test if a decl is an anonymous data member.
5691///
5692/// @param d the decl to consider.
5693///
5694/// @return true iff @p d is an anonymous data member.
5695bool
5697{return is_anonymous_data_member(&d);}
5698
5699/// Test if a decl is an anonymous data member.
5700///
5701/// @param d the decl to consider.
5702///
5703/// @return the var_decl representing the data member iff @p d is an
5704/// anonymous data member.
5705const var_decl*
5707{
5708 if (const var_decl* v = is_data_member(d))
5709 {
5711 return v;
5712 }
5713 return 0;
5714}
5715
5716/// Test if a decl is an anonymous data member.
5717///
5718/// @param d the decl to consider.
5719///
5720/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5721/// it's an anonymous data member. Otherwise returns a nil pointer.
5722const var_decl*
5724{
5725 if (const var_decl* v = is_data_member(d))
5726 {
5728 return v;
5729 }
5730 return 0;
5731}
5732
5733/// Test if a decl is an anonymous data member.
5734///
5735/// @param d the decl to consider.
5736///
5737/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5738/// it's an anonymous data member. Otherwise returns a nil pointer.
5741{
5742 if (var_decl_sptr v = is_data_member(d))
5743 {
5745 return v;
5746 }
5747 return var_decl_sptr();
5748}
5749
5750/// Test if a decl is an anonymous data member.
5751///
5752/// @param d the decl to consider.
5753///
5754/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5755/// it's an anonymous data member. Otherwise returns a nil pointer.
5757is_anonymous_data_member(const decl_base_sptr& d)
5758{
5759 if (var_decl_sptr v = is_data_member(d))
5760 return is_anonymous_data_member(v);
5761 return var_decl_sptr();
5762}
5763
5764/// Test if a @ref var_decl is an anonymous data member.
5765///
5766/// @param d the @ref var_decl to consider.
5767///
5768/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5769/// it's an anonymous data member. Otherwise returns a nil pointer.
5772{
5773 if (is_anonymous_data_member(d.get()))
5774 return d;
5775 return var_decl_sptr();
5776}
5777
5778/// Test if a @ref var_decl is an anonymous data member.
5779///
5780/// @param d the @ref var_decl to consider.
5781///
5782/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5783/// it's an anonymous data member. Otherwise returns a nil pointer.
5784const var_decl*
5786{
5787 if (d && is_anonymous_data_member(*d))
5788 return d;
5789 return 0;
5790}
5791
5792/// Test if a @ref var_decl is an anonymous data member.
5793///
5794/// @param d the @ref var_decl to consider.
5795///
5796/// @return true iff @p d is an anonymous data member.
5797bool
5799{
5800 return (is_data_member(d)
5801 && d.get_is_anonymous()
5802 && d.get_name().empty()
5804}
5805
5806/// Test if a @ref var_decl is a data member belonging to an anonymous
5807/// type.
5808///
5809/// @param d the @ref var_decl to consider.
5810///
5811/// @return true iff @p d is a data member belonging to an anonymous
5812/// type.
5813bool
5815{
5816 if (is_data_member(d))
5817 {
5818 scope_decl* scope = d.get_scope();
5819 if (scope && scope->get_is_anonymous())
5820 return true;
5821 }
5822 return false;
5823}
5824
5825/// Test if a @ref var_decl is a data member belonging to an anonymous
5826/// type.
5827///
5828/// @param d the @ref var_decl to consider.
5829///
5830/// @return true iff @p d is a data member belonging to an anonymous
5831/// type.
5832bool
5835
5836/// Test if a @ref var_decl is a data member belonging to an anonymous
5837/// type.
5838///
5839/// @param d the @ref var_decl to consider.
5840///
5841/// @return true iff @p d is a data member belonging to an anonymous
5842/// type.
5843bool
5846
5847/// Get the @ref class_or_union type of a given anonymous data member.
5848///
5849/// @param d the anonymous data member to consider.
5850///
5851/// @return the @ref class_or_union type of the anonymous data member
5852/// @p d.
5855{
5856 if ((d = is_anonymous_data_member(d)))
5857 return is_class_or_union_type(d->get_type().get());
5858 return 0;
5859}
5860
5861/// Get the @ref class_or_union type of a given anonymous data member.
5862///
5863/// @param d the anonymous data member to consider.
5864///
5865/// @return the @ref class_or_union type of the anonymous data member
5866/// @p d.
5867class_or_union_sptr
5869{
5871 return is_class_or_union_type(d.get_type());
5872 return class_or_union_sptr();
5873}
5874
5875/// Test if a data member has annonymous type or not.
5876///
5877/// @param d the data member to consider.
5878///
5879/// @return the anonymous class or union type iff @p turns out to have
5880/// an anonymous type. Otherwise, returns nil.
5881const class_or_union_sptr
5883{
5884 if (is_data_member(d))
5885 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
5886 if (cou->get_is_anonymous())
5887 return cou;
5888
5889 return class_or_union_sptr();
5890}
5891
5892/// Test if a data member has annonymous type or not.
5893///
5894/// @param d the data member to consider.
5895///
5896/// @return the anonymous class or union type iff @p turns out to have
5897/// an anonymous type. Otherwise, returns nil.
5898const class_or_union_sptr
5900{
5901 if (d)
5903 return class_or_union_sptr();
5904}
5905
5906/// Test if a data member has annonymous type or not.
5907///
5908/// @param d the data member to consider.
5909///
5910/// @return the anonymous class or union type iff @p turns out to have
5911/// an anonymous type. Otherwise, returns nil.
5912const class_or_union_sptr
5914{return data_member_has_anonymous_type(d.get());}
5915
5916/// Get the @ref class_or_union type of a given anonymous data member.
5917///
5918/// @param d the anonymous data member to consider.
5919///
5920/// @return the @ref class_or_union type of the anonymous data member
5921/// @p d.
5922class_or_union_sptr
5924{
5926 return is_class_or_union_type(v->get_type());
5927 return class_or_union_sptr();
5928}
5929
5930/// Test if a given anonymous data member exists in a class or union.
5931///
5932/// @param anon_dm the anonymous data member to consider.
5933///
5934/// @param clazz the class to consider.
5935///
5936/// @return true iff @p anon_dm exists in the @clazz.
5937bool
5939 const class_or_union& clazz)
5940{
5941 if (!anon_dm.get_is_anonymous()
5942 || !is_class_or_union_type(anon_dm.get_type()))
5943 return false;
5944
5945 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
5946 ABG_ASSERT(cl);
5947
5948 // Look for the presence of each data member of anon_dm in clazz.
5949 //
5950 // If one data member of anon_dm is not present in clazz, then the
5951 // data member anon_dm is considered to not exist in clazz.
5952 for (auto anon_dm_m : cl->get_non_static_data_members())
5953 {
5954 // If the data member anon_dm_m is not an anonymous data member,
5955 // it's easy to look for it.
5956 if (!is_anonymous_data_member(anon_dm_m))
5957 {
5958 if (!clazz.find_data_member(anon_dm_m->get_name()))
5959 return false;
5960 }
5961 // If anon_dm_m is itself an anonymous data member then recurse
5962 else
5963 {
5964 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
5965 return false;
5966 }
5967 }
5968
5969 return true;
5970}
5971
5972/// Test if a given decl is anonymous or has a naming typedef.
5973///
5974/// @param d the decl to consider.
5975///
5976/// @return true iff @p d is anonymous or has a naming typedef.
5977bool
5979{
5980 if (d.get_is_anonymous() || d.get_naming_typedef())
5981 return true;
5982 return false;
5983}
5984
5985/// Set the offset of a data member into its containing class.
5986///
5987/// @param m the data member to consider.
5988///
5989/// @param o the offset, in bits.
5990void
5992{
5994
5995 dm_context_rel* ctxt_rel =
5996 dynamic_cast<dm_context_rel*>(m->get_context_rel());
5997 ABG_ASSERT(ctxt_rel);
5998
5999 ctxt_rel->set_offset_in_bits(o);
6000}
6001
6002/// Get the offset of a data member.
6003///
6004/// @param m the data member to consider.
6005///
6006/// @return the offset (in bits) of @p m in its containing class.
6007uint64_t
6009{
6011 const dm_context_rel* ctxt_rel =
6012 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6013 ABG_ASSERT(ctxt_rel);
6014 return ctxt_rel->get_offset_in_bits();
6015}
6016
6017/// Get the offset of a data member.
6018///
6019/// @param m the data member to consider.
6020///
6021/// @return the offset (in bits) of @p m in its containing class.
6022uint64_t
6024{return get_data_member_offset(*m);}
6025
6026/// Get the offset of a data member.
6027///
6028/// @param m the data member to consider.
6029///
6030/// @return the offset (in bits) of @p m in its containing class.
6031uint64_t
6032get_data_member_offset(const decl_base_sptr d)
6033{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6034
6035/// Get the offset of the non-static data member that comes after a
6036/// given one.
6037///
6038/// If there is no data member after after the one given to this
6039/// function (maybe because the given one is the last data member of
6040/// the class type) then the function return false.
6041///
6042/// @param klass the class to consider.
6043///
6044/// @param dm the data member before the one we want to retrieve.
6045///
6046/// @param offset out parameter. This parameter is set by the
6047/// function to the offset of the data member that comes right after
6048/// the data member @p dm, iff the function returns true.
6049///
6050/// @return true iff the data member coming right after @p dm was
6051/// found.
6052bool
6054 const var_decl_sptr& dm,
6055 uint64_t& offset)
6056{
6057 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6058 if (!next_dm)
6059 return false;
6060 offset = get_data_member_offset(next_dm);
6061 return true;
6062}
6063
6064/// Get the offset of the non-static data member that comes after a
6065/// given one.
6066///
6067/// If there is no data member after after the one given to this
6068/// function (maybe because the given one is the last data member of
6069/// the class type) then the function return false.
6070///
6071/// @param klass the class to consider.
6072///
6073/// @param dm the data member before the one we want to retrieve.
6074///
6075/// @param offset out parameter. This parameter is set by the
6076/// function to the offset of the data member that comes right after
6077/// the data member @p dm, iff the function returns true.
6078///
6079/// @return true iff the data member coming right after @p dm was
6080/// found.
6081bool
6082get_next_data_member_offset(const class_or_union_sptr& klass,
6083 const var_decl_sptr& dm,
6084 uint64_t& offset)
6085{return get_next_data_member_offset(klass.get(), dm, offset);}
6086
6087/// Get the absolute offset of a data member.
6088///
6089/// If the data member is part of an anonymous data member then this
6090/// returns the absolute offset -- relative to the beginning of the
6091/// containing class of the anonymous data member.
6092///
6093/// @param m the data member to consider.
6094///
6095/// @return the aboslute offset of the data member @p m.
6096uint64_t
6098{
6100 const dm_context_rel* ctxt_rel =
6101 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6102 ABG_ASSERT(ctxt_rel);
6103
6104 const var_decl *containing_anonymous_data_member =
6105 ctxt_rel->get_anonymous_data_member();
6106
6107 uint64_t containing_anonymous_data_member_offset = 0;
6108 if (containing_anonymous_data_member)
6109 containing_anonymous_data_member_offset =
6110 get_absolute_data_member_offset(*containing_anonymous_data_member);
6111
6112 return (ctxt_rel->get_offset_in_bits()
6113 +
6114 containing_anonymous_data_member_offset);
6115}
6116
6117/// Get the absolute offset of a data member.
6118///
6119/// If the data member is part of an anonymous data member then this
6120/// returns the absolute offset -- relative to the beginning of the
6121/// containing class of the anonymous data member.
6122///
6123/// @param m the data member to consider.
6124///
6125/// @return the aboslute offset of the data member @p m.
6126uint64_t
6128{
6129 if (!m)
6130 return 0;
6132}
6133
6134/// Get the size of a given variable.
6135///
6136/// @param v the variable to consider.
6137///
6138/// @return the size of variable @p v.
6139uint64_t
6141{
6142 type_base_sptr t = v->get_type();
6143 ABG_ASSERT(t);
6144
6145 return t->get_size_in_bits();
6146}
6147
6148/// Set a flag saying if a data member is laid out.
6149///
6150/// @param m the data member to consider.
6151///
6152/// @param l true if @p m is to be considered as laid out.
6153void
6155{
6157 dm_context_rel* ctxt_rel =
6158 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6159 ctxt_rel->set_is_laid_out(l);
6160}
6161
6162/// Test whether a data member is laid out.
6163///
6164/// @param m the data member to consider.
6165///
6166/// @return true if @p m is laid out, false otherwise.
6167bool
6169{
6171 const dm_context_rel* ctxt_rel =
6172 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6173
6174 return ctxt_rel->get_is_laid_out();
6175}
6176
6177/// Test whether a data member is laid out.
6178///
6179/// @param m the data member to consider.
6180///
6181/// @return true if @p m is laid out, false otherwise.
6182bool
6184{return get_data_member_is_laid_out(*m);}
6185
6186/// Test whether a function_decl is a member function.
6187///
6188/// @param f the function_decl to test.
6189///
6190/// @return true if @p f is a member function, false otherwise.
6191bool
6193{return is_member_decl(f);}
6194
6195/// Test whether a function_decl is a member function.
6196///
6197/// @param f the function_decl to test.
6198///
6199/// @return true if @p f is a member function, false otherwise.
6200bool
6202{return is_member_decl(*f);}
6203
6204/// Test whether a function_decl is a member function.
6205///
6206/// @param f the function_decl to test.
6207///
6208/// @return true if @p f is a member function, false otherwise.
6209bool
6211{return is_member_decl(*f);}
6212
6213/// Test whether a member function is a constructor.
6214///
6215/// @param f the member function to test.
6216///
6217/// @return true if @p f is a constructor, false otherwise.
6218bool
6220{
6222
6223 const method_decl* m = is_method_decl(&f);
6224 ABG_ASSERT(m);
6225
6226 const mem_fn_context_rel* ctxt =
6227 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6228
6229 return ctxt->is_constructor();
6230}
6231
6232/// Test whether a member function is a constructor.
6233///
6234/// @param f the member function to test.
6235///
6236/// @return true if @p f is a constructor, false otherwise.
6237bool
6239{return get_member_function_is_ctor(*f);}
6240
6241
6242/// Setter for the is_ctor property of the member function.
6243///
6244/// @param f the member function to set.
6245///
6246/// @param f the new boolean value of the is_ctor property. Is true
6247/// if @p f is a constructor, false otherwise.
6248void
6250{
6252
6253 method_decl* m = is_method_decl(&f);
6254 ABG_ASSERT(m);
6255
6256 mem_fn_context_rel* ctxt =
6257 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6258
6259 ctxt->is_constructor(c);
6260}
6261
6262/// Setter for the is_ctor property of the member function.
6263///
6264/// @param f the member function to set.
6265///
6266/// @param f the new boolean value of the is_ctor property. Is true
6267/// if @p f is a constructor, false otherwise.
6268void
6271
6272/// Test whether a member function is a destructor.
6273///
6274/// @param f the function to test.
6275///
6276/// @return true if @p f is a destructor, false otherwise.
6277bool
6279{
6281
6282 const method_decl* m = is_method_decl(&f);
6283 ABG_ASSERT(m);
6284
6285 const mem_fn_context_rel* ctxt =
6286 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6287
6288 return ctxt->is_destructor();
6289}
6290
6291/// Test whether a member function is a destructor.
6292///
6293/// @param f the function to test.
6294///
6295/// @return true if @p f is a destructor, false otherwise.
6296bool
6298{return get_member_function_is_dtor(*f);}
6299
6300/// Set the destructor-ness property of a member function.
6301///
6302/// @param f the function to set.
6303///
6304/// @param d true if @p f is a destructor, false otherwise.
6305void
6307{
6309
6310 method_decl* m = is_method_decl(&f);
6311 ABG_ASSERT(m);
6312
6313 mem_fn_context_rel* ctxt =
6314 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6315
6316 ctxt->is_destructor(d);
6317}
6318
6319/// Set the destructor-ness property of a member function.
6320///
6321/// @param f the function to set.
6322///
6323/// @param d true if @p f is a destructor, false otherwise.
6324void
6327
6328/// Test whether a member function is const.
6329///
6330/// @param f the function to test.
6331///
6332/// @return true if @p f is const, false otherwise.
6333bool
6335{
6337
6338 const method_decl* m = is_method_decl(&f);
6339 ABG_ASSERT(m);
6340
6341 const mem_fn_context_rel* ctxt =
6342 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6343
6344 return ctxt->is_const();
6345}
6346
6347/// Test whether a member function is const.
6348///
6349/// @param f the function to test.
6350///
6351/// @return true if @p f is const, false otherwise.
6352bool
6354{return get_member_function_is_const(*f);}
6355
6356/// set the const-ness property of a member function.
6357///
6358/// @param f the function to set.
6359///
6360/// @param is_const the new value of the const-ness property of @p f
6361void
6363{
6365
6366 method_decl* m = is_method_decl(&f);
6367 ABG_ASSERT(m);
6368
6369 mem_fn_context_rel* ctxt =
6370 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6371
6372 ctxt->is_const(is_const);
6373}
6374
6375/// set the const-ness property of a member function.
6376///
6377/// @param f the function to set.
6378///
6379/// @param is_const the new value of the const-ness property of @p f
6380void
6382{set_member_function_is_const(*f, is_const);}
6383
6384/// Test if a virtual member function has a vtable offset set.
6385///
6386/// @param f the virtual member function to consider.
6387///
6388/// @return true iff the virtual member function has its vtable offset
6389/// set, i.e, if the vtable offset of @p is different from -1.
6390bool
6392{return get_member_function_vtable_offset(f) != -1;}
6393
6394/// Get the vtable offset of a member function.
6395///
6396/// @param f the member function to consider.
6397///
6398/// @return the vtable offset of @p f. Note that a vtable offset of
6399/// value -1 means that the member function does *NOT* yet have a
6400/// vtable offset associated to it.
6401ssize_t
6403{
6405
6406 const method_decl* m =
6407 dynamic_cast<const method_decl*>(&f);
6408 ABG_ASSERT(m);
6409
6410 const mem_fn_context_rel* ctxt =
6411 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6412
6413 return ctxt->vtable_offset();
6414}
6415
6416/// Get the vtable offset of a member function.
6417///
6418/// @param f the member function to consider.
6419///
6420/// @return the vtable offset of @p f. Note that a vtable offset of
6421/// value -1 means that the member function does *NOT* yet have a
6422/// vtable offset associated to it.
6423ssize_t
6426
6427/// Set the vtable offset of a member function.
6428///
6429/// @param f the member function to consider.
6430///
6431/// @param s the new vtable offset. Please note that a vtable offset
6432/// of value -1 means that the virtual member function does not (yet)
6433/// have any vtable offset associated to it.
6434static void
6435set_member_function_vtable_offset(function_decl& f, ssize_t s)
6436{
6438
6439 method_decl* m = is_method_decl(&f);
6440 ABG_ASSERT(m);
6441
6442 mem_fn_context_rel* ctxt =
6443 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6444
6445 ctxt->vtable_offset(s);
6446}
6447
6448/// Get the vtable offset of a member function.
6449///
6450/// @param f the member function to consider.
6451///
6452/// @param s the new vtable offset. Please note that a vtable offset
6453/// of value -1 means that the virtual member function does not (yet)
6454/// have any vtable offset associated to it.
6455static void
6456set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
6457{return set_member_function_vtable_offset(*f, s);}
6458
6459/// Test if a given member function is virtual.
6460///
6461/// @param mem_fn the member function to consider.
6462///
6463/// @return true iff a @p mem_fn is virtual.
6464bool
6466{
6468
6469 const method_decl* m =
6470 dynamic_cast<const method_decl*>(&f);
6471 ABG_ASSERT(m);
6472
6473 const mem_fn_context_rel* ctxt =
6474 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6475
6476 return ctxt->is_virtual();
6477}
6478
6479/// Test if a given member function is virtual.
6480///
6481/// @param mem_fn the member function to consider.
6482///
6483/// @return true iff a @p mem_fn is virtual.
6484bool
6486{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6487
6488/// Test if a given member function is virtual.
6489///
6490/// @param mem_fn the member function to consider.
6491///
6492/// @return true iff a @p mem_fn is virtual.
6493bool
6495{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6496
6497/// Set the virtual-ness of a member function.
6498///
6499/// @param f the member function to consider.
6500///
6501/// @param is_virtual set to true if the function is virtual.
6502static void
6503set_member_function_is_virtual(function_decl& f, bool is_virtual)
6504{
6506
6507 method_decl* m = is_method_decl(&f);
6508 ABG_ASSERT(m);
6509
6510 mem_fn_context_rel* ctxt =
6511 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6512
6513 ctxt->is_virtual(is_virtual);
6514}
6515
6516/// Set the virtual-ness of a member function.
6517///
6518/// @param f the member function to consider.
6519///
6520/// @param is_virtual set to true if the function is virtual.
6521static void
6522set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
6523{
6524 if (fn)
6525 {
6526 set_member_function_is_virtual(*fn, is_virtual);
6528 }
6529}
6530
6531/// Set the virtual-ness of a member fcuntion
6532///
6533/// @param fn the member function to consider.
6534///
6535/// @param is_virtual whether the function is virtual.
6536///
6537/// @param voffset the virtual offset of the virtual function.
6538void
6540 bool is_virtual,
6541 ssize_t voffset)
6542{
6543 // Setting the offset must come first because the second function
6544 // does assume the voffset is set, in case of virtuality
6545 set_member_function_vtable_offset(fn, voffset);
6546 set_member_function_is_virtual(fn, is_virtual);
6547}
6548
6549/// Set the virtual-ness of a member fcuntion
6550///
6551/// @param fn the member function to consider.
6552///
6553/// @param is_virtual whether the function is virtual.
6554///
6555/// @param voffset the virtual offset of the virtual function.
6556void
6558 bool is_virtual,
6559 ssize_t voffset)
6560{
6561 if (fn)
6562 set_member_function_virtuality(*fn, is_virtual, voffset);
6563}
6564
6565/// Set the virtual-ness of a member fcuntion
6566///
6567/// @param fn the member function to consider.
6568///
6569/// @param is_virtual whether the function is virtual.
6570///
6571/// @param voffset the virtual offset of the virtual function.
6572void
6574 bool is_virtual,
6575 ssize_t voffset)
6576{
6577 set_member_function_vtable_offset(fn, voffset);
6578 set_member_function_is_virtual(fn, is_virtual);
6579}
6580
6581/// Recursively returns the the underlying type of a typedef. The
6582/// return type should not be a typedef of anything anymore.
6583///
6584///
6585/// Also recursively strip typedefs from the sub-types of the type
6586/// given in arguments.
6587///
6588/// Note that this function builds types in which typedefs are
6589/// stripped off. Usually, types are held by their scope, so their
6590/// life time is bound to the life time of their scope. But as this
6591/// function cannot really insert the built type into it's scope, it
6592/// must ensure that the newly built type stays live long enough.
6593///
6594/// So, if the newly built type has a canonical type, this function
6595/// returns the canonical type. Otherwise, this function ensure that
6596/// the newly built type has a life time that is the same as the life
6597/// time of the entire libabigail library.
6598///
6599/// @param type the type to strip the typedefs from.
6600///
6601/// @return the resulting type stripped from its typedefs, or just
6602/// return @p type if it has no typedef in any of its sub-types.
6603type_base_sptr
6604strip_typedef(const type_base_sptr type)
6605{
6606 if (!type)
6607 return type;
6608
6609 // If type is a class type then do not try to strip typedefs from it.
6610 // And if it has no canonical type (which can mean that it's a
6611 // declaration-only class), then, make sure its live for ever and
6612 // return it.
6613 if (class_decl_sptr cl = is_class_type(type))
6614 {
6615 if (!cl->get_canonical_type())
6616 keep_type_alive(type);
6617 return type;
6618 }
6619
6620 const environment& env = type->get_environment();
6621 type_base_sptr t = type;
6622
6623 if (const typedef_decl_sptr ty = is_typedef(t))
6624 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6625 else if (const reference_type_def_sptr ty = is_reference_type(t))
6626 {
6627 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6628 env));
6629 ABG_ASSERT(p);
6630 t.reset(new reference_type_def(p,
6631 ty->is_lvalue(),
6632 ty->get_size_in_bits(),
6633 ty->get_alignment_in_bits(),
6634 ty->get_location()));
6635 }
6636 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6637 {
6638 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6639 env));
6640 ABG_ASSERT(p);
6641 t.reset(new pointer_type_def(p,
6642 ty->get_size_in_bits(),
6643 ty->get_alignment_in_bits(),
6644 ty->get_location()));
6645 }
6646 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6647 {
6648 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6649 env));
6650 ABG_ASSERT(p);
6651 t.reset(new qualified_type_def(p,
6652 ty->get_cv_quals(),
6653 ty->get_location()));
6654 }
6655 else if (const array_type_def_sptr ty = is_array_type(t))
6656 {
6657 type_base_sptr p = strip_typedef(ty->get_element_type());
6658 ABG_ASSERT(p);
6659 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6660 }
6661 else if (const method_type_sptr ty = is_method_type(t))
6662 {
6664 for (function_decl::parameters::const_iterator i =
6665 ty->get_parameters().begin();
6666 i != ty->get_parameters().end();
6667 ++i)
6668 {
6670 type_base_sptr typ = strip_typedef(p->get_type());
6671 ABG_ASSERT(typ);
6673 (new function_decl::parameter(typ,
6674 p->get_index(),
6675 p->get_name(),
6676 p->get_location(),
6677 p->get_variadic_marker(),
6678 p->get_is_artificial()));
6679 parm.push_back(stripped);
6680 }
6681 type_base_sptr p = strip_typedef(ty->get_return_type());
6682 ABG_ASSERT(!!p == !!ty->get_return_type());
6683 t.reset(new method_type(p, ty->get_class_type(),
6684 parm, ty->get_is_const(),
6685 ty->get_size_in_bits(),
6686 ty->get_alignment_in_bits()));
6687 }
6688 else if (const function_type_sptr ty = is_function_type(t))
6689 {
6691 for (function_decl::parameters::const_iterator i =
6692 ty->get_parameters().begin();
6693 i != ty->get_parameters().end();
6694 ++i)
6695 {
6697 type_base_sptr typ = strip_typedef(p->get_type());
6698 ABG_ASSERT(typ);
6700 (new function_decl::parameter(typ,
6701 p->get_index(),
6702 p->get_name(),
6703 p->get_location(),
6704 p->get_variadic_marker(),
6705 p->get_is_artificial()));
6706 parm.push_back(stripped);
6707 }
6708 type_base_sptr p = strip_typedef(ty->get_return_type());
6709 ABG_ASSERT(!!p == !!ty->get_return_type());
6710 t.reset(new function_type(p, parm,
6711 ty->get_size_in_bits(),
6712 ty->get_alignment_in_bits()));
6713 }
6714
6715 if (!t->get_translation_unit())
6716 t->set_translation_unit(type->get_translation_unit());
6717
6718 if (!(type->get_canonical_type() && canonicalize(t)))
6719 keep_type_alive(t);
6720
6721 return t->get_canonical_type() ? t->get_canonical_type() : t;
6722}
6723
6724/// Strip qualification from a qualified type, when it makes sense.
6725///
6726/// DWARF constructs "const reference". This is redundant because a
6727/// reference is always const. It also constructs the useless "const
6728/// void" type. The issue is these redundant types then leak into the
6729/// IR and make for bad diagnostics.
6730///
6731/// This function thus strips the const qualifier from the type in
6732/// that case. It might contain code to strip other cases like this
6733/// in the future.
6734///
6735/// @param t the type to strip const qualification from.
6736///
6737/// @return the stripped type or just return @p t.
6738decl_base_sptr
6739strip_useless_const_qualification(const qualified_type_def_sptr t)
6740{
6741 if (!t)
6742 return t;
6743
6744 decl_base_sptr result = t;
6745 type_base_sptr u = t->get_underlying_type();
6746 const environment& env = t->get_environment();
6747
6748 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6749 && (is_reference_type(u)))
6750 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6751 && env.is_void_type(u))
6752 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6753 // Let's strip the const qualifier because a reference is always
6754 // 'const' and a const void doesn't make sense. They will just
6755 // lead to spurious changes later down the pipeline, that we'll
6756 // have to deal with by doing painful and error-prone editing of
6757 // the diff IR. Dropping that useless and inconsistent artefact
6758 // right here seems to be a good way to go.
6759 result = is_decl(u);
6760
6761 return result;
6762}
6763
6764/// Merge redundant qualifiers from a tree of qualified types.
6765///
6766/// Suppose a tree of qualified types leads to:
6767///
6768/// const virtual const restrict const int;
6769///
6770/// Suppose the IR tree of qualified types ressembles (with C meaning
6771/// const, V meaning virtual and R meaning restrict):
6772///
6773/// [C|V]-->[C|R] -->[C] --> [int].
6774///
6775/// This function walks the IR and remove the redundant CV qualifiers
6776/// so the IR becomes:
6777///
6778/// [C|V] --> [R] --> [] -->[int].
6779///
6780/// Note that the empty qualified type (noted []) represents a
6781/// qualified type with no qualifier. It's rare, but it can exist.
6782/// I've put it here just for the sake of example.
6783///
6784/// The resulting IR thus represents the (merged) type:
6785///
6786/// const virtual restrict int.
6787///
6788/// This function is a sub-routine of the overload @ref
6789/// strip_useless_const_qualification which doesn't return any value.
6790///
6791/// @param t the qualified type to consider.
6792///
6793/// @param redundant_quals the (redundant) qualifiers to be removed
6794/// from the qualifiers of the underlying types of @p t.
6795///
6796/// @return the underlying type of @p t which might have had its
6797/// redundant qualifiers removed.
6798static qualified_type_def_sptr
6799strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
6800 qualified_type_def::CV redundant_quals)
6801{
6802 if (!t)
6803 return t;
6804
6805 // We must NOT edit canonicalized types.
6806 ABG_ASSERT(!t->get_canonical_type());
6807
6808 qualified_type_def_sptr underlying_qualified_type =
6809 is_qualified_type(t->get_underlying_type());
6810
6811 // Let's build 'currated qualifiers' that are the qualifiers of the
6812 // current type from which redundant qualifiers are removed.
6813 qualified_type_def::CV currated_quals = t->get_cv_quals();
6814
6815 // Remove the redundant qualifiers from these currated qualifiers
6816 currated_quals &= ~redundant_quals;
6817 t->set_cv_quals(currated_quals);
6818
6819 // The redundant qualifiers, moving forward, is now the union of the
6820 // previous set of redundant qualifiers and the currated qualifiers.
6821 redundant_quals |= currated_quals;
6822
6823 qualified_type_def_sptr result = t;
6824 if (underlying_qualified_type)
6825 // Now remove the redundant qualifiers from the qualified types
6826 // potentially carried by the underlying type.
6827 result =
6828 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
6829 redundant_quals);
6830
6831 return result;
6832}
6833
6834/// Merge redundant qualifiers from a tree of qualified types.
6835///
6836/// Suppose a tree of qualified types leads to:
6837///
6838/// const virtual const restrict const int;
6839///
6840/// Suppose the IR tree of qualified types ressembles (with C meaning
6841/// const, V meaning virtual and R meaning restrict):
6842///
6843/// [C|V]-->[C|R] -->[C] --> [int].
6844///
6845/// This function walks the IR and remove the redundant CV qualifiers
6846/// so the IR becomes:
6847///
6848/// [C|V] --> [R] --> [] -->[int].
6849///
6850/// Note that the empty qualified type (noted []) represents a
6851/// qualified type with no qualifier. It's rare, but it can exist.
6852/// I've put it here just for the sake of example.
6853///
6854/// The resulting IR thus represents the (merged) type:
6855///
6856/// const virtual restrict int.
6857///
6858/// @param t the qualified type to consider. The IR below the
6859/// argument to this parameter will be edited to remove redundant
6860/// qualifiers where applicable.
6861void
6862strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
6863{
6864 if (!t)
6865 return;
6866
6867 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
6868 strip_redundant_quals_from_underyling_types(t, redundant_quals);
6869}
6870
6871/// Return the leaf underlying type node of a @ref typedef_decl node.
6872///
6873/// If the underlying type of a @ref typedef_decl node is itself a
6874/// @ref typedef_decl node, then recursively look at the underlying
6875/// type nodes to get the first one that is not a a @ref typedef_decl
6876/// node. This is what a leaf underlying type node means.
6877///
6878/// Otherwise, if the underlying type node of @ref typedef_decl is
6879/// *NOT* a @ref typedef_decl node, then just return the underlying
6880/// type node.
6881///
6882/// And if the type node considered is not a @ref typedef_decl node,
6883/// then just return it.
6884///
6885/// @return the leaf underlying type node of a @p type.
6886type_base_sptr
6887peel_typedef_type(const type_base_sptr& type)
6888{
6889 typedef_decl_sptr t = is_typedef(type);
6890 if (!t)
6891 return type;
6892
6893 if (is_typedef(t->get_underlying_type()))
6894 return peel_typedef_type(t->get_underlying_type());
6895 return t->get_underlying_type();
6896}
6897
6898/// Return the leaf underlying type node of a @ref typedef_decl node.
6899///
6900/// If the underlying type of a @ref typedef_decl node is itself a
6901/// @ref typedef_decl node, then recursively look at the underlying
6902/// type nodes to get the first one that is not a a @ref typedef_decl
6903/// node. This is what a leaf underlying type node means.
6904///
6905/// Otherwise, if the underlying type node of @ref typedef_decl is
6906/// *NOT* a @ref typedef_decl node, then just return the underlying
6907/// type node.
6908///
6909/// And if the type node considered is not a @ref typedef_decl node,
6910/// then just return it.
6911///
6912/// @return the leaf underlying type node of a @p type.
6913const type_base*
6915{
6916 const typedef_decl* t = is_typedef(type);
6917 if (!t)
6918 return type;
6919
6920 return peel_typedef_type(t->get_underlying_type()).get();
6921}
6922
6923/// Return the leaf pointed-to type node of a @ref pointer_type_def
6924/// node.
6925///
6926/// If the pointed-to type of a @ref pointer_type_def node is itself a
6927/// @ref pointer_type_def node, then recursively look at the
6928/// pointed-to type nodes to get the first one that is not a a @ref
6929/// pointer_type_def node. This is what a leaf pointed-to type node
6930/// means.
6931///
6932/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
6933/// *NOT* a @ref pointer_type_def node, then just return the
6934/// pointed-to type node.
6935///
6936/// And if the type node considered is not a @ref pointer_type_def
6937/// node, then just return it.
6938///
6939/// @return the leaf pointed-to type node of a @p type.
6940type_base_sptr
6941peel_pointer_type(const type_base_sptr& type)
6942{
6944 if (!t)
6945 return type;
6946
6947 if (is_pointer_type(t->get_pointed_to_type()))
6948 return peel_pointer_type(t->get_pointed_to_type());
6949 return t->get_pointed_to_type();
6950}
6951
6952/// Return the leaf pointed-to type node of a @ref pointer_type_def
6953/// node.
6954///
6955/// If the pointed-to type of a @ref pointer_type_def node is itself a
6956/// @ref pointer_type_def node, then recursively look at the
6957/// pointed-to type nodes to get the first one that is not a a @ref
6958/// pointer_type_def node. This is what a leaf pointed-to type node
6959/// means.
6960///
6961/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
6962/// *NOT* a @ref pointer_type_def node, then just return the
6963/// pointed-to type node.
6964///
6965/// And if the type node considered is not a @ref pointer_type_def
6966/// node, then just return it.
6967///
6968/// @return the leaf pointed-to type node of a @p type.
6969const type_base*
6971{
6972 const pointer_type_def* t = is_pointer_type(type);
6973 if (!t)
6974 return type;
6975
6976 return peel_pointer_type(t->get_pointed_to_type()).get();
6977}
6978
6979/// Return the leaf pointed-to type node of a @ref reference_type_def
6980/// node.
6981///
6982/// If the pointed-to type of a @ref reference_type_def node is itself
6983/// a @ref reference_type_def node, then recursively look at the
6984/// pointed-to type nodes to get the first one that is not a a @ref
6985/// reference_type_def node. This is what a leaf pointed-to type node
6986/// means.
6987///
6988/// Otherwise, if the pointed-to type node of @ref reference_type_def
6989/// is *NOT* a @ref reference_type_def node, then just return the
6990/// pointed-to type node.
6991///
6992/// And if the type node considered is not a @ref reference_type_def
6993/// node, then just return it.
6994///
6995/// @return the leaf pointed-to type node of a @p type.
6996type_base_sptr
6997peel_reference_type(const type_base_sptr& type)
6998{
7000 if (!t)
7001 return type;
7002
7003 if (is_reference_type(t->get_pointed_to_type()))
7004 return peel_reference_type(t->get_pointed_to_type());
7005 return t->get_pointed_to_type();
7006}
7007
7008/// Return the leaf pointed-to type node of a @ref reference_type_def
7009/// node.
7010///
7011/// If the pointed-to type of a @ref reference_type_def node is itself
7012/// a @ref reference_type_def node, then recursively look at the
7013/// pointed-to type nodes to get the first one that is not a a @ref
7014/// reference_type_def node. This is what a leaf pointed-to type node
7015/// means.
7016///
7017/// Otherwise, if the pointed-to type node of @ref reference_type_def
7018/// is *NOT* a @ref reference_type_def node, then just return the
7019/// pointed-to type node.
7020///
7021/// And if the type node considered is not a @ref reference_type_def
7022/// node, then just return it.
7023///
7024/// @return the leaf pointed-to type node of a @p type.
7025const type_base*
7027{
7028 const reference_type_def* t = is_reference_type(type);
7029 if (!t)
7030 return type;
7031
7032 return peel_reference_type(t->get_pointed_to_type()).get();
7033}
7034
7035/// Return the leaf element type of an array.
7036///
7037/// If the element type is itself an array, then recursively return
7038/// the element type of that array itself.
7039///
7040/// @param type the array type to consider. If this is not an array
7041/// type, this type is returned by the function.
7042///
7043/// @return the leaf element type of the array @p type, or, if it's
7044/// not an array type, then just return @p.
7045const type_base_sptr
7046peel_array_type(const type_base_sptr& type)
7047{
7048 const array_type_def_sptr t = is_array_type(type);
7049 if (!t)
7050 return type;
7051
7052 return peel_array_type(t->get_element_type());
7053}
7054
7055/// Return the leaf element type of an array.
7056///
7057/// If the element type is itself an array, then recursively return
7058/// the element type of that array itself.
7059///
7060/// @param type the array type to consider. If this is not an array
7061/// type, this type is returned by the function.
7062///
7063/// @return the leaf element type of the array @p type, or, if it's
7064/// not an array type, then just return @p.
7065const type_base*
7067{
7068 const array_type_def* t = is_array_type(type);
7069 if (!t)
7070 return type;
7071
7072 return peel_array_type(t->get_element_type()).get();
7073}
7074
7075/// Return the leaf underlying type of a qualified type.
7076///
7077/// If the underlying type is itself a qualified type, then
7078/// recursively return the first underlying type of that qualified
7079/// type to return the first underlying type that is not a qualified type.
7080///
7081/// If the underlying type is NOT a qualified type, then just return
7082/// that underlying type.
7083///
7084/// @param type the qualified type to consider.
7085///
7086/// @return the leaf underlying type.
7087const type_base*
7089{
7090 const qualified_type_def* t = is_qualified_type(type);
7091 if (!t)
7092 return type;
7093
7094 return peel_qualified_type(t->get_underlying_type().get());
7095}
7096
7097/// Return the leaf underlying type of a qualified type.
7098///
7099/// If the underlying type is itself a qualified type, then
7100/// recursively return the first underlying type of that qualified
7101/// type to return the first underlying type that is not a qualified type.
7102///
7103/// If the underlying type is NOT a qualified type, then just return
7104/// that underlying type.
7105///
7106/// @param type the qualified type to consider.
7107///
7108/// @return the leaf underlying type.
7109const type_base_sptr
7110peel_qualified_type(const type_base_sptr& type)
7111{
7112 const qualified_type_def_sptr t = is_qualified_type(type);
7113 if (!t)
7114 return type;
7115
7116 return peel_qualified_type(t->get_underlying_type());
7117}
7118
7119/// Test if a given qualified type is const.
7120///
7121/// @pram t the qualified type to consider.
7122///
7123/// @return true iff @p t is a const qualified type.
7124bool
7125is_const_qualified_type(const qualified_type_def_sptr& t)
7126{
7127 if (!t)
7128 return false;
7129
7130 if (t->get_cv_quals() == qualified_type_def::CV_CONST)
7131 return true;
7132
7133 return false;
7134}
7135
7136/// Test if a given type is const-qualified.
7137///
7138/// @pram t the type to consider.
7139///
7140/// @return true iff @p t is a const qualified type.
7141bool
7142is_const_qualified_type(const type_base_sptr& t)
7143{
7144 qualified_type_def_sptr q = is_qualified_type(t);
7145 if (!q)
7146 return false;
7147 return is_const_qualified_type(q);
7148}
7149
7150/// If a qualified type is const, then return its underlying type.
7151///
7152/// @param q the qualified type to consider.
7153///
7154/// @return the underlying type of @p q if it's a const-qualified
7155/// type, otherwise, return @p q itself.
7156type_base_sptr
7157peel_const_qualified_type(const qualified_type_def_sptr& q)
7158{
7159 if (!q)
7160 return q;
7161
7163 return q->get_underlying_type();
7164
7165 return q;
7166}
7167
7168/// Return the leaf underlying type of a qualified or typedef type.
7169///
7170/// If the underlying type is itself a qualified or typedef type, then
7171/// recursively return the first underlying type of that qualified or
7172/// typedef type to return the first underlying type that is not a
7173/// qualified or typedef type.
7174///
7175/// If the underlying type is NOT a qualified nor a typedef type, then
7176/// just return that underlying type.
7177///
7178/// @param type the qualified or typedef type to consider.
7179///
7180/// @return the leaf underlying type.
7181type_base*
7183{
7184 while (is_typedef(type) || is_qualified_type(type))
7185 {
7186 if (const typedef_decl* t = is_typedef(type))
7187 type = peel_typedef_type(t);
7188
7189 if (const qualified_type_def* t = is_qualified_type(type))
7190 type = peel_qualified_type(t);
7191 }
7192
7193 return const_cast<type_base*>(type);
7194}
7195
7196/// Return the leaf underlying type of a qualified or typedef type.
7197///
7198/// If the underlying type is itself a qualified or typedef type, then
7199/// recursively return the first underlying type of that qualified or
7200/// typedef type to return the first underlying type that is not a
7201/// qualified or typedef type.
7202///
7203/// If the underlying type is NOT a qualified nor a typedef type, then
7204/// just return that underlying type.
7205///
7206/// @param type the qualified or typedef type to consider.
7207///
7208/// @return the leaf underlying type.
7209type_base_sptr
7210peel_qualified_or_typedef_type(const type_base_sptr &t)
7211{
7212 type_base_sptr type = t;
7213 while (is_typedef(type) || is_qualified_type(type))
7214 {
7215 if (typedef_decl_sptr t = is_typedef(type))
7216 type = peel_typedef_type(t);
7217
7218 if (qualified_type_def_sptr t = is_qualified_type(type))
7219 type = peel_qualified_type(t);
7220 }
7221
7222 return type;
7223}
7224
7225/// Return the leaf underlying or pointed-to type node of a @ref
7226/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7227/// or @ref array_type_def node.
7228///
7229/// @param type the type to peel.
7230///
7231/// @return the leaf underlying or pointed-to type node of @p type.
7232type_base_sptr
7234{
7235 type_base_sptr typ = type;
7236 while (is_typedef(typ)
7237 || is_pointer_type(typ)
7238 || is_reference_type(typ)
7239 || is_array_type(typ))
7240 {
7241 if (typedef_decl_sptr t = is_typedef(typ))
7242 typ = peel_typedef_type(t);
7243
7245 typ = peel_pointer_type(t);
7246
7248 typ = peel_reference_type(t);
7249
7250 if (const array_type_def_sptr t = is_array_type(typ))
7251 typ = peel_array_type(t);
7252 }
7253
7254 return typ;
7255}
7256
7257/// Return the leaf underlying or pointed-to type node of a @ref
7258/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7259/// node.
7260///
7261/// @param type the type to peel.
7262///
7263/// @return the leaf underlying or pointed-to type node of @p type.
7264type_base*
7266{
7267 while (is_typedef(type)
7268 || is_pointer_type(type)
7269 || is_reference_type(type)
7270 || is_array_type(type))
7271 {
7272 if (const typedef_decl* t = is_typedef(type))
7273 type = peel_typedef_type(t);
7274
7275 if (const pointer_type_def* t = is_pointer_type(type))
7276 type = peel_pointer_type(t);
7277
7278 if (const reference_type_def* t = is_reference_type(type))
7279 type = peel_reference_type(t);
7280
7281 if (const array_type_def* t = is_array_type(type))
7282 type = peel_array_type(t);
7283 }
7284
7285 return const_cast<type_base*>(type);
7286}
7287
7288/// Return the leaf underlying or pointed-to type node of a @ref
7289/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7290/// node.
7291///
7292/// @param type the type to peel.
7293///
7294/// @return the leaf underlying or pointed-to type node of @p type.
7295type_base*
7297 bool peel_qual_type)
7298{
7299 while (is_typedef(type)
7300 || is_pointer_type(type)
7301 || is_reference_type(type)
7302 || is_array_type(type)
7303 || (peel_qual_type && is_qualified_type(type)))
7304 {
7305 if (const typedef_decl* t = is_typedef(type))
7306 type = peel_typedef_type(t);
7307
7308 if (const pointer_type_def* t = is_pointer_type(type))
7309 type = peel_pointer_type(t);
7310
7311 if (const reference_type_def* t = is_reference_type(type))
7312 type = peel_reference_type(t);
7313
7314 if (const array_type_def* t = is_array_type(type))
7315 type = peel_array_type(t);
7316
7317 if (peel_qual_type)
7318 if (const qualified_type_def* t = is_qualified_type(type))
7319 type = peel_qualified_type(t);
7320 }
7321
7322 return const_cast<type_base*>(type);
7323}
7324
7325/// Return the leaf underlying or pointed-to type node of a, @ref
7326/// pointer_type_def, @ref reference_type_def or @ref
7327/// qualified_type_def type node.
7328///
7329/// @param type the type to peel.
7330///
7331/// @param peel_qualified_type if true, also peel qualified types.
7332///
7333/// @return the leaf underlying or pointed-to type node of @p type.
7334type_base*
7336 bool peel_qual_type)
7337{
7338 while (is_pointer_type(type)
7339 || is_reference_type(type)
7340 || is_array_type(type)
7341 || (peel_qual_type && is_qualified_type(type)))
7342 {
7343 if (const pointer_type_def* t = is_pointer_type(type))
7344 type = peel_pointer_type(t);
7345
7346 if (const reference_type_def* t = is_reference_type(type))
7347 type = peel_reference_type(t);
7348
7349 if (const array_type_def* t = is_array_type(type))
7350 type = peel_array_type(t);
7351
7352 if (peel_qual_type)
7353 if (const qualified_type_def* t = is_qualified_type(type))
7354 type = peel_qualified_type(t);
7355 }
7356
7357 return const_cast<type_base*>(type);
7358}
7359
7360/// Clone an array type.
7361///
7362/// Note that the element type of the new array is shared witht the
7363/// old one.
7364///
7365/// @param array the array type to clone.
7366///
7367/// @return a newly built array type. Note that it needs to be added
7368/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7369/// bound to the one of that scope. Otherwise, its lifetime is bound
7370/// to the lifetime of its containing shared pointer.
7373{
7374 vector<array_type_def::subrange_sptr> subranges;
7375
7376 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7377 array->get_subranges().begin();
7378 i != array->get_subranges().end();
7379 ++i)
7380 {
7382 (new array_type_def::subrange_type(array->get_environment(),
7383 (*i)->get_name(),
7384 (*i)->get_lower_bound(),
7385 (*i)->get_upper_bound(),
7386 (*i)->get_underlying_type(),
7387 (*i)->get_location(),
7388 (*i)->get_language()));
7389 subrange->is_non_finite((*i)->is_non_finite());
7390 if (scope_decl *scope = (*i)->get_scope())
7391 add_decl_to_scope(subrange, scope);
7392 subranges.push_back(subrange);
7393 }
7394
7395 array_type_def_sptr result
7396 (new array_type_def(array->get_element_type(),
7397 subranges, array->get_location()));
7398
7399 return result;
7400}
7401
7402/// Clone a typedef type.
7403///
7404/// Note that the underlying type of the newly constructed typedef is
7405/// shared with the old one.
7406///
7407/// @param t the typedef to clone.
7408///
7409/// @return the newly constructed typedef. Note that it needs to be
7410/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7411/// to be bound to the one of that scope. Otherwise, its lifetime is
7412/// bound to the lifetime of its containing shared pointer.
7415{
7416 if (!t)
7417 return t;
7418
7419 typedef_decl_sptr result
7420 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7421 t->get_location(), t->get_linkage_name(),
7422 t->get_visibility()));
7423 return result;
7424}
7425
7426/// Clone a qualifiend type.
7427///
7428/// Note that underlying type of the newly constructed qualified type
7429/// is shared with the old one.
7430///
7431/// @param t the qualified type to clone.
7432///
7433/// @return the newly constructed qualified type. Note that it needs
7434/// to be added to a scope (e.g, using add_decl_to_scope) for its
7435/// lifetime to be bound to the one of that scope. Otherwise, its
7436/// lifetime is bound to the lifetime of its containing shared
7437/// pointer.
7438qualified_type_def_sptr
7439clone_qualified_type(const qualified_type_def_sptr& t)
7440{
7441 if (!t)
7442 return t;
7443
7444 qualified_type_def_sptr result
7445 (new qualified_type_def(t->get_underlying_type(),
7446 t->get_cv_quals(), t->get_location()));
7447
7448 return result;
7449}
7450
7451/// Clone a typedef, an array or a qualified tree.
7452///
7453/// @param type the typedef, array or qualified tree to clone. any
7454/// order.
7455///
7456/// @return the cloned type, or NULL if @type was neither a typedef,
7457/// array nor a qualified type.
7458static type_base_sptr
7459clone_typedef_array_qualified_type(type_base_sptr type)
7460{
7461 if (!type)
7462 return type;
7463
7464 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7465 type_base_sptr result;
7466
7467 if (typedef_decl_sptr t = is_typedef(type))
7468 result = clone_typedef(is_typedef(t));
7469 else if (qualified_type_def_sptr t = is_qualified_type(type))
7470 result = clone_qualified_type(t);
7471 else if (array_type_def_sptr t = is_array_type(type))
7472 result = clone_array(t);
7473 else
7474 return type_base_sptr();
7475
7476 if (scope)
7477 add_decl_to_scope(is_decl(result), scope);
7478
7479 return result;
7480}
7481
7482/// Clone a type tree made of an array or a typedef of array.
7483///
7484/// Note that this can be a tree which root node is a typedef an which
7485/// sub-tree can be any arbitrary combination of typedef, qualified
7486/// type and arrays.
7487///
7488/// @param t the array or typedef of qualified array to consider.
7489///
7490/// @return a clone of @p t.
7491type_base_sptr
7492clone_array_tree(const type_base_sptr t)
7493{
7495
7496 scope_decl* scope = is_decl(t)->get_scope();
7497 type_base_sptr result = clone_typedef_array_qualified_type(t);
7498 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7499
7500 type_base_sptr subtree;
7501 if (typedef_decl_sptr type = is_typedef(result))
7502 {
7503 type_base_sptr s =
7504 clone_typedef_array_qualified_type(type->get_underlying_type());
7505 if (s)
7506 {
7507 subtree = s;
7508 type->set_underlying_type(subtree);
7509 }
7510 }
7511 else if (array_type_def_sptr type = is_array_type(result))
7512 {
7513 type_base_sptr s =
7514 clone_typedef_array_qualified_type(type->get_element_type());
7515 if (s)
7516 {
7517 subtree = s;
7518 type->set_element_type(subtree);
7519 }
7520 }
7521 add_decl_to_scope(is_decl(subtree), scope);
7522
7523 for (;;)
7524 {
7525 if (typedef_decl_sptr t = is_typedef(subtree))
7526 {
7527 type_base_sptr s =
7528 clone_typedef_array_qualified_type(t->get_underlying_type());
7529 if (s)
7530 {
7531 scope_decl* scope =
7532 is_decl(t->get_underlying_type())->get_scope();
7533 ABG_ASSERT(scope);
7534 add_decl_to_scope(is_decl(s), scope);
7535 t->set_underlying_type (s);
7536 subtree = s;
7537 }
7538 else
7539 break;
7540 }
7541 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7542 {
7543 type_base_sptr s =
7544 clone_typedef_array_qualified_type(t->get_underlying_type());
7545 if (s)
7546 {
7547 scope_decl* scope =
7548 is_decl(t->get_underlying_type())->get_scope();
7549 ABG_ASSERT(scope);
7550 add_decl_to_scope(is_decl(s), scope);
7551 t->set_underlying_type(s);
7552 subtree = s;
7553 }
7554 else
7555 break;
7556 }
7557 else if (array_type_def_sptr t = is_array_type(subtree))
7558 {
7559 type_base_sptr e = t->get_element_type();
7560 if (is_typedef(e) || is_qualified_type(e))
7561 {
7562 type_base_sptr s =
7563 clone_typedef_array_qualified_type(e);
7564 if (s)
7565 {
7566 scope_decl* scope = is_decl(e)->get_scope();
7567 ABG_ASSERT(scope);
7568 add_decl_to_scope(is_decl(s), scope);
7569 t->set_element_type(s);
7570 }
7571 else
7572 break;
7573 }
7574 break;
7575 }
7576 else
7577 break;
7578 }
7579 return result;
7580}
7581
7582/// Update the qualified name of a given sub-tree.
7583///
7584/// @param d the sub-tree for which to update the qualified name.
7585static void
7586update_qualified_name(decl_base * d)
7587{
7588 ::qualified_name_setter setter;
7589 d->traverse(setter);
7590}
7591
7592/// Update the qualified name of a given sub-tree.
7593///
7594/// @param d the sub-tree for which to update the qualified name.
7595static void
7596update_qualified_name(decl_base_sptr d)
7597{return update_qualified_name(d.get());}
7598
7599// <scope_decl stuff>
7600
7601/// Hash a type by returning the pointer value of its canonical type.
7602///
7603/// @param l the type to hash.
7604///
7605/// @return the the pointer value of the canonical type of @p l.
7606size_t
7607canonical_type_hash::operator()(const type_base_sptr& l) const
7608{return operator()(l.get());}
7609
7610/// Hash a (canonical) type by returning its pointer value
7611///
7612/// @param l the canonical type to hash.
7613///
7614/// @return the pointer value of the canonical type of @p l.
7615size_t
7617{return reinterpret_cast<size_t>(l);}
7618
7619struct scope_decl::priv
7620{
7621 declarations members_;
7622 declarations sorted_members_;
7623 type_base_sptrs_type member_types_;
7624 type_base_sptrs_type sorted_member_types_;
7625 scopes member_scopes_;
7626 canonical_type_sptr_set_type canonical_types_;
7627 type_base_sptrs_type sorted_canonical_types_;
7628 bool clear_sorted_member_types_cache_ = false;
7629}; // end struct scope_decl::priv
7630
7631/// Constructor of the @ref scope_decl type.
7632///
7633/// @param the environment to use for the new instance.
7634///
7635/// @param the name of the scope decl.
7636///
7637/// @param locus the source location where the scope_decl is defined.
7638///
7639/// @param vis the visibility of the declaration.
7640scope_decl::scope_decl(const environment& env,
7641 const string& name,
7642 const location& locus,
7643 visibility vis)
7644 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7645 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7646 priv_(new priv)
7647{}
7648
7649/// Constructor of the @ref scope_decl type.
7650///
7651/// @param the environment to use for the new instance.
7652///
7653/// @param l the source location where the scope_decl is defined.
7654///
7655/// @param vis the visibility of the declaration.
7656scope_decl::scope_decl(const environment& env, location& l)
7657 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7658 decl_base(env, "", l),
7659 priv_(new priv)
7660{}
7661
7662/// @eturn the set of canonical types of the the current scope.
7665{return priv_->canonical_types_;}
7666
7667/// @eturn the set of canonical types of the the current scope.
7670{return const_cast<scope_decl*>(this)->get_canonical_types();}
7671
7672/// Return a vector of sorted canonical types of the current scope.
7673///
7674/// The types are sorted "almost topologically". That means, they are
7675/// sorted using the lexicographic order of the string representing
7676/// the location their definition point. If a type doesn't have a
7677/// location, then its pretty representation is used.
7678///
7679/// @return a vector of sorted canonical types of the current scope.
7682{
7683 if (priv_->sorted_canonical_types_.empty())
7684 {
7685 for (canonical_type_sptr_set_type::const_iterator e =
7686 get_canonical_types().begin();
7687 e != get_canonical_types().end();
7688 ++e)
7689 priv_->sorted_canonical_types_.push_back(*e);
7690
7691 type_topo_comp comp;
7692 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7693 priv_->sorted_canonical_types_.end(),
7694 comp);
7695 }
7696 return priv_->sorted_canonical_types_;
7697}
7698
7699/// Getter for the member declarations carried by the current @ref
7700/// scope_decl.
7701///
7702/// @return the member declarations carried by the current @ref
7703/// scope_decl.
7706{return priv_->members_;}
7707
7708/// Getter for the member declarations carried by the current @ref
7709/// scope_decl.
7710///
7711/// @return the member declarations carried by the current @ref
7712/// scope_decl.
7715{return priv_->members_;}
7716
7717/// Getter for the sorted member declarations carried by the current
7718/// @ref scope_decl.
7719///
7720/// @return the sorted member declarations carried by the current @ref
7721/// scope_decl. The declarations are sorted topologically.
7724{
7725 decl_topo_comp comp;
7726 if (priv_->sorted_members_.empty())
7727 {
7728 for (declarations::const_iterator i = get_member_decls().begin();
7729 i != get_member_decls().end();
7730 ++i)
7731 priv_->sorted_members_.push_back(*i);
7732
7733 std::stable_sort(priv_->sorted_members_.begin(),
7734 priv_->sorted_members_.end(),
7735 comp);
7736 }
7737 return priv_->sorted_members_;
7738}
7739
7740/// Getter for the number of anonymous classes contained in this
7741/// scope.
7742///
7743/// @return the number of anonymous classes contained in this scope.
7744size_t
7746{
7747 int result = 0;
7748 for (declarations::const_iterator it = get_member_decls().begin();
7749 it != get_member_decls().end();
7750 ++it)
7751 if (class_decl_sptr t = is_class_type(*it))
7752 if (t->get_is_anonymous())
7753 ++result;
7754
7755 return result;
7756}
7757
7758/// Getter for the number of anonymous unions contained in this
7759/// scope.
7760///
7761/// @return the number of anonymous unions contained in this scope.
7762size_t
7764{
7765 int result = 0;
7766 for (declarations::const_iterator it = get_member_decls().begin();
7767 it != get_member_decls().end();
7768 ++it)
7769 if (union_decl_sptr t = is_union_type(*it))
7770 if (t->get_is_anonymous())
7771 ++result;
7772
7773 return result;
7774}
7775
7776/// Getter for the number of anonymous enums contained in this
7777/// scope.
7778///
7779/// @return the number of anonymous enums contained in this scope.
7780size_t
7782{
7783 int result = 0;
7784 for (declarations::const_iterator it = get_member_decls().begin();
7785 it != get_member_decls().end();
7786 ++it)
7787 if (enum_type_decl_sptr t = is_enum_type(*it))
7788 if (t->get_is_anonymous())
7789 ++result;
7790
7791 return result;
7792}
7793
7794/// Getter for the scopes carried by the current scope.
7795///
7796/// @return the scopes carried by the current scope.
7799{return priv_->member_scopes_;}
7800
7801/// Getter for the scopes carried by the current scope.
7802///
7803/// @return the scopes carried by the current scope.
7804const scope_decl::scopes&
7806{return priv_->member_scopes_;}
7807
7808/// Test if the current scope is empty.
7809///
7810/// @return true iff the current scope is empty.
7811bool
7813{
7814 return (get_member_decls().empty()
7815 && get_canonical_types().empty());
7816}
7817
7818/// Set the translation unit of a decl
7819///
7820/// It also perform some IR integrity checks.
7821///
7822/// This is a sub-routine of scope_decl::{insert,add}_member_decl.
7823///
7824/// @param decl the decl to set the translation unit for.
7825///
7826/// @param tu the translation unit to set.
7827static void
7828maybe_set_translation_unit(const decl_base_sptr& decl,
7829 translation_unit* tu)
7830{
7831 ABG_ASSERT(tu);
7832
7833 if (translation_unit* existing_tu = decl->get_translation_unit())
7834 // The decl already belongs to a translation unit.
7835 // Either:
7836 //
7837 // 1/ it's a unique type, in which case we should not add it to
7838 // any translation unique since unique types are "logically"
7839 // supposed to belong to no translation unit in particular, as
7840 // they are unique.
7841 //
7842 // 2/ or the decl was already added to this translation unit.
7843 ABG_ASSERT(tu == existing_tu || is_unique_type(is_type(decl)));
7844 else
7845 decl->set_translation_unit(tu);
7846}
7847
7848/// Add a member decl to this scope. Note that user code should not
7849/// use this, but rather use add_decl_to_scope.
7850///
7851/// Note that this function updates the qualified name of the member
7852/// decl that is added. It also sets the scope of the member. Thus,
7853/// it ABG_ASSERTs that member should not have its scope set, prior to
7854/// calling this function.
7855///
7856/// @param member the new member decl to add to this scope.
7857decl_base_sptr
7858scope_decl::add_member_decl(const decl_base_sptr& member)
7859{
7860 ABG_ASSERT(!has_scope(member));
7861
7862 member->set_scope(this);
7863 priv_->members_.push_back(member);
7864 if (is_type(member))
7865 {
7866 priv_->member_types_.push_back(is_type(member));
7867 priv_->clear_sorted_member_types_cache_ = true;
7868 }
7869
7870 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
7871 priv_->member_scopes_.push_back(m);
7872
7873 update_qualified_name(member);
7874
7876 maybe_set_translation_unit(member, tu);
7877
7879
7880 return member;
7881}
7882
7883/// Get the member types of this @ref scope_decl.
7884///
7885/// @return a vector of the member types of this ref class_or_union.
7888{return priv_->member_types_;}
7889
7890/// Find a member type of a given name, inside the current @ref
7891/// scope_decl.
7892///
7893/// @param name the name of the member type to look for.
7894///
7895/// @return a pointer to the @ref type_base that represents the member
7896/// type of name @p name, for the current scope.
7897type_base_sptr
7898scope_decl::find_member_type(const string& name) const
7899{
7900 for (auto t : get_member_types())
7901 if (get_type_name(t, /*qualified*/false) == name)
7902 return t;
7903 return type_base_sptr();
7904}
7905
7906/// Insert a member type.
7907///
7908/// @param t the type to insert in the @ref scope_decl type.
7909///
7910/// @param an iterator right before which @p t has to be inserted.
7911void
7913 declarations::iterator before)
7914{
7915 decl_base_sptr d = get_type_declaration(t);
7916 ABG_ASSERT(d);
7917 ABG_ASSERT(!has_scope(d));
7918
7919 priv_->member_types_.push_back(t);
7920 priv_->clear_sorted_member_types_cache_= true;
7921 insert_member_decl(d, before);
7922}
7923
7924/// Add a member type to the current instance of class_or_union.
7925///
7926/// @param t the member type to add. It must not have been added to a
7927/// scope, otherwise this will violate an ABG_ASSERTion.
7928void
7931
7932/// Add a member type to the current instance of class_or_union.
7933///
7934/// @param t the type to be added as a member type to the current
7935/// instance of class_or_union. An instance of class_or_union::member_type
7936/// will be created out of @p t and and added to the the class.
7937///
7938/// @param a the access specifier for the member type to be created.
7939type_base_sptr
7941{
7942 decl_base_sptr d = get_type_declaration(t);
7943 ABG_ASSERT(d);
7945 add_member_type(t);
7947 return t;
7948}
7949
7950/// Remove a member type from the current @ref class_or_union scope.
7951///
7952/// @param t the type to remove.
7953void
7955{
7956 for (auto i = priv_->member_types_.begin();
7957 i != priv_->member_types_.end();
7958 ++i)
7959 {
7960 if (*((*i)) == *t)
7961 {
7962 priv_->member_types_.erase(i);
7963 return;
7964 }
7965 }
7966}
7967
7968/// Get the sorted member types of this @ref scope_decl
7969///
7970/// @return a vector of the sorted member types of this ref
7971/// class_or_union.
7974{
7975 if (priv_->clear_sorted_member_types_cache_)
7976 {
7977 priv_->sorted_member_types_.clear();
7978 priv_->clear_sorted_member_types_cache_ = false;
7979 }
7980
7981 if (priv_->sorted_member_types_.empty())
7982 {
7983 unordered_set<type_base_sptr> canonical_pointer_types;
7984 for (auto t : get_member_types())
7985 {
7987 priv_->sorted_member_types_.push_back(t);
7988 else if (auto c = t->get_canonical_type())
7989 canonical_pointer_types.insert(c);
7990 else
7991 canonical_pointer_types.insert(t);
7992 }
7993
7994 for (auto t : canonical_pointer_types)
7995 priv_->sorted_member_types_.push_back(t);
7996
7997 type_topo_comp comp;
7998 std::stable_sort(priv_->sorted_member_types_.begin(),
7999 priv_->sorted_member_types_.end(),
8000 comp);
8001 }
8002
8003 const ir::environment& env = get_environment();
8005 priv_->clear_sorted_member_types_cache_ = true;
8006
8007 return priv_->sorted_member_types_;
8008}
8009
8010/// Insert a member decl to this scope, right before an element
8011/// pointed to by a given iterator. Note that user code should not
8012/// use this, but rather use insert_decl_into_scope.
8013///
8014/// Note that this function updates the qualified name of the inserted
8015/// member.
8016///
8017/// @param member the new member decl to add to this scope.
8018///
8019/// @param before an interator pointing to the element before which
8020/// the new member should be inserted.
8021decl_base_sptr
8023 declarations::iterator before)
8024{
8025 ABG_ASSERT(!member->get_scope());
8026
8027 member->set_scope(this);
8028 priv_->members_.insert(before, member);
8029
8030 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8031 priv_-> member_scopes_.push_back(m);
8032
8033 update_qualified_name(member);
8034
8036 maybe_set_translation_unit(member, tu);
8037
8039
8040 return member;
8041}
8042
8043/// Remove a declaration from the current scope.
8044///
8045/// @param member the declaration to remove from the scope.
8046void
8048{
8049 for (declarations::iterator i = priv_->members_.begin();
8050 i != priv_->members_.end();
8051 ++i)
8052 {
8053 if (**i == *member)
8054 {
8055 priv_->members_.erase(i);
8056 // Do not access i after this point as it's invalided by the
8057 // erase call.
8058 break;
8059 }
8060 }
8061
8062 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8063 if (scope)
8064 {
8065 for (scopes::iterator i = priv_->member_scopes_.begin();
8066 i != priv_->member_scopes_.end();
8067 ++i)
8068 {
8069 if (**i == *member)
8070 {
8071 priv_->member_scopes_.erase(i);
8072 break;
8073 }
8074 }
8075 }
8076
8077 member->set_scope(nullptr);
8078 member->set_translation_unit(nullptr);
8079}
8080
8081/// Compares two instances of @ref scope_decl.
8082///
8083/// If the two intances are different, set a bitfield to give some
8084/// insight about the kind of differences there are.
8085///
8086/// @param l the first artifact of the comparison.
8087///
8088/// @param r the second artifact of the comparison.
8089///
8090/// @param k a pointer to a bitfield that gives information about the
8091/// kind of changes there are between @p l and @p r. This one is set
8092/// iff @p k is non-null and the function returns false.
8093///
8094/// Please note that setting k to a non-null value does have a
8095/// negative performance impact because even if @p l and @p r are not
8096/// equal, the function keeps up the comparison in order to determine
8097/// the different kinds of ways in which they are different.
8098///
8099/// @return true if @p l equals @p r, false otherwise.
8100bool
8102{
8103 bool result = true;
8104
8105 if (!l.decl_base::operator==(r))
8106 {
8107 result = false;
8108 if (k)
8110 else
8112 }
8113
8114 scope_decl::declarations::const_iterator i, j;
8115 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8116 i != l.get_member_decls().end() && j != r.get_member_decls().end();
8117 ++i, ++j)
8118 {
8119 if (**i != **j)
8120 {
8121 result = false;
8122 if (k)
8123 {
8124 *k |= SUBTYPE_CHANGE_KIND;
8125 break;
8126 }
8127 else
8129 }
8130 }
8131
8132 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8133 {
8134 result = false;
8135 if (k)
8137 else
8139 }
8140
8141 ABG_RETURN(result);
8142}
8143
8144/// Return true iff both scopes have the same names and have the same
8145/// member decls.
8146///
8147/// This function doesn't check for equality of the scopes of its
8148/// arguments.
8149bool
8151{
8152 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8153 if (!other)
8154 return false;
8155
8156 return equals(*this, *other, 0);
8157}
8158
8159/// Equality operator for @ref scope_decl_sptr.
8160///
8161/// @param l the left hand side operand of the equality operator.
8162///
8163/// @pram r the right hand side operand of the equalify operator.
8164///
8165/// @return true iff @p l equals @p r.
8166bool
8168{
8169 if (!!l != !!r)
8170 return false;
8171 if (l.get() == r.get())
8172 return true;
8173 return *l == *r;
8174}
8175
8176/// Inequality operator for @ref scope_decl_sptr.
8177///
8178/// @param l the left hand side operand of the equality operator.
8179///
8180/// @pram r the right hand side operand of the equalify operator.
8181///
8182/// @return true iff @p l equals @p r.
8183bool
8185{return !operator==(l, r);}
8186
8187/// Find a member of the current scope and return an iterator on it.
8188///
8189/// @param decl the scope member to find.
8190///
8191/// @param i the iterator to set to the member @p decl. This is set
8192/// iff the function returns true.
8193///
8194/// @return true if the member decl was found, false otherwise.
8195bool
8197 declarations::iterator& i)
8198{
8199 if (!decl)
8200 return false;
8201
8202 if (get_member_decls().empty())
8203 {
8204 i = get_member_decls().end();
8205 return false;
8206 }
8207
8208 for (declarations::iterator it = get_member_decls().begin();
8209 it != get_member_decls().end();
8210 ++it)
8211 {
8212 if ((*it).get() == decl)
8213 {
8214 i = it;
8215 return true;
8216 }
8217 }
8218
8219 return false;
8220}
8221
8222/// Find a member of the current scope and return an iterator on it.
8223///
8224/// @param decl the scope member to find.
8225///
8226/// @param i the iterator to set to the member @p decl. This is set
8227/// iff the function returns true.
8228///
8229/// @return true if the member decl was found, false otherwise.
8230bool
8232 declarations::iterator& i)
8233{return find_iterator_for_member(decl.get(), i);}
8234
8235/// This implements the ir_traversable_base::traverse pure virtual
8236/// function.
8237///
8238/// @param v the visitor used on the current instance of scope_decl
8239/// and on its member nodes.
8240///
8241/// @return true if the traversal of the tree should continue, false
8242/// otherwise.
8243bool
8245{
8246 if (visiting())
8247 return true;
8248
8249 if (v.visit_begin(this))
8250 {
8251 visiting(true);
8252 for (scope_decl::declarations::const_iterator i =
8253 get_member_decls().begin();
8254 i != get_member_decls ().end();
8255 ++i)
8256 if (!(*i)->traverse(v))
8257 break;
8258 visiting(false);
8259 }
8260 return v.visit_end(this);
8261}
8262
8263scope_decl::~scope_decl()
8264{}
8265
8266/// Appends a declaration to a given scope, if the declaration
8267/// doesn't already belong to one and if the declaration is not for a
8268/// type that is supposed to be unique.
8269///
8270/// @param decl the declaration to add to the scope
8271///
8272/// @param scope the scope to append the declaration to
8273decl_base_sptr
8274add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8275{
8276 if (!scope)
8277 return decl;
8278
8279 if (scope && decl && !decl->get_scope())
8280 decl = scope->add_member_decl(decl);
8281
8282 return decl;
8283}
8284
8285/// Appends a declaration to a given scope, if the declaration doesn't
8286/// already belong to a scope.
8287///
8288/// @param decl the declaration to add append to the scope
8289///
8290/// @param scope the scope to append the decl to
8291decl_base_sptr
8292add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8293{return add_decl_to_scope(decl, scope.get());}
8294
8295/// Remove a given decl from its scope
8296///
8297/// @param decl the decl to remove from its scope.
8298void
8299remove_decl_from_scope(decl_base_sptr decl)
8300{
8301 if (!decl)
8302 return;
8303
8304 scope_decl* scope = decl->get_scope();
8305 scope->remove_member_decl(decl);
8306}
8307
8308/// Inserts a declaration into a given scope, before a given IR child
8309/// node of the scope.
8310///
8311/// @param decl the declaration to insert into the scope.
8312///
8313/// @param before an iterator pointing to the child IR node before
8314/// which to insert the declaration.
8315///
8316/// @param scope the scope into which to insert the declaration.
8317decl_base_sptr
8318insert_decl_into_scope(decl_base_sptr decl,
8319 scope_decl::declarations::iterator before,
8320 scope_decl* scope)
8321{
8322 if (scope && decl && !decl->get_scope())
8323 {
8324 decl_base_sptr d = scope->insert_member_decl(decl, before);
8325 decl = d;
8326 }
8327 return decl;
8328}
8329
8330/// Inserts a declaration into a given scope, before a given IR child
8331/// node of the scope.
8332///
8333/// @param decl the declaration to insert into the scope.
8334///
8335/// @param before an iterator pointing to the child IR node before
8336/// which to insert the declaration.
8337///
8338/// @param scope the scope into which to insert the declaration.
8339decl_base_sptr
8340insert_decl_into_scope(decl_base_sptr decl,
8341 scope_decl::declarations::iterator before,
8342 scope_decl_sptr scope)
8343{return insert_decl_into_scope(decl, before, scope.get());}
8344
8345/// Constructor of the @ref global_scope type.
8346///
8347/// @param tu the translation unit the scope belongs to.
8348global_scope::global_scope(translation_unit *tu)
8349 : type_or_decl_base(tu->get_environment(),
8350 GLOBAL_SCOPE_DECL
8351 | ABSTRACT_DECL_BASE
8352 | ABSTRACT_SCOPE_DECL),
8353 decl_base(tu->get_environment(), "", location()),
8354 scope_decl(tu->get_environment(), "", location()),
8355 translation_unit_(tu)
8356{
8357 runtime_type_instance(this);
8358}
8359
8360/// return the global scope as seen by a given declaration.
8361///
8362/// @param decl the declaration to consider.
8363///
8364/// @return the global scope of the decl, or a null pointer if the
8365/// decl is not yet added to a translation_unit.
8366const global_scope*
8368{
8369 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8370 return s;
8371
8372 scope_decl* scope = decl.get_scope();
8373 while (scope && !dynamic_cast<global_scope*>(scope))
8374 scope = scope->get_scope();
8375
8376 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8377}
8378
8379/// return the global scope as seen by a given declaration.
8380///
8381/// @param decl the declaration to consider.
8382///
8383/// @return the global scope of the decl, or a null pointer if the
8384/// decl is not yet added to a translation_unit.
8385const global_scope*
8387{return get_global_scope(*decl);}
8388
8389/// Return the global scope as seen by a given declaration.
8390///
8391/// @param decl the declaration to consider.
8392///
8393/// @return the global scope of the decl, or a null pointer if the
8394/// decl is not yet added to a translation_unit.
8395const global_scope*
8396get_global_scope(const shared_ptr<decl_base> decl)
8397{return get_global_scope(decl.get());}
8398
8399/// Return the a scope S containing a given declaration and that is
8400/// right under a given scope P.
8401///
8402/// Note that @p scope must come before @p decl in topological
8403/// order.
8404///
8405/// @param decl the decl for which to find a scope.
8406///
8407/// @param scope the scope under which the resulting scope must be.
8408///
8409/// @return the resulting scope.
8410const scope_decl*
8412 const scope_decl* scope)
8413{
8414 if (!decl)
8415 return 0;
8416
8417 if (scope == 0)
8418 return get_global_scope(decl);
8419
8420 // Handle the case where decl is a scope itself.
8421 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8422 if (!s)
8423 s = decl->get_scope();
8424
8425 if (is_global_scope(s))
8426 return scope;
8427
8428 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8429 // same. The caller needs to be prepared to deal with this case.
8430 if (s == scope)
8431 return s;
8432
8433 while (s && !is_global_scope(s) && s->get_scope() != scope)
8434 s = s->get_scope();
8435
8436 if (!s || is_global_scope(s))
8437 // SCOPE must come before decl in topological order, but I don't
8438 // know how to ensure that ...
8439 return scope;
8440 ABG_ASSERT(s);
8441
8442 return s;
8443}
8444
8445/// Return the a scope S containing a given declaration and that is
8446/// right under a given scope P.
8447///
8448/// @param decl the decl for which to find a scope.
8449///
8450/// @param scope the scope under which the resulting scope must be.
8451///
8452/// @return the resulting scope.
8453const scope_decl*
8454get_top_most_scope_under(const decl_base_sptr decl,
8455 const scope_decl* scope)
8456{return get_top_most_scope_under(decl.get(), scope);}
8457
8458/// Return the a scope S containing a given declaration and that is
8459/// right under a given scope P.
8460///
8461/// @param decl the decl for which to find a scope.
8462///
8463/// @param scope the scope under which the resulting scope must be.
8464///
8465/// @return the resulting scope.
8466const scope_decl*
8467get_top_most_scope_under(const decl_base_sptr decl,
8468 const scope_decl_sptr scope)
8469{return get_top_most_scope_under(decl, scope.get());}
8470
8471// </scope_decl stuff>
8472
8473
8474/// Get the string representation of a CV qualifier bitmap.
8475///
8476/// @param cv_quals the bitmap of CV qualifiers to consider.
8477///
8478/// @return the string representation.
8479string
8481{
8482 string repr;
8483 if (cv_quals & qualified_type_def::CV_RESTRICT)
8484 repr = "restrict";
8485 if (cv_quals & qualified_type_def::CV_CONST)
8486 {
8487 if (!repr.empty())
8488 repr += ' ';
8489 repr += "const";
8490 }
8491 if (cv_quals & qualified_type_def::CV_VOLATILE)
8492 {
8493 if (!repr.empty())
8494 repr += ' ';
8495 repr += "volatile";
8496 }
8497 return repr;
8498}
8499
8500/// Build and return a copy of the name of an ABI artifact that is
8501/// either a type or a decl.
8502///
8503/// @param tod the ABI artifact to get the name for.
8504///
8505/// @param qualified if yes, return the qualified name of @p tod;
8506/// otherwise, return the non-qualified name;
8507///
8508/// @return the name of @p tod.
8509string
8510get_name(const type_or_decl_base *tod, bool qualified)
8511{
8512 string result;
8513
8514 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8515
8516 if (type_base* t = dynamic_cast<type_base*>(a))
8517 result = get_type_name(t, qualified);
8518 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8519 {
8520 if (qualified)
8521 result = d->get_qualified_name();
8522 else
8523 result = d->get_name();
8524 }
8525 else
8526 // We should never reach this point.
8527 abort();
8528
8529 return result;
8530}
8531
8532/// Build and return a copy of the name of an ABI artifact that is
8533/// either a type of a decl.
8534///
8535/// @param tod the ABI artifact to get the name for.
8536///
8537/// @param qualified if yes, return the qualified name of @p tod;
8538/// otherwise, return the non-qualified name;
8539///
8540/// @return the name of @p tod.
8541string
8542get_name(const type_or_decl_base_sptr& tod, bool qualified)
8543{return get_name(tod.get(), qualified);}
8544
8545/// Build and return a qualified name from a name and its scope.
8546///
8547/// The name is supposed to be for an entity that is part of the
8548/// scope.
8549///
8550/// @param the scope to consider.
8551///
8552/// @param name of the name to consider.
8553///
8554/// @return a copy of the string that represents the qualified name.
8555string
8556build_qualified_name(const scope_decl* scope, const string& name)
8557{
8558 if (name.empty())
8559 return "";
8560
8561 string qualified_name;
8562 if (scope)
8563 qualified_name = scope->get_qualified_name();
8564
8565 if (qualified_name.empty())
8566 qualified_name = name;
8567 else
8568 qualified_name = qualified_name + "::" + name;
8569
8570 return qualified_name;
8571}
8572
8573/// Build and return the qualified name of a type in its scope.
8574///
8575/// @param scope the scope of the type to consider.
8576///
8577/// @param type the type to consider.
8578string
8579build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8580{return build_qualified_name(scope, get_name((type)));}
8581
8582// </scope_decl stuff>
8583
8584/// Get the location of the declaration of a given type.
8585///
8586/// @param type the type to consider.
8587///
8588/// @return the location of the declaration of type @p type.
8590get_location(const type_base_sptr& type)
8591{
8592 if (decl_base_sptr decl = get_type_declaration(type))
8593 return get_location(decl);
8594 return location();
8595}
8596
8597/// Get the location of a given declaration.
8598///
8599/// @param decl the declaration to consider.
8600///
8601/// @return the location of the declaration @p decl.
8603get_location(const decl_base_sptr& decl)
8604{
8605 location loc = decl->get_location();
8606 if (!loc)
8607 {
8608 if (class_or_union_sptr c = is_class_or_union_type(decl))
8609 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8610 {
8611 c = is_class_or_union_type(c->get_definition_of_declaration());
8612 loc = c->get_location();
8613 }
8614 }
8615 return loc;
8616}
8617
8618/// Get the scope of a given type.
8619///
8620/// @param t the type to consider.
8621///
8622/// @return the scope of type @p t or 0 if the type has no scope yet.
8625{
8626 if (!t)
8627 return 0;
8628
8630 if (d)
8631 return d->get_scope();
8632 return 0;
8633}
8634
8635/// Get the scope of a given type.
8636///
8637/// @param t the type to consider.
8638///
8639/// @return the scope of type @p t or 0 if the type has no scope yet.
8641get_type_scope(const type_base_sptr& t)
8642{return get_type_scope(t.get());}
8643
8644/// Get the name of a given type and return a copy of it.
8645///
8646/// @param t the type to consider.
8647///
8648/// @param qualified if true then return the qualified name of the
8649/// type.
8650///
8651/// @param internal set to true if the call is intended for an
8652/// internal use (for technical use inside the library itself), false
8653/// otherwise. If you don't know what this is for, then set it to
8654/// false.
8655///
8656/// @return a copy of the type name if the type has a name, or the
8657/// empty string if it does not.
8659get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8660{return get_type_name(t.get(), qualified, internal);}
8661
8662/// Return true iff a decl is for a type type that has a generic
8663/// anonymous internal type name.
8664///
8665/// @param d the decl to considier.
8666///
8667/// @return true iff @p d is for a type type that has a generic
8668/// anonymous internal type name.
8669static bool
8670has_generic_anonymous_internal_type_name(const decl_base *d)
8671{
8672 return (is_class_or_union_type(d)
8673 || is_enum_type(d)
8674 || is_subrange_type(d));
8675}
8676
8677/// Return the generic internal name of an anonymous type.
8678///
8679/// For internal purposes, we want to define a generic name for all
8680/// anonymous types of a certain kind. For instance, all anonymous
8681/// structs will be have a generic name of "__anonymous_struct__", all
8682/// anonymous unions will have a generic name of
8683/// "__anonymous_union__", etc.
8684///
8685/// That generic name can be used as a hash to put all anonymous types
8686/// of a certain kind in the same hash table bucket, for instance.
8687static interned_string
8688get_generic_anonymous_internal_type_name(const decl_base *d)
8689{
8690 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8691
8692 const environment&env = d->get_environment();
8693
8694 interned_string result;
8695 if (is_class_type(d))
8696 result =
8698 else if (is_union_type(d))
8699 result =
8701 else if (is_enum_type(d))
8702 result =
8704 else if (is_subrange_type(d))
8705 result =
8707 else
8709
8710 return result;
8711}
8712
8713/// Get the internal name for a given real type.
8714///
8715/// All real types that have the modifiers 'short, long or long
8716/// long' have the same internal name. This is so that they can all
8717/// have the same canonical type if they are of the same size.
8718/// Otherwise, 'long int' and 'long long int' would have different
8719/// canonical types even though they are equivalent from an ABI point
8720/// of view.
8721///
8722/// @param t the real type to consider
8723///
8724/// @return the internal name for @p t if it's an integral type, or
8725/// the empty string if @p t is not a real type.
8726static string
8727get_internal_real_type_name(const type_base* t)
8728{
8729 string name;
8730 type_decl *type = is_real_type(t);
8731
8732 if (!type)
8733 return name;
8734
8735 real_type int_type;
8736 if (parse_real_type(type->get_name(), int_type))
8737 name = int_type.to_string(/*internal=*/true);
8738
8739 return name;
8740}
8741
8742/// Get the name of a given type and return a copy of it.
8743///
8744/// @param t the type to consider.
8745///
8746/// @param qualified if true then return the qualified name of the
8747/// type.
8748///
8749/// @param internal set to true if the call is intended for an
8750/// internal use (for technical use inside the library itself), false
8751/// otherwise. If you don't know what this is for, then set it to
8752/// false.
8753///
8754/// @return a copy of the type name if the type has a name, or the
8755/// empty string if it does not.
8756interned_string
8757get_type_name(const type_base* t, bool qualified, bool internal)
8758{
8759 const decl_base* d = dynamic_cast<const decl_base*>(t);
8760 if (!d)
8761 {
8762 const function_type* fn_type = is_function_type(t);
8763 ABG_ASSERT(fn_type);
8764 return fn_type->get_cached_name(internal);
8765 }
8766
8767 const environment&env = d->get_environment();
8768
8769 // All anonymous types of a given kind get to have the same internal
8770 // name for internal purpose. This to allow them to be compared
8771 // among themselves during type canonicalization.
8772 if (internal)
8773 {
8774 if (d->get_is_anonymous() && !is_type_decl(t))
8775 {
8776 // Note that anonymous type_decl that are used for
8777 // enumerators are not handled here because they don't have
8778 // generic internal type names.
8779 string r;
8780 r += get_generic_anonymous_internal_type_name(d);
8781 return t->get_environment().intern(r);
8782 }
8783
8784 if (is_typedef(t))
8785 return d->get_name();
8786
8787 if (qualified)
8788 return d->get_qualified_name(internal);
8789
8790 return env.intern(get_internal_real_type_name(t));
8791 }
8792
8793 if (d->get_is_anonymous())
8794 {
8796 return env.intern
8798 /*one_line=*/true,
8799 internal, qualified));
8800 }
8801
8802 if (qualified)
8803 return d->get_qualified_name(internal);
8804 return d->get_name();
8805}
8806
8807/// Get the name of a given type and return a copy of it.
8808///
8809/// @param t the type to consider.
8810///
8811/// @param qualified if true then return the qualified name of the
8812/// type.
8813///
8814/// @param internal set to true if the call is intended for an
8815/// internal use (for technical use inside the library itself), false
8816/// otherwise. If you don't know what this is for, then set it to
8817/// false.
8818///
8819/// @return a copy of the type name if the type has a name, or the
8820/// empty string if it does not.
8822get_type_name(const type_base& t, bool qualified, bool internal)
8823{return get_type_name(&t, qualified, internal);}
8824
8825/// Get the name of the pointer to a given type.
8826///
8827/// @param pointed_to_type the pointed-to-type to consider.
8828///
8829/// @param qualified this is true if the resulting name should be of a
8830/// pointer to a *fully-qualified* pointed-to-type.
8831///
8832/// @param internal true if the name is for libabigail-internal
8833/// purposes.
8834///
8835/// @return the name (string representation) of the pointer.
8838 bool qualified, bool internal)
8839{
8840 const environment& env = pointed_to_type.get_environment();
8841 string tn = get_type_name(pointed_to_type, qualified, internal);
8842 tn = tn + "*";
8843
8844 return env.intern(tn);
8845}
8846
8847/// Get the name of the reference to a given type.
8848///
8849/// @param pointed_to_type the pointed-to-type to consider.
8850///
8851/// @param qualified this is true if the resulting name should be of a
8852/// reference to a *fully-qualified* pointed-to-type.
8853///
8854/// @param internal true if the name is for libabigail-internal
8855/// purposes.
8856///
8857/// @return the name (string representation) of the reference.
8860 bool lvalue_reference,
8861 bool qualified, bool internal)
8862{
8863 const environment& env = pointed_to_type.get_environment();
8864
8865 string name = get_type_name(pointed_to_type, qualified, internal);
8866 if (lvalue_reference)
8867 name = name + "&";
8868 else
8869 name = name + "&&";
8870
8871 return env.intern(name);
8872}
8873
8874/// Get the name of a qualified type, given the underlying type and
8875/// its qualifiers.
8876///
8877/// @param underlying_type the underlying type to consider.
8878///
8879/// @param quals the CV qualifiers of the name.
8880///
8881/// @param qualified true if we should consider the fully qualified
8882/// name of @p underlying_type.
8883///
8884/// @param internal true if the result is to be used for
8885/// libabigail-internal purposes.
8886///
8887/// @return the name (string representation) of the qualified type.
8889get_name_of_qualified_type(const type_base_sptr& underlying_type,
8891 bool qualified, bool internal)
8892{
8893 const environment& env = underlying_type->get_environment();
8894
8895 string quals_repr = get_string_representation_of_cv_quals(quals);
8896 string name = get_type_name(underlying_type, qualified, internal);
8897
8898 if (quals_repr.empty() && internal)
8899 // We are asked to return the internal name, that might be used
8900 // for type canonicalization. For that canonicalization, we need
8901 // to make a difference between a no-op qualified type which
8902 // underlying type is foo (the qualified type is named "none
8903 // foo"), and the name of foo, which is just "foo".
8904 //
8905 // Please remember that this has to be kept in sync with what is
8906 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
8907 // change this code here, please change that code there too.
8908 quals_repr = "";
8909
8910 if (!quals_repr.empty())
8911 {
8912 if (is_pointer_type(peel_qualified_type(underlying_type))
8913 || is_reference_type(peel_qualified_type(underlying_type)))
8914 {
8915 name += " ";
8916 name += quals_repr;
8917 }
8918 else
8919 name = quals_repr + " " + name;
8920 }
8921
8922 return env.intern(name);
8923}
8924
8925/// Get the name of a given function type and return a copy of it.
8926///
8927/// @param fn_type the function type to consider.
8928///
8929/// @param internal set to true if the call is intended for an
8930/// internal use (for technical use inside the library itself), false
8931/// otherwise. If you don't know what this is for, then set it to
8932/// false.
8933///
8934/// @return a copy of the function type name
8937 bool internal)
8938{return get_function_type_name(fn_type.get(), internal);}
8939
8940/// Get the name of a given function type and return a copy of it.
8941///
8942/// @param fn_type the function type to consider.
8943///
8944/// @param internal set to true if the call is intended for an
8945/// internal use (for technical use inside the library itself), false
8946/// otherwise. If you don't know what this is for, then set it to
8947/// false.
8948///
8949/// @return a copy of the function type name
8952 bool internal)
8953{
8954 ABG_ASSERT(fn_type);
8955
8956 if (const method_type* method = is_method_type(fn_type))
8957 return get_method_type_name(method, internal);
8958
8959 return get_function_type_name(*fn_type, internal);
8960}
8961
8962/// Get the name of a given function type and return a copy of it.
8963///
8964/// @param fn_type the function type to consider.
8965///
8966/// @param internal set to true if the call is intended for an
8967/// internal use (for technical use inside the library itself), false
8968/// otherwise. If you don't know what this is for, then set it to
8969/// false.
8970///
8971/// @return a copy of the function type name
8974 bool internal)
8975{
8976 std::ostringstream o;
8977 // When the function name is used for internal purposes (e.g, for
8978 // canonicalization), we want its representation to stay the same,
8979 // regardless of typedefs. So let's strip typedefs from the return
8980 // type.
8981 type_base_sptr return_type = fn_type.get_return_type();
8982 const environment& env = fn_type.get_environment();
8983
8984 o << get_type_name(return_type, /*qualified=*/true, internal) << " ";
8985 stream_pretty_representation_of_fn_parms(fn_type, o,
8986 /*qualified=*/true,
8987 internal);
8988 return env.intern(o.str());
8989}
8990
8991/// Get the ID of a function, or, if the ID can designate several
8992/// different functions, get its pretty representation.
8993///
8994/// @param fn the function to consider
8995///
8996/// @return the function ID of pretty representation of @p fn.
8999{
9000 ABG_ASSERT(fn);
9001
9002 interned_string result = fn->get_environment().intern(fn->get_id());
9003
9004 if (const corpus *c = fn->get_corpus())
9005 {
9007 c->get_exported_decls_builder();
9008 if (b->fn_id_maps_to_several_fns(fn))
9009 result = fn->get_environment().intern(fn->get_pretty_representation());
9010 }
9011
9012 return result;
9013}
9014
9015/// Get the name of a given method type and return a copy of it.
9016///
9017/// @param fn_type the function type to consider.
9018///
9019/// @param internal set to true if the call is intended for an
9020/// internal use (for technical use inside the library itself), false
9021/// otherwise. If you don't know what this is for, then set it to
9022/// false.
9023///
9024/// @return a copy of the function type name
9027 bool internal)
9028{return get_method_type_name(fn_type.get(), internal);}
9029
9030/// Get the name of a given method type and return a copy of it.
9031///
9032/// @param fn_type the function type to consider.
9033///
9034/// @param internal set to true if the call is intended for an
9035/// internal use (for technical use inside the library itself), false
9036/// otherwise. If you don't know what this is for, then set it to
9037/// false.
9038///
9039/// @return a copy of the function type name
9042 bool internal)
9043{
9044 if (fn_type)
9045 return get_method_type_name(*fn_type, internal);
9046
9047 return interned_string();
9048}
9049
9050/// Get the name of a given method type and return a copy of it.
9051///
9052/// @param fn_type the function type to consider.
9053///
9054/// @param internal set to true if the call is intended for an
9055/// internal use (for technical use inside the library itself), false
9056/// otherwise. If you don't know what this is for, then set it to
9057/// false.
9058///
9059/// @return a copy of the function type name
9062 bool internal)
9063{
9064 std::ostringstream o;
9065 // When the function name is used for internal purposes (e.g, for
9066 // canonicalization), we want its representation to stay the same,
9067 // regardless of typedefs. So let's strip typedefs from the return
9068 // type.
9069 type_base_sptr return_type = fn_type.get_return_type();
9070
9071 const environment& env = fn_type.get_environment();
9072
9073 if (return_type)
9074 o << get_type_name(return_type, /*qualified=*/true, internal);
9075 else
9076 // There are still some abixml files out there in which "void"
9077 // can be expressed as an empty type.
9078 o << "void";
9079
9080 class_or_union_sptr class_type = fn_type.get_class_type();
9081 ABG_ASSERT(class_type);
9082
9083 o << " (" << class_type->get_qualified_name(internal) << "::*) ";
9084 stream_pretty_representation_of_fn_parms(fn_type, o,
9085 /*qualified=*/true,
9086 internal);
9087
9088 return env.intern(o.str());
9089}
9090
9091/// Build and return a copy of the pretty representation of an ABI
9092/// artifact that could be either a type of a decl.
9093///
9094/// param tod the ABI artifact to consider.
9095///
9096/// @param internal set to true if the call is intended for an
9097/// internal use (for technical use inside the library itself), false
9098/// otherwise. If you don't know what this is for, then set it to
9099/// false.
9100///
9101/// @return a copy of the pretty representation of an ABI artifact
9102/// that could be either a type of a decl.
9103string
9105{
9106 string result;
9107
9108 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9109 result = get_pretty_representation(t, internal);
9110 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9111 result = get_pretty_representation(d, internal);
9112 else
9113 // We should never reach this point
9114 abort();
9115
9116 return result;
9117}
9118
9119/// Build and return a copy of the pretty representation of an ABI
9120/// artifact that could be either a type of a decl.
9121///
9122/// param tod the ABI artifact to consider.
9123///
9124/// @param internal set to true if the call is intended for an
9125/// internal use (for technical use inside the library itself), false
9126/// otherwise. If you don't know what this is for, then set it to
9127/// false.
9128///
9129/// @return a copy of the pretty representation of an ABI artifact
9130/// that could be either a type of a decl.
9131string
9133{return get_pretty_representation(tod.get(), internal);}
9134
9135/// Get a copy of the pretty representation of a decl.
9136///
9137/// @param d the decl to consider.
9138///
9139/// @param internal set to true if the call is intended for an
9140/// internal use (for technical use inside the library itself), false
9141/// otherwise. If you don't know what this is for, then set it to
9142/// false.
9143///
9144/// @return the pretty representation of the decl.
9145string
9146get_pretty_representation(const decl_base* d, bool internal)
9147{
9148 if (!d)
9149 return "";
9150 return d->get_pretty_representation(internal);
9151}
9152
9153/// Get a copy of the pretty representation of a type.
9154///
9155/// @param d the type to consider.
9156///
9157/// @param internal set to true if the call is intended for an
9158/// internal use (for technical use inside the library itself), false
9159/// otherwise. If you don't know what this is for, then set it to
9160/// false.
9161///
9162/// @return the pretty representation of the type.
9163string
9164get_pretty_representation(const type_base* t, bool internal)
9165{
9166 if (!t)
9167 return "void";
9168 if (const function_type* fn_type = is_function_type(t))
9169 return get_pretty_representation(fn_type, internal);
9170
9171 const decl_base* d = get_type_declaration(t);
9172 ABG_ASSERT(d);
9173 return get_pretty_representation(d, internal);
9174}
9175
9176/// Get a copy of the pretty representation of a decl.
9177///
9178/// @param d the decl to consider.
9179///
9180/// @param internal set to true if the call is intended for an
9181/// internal use (for technical use inside the library itself), false
9182/// otherwise. If you don't know what this is for, then set it to
9183/// false.
9184///
9185/// @return the pretty representation of the decl.
9186string
9187get_pretty_representation(const decl_base_sptr& d, bool internal)
9188{return get_pretty_representation(d.get(), internal);}
9189
9190/// Get a copy of the pretty representation of a type.
9191///
9192/// @param d the type to consider.
9193///
9194/// @param internal set to true if the call is intended for an
9195/// internal use (for technical use inside the library itself), false
9196/// otherwise. If you don't know what this is for, then set it to
9197/// false.
9198///
9199/// @return the pretty representation of the type.
9200string
9201get_pretty_representation(const type_base_sptr& t, bool internal)
9202{return get_pretty_representation(t.get(), internal);}
9203
9204/// Get the pretty representation of a function type.
9205///
9206/// @param fn_type the function type to consider.
9207///
9208/// @param internal set to true if the call is intended for an
9209/// internal use (for technical use inside the library itself), false
9210/// otherwise. If you don't know what this is for, then set it to
9211/// false.
9212///
9213/// @return the string represenation of the function type.
9214string
9216 bool internal)
9217{return get_pretty_representation(fn_type.get(), internal);}
9218
9219/// Get the pretty representation of a function type.
9220///
9221/// @param fn_type the function type to consider.
9222///
9223/// @param internal set to true if the call is intended for an
9224/// internal use (for technical use inside the library itself), false
9225/// otherwise. If you don't know what this is for, then set it to
9226/// false.
9227///
9228/// @return the string represenation of the function type.
9229string
9230get_pretty_representation(const function_type* fn_type, bool internal)
9231{
9232 if (!fn_type)
9233 return "void";
9234
9235 if (const method_type* method = is_method_type(fn_type))
9236 return get_pretty_representation(method, internal);
9237
9238 return get_pretty_representation(*fn_type, internal);
9239}
9240
9241/// Get the pretty representation of a function type.
9242///
9243/// @param fn_type the function type to consider.
9244///
9245/// @param internal set to true if the call is intended for an
9246/// internal use (for technical use inside the library itself), false
9247/// otherwise. If you don't know what this is for, then set it to
9248/// false.
9249///
9250/// @return the string represenation of the function type.
9251string
9252get_pretty_representation(const function_type& fn_type, bool internal)
9253{
9254 std::ostringstream o;
9255 o << "function type " << get_function_type_name(fn_type, internal);
9256 return o.str();
9257}
9258
9259/// Get the pretty representation of a method type.
9260///
9261/// @param method the method type to consider.
9262///
9263/// @param internal set to true if the call is intended for an
9264/// internal use (for technical use inside the library itself), false
9265/// otherwise. If you don't know what this is for, then set it to
9266/// false.
9267///
9268/// @return the string represenation of the method type.
9269string
9270get_pretty_representation(const method_type& method, bool internal)
9271{
9272 std::ostringstream o;
9273 o << "method type " << get_method_type_name(method, internal);
9274 return o.str();
9275}
9276
9277/// Get the pretty representation of a method type.
9278///
9279/// @param method the method type to consider.
9280///
9281/// @param internal set to true if the call is intended for an
9282/// internal use (for technical use inside the library itself), false
9283/// otherwise. If you don't know what this is for, then set it to
9284/// false.
9285///
9286/// @return the string represenation of the method type.
9287string
9288get_pretty_representation(const method_type* method, bool internal)
9289{
9290 if (!method)
9291 return "void";
9292 return get_pretty_representation(*method, internal);
9293}
9294
9295/// Get the pretty representation of a method type.
9296///
9297/// @param method the method type to consider.
9298///
9299/// @param internal set to true if the call is intended for an
9300/// internal use (for technical use inside the library itself), false
9301/// otherwise. If you don't know what this is for, then set it to
9302/// false.
9303///
9304/// @return the string represenation of the method type.
9305string
9307{return get_pretty_representation(method.get(), internal);}
9308
9309/// Get the flat representation of an instance of @ref class_or_union
9310/// type.
9311///
9312/// The flat representation of a given @ref class_or_union type is the
9313/// actual definition of the type, for instance:
9314///
9315/// struct foo {int a; char b;}
9316///
9317///@param cou the instance of @ref class_or_union to consider.
9318///
9319///@param indent the identation spaces to use in the representation.
9320///
9321///@param one_line if true, then the flat representation stands on one
9322///line. Otherwise, it stands on multiple lines.
9323///
9324///@return the resulting flat representation.
9325string
9327 const string& indent,
9328 bool one_line,
9329 bool internal,
9330 bool qualified_names)
9331{
9332 string repr;
9333 string local_indent = " ";
9334
9335 if (class_decl* clazz = is_class_type(&cou))
9336 {
9337 repr = indent;
9338 if (!internal && clazz->is_struct())
9339 repr += "struct";
9340 else
9341 repr += "class";
9342 }
9343 else if (is_union_type(cou))
9344 repr = indent + "union";
9345 else
9346 return "";
9347
9348 repr += " ";
9349
9350 string name = cou.get_qualified_name();
9351
9352 if (!cou.get_is_anonymous())
9353 repr += name;
9354
9355 if (cou.priv_->is_printing_flat_representation())
9356 {
9357 // We have just detected a cycle while walking the sub-tree
9358 // of this class or union type for the purpose of printing
9359 // its flat representation. We need to get out of here
9360 // pronto or else we'll be spinning endlessly.
9361 repr += "{}";
9362 return repr;
9363 }
9364
9365 // Let's mark this class or union type to signify that we started
9366 // walking its sub-tree. This is to detect potential cycles and
9367 // avoid looping endlessly.
9369
9370 repr += "{";
9371
9372 if (!one_line)
9373 repr += "\n";
9374
9375 string real_indent;
9377 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9378 dm != dmems.end();
9379 ++dm)
9380 {
9381 if (dm != dmems.begin())
9382 {
9383 if (one_line)
9384 real_indent = " ";
9385 else
9386 real_indent = "\n" + indent + local_indent;
9387 }
9388
9390 repr +=
9393 real_indent, one_line, internal, qualified_names);
9394 else
9395 {
9396 if (one_line)
9397 {
9398 if (dm != dmems.begin())
9399 repr += real_indent;
9400 repr += (*dm)->get_pretty_representation(internal,
9401 qualified_names);
9402 }
9403 else
9404 repr +=
9405 real_indent+ (*dm)->get_pretty_representation(internal,
9406 qualified_names);
9407 }
9408 repr += ";";
9409 }
9410
9411 if (one_line)
9412 repr += "}";
9413 else
9414 repr += indent + "}";
9415
9416 // Let's unmark this class or union type to signify that we are done
9417 // walking its sub-tree. This was to detect potential cycles and
9418 // avoid looping endlessly.
9420
9421 return repr;
9422}
9423
9424/// Get the flat representation of an instance of @ref class_or_union
9425/// type.
9426///
9427/// The flat representation of a given @ref class_or_union type is the
9428/// actual definition of the type, for instance:
9429///
9430/// struct foo {int a; char b;}
9431///
9432///@param cou the instance of @ref class_or_union to consider.
9433///
9434///@param indent the identation spaces to use in the representation.
9435///
9436///@param one_line if true, then the flat representation stands on one
9437///line. Otherwise, it stands on multiple lines.
9438///
9439///@return the resulting flat representation.
9440string
9442 const string& indent,
9443 bool one_line,
9444 bool internal,
9445 bool qualified_names)
9446{
9447 if (cou)
9448 return get_class_or_union_flat_representation(*cou, indent, one_line,
9449 internal, qualified_names);
9450 return "";
9451}
9452
9453/// Get the flat representation of an instance of @ref class_or_union
9454/// type.
9455///
9456/// The flat representation of a given @ref class_or_union type is the
9457/// actual definition of the type, for instance:
9458///
9459/// struct foo {int a; char b;}
9460///
9461///@param cou the instance of @ref class_or_union to consider.
9462///
9463///@param indent the identation spaces to use in the representation.
9464///
9465///@param one_line if true, then the flat representation stands on one
9466///line. Otherwise, it stands on multiple lines.
9467///
9468///@return the resulting flat representation.
9469string
9470get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9471 const string& indent,
9472 bool one_line,
9473 bool internal,
9474 bool qualified_names)
9476 indent,
9477 one_line,
9478 internal,
9479 qualified_names);}
9480
9481/// Get the flat representation of an instance of @ref enum_type_decl
9482/// type.
9483///
9484/// The flat representation of a given @ref enum_type_decl type is the
9485/// actual definition of the type, for instance:
9486///
9487/// enum {E_0 =0, E_1 = 1}
9488///
9489///@param enum_type the enum type to consider.
9490///
9491///@param indent the identation spaces to use in the representation.
9492///
9493///@param one_line if true, then the flat representation stands on one
9494///line. Otherwise, it stands on multiple lines.
9495///
9496///@param qualified_names use qualified names when applicable.
9497///Typically, if this is true, the name of the enum is going to be
9498///qualified.
9499///
9500///@return the resulting flat representation.
9501string
9503 const string& indent, bool one_line,
9504 bool qualified_names)
9505{
9506 string repr;
9507 std::ostringstream o;
9508 string local_indent = " ";
9509
9510 repr = indent + "enum ";
9511
9512 if (!enum_type.get_is_anonymous())
9513 o << (qualified_names
9514 ? enum_type.get_qualified_name()
9515 : enum_type.get_name()) + " ";
9516
9517 o << "{";
9518
9519 if (!one_line)
9520 o << "\n";
9521
9522 for (const auto &enumerator : enum_type.get_sorted_enumerators())
9523 {
9524 if (!one_line)
9525 o << "\n" + indent;
9526
9527 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
9528 }
9529
9530 if (!one_line)
9531 o << "\n" + indent << "}";
9532 else
9533 o << "}";
9534
9535 repr =o.str();
9536
9537 return repr;
9538}
9539
9540/// Get the flat representation of an instance of @ref enum_type_decl
9541/// type.
9542///
9543/// The flat representation of a given @ref enum_type_decl type is the
9544/// actual definition of the type, for instance:
9545///
9546/// enum {E_0 =0, E_1 = 1}
9547///
9548///@param enum_type the enum type to consider.
9549///
9550///@param indent the identation spaces to use in the representation.
9551///
9552///@param one_line if true, then the flat representation stands on one
9553///line. Otherwise, it stands on multiple lines.
9554///
9555///@param qualified_names use qualified names when applicable.
9556///Typically, if this is true, the name of the enum is going to be
9557///qualified.
9558///
9559///@return the resulting flat representation.
9560string
9562 const string& indent, bool one_line,
9563 bool qualified_names)
9564{
9565 if (!enum_type)
9566 return "";
9567
9568 return get_enum_flat_representation(*enum_type, indent,
9569 one_line, qualified_names);
9570}
9571
9572/// Get the flat representation of an instance of @ref enum_type_decl
9573/// type.
9574///
9575/// The flat representation of a given @ref enum_type_decl type is the
9576/// actual definition of the type, for instance:
9577///
9578/// enum {E_0 =0, E_1 = 1}
9579///
9580///@param enum_type the enum type to consider.
9581///
9582///@param indent the identation spaces to use in the representation.
9583///
9584///@param one_line if true, then the flat representation stands on one
9585///line. Otherwise, it stands on multiple lines.
9586///
9587///@param qualified_names use qualified names when applicable.
9588///Typically, if this is true, the name of the enum is going to be
9589///qualified.
9590///
9591///@return the resulting flat representation.
9592string
9594 const string& indent, bool one_line,
9595 bool qualified_names)
9596{
9597 return get_enum_flat_representation(enum_type.get(),
9598 indent, one_line,
9599 qualified_names);
9600}
9601
9602/// Get the flat representation of an instance of @ref enum_type_decl
9603/// type.
9604///
9605/// The flat representation of a given @ref enum_type_decl type is the
9606/// actual definition of the type, for instance:
9607///
9608/// enum {E_0 =0, E_1 = 1}
9609///
9610///@param enum_type the enum type to consider.
9611///
9612///@param indent the identation spaces to use in the representation.
9613///
9614///@param one_line if true, then the flat representation stands on one
9615///line. Otherwise, it stands on multiple lines.
9616///
9617///@param qualified_names use qualified names when applicable.
9618///Typically, if this is true, the name of the enum is going to be
9619///qualified.
9620///
9621///@return the resulting flat representation.
9622string
9624 const string& indent,
9625 bool one_line,
9626 bool internal,
9627 bool qualified_name)
9628
9629{
9630 string repr;
9631 if (const class_or_union* cou = is_class_or_union_type(&coe))
9632 repr = get_class_or_union_flat_representation(cou, indent, one_line,
9633 internal, qualified_name);
9634 else if (const enum_type_decl* enom = is_enum_type(&coe))
9635 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9636
9637 return repr;
9638}
9639
9640/// Get the textual representation of a type for debugging purposes.
9641///
9642/// If the type is a class/union, this shows the data members, virtual
9643/// member functions, size, pointer value of its canonical type, etc.
9644/// Otherwise, this just shows the name of the artifact as returned by
9645/// type_or_decl_base:get_pretty_representation().
9646///
9647/// @param artifact the artifact to show a debugging representation of.
9648///
9649/// @return a debugging string representation of @p artifact.
9650string
9652{
9653 string nil_str;
9654 if (!artifact)
9655 return nil_str;
9656
9657 class_or_union * c = is_class_or_union_type(artifact);
9658 if (c)
9659 {
9660 class_decl *clazz = is_class_type(c);
9661 string name = c->get_qualified_name();
9662 std::ostringstream o;
9663 if (clazz)
9664 {
9665 if (clazz->is_struct())
9666 o << "struct ";
9667 else
9668 o << "class ";
9669 }
9670 else if (is_union_type(c))
9671 o << "union ";
9672 o << name;
9673
9674 if (clazz)
9675 {
9676 if (!clazz->get_base_specifiers().empty())
9677 o << " :" << std::endl;
9678 for (auto &b : clazz->get_base_specifiers())
9679 {
9680 o << " ";
9681 if (b->get_is_virtual())
9682 o << "virtual ";
9683 o << b->get_base_class()->get_qualified_name()
9684 << " // hash: ";
9685 hash_t h = peek_hash_value(*b->get_base_class());
9686 if (h)
9687 o << std::hex << *h << std::dec;
9688 else
9689 o << "none";
9690 o << std::endl;
9691 }
9692 }
9693 o << std::endl
9694 << "{"
9695 << " // size in bits: " << c->get_size_in_bits() << "\n"
9696 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9697 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9698 << " // translation unit: "
9699 << (c->get_translation_unit()
9701 : nil_str)
9702 << std::endl
9703 << " // @: " << std::hex << is_type(c)
9704 << ", @canonical: " << c->get_canonical_type().get() << std::dec << "\n"
9705 << " // hash: " ;
9706
9707 hash_t h = peek_hash_value(*c);
9708 if (h)
9709 o << std::hex << *h << std::dec;
9710 else
9711 o << "none";
9712 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*c);
9713 o << "\n\n";
9714
9715
9716 for (auto member_type : c->get_sorted_member_types())
9717 {
9718 o << " "
9719 << member_type->get_pretty_representation(/*internal=*/false,
9720 /*qualified=*/false)
9721 << ";";
9722 if (member_type->get_canonical_type())
9723 {
9724 o << " // uses canonical type: '@"
9725 << std::hex << member_type->get_canonical_type().get() << "'";
9726 o << " / h:";
9727 hash_t h = peek_hash_value(*member_type);
9728 o << std::hex << *h << std::dec;
9729 if (get_canonical_type_index(*member_type))
9730 o << "#" << get_canonical_type_index(*member_type);
9731 }
9732 o << "\n";
9733 }
9734
9735 if (!c->get_sorted_member_types().empty())
9736 o << std::endl;
9737
9738 for (auto m : c->get_data_members())
9739 {
9740 type_base_sptr t = m->get_type();
9742
9743 o << " "
9744 << m->get_pretty_representation(/*internal=*/false,
9745 /*qualified=*/false)
9746 << ";";
9747
9748 if (t && t->get_canonical_type())
9749 o << " // uses canonical type '@"
9750 << std::hex << t->get_canonical_type().get() << "'";
9751
9752 o << "/ h:";
9753 hash_t h = peek_hash_value(*m->get_type());
9754 if (h)
9755 o << std::hex << *h << std::dec;
9756 else
9757 o << "none";
9758 o << std::endl;
9759 }
9760
9761 if (!c->get_data_members().empty())
9762 o << std::endl;
9763
9764 if (clazz && clazz->has_vtable())
9765 {
9766 o << " // virtual member functions\n\n";
9767 for (auto f : clazz->get_virtual_mem_fns())
9768 {
9769 o << " " << f->get_pretty_representation(/*internal=*/false,
9770 /*qualified=*/false)
9771 << " // voffset: " << get_member_function_vtable_offset(f)
9772 << ", h: ";
9773 hash_t h = peek_hash_value(*f->get_type());
9774 if (h)
9775 o << std::hex << *h << std::dec;
9776 else
9777 o << "none";
9778 o << ";" << std::endl;
9779 }
9780 }
9781
9782 o << "};" << std::endl;
9783
9784 return o.str();
9785 }
9786 else if (const enum_type_decl* e = is_enum_type(artifact))
9787 {
9788 string name = e->get_qualified_name();
9789 std::ostringstream o;
9790 o << "enum " << name
9791 << " : "
9792 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9793 true)
9794 << "\n"
9795 << "{\n"
9796 << " // size in bits: " << e->get_size_in_bits() << "\n"
9797 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9798 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9799 << " // translation unit: "
9800 << e->get_translation_unit()->get_absolute_path() << "\n"
9801 << " // @: " << std::hex << is_type(e)
9802 << ", @canonical: " << e->get_canonical_type().get() << std::dec << "\n"
9803 << " // hash: ";
9804
9805 hash_t h = peek_hash_value(*e);
9806 if (h)
9807 o << std::hex << *h << std::dec;
9808 else
9809 o << "none";
9810 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*e);
9811 o << "\n\n";
9812
9813 for (const auto &enom : e->get_enumerators())
9814 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9815
9816 o << "};\n";
9817
9818 return o.str();
9819 }
9820 else if (type_base *t = is_type(artifact))
9821 {
9822 std::ostringstream o;
9823 o << t->get_pretty_representation(/*internal=*/true,
9824 /*qualified=*/true)
9825 << " // cti: " << get_canonical_type_index(*t)
9826 << "\n";
9827 return o.str();
9828 }
9829
9830 return artifact->get_pretty_representation(/*internal=*/true,
9831 /*qualified=*/true);
9832}
9833
9834/// Get a given data member, referred to by its name, of a class type.
9835///
9836/// @param clazz the class to consider.
9837///
9838/// @param member_name name of the data member to get.
9839///
9840/// @return the resulting data member or nullptr if none was found.
9842get_data_member(class_or_union *clazz, const char* member_name)
9843{
9844 if (!clazz)
9845 return var_decl_sptr();
9846 return clazz->find_data_member(member_name);
9847}
9848
9849/// Get a given data member, referred to by its name, of a class type.
9850///
9851/// @param clazz the class to consider.
9852///
9853/// @param member_name name of the data member to get.
9854///
9855/// @return the resulting data member or nullptr if none was found.
9857get_data_member(type_base *clazz, const char* member_name)
9858{return get_data_member(is_class_or_union_type(clazz), member_name);}
9859
9860/// Get the non-artificial (natural) location of a decl.
9861///
9862/// If the decl doesn't have a natural location then return its
9863/// artificial one.
9864///
9865/// @param decl the decl to consider.
9866///
9867/// @return the natural location @p decl if it has one; otherwise,
9868/// return its artificial one.
9869const location&
9871{
9872 ABG_ASSERT(decl);
9873
9874 if (decl->get_location())
9875 return decl->get_location();
9876 return decl->get_artificial_location();
9877}
9878
9879/// Get the artificial location of a decl.
9880///
9881/// If the decl doesn't have an artificial location then return its
9882/// natural one.
9883///
9884/// @param decl the decl to consider.
9885///
9886/// @return the artificial location @p decl if it has one; otherwise,
9887/// return its natural one.
9888const location&
9890{
9891 ABG_ASSERT(decl);
9892
9893 if (decl->has_artificial_location())
9894 return decl->get_artificial_location();
9895 return decl->get_location();
9896}
9897
9898/// Emit a textual representation of an artifact to std error stream
9899/// for debugging purposes.
9900///
9901/// This is useful to invoke from within a command line debugger like
9902/// GDB to help make sense of a given ABI artifact.
9903///
9904/// @param artifact the ABI artifact to emit the debugging
9905/// representation for.
9906///
9907/// @return the artifact @p artifact.
9909debug(const type_or_decl_base* artifact)
9910{
9911 std::cerr << get_debug_representation(artifact) << std::endl;
9912 return const_cast<type_or_decl_base*>(artifact);
9913}
9914
9915/// Emit a textual representation of an artifact to std error stream
9916/// for debugging purposes.
9917///
9918/// This is useful to invoke from within a command line debugger like
9919/// GDB to help make sense of a given ABI artifact.
9920///
9921/// @param artifact the ABI artifact to emit the debugging
9922/// representation for.
9923///
9924/// @return the artifact @p artifact.
9925type_base*
9926debug(const type_base* artifact)
9927{
9928 debug(static_cast<const type_or_decl_base*>(artifact));
9929 return const_cast<type_base*>(artifact);
9930}
9931
9932/// Emit a textual representation of an artifact to std error stream
9933/// for debugging purposes.
9934///
9935/// This is useful to invoke from within a command line debugger like
9936/// GDB to help make sense of a given ABI artifact.
9937///
9938/// @param artifact the ABI artifact to emit the debugging
9939/// representation for.
9940///
9941/// @return the artifact @p artifact.
9942decl_base*
9943debug(const decl_base* artifact)
9944{
9945 debug(static_cast<const type_or_decl_base*>(artifact));
9946 return const_cast<decl_base*>(artifact);
9947}
9948
9949/// Test if two ABI artifacts are equal.
9950///
9951/// This can be useful when used from the command line of a debugger
9952/// like GDB.
9953///
9954/// @param l the first ABI artifact to consider in the comparison.
9955///
9956/// @param r the second ABI artifact to consider in the comparison.
9957///
9958/// @return true iff @p l equals @p r.
9959bool
9961{
9962 if (!!l != !!r)
9963 return false;
9964 if (!l && !r)
9965 return true;
9966
9967 return (*l == *r);
9968}
9969
9970/// Emit a trace of a comparison operand stack.
9971///
9972/// @param vect the operand stack to emit the trace for.
9973///
9974/// @param o the output stream to emit the trace to.
9975static void
9976debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
9977{
9978 for (auto t : vect)
9979 {
9980 o << "|" << t->get_pretty_representation()
9981 << "@" << std::hex << t << std::dec;
9982 }
9983 if (!vect.empty())
9984 o << "|";
9985}
9986
9987/// Construct a trace of the two comparison operand stacks.
9988///
9989/// @param the environment in which the comparison operand stacks are.
9990///
9991/// @return a string representing the trace.
9992static string
9993print_comp_stack(const environment& env)
9994{
9995 std::ostringstream o;
9996 o << "left-operands: ";
9997 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
9998 o << "\n" << "right-operands: ";
9999 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10000 o << "\n";
10001 return o.str();
10002}
10003
10004/// Emit a trace of the two comparison operands stack on the standard
10005/// error stream.
10006///
10007/// @param env the environment the comparison operands stack belong
10008/// to.
10009void
10011{
10012 std::cerr << print_comp_stack(env);
10013 std::cerr << std::endl;
10014}
10015
10016/// By looking at the language of the TU a given ABI artifact belongs
10017/// to, test if the ONE Definition Rule should apply.
10018///
10019/// To date, it applies to c++, java and ada.
10020///
10021/// @param artifact the ABI artifact to consider.
10022///
10023/// @return true iff the One Definition Rule should apply.
10024bool
10026{
10027 if (!artifact.get_translation_unit())
10028 return false;
10029
10031 artifact.get_translation_unit()->get_language();
10032
10034 || is_java_language(l)
10035 || is_ada_language(l))
10036 return true;
10037
10038 return false;
10039}
10040
10041/// Get the declaration for a given type.
10042///
10043/// @param t the type to consider.
10044///
10045/// @return the declaration for the type to return.
10046const decl_base*
10048{return dynamic_cast<const decl_base*>(t);}
10049
10050/// Get the declaration for a given type.
10051///
10052/// @param t the type to consider.
10053///
10054/// @return the declaration for the type to return.
10055decl_base*
10057{return dynamic_cast<decl_base*>(t);}
10058
10059/// Get the declaration for a given type.
10060///
10061/// @param t the type to consider.
10062///
10063/// @return the declaration for the type to return.
10064decl_base_sptr
10065get_type_declaration(const type_base_sptr t)
10066{return dynamic_pointer_cast<decl_base>(t);}
10067
10068/// Test if two types are equal modulo a typedef.
10069///
10070/// Type A and B are compatible if
10071///
10072/// - A and B are equal
10073/// - or if one type is a typedef of the other one.
10074///
10075/// @param type1 the first type to consider.
10076///
10077/// @param type2 the second type to consider.
10078///
10079/// @return true iff @p type1 and @p type2 are compatible.
10080bool
10081types_are_compatible(const type_base_sptr type1,
10082 const type_base_sptr type2)
10083{
10084 if (!type1 || !type2)
10085 return false;
10086
10087 if (type1 == type2)
10088 return true;
10089
10090 // Normally we should strip typedefs entirely, but this is
10091 // potentially costly, especially on binaries with huge changesets
10092 // like the Linux Kernel. So we just get the leaf types for now.
10093 //
10094 // Maybe there should be an option by which users accepts to pay the
10095 // CPU usage toll in exchange for finer filtering?
10096
10097 // type_base_sptr t1 = strip_typedef(type1);
10098 // type_base_sptr t2 = strip_typedef(type2);
10099
10100 type_base_sptr t1 = peel_typedef_type(type1);
10101 type_base_sptr t2 = peel_typedef_type(type2);
10102
10103 return t1 == t2;
10104}
10105
10106/// Test if two types are equal modulo a typedef.
10107///
10108/// Type A and B are compatible if
10109///
10110/// - A and B are equal
10111/// - or if one type is a typedef of the other one.
10112///
10113/// @param type1 the declaration of the first type to consider.
10114///
10115/// @param type2 the declaration of the second type to consider.
10116///
10117/// @return true iff @p type1 and @p type2 are compatible.
10118bool
10119types_are_compatible(const decl_base_sptr d1,
10120 const decl_base_sptr d2)
10121{return types_are_compatible(is_type(d1), is_type(d2));}
10122
10123/// Return the translation unit a declaration belongs to.
10124///
10125/// @param decl the declaration to consider.
10126///
10127/// @return the resulting translation unit, or null if the decl is not
10128/// yet added to a translation unit.
10131{
10132 translation_unit* result =
10133 const_cast<translation_unit*>(t.get_translation_unit());
10134
10135 if (result)
10136 return result;
10137
10138 if (decl_base* decl = is_decl(&t))
10139 {
10140 scope_decl* scope = decl->get_scope();
10141 while (scope)
10142 {
10143 result = scope->get_translation_unit();
10144 if (result)
10145 break;
10146 scope = scope->get_scope();
10147 }
10148 }
10149
10150 return result;
10151}
10152
10153/// Return the translation unit a declaration belongs to.
10154///
10155/// @param decl the declaration to consider.
10156///
10157/// @return the resulting translation unit, or null if the decl is not
10158/// yet added to a translation unit.
10161{return decl ? get_translation_unit(*decl) : nullptr;}
10162
10163/// Return the translation unit a declaration belongs to.
10164///
10165/// @param decl the declaration to consider.
10166///
10167/// @return the resulting translation unit, or null if the decl is not
10168/// yet added to a translation unit.
10171{return get_translation_unit(decl.get());}
10172
10173/// Tests whether if a given scope is the global scope.
10174///
10175/// @param scope the scope to consider.
10176///
10177/// @return true iff the current scope is the global one.
10178bool
10180{return !!dynamic_cast<const global_scope*>(&scope);}
10181
10182/// Tests whether if a given scope is the global scope.
10183///
10184/// @param scope the scope to consider.
10185///
10186/// @return the @ref global_scope* representing the scope @p scope or
10187/// 0 if @p scope is not a global scope.
10188const global_scope*
10190{return dynamic_cast<const global_scope*>(scope);}
10191
10192/// Tests whether if a given scope is the global scope.
10193///
10194/// @param scope the scope to consider.
10195///
10196/// @return true iff the current scope is the global one.
10197bool
10198is_global_scope(const shared_ptr<scope_decl>scope)
10199{return is_global_scope(scope.get());}
10200
10201/// Tests whether a given declaration is at global scope.
10202///
10203/// @param decl the decl to consider.
10204///
10205/// @return true iff decl is at global scope.
10206bool
10208{return (is_global_scope(decl.get_scope()));}
10209
10210/// Tests whether a given declaration is at global scope.
10211///
10212/// @param decl the decl to consider.
10213///
10214/// @return true iff decl is at global scope.
10215bool
10216is_at_global_scope(const decl_base_sptr decl)
10217{return (decl && is_global_scope(decl->get_scope()));}
10218
10219/// Tests whether a given declaration is at global scope.
10220///
10221/// @param decl the decl to consider.
10222///
10223/// @return true iff decl is at global scope.
10224bool
10226{return is_at_global_scope(*decl);}
10227
10228/// Tests whether a given decl is at class scope.
10229///
10230/// @param decl the decl to consider.
10231///
10232/// @return true iff decl is at class scope.
10234is_at_class_scope(const decl_base_sptr decl)
10235{return is_at_class_scope(decl.get());}
10236
10237/// Tests whether a given decl is at class scope.
10238///
10239/// @param decl the decl to consider.
10240///
10241/// @return true iff decl is at class scope.
10244{
10245 if (!decl)
10246 return 0;
10247
10248 return is_at_class_scope(*decl);
10249}
10250
10251/// Tests whether a given decl is at class scope.
10252///
10253/// @param decl the decl to consider.
10254///
10255/// @return true iff decl is at class scope.
10258{
10259 scope_decl* scope = decl.get_scope();
10260 if (class_or_union* cl = is_class_type(scope))
10261 return cl;
10262 if (class_or_union* cl = is_union_type(scope))
10263 return cl;
10264 return 0;
10265}
10266
10267/// Find a data member inside an anonymous data member.
10268///
10269/// An anonymous data member has a type which is a class or union.
10270/// This function looks for a data member inside the type of that
10271/// anonymous data member.
10272///
10273/// @param anon_dm the anonymous data member to consider.
10274///
10275/// @param name the name of the data member to look for.
10278 const string& name)
10279{
10280 const class_or_union* containing_class_or_union =
10282
10283 if (!containing_class_or_union)
10284 return var_decl_sptr();
10285
10286 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10287 return result;
10288}
10289
10290/// Tests whether a given decl is at template scope.
10291///
10292/// Note that only template parameters , types that are compositions,
10293/// and template patterns (function or class) can be at template scope.
10294///
10295/// @param decl the decl to consider.
10296///
10297/// @return true iff the decl is at template scope.
10298bool
10299is_at_template_scope(const shared_ptr<decl_base> decl)
10300{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10301
10302/// Tests whether a decl is a template parameter.
10303///
10304/// @param decl the decl to consider.
10305///
10306/// @return true iff decl is a template parameter.
10307bool
10308is_template_parameter(const shared_ptr<decl_base> decl)
10309{
10310 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10311 || dynamic_pointer_cast<non_type_tparameter>(decl)
10312 || dynamic_pointer_cast<template_tparameter>(decl)));
10313}
10314
10315/// Test whether a declaration is a @ref function_decl.
10316///
10317/// @param d the declaration to test for.
10318///
10319/// @return a shared pointer to @ref function_decl if @p d is a @ref
10320/// function_decl. Otherwise, a nil shared pointer.
10323{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10324
10325/// Test whether a declaration is a @ref function_decl.
10326///
10327/// @param d the declaration to test for.
10328///
10329/// @return true if @p d is a function_decl.
10330bool
10332{return is_function_decl(&d);}
10333
10334/// Test whether a declaration is a @ref function_decl.
10335///
10336/// @param d the declaration to test for.
10337///
10338/// @return a shared pointer to @ref function_decl if @p d is a @ref
10339/// function_decl. Otherwise, a nil shared pointer.
10342{return dynamic_pointer_cast<function_decl>(d);}
10343
10344/// Test whether a declaration is a @ref function_decl.
10345///
10346/// @param d the declaration to test for.
10347///
10348/// @return a pointer to @ref function_decl if @p d is a @ref
10349/// function_decl. Otherwise, a nil shared pointer.
10352{
10353 return dynamic_cast<function_decl::parameter*>
10354 (const_cast<type_or_decl_base*>(tod));
10355}
10356
10357/// Test whether an ABI artifact is a @ref function_decl.
10358///
10359/// @param tod the declaration to test for.
10360///
10361/// @return a pointer to @ref function_decl if @p d is a @ref
10362/// function_decl. Otherwise, a nil shared pointer.
10365{return dynamic_pointer_cast<function_decl::parameter>(tod);}
10366
10367/// Test if an ABI artifact is a declaration.
10368///
10369/// @param d the artifact to consider.
10370///
10371/// @param return the declaration sub-object of @p d if it's a
10372/// declaration, or NULL if it is not.
10373decl_base*
10375{
10376 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10377 {
10378 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10379 // The artifact is a decl-only (like a function or a
10380 // variable). That is, it's not a type that also has a
10381 // declaration. In this case, we are in the fast path and we
10382 // have a pointer to the decl sub-object handy. Just return
10383 // it ...
10384 return reinterpret_cast<decl_base*>
10385 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10386
10387 // ... Otherwise, we are in the slow path, which is that the
10388 // artifact is a type which has a declaration. In that case,
10389 // let's use the slow dynamic_cast because we don't have the
10390 // pointer to the decl sub-object handily present.
10391 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10392 }
10393 return 0;
10394}
10395
10396/// Test if an ABI artifact is a declaration.
10397///
10398/// @param d the artifact to consider.
10399///
10400/// @param return the declaration sub-object of @p d if it's a
10401/// declaration, or NULL if it is not.
10402decl_base_sptr
10404{return dynamic_pointer_cast<decl_base>(d);}
10405
10406/// Test if an ABI artifact is a declaration.
10407///
10408/// This is done using a slow path that uses dynamic_cast.
10409///
10410/// @param d the artifact to consider.
10411///
10412/// @param return the declaration sub-object of @p d if it's a
10413decl_base*
10415{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10416
10417/// Test if an ABI artifact is a declaration.
10418///
10419/// This is done using a slow path that uses dynamic_cast.
10420///
10421/// @param d the artifact to consider.
10422///
10423/// @param return the declaration sub-object of @p d if it's a
10424decl_base_sptr
10426{return dynamic_pointer_cast<decl_base>(t);}
10427
10428/// Test whether a declaration is a type.
10429///
10430/// @param d the IR artefact to test for.
10431///
10432/// @return true if the artifact is a type, false otherwise.
10433bool
10435{
10436 if (dynamic_cast<const type_base*>(&tod))
10437 return true;
10438 return false;
10439}
10440
10441/// Test whether a declaration is a type.
10442///
10443/// @param d the IR artefact to test for.
10444///
10445/// @return true if the artifact is a type, false otherwise.
10446type_base*
10448{
10449 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10450 return reinterpret_cast<type_base*>
10451 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10452
10453 return 0;
10454}
10455
10456/// Test whether a declaration is a type.
10457///
10458/// @param d the IR artefact to test for.
10459///
10460/// @return true if the artifact is a type, false otherwise.
10461type_base_sptr
10463{return dynamic_pointer_cast<type_base>(tod);}
10464
10465/// Test whether a declaration is a type.
10466///
10467/// @param d the declaration to test for.
10468///
10469/// @return true if the declaration is a type, false otherwise.
10470
10471/// Test if a given type is anonymous.
10472///
10473/// Note that this function considers that an anonymous class that is
10474/// named by a typedef is not anonymous anymore. This is the C idiom:
10475///
10476/// typedef struct {int member;} s_type;
10477///
10478/// The typedef s_type becomes the name of the originally anonymous
10479/// struct.
10480///
10481/// @param t the type to consider.
10482///
10483/// @return true iff @p t is anonymous.
10484bool
10486{
10487 const decl_base* d = get_type_declaration(t);
10488 if (d)
10489 if (d->get_is_anonymous())
10490 {
10492 {
10493 // An anonymous class that is named by a typedef is not
10494 // considered anonymous anymore.
10495 if (!cou->get_naming_typedef())
10496 return true;
10497 }
10498 else
10499 return true;
10500 }
10501 return false;
10502}
10503
10504/// Test if a given type is anonymous.
10505///
10506/// @param t the type to consider.
10507///
10508/// @return true iff @p t is anonymous.
10509bool
10510is_anonymous_type(const type_base_sptr& t)
10511{return is_anonymous_type(t.get());}
10512
10513/// Test if a type is a neither a pointer, an array nor a function
10514/// type.
10515///
10516/// @param t the type to consider.
10517///
10518/// @return true if the @p t is NOT a pointer, an array nor a
10519/// function.
10520bool
10521is_npaf_type(const type_base_sptr& t)
10522{
10523 if (!(is_pointer_type(t)
10524 || is_array_type(t)
10525 || is_function_type(t)
10526 || is_ptr_to_mbr_type(t)))
10527 return true;
10528 return false;
10529}
10530
10531/// Test whether a type is a type_decl (a builtin type).
10532///
10533/// @return the type_decl* for @t if it's type_decl, otherwise, return
10534/// nil.
10535const type_decl*
10537{return dynamic_cast<const type_decl*>(t);}
10538
10539/// Test whether a type is a type_decl (a builtin type).
10540///
10541/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10542/// return nil.
10545{return dynamic_pointer_cast<type_decl>(t);}
10546
10547/// Test if a type is a real type.
10548///
10549/// @param t the type to test.
10550///
10551/// @return the real type @p t can be converted to, or nil if @p
10552/// is not a real type.
10553type_decl*
10555{
10556 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10557 if (!type)
10558 return nullptr;
10559
10560 real_type int_type;
10561 if (!parse_real_type(type->get_name(), int_type))
10562 return nullptr;
10563
10564 return type;
10565}
10566
10567/// Test if a type is a real type.
10568///
10569/// @param t the type to test.
10570///
10571/// @return the real type @p t can be converted to, or nil if @p is
10572/// not a real type.
10575{
10576 const type_decl_sptr type = is_type_decl(t);
10577 if (!type)
10578 return type_decl_sptr();
10579
10580 real_type int_type;
10581 if (!parse_real_type(type->get_name(), int_type))
10582 return type_decl_sptr();
10583
10584 return type;
10585}
10586
10587/// Test if a type is an integral type.
10588///
10589/// @param t the type to test.
10590///
10591/// @return the integral type @p t can be converted to, or nil if @p
10592/// is not an integral type.
10593type_decl*
10595{
10596 type_decl* type = is_real_type(t);
10597 if (!type)
10598 return nullptr;
10599
10600 real_type rt;
10601 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10604 return nullptr;
10605
10606 return type;
10607}
10608
10609/// Test if a type is an integral type.
10610///
10611/// @param t the type to test.
10612///
10613/// @return the integral type @p t can be converted to, or nil if @p
10614/// is not an integral type.
10617{
10618 type_decl_sptr type = is_real_type(t);
10619 if (!type)
10620 return type;
10621
10622 real_type rt;
10623 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10626 return type_decl_sptr();
10627
10628 return type;
10629}
10630
10631/// Test whether a type is a typedef.
10632///
10633/// @param t the type to test for.
10634///
10635/// @return the typedef declaration of the @p t, or NULL if it's not a
10636/// typedef.
10639{return dynamic_pointer_cast<typedef_decl>(t);}
10640
10641/// Test whether a type is a typedef.
10642///
10643/// @param t the declaration of the type to test for.
10644///
10645/// @return the typedef declaration of the @p t, or NULL if it's not a
10646/// typedef.
10647const typedef_decl*
10649{return dynamic_cast<const typedef_decl*>(t);}
10650
10651/// Test whether a type is a typedef.
10652///
10653/// @param t the declaration of the type to test for.
10654///
10655/// @return the typedef declaration of the @p t, or NULL if it's not a
10656/// typedef.
10659{return dynamic_cast<typedef_decl*>(t);}
10660
10661/// Test whether a type is a typedef.
10662///
10663/// @param t the declaration of the type to test for.
10664///
10665/// @return the typedef declaration of the @p t, or NULL if it's not a
10666/// typedef.
10667const typedef_decl*
10669{return dynamic_cast<const typedef_decl*>(t);}
10670/// Test if a type is an enum. This function looks through typedefs.
10671///
10672/// @parm t the type to consider.
10673///
10674/// @return the enum_decl if @p t is an @ref enum_decl or null
10675/// otherwise.
10677is_compatible_with_enum_type(const type_base_sptr& t)
10678{
10679 if (!t)
10680 return enum_type_decl_sptr();
10681
10682 // Normally we should strip typedefs entirely, but this is
10683 // potentially costly, especially on binaries with huge changesets
10684 // like the Linux Kernel. So we just get the leaf types for now.
10685 //
10686 // Maybe there should be an option by which users accepts to pay the
10687 // CPU usage toll in exchange for finer filtering?
10688
10689 // type_base_sptr ty = strip_typedef(t);
10690 type_base_sptr ty = peel_typedef_type(t);;
10691 return is_enum_type(ty);
10692}
10693
10694/// Test if a type is an enum. This function looks through typedefs.
10695///
10696/// @parm t the type to consider.
10697///
10698/// @return the enum_decl if @p t is an @ref enum_decl or null
10699/// otherwise.
10701is_compatible_with_enum_type(const decl_base_sptr& t)
10703
10704/// Test if a decl is an enum_type_decl
10705///
10706/// @param d the decl to test for.
10707///
10708/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
10709const enum_type_decl*
10711{return dynamic_cast<const enum_type_decl*>(d);}
10712
10713/// Test if a decl is an enum_type_decl
10714///
10715/// @param d the decl to test for.
10716///
10717/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
10720{return dynamic_pointer_cast<enum_type_decl>(d);}
10721
10722/// Test if a type is a class. This function looks through typedefs.
10723///
10724/// @parm t the type to consider.
10725///
10726/// @return the class_decl if @p t is a class_decl or null otherwise.
10728is_compatible_with_class_type(const type_base_sptr& t)
10729{
10730 if (!t)
10731 return class_decl_sptr();
10732
10733 // Normally we should strip typedefs entirely, but this is
10734 // potentially costly, especially on binaries with huge changesets
10735 // like the Linux Kernel. So we just get the leaf types for now.
10736 //
10737 // Maybe there should be an option by which users accepts to pay the
10738 // CPU usage toll in exchange for finer filtering?
10739
10740 // type_base_sptr ty = strip_typedef(t);
10741 type_base_sptr ty = peel_typedef_type(t);
10742 return is_class_type(ty);
10743}
10744
10745/// Test if a type is a class. This function looks through typedefs.
10746///
10747/// @parm t the type to consider.
10748///
10749/// @return the class_decl if @p t is a class_decl or null otherwise.
10751is_compatible_with_class_type(const decl_base_sptr& t)
10753
10754/// Test whether a type is a class.
10755///
10756/// @parm t the type to consider.
10757///
10758/// @return true iff @p t is a class_decl.
10759bool
10761{return is_class_type(&t);}
10762
10763/// Test whether a type is a class.
10764///
10765/// @parm t the type to consider.
10766///
10767/// @return the class_decl if @p t is a class_decl or null otherwise.
10770{
10771 if (!t)
10772 return 0;
10773
10774 if (t->kind() & type_or_decl_base::CLASS_TYPE)
10775 return reinterpret_cast<class_decl*>
10776 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10777
10778 return 0;
10779}
10780
10781/// Test whether a type is a class.
10782///
10783/// @parm t the type to consider.
10784///
10785/// @return the class_decl if @p t is a class_decl or null otherwise.
10788{return dynamic_pointer_cast<class_decl>(d);}
10789
10790/// Test if the last data member of a class is an array with
10791/// non-finite data member.
10792///
10793/// The flexible data member idiom is a well known C idiom:
10794/// https://en.wikipedia.org/wiki/Flexible_array_member.
10795///
10796/// @param klass the class to consider.
10797///
10798/// @return the data member which type is a flexible array, if any, or
10799/// nil.
10802{
10803 var_decl_sptr nil;
10805 if (dms.empty())
10806 return nil;
10807
10808 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
10809 {// The type of the last data member is an array.
10810 if (array->is_non_finite())
10811 // The array has a non-finite size. We are thus looking at a
10812 // flexible array data member. Let's return it.
10813 return dms.back();
10814 }
10815
10816 return nil;
10817}
10818
10819/// Test if the last data member of a class is an array with
10820/// non-finite data member.
10821///
10822/// The flexible data member idiom is a well known C idiom:
10823/// https://en.wikipedia.org/wiki/Flexible_array_member.
10824///
10825/// @param klass the class to consider.
10826///
10827/// @return the data member which type is a flexible array, if any, or
10828/// nil.
10831{
10832 if (!klass)
10833 return var_decl_sptr();
10834
10835 return has_flexible_array_data_member(*klass);
10836}
10837
10838/// Test if the last data member of a class is an array with
10839/// non-finite data member.
10840///
10841/// The flexible data member idiom is a well known C idiom:
10842/// https://en.wikipedia.org/wiki/Flexible_array_member.
10843///
10844/// @param klass the class to consider.
10845///
10846/// @return the data member which type is a flexible array, if any, or
10847/// nil.
10850{return has_flexible_array_data_member(klass.get());}
10851
10852/// Test if the last data member of a class is an array with
10853/// one element.
10854///
10855/// An array with one element is a way to mimic the flexible data
10856/// member idiom that was later standardized in C99.
10857///
10858/// To learn more about the flexible data member idiom, please
10859/// consider reading :
10860/// https://en.wikipedia.org/wiki/Flexible_array_member.
10861///
10862/// The various ways of representing that idiom pre-standardization
10863/// are presented in this article:
10864/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10865///
10866/// @param klass the class to consider.
10867///
10868/// @return the data member which type is a fake flexible array, if
10869/// any, or nil.
10872{
10873 var_decl_sptr nil;
10875 if (dms.empty())
10876 return nil;
10877
10878 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
10879 {// The type of the last data member is an array.
10880 if (array->get_subranges().size() == 1
10881 && array->get_subranges()[0]->get_length() == 1)
10882 // The array has a size of one. We are thus looking at a
10883 // "fake" flexible array data member. Let's return it.
10884 return dms.back();
10885 }
10886
10887 return nil;
10888}
10889
10890/// Test if the last data member of a class is an array with
10891/// one element.
10892///
10893/// An array with one element is a way to mimic the flexible data
10894/// member idiom that was later standardized in C99.
10895///
10896/// To learn more about the flexible data member idiom, please
10897/// consider reading :
10898/// https://en.wikipedia.org/wiki/Flexible_array_member.
10899///
10900/// The various ways of representing that idiom pre-standardization
10901/// are presented in this article:
10902/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10903///
10904/// @param klass the class to consider.
10905///
10906/// @return the data member which type is a fake flexible array, if
10907/// any, or nil.
10911
10912/// Test if the last data member of a class is an array with
10913/// one element.
10914///
10915/// An array with one element is a way to mimic the flexible data
10916/// member idiom that was later standardized in C99.
10917///
10918/// To learn more about the flexible data member idiom, please
10919/// consider reading :
10920/// https://en.wikipedia.org/wiki/Flexible_array_member.
10921///
10922/// The various ways of representing that idiom pre-standardization
10923/// are presented in this article:
10924/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10925///
10926/// @param klass the class to consider.
10927///
10928/// @return the data member which type is a fake flexible array, if
10929/// any, or nil.
10932{return has_fake_flexible_array_data_member(klass.get());}
10933
10934/// Test wheter a type is a declaration-only class.
10935///
10936/// @param t the type to considier.
10937///
10938/// @param look_through_decl_only if true, then look through the
10939/// decl-only class to see if it actually has a class definition in
10940/// the same ABI corpus.
10941///
10942/// @return true iff @p t is a declaration-only class.
10943bool
10946{
10947 if (class_or_union *klass = is_class_or_union_type(t))
10948 {
10950 klass = look_through_decl_only_class(klass);
10951 return klass->get_is_declaration_only();
10952 }
10953 return false;
10954}
10955
10956/// Test wheter a type is a declaration-only class.
10957///
10958/// @param t the type to considier.
10959///
10960/// @param look_through_decl_only if true, then look through the
10961/// decl-only class to see if it actually has a class definition in
10962/// the same ABI corpus.
10963///
10964/// @return true iff @p t is a declaration-only class.
10965bool
10969
10970/// Test wheter a type is a declaration-only class.
10971///
10972/// @param t the type to considier.
10973///
10974/// @param look_through_decl_only if true, then look through the
10975/// decl-only class to see if it actually has a class definition in
10976/// the same ABI corpus.
10977///
10978/// @return true iff @p t is a declaration-only class.
10979bool
10980is_declaration_only_class_type(const type_base_sptr& t,
10983
10984/// Test if a type is a @ref class_or_union.
10985///
10986/// @param t the type to consider.
10987///
10988/// @return the @ref class_or_union is @p is a @ref class_or_union, or
10989/// nil otherwise.
10992{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
10993
10994/// Test if a type is a @ref class_or_union.
10995///
10996/// @param t the type to consider.
10997///
10998/// @return the @ref class_or_union is @p is a @ref class_or_union, or
10999/// nil otherwise.
11000shared_ptr<class_or_union>
11001is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
11002{return dynamic_pointer_cast<class_or_union>(t);}
11003
11004/// Test if two class or union types are of the same kind.
11005///
11006/// @param first the first type to consider.
11007///
11008/// @param second the second type to consider.
11009///
11010/// @return true iff @p first is of the same kind as @p second.
11011bool
11013 const class_or_union* second)
11014{
11015 if ((is_class_type(first) && is_class_type(second))
11016 || (is_union_type(first) && is_union_type(second)))
11017 return true;
11018
11019 return false;
11020}
11021
11022/// Test if two class or union types are of the same kind.
11023///
11024/// @param first the first type to consider.
11025///
11026/// @param second the second type to consider.
11027///
11028/// @return true iff @p first is of the same kind as @p second.
11029bool
11030class_or_union_types_of_same_kind(const class_or_union_sptr& first,
11031 const class_or_union_sptr& second)
11032{return class_or_union_types_of_same_kind(first.get(), second.get());}
11033
11034/// Test if a type is a @ref union_decl.
11035///
11036/// @param t the type to consider.
11037///
11038/// @return true iff @p t is a union_decl.
11039bool
11041{return is_union_type(&t);}
11042
11043/// Test if a type is a @ref union_decl.
11044///
11045/// @param t the type to consider.
11046///
11047/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11048/// otherwise.
11051{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
11052
11053/// Test if a type is a @ref union_decl.
11054///
11055/// @param t the type to consider.
11056///
11057/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11058/// otherwise.
11059union_decl_sptr
11060is_union_type(const shared_ptr<type_or_decl_base>& t)
11061{return dynamic_pointer_cast<union_decl>(t);}
11062
11063/// Test whether a type is a pointer_type_def.
11064///
11065/// @param t the type to test.
11066///
11067/// @param look_through_decl_only if this is true, then look through
11068/// qualified types to see if the underlying type is a
11069/// pointer_type_def.
11070///
11071/// @return the @ref pointer_type_def_sptr if @p t is a
11072/// pointer_type_def, null otherwise.
11073const pointer_type_def*
11075 bool look_through_qualifiers)
11076{
11077 if (!t)
11078 return 0;
11079
11080 const type_base* type = is_type(t);
11081 if (look_through_qualifiers)
11082 type = peel_qualified_type(is_type(t));
11083
11084 return dynamic_cast<pointer_type_def*>(const_cast<type_base*>(type));
11085}
11086
11087/// Test whether a type is a pointer_type_def.
11088///
11089/// @param t the type to test.
11090///
11091/// @param look_through_decl_only if this is true, then look through
11092/// qualified types to see if the underlying type is a
11093/// pointer_type_def.
11094///
11095/// @return the @ref pointer_type_def_sptr if @p t is a
11096/// pointer_type_def, null otherwise.
11099 bool look_through_qualifiers)
11100{
11101 type_base_sptr type = is_type(t);
11102 if (look_through_qualifiers)
11103 type = peel_qualified_type(type);
11104 return dynamic_pointer_cast<pointer_type_def>(type);
11105}
11106
11107/// Test if a type is a pointer to function type.
11108///
11109/// @param t the type to consider.
11110///
11111/// @return the @ref pointer_type_def_sptr iff @p t is a pointer to
11112/// function type.
11114is_pointer_to_function_type(const type_base_sptr& t)
11115{
11117 {
11118 if (is_function_type(p->get_pointed_to_type()))
11119 return p;
11120 }
11121 return pointer_type_def_sptr();
11122}
11123
11124/// Test if a type is a pointer to array type.
11125///
11126/// @param t the type to consider.
11127///
11128/// @return the pointer_type_def_sptr iff @p t is a pointer to array
11129/// type.
11131is_pointer_to_array_type(const type_base_sptr& t)
11132{
11134 {
11135 if (is_array_type(p->get_pointed_to_type()))
11136 return p;
11137 }
11138 return pointer_type_def_sptr();
11139}
11140
11141/// Test if we are looking at a pointer to a
11142/// neither-a-pointer-to-an-array-nor-a-function type.
11143///
11144/// @param t the type to consider.
11145///
11146/// @return the @ref pointer_type_def_sptr type iff @p t is a
11147/// neither-a-pointer-an-array-nor-a-function type.
11149is_pointer_to_npaf_type(const type_base_sptr& t)
11150{
11152 {
11153 if (is_npaf_type(p->get_pointed_to_type()))
11154 return p;
11155 }
11156 return pointer_type_def_sptr();
11157}
11158
11159/// Test if we are looking at a pointer to pointer to member type.
11160///
11161/// @param t the type to consider.
11162///
11163/// @return the @ref pointer_type_def_sptr type iff @p t is a pointer
11164/// to pointer to member type.
11166is_pointer_to_ptr_to_mbr_type(const type_base_sptr& t)
11167{
11169 {
11170 if (is_ptr_to_mbr_type(p->get_pointed_to_type()))
11171 return p;
11172 }
11173 return pointer_type_def_sptr();
11174}
11175
11176/// Test if a type is a typedef, pointer or reference to a decl-only
11177/// class/union.
11178///
11179/// This looks into qualified types too.
11180///
11181/// @param t the type to consider.
11182///
11183/// @return true iff @p t is a type is a typedef, pointer or reference
11184/// to a decl-only class/union.
11185bool
11187{
11188 const type_base * type =
11189 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11190
11192 /*look_through_decl_only=*/true))
11193 return true;
11194
11195 return false;
11196}
11197
11198/// Test if a type is a typedef of a class or union type, or a typedef
11199/// of a qualified class or union type.
11200///
11201/// Note that if the type is directly a class or union type, the
11202/// function returns true as well.
11203///
11204/// @param t the type to consider.
11205///
11206/// @return true iff @p t is a typedef of a class or union type, or a
11207/// typedef of a qualified class or union type.
11208bool
11210{
11211 if (!t)
11212 return false;
11213
11216 return true;
11217
11218return false;
11219}
11220
11221/// Test if a type is a typedef of a class or union type, or a typedef
11222/// of a qualified class or union type.
11223///
11224/// Note that if the type is directly a class or union type, the
11225/// function returns true as well.
11226///
11227/// @param t the type to consider.
11228///
11229/// @return true iff @p t is a typedef of a class or union type, or a
11230/// typedef of a qualified class or union type.
11231bool
11234
11235/// Test whether a type is a reference_type_def.
11236///
11237/// @param t the type to test.
11238///
11239/// @param look_through_decl_only if this is true, then look through
11240/// qualified types to see if the underlying type is a
11241/// reference_type_def.
11242///
11243/// @return the @ref reference_type_def_sptr if @p t is a
11244/// reference_type_def, null otherwise.
11247 bool look_through_qualifiers)
11248{
11249 const type_base* type = is_type(t);
11250 if (!type)
11251 return nullptr;
11252
11253 if (look_through_qualifiers)
11254 type = peel_qualified_type(type);
11255 return dynamic_cast<reference_type_def*>(const_cast<type_base*>(type));
11256}
11257
11258/// Test whether a type is a reference_type_def.
11259///
11260/// @param t the type to test.
11261///
11262/// @param look_through_decl_only if this is true, then look through
11263/// qualified types to see if the underlying type is a
11264/// reference_type_def.
11265///
11266/// @return the @ref reference_type_def_sptr if @p t is a
11267/// reference_type_def, null otherwise.
11268const reference_type_def*
11270 bool look_through_qualifiers)
11271{
11272 const type_base* type = is_type(t);
11273
11274 if (look_through_qualifiers)
11275 type = peel_qualified_type(type);
11276 return dynamic_cast<const reference_type_def*>(type);
11277}
11278
11279/// Test whether a type is a reference_type_def.
11280///
11281/// @param t the type to test.
11282///
11283/// @param look_through_decl_only if this is true, then look through
11284/// qualified types to see if the underlying type is a
11285/// reference_type_def.
11286///
11287/// @return the @ref reference_type_def_sptr if @p t is a
11288/// reference_type_def, null otherwise.
11291 bool look_through_qualifiers)
11292{
11293 type_base_sptr type = is_type(t);
11294 if (look_through_qualifiers)
11295 type = peel_qualified_type(type);
11296 return dynamic_pointer_cast<reference_type_def>(type);
11297}
11298
11299/// Test whether a type is a @ref ptr_to_mbr_type.
11300///
11301/// @param t the type to test.
11302///
11303/// @return the @ref ptr_to_mbr_type* if @p t is a @ref
11304/// ptr_to_mbr_type type, null otherwise.
11305const ptr_to_mbr_type*
11307 bool look_through_qualifiers)
11308{
11309 const type_base* type = is_type(t);
11310 if (look_through_qualifiers)
11311 type = peel_qualified_type(type);
11312 return dynamic_cast<const ptr_to_mbr_type*>(type);
11313}
11314
11315/// Test whether a type is a @ref ptr_to_mbr_type_sptr.
11316///
11317/// @param t the type to test.
11318///
11319/// @param look_through_decl_only if this is true, then look through
11320/// qualified types to see if the underlying type is a
11321/// ptr_to_mbr_type..
11322///
11323/// @return the @ref ptr_to_mbr_type_sptr if @p t is a @ref
11324/// ptr_to_mbr_type type, null otherwise.
11327 bool look_through_qualifiers)
11328{
11329 type_base_sptr type = is_type(t);
11330 if (look_through_qualifiers)
11331 type = peel_qualified_type(type);
11332 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
11333}
11334
11335/// Test if a type is equivalent to a pointer to void type.
11336///
11337/// Note that this looks trough typedefs or CV qualifiers to look for
11338/// the void pointer.
11339///
11340/// @param type the type to consider.
11341///
11342/// @return the actual void pointer if @p is eqivalent to a void
11343/// pointer or NULL if it's not.
11344const type_base*
11346{
11347 type = peel_qualified_or_typedef_type(type);
11348
11349 const pointer_type_def * t = is_pointer_type(type);
11350 if (!t)
11351 return 0;
11352
11353 // Look through typedefs in the pointed-to type as well.
11354 type_base * ty = t->get_pointed_to_type().get();
11356 if (ty && ty->get_environment().is_void_type(ty))
11357 return ty;
11358
11359 return 0;
11360}
11361
11362/// Test if a type is equivalent to a pointer to void type.
11363///
11364/// Note that this looks trough typedefs or CV qualifiers to look for
11365/// the void pointer.
11366///
11367/// @param type the type to consider.
11368///
11369/// @return the actual void pointer if @p is eqivalent to a void
11370/// pointer or NULL if it's not.
11371const type_base*
11373{return is_void_pointer_type_equivalent(&type);}
11374
11375/// Test if a type is a pointer to void type.
11376///
11377/// @param type the type to consider.
11378///
11379/// @return the actual void pointer if @p is a void pointer or NULL if
11380/// it's not.
11381const type_base*
11383{
11384 if (!t)
11385 return nullptr;
11386
11387 if (t->get_environment().get_void_pointer_type().get() == t)
11388 return t;
11389
11390 const pointer_type_def* ptr = is_pointer_type(t);
11391 if (!ptr)
11392 return nullptr;
11393
11395 return t;
11396
11397 return nullptr;
11398}
11399
11400/// Test if a type is a pointer to void type.
11401///
11402/// @param type the type to consider.
11403///
11404/// @return the actual void pointer if @p is a void pointer or NULL if
11405/// it's not.
11406const type_base_sptr
11407is_void_pointer_type(const type_base_sptr& t)
11408{
11409 type_base_sptr nil;
11410 if (!t)
11411 return nil;
11412
11413 if (t->get_environment().get_void_pointer_type().get() == t.get())
11414 return t;
11415
11416 const pointer_type_def* ptr = is_pointer_type(t.get());
11417 if (!ptr)
11418 return nil;
11419
11420 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11421 return t;
11422
11423 return nil;
11424}
11425
11426/// Test whether a type is a reference_type_def.
11427///
11428/// @param t the type to test.
11429///
11430/// @return the @ref reference_type_def_sptr if @p t is a
11431/// reference_type_def, null otherwise.
11434{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11435
11436/// Test whether a type is a qualified_type_def.
11437///
11438/// @param t the type to test.
11439///
11440/// @return the @ref qualified_type_def_sptr if @p t is a
11441/// qualified_type_def, null otherwise.
11442qualified_type_def_sptr
11444{return dynamic_pointer_cast<qualified_type_def>(t);}
11445
11446/// Test whether a type is a function_type.
11447///
11448/// @param t the type to test.
11449///
11450/// @return the @ref function_type_sptr if @p t is a
11451/// function_type, null otherwise.
11454{return dynamic_pointer_cast<function_type>(t);}
11455
11456/// Test whether a type is a function_type.
11457///
11458/// @param t the type to test.
11459///
11460/// @return the @ref function_type_sptr if @p t is a
11461/// function_type, null otherwise.
11464{return dynamic_cast<function_type*>(t);}
11465
11466/// Test whether a type is a function_type.
11467///
11468/// @param t the type to test.
11469///
11470/// @return the @ref function_type_sptr if @p t is a
11471/// function_type, null otherwise.
11472const function_type*
11474{return dynamic_cast<const function_type*>(t);}
11475
11476/// Test whether a type is a method_type.
11477///
11478/// @param t the type to test.
11479///
11480/// @return the @ref method_type_sptr if @p t is a
11481/// method_type, null otherwise.
11484{return dynamic_pointer_cast<method_type>(t);}
11485
11486/// Test whether a type is a method_type.
11487///
11488/// @param t the type to test.
11489///
11490/// @return the @ref method_type_sptr if @p t is a
11491/// method_type, null otherwise.
11492const method_type*
11494{return dynamic_cast<const method_type*>(t);}
11495
11496/// Test whether a type is a method_type.
11497///
11498/// @param t the type to test.
11499///
11500/// @return the @ref method_type_sptr if @p t is a
11501/// method_type, null otherwise.
11504{return dynamic_cast<method_type*>(t);}
11505
11506/// If a class (or union) is a decl-only class, get its definition.
11507/// Otherwise, just return the initial class.
11508///
11509/// @param the_class the class (or union) to consider.
11510///
11511/// @return either the definition of the class, or the class itself.
11515
11516/// If a class (or union) is a decl-only class, get its definition.
11517/// Otherwise, just return the initial class.
11518///
11519/// @param the_class the class (or union) to consider.
11520///
11521/// @return either the definition of the class, or the class itself.
11522class_or_union_sptr
11525
11526/// If a class (or union) is a decl-only class, get its definition.
11527/// Otherwise, just return the initial class.
11528///
11529/// @param klass the class (or union) to consider.
11530///
11531/// @return either the definition of the class, or the class itself.
11532class_or_union_sptr
11533look_through_decl_only_class(class_or_union_sptr klass)
11535
11536/// If an enum is a decl-only enum, get its definition.
11537/// Otherwise, just return the initial enum.
11538///
11539/// @param the_enum the enum to consider.
11540///
11541/// @return either the definition of the enum, or the enum itself.
11544{return is_enum_type(look_through_decl_only(the_enum));}
11545
11546/// If an enum is a decl-only enum, get its definition.
11547/// Otherwise, just return the initial enum.
11548///
11549/// @param enom the enum to consider.
11550///
11551/// @return either the definition of the enum, or the enum itself.
11554{return is_enum_type(look_through_decl_only(enom));}
11555
11556/// If a decl is decl-only get its definition. Otherwise, just return nil.
11557///
11558/// @param d the decl to consider.
11559///
11560/// @return either the definition of the decl, or nil.
11561decl_base_sptr
11563{
11564 decl_base_sptr decl;
11567
11568 if (!decl)
11569 return decl;
11570
11571 while (decl->get_is_declaration_only()
11572 && decl->get_definition_of_declaration())
11573 decl = decl->get_definition_of_declaration();
11574
11575 return decl;
11576}
11577
11578/// If a decl is decl-only enum, get its definition. Otherwise, just
11579/// return the initial decl.
11580///
11581/// @param d the decl to consider.
11582///
11583/// @return either the definition of the enum, or the decl itself.
11584decl_base*
11586{
11587 if (!d)
11588 return d;
11589
11590 decl_base* result = look_through_decl_only(*d).get();
11591 if (!result)
11592 result = d;
11593
11594 return result;
11595}
11596
11597/// If a decl is decl-only get its definition. Otherwise, just return nil.
11598///
11599/// @param d the decl to consider.
11600///
11601/// @return either the definition of the decl, or nil.
11602decl_base_sptr
11603look_through_decl_only(const decl_base_sptr& d)
11604{
11605 if (!d)
11606 return d;
11607
11608 decl_base_sptr result = look_through_decl_only(*d);
11609 if (!result)
11610 result = d;
11611
11612 return result;
11613}
11614
11615/// If a type is is decl-only, then get its definition. Otherwise,
11616/// just return the initial type.
11617///
11618/// @param d the decl to consider.
11619///
11620/// @return either the definition of the decl, or the initial type.
11621type_base*
11623{
11624 decl_base* d = is_decl(t);
11625 if (!d)
11626 return t;
11628 return is_type(d);
11629}
11630
11631/// If a type is is decl-only, then get its definition. Otherwise,
11632/// just return the initial type.
11633///
11634/// @param d the decl to consider.
11635///
11636/// @return either the definition of the decl, or the initial type.
11637type_base_sptr
11638look_through_decl_only_type(const type_base_sptr& t)
11639{
11640 decl_base_sptr d = is_decl(t);
11641 if (!d)
11642 return t;
11644 return is_type(d);
11645}
11646
11647/// Tests if a declaration is a variable declaration.
11648///
11649/// @param decl the decl to test.
11650///
11651/// @return the var_decl_sptr iff decl is a variable declaration; nil
11652/// otherwise.
11653var_decl*
11655{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
11656
11657/// Tests if a declaration is a variable declaration.
11658///
11659/// @param decl the decl to test.
11660///
11661/// @return the var_decl_sptr iff decl is a variable declaration; nil
11662/// otherwise.
11665{return dynamic_pointer_cast<var_decl>(decl);}
11666
11667/// Tests if a declaration is a namespace declaration.
11668///
11669/// @param d the decalration to consider.
11670///
11671/// @return the namespace declaration if @p d is a namespace.
11673is_namespace(const decl_base_sptr& d)
11674{return dynamic_pointer_cast<namespace_decl>(d);}
11675
11676/// Tests if a declaration is a namespace declaration.
11677///
11678/// @param d the decalration to consider.
11679///
11680/// @return the namespace declaration if @p d is a namespace.
11683{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
11684
11685/// Tests whether a decl is a template parameter composition type.
11686///
11687/// @param decl the declaration to consider.
11688///
11689/// @return true iff decl is a template parameter composition type.
11690bool
11691is_template_parm_composition_type(const shared_ptr<decl_base> decl)
11692{
11693 return (decl
11694 && is_at_template_scope(decl)
11695 && is_type(decl)
11696 && !is_template_parameter(decl));
11697}
11698
11699/// Test whether a decl is the pattern of a function template.
11700///
11701/// @param decl the decl to consider.
11702///
11703/// @return true iff decl is the pattern of a function template.
11704bool
11705is_function_template_pattern(const shared_ptr<decl_base> decl)
11706{
11707 return (decl
11708 && dynamic_pointer_cast<function_decl>(decl)
11709 && dynamic_cast<template_decl*>(decl->get_scope()));
11710}
11711
11712/// Test if a type is an array_type_def.
11713///
11714/// @param type the type to consider.
11715///
11716/// @return true iff @p type is an array_type_def.
11719 bool look_through_qualifiers)
11720{
11721 const type_base* t = is_type(type);
11722
11723 if (look_through_qualifiers)
11724 t = peel_qualified_type(t);
11725 return dynamic_cast<array_type_def*>(const_cast<type_base*>(t));
11726}
11727
11728/// Test if a type is an array_type_def.
11729///
11730/// @param type the type to consider.
11731///
11732/// @return true iff @p type is an array_type_def.
11735 bool look_through_qualifiers)
11736{
11737 type_base_sptr t = is_type(type);
11738
11739 if (look_through_qualifiers)
11740 t = peel_qualified_type(t);
11741 return dynamic_pointer_cast<array_type_def>(t);
11742}
11743
11744/// Tests if the element of a given array is a qualified type.
11745///
11746/// @param array the array type to consider.
11747///
11748/// @return the qualified element of the array iff it's a qualified
11749/// type. Otherwise, return a nil object.
11750qualified_type_def_sptr
11752{
11753 if (!array)
11754 return qualified_type_def_sptr();
11755
11756 return is_qualified_type(array->get_element_type());
11757}
11758
11759/// Test if an array type is an array to a qualified element type.
11760///
11761/// @param type the array type to consider.
11762///
11763/// @return true the array @p type iff it's an array to a qualified
11764/// element type.
11766is_array_of_qualified_element(const type_base_sptr& type)
11767{
11768 if (array_type_def_sptr array = is_array_type(type))
11770 return array;
11771
11772 return array_type_def_sptr();
11773}
11774
11775/// Test if a type is a typedef of an array.
11776///
11777/// Note that the function looks through qualified and typedefs types
11778/// of the underlying type of the current typedef. In other words, if
11779/// we are looking at a typedef of a CV-qualified array, or at a
11780/// typedef of a CV-qualified typedef of an array, this function will
11781/// still return TRUE.
11782///
11783/// @param t the type to consider.
11784///
11785/// @return true if t is a typedef which underlying type is an array.
11786/// That array might be either cv-qualified array or a typedef'ed
11787/// array, or a combination of both.
11789is_typedef_of_array(const type_base_sptr& t)
11790{
11791 array_type_def_sptr result;
11792
11793 if (typedef_decl_sptr typdef = is_typedef(t))
11794 {
11795 type_base_sptr u =
11796 peel_qualified_or_typedef_type(typdef->get_underlying_type());
11797 result = is_array_type(u);
11798 }
11799
11800 return result;
11801}
11802
11803/// Test if a type is an array_type_def::subrange_type.
11804///
11805/// @param type the type to consider.
11806///
11807/// @return the array_type_def::subrange_type which @p type is a type
11808/// of, or nil if it's not of that type.
11811{
11812 return dynamic_cast<array_type_def::subrange_type*>
11813 (const_cast<type_or_decl_base*>(type));
11814}
11815
11816/// Test if a type is an array_type_def::subrange_type.
11817///
11818/// @param type the type to consider.
11819///
11820/// @return the array_type_def::subrange_type which @p type is a type
11821/// of, or nil if it's not of that type.
11824{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
11825
11826/// Tests whether a decl is a template.
11827///
11828/// @param decl the decl to consider.
11829///
11830/// @return true iff decl is a function template, class template, or
11831/// template template parameter.
11832bool
11833is_template_decl(const decl_base_sptr& decl)
11834{return decl && dynamic_pointer_cast<template_decl>(decl);}
11835
11836/// This enum describe the kind of entity to lookup, while using the
11837/// lookup API.
11839{
11840 LOOKUP_ENTITY_TYPE,
11841 LOOKUP_ENTITY_VAR,
11842};
11843
11844/// Find the first relevant delimiter (the "::" string) in a fully
11845/// qualified C++ type name, starting from a given position. The
11846/// delimiter returned separates a type name from the name of its
11847/// context.
11848///
11849/// This is supposed to work correctly on names in cases like this:
11850///
11851/// foo<ns1::name1, ns2::name2>
11852///
11853/// In that case when called with with parameter @p begin set to 0, no
11854/// delimiter is returned, because the type name in this case is:
11855/// 'foo<ns1::name1, ns2::name2>'.
11856///
11857/// But in this case:
11858///
11859/// foo<p1, bar::name>::some_type
11860///
11861/// The "::" returned is the one right before 'some_type'.
11862///
11863/// @param fqn the fully qualified name of the type to consider.
11864///
11865/// @param begin the position from which to look for the delimiter.
11866///
11867/// @param delim_pos out parameter. Is set to the position of the
11868/// delimiter iff the function returned true.
11869///
11870/// @return true iff the function found and returned the delimiter.
11871static bool
11872find_next_delim_in_cplus_type(const string& fqn,
11873 size_t begin,
11874 size_t& delim_pos)
11875{
11876 int angle_count = 0;
11877 bool found = false;
11878 size_t i = begin;
11879 for (; i < fqn.size(); ++i)
11880 {
11881 if (fqn[i] == '<')
11882 ++angle_count;
11883 else if (fqn[i] == '>')
11884 --angle_count;
11885 else if (i + 1 < fqn.size()
11886 && !angle_count
11887 && fqn[i] == ':'
11888 && fqn[i+1] == ':')
11889 {
11890 delim_pos = i;
11891 found = true;
11892 break;
11893 }
11894 }
11895 return found;
11896}
11897
11898/// Decompose a fully qualified name into the list of its components.
11899///
11900/// @param fqn the fully qualified name to decompose.
11901///
11902/// @param comps the resulting list of component to fill.
11903void
11904fqn_to_components(const string& fqn,
11905 list<string>& comps)
11906{
11907 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
11908 do
11909 {
11910 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
11911 comp_end = fqn_size;
11912
11913 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
11914 comps.push_back(comp);
11915
11916 comp_begin = comp_end + 2;
11917 if (comp_begin >= fqn_size)
11918 break;
11919 } while (true);
11920}
11921
11922/// Turn a set of qualified name components (that name a type) into a
11923/// qualified name string.
11924///
11925/// @param comps the name components
11926///
11927/// @return the resulting string, which would be the qualified name of
11928/// a type.
11929string
11930components_to_type_name(const list<string>& comps)
11931{
11932 string result;
11933 for (list<string>::const_iterator c = comps.begin();
11934 c != comps.end();
11935 ++c)
11936 if (c == comps.begin())
11937 result = *c;
11938 else
11939 result += "::" + *c;
11940 return result;
11941}
11942
11943/// This predicate returns true if a given container iterator points
11944/// to the last element of the container, false otherwise.
11945///
11946/// @tparam T the type of the container of the iterator.
11947///
11948/// @param container the container the iterator points into.
11949///
11950/// @param i the iterator to consider.
11951///
11952/// @return true iff the iterator points to the last element of @p
11953/// container.
11954template<typename T>
11955static bool
11956iterator_is_last(T& container,
11957 typename T::const_iterator i)
11958{
11959 typename T::const_iterator next = i;
11960 ++next;
11961 return (next == container.end());
11962}
11963
11964//--------------------------------
11965// <type and decls lookup stuff>
11966// ------------------------------
11967
11968/// Lookup all the type*s* that have a given fully qualified name.
11969///
11970/// @param type_name the fully qualified name of the type to
11971/// lookup.
11972///
11973/// @param type_map the map to look into.
11974///
11975/// @return the vector containing the types named @p type_name. If
11976/// the lookup didn't yield any type, then this function returns nil.
11977static const type_base_wptrs_type*
11978lookup_types_in_map(const interned_string& type_name,
11979 const istring_type_base_wptrs_map_type& type_map)
11980{
11981 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
11982 if (i != type_map.end())
11983 return &i->second;
11984 return 0;
11985}
11986
11987/// Lookup a type (with a given name) in a map that associates a type
11988/// name to a type. If there are several types with a given name,
11989/// then try to return the first one that is not decl-only.
11990/// Otherwise, return the last of such types, that is, the last one
11991/// that got registered.
11992///
11993/// @tparam TypeKind the type of the type this function is supposed to
11994/// return.
11995///
11996/// @param type_name the name of the type to lookup.
11997///
11998/// @param type_map the map in which to look.
11999///
12000/// @return a shared_ptr to the type found. If no type was found or
12001/// if the type found was not of type @p TypeKind then the function
12002/// returns nil.
12003template <class TypeKind>
12004static shared_ptr<TypeKind>
12005lookup_type_in_map(const interned_string& type_name,
12006 const istring_type_base_wptrs_map_type& type_map)
12007{
12008 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12009 if (i != type_map.end())
12010 {
12011 // Walk the types that have the name "type_name" and return the
12012 // first one that is not declaration-only ...
12013 for (auto j : i->second)
12014 {
12015 type_base_sptr t(j);
12016 decl_base_sptr d = is_decl(t);
12017 if (d && !d->get_is_declaration_only())
12018 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
12019 }
12020 // ... or return the last type with the name "type_name" that
12021 // was recorded. It's likely to be declaration-only if we
12022 // reached this point.
12023 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
12024 }
12025 return shared_ptr<TypeKind>();
12026}
12027
12028/// Lookup a basic type from a translation unit.
12029///
12030/// This is done by looking the type up in the type map that is
12031/// maintained in the translation unit. So this is as fast as
12032/// possible.
12033///
12034/// @param type_name the name of the basic type to look for.
12035///
12036/// @param tu the translation unit to look into.
12037///
12038/// @return the basic type found or nil if no basic type was found.
12041{
12042 return lookup_type_in_map<type_decl>(type_name,
12043 tu.get_types().basic_types());
12044}
12045
12046/// Lookup a basic type from a translation unit.
12047///
12048/// This is done by looking the type up in the type map that is
12049/// maintained in the translation unit. So this is as fast as
12050/// possible.
12051///
12052/// @param type_name the name of the basic type to look for.
12053///
12054/// @param tu the translation unit to look into.
12055///
12056/// @return the basic type found or nil if no basic type was found.
12058lookup_basic_type(const string& type_name, const translation_unit& tu)
12059{
12060 const environment& env = tu.get_environment();
12061
12062 interned_string s = env.intern(type_name);
12063 return lookup_basic_type(s, tu);
12064}
12065
12066/// Lookup a class type from a translation unit.
12067///
12068/// This is done by looking the type up in the type map that is
12069/// maintained in the translation unit. So this is as fast as
12070/// possible.
12071///
12072/// @param fqn the fully qualified name of the class type node to look
12073/// up.
12074///
12075/// @param tu the translation unit to perform lookup from.
12076///
12077/// @return the declaration of the class type IR node found, NULL
12078/// otherwise.
12080lookup_class_type(const string& fqn, const translation_unit& tu)
12081{
12082 const environment& env = tu.get_environment();
12083 interned_string s = env.intern(fqn);
12084 return lookup_class_type(s, tu);
12085}
12086
12087/// Lookup a class type from a translation unit.
12088///
12089/// This is done by looking the type up in the type map that is
12090/// maintained in the translation unit. So this is as fast as
12091/// possible.
12092///
12093/// @param type_name the name of the class type to look for.
12094///
12095/// @param tu the translation unit to look into.
12096///
12097/// @return the class type found or nil if no class type was found.
12100{
12101 return lookup_type_in_map<class_decl>(type_name,
12102 tu.get_types().class_types());
12103}
12104
12105/// Lookup a union type from a translation unit.
12106///
12107/// This is done by looking the type up in the type map that is
12108/// maintained in the translation unit. So this is as fast as
12109/// possible.
12110///
12111/// @param type_name the name of the union type to look for.
12112///
12113/// @param tu the translation unit to look into.
12114///
12115/// @return the union type found or nil if no union type was found.
12116union_decl_sptr
12118{
12119 return lookup_type_in_map<union_decl>(type_name,
12120 tu.get_types().union_types());
12121}
12122
12123/// Lookup a union type from a translation unit.
12124///
12125/// This is done by looking the type up in the type map that is
12126/// maintained in the translation unit. So this is as fast as
12127/// possible.
12128///
12129/// @param fqn the fully qualified name of the type to lookup.
12130///
12131/// @param tu the translation unit to look into.
12132///
12133/// @return the union type found or nil if no union type was found.
12134union_decl_sptr
12135lookup_union_type(const string& fqn, const translation_unit& tu)
12136{
12137 const environment& env = tu.get_environment();
12138 interned_string s = env.intern(fqn);
12139 return lookup_union_type(s, tu);
12140}
12141
12142/// Lookup a union type in a given corpus, from its location.
12143///
12144/// @param loc the location of the union type to look for.
12145///
12146/// @param corp the corpus to look it from.
12147///
12148/// @return the resulting union_decl.
12149union_decl_sptr
12151{
12154 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
12155
12156 return result;
12157}
12158
12159/// Lookup a union type in a given corpus, from its location.
12160///
12161/// @param loc the location of the union type to look for.
12162///
12163/// @param corp the corpus to look it from.
12164///
12165/// @return the resulting union_decl.
12166union_decl_sptr
12167lookup_union_type_per_location(const string& loc, const corpus& corp)
12168{
12169 const environment& env = corp.get_environment();
12170 return lookup_union_type_per_location(env.intern(loc), corp);
12171}
12172
12173/// Lookup an enum type from a translation unit.
12174///
12175/// This is done by looking the type up in the type map that is
12176/// maintained in the translation unit. So this is as fast as
12177/// possible.
12178///
12179/// @param type_name the name of the enum type to look for.
12180///
12181/// @param tu the translation unit to look into.
12182///
12183/// @return the enum type found or nil if no enum type was found.
12186{
12187 return lookup_type_in_map<enum_type_decl>(type_name,
12188 tu.get_types().enum_types());
12189}
12190
12191/// Lookup an enum type from a translation unit.
12192///
12193/// This is done by looking the type up in the type map that is
12194/// maintained in the translation unit. So this is as fast as
12195/// possible.
12196///
12197/// @param type_name the name of the enum type to look for.
12198///
12199/// @param tu the translation unit to look into.
12200///
12201/// @return the enum type found or nil if no enum type was found.
12203lookup_enum_type(const string& type_name, const translation_unit& tu)
12204{
12205 const environment& env = tu.get_environment();
12206 interned_string s = env.intern(type_name);
12207 return lookup_enum_type(s, tu);
12208}
12209
12210/// Lookup a typedef type from a translation unit.
12211///
12212/// This is done by looking the type up in the type map that is
12213/// maintained in the translation unit. So this is as fast as
12214/// possible.
12215///
12216/// @param type_name the name of the typedef type to look for.
12217///
12218/// @param tu the translation unit to look into.
12219///
12220/// @return the typedef type found or nil if no typedef type was
12221/// found.
12224 const translation_unit& tu)
12225{
12226 return lookup_type_in_map<typedef_decl>(type_name,
12227 tu.get_types().typedef_types());
12228}
12229
12230/// Lookup a typedef type from a translation unit.
12231///
12232/// This is done by looking the type up in the type map that is
12233/// maintained in the translation unit. So this is as fast as
12234/// possible.
12235///
12236/// @param type_name the name of the typedef type to look for.
12237///
12238/// @param tu the translation unit to look into.
12239///
12240/// @return the typedef type found or nil if no typedef type was
12241/// found.
12243lookup_typedef_type(const string& type_name, const translation_unit& tu)
12244{
12245 const environment& env = tu.get_environment();
12246 interned_string s = env.intern(type_name);
12247 return lookup_typedef_type(s, tu);
12248}
12249
12250/// Lookup a qualified type from a translation unit.
12251///
12252/// This is done by looking the type up in the type map that is
12253/// maintained in the translation unit. So this is as fast as
12254/// possible.
12255///
12256/// @param type_name the name of the qualified type to look for.
12257///
12258/// @param tu the translation unit to look into.
12259///
12260/// @return the qualified type found or nil if no qualified type was
12261/// found.
12262qualified_type_def_sptr
12264 const translation_unit& tu)
12265{
12266 const type_maps& m = tu.get_types();
12267 return lookup_type_in_map<qualified_type_def>(type_name,
12268 m.qualified_types());
12269}
12270
12271/// Lookup a qualified type from a translation unit.
12272///
12273/// This is done by looking the type up in the type map that is
12274/// maintained in the translation unit. So this is as fast as
12275/// possible.
12276///
12277/// @param underlying_type the underying type of the qualified type to
12278/// look up.
12279///
12280/// @param quals the CV-qualifiers of the qualified type to look for.
12281///
12282/// @param tu the translation unit to look into.
12283///
12284/// @return the qualified type found or nil if no qualified type was
12285/// found.
12286qualified_type_def_sptr
12287lookup_qualified_type(const type_base_sptr& underlying_type,
12289 const translation_unit& tu)
12290{
12291 interned_string type_name = get_name_of_qualified_type(underlying_type,
12292 quals);
12293 return lookup_qualified_type(type_name, tu);
12294}
12295
12296/// Lookup a pointer type from a translation unit.
12297///
12298/// This is done by looking the type up in the type map that is
12299/// maintained in the translation unit. So this is as fast as
12300/// possible.
12301///
12302/// @param type_name the name of the pointer type to look for.
12303///
12304/// @param tu the translation unit to look into.
12305///
12306/// @return the pointer type found or nil if no pointer type was
12307/// found.
12310 const translation_unit& tu)
12311{
12312 const type_maps& m = tu.get_types();
12313 return lookup_type_in_map<pointer_type_def>(type_name,
12314 m.pointer_types());
12315}
12316
12317/// Lookup a pointer type from a translation unit.
12318///
12319/// This is done by looking the type up in the type map that is
12320/// maintained in the translation unit. So this is as fast as
12321/// possible.
12322///
12323/// @param type_name the name of the pointer type to look for.
12324///
12325/// @param tu the translation unit to look into.
12326///
12327/// @return the pointer type found or nil if no pointer type was
12328/// found.
12330lookup_pointer_type(const string& type_name, const translation_unit& tu)
12331{
12332 const environment& env = tu.get_environment();
12333 interned_string s = env.intern(type_name);
12334 return lookup_pointer_type(s, tu);
12335}
12336
12337/// Lookup a pointer type from a translation unit.
12338///
12339/// This is done by looking the type up in the type map that is
12340/// maintained in the translation unit. So this is as fast as
12341/// possible.
12342///
12343/// @param pointed_to_type the pointed-to-type of the pointer to look for.
12344///
12345/// @param tu the translation unit to look into.
12346///
12347/// @return the pointer type found or nil if no pointer type was
12348/// found.
12350lookup_pointer_type(const type_base_sptr& pointed_to_type,
12351 const translation_unit& tu)
12352{
12353 type_base_sptr t = look_through_decl_only_type(pointed_to_type);
12355 return lookup_pointer_type(type_name, tu);
12356}
12357
12358/// Lookup a reference type from a translation unit.
12359///
12360/// This is done by looking the type up in the type map that is
12361/// maintained in the translation unit. So this is as fast as
12362/// possible.
12363///
12364/// @param type_name the name of the reference type to look for.
12365///
12366/// @param tu the translation unit to look into.
12367///
12368/// @return the reference type found or nil if no reference type was
12369/// found.
12372 const translation_unit& tu)
12373{
12374 const type_maps& m = tu.get_types();
12375 return lookup_type_in_map<reference_type_def>(type_name,
12376 m.reference_types());
12377}
12378
12379/// Lookup a reference type from a translation unit.
12380///
12381/// This is done by looking the type up in the type map that is
12382/// maintained in the translation unit. So this is as fast as
12383/// possible.
12384///
12385/// @param pointed_to_type the pointed-to-type of the reference to
12386/// look up.
12387///
12388/// @param tu the translation unit to look into.
12389///
12390/// @return the reference type found or nil if no reference type was
12391/// found.
12393lookup_reference_type(const type_base_sptr& pointed_to_type,
12394 bool lvalue_reference,
12395 const translation_unit& tu)
12396{
12397 interned_string type_name =
12399 lvalue_reference);
12400 return lookup_reference_type(type_name, tu);
12401}
12402
12403/// Lookup an array type from a translation unit.
12404///
12405/// This is done by looking the type up in the type map that is
12406/// maintained in the translation unit. So this is as fast as
12407/// possible.
12408///
12409/// @param type_name the name of the array type to look for.
12410///
12411/// @param tu the translation unit to look into.
12412///
12413/// @return the array type found or nil if no array type was found.
12416 const translation_unit& tu)
12417{
12418 const type_maps& m = tu.get_types();
12419 return lookup_type_in_map<array_type_def>(type_name,
12420 m.array_types());
12421}
12422
12423/// Lookup a function type from a translation unit.
12424///
12425/// This is done by looking the type up in the type map that is
12426/// maintained in the translation unit. So this is as fast as
12427/// possible.
12428///
12429/// @param type_name the name of the type to lookup.
12430///
12431/// @param tu the translation unit to look into.
12432///
12433/// @return the function type found, or NULL of none was found.
12436 const translation_unit& tu)
12437{
12438 const type_maps& m = tu.get_types();
12439 return lookup_type_in_map<function_type>(type_name,
12440 m.function_types());
12441}
12442
12443/// Lookup a function type from a translation unit.
12444///
12445/// This walks all the function types held by the translation unit and
12446/// compare their sub-type *names*. If the names match then return
12447/// the function type found in the translation unit.
12448///
12449/// @param t the function type to look for.
12450///
12451/// @param tu the translation unit to look into.
12452///
12453/// @return the function type found, or NULL of none was found.
12456 const translation_unit& tu)
12457{
12458 interned_string type_name = get_type_name(t);
12459 return lookup_function_type(type_name, tu);
12460}
12461
12462/// Lookup a function type from a translation unit.
12463///
12464/// This is done by looking the type up in the type map that is
12465/// maintained in the translation unit. So this is as fast as
12466/// possible.
12467///
12468/// @param t the function type to look for.
12469///
12470/// @param tu the translation unit to look into.
12471///
12472/// @return the function type found, or NULL of none was found.
12475 const translation_unit& tu)
12476{return lookup_function_type(*t, tu);}
12477
12478/// Lookup a type in a translation unit.
12479///
12480/// @param fqn the fully qualified name of the type to lookup.
12481///
12482/// @param tu the translation unit to consider.
12483///
12484/// @return the declaration of the type if found, NULL otherwise.
12485const type_base_sptr
12487 const translation_unit& tu)
12488{
12489 type_base_sptr result;
12490 ((result = lookup_typedef_type(fqn, tu))
12491 || (result = lookup_class_type(fqn, tu))
12492 || (result = lookup_union_type(fqn, tu))
12493 || (result = lookup_enum_type(fqn, tu))
12494 || (result = lookup_qualified_type(fqn, tu))
12495 || (result = lookup_pointer_type(fqn, tu))
12496 || (result = lookup_reference_type(fqn, tu))
12497 || (result = lookup_array_type(fqn, tu))
12498 || (result = lookup_function_type(fqn, tu))
12499 || (result = lookup_basic_type(fqn, tu)));
12500
12501 return result;
12502}
12503
12504/// Lookup a type in a translation unit, starting from the global
12505/// namespace.
12506///
12507/// @param fqn the fully qualified name of the type to lookup.
12508///
12509/// @param tu the translation unit to consider.
12510///
12511/// @return the declaration of the type if found, NULL otherwise.
12512type_base_sptr
12513lookup_type(const string& fqn, const translation_unit& tu)
12514{
12515 const environment&env = tu.get_environment();
12516 interned_string ifqn = env.intern(fqn);
12517 return lookup_type(ifqn, tu);
12518}
12519
12520/// Lookup a type from a translation unit.
12521///
12522/// @param fqn the components of the fully qualified name of the node
12523/// to look up.
12524///
12525/// @param tu the translation unit to perform lookup from.
12526///
12527/// @return the declaration of the IR node found, NULL otherwise.
12528const type_base_sptr
12529lookup_type(const type_base_sptr type,
12530 const translation_unit& tu)
12531{
12532 interned_string type_name = get_type_name(type);
12533 return lookup_type(type_name, tu);
12534}
12535
12536/// Lookup a type in a scope.
12537///
12538/// This is really slow as it walks the member types of the scope in
12539/// sequence to find the type with a given name.
12540///
12541/// If possible, users should prefer looking up types from the
12542/// enclosing translation unit or even ABI corpus because both the
12543/// translation unit and the corpus have a map of type, indexed by
12544/// their name. Looking up a type from those maps is thus much
12545/// faster.
12546///
12547/// @param fqn the fully qualified name of the type to lookup.
12548///
12549/// @param skope the scope to look into.
12550///
12551/// @return the declaration of the type if found, NULL otherwise.
12552const type_base_sptr
12553lookup_type_in_scope(const string& fqn,
12554 const scope_decl_sptr& skope)
12555{
12556 list<string> comps;
12557 fqn_to_components(fqn, comps);
12558 return lookup_type_in_scope(comps, skope);
12559}
12560
12561/// Lookup a @ref var_decl in a scope.
12562///
12563/// @param fqn the fuly qualified name of the @var_decl to lookup.
12564///
12565/// @param skope the scope to look into.
12566///
12567/// @return the declaration of the @ref var_decl if found, NULL
12568/// otherwise.
12569const decl_base_sptr
12571 const scope_decl_sptr& skope)
12572{
12573 list<string> comps;
12574 fqn_to_components(fqn, comps);
12575 return lookup_var_decl_in_scope(comps, skope);
12576}
12577
12578/// A generic function (template) to get the name of a node, whatever
12579/// node it is. This has to be specialized for the kind of node we
12580/// want.
12581///
12582/// Note that a node is a member of a scope.
12583///
12584/// @tparam NodeKind the kind of node to consider.
12585///
12586/// @param node the node to get the name from.
12587///
12588/// @return the name of the node.
12589template<typename NodeKind>
12590static const interned_string&
12591get_node_name(shared_ptr<NodeKind> node);
12592
12593/// Gets the name of a class_decl node.
12594///
12595/// @param node the decl_base node to get the name from.
12596///
12597/// @return the name of the node.
12598template<>
12599const interned_string&
12601{return node->get_name();}
12602
12603/// Gets the name of a type_base node.
12604///
12605/// @param node the type_base node to get the name from.
12606///
12607/// @return the name of the node.
12608template<>
12609const interned_string&
12610get_node_name(type_base_sptr node)
12611{return get_type_declaration(node)->get_name();}
12612
12613/// Gets the name of a var_decl node.
12614///
12615/// @param node the var_decl node to get the name from.
12616///
12617/// @return the name of the node.
12618template<>
12619const interned_string&
12621{return node->get_name();}
12622
12623/// Generic function to get the declaration of a given node, whatever
12624/// it is. There has to be specializations for the kind of the nodes
12625/// we want to support.
12626///
12627/// @tparam NodeKind the type of the node we are looking at.
12628///
12629/// @return the declaration.
12630template<typename NodeKind>
12631static decl_base_sptr
12632convert_node_to_decl(shared_ptr<NodeKind> node);
12633
12634/// Lookup a node in a given scope.
12635///
12636/// @tparam the type of the node to lookup.
12637///
12638/// @param fqn the components of the fully qualified name of the node
12639/// to lookup.
12640///
12641/// @param skope the scope to look into.
12642///
12643/// @return the declaration of the looked up node, or NULL if it
12644/// wasn't found.
12645template<typename NodeKind>
12646static const type_or_decl_base_sptr
12647lookup_node_in_scope(const list<string>& fqn,
12648 const scope_decl_sptr& skope)
12649{
12650 type_or_decl_base_sptr resulting_decl;
12651 shared_ptr<NodeKind> node;
12652 bool it_is_last = false;
12653 scope_decl_sptr cur_scope = skope, new_scope, scope;
12654
12655 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
12656 {
12657 new_scope.reset();
12658 it_is_last = iterator_is_last(fqn, c);
12659 for (scope_decl::declarations::const_iterator m =
12660 cur_scope->get_member_decls().begin();
12661 m != cur_scope->get_member_decls().end();
12662 ++m)
12663 {
12664 if (!it_is_last)
12665 {
12666 // looking for a scope
12667 scope = dynamic_pointer_cast<scope_decl>(*m);
12668 if (scope && scope->get_name() == *c)
12669 {
12670 new_scope = scope;
12671 break;
12672 }
12673 }
12674 else
12675 {
12676 //looking for a final type.
12677 node = dynamic_pointer_cast<NodeKind>(*m);
12678 if (node && get_node_name(node) == *c)
12679 {
12680 if (class_decl_sptr cl =
12681 dynamic_pointer_cast<class_decl>(node))
12682 if (cl->get_is_declaration_only()
12683 && !cl->get_definition_of_declaration())
12684 continue;
12685 resulting_decl = node;
12686 break;
12687 }
12688 }
12689 }
12690 if (!new_scope && !resulting_decl)
12691 return decl_base_sptr();
12692 cur_scope = new_scope;
12693 }
12694 ABG_ASSERT(resulting_decl);
12695 return resulting_decl;
12696}
12697
12698/// lookup a type in a scope.
12699///
12700///
12701/// This is really slow as it walks the member types of the scope in
12702/// sequence to find the type with a given name.
12703///
12704/// If possible, users should prefer looking up types from the
12705/// enclosing translation unit or even ABI corpus because both the
12706/// translation unit and the corpus have a map of type, indexed by
12707/// their name. Looking up a type from those maps is thus much
12708/// faster.
12709///
12710/// @param comps the components of the fully qualified name of the
12711/// type to lookup.
12712///
12713/// @param skope the scope to look into.
12714///
12715/// @return the declaration of the type found.
12716const type_base_sptr
12717lookup_type_in_scope(const list<string>& comps,
12718 const scope_decl_sptr& scope)
12719{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
12720
12721/// lookup a type in a scope.
12722///
12723/// This is really slow as it walks the member types of the scope in
12724/// sequence to find the type with a given name.
12725///
12726/// If possible, users should prefer looking up types from the
12727/// enclosing translation unit or even ABI corpus because both the
12728/// translation unit and the corpus have a map of type, indexed by
12729/// their name. Looking up a type from those maps is thus much
12730/// faster.
12731///
12732/// @param type the type to look for.
12733///
12734/// @param access_path a vector of scopes the path of scopes to follow
12735/// before reaching the scope into which to look for @p type. Note
12736/// that the deepest scope (the one immediately containing @p type) is
12737/// at index 0 of this vector, and the top-most scope is the last
12738/// element of the vector.
12739///
12740/// @param scope the top-most scope into which to look for @p type.
12741///
12742/// @return the scope found in @p scope, or NULL if it wasn't found.
12743static const type_base_sptr
12745 const vector<scope_decl*>& access_path,
12746 const scope_decl* scope)
12747{
12748 vector<scope_decl*> a = access_path;
12749 type_base_sptr result;
12750
12751 scope_decl* first_scope = 0;
12752 if (!a.empty())
12753 {
12754 first_scope = a.back();
12755 ABG_ASSERT(first_scope->get_name() == scope->get_name());
12756 a.pop_back();
12757 }
12758
12759 if (a.empty())
12760 {
12761 interned_string n = get_type_name(type, false);
12762 for (scope_decl::declarations::const_iterator i =
12763 scope->get_member_decls().begin();
12764 i != scope->get_member_decls().end();
12765 ++i)
12766 if (is_type(*i) && (*i)->get_name() == n)
12767 {
12768 result = is_type(*i);
12769 break;
12770 }
12771 }
12772 else
12773 {
12774 first_scope = a.back();
12775 interned_string scope_name, cur_scope_name = first_scope->get_name();
12776 for (scope_decl::scopes::const_iterator i =
12777 scope->get_member_scopes().begin();
12778 i != scope->get_member_scopes().end();
12779 ++i)
12780 {
12781 scope_name = (*i)->get_name();
12782 if (scope_name == cur_scope_name)
12783 {
12784 result = lookup_type_in_scope(type, a, (*i).get());
12785 break;
12786 }
12787 }
12788 }
12789 return result;
12790}
12791
12792/// lookup a type in a scope.
12793///
12794/// This is really slow as it walks the member types of the scope in
12795/// sequence to find the type with a given name.
12796///
12797/// If possible, users should prefer looking up types from the
12798/// enclosing translation unit or even ABI corpus because both the
12799/// translation unit and the corpus have a map of type, indexed by
12800/// their name. Looking up a type from those maps is thus much
12801/// faster.
12802///
12803/// @param type the type to look for.
12804///
12805/// @param scope the top-most scope into which to look for @p type.
12806///
12807/// @return the scope found in @p scope, or NULL if it wasn't found.
12808static const type_base_sptr
12809lookup_type_in_scope(const type_base_sptr type,
12810 const scope_decl* scope)
12811{
12812 if (!type || is_function_type(type))
12813 return type_base_sptr();
12814
12815 decl_base_sptr type_decl = get_type_declaration(type);
12816 ABG_ASSERT(type_decl);
12817 vector<scope_decl*> access_path;
12818 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
12819 {
12820 access_path.push_back(s);
12821 if (is_global_scope(s))
12822 break;
12823 }
12824 return lookup_type_in_scope(*type, access_path, scope);
12825}
12826
12827/// Lookup a type from a translation unit by walking the scopes of the
12828/// translation unit in sequence and looking into them.
12829///
12830/// This is really slow as it walks the member types of the scopes in
12831/// sequence to find the type with a given name.
12832///
12833/// If possible, users should prefer looking up types from the
12834/// translation unit or even ABI corpus in a more direct way, by using
12835/// the lookup_type() functins.
12836///
12837///
12838/// This is because both the translation unit and the corpus have a
12839/// map of types, indexed by their name. Looking up a type from those
12840/// maps is thus much faster. @param fqn the components of the fully
12841/// qualified name of the node to look up.
12842///
12843/// @param tu the translation unit to perform lookup from.
12844///
12845/// @return the declaration of the IR node found, NULL otherwise.
12846const type_base_sptr
12847lookup_type_through_scopes(const type_base_sptr type,
12848 const translation_unit& tu)
12849{
12850 if (function_type_sptr fn_type = is_function_type(type))
12851 return lookup_function_type(fn_type, tu);
12852 return lookup_type_in_scope(type, tu.get_global_scope().get());
12853}
12854
12855/// lookup a var_decl in a scope.
12856///
12857/// @param comps the components of the fully qualified name of the
12858/// var_decl to lookup.
12859///
12860/// @param skope the scope to look into.
12861const decl_base_sptr
12862lookup_var_decl_in_scope(const std::list<string>& comps,
12863 const scope_decl_sptr& skope)
12864{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
12865
12866/// Lookup an IR node from a translation unit.
12867///
12868/// @tparam NodeKind the type of the IR node to lookup from the
12869/// translation unit.
12870///
12871/// @param fqn the components of the fully qualified name of the node
12872/// to look up.
12873///
12874/// @param tu the translation unit to perform lookup from.
12875///
12876/// @return the declaration of the IR node found, NULL otherwise.
12877template<typename NodeKind>
12878static const type_or_decl_base_sptr
12879lookup_node_in_translation_unit(const list<string>& fqn,
12880 const translation_unit& tu)
12881{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
12882
12883/// Lookup a type from a translation unit by walking its scopes in
12884/// sequence and by looking into them.
12885///
12886/// This is much slower than using the lookup_type() function.
12887///
12888/// @param fqn the components of the fully qualified name of the node
12889/// to look up.
12890///
12891/// @param tu the translation unit to perform lookup from.
12892///
12893/// @return the declaration of the IR node found, NULL otherwise.
12894type_base_sptr
12895lookup_type_through_scopes(const list<string>& fqn,
12896 const translation_unit& tu)
12897{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
12898
12899
12900/// Lookup a class type from a translation unit by walking its scopes
12901/// in sequence and by looking into them.
12902///
12903/// This is much slower than using the lookup_class_type() function
12904/// because it walks all the scopes of the translation unit in
12905/// sequence and lookup the types to find one that has a given name.
12906///
12907/// @param fqn the components of the fully qualified name of the class
12908/// type node to look up.
12909///
12910/// @param tu the translation unit to perform lookup from.
12911///
12912/// @return the declaration of the class type IR node found, NULL
12913/// otherwise.
12915lookup_class_type_through_scopes(const list<string>& fqn,
12916 const translation_unit& tu)
12917{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
12918
12919/// Lookup a basic type from all the translation units of a given
12920/// corpus.
12921///
12922/// @param fqn the components of the fully qualified name of the basic
12923/// type node to look up.
12924///
12925/// @param tu the translation unit to perform lookup from.
12926///
12927/// @return the declaration of the basic type IR node found, NULL
12928/// otherwise.
12929static type_decl_sptr
12930lookup_basic_type_through_translation_units(const interned_string& type_name,
12931 const corpus& abi_corpus)
12932{
12933 type_decl_sptr result;
12934
12935 for (translation_units::const_iterator tu =
12936 abi_corpus.get_translation_units().begin();
12937 tu != abi_corpus.get_translation_units().end();
12938 ++tu)
12939 if ((result = lookup_basic_type(type_name, **tu)))
12940 break;
12941
12942 return result;
12943}
12944
12945/// Lookup a union type from all the translation units of a given
12946/// corpus.
12947///
12948/// @param fqn the components of the fully qualified name of the union
12949/// type node to look up.
12950///
12951/// @param tu the translation unit to perform lookup from.
12952///
12953/// @return the declaration of the union type IR node found, NULL
12954/// otherwise.
12955static union_decl_sptr
12956lookup_union_type_through_translation_units(const interned_string& type_name,
12957 const corpus & abi_corpus)
12958{
12959 union_decl_sptr result;
12960
12961 for (translation_units::const_iterator tu =
12962 abi_corpus.get_translation_units().begin();
12963 tu != abi_corpus.get_translation_units().end();
12964 ++tu)
12965 if ((result = lookup_union_type(type_name, **tu)))
12966 break;
12967
12968 return result;
12969}
12970
12971/// Lookup an enum type from all the translation units of a given
12972/// corpus.
12973///
12974/// @param fqn the components of the fully qualified name of the enum
12975/// type node to look up.
12976///
12977/// @param tu the translation unit to perform lookup from.
12978///
12979/// @return the declaration of the enum type IR node found, NULL
12980/// otherwise.
12982lookup_enum_type_through_translation_units(const interned_string& type_name,
12983 const corpus & abi_corpus)
12984{
12985 enum_type_decl_sptr result;
12986
12987 for (translation_units::const_iterator tu =
12988 abi_corpus.get_translation_units().begin();
12989 tu != abi_corpus.get_translation_units().end();
12990 ++tu)
12991 if ((result = lookup_enum_type(type_name, **tu)))
12992 break;
12993
12994 return result;
12995}
12996
12997/// Lookup a typedef type definition in all the translation units of a
12998/// given ABI corpus.
12999///
13000/// @param @param qn the fully qualified name of the typedef type to lookup.
13001///
13002/// @param abi_corpus the ABI corpus which to look the type up in.
13003///
13004/// @return the type definition if any was found, or a NULL pointer.
13005static typedef_decl_sptr
13006lookup_typedef_type_through_translation_units(const interned_string& type_name,
13007 const corpus & abi_corpus)
13008{
13009 typedef_decl_sptr result;
13010
13011 for (translation_units::const_iterator tu =
13012 abi_corpus.get_translation_units().begin();
13013 tu != abi_corpus.get_translation_units().end();
13014 ++tu)
13015 if ((result = lookup_typedef_type(type_name, **tu)))
13016 break;
13017
13018 return result;
13019}
13020
13021/// Lookup a qualified type definition in all the translation units of a
13022/// given ABI corpus.
13023///
13024/// @param @param qn the fully qualified name of the qualified type to
13025/// lookup.
13026///
13027/// @param abi_corpus the ABI corpus which to look the type up in.
13028///
13029/// @return the type definition if any was found, or a NULL pointer.
13030static qualified_type_def_sptr
13031lookup_qualified_type_through_translation_units(const interned_string& t_name,
13032 const corpus & abi_corpus)
13033{
13034 qualified_type_def_sptr result;
13035
13036 for (translation_units::const_iterator tu =
13037 abi_corpus.get_translation_units().begin();
13038 tu != abi_corpus.get_translation_units().end();
13039 ++tu)
13040 if ((result = lookup_qualified_type(t_name, **tu)))
13041 break;
13042
13043 return result;
13044}
13045
13046/// Lookup a pointer type definition in all the translation units of a
13047/// given ABI corpus.
13048///
13049/// @param @param qn the fully qualified name of the pointer type to
13050/// lookup.
13051///
13052/// @param abi_corpus the ABI corpus which to look the type up in.
13053///
13054/// @return the type definition if any was found, or a NULL pointer.
13056lookup_pointer_type_through_translation_units(const interned_string& type_name,
13057 const corpus & abi_corpus)
13058{
13059 pointer_type_def_sptr result;
13060
13061 for (translation_units::const_iterator tu =
13062 abi_corpus.get_translation_units().begin();
13063 tu != abi_corpus.get_translation_units().end();
13064 ++tu)
13065 if ((result = lookup_pointer_type(type_name, **tu)))
13066 break;
13067
13068 return result;
13069}
13070
13071/// Lookup a reference type definition in all the translation units of a
13072/// given ABI corpus.
13073///
13074/// @param @param qn the fully qualified name of the reference type to
13075/// lookup.
13076///
13077/// @param abi_corpus the ABI corpus which to look the type up in.
13078///
13079/// @return the type definition if any was found, or a NULL pointer.
13081lookup_reference_type_through_translation_units(const interned_string& t_name,
13082 const corpus & abi_corpus)
13083{
13085
13086 for (translation_units::const_iterator tu =
13087 abi_corpus.get_translation_units().begin();
13088 tu != abi_corpus.get_translation_units().end();
13089 ++tu)
13090 if ((result = lookup_reference_type(t_name, **tu)))
13091 break;
13092
13093 return result;
13094}
13095
13096/// Lookup a array type definition in all the translation units of a
13097/// given ABI corpus.
13098///
13099/// @param @param qn the fully qualified name of the array type to
13100/// lookup.
13101///
13102/// @param abi_corpus the ABI corpus which to look the type up in.
13103///
13104/// @return the type definition if any was found, or a NULL pointer.
13106lookup_array_type_through_translation_units(const interned_string& type_name,
13107 const corpus & abi_corpus)
13108{
13109 array_type_def_sptr result;
13110
13111 for (translation_units::const_iterator tu =
13112 abi_corpus.get_translation_units().begin();
13113 tu != abi_corpus.get_translation_units().end();
13114 ++tu)
13115 if ((result = lookup_array_type(type_name, **tu)))
13116 break;
13117
13118 return result;
13119}
13120
13121/// Lookup a function type definition in all the translation units of
13122/// a given ABI corpus.
13123///
13124/// @param @param qn the fully qualified name of the function type to
13125/// lookup.
13126///
13127/// @param abi_corpus the ABI corpus which to look the type up in.
13128///
13129/// @return the type definition if any was found, or a NULL pointer.
13130static function_type_sptr
13131lookup_function_type_through_translation_units(const interned_string& type_name,
13132 const corpus & abi_corpus)
13133{
13134 function_type_sptr result;
13135
13136 for (translation_units::const_iterator tu =
13137 abi_corpus.get_translation_units().begin();
13138 tu != abi_corpus.get_translation_units().end();
13139 ++tu)
13140 if ((result = lookup_function_type(type_name, **tu)))
13141 break;
13142
13143 return result;
13144}
13145
13146/// Lookup a type definition in all the translation units of a given
13147/// ABI corpus.
13148///
13149/// @param @param qn the fully qualified name of the type to lookup.
13150///
13151/// @param abi_corpus the ABI corpus which to look the type up in.
13152///
13153/// @return the type definition if any was found, or a NULL pointer.
13154type_base_sptr
13156 const corpus& abi_corpus)
13157{
13158 type_base_sptr result;
13159
13160 for (translation_units::const_iterator tu =
13161 abi_corpus.get_translation_units().begin();
13162 tu != abi_corpus.get_translation_units().end();
13163 ++tu)
13164 if ((result = lookup_type(qn, **tu)))
13165 break;
13166
13167 return result;
13168}
13169
13170/// Lookup a type from a given translation unit present in a give corpus.
13171///
13172/// @param type_name the name of the type to look for.
13173///
13174/// @parm tu_path the path of the translation unit to consider.
13175///
13176/// @param corp the corpus to consider.
13177///
13178/// @return the resulting type, if any.
13179type_base_sptr
13181 const string& tu_path,
13182 const corpus& corp)
13183{
13184 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
13185 if (i == corp.priv_->path_tu_map.end())
13186 return type_base_sptr();
13187
13188 translation_unit_sptr tu = i->second;
13189 ABG_ASSERT(tu);
13190
13191 type_base_sptr t = lookup_type(type_name, *tu);
13192 return t;
13193}
13194
13195/// Look into an ABI corpus for a function type.
13196///
13197/// @param fn_type the function type to be looked for in the ABI
13198/// corpus.
13199///
13200/// @param corpus the ABI corpus into which to look for the function
13201/// type.
13202///
13203/// @return the function type found in the corpus.
13206 const corpus& corpus)
13207{
13208 ABG_ASSERT(fn_t);
13209
13210 function_type_sptr result;
13211
13212 if ((result = lookup_function_type(fn_t, corpus)))
13213 return result;
13214
13215 for (translation_units::const_iterator i =
13216 corpus.get_translation_units().begin();
13217 i != corpus.get_translation_units().end();
13218 ++i)
13220 **i)))
13221 return result;
13222
13223 return result;
13224}
13225
13226/// Look into a given corpus to find a type which has the same
13227/// qualified name as a giventype.
13228///
13229/// If the per-corpus type map is non-empty (because the corpus allows
13230/// the One Definition Rule) then the type islooked up in that
13231/// per-corpus type map. Otherwise, the type is looked-up in each
13232/// translation unit.
13233///
13234/// @param t the type which has the same qualified name as the type we
13235/// are looking for.
13236///
13237/// @param corp the ABI corpus to look into for the type.
13239lookup_basic_type(const type_decl& t, const corpus& corp)
13240{return lookup_basic_type(t.get_name(), corp);}
13241
13242/// Look into a given corpus to find a basic type which has a given
13243/// qualified name.
13244///
13245/// If the per-corpus type map is non-empty (because the corpus allows
13246/// the One Definition Rule) then the type islooked up in that
13247/// per-corpus type map. Otherwise, the type is looked-up in each
13248/// translation unit.
13249///
13250/// @param qualified_name the qualified name of the basic type to look
13251/// for.
13252///
13253/// @param corp the corpus to look into.
13255lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
13256{
13258 type_decl_sptr result;
13259
13260 if (!m.empty())
13261 result = lookup_type_in_map<type_decl>(qualified_name, m);
13262 else
13263 result = lookup_basic_type_through_translation_units(qualified_name, corp);
13264
13265 return result;
13266}
13267
13268/// Lookup a @ref type_decl type from a given corpus, by its location.
13269///
13270/// @param loc the location to consider.
13271///
13272/// @param corp the corpus to consider.
13273///
13274/// @return the resulting basic type, if any.
13277 const corpus &corp)
13278{
13281 type_decl_sptr result;
13282
13283 result = lookup_type_in_map<type_decl>(loc, m);
13284
13285 return result;
13286}
13287
13288/// Lookup a @ref type_decl type from a given corpus, by its location.
13289///
13290/// @param loc the location to consider.
13291///
13292/// @param corp the corpus to consider.
13293///
13294/// @return the resulting basic type, if any.
13296lookup_basic_type_per_location(const string &loc, const corpus &corp)
13297{
13298 const environment& env = corp.get_environment();
13299 return lookup_basic_type_per_location(env.intern(loc), corp);
13300}
13301
13302/// Look into a given corpus to find a basic type which has a given
13303/// qualified name.
13304///
13305/// If the per-corpus type map is non-empty (because the corpus allows
13306/// the One Definition Rule) then the type islooked up in that
13307/// per-corpus type map. Otherwise, the type is looked-up in each
13308/// translation unit.
13309///
13310/// @param qualified_name the qualified name of the basic type to look
13311/// for.
13312///
13313/// @param corp the corpus to look into.
13315lookup_basic_type(const string& qualified_name, const corpus& corp)
13316{
13317 return lookup_basic_type(corp.get_environment().intern(qualified_name),
13318 corp);
13319}
13320
13321/// Look into a given corpus to find a class type which has the same
13322/// qualified name as a given type.
13323///
13324/// If the per-corpus type map is non-empty (because the corpus allows
13325/// the One Definition Rule) then the type islooked up in that
13326/// per-corpus type map. Otherwise, the type is looked-up in each
13327/// translation unit.
13328///
13329/// @param t the class decl type which has the same qualified name as
13330/// the type we are looking for.
13331///
13332/// @param corp the corpus to look into.
13335{
13337 return lookup_class_type(s, corp);
13338}
13339
13340/// Look into a given corpus to find a class type which has a given
13341/// qualified name.
13342///
13343/// If the per-corpus type map is non-empty (because the corpus allows
13344/// the One Definition Rule) then the type islooked up in that
13345/// per-corpus type map. Otherwise, the type is looked-up in each
13346/// translation unit.
13347///
13348/// @param qualified_name the qualified name of the type to look for.
13349///
13350/// @param corp the corpus to look into.
13352lookup_class_type(const string& qualified_name, const corpus& corp)
13353{
13354 interned_string s = corp.get_environment().intern(qualified_name);
13355 return lookup_class_type(s, corp);
13356}
13357
13358/// Look into a given corpus to find a class type which has a given
13359/// qualified name.
13360///
13361/// If the per-corpus type map is non-empty (because the corpus allows
13362/// the One Definition Rule) then the type islooked up in that
13363/// per-corpus type map. Otherwise, the type is looked-up in each
13364/// translation unit.
13365///
13366/// @param qualified_name the qualified name of the type to look for.
13367///
13368/// @param corp the corpus to look into.
13370lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13371{
13373
13374 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13375
13376 return result;
13377}
13378
13379/// Look into a given corpus to find the class type*s* that have a
13380/// given qualified name.
13381///
13382/// @param qualified_name the qualified name of the type to look for.
13383///
13384/// @param corp the corpus to look into.
13385///
13386/// @return the vector of class types named @p qualified_name.
13388lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13389{
13391
13392 return lookup_types_in_map(qualified_name, m);
13393}
13394
13395/// Look into a given corpus to find the class type*s* that have a
13396/// given qualified name and that are declaration-only.
13397///
13398/// @param qualified_name the qualified name of the type to look for.
13399///
13400/// @param corp the corpus to look into.
13401///
13402/// @param result the vector of decl-only class types named @p
13403/// qualified_name. This is populated iff the function returns true.
13404///
13405/// @return true iff @p result was populated with the decl-only
13406/// classes named @p qualified_name.
13407bool
13409 const corpus& corp,
13410 type_base_wptrs_type& result)
13411{
13413
13414 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13415 if (!v)
13416 return false;
13417
13418 for (auto type : *v)
13419 {
13420 type_base_sptr t(type);
13422 if (c->get_is_declaration_only()
13423 && !c->get_definition_of_declaration())
13424 result.push_back(type);
13425 }
13426
13427 return !result.empty();
13428}
13429
13430/// Look into a given corpus to find the union type*s* that have a
13431/// given qualified name.
13432///
13433/// @param qualified_name the qualified name of the type to look for.
13434///
13435/// @param corp the corpus to look into.
13436///
13437/// @return the vector of union types named @p qualified_name.
13439lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13440{
13442
13443 return lookup_types_in_map(qualified_name, m);
13444}
13445
13446/// Look into a given corpus to find the class type*s* that have a
13447/// given qualified name.
13448///
13449/// @param qualified_name the qualified name of the type to look for.
13450///
13451/// @param corp the corpus to look into.
13452///
13453/// @return the vector of class types which name is @p qualified_name.
13455lookup_class_types(const string& qualified_name, const corpus& corp)
13456{
13457 interned_string s = corp.get_environment().intern(qualified_name);
13458 return lookup_class_types(s, corp);
13459}
13460
13461/// Look into a given corpus to find the union types that have a given
13462/// qualified name.
13463///
13464/// @param qualified_name the qualified name of the type to look for.
13465///
13466/// @param corp the corpus to look into.
13467///
13468/// @return the vector of union types which name is @p qualified_name.
13470lookup_union_types(const string& qualified_name, const corpus& corp)
13471{
13472 interned_string s = corp.get_environment().intern(qualified_name);
13473 return lookup_union_types(s, corp);
13474}
13475
13476/// Look up a @ref class_decl from a given corpus by its location.
13477///
13478/// @param loc the location to consider.
13479///
13480/// @param corp the corpus to consider.
13481///
13482/// @return the resulting class decl, if any.
13485 const corpus& corp)
13486{
13489 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13490
13491 return result;
13492}
13493
13494/// Look up a @ref class_decl from a given corpus by its location.
13495///
13496/// @param loc the location to consider.
13497///
13498/// @param corp the corpus to consider.
13499///
13500/// @return the resulting class decl, if any.
13502lookup_class_type_per_location(const string &loc, const corpus &corp)
13503{
13504 const environment& env = corp.get_environment();
13505 return lookup_class_type_per_location(env.intern(loc), corp);
13506}
13507
13508/// Look into a given corpus to find a union type which has a given
13509/// qualified name.
13510///
13511/// If the per-corpus type map is non-empty (because the corpus allows
13512/// the One Definition Rule) then the type islooked up in that
13513/// per-corpus type map. Otherwise, the type is looked-up in each
13514/// translation unit.
13515///
13516/// @param qualified_name the qualified name of the type to look for.
13517///
13518/// @param corp the corpus to look into.
13519union_decl_sptr
13520lookup_union_type(const interned_string& type_name, const corpus& corp)
13521{
13523
13524 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13525 if (!result)
13526 result = lookup_union_type_through_translation_units(type_name, corp);
13527
13528 return result;
13529}
13530
13531/// Look into a given corpus to find a union type which has a given
13532/// qualified name.
13533///
13534/// If the per-corpus type map is non-empty (because the corpus allows
13535/// the One Definition Rule) then the type islooked up in that
13536/// per-corpus type map. Otherwise, the type is looked-up in each
13537/// translation unit.
13538///
13539/// @param qualified_name the qualified name of the type to look for.
13540///
13541/// @param corp the corpus to look into.
13542union_decl_sptr
13543lookup_union_type(const string& type_name, const corpus& corp)
13544{
13545 interned_string s = corp.get_environment().intern(type_name);
13546 return lookup_union_type(s, corp);
13547}
13548
13549/// Look into a given corpus to find an enum type which has the same
13550/// qualified name as a given enum type.
13551///
13552/// If the per-corpus type map is non-empty (because the corpus allows
13553/// the One Definition Rule) then the type islooked up in that
13554/// per-corpus type map. Otherwise, the type is looked-up in each
13555/// translation unit.
13556///
13557/// @param t the enum type which has the same qualified name as the
13558/// type we are looking for.
13559///
13560/// @param corp the corpus to look into.
13563{
13565 return lookup_enum_type(s, corp);
13566}
13567
13568/// Look into a given corpus to find an enum type which has a given
13569/// qualified name.
13570///
13571/// If the per-corpus type map is non-empty (because the corpus allows
13572/// the One Definition Rule) then the type islooked up in that
13573/// per-corpus type map. Otherwise, the type is looked-up in each
13574/// translation unit.
13575///
13576/// @param qualified_name the qualified name of the enum type to look
13577/// for.
13578///
13579/// @param corp the corpus to look into.
13581lookup_enum_type(const string& qualified_name, const corpus& corp)
13582{
13583 interned_string s = corp.get_environment().intern(qualified_name);
13584 return lookup_enum_type(s, corp);
13585}
13586
13587/// Look into a given corpus to find an enum type which has a given
13588/// qualified name.
13589///
13590/// If the per-corpus type map is non-empty (because the corpus allows
13591/// the One Definition Rule) then the type islooked up in that
13592/// per-corpus type map. Otherwise, the type is looked-up in each
13593/// translation unit.
13594///
13595/// @param qualified_name the qualified name of the enum type to look
13596/// for.
13597///
13598/// @param corp the corpus to look into.
13600lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
13601{
13603
13604 enum_type_decl_sptr result =
13605 lookup_type_in_map<enum_type_decl>(qualified_name, m);
13606 if (!result)
13607 result = lookup_enum_type_through_translation_units(qualified_name, corp);
13608
13609 return result;
13610}
13611
13612/// Look into a given corpus to find the enum type*s* that have a
13613/// given qualified name.
13614///
13615/// @param qualified_name the qualified name of the type to look for.
13616///
13617/// @param corp the corpus to look into.
13618///
13619/// @return the vector of enum types that which name is @p qualified_name.
13621lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
13622{
13624
13625 return lookup_types_in_map(qualified_name, m);
13626}
13627
13628/// Look into a given corpus to find the enum type*s* that have a
13629/// given qualified name.
13630///
13631/// @param qualified_name the qualified name of the type to look for.
13632///
13633/// @param corp the corpus to look into.
13634///
13635/// @return the vector of enum types that which name is @p qualified_name.
13637lookup_enum_types(const string& qualified_name, const corpus& corp)
13638{
13639 interned_string s = corp.get_environment().intern(qualified_name);
13640 return lookup_enum_types(s, corp);
13641}
13642
13643/// Look up an @ref enum_type_decl from a given corpus, by its location.
13644///
13645/// @param loc the location to consider.
13646///
13647/// @param corp the corpus to look the type from.
13648///
13649/// @return the resulting enum type, if any.
13652{
13655 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
13656
13657 return result;
13658}
13659
13660/// Look up an @ref enum_type_decl from a given corpus, by its location.
13661///
13662/// @param loc the location to consider.
13663///
13664/// @param corp the corpus to look the type from.
13665///
13666/// @return the resulting enum type, if any.
13668lookup_enum_type_per_location(const string &loc, const corpus &corp)
13669{
13670 const environment& env = corp.get_environment();
13671 return lookup_enum_type_per_location(env.intern(loc), corp);
13672}
13673
13674/// Look into a given corpus to find a typedef type which has the
13675/// same qualified name as a given typedef type.
13676///
13677/// If the per-corpus type map is non-empty (because the corpus allows
13678/// the One Definition Rule) then the type islooked up in that
13679/// per-corpus type map. Otherwise, the type is looked-up in each
13680/// translation unit.
13681///
13682/// @param t the typedef type which has the same qualified name as the
13683/// typedef type we are looking for.
13684///
13685/// @param corp the corpus to look into.
13688{
13690 return lookup_typedef_type(s, corp);
13691}
13692
13693/// Look into a given corpus to find a typedef type which has the
13694/// same qualified name as a given typedef type.
13695///
13696/// If the per-corpus type map is non-empty (because the corpus allows
13697/// the One Definition Rule) then the type islooked up in that
13698/// per-corpus type map. Otherwise, the type is looked-up in each
13699/// translation unit.
13700///
13701/// @param t the typedef type which has the same qualified name as the
13702/// typedef type we are looking for.
13703///
13704/// @param corp the corpus to look into.
13706lookup_typedef_type(const string& qualified_name, const corpus& corp)
13707{
13708 interned_string s = corp.get_environment().intern(qualified_name);
13709 return lookup_typedef_type(s, corp);
13710}
13711
13712/// Look into a given corpus to find a typedef type which has a
13713/// given qualified name.
13714///
13715/// If the per-corpus type map is non-empty (because the corpus allows
13716/// the One Definition Rule) then the type islooked up in that
13717/// per-corpus type map. Otherwise, the type is looked-up in each
13718/// translation unit.
13719///
13720/// @param qualified_name the qualified name of the typedef type to
13721/// look for.
13722///
13723/// @param corp the corpus to look into.
13725lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
13726{
13728
13729 typedef_decl_sptr result =
13730 lookup_type_in_map<typedef_decl>(qualified_name, m);
13731 if (!result)
13732 result = lookup_typedef_type_through_translation_units(qualified_name,
13733 corp);
13734
13735 return result;
13736}
13737
13738/// Lookup a @ref typedef_decl from a corpus, by its location.
13739///
13740/// @param loc the location to consider.
13741///
13742/// @param corp the corpus to consider.
13743///
13744/// @return the typedef_decl found, if any.
13747{
13750 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
13751
13752 return result;
13753}
13754
13755/// Lookup a @ref typedef_decl from a corpus, by its location.
13756///
13757/// @param loc the location to consider.
13758///
13759/// @param corp the corpus to consider.
13760///
13761/// @return the typedef_decl found, if any.
13763lookup_typedef_type_per_location(const string &loc, const corpus &corp)
13764{
13765 const environment& env = corp.get_environment();
13766 return lookup_typedef_type_per_location(env.intern(loc), corp);
13767}
13768
13769/// Look into a corpus to find a class, union or typedef type which
13770/// has a given qualified name.
13771///
13772/// If the per-corpus type map is non-empty (because the corpus allows
13773/// the One Definition Rule) then the type islooked up in that
13774/// per-corpus type map. Otherwise, the type is looked-up in each
13775/// translation unit.
13776///
13777/// @param qualified_name the name of the type to find.
13778///
13779/// @param corp the corpus to look into.
13780///
13781/// @return the typedef or class type found.
13782type_base_sptr
13783lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
13784{
13785 type_base_sptr result = lookup_class_type(qualified_name, corp);
13786 if (!result)
13787 result = lookup_union_type(qualified_name, corp);
13788
13789 if (!result)
13790 result = lookup_typedef_type(qualified_name, corp);
13791 return result;
13792}
13793
13794/// Look into a corpus to find a class, typedef or enum type which has
13795/// a given qualified name.
13796///
13797/// If the per-corpus type map is non-empty (because the corpus allows
13798/// the One Definition Rule) then the type islooked up in that
13799/// per-corpus type map. Otherwise, the type is looked-up in each
13800/// translation unit.
13801///
13802/// @param qualified_name the qualified name of the type to look for.
13803///
13804/// @param corp the corpus to look into.
13805///
13806/// @return the typedef, class or enum type found.
13807type_base_sptr
13808lookup_class_typedef_or_enum_type(const string& qualified_name,
13809 const corpus& corp)
13810{
13811 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
13812 if (!result)
13813 result = lookup_enum_type(qualified_name, corp);
13814
13815 return result;
13816}
13817
13818/// Look into a given corpus to find a qualified type which has the
13819/// same qualified name as a given type.
13820///
13821/// @param t the type which has the same qualified name as the
13822/// qualified type we are looking for.
13823///
13824/// @param corp the corpus to look into.
13825///
13826/// @return the qualified type found.
13827qualified_type_def_sptr
13829{
13831 return lookup_qualified_type(s, corp);
13832}
13833
13834/// Look into a given corpus to find a qualified type which has a
13835/// given qualified name.
13836///
13837/// @param qualified_name the qualified name of the type to look for.
13838///
13839/// @param corp the corpus to look into.
13840///
13841/// @return the type found.
13842qualified_type_def_sptr
13843lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
13844{
13846 corp.get_types().qualified_types();
13847
13848 qualified_type_def_sptr result =
13849 lookup_type_in_map<qualified_type_def>(qualified_name, m);
13850
13851 if (!result)
13852 result = lookup_qualified_type_through_translation_units(qualified_name,
13853 corp);
13854
13855 return result;
13856}
13857
13858/// Look into a given corpus to find a pointer type which has the same
13859/// qualified name as a given pointer type.
13860///
13861/// @param t the pointer type which has the same qualified name as the
13862/// type we are looking for.
13863///
13864/// @param corp the corpus to look into.
13865///
13866/// @return the pointer type found.
13869{
13871 return lookup_pointer_type(s, corp);
13872}
13873
13874/// Look into a given corpus to find a pointer type which has a given
13875/// qualified name.
13876///
13877/// If the per-corpus type map is non-empty (because the corpus allows
13878/// the One Definition Rule) then the type islooked up in that
13879/// per-corpus type map. Otherwise, the type is looked-up in each
13880/// translation unit.
13881///
13882/// @param qualified_name the qualified name of the pointer type to
13883/// look for.
13884///
13885/// @param corp the corpus to look into.
13886///
13887/// @return the pointer type found.
13889lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
13890{
13892
13893 pointer_type_def_sptr result =
13894 lookup_type_in_map<pointer_type_def>(qualified_name, m);
13895 if (!result)
13896 result = lookup_pointer_type_through_translation_units(qualified_name,
13897 corp);
13898
13899 return result;
13900}
13901
13902/// Look into a given corpus to find a reference type which has the
13903/// same qualified name as a given reference type.
13904///
13905/// If the per-corpus type map is non-empty (because the corpus allows
13906/// the One Definition Rule) then the type islooked up in that
13907/// per-corpus type map. Otherwise, the type is looked-up in each
13908/// translation unit.
13909///
13910/// @param t the reference type which has the same qualified name as
13911/// the reference type we are looking for.
13912///
13913/// @param corp the corpus to look into.
13914///
13915/// @return the reference type found.
13918{
13920 return lookup_reference_type(s, corp);
13921}
13922
13923/// Look into a given corpus to find a reference type which has a
13924/// given qualified name.
13925///
13926/// If the per-corpus type map is non-empty (because the corpus allows
13927/// the One Definition Rule) then the type islooked up in that
13928/// per-corpus type map. Otherwise, the type is looked-up in each
13929/// translation unit.
13930///
13931/// @param qualified_name the qualified name of the reference type to
13932/// look for.
13933///
13934/// @param corp the corpus to look into.
13935///
13936/// @return the reference type found.
13938lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
13939{
13941 corp.get_types().reference_types();
13942
13944 lookup_type_in_map<reference_type_def>(qualified_name, m);
13945 if (!result)
13946 result = lookup_reference_type_through_translation_units(qualified_name,
13947 corp);
13948
13949 return result;
13950}
13951
13952/// Look into a given corpus to find an array type which has a given
13953/// qualified name.
13954///
13955/// If the per-corpus type map is non-empty (because the corpus allows
13956/// the One Definition Rule) then the type islooked up in that
13957/// per-corpus type map. Otherwise, the type is looked-up in each
13958/// translation unit.
13959///
13960/// @param qualified_name the qualified name of the array type to look
13961/// for.
13962///
13963/// @param corp the corpus to look into.
13964///
13965/// @return the array type found.
13968{
13970 return lookup_array_type(s, corp);
13971}
13972
13973/// Look into a given corpus to find an array type which has the same
13974/// qualified name as a given array type.
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 t the type which has the same qualified name as the type we
13982/// are looking for.
13983///
13984/// @param corp the corpus to look into.
13985///
13986/// @return the type found.
13988lookup_array_type(const interned_string& qualified_name, const corpus& corp)
13989{
13991
13992 array_type_def_sptr result =
13993 lookup_type_in_map<array_type_def>(qualified_name, m);
13994 if (!result)
13995 result = lookup_array_type_through_translation_units(qualified_name, corp);
13996
13997 return result;
13998}
13999
14000/// Look into a given corpus to find a function type which has the same
14001/// qualified name as a given function type.
14002///
14003/// If the per-corpus type map is non-empty (because the corpus allows
14004/// the One Definition Rule) then the type islooked up in that
14005/// per-corpus type map. Otherwise, the type is looked-up in each
14006/// translation unit.
14007///
14008/// @param t the function type which has the same qualified name as
14009/// the function type we are looking for.
14010///
14011/// @param corp the corpus to look into.
14012///
14013/// @return the function type found.
14016{
14017 interned_string type_name = get_type_name(t);
14018 return lookup_function_type(type_name, corp);
14019}
14020
14021/// Look into a given corpus to find a function type which has the same
14022/// qualified name as a given function type.
14023///
14024/// If the per-corpus type map is non-empty (because the corpus allows
14025/// the One Definition Rule) then the type islooked up in that
14026/// per-corpus type map. Otherwise, the type is looked-up in each
14027/// translation unit.
14028///
14029/// @param t the function type which has the same qualified name as
14030/// the function type we are looking for.
14031///
14032/// @param corp the corpus to look into.
14033///
14034/// @return the function type found.
14037 const corpus& corpus)
14038{
14039 if (fn_t)
14040 return lookup_function_type(*fn_t, corpus);
14041 return function_type_sptr();
14042}
14043
14044/// Look into a given corpus to find a function type which has a given
14045/// qualified name.
14046///
14047/// If the per-corpus type map is non-empty (because the corpus allows
14048/// the One Definition Rule) then the type islooked up in that
14049/// per-corpus type map. Otherwise, the type is looked-up in each
14050/// translation unit.
14051///
14052/// @param qualified_name the qualified name of the function type to
14053/// look for.
14054///
14055/// @param corp the corpus to look into.
14056///
14057/// @return the function type found.
14059lookup_function_type(const interned_string& qualified_name, const corpus& corp)
14060{
14062
14063 function_type_sptr result =
14064 lookup_type_in_map<function_type>(qualified_name, m);
14065 if (!result)
14066 result = lookup_function_type_through_translation_units(qualified_name,
14067 corp);
14068
14069 return result;
14070}
14071
14072/// Look into a given corpus to find a type which has a given
14073/// qualified name.
14074///
14075/// If the per-corpus type map is non-empty (because the corpus allows
14076/// the One Definition Rule) then the type islooked up in that
14077/// per-corpus type map. Otherwise, the type is looked-up in each
14078/// translation unit.
14079///
14080/// @param qualified_name the qualified name of the function type to
14081/// look for.
14082///
14083/// @param corp the corpus to look into.
14084///
14085/// @return the function type found.
14086type_base_sptr
14087lookup_type(const interned_string& n, const corpus& corp)
14088{
14089 type_base_sptr result;
14090
14091 ((result = lookup_basic_type(n, corp))
14092 || (result = lookup_class_type(n, corp))
14093 || (result = lookup_union_type(n, corp))
14094 || (result = lookup_enum_type(n, corp))
14095 || (result = lookup_typedef_type(n, corp))
14096 || (result = lookup_qualified_type(n, corp))
14097 || (result = lookup_pointer_type(n, corp))
14098 || (result = lookup_reference_type(n, corp))
14099 || (result = lookup_array_type(n, corp))
14100 || (result= lookup_function_type(n, corp)));
14101
14102 return result;
14103}
14104
14105/// Lookup a type from a corpus, by its location.
14106///
14107/// @param loc the location to consider.
14108///
14109/// @param corp the corpus to look the type from.
14110///
14111/// @return the resulting type, if any found.
14112type_base_sptr
14114{
14115 // TODO: finish this.
14116
14117 //TODO: when we fully support types indexed by their location, this
14118 //function should return a vector of types because at each location,
14119 //there can be several types that are defined (yay, C and C++,
14120 //*sigh*).
14121
14122 type_base_sptr result;
14123 ((result = lookup_basic_type_per_location(loc, corp))
14124 || (result = lookup_class_type_per_location(loc, corp))
14125 || (result = lookup_union_type_per_location(loc, corp))
14126 || (result = lookup_enum_type_per_location(loc, corp))
14127 || (result = lookup_typedef_type_per_location(loc, corp)));
14128
14129 return result;
14130}
14131
14132/// Look into a given corpus to find a type
14133///
14134/// If the per-corpus type map is non-empty (because the corpus allows
14135/// the One Definition Rule) then the type islooked up in that
14136/// per-corpus type map. Otherwise, the type is looked-up in each
14137/// translation unit.
14138///
14139/// @param qualified_name the qualified name of the function type to
14140/// look for.
14141///
14142/// @param corp the corpus to look into.
14143///
14144/// @return the function type found.
14145type_base_sptr
14146lookup_type(const type_base&t, const corpus& corp)
14147{
14149 return lookup_type(n, corp);
14150}
14151
14152/// Look into a given corpus to find a type
14153///
14154/// If the per-corpus type map is non-empty (because the corpus allows
14155/// the One Definition Rule) then the type islooked up in that
14156/// per-corpus type map. Otherwise, the type is looked-up in each
14157/// translation unit.
14158///
14159/// @param qualified_name the qualified name of the function type to
14160/// look for.
14161///
14162/// @param corp the corpus to look into.
14163///
14164/// @return the function type found.
14165type_base_sptr
14166lookup_type(const type_base_sptr&t, const corpus& corp)
14167{
14168 if (t)
14169 return lookup_type(*t, corp);
14170 return type_base_sptr();
14171}
14172
14173/// Update the map that associates a fully qualified name of a given
14174/// type to that type.
14175///
14176///
14177/// @param type the type we are considering.
14178///
14179/// @param types_map the map to update. It's a map that assciates a
14180/// fully qualified name of a type to the type itself.
14181///
14182/// @param use_type_name_as_key if true, use the name of the type as
14183/// the key to look it up later. If false, then use the location of
14184/// the type as a key to look it up later.
14185///
14186/// @return true iff the type was added to the map.
14187template<typename TypeKind>
14188bool
14189maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
14191 bool use_type_name_as_key = true)
14192{
14194
14195 if (use_type_name_as_key)
14196 s = get_type_name(type);
14197 else if (location l = type->get_location())
14198 {
14199 string str = l.expand();
14200 s = type->get_environment().intern(str);
14201 }
14202
14203 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14204 bool result = false;
14205
14206 if (i == types_map.end())
14207 {
14208 types_map[s].push_back(type);
14209 result = true;
14210 }
14211 else
14212 i->second.push_back(type);
14213
14214 return result;
14215}
14216
14217/// This is the specialization for type @ref class_decl of the
14218/// function template:
14219///
14220/// maybe_update_types_lookup_map<T>(scope_decl*,
14221/// const shared_ptr<T>&,
14222/// istring_type_base_wptrs_map_type&)
14223///
14224/// @param class_type the type to consider.
14225///
14226/// @param types_map the type map to update.
14227///
14228/// @return true iff the type was added to the map.
14229template<>
14230bool
14233 bool use_type_name_as_key)
14234{
14235 class_decl_sptr type = class_type;
14236
14237 bool update_qname_map = true;
14238 if (type->get_is_declaration_only())
14239 {
14240 // Let's try to look through decl-only classes to get their
14241 // definition. But if the class doesn't have a definition then
14242 // we'll keep it.
14243 if (class_decl_sptr def =
14244 is_class_type(class_type->get_definition_of_declaration()))
14245 type = def;
14246 }
14247
14248 if (!update_qname_map)
14249 return false;
14250
14252 if (use_type_name_as_key)
14253 {
14254 string qname = type->get_qualified_name();
14255 s = type->get_environment().intern(qname);
14256 }
14257 else if (location l = type->get_location())
14258 {
14259 string str = l.expand();
14260 s = type->get_environment().intern(str);
14261 }
14262
14263 bool result = false;
14264 istring_type_base_wptrs_map_type::iterator i = map.find(s);
14265 if (i == map.end())
14266 {
14267 map[s].push_back(type);
14268 result = true;
14269 }
14270 else
14271 i->second.push_back(type);
14272
14273 return result;
14274}
14275
14276/// This is the specialization for type @ref function_type of the
14277/// function template:
14278///
14279/// maybe_update_types_lookup_map<T>(scope_decl*,
14280/// const shared_ptr<T>&,
14281/// istring_type_base_wptrs_map_type&)
14282///
14283/// @param scope the scope of the type to consider.
14284///
14285/// @param class_type the type to consider.
14286///
14287/// @param types_map the type map to update.
14288///
14289/// @return true iff the type was added to the map.
14290template<>
14291bool
14293(const function_type_sptr& type,
14295 bool /*use_type_name_as_key*/)
14296{
14297 bool result = false;
14299 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14300 if (i == types_map.end())
14301 {
14302 types_map[s].push_back(type);
14303 result = true;
14304 }
14305 else
14306 i->second.push_back(type);
14307
14308 return result;
14309}
14310
14311/// Update the map that associates the fully qualified name of a basic
14312/// type with the type itself.
14313///
14314/// The per-translation unit type map is updated if no type with this
14315/// name was already existing in that map.
14316///
14317/// If no type with this name did already exist in the per-corpus type
14318/// map, then that per-corpus type map is updated. Otherwise, that
14319/// type is erased from that per-corpus map.
14320///
14321/// @param basic_type the basic type to consider.
14322void
14324{
14325 if (translation_unit *tu = basic_type->get_translation_unit())
14326 maybe_update_types_lookup_map<type_decl>
14327 (basic_type, tu->get_types().basic_types());
14328
14329 if (corpus *type_corpus = basic_type->get_corpus())
14330 {
14331 maybe_update_types_lookup_map<type_decl>
14332 (basic_type,
14333 type_corpus->priv_->get_types().basic_types());
14334
14335 maybe_update_types_lookup_map<type_decl>
14336 (basic_type,
14337 type_corpus->get_type_per_loc_map().basic_types(),
14338 /*use_type_name_as_key*/false);
14339
14340 if (corpus *group = type_corpus->get_group())
14341 {
14342 maybe_update_types_lookup_map<type_decl>
14343 (basic_type,
14344 group->priv_->get_types().basic_types());
14345
14346 maybe_update_types_lookup_map<type_decl>
14347 (basic_type,
14348 group->get_type_per_loc_map().basic_types(),
14349 /*use_type_name_as_key*/false);
14350 }
14351 }
14352
14353}
14354
14355/// Update the map that associates the fully qualified name of a class
14356/// type with the type itself.
14357///
14358/// The per-translation unit type map is updated if no type with this
14359/// name was already existing in that map.
14360///
14361/// If no type with this name did already exist in the per-corpus type
14362/// map, then that per-corpus type map is updated. Otherwise, that
14363/// type is erased from that per-corpus map.
14364///
14365/// @param class_type the class type to consider.
14366void
14368{
14369 if (translation_unit *tu = class_type->get_translation_unit())
14371 (class_type, tu->get_types().class_types());
14372
14373 if (corpus *type_corpus = class_type->get_corpus())
14374 {
14376 (class_type,
14377 type_corpus->priv_->get_types().class_types());
14378
14380 (class_type,
14381 type_corpus->get_type_per_loc_map().class_types(),
14382 /*use_type_name_as_key*/false);
14383
14384 if (corpus *group = type_corpus->get_group())
14385 {
14387 (class_type,
14388 group->priv_->get_types().class_types());
14389
14391 (class_type,
14392 group->get_type_per_loc_map().class_types(),
14393 /*use_type_name_as_key*/false);
14394 }
14395 }
14396}
14397
14398/// Update the map that associates the fully qualified name of a union
14399/// type with the type itself.
14400///
14401/// The per-translation unit type map is updated if no type with this
14402/// name was already existing in that map.
14403///
14404/// If no type with this name did already exist in the per-corpus type
14405/// map, then that per-corpus type map is updated. Otherwise, that
14406/// type is erased from that per-corpus map.
14407///
14408/// @param union_type the union type to consider.
14409void
14410maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14411{
14412 if (translation_unit *tu = union_type->get_translation_unit())
14413 maybe_update_types_lookup_map<union_decl>
14414 (union_type, tu->get_types().union_types());
14415
14416 if (corpus *type_corpus = union_type->get_corpus())
14417 {
14418 maybe_update_types_lookup_map<union_decl>
14419 (union_type,
14420 type_corpus->priv_->get_types().union_types());
14421
14422 maybe_update_types_lookup_map<union_decl>
14423 (union_type,
14424 type_corpus->get_type_per_loc_map().union_types(),
14425 /*use_type_name_as_key*/false);
14426
14427 if (corpus *group = type_corpus->get_group())
14428 {
14429 maybe_update_types_lookup_map<union_decl>
14430 (union_type,
14431 group->priv_->get_types().union_types());
14432
14433 maybe_update_types_lookup_map<union_decl>
14434 (union_type,
14435 group->get_type_per_loc_map().union_types(),
14436 /*use_type_name_as_key*/false);
14437 }
14438 }
14439}
14440
14441/// Update the map that associates the fully qualified name of an enum
14442/// type with the type itself.
14443///
14444/// The per-translation unit type map is updated if no type with this
14445/// name was already existing in that map.
14446///
14447/// If no type with this name did already exist in the per-corpus type
14448/// map, then that per-corpus type map is updated. Otherwise, that
14449/// type is erased from that per-corpus map.
14450///
14451/// @param enum_type the type to consider.
14452void
14454{
14455 if (translation_unit *tu = enum_type->get_translation_unit())
14456 maybe_update_types_lookup_map<enum_type_decl>
14457 (enum_type, tu->get_types().enum_types());
14458
14459 if (corpus *type_corpus = enum_type->get_corpus())
14460 {
14461 maybe_update_types_lookup_map<enum_type_decl>
14462 (enum_type,
14463 type_corpus->priv_->get_types().enum_types());
14464
14465 maybe_update_types_lookup_map<enum_type_decl>
14466 (enum_type,
14467 type_corpus->get_type_per_loc_map().enum_types(),
14468 /*use_type_name_as_key*/false);
14469
14470 if (corpus *group = type_corpus->get_group())
14471 {
14472 maybe_update_types_lookup_map<enum_type_decl>
14473 (enum_type,
14474 group->priv_->get_types().enum_types());
14475
14476 maybe_update_types_lookup_map<enum_type_decl>
14477 (enum_type,
14478 group->get_type_per_loc_map().enum_types(),
14479 /*use_type_name_as_key*/false);
14480 }
14481 }
14482
14483}
14484
14485/// Update the map that associates the fully qualified name of a
14486/// typedef type with the type itself.
14487///
14488/// The per-translation unit type map is updated if no type with this
14489/// name was already existing in that map.
14490///
14491/// If no type with this name did already exist in the per-corpus type
14492/// map, then that per-corpus type map is updated. Otherwise, that
14493/// type is erased from that per-corpus map.
14494///
14495/// @param typedef_type the type to consider.
14496void
14498{
14499 if (translation_unit *tu = typedef_type->get_translation_unit())
14500 maybe_update_types_lookup_map<typedef_decl>
14501 (typedef_type, tu->get_types().typedef_types());
14502
14503 if (corpus *type_corpus = typedef_type->get_corpus())
14504 {
14505 maybe_update_types_lookup_map<typedef_decl>
14506 (typedef_type,
14507 type_corpus->priv_->get_types().typedef_types());
14508
14509 maybe_update_types_lookup_map<typedef_decl>
14510 (typedef_type,
14511 type_corpus->get_type_per_loc_map().typedef_types(),
14512 /*use_type_name_as_key*/false);
14513
14514 if (corpus *group = type_corpus->get_group())
14515 {
14516 maybe_update_types_lookup_map<typedef_decl>
14517 (typedef_type,
14518 group->priv_->get_types().typedef_types());
14519
14520 maybe_update_types_lookup_map<typedef_decl>
14521 (typedef_type,
14522 group->get_type_per_loc_map().typedef_types(),
14523 /*use_type_name_as_key*/false);
14524 }
14525 }
14526}
14527
14528/// Update the map that associates the fully qualified name of a
14529/// qualified type with the type itself.
14530///
14531/// The per-translation unit type map is updated if no type with this
14532/// name was already existing in that map.
14533///
14534/// If no type with this name did already exist in the per-corpus type
14535/// map, then that per-corpus type map is updated. Otherwise, that
14536/// type is erased from that per-corpus map.
14537///
14538/// @param qualified_type the type to consider.
14539void
14540maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14541{
14542 if (translation_unit *tu = qualified_type->get_translation_unit())
14543 maybe_update_types_lookup_map<qualified_type_def>
14544 (qualified_type, tu->get_types().qualified_types());
14545
14546 if (corpus *type_corpus = qualified_type->get_corpus())
14547 {
14548 maybe_update_types_lookup_map<qualified_type_def>
14549 (qualified_type,
14550 type_corpus->priv_->get_types().qualified_types());
14551
14552 if (corpus *group = type_corpus->get_group())
14553 {
14554 maybe_update_types_lookup_map<qualified_type_def>
14555 (qualified_type,
14556 group->priv_->get_types().qualified_types());
14557 }
14558 }
14559}
14560
14561/// Update the map that associates the fully qualified name of a
14562/// pointer type with the type itself.
14563///
14564/// The per-translation unit type map is updated if no type with this
14565/// name was already existing in that map.
14566///
14567/// If no type with this name did already exist in the per-corpus type
14568/// map, then that per-corpus type map is updated. Otherwise, that
14569/// type is erased from that per-corpus map.
14570///
14571/// @param pointer_type the type to consider.
14572void
14574{
14575 if (translation_unit *tu = pointer_type->get_translation_unit())
14576 maybe_update_types_lookup_map<pointer_type_def>
14577 (pointer_type, tu->get_types().pointer_types());
14578
14579 if (corpus *type_corpus = pointer_type->get_corpus())
14580 {
14581 maybe_update_types_lookup_map<pointer_type_def>
14582 (pointer_type,
14583 type_corpus->priv_->get_types().pointer_types());
14584
14585 if (corpus *group = type_corpus->get_group())
14586 {
14587 maybe_update_types_lookup_map<pointer_type_def>
14588 (pointer_type,
14589 group->priv_->get_types().pointer_types());
14590 }
14591 }
14592}
14593
14594/// Update the map that associates the fully qualified name of a
14595/// pointer-to-member type with the type itself.
14596///
14597/// The per-translation unit type map is updated if no type with this
14598/// name was already existing in that map.
14599///
14600/// If no type with this name did already exist in the per-corpus type
14601/// map, then that per-corpus type map is updated. Otherwise, that
14602/// type is erased from that per-corpus map.
14603///
14604/// @param ptr_to_mbr_type the type to consider.
14605void
14607{
14608 if (translation_unit *tu = ptr_to_member->get_translation_unit())
14609 maybe_update_types_lookup_map<ptr_to_mbr_type>
14610 (ptr_to_member, tu->get_types().ptr_to_mbr_types());
14611
14612 if (corpus *type_corpus = ptr_to_member->get_corpus())
14613 {
14614 maybe_update_types_lookup_map<ptr_to_mbr_type>
14615 (ptr_to_member,
14616 type_corpus->priv_->get_types().ptr_to_mbr_types());
14617
14618 if (corpus *group = type_corpus->get_group())
14619 {
14620 maybe_update_types_lookup_map<ptr_to_mbr_type>
14621 (ptr_to_member,
14622 group->priv_->get_types().ptr_to_mbr_types());
14623 }
14624 }
14625}
14626
14627/// Update the map that associates the fully qualified name of a
14628/// reference type with the type itself.
14629///
14630/// The per-translation unit type map is updated if no type with this
14631/// name was already existing in that map.
14632///
14633/// If no type with this name did already exist in the per-corpus type
14634/// map, then that per-corpus type map is updated. Otherwise, that
14635/// type is erased from that per-corpus map.
14636///
14637/// @param reference_type the type to consider.
14638void
14640{
14641 if (translation_unit *tu = reference_type->get_translation_unit())
14642 maybe_update_types_lookup_map<reference_type_def>
14643 (reference_type, tu->get_types().reference_types());
14644
14645 if (corpus *type_corpus = reference_type->get_corpus())
14646 {
14647 maybe_update_types_lookup_map<reference_type_def>
14648 (reference_type,
14649 type_corpus->priv_->get_types().reference_types());
14650
14651 if (corpus *group = type_corpus->get_group())
14652 {
14653 maybe_update_types_lookup_map<reference_type_def>
14654 (reference_type,
14655 group->priv_->get_types().reference_types());
14656 }
14657 }
14658}
14659
14660/// Update the map that associates the fully qualified name of a type
14661/// with the type itself.
14662///
14663/// The per-translation unit type map is updated if no type with this
14664/// name was already existing in that map.
14665///
14666/// If no type with this name did already exist in the per-corpus type
14667/// map, then that per-corpus type map is updated. Otherwise, that
14668/// type is erased from that per-corpus map.
14669///
14670/// @param array_type the type to consider.
14671void
14673{
14674 if (translation_unit *tu = array_type->get_translation_unit())
14675 maybe_update_types_lookup_map<array_type_def>
14676 (array_type, tu->get_types().array_types());
14677
14678 if (corpus *type_corpus = array_type->get_corpus())
14679 {
14680 maybe_update_types_lookup_map<array_type_def>
14681 (array_type,
14682 type_corpus->priv_->get_types().array_types());
14683
14684 maybe_update_types_lookup_map<array_type_def>
14685 (array_type,
14686 type_corpus->get_type_per_loc_map().array_types(),
14687 /*use_type_name_as_key*/false);
14688
14689 if (corpus *group = type_corpus->get_group())
14690 {
14691 maybe_update_types_lookup_map<array_type_def>
14692 (array_type,
14693 group->priv_->get_types().array_types());
14694
14695 maybe_update_types_lookup_map<array_type_def>
14696 (array_type,
14697 group->get_type_per_loc_map().array_types(),
14698 /*use_type_name_as_key*/false);
14699 }
14700 }
14701}
14702
14703/// Update the map that associates the fully qualified name of a type
14704/// with the type itself.
14705///
14706/// The per-translation unit type map is updated if no type with this
14707/// name was already existing in that map.
14708///
14709/// If no type with this name did already exist in the per-corpus type
14710/// map, then that per-corpus type map is updated. Otherwise, that
14711/// type is erased from that per-corpus map.
14712///
14713/// @param subrange_type the type to consider.
14714void
14716(const array_type_def::subrange_sptr& subrange_type)
14717{
14718 if (translation_unit *tu = subrange_type->get_translation_unit())
14719 maybe_update_types_lookup_map<array_type_def::subrange_type>
14720 (subrange_type, tu->get_types().subrange_types());
14721
14722 if (corpus *type_corpus = subrange_type->get_corpus())
14723 {
14724 maybe_update_types_lookup_map<array_type_def::subrange_type>
14725 (subrange_type,
14726 type_corpus->priv_->get_types().subrange_types());
14727
14728 maybe_update_types_lookup_map<array_type_def::subrange_type>
14729 (subrange_type,
14730 type_corpus->get_type_per_loc_map().subrange_types(),
14731 /*use_type_name_as_key*/false);
14732
14733 if (corpus *group = subrange_type->get_corpus())
14734 {
14735 maybe_update_types_lookup_map<array_type_def::subrange_type>
14736 (subrange_type,
14737 group->priv_->get_types().subrange_types());
14738
14739 maybe_update_types_lookup_map<array_type_def::subrange_type>
14740 (subrange_type,
14741 group->get_type_per_loc_map().subrange_types(),
14742 /*use_type_name_as_key*/false);
14743 }
14744 }
14745}
14746
14747/// Update the map that associates the fully qualified name of a
14748/// function type with the type itself.
14749///
14750/// The per-translation unit type map is updated if no type with this
14751/// name was already existing in that map.
14752///
14753/// If no type with this name did already exist in the per-corpus type
14754/// map, then that per-corpus type map is updated. Otherwise, that
14755/// type is erased from that per-corpus map.
14756///
14757/// @param scope the scope of the function type.
14758/// @param fn_type the type to consider.
14759void
14761{
14762 if (translation_unit *tu = fn_type->get_translation_unit())
14764 (fn_type, tu->get_types().function_types());
14765
14766 if (corpus *type_corpus = fn_type->get_corpus())
14767 {
14769 (fn_type,
14770 type_corpus->priv_->get_types().function_types());
14771
14772 if (corpus *group = fn_type->get_corpus())
14773 {
14775 (fn_type,
14776 group->priv_->get_types().function_types());
14777 }
14778 }
14779}
14780
14781/// Update the map that associates the fully qualified name of a type
14782/// declaration with the type itself.
14783///
14784/// The per-translation unit type map is updated if no type with this
14785/// name was already existing in that map.
14786///
14787/// If no type with this name did already exist in the per-corpus type
14788/// map, then that per-corpus type map is updated. Otherwise, that
14789/// type is erased from that per-corpus map.
14790///
14791/// @param decl the declaration of the type to consider.
14792void
14793maybe_update_types_lookup_map(const decl_base_sptr& decl)
14794{
14795 if (!is_type(decl))
14796 return;
14797
14798 if (type_decl_sptr basic_type = is_type_decl(decl))
14800 else if (class_decl_sptr class_type = is_class_type(decl))
14802 else if (union_decl_sptr union_type = is_union_type(decl))
14804 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
14806 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
14807 maybe_update_types_lookup_map(typedef_type);
14808 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
14809 maybe_update_types_lookup_map(qualified_type);
14810 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
14811 maybe_update_types_lookup_map(pointer_type);
14812 else if (ptr_to_mbr_type_sptr ptr_to_member = is_ptr_to_mbr_type(decl))
14813 maybe_update_types_lookup_map(ptr_to_member);
14814 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
14815 maybe_update_types_lookup_map(reference_type);
14816 else if (array_type_def_sptr array_type = is_array_type(decl))
14818 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
14819 maybe_update_types_lookup_map(subrange_type);
14820 else if (function_type_sptr fn_type = is_function_type(decl))
14822 else
14824}
14825
14826/// Update the map that associates the fully qualified name of a type
14827/// with the type itself.
14828///
14829/// The per-translation unit type map is updated if no type with this
14830/// name was already existing in that map.
14831///
14832/// If no type with this name did already exist in the per-corpus type
14833/// map, then that per-corpus type map is updated. Otherwise, that
14834/// type is erased from that per-corpus map.
14835///
14836/// @param type the type to consider.
14837void
14838maybe_update_types_lookup_map(const type_base_sptr& type)
14839{
14840 if (decl_base_sptr decl = get_type_declaration(type))
14842 else if (function_type_sptr fn_type = is_function_type(type))
14844 else
14846}
14847
14848//--------------------------------
14849// </type and decls lookup stuff>
14850// ------------------------------
14851
14852/// In a translation unit, lookup a given type or synthesize it if
14853/// it's a qualified type.
14854///
14855/// So this function first looks the type up in the translation unit.
14856/// If it's found, then OK, it's returned. Otherwise, if it's a
14857/// qualified, reference or pointer or function type (a composite
14858/// type), lookup the underlying type, synthesize the type we want
14859/// from it and return it.
14860///
14861/// If the underlying types is not not found, then give up and return
14862/// nil.
14863///
14864/// @return the type that was found or the synthesized type.
14865type_base_sptr
14866synthesize_type_from_translation_unit(const type_base_sptr& type,
14867 translation_unit& tu)
14868{
14869 type_base_sptr result;
14870
14871 result = lookup_type(type, tu);
14872
14873 if (!result)
14874 {
14875 if (qualified_type_def_sptr qual = is_qualified_type(type))
14876 {
14877 type_base_sptr underlying_type =
14878 synthesize_type_from_translation_unit(qual->get_underlying_type(),
14879 tu);
14880 if (underlying_type)
14881 {
14882 result.reset(new qualified_type_def(underlying_type,
14883 qual->get_cv_quals(),
14884 qual->get_location()));
14885 }
14886 }
14887 else if (pointer_type_def_sptr p = is_pointer_type(type))
14888 {
14889 type_base_sptr pointed_to_type =
14890 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
14891 tu);
14892 if (pointed_to_type)
14893 {
14894 result.reset(new pointer_type_def(pointed_to_type,
14895 p->get_size_in_bits(),
14896 p->get_alignment_in_bits(),
14897 p->get_location()));
14898 }
14899 }
14900 else if (reference_type_def_sptr r = is_reference_type(type))
14901 {
14902 type_base_sptr pointed_to_type =
14903 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
14904 if (pointed_to_type)
14905 {
14906 result.reset(new reference_type_def(pointed_to_type,
14907 r->is_lvalue(),
14908 r->get_size_in_bits(),
14909 r->get_alignment_in_bits(),
14910 r->get_location()));
14911 }
14912 }
14913 else if (function_type_sptr f = is_function_type(type))
14915
14916 if (result)
14917 {
14919 canonicalize(result);
14920 }
14921 }
14922
14923 if (result)
14924 tu.priv_->synthesized_types_.push_back(result);
14925
14926 return result;
14927}
14928
14929/// In a translation unit, lookup the sub-types that make up a given
14930/// function type and if the sub-types are all found, synthesize and
14931/// return a function_type with them.
14932///
14933/// This function is like lookup_function_type_in_translation_unit()
14934/// execept that it constructs the function type from the sub-types
14935/// found in the translation, rather than just looking for the
14936/// function types held by the translation unit. This can be useful
14937/// if the translation unit doesnt hold the function type we are
14938/// looking for (i.e, lookup_function_type_in_translation_unit()
14939/// returned NULL) but we still want to see if the sub-types of the
14940/// function types are present in the translation unit.
14941///
14942/// @param fn_type the function type to consider.
14943///
14944/// @param tu the translation unit to look into.
14945///
14946/// @return the resulting synthesized function type if all its
14947/// sub-types have been found, NULL otherwise.
14950 translation_unit& tu)
14951{
14953
14954 const environment& env = tu.get_environment();
14955
14956 type_base_sptr return_type = fn_type.get_return_type();
14957 type_base_sptr result_return_type;
14958 if (!return_type || env.is_void_type(return_type))
14959 result_return_type = env.get_void_type();
14960 else
14961 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
14962 if (!result_return_type)
14963 return nil;
14964
14966 type_base_sptr parm_type;
14968 for (function_type::parameters::const_iterator i =
14969 fn_type.get_parameters().begin();
14970 i != fn_type.get_parameters().end();
14971 ++i)
14972 {
14973 type_base_sptr t = (*i)->get_type();
14974 parm_type = synthesize_type_from_translation_unit(t, tu);
14975 if (!parm_type)
14976 return nil;
14977 parm.reset(new function_decl::parameter(parm_type,
14978 (*i)->get_index(),
14979 (*i)->get_name(),
14980 (*i)->get_location(),
14981 (*i)->get_variadic_marker(),
14982 (*i)->get_is_artificial()));
14983 parms.push_back(parm);
14984 }
14985
14986 class_or_union_sptr class_type;
14987 const method_type* method = is_method_type(&fn_type);
14988 if (method)
14989 {
14990 class_type = is_class_or_union_type
14992 ABG_ASSERT(class_type);
14993 }
14994
14995 function_type_sptr result_fn_type;
14996
14997 if (class_type)
14998 result_fn_type.reset(new method_type(result_return_type,
14999 class_type,
15000 parms,
15001 method->get_is_const(),
15002 fn_type.get_size_in_bits(),
15003 fn_type.get_alignment_in_bits()));
15004 else
15005 result_fn_type.reset(new function_type(result_return_type,
15006 parms,
15007 fn_type.get_size_in_bits(),
15008 fn_type.get_alignment_in_bits()));
15009
15010 tu.priv_->synthesized_types_.push_back(result_fn_type);
15011 tu.bind_function_type_life_time(result_fn_type);
15012
15013 canonicalize(result_fn_type);
15014 return result_fn_type;
15015}
15016
15017/// Demangle a C++ mangled name and return the resulting string
15018///
15019/// @param mangled_name the C++ mangled name to demangle.
15020///
15021/// @return the resulting mangled name.
15022string
15023demangle_cplus_mangled_name(const string& mangled_name)
15024{
15025 if (mangled_name.empty())
15026 return "";
15027
15028 size_t l = 0;
15029 int status = 0;
15030 char * str = abi::__cxa_demangle(mangled_name.c_str(),
15031 NULL, &l, &status);
15032 string demangled_name = mangled_name;
15033 if (str)
15034 {
15035 ABG_ASSERT(status == 0);
15036 demangled_name = str;
15037 free(str);
15038 str = 0;
15039 }
15040 return demangled_name;
15041}
15042
15043/// Return either the type given in parameter if it's non-null, or the
15044/// void type.
15045///
15046/// @param t the type to consider.
15047///
15048/// @param env the environment to use. If NULL, just abort the
15049/// process.
15050///
15051/// @return either @p t if it is non-null, or the void type.
15052type_base_sptr
15053type_or_void(const type_base_sptr t, const environment& env)
15054{
15055 type_base_sptr r;
15056
15057 if (t)
15058 r = t;
15059 else
15060 r = type_base_sptr(env.get_void_type());
15061
15062 return r;
15063}
15064
15065global_scope::~global_scope()
15066{
15067}
15068
15069/// Test if two types are eligible to the "Linux Kernel Fast Type
15070/// Comparison Optimization", a.k.a LKFTCO.
15071///
15072/// Two types T1 and T2 (who are presumably of the same name and kind)
15073/// are eligible to the LKFTCO if they fulfill the following criteria/
15074///
15075/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
15076/// either class, union or enums.
15077///
15078/// 2/ They are defined in the same translation unit.
15079///
15080/// @param t1 the first type to consider.
15081///
15082/// @param t2 the second type to consider.
15083///
15084/// @return true iff t1 and t2 are eligible to the LKFTCO.
15085static bool
15086types_defined_same_linux_kernel_corpus_public(const type_base& t1,
15087 const type_base& t2)
15088{
15089 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
15090 string t1_file_path, t2_file_path;
15091
15092 /// If the t1 (and t2) are classes/unions/enums from the same linux
15093 /// kernel corpus, let's move on. Otherwise bail out.
15094 if (!(t1_corpus && t2_corpus
15095 && t1_corpus == t2_corpus
15096 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
15097 && (is_class_or_union_type(&t1)
15098 || is_enum_type(&t1))))
15099 return false;
15100
15101 class_or_union *c1 = 0, *c2 = 0;
15102 c1 = is_class_or_union_type(&t1);
15103 c2 = is_class_or_union_type(&t2);
15104
15105 // Two anonymous class types with no naming typedefs cannot be
15106 // eligible to this optimization.
15107 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
15108 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
15109 return false;
15110
15111 // Two anonymous classes with naming typedefs should have the same
15112 // typedef name.
15113 if (c1
15114 && c2
15115 && c1->get_is_anonymous() && c1->get_naming_typedef()
15116 && c2->get_is_anonymous() && c2->get_naming_typedef())
15117 if (c1->get_naming_typedef()->get_name()
15118 != c2->get_naming_typedef()->get_name())
15119 return false;
15120
15121 // Two anonymous enum types cannot be eligible to this optimization.
15122 if (const enum_type_decl *e1 = is_enum_type(&t1))
15123 if (const enum_type_decl *e2 = is_enum_type(&t2))
15124 if (e1->get_is_anonymous() || e2->get_is_anonymous())
15125 return false;
15126
15127 // Look through declaration-only types. That is, get the associated
15128 // definition type.
15131
15132 if (c1 && c2)
15133 {
15134 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
15135 {
15136 if (c1->get_environment().decl_only_class_equals_definition())
15137 // At least one of classes/union is declaration-only.
15138 // Because we are in a context in which a declaration-only
15139 // class/union is equal to all definitions of that
15140 // class/union, we can assume that the two types are
15141 // equal.
15142 return true;
15143 }
15144 }
15145
15146 if (t1.get_size_in_bits() != t2.get_size_in_bits())
15147 return false;
15148
15149 // Look at the file names of the locations of t1 and t2. If they
15150 // are equal, then t1 and t2 are defined in the same file.
15151 {
15152 location l;
15153
15154 if (c1)
15155 l = c1->get_location();
15156 else
15157 l = dynamic_cast<const decl_base&>(t1).get_location();
15158
15159 unsigned line = 0, col = 0;
15160 if (l)
15161 l.expand(t1_file_path, line, col);
15162 if (c2)
15163 l = c2->get_location();
15164 else
15165 l = dynamic_cast<const decl_base&>(t2).get_location();
15166 if (l)
15167 l.expand(t2_file_path, line, col);
15168 }
15169
15170 if (t1_file_path.empty() || t2_file_path.empty())
15171 return false;
15172
15173 if (t1_file_path == t2_file_path)
15174 return true;
15175
15176 return false;
15177}
15178
15179
15180/// Compare a type T against a canonical type.
15181///
15182/// This function is called during the canonicalization process of the
15183/// type T. T is called the "candidate type" because it's in the
15184/// process of being canonicalized. Meaning, it's going to be
15185/// compared to a canonical type C. If T equals C, then the canonical
15186/// type of T is C.
15187///
15188/// The purpose of this function is to allow the debugging of the
15189/// canonicalization of T, if that debugging is activated by
15190/// configuring the libabigail package with
15191/// --enable-debug-type-canonicalization and by running "abidw
15192/// --debug-tc". In that case, T is going to be compared to C twice:
15193/// once with canonical equality and once with structural equality.
15194/// The two comparisons must be equal. Otherwise, the
15195/// canonicalization process is said to be faulty and this function
15196/// aborts.
15197///
15198/// This is a sub-routine of type_base::get_canonical_type_for.
15199///
15200/// @param canonical_type the canonical type to compare the candidate
15201/// type against.
15202///
15203/// @param candidate_type the candidate type to compare against the
15204/// canonical type.
15205///
15206/// @return true iff @p canonical_type equals @p candidate_type.
15207///
15208static bool
15209compare_types_during_canonicalization(const type_base& canonical_type,
15210 const type_base& candidate_type)
15211{
15212#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
15213 const environment& env = canonical_type.get_environment();
15214 if (env.debug_type_canonicalization_is_on())
15215 {
15216 bool canonical_equality = false, structural_equality = false;
15217 env.priv_->allow_type_comparison_results_caching(false);
15218 env.priv_->use_canonical_type_comparison_ = false;
15219 structural_equality = canonical_type == candidate_type;
15220 env.priv_->use_canonical_type_comparison_ = true;
15221 canonical_equality = canonical_type == candidate_type;
15222 env.priv_->allow_type_comparison_results_caching(true);
15223 if (canonical_equality != structural_equality)
15224 {
15225 std::cerr << "structural & canonical equality different for type: "
15226 << canonical_type.get_pretty_representation(true, true)
15227 << std::endl;
15229 }
15230 return structural_equality;
15231 }
15232#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
15233 return canonical_type == candidate_type;
15234}
15235
15236/// Compare a canonical type against a candidate canonical type.
15237///
15238/// This is ultimately a sub-routine of the
15239/// type_base::get_canonical_type_for().
15240///
15241/// The goal of this function is to ease debugging because it can be
15242/// called from within type_base::get_canonical_type_for() from the
15243/// prompt of the debugger (with some breakpoint appropriately set) to
15244/// debug the comparison that happens during type canonicalization,
15245/// between a candidate type being canonicalized, and an existing
15246/// canonical type that is registered in the system, in as returned by
15247/// environment::get_canonical_types()
15248///
15249/// @param canonical_type the canonical type to consider.
15250///
15251/// @param candidate_type the candidate type that is being
15252/// canonicalized, and thus compared to @p canonical_type.
15253///
15254/// @return true iff @p canonical_type compares equal to @p
15255/// candidate_type.
15256static bool
15257compare_canonical_type_against_candidate(const type_base& canonical_type,
15258 const type_base& candidate_type)
15259{
15260 environment& env = const_cast<environment&>(canonical_type.get_environment());
15261
15262 // Before the "*it == it" comparison below is done, let's
15263 // perform on-the-fly-canonicalization. For C types, let's
15264 // consider that an unresolved struct declaration 'struct S'
15265 // is different from a definition 'struct S'. This is
15266 // because normally, at this point all the declarations of
15267 // struct S that are compatible with the definition of
15268 // struct S have already been resolved to that definition,
15269 // during the DWARF parsing. The remaining unresolved
15270 // declaration are thus considered different. With this
15271 // setup we can properly handle cases of two *different*
15272 // struct S being defined in the same binary (in different
15273 // translation units), and a third struct S being only
15274 // declared as an opaque type in a third translation unit of
15275 // its own, with no definition in there. In that case, the
15276 // declaration-only struct S should be left alone and not
15277 // resolved to any of the two definitions of struct S.
15278 bool saved_decl_only_class_equals_definition =
15279 env.decl_only_class_equals_definition();
15280
15281 // Compare types by considering that decl-only classes don't
15282 // equal their definition.
15283 env.decl_only_class_equals_definition(false);
15284 env.priv_->allow_type_comparison_results_caching(true);
15285 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
15286 candidate_type)
15287 || compare_types_during_canonicalization(canonical_type,
15288 candidate_type));
15289 // Restore the state of the on-the-fly-canonicalization and
15290 // the decl-only-class-being-equal-to-a-matching-definition
15291 // flags.
15292 env.priv_->clear_type_comparison_results_cache();
15293 env.priv_->allow_type_comparison_results_caching(false);
15294 env.decl_only_class_equals_definition
15295 (saved_decl_only_class_equals_definition);
15296 return equal;
15297}
15298
15299/// Compare a canonical type against a candidate canonical type.
15300///
15301/// This is ultimately a sub-routine of the
15302/// type_base::get_canonical_type_for().
15303///
15304/// The goal of this function is to ease debugging because it can be
15305/// called from within type_base::get_canonical_type_for() from the
15306/// prompt of the debugger (with some breakpoint appropriately set) to
15307/// debug the comparison that happens during type canonicalization,
15308/// between a candidate type being canonicalized, and an existing
15309/// canonical type that is registered in the system, in as returned by
15310/// environment::get_canonical_types()
15311///
15312/// @param canonical_type the canonical type to consider.
15313///
15314/// @param candidate_type the candidate type that is being
15315/// canonicalized, and thus compared to @p canonical_type.
15316///
15317/// @return true iff @p canonical_type compares equal to @p
15318/// candidate_type.
15319static bool
15320compare_canonical_type_against_candidate(const type_base* canonical_type,
15321 const type_base* candidate_type)
15322{
15323 return compare_canonical_type_against_candidate(*canonical_type,
15324 *candidate_type);
15325}
15326
15327/// Compare a canonical type against a candidate canonical type.
15328///
15329/// This is ultimately a sub-routine of the
15330/// type_base::get_canonical_type_for().
15331///
15332/// The goal of this function is to ease debugging because it can be
15333/// called from within type_base::get_canonical_type_for() from the
15334/// prompt of the debugger (with some breakpoint appropriately set) to
15335/// debug the comparison that happens during type canonicalization,
15336/// between a candidate type being canonicalized, and an existing
15337/// canonical type that is registered in the system, in as returned by
15338/// environment::get_canonical_types()
15339///
15340/// @param canonical_type the canonical type to consider.
15341///
15342/// @param candidate_type the candidate type that is being
15343/// canonicalized, and thus compared to @p canonical_type.
15344///
15345/// @return true iff @p canonical_type compares equal to @p
15346/// candidate_type.
15347static bool
15348compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15349 const type_base_sptr& candidate_type)
15350{
15351 return compare_canonical_type_against_candidate(canonical_type.get(),
15352 candidate_type.get());
15353}
15354
15355/// Test if a candidate for type canonicalization coming from ABIXML
15356/// matches a canonical type by first looking at their hash values.
15357///
15358/// If the two hash values are equal then the candidate is
15359/// structurally compared to the canonical type. If the two hashes
15360/// are different then the two types are considered different and the
15361/// function returns nullptr.
15362///
15363/// If the candidate doesn't come from ABIXML then the function
15364/// returns nullptr.
15365///
15366/// @param cncls the vector of canonical types to consider.
15367///
15368/// @param type the candidate to consider for canonicalization.
15369///
15370/// @return the canonical type from @p cncls that matches the
15371/// candidate @p type.
15372static type_base_sptr
15373candidate_matches_a_canonical_type_hash(const vector<type_base_sptr>& cncls,
15374 type_base& type)
15375{
15376 if (type.get_corpus()
15377 && type.get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
15378 && peek_hash_value(type))
15379 {
15380 // The candidate type comes from ABIXML and does have a stashed
15381 // hash value coming from the ABIXML.
15382
15383 // Let's see if we find a potential canonical type whose hash
15384 // matches the stashed hash and whose canonical type index
15385 // matches it too.
15386 for (const auto& c : cncls)
15387 if (peek_hash_value(type) == peek_hash_value(*c))
15389 // We found a potential canonical type which hash matches the
15390 // stashed hash of the candidate type. Let's compare them to
15391 // see if they match.
15392 if (compare_canonical_type_against_candidate(*c, type))
15393 return c;
15394
15395 // Let's do the same things, but just consideing hash values.
15396 for (const auto& c : cncls)
15397 if (peek_hash_value(type) == peek_hash_value(*c))
15398 // We found a potential canonical type which hash matches the
15399 // stashed hash of the candidate type. Let's compare them to
15400 // see if they match.
15401 if (compare_canonical_type_against_candidate(*c, type))
15402 return c;
15403 }
15404
15405 return nullptr;
15406}
15407
15408/// Test if we should attempt to compute a hash value for a given
15409/// type.
15410///
15411/// For now this function returns true only for types originating from
15412/// ELF. For types originating from ABIXML, for instance, the
15413/// function return false, meaning that types originating from ABIXML
15414/// should NOT be hashed.
15415///
15416/// @param t the type to consider.
15417///
15418/// @return true iff @p type should be considered for hashing.
15419bool
15421{
15422 if (t.get_corpus()
15423 && (t.get_corpus()->get_origin() & corpus::ELF_ORIGIN))
15424 return true;
15425 return false;
15426}
15427
15428/// Compute the canonical type for a given instance of @ref type_base.
15429///
15430/// Consider two types T and T'. The canonical type of T, denoted
15431/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
15432/// otherwise, to compare two types, one just needs to compare their
15433/// canonical types using pointer equality. That makes type
15434/// comparison faster than the structural comparison performed by the
15435/// abigail::ir::equals() overloads.
15436///
15437/// If there is not yet any canonical type for @p t, then @p t is its
15438/// own canonical type. Otherwise, this function returns the
15439/// canonical type of @p t which is the canonical type that has the
15440/// same hash value as @p t and that structurally equals @p t. Note
15441/// that after invoking this function, the life time of the returned
15442/// canonical time is then equals to the life time of the current
15443/// process.
15444///
15445/// @param t a smart pointer to instance of @ref type_base we want to
15446/// compute a canonical type for.
15447///
15448/// @return the canonical type for the current instance of @ref
15449/// type_base.
15450type_base_sptr
15451type_base::get_canonical_type_for(type_base_sptr t)
15452{
15453 if (!t)
15454 return t;
15455
15456 environment& env = const_cast<environment&>(t->get_environment());
15457
15459 // This type should not be canonicalized!
15460 return type_base_sptr();
15461
15462 if (is_decl(t))
15464
15465 // Look through decl-only types (classes, unions and enums)
15466 bool decl_only_class_equals_definition =
15468
15469 class_or_union_sptr class_or_union = is_class_or_union_type(t);
15470
15471 // In the context of types from C++ or languages where we assume the
15472 // "One Definition Rule", we assume that a declaration-only
15473 // non-anonymous class equals all fully defined classes of the same
15474 // name.
15475 //
15476 // Otherwise, all classes, including declaration-only classes are
15477 // canonicalized and only canonical comparison is going to be used
15478 // in the system.
15479 if (decl_only_class_equals_definition)
15480 if (class_or_union)
15482 return type_base_sptr();
15483
15484 class_decl_sptr is_class = is_class_type(t);
15485 if (t->get_canonical_type())
15486 return t->get_canonical_type();
15487
15488 // For classes and union, ensure that an anonymous class doesn't
15489 // have a linkage name. If it does in the future, then me must be
15490 // mindful that the linkage name respects the type identity
15491 // constraints which states that "if two linkage names are different
15492 // then the two types are different".
15496
15497 // We want the pretty representation of the type, but for an
15498 // internal use, not for a user-facing purpose.
15499 //
15500 // If two classe types Foo are declared, one as a class and the
15501 // other as a struct, but are otherwise equivalent, we want their
15502 // pretty representation to be the same. Hence the 'internal'
15503 // argument of ir::get_pretty_representation() is set to true here.
15504 // So in this case, the pretty representation of Foo is going to be
15505 // "class Foo", regardless of its struct-ness. This also applies to
15506 // composite types which would have "class Foo" as a sub-type.
15507 string repr = t->get_cached_pretty_representation(/*internal=*/true);
15508
15509 // If 't' already has a canonical type 'inside' its corpus
15510 // (t_corpus), then this variable is going to contain that canonical
15511 // type.
15512 type_base_sptr canonical_type_present_in_corpus;
15515
15516 type_base_sptr result;
15517 environment::canonical_types_map_type::iterator i = types.find(repr);
15518
15519 if (i == types.end())
15520 {
15521 vector<type_base_sptr> v;
15522 v.push_back(t);
15523 types[repr] = v;
15524 result = t;
15525 }
15526 else
15527 {
15528 vector<type_base_sptr> &v = i->second;
15529 // Look at the canonical types and if the current candidate type
15530 // coming from abixml has the same hash as one of the canonical
15531 // types, then compare the current candidate with the one with a
15532 // matching hash.
15533 result = candidate_matches_a_canonical_type_hash(v, *t);
15534
15535 // Let's compare 't' structurally (i.e, compare its sub-types
15536 // recursively) against the canonical types of the system. If it
15537 // equals a given canonical type C, then it means C is the
15538 // canonical type of 't'. Otherwise, if 't' is different from
15539 // all the canonical types of the system, then it means 't' is a
15540 // canonical type itself.
15541 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15542 !result && it != v.rend();
15543 ++it)
15544 {
15545 bool equal = compare_canonical_type_against_candidate(*it, t);
15546 if (equal)
15547 {
15548 result = *it;
15549 break;
15550 }
15551 }
15552#ifdef WITH_DEBUG_SELF_COMPARISON
15553 if (env.self_comparison_debug_is_on())
15554 {
15555 // So we are debugging the canonicalization process,
15556 // possibly via the use of 'abidw --debug-abidiff <binary>'.
15557 corpus_sptr corp1, corp2;
15558 env.get_self_comparison_debug_inputs(corp1, corp2);
15559 if (corp1 && corp2 && type_originates_from_corpus(t, corp2)
15560 && corp1->get_origin() != corp2->get_origin()
15561 && corp2->get_origin() & corpus::NATIVE_XML_ORIGIN)
15562 {
15563 // If 't' comes from the second corpus, then it *must*
15564 // be equal to its matching canonical type coming from
15565 // the first corpus because the second corpus is the
15566 // abixml representation of the first corpus. In other
15567 // words, all types coming from the second corpus must
15568 // have canonical types coming from the first corpus.
15569 if (result)
15570 {
15571 if (!env.priv_->
15572 check_canonical_type_from_abixml_during_self_comp(t,
15573 result))
15574 {
15575 // The canonical type of the type re-read from abixml
15576 // type doesn't match the canonical type that was
15577 // initially serialized down.
15578 uintptr_t should_have_canonical_type = 0;
15579 string type_id = env.get_type_id_from_type(t.get());
15580 if (type_id.empty())
15581 type_id = "type-id-<not-found>";
15582 else
15583 should_have_canonical_type =
15584 env.get_canonical_type_from_type_id(type_id.c_str());
15585 std::cerr << "error: wrong canonical type for '"
15586 << repr
15587 << "' / type: @"
15588 << std::hex
15589 << t.get()
15590 << "/ canon: @"
15591 << result.get()
15592 << ", type-id: '"
15593 << type_id
15594 << "'. Should have had canonical type: "
15595 << std::hex
15596 << should_have_canonical_type
15597 << std::dec
15598 << std::endl;
15599 }
15600 }
15601 else //!result
15602 {
15603 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
15604 string type_id = env.get_type_id_from_pointer(ptr_val);
15605 if (type_id.empty())
15606 type_id = "type-id-<not-found>";
15607 // We are in the case where 't' is different from all
15608 // the canonical types of the same name that come from
15609 // the first corpus.
15610 //
15611 // If 't' indeed comes from the second corpus then this
15612 // clearly is a canonicalization failure.
15613 //
15614 // There was a problem either during the serialization
15615 // of 't' into abixml, or during the de-serialization
15616 // from abixml into abigail::ir. Further debugging is
15617 // needed to determine what that root cause problem is.
15618 //
15619 // Note that the first canonicalization problem of this
15620 // kind must be fixed before looking at the subsequent
15621 // ones, because the later might well just be
15622 // consequences of the former.
15623 std::cerr << "error: wrong induced canonical type for '"
15624 << repr
15625 << "' from second corpus"
15626 << ", ptr: " << std::hex << t.get()
15627 << " type-id: " << type_id
15628 << " /hash="
15629 << *t->hash_value()
15630 << std::dec
15631 << std::endl;
15632 }
15633 }
15634 if (result)
15635 {
15636 if (!is_type_decl(t))
15637 if (hash_t t_hash = peek_hash_value(*t))
15638 if (hash_t result_hash = peek_hash_value(*result))
15639 if (t_hash != result_hash)
15640 {
15641 std::cerr << "error: type hash mismatch"
15642 << " between type: '"
15643 << repr
15644 << "' @ "
15645 << std::hex
15646 << t.get()
15647 << "/hash="
15648 << *t->hash_value()
15649 << " and its computed canonical type @"
15650 << std::hex
15651 << result.get()
15652 << "/hash="
15653 << std::hex
15654 << *result->hash_value()
15655 << std::dec
15656 << std::endl;
15657 }
15658 }
15659 }
15660#endif //WITH_DEBUG_SELF_COMPARISON
15661
15662 if (!result)
15663 {
15664 v.push_back(t);
15665 result = t;
15666 // we need to generate a canonical type index to sort these
15667 // types that have the same representation and potentially
15668 // same hash value but are canonically different.
15669 t->priv_->canonical_type_index = v.size();
15670 }
15671 }
15672
15673 return result;
15674}
15675
15676/// This method is invoked automatically right after the current
15677/// instance of @ref class_decl has been canonicalized.
15678void
15680{}
15681
15682/// This is a subroutine of the canonicalize() function.
15683///
15684/// When the canonical type C of type T has just been computed, there
15685/// can be cases where T has member functions that C doesn't have.
15686///
15687/// This is possible because non virtual member functions are not
15688/// taken in account when comparing two types.
15689///
15690/// In that case, this function updates C so that it contains the
15691/// member functions.
15692///
15693/// There can also be cases where C has a method M which is not linked
15694/// to any underlying symbol, whereas in T, M is to link to an
15695/// underlying symbol. In that case, this function updates M in C so
15696/// that it's linked to the same underlying symbol as for M in T.
15697static void
15698maybe_adjust_canonical_type(const type_base_sptr& canonical,
15699 const type_base_sptr& type)
15700{
15701 if (type->get_naked_canonical_type())
15702 return;
15703
15704 class_decl_sptr canonical_class = is_class_type(canonical);
15705
15706 if (class_decl_sptr cl = is_class_type(type))
15707 {
15709 if (canonical_class
15710 && canonical_class.get() != cl.get())
15711 {
15712 // Set symbols of member functions that might be missing
15713 // theirs.
15714 for (class_decl::member_functions::const_iterator i =
15715 cl->get_member_functions().begin();
15716 i != cl->get_member_functions().end();
15717 ++i)
15718 if ((*i)->get_symbol())
15719 {
15720 if (method_decl *m = canonical_class->
15721 find_member_function((*i)->get_linkage_name()))
15722 {
15723 elf_symbol_sptr s1 = (*i)->get_symbol();
15724 if (s1 && !m->get_symbol())
15725 // Method 'm' in the canonical type is not
15726 // linked to the underlying symbol of '*i'.
15727 // Let's link it now. have th
15728 m->set_symbol(s1);
15729 }
15730 else
15731 if (canonical_class->get_corpus()
15732 && cl->get_corpus()
15733 && (cl->get_corpus() == canonical_class->get_corpus()))
15734 // There is a member function defined and publicly
15735 // exported in the other class and the canonical
15736 // class doesn't have that member function. This
15737 // should not have happened! For instance, the
15738 // DWARF reader does merge the member functions of
15739 // classes having the same name so that all of them
15740 // end-up having the same member functions. What's
15741 // going on here?
15743 }
15744
15745 // Set symbols of static data members that might be missing
15746 // theirs.
15747 for (const auto& data_member : cl->get_data_members())
15748 {
15749 if (!get_member_is_static(data_member))
15750 continue;
15751 elf_symbol_sptr sym = data_member->get_symbol();
15752 if (!sym)
15753 continue;
15754 const auto& canonical_data_member =
15755 canonical_class->find_data_member(data_member->get_name());
15756 if (!canonical_data_member)
15757 // Hmmh, maybe we
15758 // should consider
15759 // static data members
15760 // when comparing two
15761 // classes for the
15762 // purpose of type
15763 // canonicalization?
15764 continue;
15765 if (!canonical_data_member->get_symbol())
15766 canonical_data_member->set_symbol(sym);
15767 }
15768 }
15769 }
15770
15771 // Make sure the virtual member functions with exported symbols are
15772 // all added to the set of exported functions of the corpus.
15773
15774 // If we are looking at a non-canonicalized class (for instance, a
15775 // decl-only class that has virtual member functions), let's pretend
15776 // it does have a canonical class so that we can perform the
15777 // necessary virtual member function adjustments
15778 if (class_decl_sptr cl = is_class_type(type))
15780 {
15781 ABG_ASSERT(!canonical_class);
15782 canonical_class = cl;
15783 }
15784
15785 if (canonical_class)
15786 {
15787 if (auto abi_corpus = canonical_class->get_corpus())
15788 {
15789 for (auto& fn : canonical_class->get_member_functions())
15790 {
15791 if (elf_symbol_sptr sym = fn->get_symbol())
15792 {
15793 if (sym->is_defined() && sym->is_public())
15794 {
15795 fn->set_is_in_public_symbol_table(true);
15796 auto b = abi_corpus->get_exported_decls_builder();
15797 b->maybe_add_fn_to_exported_fns(fn.get());
15798 }
15799 else if (!sym->is_defined())
15800 abi_corpus->get_undefined_functions().insert(fn.get());
15801 }
15802 }
15803 }
15804 }
15805
15806 // If an artificial function type equals a non-artfificial one in
15807 // the system, then the canonical type of both should be deemed
15808 // non-artificial. This is important because only non-artificial
15809 // canonical function types are emitted out into abixml, so if don't
15810 // do this we risk missing to emit some function types.
15811 if (is_function_type(type))
15812 if (type->get_is_artificial() != canonical->get_is_artificial())
15813 canonical->set_is_artificial(false);
15814}
15815
15816/// Compute the canonical type of a given type.
15817///
15818/// It means that after invoking this function, comparing the intance
15819/// instance @ref type_base and another one (on which
15820/// type_base::enable_canonical_equality() would have been invoked as
15821/// well) is performed by just comparing the pointer values of the
15822/// canonical types of both types. That equality comparison is
15823/// supposedly faster than structural comparison of the types.
15824///
15825/// @param t a smart pointer to the instance of @ref type_base for
15826/// which to compute the canonical type. After this call,
15827/// t->get_canonical_type() will return the newly computed canonical
15828/// type.
15829///
15830/// @param do_log if true then logs are emitted about canonicalization
15831/// progress.
15832///
15833/// @param show_stats if true and if @p do_log is true as well, then
15834/// more detailed logs are emitted about canonicalization.
15835///
15836/// @return the canonical type computed for @p t.
15837type_base_sptr
15838canonicalize(type_base_sptr t, bool do_log, bool show_stats)
15839{
15840 if (!t)
15841 return t;
15842
15843 if (t->get_canonical_type())
15844 return t->get_canonical_type();
15845
15846 if (do_log && show_stats)
15847 std::cerr << "Canonicalization of type '"
15848 << t->get_pretty_representation(true, true)
15849 << "/@#" << std::hex << t.get() << ": ";
15850
15852
15853 if (do_log && show_stats)
15854 tmr.start();
15855 type_base_sptr canonical = type_base::get_canonical_type_for(t);
15856
15857 if (do_log && show_stats)
15858 tmr.stop();
15859
15860 if (do_log && show_stats)
15861 std::cerr << tmr << "\n";
15862
15863 maybe_adjust_canonical_type(canonical, t);
15864
15865 t->priv_->canonical_type = canonical;
15866 t->priv_->naked_canonical_type = canonical.get();
15867
15868 if (canonical)
15869 if (!t->priv_->canonical_type_index)
15870 t->priv_->canonical_type_index = canonical->priv_->canonical_type_index;
15871
15872 if (class_decl_sptr cl = is_class_type(t))
15873 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
15874 if ((canonical = d->get_canonical_type()))
15875 {
15876 d->priv_->canonical_type = canonical;
15877 d->priv_->naked_canonical_type = canonical.get();
15878 }
15879
15880 if (canonical)
15881 {
15882 if (decl_base_sptr d = is_decl_slow(canonical))
15883 {
15884 scope_decl *scope = d->get_scope();
15885 // Add the canonical type to the set of canonical types
15886 // belonging to its scope.
15887 if (scope)
15888 {
15889 if (is_type(scope))
15890 // The scope in question is itself a type (e.g, a class
15891 // or union). Let's call that type ST. We want to add
15892 // 'canonical' to the set of canonical types belonging
15893 // to ST.
15894 if (type_base_sptr c = is_type(scope)->get_canonical_type())
15895 // We want to add 'canonical' to the set of
15896 // canonical types belonging to the canonical type
15897 // of ST. That way, just looking at the canonical
15898 // type of ST is enough to get the types that belong
15899 // to the scope of the class of equivalence of ST.
15900 scope = is_scope_decl(is_decl(c)).get();
15901 scope->get_canonical_types().insert(canonical);
15902 }
15903 // else, if the type doesn't have a scope, it's not meant to be
15904 // emitted. This can be the case for the result of the
15905 // function strip_typedef, for instance.
15906 }
15907 }
15908
15909 t->on_canonical_type_set();
15910 return canonical;
15911}
15912
15913/// Set the definition of this declaration-only @ref decl_base.
15914///
15915/// @param d the new definition to set.
15916void
15918{
15920 priv_->definition_of_declaration_ = d;
15921 if (type_base *t = is_type(this))
15922 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
15923 t->priv_->canonical_type = canonical_type;
15924
15925 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
15926}
15927
15928/// The constructor of @ref type_base.
15929///
15930/// @param s the size of the type, in bits.
15931///
15932/// @param a the alignment of the type, in bits.
15933type_base::type_base(const environment& e, size_t s, size_t a)
15934 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
15935 priv_(new priv(s, a))
15936{}
15937
15938/// Return the hash value of the current IR node.
15939///
15940/// Note that upon the first invocation, this member functions
15941/// computes the hash value and returns it. Subsequent invocations
15942/// just return the hash value that was previously calculated.
15943///
15944/// @return the hash value of the current IR node.
15945hash_t
15947{
15948 type_base::hash do_hash;
15949 return do_hash(this);
15950}
15951
15952/// Getter of the canonical type of the current instance of @ref
15953/// type_base.
15954///
15955/// @return a smart pointer to the canonical type of the current
15956/// intance of @ref type_base, or an empty smart pointer if the
15957/// current instance of @ref type_base doesn't have any canonical
15958/// type.
15959type_base_sptr
15961{return priv_->canonical_type.lock();}
15962
15963/// Getter of the canonical type pointer.
15964///
15965/// Note that this function doesn't return a smart pointer, but rather
15966/// the underlying pointer managed by the smart pointer. So it's as
15967/// fast as possible. This getter is to be used in code paths that
15968/// are proven to be performance hot spots; especially, when comparing
15969/// sensitive types like class, function, pointers and reference
15970/// types. Those are compared extremely frequently and thus, their
15971/// accessing the canonical type must be fast.
15972///
15973/// @return the canonical type pointer, not managed by a smart
15974/// pointer.
15975type_base*
15977{return priv_->naked_canonical_type;}
15978
15979/// Get the pretty representation of the current type.
15980///
15981/// The pretty representation is retrieved from a cache. If the cache
15982/// is empty, this function computes the pretty representation, put it
15983/// in the cache and returns it.
15984///
15985/// Please note that if this function is called too early in the life
15986/// cycle of the type (before the type is fully constructed), then the
15987/// pretty representation that is cached is going to represent a
15988/// non-complete (and thus wrong) representation of the type. Thus
15989/// this function must be called only once the type is fully
15990/// constructed.
15991///
15992/// @param internal if true, then the pretty representation is to be
15993/// used for purpuses that are internal to the libabigail library
15994/// itself. If you don't know what this means, then you probably
15995/// should set this parameter to "false".
15996///
15997/// @return a reference to a cached @ref interned_string holding the
15998/// pretty representation of the current type.
15999const interned_string&
16001{
16002 if (internal)
16003 {
16004 if (priv_->internal_cached_repr_.empty())
16005 {
16006 string r = ir::get_pretty_representation(this, internal);
16007 priv_->internal_cached_repr_ = get_environment().intern(r);
16008 }
16009 return priv_->internal_cached_repr_;
16010 }
16011
16012 if (priv_->cached_repr_.empty())
16013 {
16014 string r = ir::get_pretty_representation(this, internal);
16015 priv_->cached_repr_ = get_environment().intern(r);
16016 }
16017
16018 return priv_->cached_repr_;
16019}
16020
16021/// Compares two instances of @ref type_base.
16022///
16023/// If the two intances are different, set a bitfield to give some
16024/// insight about the kind of differences there are.
16025///
16026/// @param l the first artifact of the comparison.
16027///
16028/// @param r the second artifact of the comparison.
16029///
16030/// @param k a pointer to a bitfield that gives information about the
16031/// kind of changes there are between @p l and @p r. This one is set
16032/// iff @p is non-null and if the function returns false.
16033///
16034/// Please note that setting k to a non-null value does have a
16035/// negative performance impact because even if @p l and @p r are not
16036/// equal, the function keeps up the comparison in order to determine
16037/// the different kinds of ways in which they are different.
16038///
16039/// @return true if @p l equals @p r, false otherwise.
16040bool
16041equals(const type_base& l, const type_base& r, change_kind* k)
16042{
16043 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
16045 if (!result)
16046 if (k)
16048 ABG_RETURN(result);
16049}
16050
16051/// Return true iff both type declarations are equal.
16052///
16053/// Note that this doesn't test if the scopes of both types are equal.
16054bool
16056{return equals(*this, other, 0);}
16057
16058/// Inequality operator.
16059///
16060///@param other the instance of @ref type_base to compare the current
16061/// instance against.
16062///
16063/// @return true iff the current instance is different from @p other.
16064bool
16066{return !operator==(other);}
16067
16068/// Setter for the size of the type.
16069///
16070/// @param s the new size -- in bits.
16071void
16073{priv_->size_in_bits = s;}
16074
16075/// Getter for the size of the type.
16076///
16077/// @return the size in bits of the type.
16078size_t
16080{return priv_->size_in_bits;}
16081
16082/// Setter for the alignment of the type.
16083///
16084/// @param a the new alignment -- in bits.
16085void
16087{priv_->alignment_in_bits = a;}
16088
16089/// Getter for the alignment of the type.
16090///
16091/// @return the alignment of the type in bits.
16092size_t
16094{return priv_->alignment_in_bits;}
16095
16096/// Default implementation of traversal for types. This function does
16097/// nothing. It must be implemented by every single new type that is
16098/// written.
16099///
16100/// Please look at e.g, class_decl::traverse() for an example of how
16101/// to implement this.
16102///
16103/// @param v the visitor used to visit the type.
16104bool
16106{
16107 if (v.type_node_has_been_visited(this))
16108 return true;
16109
16110 v.visit_begin(this);
16111 bool result = v.visit_end(this);
16113
16114 return result;
16115}
16116
16117type_base::~type_base()
16118{delete priv_;}
16119
16120// </type_base definitions>
16121
16122// <real_type definitions>
16123
16124/// Bitwise OR operator for real_type::modifiers_type.
16125///
16126/// @param l the left-hand side operand.
16127///
16128/// @param r the right-hand side operand.
16129///
16130/// @return the result of the bitwise OR.
16133{
16134 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16135 |
16136 static_cast<unsigned>(r));
16137}
16138
16139/// Bitwise AND operator for real_type::modifiers_type.
16140///
16141/// @param l the left-hand side operand.
16142///
16143/// @param r the right-hand side operand.
16144///
16145/// @return the result of the bitwise AND.
16148{
16149 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16150 &
16151 static_cast<unsigned>(r));
16152}
16153
16154/// Bitwise one's complement operator for real_type::modifiers_type.
16155///
16156/// @param l the left-hand side operand.
16157///
16158/// @param r the right-hand side operand.
16159///
16160/// @return the result of the bitwise one's complement operator.
16163{
16164 return static_cast<real_type::modifiers_type>(~static_cast<unsigned>(l));
16165}
16166
16167/// Bitwise |= operator for real_type::modifiers_type.
16168///
16169/// @param l the left-hand side operand.
16170///
16171/// @param r the right-hand side operand.
16172///
16173/// @return the result of the bitwise |=.
16176{
16177 l = l | r;
16178 return l;
16179}
16180
16181/// Bitwise &= operator for real_type::modifiers_type.
16182///
16183/// @param l the left-hand side operand.
16184///
16185/// @param r the right-hand side operand.
16186///
16187/// @return the result of the bitwise &=.
16190{
16191 l = l & r;
16192 return l;
16193}
16194
16195/// Parse a word containing one real type modifier.
16196///
16197/// A word is considered to be a string of characters that doesn't
16198/// contain any white space.
16199///
16200/// @param word the word to parse. It is considered to be a string of
16201/// characters that doesn't contain any white space.
16202///
16203/// @param modifiers out parameter. It's set by this function to the
16204/// parsed modifier iff the function returned true.
16205///
16206/// @return true iff @word was successfully parsed.
16207static bool
16208parse_real_type_modifier(const string& word,
16209 real_type::modifiers_type &modifiers)
16210{
16211 if (word == "signed")
16212 modifiers |= real_type::SIGNED_MODIFIER;
16213 else if (word == "unsigned")
16214 modifiers |= real_type::UNSIGNED_MODIFIER;
16215 else if (word == "short")
16216 modifiers |= real_type::SHORT_MODIFIER;
16217 else if (word == "long")
16218 modifiers |= real_type::LONG_MODIFIER;
16219 else if (word == "long long")
16220 modifiers |= real_type::LONG_LONG_MODIFIER;
16221 else
16222 return false;
16223
16224 return true;
16225}
16226
16227/// Parse a base type of a real type from a string.
16228///
16229/// @param type_name the type name to parse.
16230///
16231/// @param base out parameter. This is set to the resulting base type
16232/// parsed, iff the function returned true.
16233///
16234/// @return true iff the function could successfully parse the base
16235/// type.
16236static bool
16237parse_base_real_type(const string& type_name,
16239{
16240 if (type_name == "int")
16242 else if (type_name == "char")
16244 else if (type_name == "bool" || type_name == "_Bool")
16246 else if (type_name == "double")
16248 else if (type_name =="float")
16250 else if (type_name == "char16_t")
16252 else if (type_name == "char32_t")
16254 else if (type_name == "wchar_t")
16256 else if (type_name == "__ARRAY_SIZE_TYPE__")
16258 else if (type_name == "sizetype")
16259 base = real_type::SIZE_BASE_TYPE;
16260 else if (type_name == "ssizetype")
16261 base = real_type::SSIZE_BASE_TYPE;
16262 else if (type_name == "bitsizetype")
16263 base = real_type::BIT_SIZE_BASE_TYPE;
16264 else if (type_name == "sbitsizetype")
16265 base = real_type::SBIT_SIZE_BASE_TYPE;
16266 else
16267 return false;
16268
16269 return true;
16270}
16271
16272/// Parse a real type from a string.
16273///
16274/// @param type_name the string containing the real type to parse.
16275///
16276/// @param base out parameter. Is set by this function to the base
16277/// type of the real type, iff the function returned true.
16278///
16279/// @param modifiers out parameter If set by this function to the
16280/// modifier of the real type, iff the function returned true.
16281///
16282/// @return true iff the function could parse a real type from @p
16283/// type_name.
16284static bool
16285parse_real_type(const string& type_name,
16287 real_type::modifiers_type& modifiers)
16288{
16289 string input = type_name;
16290 string::size_type len = input.length();
16291 string::size_type cur_pos = 0, prev_pos = 0;
16292 string cur_word, prev_word;
16293 bool ok = false;
16294
16295 while (cur_pos < len)
16296 {
16297 if (cur_pos < len && isspace(input[cur_pos]))
16298 do
16299 ++cur_pos;
16300 while (cur_pos < len && isspace(input[cur_pos]));
16301
16302 prev_pos = cur_pos;
16303 cur_pos = input.find(' ', prev_pos);
16304 prev_word = cur_word;
16305 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16306
16307 if (cur_pos < len
16308 && cur_word == "long"
16309 && prev_word != "long")
16310 {
16311 if (cur_pos < len && isspace(input[cur_pos]))
16312 do
16313 ++cur_pos;
16314 while (cur_pos < len && isspace(input[cur_pos]));
16315 prev_pos = cur_pos;
16316
16317 cur_pos = input.find(' ', prev_pos);
16318 string saved_prev_word = prev_word;
16319 prev_word = cur_word;
16320 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16321 if (cur_word == "long")
16322 cur_word = "long long";
16323 else
16324 {
16325 cur_pos = prev_pos;
16326 cur_word = prev_word;
16327 prev_word = saved_prev_word;
16328 }
16329 }
16330
16331 if (!parse_real_type_modifier(cur_word, modifiers))
16332 {
16333 if (!parse_base_real_type(cur_word, base))
16334 return false;
16335 else
16336 ok = true;
16337 }
16338 else
16339 ok = true;
16340 }
16341
16342 return ok;
16343}
16344
16345/// Parse a real type from a string.
16346///
16347/// @param str the string containing the real type to parse.
16348///
16349///@param type the resulting @ref real_type. Is set to the result
16350///of the parse, iff the function returns true.
16351///
16352/// @return true iff the function could parse a real type from @p
16353/// str.
16354bool
16355parse_real_type(const string& str, real_type& type)
16356{
16358 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16359
16360 if (!parse_real_type(str, base_type, modifiers))
16361 return false;
16362
16363 // So this is a real type.
16364 real_type int_type(base_type, modifiers);
16365 type = int_type;
16366 return true;
16367}
16368
16369/// Default constructor of the @ref real_type.
16371 : base_(INT_BASE_TYPE),
16372 modifiers_(NO_MODIFIER)
16373{}
16374
16375/// Constructor of the @ref real_type.
16376///
16377/// @param b the base type of the real type.
16378///
16379/// @param m the modifiers of the real type.
16381 : base_(b), modifiers_(m)
16382{}
16383
16384/// Constructor of the @ref real_type.
16385///
16386/// @param the name of the real type to parse to initialize the
16387/// current instance of @ref real_type.
16388real_type::real_type(const string& type_name)
16389 : base_(INT_BASE_TYPE),
16390 modifiers_(NO_MODIFIER)
16391{
16392 bool could_parse = parse_real_type(type_name, base_, modifiers_);
16393 ABG_ASSERT(could_parse);
16394}
16395
16396/// Getter of the base type of the @ref real_type.
16397///
16398/// @return the base type of the @ref real_type.
16401{return base_;}
16402
16403/// Getter of the modifiers bitmap of the @ref real_type.
16404///
16405/// @return the modifiers bitmap of the @ref real_type.
16408{return modifiers_;}
16409
16410/// Setter of the modifiers bitmap of the @ref real_type.
16411///
16412/// @param m the new modifiers.
16413void
16415{modifiers_ = m;}
16416
16417/// Equality operator for the @ref real_type.
16418///
16419/// @param other the other real type to compare against.
16420///
16421/// @return true iff @p other equals the current instance of @ref
16422/// real_type.
16423bool
16425{return base_ == other.base_ && modifiers_ == other.modifiers_;}
16426
16427/// Return the string representation of the current instance of @ref
16428/// real_type.
16429///
16430/// @param internal if true the string representation is to be used
16431/// for internal purposes. In general, it means it's for type
16432/// canonicalization purposes.
16433///
16434/// @return the string representation of the current instance of @ref
16435/// real_type.
16436string
16437real_type::to_string(bool internal) const
16438{
16439 string result;
16440
16441 // Look at modifiers ...
16442 if (modifiers_ & SIGNED_MODIFIER)
16443 result += "signed ";
16444 if (modifiers_ & UNSIGNED_MODIFIER)
16445 result += "unsigned ";
16446 if (!internal)
16447 {
16448 // For canonicalization purposes, we won't emit the "short, long, or
16449 // long long" modifiers. This is because on some platforms, "long
16450 // int" and "long long int" might have the same size. In those
16451 // cases, we want the two types to be equivalent if they have the
16452 // same size. If they don't have the same internal string
16453 // representation, they'd automatically have different canonical
16454 // types and thus be canonically different.
16455 if (modifiers_ & SHORT_MODIFIER)
16456 result += "short ";
16457 if (modifiers_ & LONG_MODIFIER)
16458 result += "long ";
16459 if (modifiers_ & LONG_LONG_MODIFIER)
16460 result += "long long ";
16461 }
16462
16463 // ... and look at base types.
16464 if (base_ == INT_BASE_TYPE)
16465 result += "int";
16466 else if (base_ == CHAR_BASE_TYPE)
16467 result += "char";
16468 else if (base_ == BOOL_BASE_TYPE)
16469 result += "bool";
16470 else if (base_ == DOUBLE_BASE_TYPE)
16471 result += "double";
16472 else if (base_ == FLOAT_BASE_TYPE)
16473 result += "float";
16474 else if (base_ == CHAR16_T_BASE_TYPE)
16475 result += "char16_t";
16476 else if (base_ == CHAR32_T_BASE_TYPE)
16477 result += "char32_t";
16478 else if (base_ == WCHAR_T_BASE_TYPE)
16479 result += "wchar_t";
16480 else if (base_ == ARRAY_SIZE_BASE_TYPE)
16481 result += "__ARRAY_SIZE_TYPE__";
16482 else if (base_ == SIZE_BASE_TYPE)
16483 result += "sizetype";
16484 else if (base_ == SSIZE_BASE_TYPE)
16485 result += "ssizetype";
16486 else if (base_ == BIT_SIZE_BASE_TYPE)
16487 result += "bitsizetype";
16488 else if (base_ == SBIT_SIZE_BASE_TYPE)
16489 result += "sbitsizetype";
16490 return result;
16491}
16492
16493/// Convert the current instance of @ref real_type into its string
16494/// representation.
16495///
16496/// @return the string representation of the current instance of @ref
16497/// real_type.
16498real_type::operator string() const
16499{return to_string();}
16500
16501// </real_type definitions>
16502
16503//<type_decl definitions>
16504
16505/// Constructor.
16506///
16507/// @param env the environment we are operating from.
16508///
16509/// @param name the name of the type declaration.
16510///
16511/// @param size_in_bits the size of the current type_decl, in bits.
16512///
16513/// @param alignment_in_bits the alignment of the current typ, in
16514/// bits.
16515///
16516/// @param locus the source location of the current type declaration.
16517///
16518/// @param linkage_name the linkage_name of the current type declaration.
16519///
16520/// @param vis the visibility of the type declaration.
16521type_decl::type_decl(const environment& env,
16522 const string& name,
16523 size_t size_in_bits,
16524 size_t alignment_in_bits,
16525 const location& locus,
16526 const string& linkage_name,
16527 visibility vis)
16528
16529 : type_or_decl_base(env,
16530 BASIC_TYPE
16531 | ABSTRACT_TYPE_BASE
16532 | ABSTRACT_DECL_BASE),
16533 decl_base(env, name, locus, linkage_name, vis),
16534 type_base(env, size_in_bits, alignment_in_bits)
16535{
16537
16539 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16540 real_type int_type(base_type, modifiers);
16541 if (parse_real_type(name, int_type))
16542 {
16543 // Convert the real_type into its canonical string
16544 // representation.
16545 string real_type_name = int_type;
16546
16547 // Set the name of this type_decl to the canonical string
16548 // representation above
16549 set_name(real_type_name);
16551
16552 if (!get_linkage_name().empty())
16553 set_linkage_name(real_type_name);
16554 }
16555}
16556
16557/// Return the hash value of the current IR node.
16558///
16559/// Note that upon the first invocation, this member functions
16560/// computes the hash value and returns it. Subsequent invocations
16561/// just return the hash value that was previously calculated.
16562///
16563/// @return the hash value of the current IR node.
16564hash_t
16566{
16568 return h;
16569}
16570
16571/// Compares two instances of @ref type_decl.
16572///
16573/// If the two intances are different, set a bitfield to give some
16574/// insight about the kind of differences there are.
16575///
16576/// @param l the first artifact of the comparison.
16577///
16578/// @param r the second artifact of the comparison.
16579///
16580/// @param k a pointer to a bitfield that gives information about the
16581/// kind of changes there are between @p l and @p r. This one is set
16582/// iff @p k is non-null and the function returns false.
16583///
16584/// Please note that setting k to a non-null value does have a
16585/// negative performance impact because even if @p l and @p r are not
16586/// equal, the function keeps up the comparison in order to determine
16587/// the different kinds of ways in which they are different.
16588///
16589/// @return true if @p l equals @p r, false otherwise.
16590bool
16591equals(const type_decl& l, const type_decl& r, change_kind* k)
16592{
16593 bool result = false;
16594
16595 // Consider the types as decls to compare their decls-related
16596 // properties.
16597 result = equals(static_cast<const decl_base&>(l),
16598 static_cast<const decl_base&>(r),
16599 k);
16600 if (!k && !result)
16602
16603 // Now consider the types a "types' to compare their size-related
16604 // properties.
16605 result &= equals(static_cast<const type_base&>(l),
16606 static_cast<const type_base&>(r),
16607 k);
16608 ABG_RETURN(result);
16609}
16610
16611/// Return true if both types equals.
16612///
16613/// This operator re-uses the overload that takes a decl_base.
16614///
16615/// Note that this does not check the scopes of any of the types.
16616///
16617/// @param o the other type_decl to check agains.
16618bool
16620{
16621 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16622 if (!other)
16623 return false;
16624 return *this == *other;
16625}
16626
16627/// Return true if both types equals.
16628///
16629/// Note that this does not check the scopes of any of the types.
16630///
16631/// @param o the other type_decl to check against.
16632bool
16634{
16635 const type_decl* other = dynamic_cast<const type_decl*>(&o);
16636 if (!other)
16637 return false;
16638 return try_canonical_compare(this, other);
16639}
16640
16641/// Return true if both types equals.
16642///
16643/// Note that this does not check the scopes of any of the types.
16644///
16645/// @param o the other type_decl to check against.
16646///
16647/// @return true iff the current isntance equals @p o
16648bool
16650{
16651 const decl_base& other = o;
16652 return *this == other;
16653}
16654
16655/// Return true if both types equals.
16656///
16657/// Note that this does not check the scopes of any of the types.
16658///
16659/// @param o the other type_decl to check against.
16660///
16661/// @return true iff the current isntance equals @p o
16662bool
16664{return !operator==(o);}
16665
16666/// Return true if both types equals.
16667///
16668/// Note that this does not check the scopes of any of the types.
16669///
16670/// @param o the other type_decl to check against.
16671///
16672/// @return true iff the current isntance equals @p o
16673bool
16675{return !operator==(o);}
16676
16677/// Inequality operator.
16678///
16679/// @param o the other type to compare against.
16680///
16681/// @return true iff the current instance is different from @p o.
16682bool
16684{return !operator==(o);}
16685
16686/// Equality operator for @ref type_decl_sptr.
16687///
16688/// @param l the first operand to compare.
16689///
16690/// @param r the second operand to compare.
16691///
16692/// @return true iff @p l equals @p r.
16693bool
16695{
16696 if (!!l != !!r)
16697 return false;
16698 if (l.get() == r.get())
16699 return true;
16700 return *l == *r;
16701}
16702
16703/// Inequality operator for @ref type_decl_sptr.
16704///
16705/// @param l the first operand to compare.
16706///
16707/// @param r the second operand to compare.
16708///
16709/// @return true iff @p l is different from @p r.
16710bool
16712{return !operator==(l, r);}
16713
16714/// Implementation for the virtual qualified name builder for @ref
16715/// type_decl.
16716///
16717/// @param qualified_name the output parameter to hold the resulting
16718/// qualified name.
16719///
16720/// @param internal set to true if the call is intended for an
16721/// internal use (for technical use inside the library itself), false
16722/// otherwise. If you don't know what this is for, then set it to
16723/// false.
16724void
16726 bool internal) const
16727{qualified_name = get_qualified_name(internal);}
16728
16729/// Implementation for the virtual qualified name builder for @ref
16730/// type_decl.
16731///
16732/// @param qualified_name the output parameter to hold the resulting
16733/// qualified name.
16734///
16735/// @param internal set to true if the call is intended for an
16736/// internal use (for technical use inside the library itself), false
16737/// otherwise. If you don't know what this is for, then set it to
16738/// false.
16739const interned_string&
16741{
16742 const environment& env = get_environment();
16743
16744
16745 if (internal)
16746 if (is_real_type(this))
16747 {
16749 {
16750 if (decl_base::priv_->internal_qualified_name_.empty())
16751 decl_base::priv_->internal_qualified_name_ =
16752 env.intern(get_internal_real_type_name(this));
16753 return decl_base::priv_->internal_qualified_name_;
16754 }
16755 else
16756 {
16757 decl_base::priv_->temporary_internal_qualified_name_ =
16758 env.intern(get_internal_real_type_name(this));
16759 return decl_base::priv_->temporary_internal_qualified_name_;
16760 }
16761 }
16762
16763 return decl_base::get_qualified_name(/*internal=*/false);
16764}
16765
16766/// Get the pretty representation of the current instance of @ref
16767/// type_decl.
16768///
16769/// @param internal set to true if the call is intended to get a
16770/// representation of the decl (or type) for the purpose of canonical
16771/// type comparison. This is mainly used in the function
16772/// type_base::get_canonical_type_for().
16773///
16774/// In other words if the argument for this parameter is true then the
16775/// call is meant for internal use (for technical use inside the
16776/// library itself), false otherwise. If you don't know what this is
16777/// for, then set it to false.
16778///
16779/// @param qualified_name if true, names emitted in the pretty
16780/// representation are fully qualified.
16781///
16782/// @return the pretty representatin of the @ref type_decl.
16783string
16785 bool qualified_name) const
16786{
16787 if (internal)
16788 if (is_real_type(this))
16789 return get_internal_real_type_name(this);
16790
16791 if (qualified_name)
16792 return get_qualified_name(internal);
16793 return get_name();
16794}
16795
16796/// This implements the ir_traversable_base::traverse pure virtual
16797/// function.
16798///
16799/// @param v the visitor used on the current instance.
16800///
16801/// @return true if the entire IR node tree got traversed, false
16802/// otherwise.
16803bool
16805{
16806 if (v.type_node_has_been_visited(this))
16807 return true;
16808
16809 v.visit_begin(this);
16810 bool result = v.visit_end(this);
16812
16813 return result;
16814}
16815
16816type_decl::~type_decl()
16817{}
16818//</type_decl definitions>
16819
16820// <scope_type_decl definitions>
16821
16822/// Constructor.
16823///
16824/// @param env the environment we are operating from.
16825///
16826/// @param name the name of the type.
16827///
16828/// @param size_in_bits the size of the type, in bits.
16829///
16830/// @param alignment_in_bits the alignment of the type, in bits.
16831///
16832/// @param locus the source location where the type is defined.
16833///
16834/// @param vis the visibility of the type.
16835scope_type_decl::scope_type_decl(const environment& env,
16836 const string& name,
16837 size_t size_in_bits,
16838 size_t alignment_in_bits,
16839 const location& locus,
16840 visibility vis)
16841 : type_or_decl_base(env,
16842 ABSTRACT_SCOPE_TYPE_DECL
16843 | ABSTRACT_TYPE_BASE
16844 | ABSTRACT_DECL_BASE),
16845 decl_base(env, name, locus, "", vis),
16846 type_base(env, size_in_bits, alignment_in_bits),
16847 scope_decl(env, name, locus)
16848{}
16849
16850/// Compares two instances of @ref scope_type_decl.
16851///
16852/// If the two intances are different, set a bitfield to give some
16853/// insight about the kind of differences there are.
16854///
16855/// @param l the first artifact of the comparison.
16856///
16857/// @param r the second artifact of the comparison.
16858///
16859/// @param k a pointer to a bitfield that gives information about the
16860/// kind of changes there are between @p l and @p r. This one is set
16861/// iff @p k is non-null and the function returns false.
16862///
16863/// Please note that setting k to a non-null value does have a
16864/// negative performance impact because even if @p l and @p r are not
16865/// equal, the function keeps up the comparison in order to determine
16866/// the different kinds of ways in which they are different.
16867///
16868/// @return true if @p l equals @p r, false otherwise.
16869bool
16871{
16872 bool result = equals(static_cast<const scope_decl&>(l),
16873 static_cast<const scope_decl&>(r),
16874 k);
16875
16876 if (!k && !result)
16878
16879 result &= equals(static_cast<const type_base&>(l),
16880 static_cast<const type_base&>(r),
16881 k);
16882
16883 ABG_RETURN(result);
16884}
16885
16886/// Equality operator between two scope_type_decl.
16887///
16888/// Note that this function does not consider the scope of the scope
16889/// types themselves.
16890///
16891/// @return true iff both scope types are equal.
16892bool
16894{
16895 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
16896 if (!other)
16897 return false;
16898 return try_canonical_compare(this, other);
16899}
16900
16901/// Equality operator between two scope_type_decl.
16902///
16903/// This re-uses the equality operator that takes a decl_base.
16904///
16905/// @param o the other scope_type_decl to compare against.
16906///
16907/// @return true iff both scope types are equal.
16908bool
16910{
16911 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16912 if (!other)
16913 return false;
16914
16915 return *this == *other;
16916}
16917
16918/// Traverses an instance of @ref scope_type_decl, visiting all the
16919/// sub-types and decls that it might contain.
16920///
16921/// @param v the visitor that is used to visit every IR sub-node of
16922/// the current node.
16923///
16924/// @return true if either
16925/// - all the children nodes of the current IR node were traversed
16926/// and the calling code should keep going with the traversing.
16927/// - or the current IR node is already being traversed.
16928/// Otherwise, returning false means that the calling code should not
16929/// keep traversing the tree.
16930bool
16932{
16933 if (visiting())
16934 return true;
16935
16936 if (v.type_node_has_been_visited(this))
16937 return true;
16938
16939 if (v.visit_begin(this))
16940 {
16941 visiting(true);
16942 for (scope_decl::declarations::const_iterator i =
16943 get_member_decls().begin();
16944 i != get_member_decls ().end();
16945 ++i)
16946 if (!(*i)->traverse(v))
16947 break;
16948 visiting(false);
16949 }
16950
16951 bool result = v.visit_end(this);
16953
16954 return result;
16955}
16956
16957scope_type_decl::~scope_type_decl()
16958{}
16959// </scope_type_decl definitions>
16960
16961// <namespace_decl>
16962
16963/// Constructor.
16964///
16965/// @param the environment we are operatin from.
16966///
16967/// @param name the name of the namespace.
16968///
16969/// @param locus the source location where the namespace is defined.
16970///
16971/// @param vis the visibility of the namespace.
16973 const string& name,
16974 const location& locus,
16975 visibility vis)
16976 // We need to call the constructor of decl_base directly here
16977 // because it is virtually inherited by scope_decl. Note that we
16978 // just implicitely call the default constructor for scope_decl
16979 // here, as what we really want is to initialize the decl_base
16980 // subobject. Wow, virtual inheritance is useful, but setting it
16981 // up is ugly.
16982 : type_or_decl_base(env,
16983 NAMESPACE_DECL
16984 | ABSTRACT_DECL_BASE
16985 | ABSTRACT_SCOPE_DECL),
16986 decl_base(env, name, locus, "", vis),
16987 scope_decl(env, name, locus)
16988{
16990}
16991
16992/// Build and return a copy of the pretty representation of the
16993/// namespace.
16994///
16995/// @param internal set to true if the call is intended to get a
16996/// representation of the decl (or type) for the purpose of canonical
16997/// type comparison. This is mainly used in the function
16998/// type_base::get_canonical_type_for().
16999///
17000/// In other words if the argument for this parameter is true then the
17001/// call is meant for internal use (for technical use inside the
17002/// library itself), false otherwise. If you don't know what this is
17003/// for, then set it to false.
17004///
17005/// @param qualified_name if true, names emitted in the pretty
17006/// representation are fully qualified.
17007///
17008/// @return a copy of the pretty representation of the namespace.
17009string
17011 bool qualified_name) const
17012{
17013 string r =
17014 "namespace " + scope_decl::get_pretty_representation(internal,
17015 qualified_name);
17016 return r;
17017}
17018
17019/// Return true iff both namespaces and their members are equal.
17020///
17021/// Note that this function does not check if the scope of these
17022/// namespaces are equal.
17023bool
17025{
17026 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
17027 if (!other)
17028 return false;
17029 return scope_decl::operator==(*other);
17030}
17031
17032/// Test if the current namespace_decl is empty or contains empty
17033/// namespaces itself.
17034///
17035/// @return true iff the current namespace_decl is empty or contains
17036/// empty itself.
17037bool
17039{
17040 if (is_empty())
17041 return true;
17042
17043 for (declarations::const_iterator i = get_member_decls().begin();
17044 i != get_member_decls().end();
17045 ++i)
17046 {
17047 if (!is_namespace(*i))
17048 return false;
17049
17051 ABG_ASSERT(ns);
17052
17053 if (!ns->is_empty_or_has_empty_sub_namespaces())
17054 return false;
17055 }
17056
17057 return true;
17058}
17059
17060/// This implements the ir_traversable_base::traverse pure virtual
17061/// function.
17062///
17063/// @param v the visitor used on the current instance and on its
17064/// member nodes.
17065///
17066/// @return true if the entire IR node tree got traversed, false
17067/// otherwise.
17068bool
17070{
17071 if (visiting())
17072 return true;
17073
17074 if (v.visit_begin(this))
17075 {
17076 visiting(true);
17077 scope_decl::declarations::const_iterator i;
17078 for (i = get_member_decls().begin();
17079 i != get_member_decls ().end();
17080 ++i)
17081 {
17083 dynamic_pointer_cast<ir_traversable_base>(*i);
17084 if (t)
17085 if (!t->traverse (v))
17086 break;
17087 }
17088 visiting(false);
17089 }
17090 return v.visit_end(this);
17091}
17092
17093namespace_decl::~namespace_decl()
17094{
17095}
17096
17097// </namespace_decl>
17098
17099// <qualified_type_def>
17100
17101/// Type of the private data of qualified_type_def.
17102class qualified_type_def::priv
17103{
17104 friend class qualified_type_def;
17105
17106 qualified_type_def::CV cv_quals_;
17107 // Before the type is canonicalized, this is used as a temporary
17108 // internal name.
17109 interned_string temporary_internal_name_;
17110 // Once the type is canonicalized, this is used as the internal
17111 // name.
17112 interned_string internal_name_;
17113 weak_ptr<type_base> underlying_type_;
17114
17115 priv()
17116 : cv_quals_(CV_NONE)
17117 {}
17118
17119 priv(qualified_type_def::CV quals,
17120 type_base_sptr t)
17121 : cv_quals_(quals),
17122 underlying_type_(t)
17123 {}
17124
17125 priv(qualified_type_def::CV quals)
17126 : cv_quals_(quals)
17127 {}
17128};// end class qualified_type_def::priv
17129
17130/// Build the name of the current instance of qualified type.
17131///
17132/// @param fully_qualified if true, build a fully qualified name.
17133///
17134/// @param internal set to true if the call is intended for an
17135/// internal use (for technical use inside the library itself), false
17136/// otherwise. If you don't know what this is for, then set it to
17137/// false.
17138///
17139/// @return a copy of the newly-built name.
17140string
17141qualified_type_def::build_name(bool fully_qualified, bool internal) const
17142{
17143 type_base_sptr t = get_underlying_type();
17144 if (!t)
17145 // The qualified type might temporarily have no underlying type,
17146 // especially during the construction of the type, while the
17147 // underlying type is not yet constructed. In that case, let's do
17148 // like if the underlying type is the 'void' type.
17150
17152 fully_qualified,
17153 internal);
17154}
17155
17156/// This function is automatically invoked whenever an instance of
17157/// this type is canonicalized.
17158///
17159/// It's an overload of the virtual type_base::on_canonical_type_set.
17160///
17161/// We put here what is thus meant to be executed only at the point of
17162/// type canonicalization.
17163void
17166
17167/// Constructor of the qualified_type_def
17168///
17169/// @param type the underlying type
17170///
17171/// @param quals a bitfield representing the const/volatile qualifiers
17172///
17173/// @param locus the location of the qualified type definition
17174qualified_type_def::qualified_type_def(type_base_sptr type,
17175 CV quals,
17176 const location& locus)
17177 : type_or_decl_base(type->get_environment(),
17178 QUALIFIED_TYPE
17179 | ABSTRACT_TYPE_BASE
17180 | ABSTRACT_DECL_BASE),
17181 type_base(type->get_environment(), type->get_size_in_bits(),
17182 type->get_alignment_in_bits()),
17183 decl_base(type->get_environment(), "", locus, "",
17184 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
17185 priv_(new priv(quals, type))
17186{
17188 interned_string name = type->get_environment().intern(build_name(false));
17189 set_name(name);
17190}
17191
17192/// Constructor of the qualified_type_def
17193///
17194/// @param env the environment of the type.
17195///
17196/// @param quals a bitfield representing the const/volatile qualifiers
17197///
17198/// @param locus the location of the qualified type definition
17199qualified_type_def::qualified_type_def(const environment& env,
17200 CV quals,
17201 const location& locus)
17202 : type_or_decl_base(env,
17203 QUALIFIED_TYPE
17204 | ABSTRACT_TYPE_BASE
17205 | ABSTRACT_DECL_BASE),
17206 type_base(env, /*size_in_bits=*/0,
17207 /*alignment_in_bits=*/0),
17208 decl_base(env, "", locus, ""),
17209 priv_(new priv(quals))
17210{
17212 // We don't yet have an underlying type. So for naming purpose,
17213 // let's temporarily pretend the underlying type is 'void'.
17214 interned_string name = env.intern("void");
17215 set_name(name);
17216}
17217
17218/// Return the hash value of the current IR node.
17219///
17220/// Note that upon the first invocation, this member functions
17221/// computes the hash value and returns it. Subsequent invocations
17222/// just return the hash value that was previously calculated.
17223///
17224/// @return the hash value of the current IR node.
17225hash_t
17227{
17229 return h;
17230}
17231
17232/// Get the size of the qualified type def.
17233///
17234/// This is an overload for type_base::get_size_in_bits().
17235///
17236/// @return the size of the qualified type.
17237size_t
17239{
17240 size_t s = 0;
17241 if (type_base_sptr ut = get_underlying_type())
17242 {
17243 // We do have the underlying type properly set, so let's make
17244 // the size of the qualified type match the size of its
17245 // underlying type.
17246 s = ut->get_size_in_bits();
17247 if (s != type_base::get_size_in_bits())
17248 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
17249 }
17251}
17252
17253/// Compares two instances of @ref qualified_type_def.
17254///
17255/// If the two intances are different, set a bitfield to give some
17256/// insight about the kind of differences there are.
17257///
17258/// @param l the first artifact of the comparison.
17259///
17260/// @param r the second artifact of the comparison.
17261///
17262/// @param k a pointer to a bitfield that gives information about the
17263/// kind of changes there are between @p l and @p r. This one is set
17264/// iff @p k is non-null and the function returns false.
17265///
17266/// Please note that setting k to a non-null value does have a
17267/// negative performance impact because even if @p l and @p r are not
17268/// equal, the function keeps up the comparison in order to determine
17269/// the different kinds of ways in which they are different.
17270///
17271/// @return true if @p l equals @p r, false otherwise.
17272bool
17274{
17275 bool result = true;
17276 if (l.get_cv_quals() != r.get_cv_quals())
17277 {
17278 result = false;
17279 if (k)
17281 else
17283 }
17284
17286 {
17287 result = false;
17288 if (k)
17289 {
17291 r.get_underlying_type().get()))
17292 // Underlying type changes in which the structure of the
17293 // type changed are considered local changes to the
17294 // qualified type.
17296 else
17297 *k |= SUBTYPE_CHANGE_KIND;
17298 }
17299 else
17300 // okay strictly speaking this is not necessary, but I am
17301 // putting it here to maintenance; that is, so that adding
17302 // subsequent clauses needed to compare two qualified types
17303 // later still works.
17305 }
17306
17307 ABG_RETURN(result);
17308}
17309
17310/// Equality operator for qualified types.
17311///
17312/// Note that this function does not check for equality of the scopes.
17313///
17314///@param o the other qualified type to compare against.
17315///
17316/// @return true iff both qualified types are equal.
17317bool
17319{
17320 const qualified_type_def* other =
17321 dynamic_cast<const qualified_type_def*>(&o);
17322 if (!other)
17323 return false;
17324 return try_canonical_compare(this, other);
17325}
17326
17327/// Equality operator for qualified types.
17328///
17329/// Note that this function does not check for equality of the scopes.
17330/// Also, this re-uses the equality operator above that takes a
17331/// decl_base.
17332///
17333///@param o the other qualified type to compare against.
17334///
17335/// @return true iff both qualified types are equal.
17336bool
17338{
17339 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17340 if (!other)
17341 return false;
17342 return *this == *other;
17343}
17344
17345/// Equality operator for qualified types.
17346///
17347/// Note that this function does not check for equality of the scopes.
17348/// Also, this re-uses the equality operator above that takes a
17349/// decl_base.
17350///
17351///@param o the other qualified type to compare against.
17352///
17353/// @return true iff both qualified types are equal.
17354bool
17356{
17357 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17358 if (!other)
17359 return false;
17360 return *this == *other;
17361}
17362
17363/// Implementation for the virtual qualified name builder for @ref
17364/// qualified_type_def.
17365///
17366/// @param qualified_name the output parameter to hold the resulting
17367/// qualified name.
17368///
17369/// @param internal set to true if the call is intended for an
17370/// internal use (for technical use inside the library itself), false
17371/// otherwise. If you don't know what this is for, then set it to
17372/// false.
17373void
17375 bool internal) const
17376{qualified_name = get_qualified_name(internal);}
17377
17378/// Implementation of the virtual qualified name builder/getter.
17379///
17380/// @param internal set to true if the call is intended for an
17381/// internal use (for technical use inside the library itself), false
17382/// otherwise. If you don't know what this is for, then set it to
17383/// false.
17384///
17385/// @return the resulting qualified name.
17386const interned_string&
17388{
17389 const environment& env = get_environment();
17390
17391
17392 if (!get_canonical_type())
17393 {
17394 // The type hasn't been canonicalized yet. We want to return a
17395 // temporary name that is not cached because the structure of
17396 // this type (and so its name) can change until its
17397 // canonicalized.
17398 if (internal)
17399 {
17400 // We are asked to return a temporary *internal* name.
17401 // Lets compute it and return a reference to where it's
17402 // stored.
17403 if (priv_->temporary_internal_name_.empty())
17404 priv_->temporary_internal_name_ =
17405 env.intern(build_name(true, /*internal=*/true));
17406 return priv_->temporary_internal_name_;
17407 }
17408 else
17409 {
17410 // We are asked to return a temporary non-internal name.
17412 (env.intern(build_name(true, /*internal=*/false)));
17414 }
17415 }
17416 else
17417 {
17418 // The type has already been canonicalized. We want to return
17419 // the definitive name and cache it.
17420 if (internal)
17421 {
17422 if (priv_->internal_name_.empty())
17423 priv_->internal_name_ =
17424 env.intern(build_name(/*qualified=*/true,
17425 /*internal=*/true));
17426 return priv_->internal_name_;
17427 }
17428 else
17429 {
17430 if (peek_qualified_name().empty())
17432 (env.intern(build_name(/*qualified=*/true,
17433 /*internal=*/false)));
17434 return peek_qualified_name();
17435 }
17436 }
17437}
17438
17439/// This implements the ir_traversable_base::traverse pure virtual
17440/// function.
17441///
17442/// @param v the visitor used on the current instance.
17443///
17444/// @return true if the entire IR node tree got traversed, false
17445/// otherwise.
17446bool
17448{
17449 if (v.type_node_has_been_visited(this))
17450 return true;
17451
17452 if (visiting())
17453 return true;
17454
17455 if (v.visit_begin(this))
17456 {
17457 visiting(true);
17458 if (type_base_sptr t = get_underlying_type())
17459 t->traverse(v);
17460 visiting(false);
17461 }
17462 bool result = v.visit_end(this);
17464 return result;
17465}
17466
17467qualified_type_def::~qualified_type_def()
17468{
17469}
17470
17471/// Getter of the const/volatile qualifier bit field
17474{return priv_->cv_quals_;}
17475
17476/// Setter of the const/value qualifiers bit field
17477void
17479{priv_->cv_quals_ = cv_quals;}
17480
17481/// Compute and return the string prefix or suffix representing the
17482/// qualifiers hold by the current instance of @ref
17483/// qualified_type_def.
17484///
17485/// @return the newly-built cv string.
17486string
17488{return get_string_representation_of_cv_quals(priv_->cv_quals_);}
17489
17490/// Getter of the underlying type
17491type_base_sptr
17493{return priv_->underlying_type_.lock();}
17494
17495/// Setter of the underlying type.
17496///
17497/// @param t the new underlying type.
17498void
17500{
17501 ABG_ASSERT(t);
17502 priv_->underlying_type_ = t;
17503 // Now we need to update other properties that depend on the new underlying type.
17504 set_size_in_bits(t->get_size_in_bits());
17505 set_alignment_in_bits(t->get_alignment_in_bits());
17507 set_name(name);
17508 if (scope_decl* s = get_scope())
17509 {
17510 // Now that the name has been updated, we need to update the
17511 // lookup maps accordingly.
17512 scope_decl::declarations::iterator i;
17513 if (s->find_iterator_for_member(this, i))
17515 else
17517 }
17518}
17519
17520/// Non-member equality operator for @ref qualified_type_def
17521///
17522/// @param l the left-hand side of the equality operator
17523///
17524/// @param r the right-hand side of the equality operator
17525///
17526/// @return true iff @p l and @p r equals.
17527bool
17528operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17529{
17530 if (l.get() == r.get())
17531 return true;
17532 if (!!l != !!r)
17533 return false;
17534
17535 return *l == *r;
17536}
17537
17538/// Non-member inequality operator for @ref qualified_type_def
17539///
17540/// @param l the left-hand side of the equality operator
17541///
17542/// @param r the right-hand side of the equality operator
17543///
17544/// @return true iff @p l and @p r equals.
17545bool
17546operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17547{return ! operator==(l, r);}
17548
17549/// Overloaded bitwise OR operator for cv qualifiers.
17552{
17553 return static_cast<qualified_type_def::CV>
17554 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
17555}
17556
17557/// Overloaded bitwise |= operator for cv qualifiers.
17560{
17561 l = l | r;
17562 return l;
17563}
17564
17565/// Overloaded bitwise &= operator for cv qualifiers.
17568{
17569 l = l & r;
17570 return l;
17571}
17572
17573/// Overloaded bitwise AND operator for CV qualifiers.
17576{
17577 return static_cast<qualified_type_def::CV>
17578 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
17579}
17580
17581/// Overloaded bitwise inverting operator for CV qualifiers.
17584{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
17585
17586/// Streaming operator for qualified_type_decl::CV
17587///
17588/// @param o the output stream to serialize the cv qualifier to.
17589///
17590/// @param cv the cv qualifier to serialize.
17591///
17592/// @return the output stream used.
17593std::ostream&
17594operator<<(std::ostream& o, qualified_type_def::CV cv)
17595{
17596 string str;
17597
17598 switch (cv)
17599 {
17600 case qualified_type_def::CV_NONE:
17601 str = "none";
17602 break;
17603 case qualified_type_def::CV_CONST:
17604 str = "const";
17605 break;
17606 case qualified_type_def::CV_VOLATILE:
17607 str = "volatile";
17608 break;
17609 case qualified_type_def::CV_RESTRICT:
17610 str = "restrict";
17611 break;
17612 }
17613
17614 o << str;
17615 return o;
17616}
17617
17618// </qualified_type_def>
17619
17620//<pointer_type_def definitions>
17621
17622/// Private data structure of the @ref pointer_type_def.
17623struct pointer_type_def::priv
17624{
17625 type_base_wptr pointed_to_type_;
17626 type_base* naked_pointed_to_type_;
17627 interned_string internal_qualified_name_;
17628 interned_string temp_internal_qualified_name_;
17629
17630 priv(const type_base_sptr& t)
17631 : pointed_to_type_(type_or_void(t, t->get_environment())),
17632 naked_pointed_to_type_(t.get())
17633 {}
17634
17635 priv()
17636 : naked_pointed_to_type_()
17637 {}
17638}; //end struct pointer_type_def
17639
17640/// This function is automatically invoked whenever an instance of
17641/// this type is canonicalized.
17642///
17643/// It's an overload of the virtual type_base::on_canonical_type_set.
17644///
17645/// We put here what is thus meant to be executed only at the point of
17646/// type canonicalization.
17647void
17650
17651
17652///Constructor of @ref pointer_type_def.
17653///
17654/// @param pointed_to the pointed-to type.
17655///
17656/// @param size_in_bits the size of the type, in bits.
17657///
17658/// @param align_in_bits the alignment of the type, in bits.
17659///
17660/// @param locus the source location where the type was defined.
17661pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
17662 size_t size_in_bits,
17663 size_t align_in_bits,
17664 const location& locus)
17665 : type_or_decl_base(pointed_to->get_environment(),
17666 POINTER_TYPE
17667 | ABSTRACT_TYPE_BASE
17668 | ABSTRACT_DECL_BASE),
17669 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17670 decl_base(pointed_to->get_environment(), "", locus, ""),
17671 priv_(new priv(pointed_to))
17672{
17674 try
17675 {
17676 ABG_ASSERT(pointed_to);
17677 const environment& env = pointed_to->get_environment();
17678 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
17679 string name = (pto ? pto->get_name() : string("void")) + "*";
17680 set_name(env.intern(name));
17681 if (pto)
17682 set_visibility(pto->get_visibility());
17683 }
17684 catch (...)
17685 {}
17686}
17687
17688///Constructor of @ref pointer_type_def.
17689///
17690/// @param env the environment of the type.
17691///
17692/// @param size_in_bits the size of the type, in bits.
17693///
17694/// @param align_in_bits the alignment of the type, in bits.
17695///
17696/// @param locus the source location where the type was defined.
17697pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
17698 size_t alignment_in_bits,
17699 const location& locus)
17700 : type_or_decl_base(env,
17701 POINTER_TYPE
17702 | ABSTRACT_TYPE_BASE
17703 | ABSTRACT_DECL_BASE),
17704 type_base(env, size_in_bits, alignment_in_bits),
17705 decl_base(env, "", locus, ""),
17706 priv_(new priv())
17707{
17709 string name = string("void") + "*";
17710 set_name(env.intern(name));
17711}
17712
17713/// Return the hash value of the current IR node.
17714///
17715/// Note that upon the first invocation, this member functions
17716/// computes the hash value and returns it. Subsequent invocations
17717/// just return the hash value that was previously calculated.
17718///
17719/// @return the hash value of the current IR node.
17720hash_t
17722{
17724 return h;
17725}
17726
17727/// Set the pointed-to type of the pointer.
17728///
17729/// @param t the new pointed-to type.
17730void
17732{
17733 ABG_ASSERT(t);
17734 priv_->pointed_to_type_ = t;
17735 priv_->naked_pointed_to_type_ = t.get();
17736
17737 try
17738 {
17739 const environment& env = t->get_environment();
17740 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
17741 string name = (pto ? pto->get_name() : string("void")) + "*";
17742 set_name(env.intern(name));
17743 if (pto)
17744 set_visibility(pto->get_visibility());
17745 }
17746 catch (...)
17747 {}
17748}
17749
17750/// Compares two instances of @ref pointer_type_def.
17751///
17752/// If the two intances are different, set a bitfield to give some
17753/// insight about the kind of differences there are.
17754///
17755/// @param l the first artifact of the comparison.
17756///
17757/// @param r the second artifact of the comparison.
17758///
17759/// @param k a pointer to a bitfield that gives information about the
17760/// kind of changes there are between @p l and @p r. This one is set
17761/// iff @p k is non-null and the function returns false.
17762///
17763/// Please note that setting k to a non-null value does have a
17764/// negative performance impact because even if @p l and @p r are not
17765/// equal, the function keeps up the comparison in order to determine
17766/// the different kinds of ways in which they are different.
17767///
17768/// @return true if @p l equals @p r, false otherwise.
17769bool
17771{
17772 // Let's peel typedefs from the pointed-to-type so that a pointer to
17773 // T and a pointer to typedef-of-T are the same. Otherwise, that
17774 // leads to subtle irrelevant comparison errors down the road.
17775 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
17776 p1 = peel_typedef_type(p1);
17777 p2 = peel_typedef_type(p2);
17778 bool result = p1 == p2;
17779 if (!result)
17780 if (k)
17781 {
17782 if (!types_have_similar_structure(&l, &r))
17783 // pointed-to type changes in which the structure of the
17784 // type changed are considered local changes to the pointer
17785 // type.
17787 *k |= SUBTYPE_CHANGE_KIND;
17788 }
17789
17790 ABG_RETURN(result);
17791}
17792
17793/// Return true iff both instances of pointer_type_def are equal.
17794///
17795/// Note that this function does not check for the scopes of the this
17796/// types.
17797bool
17799{
17800 const pointer_type_def* other = is_pointer_type(&o);
17801 if (!other)
17802 return false;
17803 return try_canonical_compare(this, other);
17804}
17805
17806/// Return true iff both instances of pointer_type_def are equal.
17807///
17808/// Note that this function does not check for the scopes of the
17809/// types.
17810///
17811/// @param other the other type to compare against.
17812///
17813/// @return true iff @p other equals the current instance.
17814bool
17816{
17817 const decl_base* o = is_decl(&other);
17818 if (!o)
17819 return false;
17820 return *this == *o;
17821}
17822
17823/// Return true iff both instances of pointer_type_def are equal.
17824///
17825/// Note that this function does not check for the scopes of the
17826/// types.
17827///
17828/// @param other the other type to compare against.
17829///
17830/// @return true iff @p other equals the current instance.
17831bool
17833{
17834 const decl_base& o = other;
17835 return *this == o;
17836}
17837
17838/// Getter of the pointed-to type.
17839///
17840/// @return the pointed-to type.
17841const type_base_sptr
17843{return priv_->pointed_to_type_.lock();}
17844
17845/// Getter of a naked pointer to the pointed-to type.
17846///
17847/// @return a naked pointed to the pointed-to type.
17848type_base*
17850{return priv_->naked_pointed_to_type_;}
17851
17852/// Build and return the qualified name of the current instance of
17853/// @ref pointer_type_def.
17854///
17855/// @param qn output parameter. The resulting qualified name.
17856///
17857/// @param internal set to true if the call is intended for an
17858/// internal use (for technical use inside the library itself), false
17859/// otherwise. If you don't know what this is for, then set it to
17860/// false.
17861void
17863{qn = get_qualified_name(internal);}
17864
17865/// Build, cache and return the qualified name of the current instance
17866/// of @ref pointer_type_def. Subsequent invocations of this function
17867/// return the cached value.
17868///
17869/// Note that this function should work even if the underlying type is
17870/// momentarily empty.
17871///
17872/// @param internal set to true if the call is intended for an
17873/// internal use (for technical use inside the library itself), false
17874/// otherwise. If you don't know what this is for, then set it to
17875/// false.
17876///
17877/// @return the resulting qualified name.
17878const interned_string&
17880{
17881 type_base* pointed_to_type = get_naked_pointed_to_type();
17882 pointed_to_type = look_through_decl_only_type(pointed_to_type);
17883
17884 if (internal)
17885 {
17886 if (get_canonical_type())
17887 {
17888 if (priv_->internal_qualified_name_.empty())
17889 if (pointed_to_type)
17890 priv_->internal_qualified_name_ =
17891 pointer_declaration_name(this,
17892 /*variable_name=*/"",
17893 /*qualified_name=*/
17894 is_typedef(pointed_to_type)
17895 ? false
17896 : true,
17897 /*internal=*/true);
17898 return priv_->internal_qualified_name_;
17899 }
17900 else
17901 {
17902 // As the type hasn't yet been canonicalized, its structure
17903 // (and so its name) can change. So let's invalidate the
17904 // cache where we store its name at each invocation of this
17905 // function.
17906 if (pointed_to_type)
17907 if (priv_->temp_internal_qualified_name_.empty())
17908 priv_->temp_internal_qualified_name_ =
17909 pointer_declaration_name(this,
17910 /*variable_name=*/"",
17911 /*qualified_name=*/
17912 is_typedef(pointed_to_type)
17913 ? false
17914 : true,
17915 /*internal=*/true);
17916 return priv_->temp_internal_qualified_name_;
17917 }
17918 }
17919 else
17920 {
17922 {
17923 if (decl_base::peek_qualified_name().empty())
17925 (pointer_declaration_name(this,
17926 /*variable_name=*/"",
17927 /*qualified_name=*/true,
17928 /*internal=*/false));
17930 }
17931 else
17932 {
17933 // As the type hasn't yet been canonicalized, its structure
17934 // (and so its name) can change. So let's invalidate the
17935 // cache where we store its name at each invocation of this
17936 // function.
17937 if (pointed_to_type)
17939 (pointer_declaration_name(this,
17940 /*variable_name=*/"",
17941 /*qualified_name=*/true,
17942 /*internal=*/false));
17944 }
17945 }
17946}
17947
17948/// This implements the ir_traversable_base::traverse pure virtual
17949/// function.
17950///
17951/// @param v the visitor used on the current instance.
17952///
17953/// @return true if the entire IR node tree got traversed, false
17954/// otherwise.
17955bool
17957{
17958 if (v.type_node_has_been_visited(this))
17959 return true;
17960
17961 if (visiting())
17962 return true;
17963
17964 if (v.visit_begin(this))
17965 {
17966 visiting(true);
17967 if (type_base_sptr t = get_pointed_to_type())
17968 t->traverse(v);
17969 visiting(false);
17970 }
17971
17972 bool result = v.visit_end(this);
17974 return result;
17975}
17976
17977pointer_type_def::~pointer_type_def()
17978{}
17979
17980/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
17981/// equality; that is, make it compare the pointed to objects too.
17982///
17983/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
17984/// of the equality.
17985///
17986/// @param r the shared_ptr of @ref pointer_type_def on
17987/// right-hand-side of the equality.
17988///
17989/// @return true if the @ref pointer_type_def pointed to by the
17990/// shared_ptrs are equal, false otherwise.
17991bool
17993{
17994 if (l.get() == r.get())
17995 return true;
17996 if (!!l != !!r)
17997 return false;
17998
17999 return *l == *r;
18000}
18001
18002/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
18003/// equality; that is, make it compare the pointed to objects too.
18004///
18005/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18006/// of the equality.
18007///
18008/// @param r the shared_ptr of @ref pointer_type_def on
18009/// right-hand-side of the equality.
18010///
18011/// @return true iff the @ref pointer_type_def pointed to by the
18012/// shared_ptrs are different.
18013bool
18015{return !operator==(l, r);}
18016
18017// </pointer_type_def definitions>
18018
18019// <reference_type_def definitions>
18020
18021/// Private data structure of the @ref reference_type_def type.
18022struct reference_type_def::priv
18023{
18024
18025 type_base_wptr pointed_to_type_;
18026 bool is_lvalue_;
18027 interned_string internal_qualified_name_;
18028 interned_string temp_internal_qualified_name_;
18029
18030 priv(const type_base_sptr& t, bool is_lvalue)
18031 : pointed_to_type_(type_or_void(t, t->get_environment())),
18032 is_lvalue_(is_lvalue)
18033 {}
18034
18035 priv(bool is_lvalue)
18036 : is_lvalue_(is_lvalue)
18037 {}
18038
18039 priv() = delete;
18040};
18041
18042/// This function is automatically invoked whenever an instance of
18043/// this type is canonicalized.
18044///
18045/// It's an overload of the virtual type_base::on_canonical_type_set.
18046///
18047/// We put here what is thus meant to be executed only at the point of
18048/// type canonicalization.
18049void
18052
18053/// Constructor of the reference_type_def type.
18054///
18055/// @param pointed_to the pointed to type.
18056///
18057/// @param lvalue wether the reference is an lvalue reference. If
18058/// false, the reference is an rvalue one.
18059///
18060/// @param size_in_bits the size of the type, in bits.
18061///
18062/// @param align_in_bits the alignment of the type, in bits.
18063///
18064/// @param locus the source location of the type.
18065reference_type_def::reference_type_def(const type_base_sptr pointed_to,
18066 bool lvalue,
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 REFERENCE_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, lvalue))
18077{
18079
18080 try
18081 {
18082 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18083 string name;
18084 if (pto)
18085 {
18086 set_visibility(pto->get_visibility());
18087 name = string(pto->get_name()) + "&";
18088 }
18089 else
18090 name = string(get_type_name(is_function_type(pointed_to),
18091 /*qualified_name=*/true)) + "&";
18092
18093 if (!is_lvalue())
18094 name += "&";
18095 const environment& env = pointed_to->get_environment();
18096 set_name(env.intern(name));
18097 }
18098 catch (...)
18099 {}
18100}
18101
18102/// Constructor of the reference_type_def type.
18103///
18104/// This one creates a type that has no pointed-to type, temporarily.
18105/// This is useful for cases where the underlying type is not yet
18106/// available. It can be set later using
18107/// reference_type_def::set_pointed_to_type().
18108///
18109/// @param env the environment of the type.
18110///
18111/// @param lvalue wether the reference is an lvalue reference. If
18112/// false, the reference is an rvalue one.
18113///
18114/// @param size_in_bits the size of the type, in bits.
18115///
18116/// @param align_in_bits the alignment of the type, in bits.
18117///
18118/// @param locus the source location of the type.
18119reference_type_def::reference_type_def(const environment& env, bool lvalue,
18120 size_t size_in_bits,
18121 size_t alignment_in_bits,
18122 const location& locus)
18123 : type_or_decl_base(env,
18124 REFERENCE_TYPE
18125 | ABSTRACT_TYPE_BASE
18126 | ABSTRACT_DECL_BASE),
18127 type_base(env, size_in_bits, alignment_in_bits),
18128 decl_base(env, "", locus, ""),
18129 priv_(new priv(lvalue))
18130{
18132 string name = "void&";
18133 if (!is_lvalue())
18134 name += "&";
18135
18136 set_name(env.intern(name));
18137 priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
18138}
18139
18140/// Return the hash value of the current IR node.
18141///
18142/// Note that upon the first invocation, this member functions
18143/// computes the hash value and returns it. Subsequent invocations
18144/// just return the hash value that was previously calculated.
18145///
18146/// @return the hash value of the current IR node.
18147hash_t
18149{
18151 return h;
18152}
18153
18154/// Setter of the pointed_to type of the current reference type.
18155///
18156/// @param pointed_to the new pointed to type.
18157void
18158reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
18159{
18160 ABG_ASSERT(pointed_to_type);
18161 priv_->pointed_to_type_ = pointed_to_type;
18162
18163 decl_base_sptr pto;
18164 try
18165 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
18166 catch (...)
18167 {}
18168
18169 if (pto)
18170 {
18171 set_visibility(pto->get_visibility());
18172 string name = string(pto->get_name()) + "&";
18173 if (!is_lvalue())
18174 name += "&";
18175 const environment& env = pto->get_environment();
18176 set_name(env.intern(name));
18177 }
18178}
18179
18180/// Compares two instances of @ref reference_type_def.
18181///
18182/// If the two intances are different, set a bitfield to give some
18183/// insight about the kind of differences there are.
18184///
18185/// @param l the first artifact of the comparison.
18186///
18187/// @param r the second artifact of the comparison.
18188///
18189/// @param k a pointer to a bitfield that gives information about the
18190/// kind of changes there are between @p l and @p r. This one is set
18191/// iff @p k is non-null and the function returns false.
18192///
18193/// Please note that setting k to a non-null value does have a
18194/// negative performance impact because even if @p l and @p r are not
18195/// equal, the function keeps up the comparison in order to determine
18196/// the different kinds of ways in which they are different.
18197///
18198/// @return true if @p l equals @p r, false otherwise.
18199bool
18201{
18202 if (l.is_lvalue() != r.is_lvalue())
18203 {
18204 if (k)
18207 }
18208
18209 // Let's peel typedefs from the pointed-to-type so that a pointer to
18210 // T and a pointer to typedef-of-T are the same. Otherwise, that
18211 // might leads to subtle irrelevant comparison errors down the road.
18212 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18213 p1 = peel_typedef_type(p1);
18214 p2 = peel_typedef_type(p2);
18215 bool result = p1 == p2;
18216 if (!result)
18217 if (k)
18218 {
18219 if (!types_have_similar_structure(&l, &r))
18221 *k |= SUBTYPE_CHANGE_KIND;
18222 }
18223 ABG_RETURN(result);
18224}
18225
18226/// Equality operator of the @ref reference_type_def type.
18227///
18228/// @param o the other instance of @ref reference_type_def to compare
18229/// against.
18230///
18231/// @return true iff the two instances are equal.
18232bool
18234{
18235 const reference_type_def* other =
18236 dynamic_cast<const reference_type_def*>(&o);
18237 if (!other)
18238 return false;
18239 return try_canonical_compare(this, other);
18240}
18241
18242/// Equality operator of the @ref reference_type_def type.
18243///
18244/// @param o the other instance of @ref reference_type_def to compare
18245/// against.
18246///
18247/// @return true iff the two instances are equal.
18248bool
18250{
18251 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18252 if (!other)
18253 return false;
18254 return *this == *other;
18255}
18256
18257/// Equality operator of the @ref reference_type_def type.
18258///
18259/// @param o the other instance of @ref reference_type_def to compare
18260/// against.
18261///
18262/// @return true iff the two instances are equal.
18263bool
18265{
18266 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18267 if (!other)
18268 return false;
18269 return *this == *other;
18270}
18271
18272type_base_sptr
18273reference_type_def::get_pointed_to_type() const
18274{return priv_->pointed_to_type_.lock();}
18275
18276bool
18277reference_type_def::is_lvalue() const
18278{return priv_->is_lvalue_;}
18279
18280/// Build and return the qualified name of the current instance of the
18281/// @ref reference_type_def.
18282///
18283/// @param qn output parameter. Is set to the newly-built qualified
18284/// name of the current instance of @ref reference_type_def.
18285///
18286/// @param internal set to true if the call is intended for an
18287/// internal use (for technical use inside the library itself), false
18288/// otherwise. If you don't know what this is for, then set it to
18289/// false.
18290void
18292{qn = get_qualified_name(internal);}
18293
18294/// Build, cache and return the qualified name of the current instance
18295/// of the @ref reference_type_def. Subsequent invocations of this
18296/// function return the cached value.
18297///
18298/// @param internal set to true if the call is intended for an
18299/// internal use (for technical use inside the library itself), false
18300/// otherwise. If you don't know what this is for, then set it to
18301/// false.
18302///
18303/// @return the newly-built qualified name of the current instance of
18304/// @ref reference_type_def.
18305const interned_string&
18307{
18308 type_base_sptr pointed_to_type = get_pointed_to_type();
18309 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18310
18311 if (internal)
18312 {
18313 if (get_canonical_type())
18314 {
18315 if (priv_->internal_qualified_name_.empty())
18316 if (pointed_to_type)
18317 priv_->internal_qualified_name_ =
18318 get_name_of_reference_to_type(*pointed_to_type,
18319 is_lvalue(),
18320 /*qualified_name=*/
18321 is_typedef(pointed_to_type)
18322 ? false
18323 : true,
18324 /*internal=*/true);
18325 return priv_->internal_qualified_name_;
18326 }
18327 else
18328 {
18329 // As the type hasn't yet been canonicalized, its structure
18330 // (and so its name) can change. So let's invalidate the
18331 // cache where we store its name at each invocation of this
18332 // function.
18333 if (pointed_to_type)
18334 if (priv_->temp_internal_qualified_name_.empty())
18335 priv_->temp_internal_qualified_name_ =
18336 get_name_of_reference_to_type(*pointed_to_type,
18337 is_lvalue(),
18338 /*qualified_name=*/
18339 is_typedef(pointed_to_type)
18340 ? false
18341 : true,
18342 /*internal=*/true);
18343 return priv_->temp_internal_qualified_name_;
18344 }
18345 }
18346 else
18347 {
18349 {
18351 (get_name_of_reference_to_type(*pointed_to_type,
18352 is_lvalue(),
18353 /*qualified_name=*/true,
18354 /*internal=*/false));
18356 }
18357 else
18358 {
18359 // As the type hasn't yet been canonicalized, its structure
18360 // (and so its name) can change. So let's invalidate the
18361 // cache where we store its name at each invocation of this
18362 // function.
18363 if (pointed_to_type)
18365 (get_name_of_reference_to_type(*pointed_to_type,
18366 is_lvalue(),
18367 /*qualified_name=*/true,
18368 /*internal=*/false));
18370 }
18371 }
18372}
18373
18374/// Get the pretty representation of the current instance of @ref
18375/// reference_type_def.
18376///
18377/// @param internal set to true if the call is intended to get a
18378/// representation of the decl (or type) for the purpose of canonical
18379/// type comparison. This is mainly used in the function
18380/// type_base::get_canonical_type_for().
18381///
18382/// In other words if the argument for this parameter is true then the
18383/// call is meant for internal use (for technical use inside the
18384/// library itself), false otherwise. If you don't know what this is
18385/// for, then set it to false.
18386///
18387/// @param qualified_name if true, names emitted in the pretty
18388/// representation are fully qualified.
18389///
18390/// @return the pretty representatin of the @ref reference_type_def.
18391string
18393 bool qualified_name) const
18394{
18395 string result =
18397 (get_pointed_to_type()),
18398 is_lvalue(),
18399 qualified_name,
18400 internal);
18401
18402 return result;
18403}
18404
18405/// This implements the ir_traversable_base::traverse pure virtual
18406/// function.
18407///
18408/// @param v the visitor used on the current instance.
18409///
18410/// @return true if the entire IR node tree got traversed, false
18411/// otherwise.
18412bool
18414{
18415 if (v.type_node_has_been_visited(this))
18416 return true;
18417
18418 if (visiting())
18419 return true;
18420
18421 if (v.visit_begin(this))
18422 {
18423 visiting(true);
18424 if (type_base_sptr t = get_pointed_to_type())
18425 t->traverse(v);
18426 visiting(false);
18427 }
18428
18429 bool result = v.visit_end(this);
18431 return result;
18432}
18433
18434reference_type_def::~reference_type_def()
18435{}
18436
18437/// Turn equality of shared_ptr of @ref reference_type_def into a deep
18438/// equality; that is, make it compare the pointed to objects too.
18439///
18440/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18441/// of the equality.
18442///
18443/// @param r the shared_ptr of @ref reference_type_def on
18444/// right-hand-side of the equality.
18445///
18446/// @return true if the @ref reference_type_def pointed to by the
18447/// shared_ptrs are equal, false otherwise.
18448bool
18450{
18451 if (l.get() == r.get())
18452 return true;
18453 if (!!l != !!r)
18454 return false;
18455
18456 return *l == *r;
18457}
18458
18459/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
18460/// equality; that is, make it compare the pointed to objects too.
18461///
18462/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18463/// of the equality.
18464///
18465/// @param r the shared_ptr of @ref reference_type_def on
18466/// right-hand-side of the equality.
18467///
18468/// @return true iff the @ref reference_type_def pointed to by the
18469/// shared_ptrs are different.
18470bool
18472{return !operator==(l, r);}
18473
18474// </reference_type_def definitions>
18475
18476// <ptr_to_mbr_type definitions>
18477
18478/// The private data type of @ref ptr_to_mbr_type.
18479struct ptr_to_mbr_type::priv
18480{
18481 // The type of the data member this pointer-to-member-type
18482 // designates.
18483 type_base_sptr dm_type_;
18484 // The class (or typedef to potentially qualified class) containing
18485 // the data member this pointer-to-member-type designates.
18486 type_base_sptr containing_type_;
18487 interned_string internal_qualified_name_;
18488 interned_string temp_internal_qualified_name_;
18489
18490 priv()
18491 {}
18492
18493 priv(const type_base_sptr& dm_type, const type_base_sptr& containing_type)
18494 : dm_type_(dm_type),
18495 containing_type_(containing_type)
18496 {}
18497};// end struct ptr_to_mbr_type::priv
18498
18499/// A constructor for a @ref ptr_to_mbr_type type.
18500///
18501/// @param env the environment to construct the @ref ptr_to_mbr_type in.
18502///
18503/// @param member_type the member type of the of the @ref
18504/// ptr_to_mbr_type to construct.
18505///
18506/// @param containing_type the containing type of the @ref
18507/// ptr_to_mbr_type to construct.
18508///
18509/// @param size_in_bits the size (in bits) of the resulting type.
18510///
18511/// @param alignment_in_bits the alignment (in bits) of the resulting
18512/// type.
18513///
18514/// @param locus the source location of the definition of the
18515/// resulting type.
18516ptr_to_mbr_type::ptr_to_mbr_type(const environment& env,
18517 const type_base_sptr& member_type,
18518 const type_base_sptr& containing_type,
18519 size_t size_in_bits,
18520 size_t alignment_in_bits,
18521 const location& locus)
18522 : type_or_decl_base(env,
18523 POINTER_TO_MEMBER_TYPE
18524 | ABSTRACT_TYPE_BASE
18525 | ABSTRACT_DECL_BASE),
18526 type_base(env, size_in_bits, alignment_in_bits),
18527 decl_base(env, "", locus, ""),
18528 priv_(new priv(member_type, containing_type))
18529{
18531 ABG_ASSERT(member_type);
18532 ABG_ASSERT(containing_type);
18533 set_is_anonymous(false);
18534}
18535
18536/// Getter of the name of the current ptr-to-mbr-type.
18537///
18538/// This just returns the qualified name.
18539///
18540/// @return the (qualified) name of the the type.
18541const interned_string&
18543{
18544 return get_qualified_name(/*internal=*/false);
18545}
18546
18547/// Return the hash value of the current IR node.
18548///
18549/// Note that upon the first invocation, this member functions
18550/// computes the hash value and returns it. Subsequent invocations
18551/// just return the hash value that was previously calculated.
18552///
18553/// @return the hash value of the current IR node.
18554hash_t
18556{
18558 return h;
18559}
18560
18561/// Getter of the member type of the current @ref ptr_to_mbr_type.
18562///
18563/// @return the type of the member referred to by the current
18564/// @ptr_to_mbr_type.
18565const type_base_sptr&
18567{return priv_->dm_type_;}
18568
18569/// Getter of the type containing the member pointed-to by the current
18570/// @ref ptr_to_mbr_type.
18571///
18572/// @return the type containing the member pointed-to by the current
18573/// @ref ptr_to_mbr_type.
18574const type_base_sptr&
18576{return priv_->containing_type_;}
18577
18578/// Equality operator for the current @ref ptr_to_mbr_type.
18579///
18580///@param o the other instance of @ref ptr_to_mbr_type to compare the
18581///current instance to.
18582///
18583/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18584bool
18586{
18587 const ptr_to_mbr_type* other =
18588 dynamic_cast<const ptr_to_mbr_type*>(&o);
18589 if (!other)
18590 return false;
18591 return try_canonical_compare(this, other);
18592}
18593
18594/// Equality operator for the current @ref ptr_to_mbr_type.
18595///
18596///@param o the other instance of @ref ptr_to_mbr_type to compare the
18597///current instance to.
18598///
18599/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18600bool
18602{
18603 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18604 if (!other)
18605 return false;
18606 return *this == *other;
18607}
18608
18609/// Equality operator for the current @ref ptr_to_mbr_type.
18610///
18611///@param o the other instance of @ref ptr_to_mbr_type to compare the
18612///current instance to.
18613///
18614/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18615bool
18617{
18618 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18619 if (!other)
18620 return false;
18621 return *this == *other;
18622}
18623
18624/// Get the qualified name for the current @ref ptr_to_mbr_type.
18625///
18626/// @param qualified_name out parameter. This is set to the name of
18627/// the current @ref ptr_to_mbr_type.
18628///
18629/// @param internal if this is true, then the qualified name is for
18630/// the purpose of type canoicalization.
18631void
18633 bool internal) const
18634{qualified_name = get_qualified_name(internal);}
18635
18636/// Get the qualified name for the current @ref ptr_to_mbr_type.
18637///
18638/// @param internal if this is true, then the qualified name is for
18639/// the purpose of type canoicalization.
18640///
18641/// @return the qualified name for the current @ref ptr_to_mbr_type.
18642const interned_string&
18644{
18645 type_base_sptr member_type = get_member_type();
18646 type_base_sptr containing_type = get_containing_type();
18647
18648 if (internal)
18649 {
18650 if (get_canonical_type())
18651 {
18652 if (priv_->internal_qualified_name_.empty())
18653 priv_->internal_qualified_name_ =
18654 ptr_to_mbr_declaration_name(this, "",
18655 /*qualified=*/true,
18656 internal);
18657 return priv_->internal_qualified_name_;
18658 }
18659 else
18660 {
18661 priv_->temp_internal_qualified_name_ =
18662 ptr_to_mbr_declaration_name(this, "", /*qualified=*/true, internal);
18663 return priv_->temp_internal_qualified_name_;
18664 }
18665 }
18666 else
18667 {
18669 (ptr_to_mbr_declaration_name(this, "", /*qualified=*/true,
18670 /*internal=*/false));
18672 }
18673}
18674
18675/// This implements the ir_traversable_base::traverse pure virtual
18676/// function for @ref ptr_to_mbr_type.
18677///
18678/// @param v the visitor used on the current instance.
18679///
18680/// @return true if the entire IR node tree got traversed, false
18681/// otherwise.
18682bool
18684{
18685 if (v.type_node_has_been_visited(this))
18686 return true;
18687
18688 if (visiting())
18689 return true;
18690
18691 if (v.visit_begin(this))
18692 {
18693 visiting(true);
18694 if (type_base_sptr t = get_member_type())
18695 t->traverse(v);
18696
18697 if (type_base_sptr t = get_containing_type())
18698 t->traverse(v);
18699 visiting(false);
18700 }
18701
18702 bool result = v.visit_end(this);
18704 return result;
18705}
18706
18707/// Desctructor for @ref ptr_to_mbr_type.
18709{}
18710
18711
18712/// Compares two instances of @ref ptr_to_mbr_type.
18713///
18714/// If the two intances are different, set a bitfield to give some
18715/// insight about the kind of differences there are.
18716///
18717/// @param l the first artifact of the comparison.
18718///
18719/// @param r the second artifact of the comparison.
18720///
18721/// @param k a pointer to a bitfield that gives information about the
18722/// kind of changes there are between @p l and @p r. This one is set
18723/// iff @p k is non-null and the function returns false.
18724///
18725/// Please note that setting k to a non-null value does have a
18726/// negative performance impact because even if @p l and @p r are not
18727/// equal, the function keeps up the comparison in order to determine
18728/// the different kinds of ways in which they are different.
18729///
18730/// @return true if @p l equals @p r, false otherwise.
18731bool
18733{
18734 bool result = true;
18735
18736 if (!(l.decl_base::operator==(r)))
18737 {
18738 result = false;
18739 if (k)
18741 else
18742 result = false;
18743 }
18744
18745 if (l.get_member_type() != r.get_member_type())
18746 {
18747 if (k)
18748 {
18749 if (!types_have_similar_structure(&l, &r))
18751 *k |= SUBTYPE_CHANGE_KIND;
18752 }
18753 result = false;
18754 }
18755
18757 {
18758 if (k)
18759 {
18760 if (!types_have_similar_structure(&l, &r))
18762 *k |= SUBTYPE_CHANGE_KIND;
18763 }
18764 result = false;
18765 }
18766
18767 ABG_RETURN(result);
18768}
18769
18770// </ptr_to_mbr_type definitions>
18771
18772// <array_type_def definitions>
18773
18774// <array_type_def::subrange_type>
18775array_type_def::subrange_type::~subrange_type() = default;
18776
18777// <array_type_def::subrante_type::bound_value>
18778
18779/// Default constructor of the @ref
18780/// array_type_def::subrange_type::bound_value class.
18781///
18782/// Constructs an unsigned bound_value of value zero.
18784 : s_(UNSIGNED_SIGNEDNESS)
18785{
18786 v_.unsigned_ = 0;
18787}
18788
18789/// Initialize an unsigned bound_value with a given value.
18790///
18791/// @param v the initial bound value.
18793 : s_(UNSIGNED_SIGNEDNESS)
18794{
18795 v_.unsigned_ = v;
18796}
18797
18798/// Initialize a signed bound_value with a given value.
18799///
18800/// @param v the initial bound value.
18802 : s_(SIGNED_SIGNEDNESS)
18803{
18804 v_.signed_ = v;
18805}
18806
18807/// Getter of the signedness (unsigned VS signed) of the bound value.
18808///
18809/// @return the signedness of the bound value.
18810enum array_type_def::subrange_type::bound_value::signedness
18812{return s_;}
18813
18814/// Setter of the signedness (unsigned VS signed) of the bound value.
18815///
18816/// @param s the new signedness of the bound value.
18817void
18819{ s_ = s;}
18820
18821/// Getter of the bound value as a signed value.
18822///
18823/// @return the bound value as signed.
18824int64_t
18826{return v_.signed_;
18827}
18828
18829/// Getter of the bound value as an unsigned value.
18830///
18831/// @return the bound value as unsigned.
18832uint64_t
18834{return v_.unsigned_;}
18835
18836/// Setter of the bound value as unsigned.
18837///
18838/// @param v the new unsigned value.
18839void
18841{
18842 s_ = UNSIGNED_SIGNEDNESS;
18843 v_.unsigned_ = v;
18844}
18845
18846/// Setter of the bound value as signed.
18847///
18848/// @param v the new signed value.
18849void
18851{
18852 s_ = SIGNED_SIGNEDNESS;
18853 v_.signed_ = v;
18854}
18855
18856/// Equality operator of the bound value.
18857///
18858/// @param v the other bound value to compare with.
18859///
18860/// @return true iff the current bound value equals @p v.
18861bool
18863{
18864 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
18865}
18866
18867// </array_type_def::subrante_type::bound_value>
18868
18869struct array_type_def::subrange_type::priv
18870{
18871 bound_value lower_bound_;
18872 bound_value upper_bound_;
18873 type_base_wptr underlying_type_;
18875 bool infinite_;
18876
18877 priv(bound_value ub,
18878 translation_unit::language l = translation_unit::LANG_C11)
18879 : upper_bound_(ub), language_(l), infinite_(false)
18880 {}
18881
18882 priv(bound_value lb, bound_value ub,
18883 translation_unit::language l = translation_unit::LANG_C11)
18884 : lower_bound_(lb), upper_bound_(ub),
18885 language_(l), infinite_(false)
18886 {}
18887
18888 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
18889 translation_unit::language l = translation_unit::LANG_C11)
18890 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
18891 language_(l), infinite_(false)
18892 {}
18893};
18894
18895/// Constructor of an array_type_def::subrange_type type.
18896///
18897/// @param env the environment this type was created from.
18898///
18899/// @param name the name of the subrange type.
18900///
18901/// @param lower_bound the lower bound of the array. This is
18902/// generally zero (at least for C and C++).
18903///
18904/// @param upper_bound the upper bound of the array.
18905///
18906/// @param underlying_type the underlying type of the subrange type.
18907///
18908/// @param loc the source location where the type is defined.
18909array_type_def::subrange_type::subrange_type(const environment& env,
18910 const string& name,
18911 bound_value lower_bound,
18912 bound_value upper_bound,
18913 const type_base_sptr& utype,
18914 const location& loc,
18916 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18917 type_base(env,
18918 utype
18919 ? utype->get_size_in_bits()
18920 : 0,
18921 0),
18922 decl_base(env, name, loc, ""),
18923 priv_(new priv(lower_bound, upper_bound, utype, l))
18924{
18926}
18927
18928/// Constructor of the array_type_def::subrange_type type.
18929///
18930/// @param env the environment this type is being created in.
18931///
18932/// @param name the name of the subrange type.
18933///
18934/// @param lower_bound the lower bound of the array. This is
18935/// generally zero (at least for C and C++).
18936///
18937/// @param upper_bound the upper bound of the array.
18938///
18939/// @param loc the source location where the type is defined.
18940///
18941/// @param l the language that generated this subrange.
18942array_type_def::subrange_type::subrange_type(const environment& env,
18943 const string& name,
18944 bound_value lower_bound,
18945 bound_value upper_bound,
18946 const location& loc,
18948 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18949 type_base(env, /*size-in-bits=*/0, /*alignment=*/0),
18950 decl_base(env, name, loc, ""),
18951 priv_(new priv(lower_bound, upper_bound, l))
18952{
18954}
18955
18956/// Constructor of the array_type_def::subrange_type type.
18957///
18958/// @param env the environment this type is being created from.
18959///
18960/// @param name of the name of type.
18961///
18962/// @param upper_bound the upper bound of the array. The lower bound
18963/// is considered to be zero.
18964///
18965/// @param loc the source location of the type.
18966///
18967/// @param the language that generated this type.
18968array_type_def::subrange_type::subrange_type(const environment& env,
18969 const string& name,
18970 bound_value upper_bound,
18971 const location& loc,
18973 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18974 type_base(env, upper_bound.get_unsigned_value(), 0),
18975 decl_base(env, name, loc, ""),
18976 priv_(new priv(upper_bound, l))
18977{
18979}
18980
18981/// Return the hash value of the current IR node.
18982///
18983/// Note that upon the first invocation, this member functions
18984/// computes the hash value and returns it. Subsequent invocations
18985/// just return the hash value that was previously calculated.
18986///
18987/// @return the hash value of the current IR node.
18988hash_t
18990{
18992 return h;
18993}
18994
18995/// Getter of the underlying type of the subrange, that is, the type
18996/// that defines the range.
18997///
18998/// @return the underlying type.
18999type_base_sptr
19001{return priv_->underlying_type_.lock();}
19002
19003/// Setter of the underlying type of the subrange, that is, the type
19004/// that defines the range.
19005///
19006/// @param u the new underlying type.
19007void
19009{
19010 ABG_ASSERT(priv_->underlying_type_.expired());
19011 priv_->underlying_type_ = u;
19012 if (u)
19013 set_size_in_bits(u->get_size_in_bits());
19014}
19015
19016/// Getter of the upper bound of the subrange type.
19017///
19018/// @return the upper bound of the subrange type.
19019int64_t
19021{return priv_->upper_bound_.get_signed_value();}
19022
19023/// Getter of the lower bound of the subrange type.
19024///
19025/// @return the lower bound of the subrange type.
19026int64_t
19028{return priv_->lower_bound_.get_signed_value();}
19029
19030/// Setter of the upper bound of the subrange type.
19031///
19032/// @param ub the new value of the upper bound.
19033void
19035{priv_->upper_bound_ = ub;}
19036
19037/// Setter of the lower bound.
19038///
19039/// @param lb the new value of the lower bound.
19040void
19042{priv_->lower_bound_ = lb;}
19043
19044/// Getter of the length of the subrange type.
19045///
19046/// Note that a length of zero means the array has an infinite (or
19047/// rather a non-known) size.
19048///
19049/// @return the length of the subrange type.
19050uint64_t
19052{
19053 if (is_non_finite())
19054 return 0;
19055
19056 // A subrange can have an upper bound that is lower than its lower
19057 // bound. This is possible in Ada for instance. In that case, the
19058 // length of the subrange is considered to be zero.
19059 if (get_upper_bound() >= get_lower_bound())
19060 return get_upper_bound() - get_lower_bound() + 1;
19061 return 0;
19062}
19063
19064/// Test if the length of the subrange type is infinite.
19065///
19066/// @return true iff the length of the subrange type is infinite.
19067bool
19069{return priv_->infinite_;}
19070
19071/// Set the infinite-ness status of the subrange type.
19072///
19073/// @param f true iff the length of the subrange type should be set to
19074/// being infinite.
19075void
19077{priv_->infinite_ = f;}
19078
19079/// Getter of the language that generated this type.
19080///
19081/// @return the language of this type.
19084{return priv_->language_;}
19085
19086/// Return a string representation of the sub range.
19087///
19088/// @return the string representation of the sub range.
19089string
19091{
19092 std::ostringstream o;
19093
19095 {
19096 type_base_sptr underlying_type = get_underlying_type();
19097 if (underlying_type)
19098 o << ir::get_pretty_representation(underlying_type, false) << " ";
19099 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
19100 }
19101 else if (is_non_finite())
19102 o << "[]";
19103 else
19104 o << "[" << get_length() << "]";
19105
19106 return o.str();
19107}
19108
19109/// Return a string representation of a vector of subranges
19110///
19111/// @return the string representation of a vector of sub ranges.
19112string
19114{
19115 if (v.empty())
19116 return "[]";
19117
19118 string r;
19119 for (vector<subrange_sptr>::const_iterator i = v.begin();
19120 i != v.end();
19121 ++i)
19122 r += (*i)->as_string();
19123
19124 return r;
19125}
19126
19127/// Compares two isntances of @ref array_type_def::subrange_type.
19128///
19129/// If the two intances are different, set a bitfield to give some
19130/// insight about the kind of differences there are.
19131///
19132/// @param l the first artifact of the comparison.
19133///
19134/// @param r the second artifact of the comparison.
19135///
19136/// @param k a pointer to a bitfield that gives information about the
19137/// kind of changes there are between @p l and @p r. This one is set
19138/// iff @p k is non-null and the function returns false.
19139///
19140/// Please note that setting k to a non-null value does have a
19141/// negative performance impact because even if @p l and @p r are not
19142/// equal, the function keeps up the comparison in order to determine
19143/// the different kinds of ways in which they are different.
19144///
19145/// @return true if @p l equals @p r, false otherwise.
19146bool
19149 change_kind* k)
19150{
19151 bool result = true;
19152
19153 if (l.get_lower_bound() != r.get_lower_bound()
19154 || l.get_upper_bound() != r.get_upper_bound()
19155 || l.get_name() != r.get_name())
19156 {
19157 result = false;
19158 if (k)
19160 else
19161 ABG_RETURN(result);
19162 }
19163
19164 if (l.get_underlying_type()
19165 && r.get_underlying_type()
19166 && (*l.get_underlying_type() != *r.get_underlying_type()))
19167 {
19168 result = false;
19169 if (k)
19170 *k |= SUBTYPE_CHANGE_KIND;
19171 else
19172 ABG_RETURN(result);
19173 }
19174
19175 ABG_RETURN(result);
19176}
19177
19178/// Equality operator.
19179///
19180/// @param o the other subrange to test against.
19181///
19182/// @return true iff @p o equals the current instance of
19183/// array_type_def::subrange_type.
19184bool
19186{
19187 const subrange_type* other =
19188 dynamic_cast<const subrange_type*>(&o);
19189 if (!other)
19190 return false;
19191 return try_canonical_compare(this, other);
19192}
19193
19194/// Equality operator.
19195///
19196/// @param o the other subrange to test against.
19197///
19198/// @return true iff @p o equals the current instance of
19199/// array_type_def::subrange_type.
19200bool
19202{
19203 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19204 if (!other)
19205 return false;
19206 return *this == *other;
19207}
19208
19209/// Equality operator.
19210///
19211/// @param o the other subrange to test against.
19212///
19213/// @return true iff @p o equals the current instance of
19214/// array_type_def::subrange_type.
19215bool
19217{
19218 const type_base &t = o;
19219 return operator==(t);
19220}
19221
19222/// Equality operator.
19223///
19224/// @param o the other subrange to test against.
19225///
19226/// @return true iff @p o equals the current instance of
19227/// array_type_def::subrange_type.
19228bool
19230{return !operator==(o);}
19231
19232/// Equality operator.
19233///
19234/// @param o the other subrange to test against.
19235///
19236/// @return true iff @p o equals the current instance of
19237/// array_type_def::subrange_type.
19238bool
19240{return !operator==(o);}
19241
19242/// Inequality operator.
19243///
19244/// @param o the other subrange to test against.
19245///
19246/// @return true iff @p o is different from the current instance of
19247/// array_type_def::subrange_type.
19248bool
19250{return !operator==(o);}
19251
19252/// Build a pretty representation for an
19253/// array_type_def::subrange_type.
19254///
19255/// @param internal set to true if the call is intended to get a
19256/// representation of the decl (or type) for the purpose of canonical
19257/// type comparison. This is mainly used in the function
19258/// type_base::get_canonical_type_for().
19259///
19260/// In other words if the argument for this parameter is true then the
19261/// call is meant for internal use (for technical use inside the
19262/// library itself), false otherwise. If you don't know what this is
19263/// for, then set it to false.
19264///
19265/// @return a copy of the pretty representation of the current
19266/// instance of typedef_decl.
19267string
19269{
19270 string name = get_name();
19271 string repr;
19272
19273 if (name.empty())
19274 repr += "<anonymous range>";
19275 else
19276 repr += "<range " + get_name() + ">";
19277 repr += as_string();
19278
19279 return repr;
19280}
19281
19282/// This implements the ir_traversable_base::traverse pure virtual
19283/// function.
19284///
19285/// @param v the visitor used on the current instance.
19286///
19287/// @return true if the entire IR node tree got traversed, false
19288/// otherwise.
19289bool
19291{
19292 if (v.type_node_has_been_visited(this))
19293 return true;
19294
19295 if (v.visit_begin(this))
19296 {
19297 visiting(true);
19298 if (type_base_sptr u = get_underlying_type())
19299 u->traverse(v);
19300 visiting(false);
19301 }
19302
19303 bool result = v.visit_end(this);
19305 return result;
19306}
19307
19308// </array_type_def::subrange_type>
19309
19310struct array_type_def::priv
19311{
19312 type_base_wptr element_type_;
19313 subranges_type subranges_;
19314 interned_string temp_internal_qualified_name_;
19315 interned_string internal_qualified_name_;
19316
19317 priv(type_base_sptr t)
19318 : element_type_(t)
19319 {}
19320
19321 priv(type_base_sptr t, subranges_type subs)
19322 : element_type_(t), subranges_(subs)
19323 {}
19324
19325 priv()
19326 {}
19327};
19328
19329/// Constructor for the type array_type_def
19330///
19331/// Note how the constructor expects a vector of subrange
19332/// objects. Parsing of the array information always entails
19333/// parsing the subrange info as well, thus the class subrange_type
19334/// is defined inside class array_type_def and also parsed
19335/// simultaneously.
19336///
19337/// @param e_type the type of the elements contained in the array
19338///
19339/// @param subs a vector of the array's subranges(dimensions)
19340///
19341/// @param locus the source location of the array type definition.
19342array_type_def::array_type_def(const type_base_sptr e_type,
19343 const std::vector<subrange_sptr>& subs,
19344 const location& locus)
19346 ARRAY_TYPE
19347 | ABSTRACT_TYPE_BASE
19348 | ABSTRACT_DECL_BASE),
19349 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
19350 decl_base(e_type->get_environment(), locus),
19351 priv_(new priv(e_type))
19352{
19354 append_subranges(subs);
19355}
19356
19357/// Constructor for the type array_type_def
19358///
19359/// This constructor builds a temporary array that has no element type
19360/// associated. Later when the element type is available, it be set
19361/// with the array_type_def::set_element_type() member function.
19362///
19363/// Note how the constructor expects a vector of subrange
19364/// objects. Parsing of the array information always entails
19365/// parsing the subrange info as well, thus the class subrange_type
19366/// is defined inside class array_type_def and also parsed
19367/// simultaneously.
19368///
19369/// @param env the environment of the array type.
19370///
19371/// @param subs a vector of the array's subranges(dimensions)
19372///
19373/// @param locus the source location of the array type definition.
19374array_type_def::array_type_def(const environment& env,
19375 const std::vector<subrange_sptr>& subs,
19376 const location& locus)
19377 : type_or_decl_base(env,
19378 ARRAY_TYPE
19379 | ABSTRACT_TYPE_BASE
19380 | ABSTRACT_DECL_BASE),
19381 type_base(env, 0, 0),
19382 decl_base(env, locus),
19383 priv_(new priv)
19384{
19386 append_subranges(subs);
19387}
19388
19389/// Return the hash value of the current IR node.
19390///
19391/// Note that upon the first invocation, this member functions
19392/// computes the hash value and returns it. Subsequent invocations
19393/// just return the hash value that was previously calculated.
19394///
19395/// @return the hash value of the current IR node.
19396hash_t
19398{
19400 return h;
19401}
19402
19403/// Update the size of the array.
19404///
19405/// This function computes the size of the array and sets it using
19406/// type_base::set_size_in_bits().
19407void
19408array_type_def::update_size()
19409{
19410 type_base_sptr e = priv_->element_type_.lock();
19411 if (e)
19412 {
19413 size_t s = e->get_size_in_bits();
19414 if (s)
19415 {
19416 for (const auto &sub : get_subranges())
19417 s *= sub->get_length();
19419 }
19420 set_alignment_in_bits(e->get_alignment_in_bits());
19421 }
19422}
19423
19424string
19425array_type_def::get_subrange_representation() const
19426{
19428 return r;
19429}
19430
19431/// Get the pretty representation of the current instance of @ref
19432/// array_type_def.
19433///
19434/// @param internal set to true if the call is intended to get a
19435/// representation of the decl (or type) for the purpose of canonical
19436/// type comparison. This is mainly used in the function
19437/// type_base::get_canonical_type_for().
19438///
19439/// In other words if the argument for this parameter is true then the
19440/// call is meant for internal use (for technical use inside the
19441/// library itself), false otherwise. If you don't know what this is
19442/// for, then set it to false.
19443/// @param internal set to true if the call is intended for an
19444/// internal use (for technical use inside the library itself), false
19445/// otherwise. If you don't know what this is for, then set it to
19446/// false.
19447///
19448/// @return the pretty representation of the ABI artifact.
19449string
19451 bool qualified_name) const
19452{
19453 return array_declaration_name(this, /*variable_name=*/"",
19454 qualified_name, internal);
19455}
19456
19457/// Compares two instances of @ref array_type_def.
19458///
19459/// If the two intances are different, set a bitfield to give some
19460/// insight about the kind of differences there are.
19461///
19462/// @param l the first artifact of the comparison.
19463///
19464/// @param r the second artifact of the comparison.
19465///
19466/// @param k a pointer to a bitfield that gives information about the
19467/// kind of changes there are between @p l and @p r. This one is set
19468/// iff @p k is non-null and the function returns false.
19469///
19470/// Please note that setting k to a non-null value does have a
19471/// negative performance impact because even if @p l and @p r are not
19472/// equal, the function keeps up the comparison in order to determine
19473/// the different kinds of ways in which they are different.
19474///
19475/// @return true if @p l equals @p r, false otherwise.
19476bool
19478{
19479 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
19480 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
19481
19482 bool result = true;
19483 if (this_subs.size() != other_subs.size())
19484 {
19485 result = false;
19486 if (k)
19488 else
19490 }
19491
19492 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19493 for (i = this_subs.begin(), j = other_subs.begin();
19494 i != this_subs.end() && j != other_subs.end();
19495 ++i, ++j)
19496 if (**i != **j)
19497 {
19498 result = false;
19499 if (k)
19500 {
19502 break;
19503 }
19504 else
19506 }
19507
19508 // Compare the element types modulo the typedefs they might have
19509 if (l.get_element_type() != r.get_element_type())
19510 {
19511 result = false;
19512 if (k)
19513 *k |= SUBTYPE_CHANGE_KIND;
19514 else
19516 }
19517
19518 ABG_RETURN(result);
19519}
19520
19521/// Test if two variables are equals modulo CV qualifiers.
19522///
19523/// @param l the first array of the comparison.
19524///
19525/// @param r the second array of the comparison.
19526///
19527/// @return true iff @p l equals @p r or, if they are different, the
19528/// difference between the too is just a matter of CV qualifiers.
19529bool
19531{
19532 if (l == r)
19533 return true;
19534
19535 if (!l || !r)
19537
19540
19541 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
19542 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
19543
19544 if (this_subs.size() != other_subs.size())
19546
19547 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19548 for (i = this_subs.begin(), j = other_subs.begin();
19549 i != this_subs.end() && j != other_subs.end();
19550 ++i, ++j)
19551 if (**i != **j)
19553
19554 type_base *first_element_type =
19556 type_base *second_element_type =
19558
19559 if (*first_element_type != *second_element_type)
19561
19562 return true;
19563}
19564
19565/// Get the language of the array.
19566///
19567/// @return the language of the array.
19570{
19571 const std::vector<subrange_sptr>& subranges =
19572 get_subranges();
19573
19574 if (subranges.empty())
19575 return translation_unit::LANG_C11;
19576 return subranges.front()->get_language();
19577}
19578
19579bool
19581{
19582 const array_type_def* other =
19583 dynamic_cast<const array_type_def*>(&o);
19584 if (!other)
19585 return false;
19586 return try_canonical_compare(this, other);
19587}
19588
19589bool
19591{
19592 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19593 if (!other)
19594 return false;
19595 return *this == *other;
19596}
19597
19598/// Getter of the type of an array element.
19599///
19600/// @return the type of an array element.
19601const type_base_sptr
19603{return priv_->element_type_.lock();}
19604
19605/// Setter of the type of array element.
19606///
19607/// Beware that after using this function, one might want to
19608/// re-compute the canonical type of the array, if one has already
19609/// been computed.
19610///
19611/// The intended use of this method is to permit in-place adjustment
19612/// of the element type's qualifiers. In particular, the size of the
19613/// element type should not be changed.
19614///
19615/// @param element_type the new element type to set.
19616void
19617array_type_def::set_element_type(const type_base_sptr& element_type)
19618{
19619 priv_->element_type_ = element_type;
19620 update_size();
19622}
19623
19624/// Append subranges from the vector @param subs to the current
19625/// vector of subranges.
19626void
19627array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
19628{
19629
19630 for (const auto &sub : subs)
19631 priv_->subranges_.push_back(sub);
19632
19633 update_size();
19635}
19636
19637/// @return true if one of the sub-ranges of the array is infinite, or
19638/// if the array has no sub-range at all, also meaning that the size
19639/// of the array is infinite.
19640bool
19642{
19643 if (priv_->subranges_.empty())
19644 return true;
19645
19646 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
19647 priv_->subranges_.begin();
19648 i != priv_->subranges_.end();
19649 ++i)
19650 if ((*i)->is_non_finite())
19651 return true;
19652
19653 return false;
19654}
19655
19656int
19657array_type_def::get_dimension_count() const
19658{return priv_->subranges_.size();}
19659
19660/// Build and return the qualified name of the current instance of the
19661/// @ref array_type_def.
19662///
19663/// @param qn output parameter. Is set to the newly-built qualified
19664/// name of the current instance of @ref array_type_def.
19665///
19666/// @param internal set to true if the call is intended for an
19667/// internal use (for technical use inside the library itself), false
19668/// otherwise. If you don't know what this is for, then set it to
19669/// false.
19670void
19672{qn = get_qualified_name(internal);}
19673
19674/// Compute the qualified name of the array.
19675///
19676/// @param internal set to true if the call is intended for an
19677/// internal use (for technical use inside the library itself), false
19678/// otherwise. If you don't know what this is for, then set it to
19679/// false.
19680///
19681/// @return the resulting qualified name.
19682const interned_string&
19684{
19685 if (internal)
19686 {
19687 if (get_canonical_type())
19688 {
19689 if (priv_->internal_qualified_name_.empty())
19690 priv_->internal_qualified_name_ =
19691 array_declaration_name(this, /*variable_name=*/"",
19692 /*qualified=*/false,
19693 /*internal=*/true);
19694 return priv_->internal_qualified_name_;
19695 }
19696 else
19697 {
19698 priv_->temp_internal_qualified_name_ =
19699 array_declaration_name(this, /*variable_name=*/"",
19700 /*qualified*/false, /*internal*/true);
19701 return priv_->temp_internal_qualified_name_;
19702 }
19703 }
19704 else
19705 {
19706 if (get_canonical_type())
19707 {
19708 if (decl_base::peek_qualified_name().empty())
19709 set_qualified_name(array_declaration_name(this,
19710 /*variable_name=*/"",
19711 /*qualified=*/false,
19712 /*internal=*/false));
19714 }
19715 else
19716 {
19718 (array_declaration_name(this, /*variable_name=*/"",
19719 /*qualified=*/false,
19720 /*internal=*/false));
19722 }
19723 }
19724}
19725
19726/// This implements the ir_traversable_base::traverse pure virtual
19727/// function.
19728///
19729/// @param v the visitor used on the current instance.
19730///
19731/// @return true if the entire IR node tree got traversed, false
19732/// otherwise.
19733bool
19735{
19736 if (v.type_node_has_been_visited(this))
19737 return true;
19738
19739 if (visiting())
19740 return true;
19741
19742 if (v.visit_begin(this))
19743 {
19744 visiting(true);
19745 if (type_base_sptr t = get_element_type())
19746 t->traverse(v);
19747 visiting(false);
19748 }
19749
19750 bool result = v.visit_end(this);
19752 return result;
19753}
19754
19755const location&
19756array_type_def::get_location() const
19757{return decl_base::get_location();}
19758
19759/// Get the array's subranges
19760const std::vector<array_type_def::subrange_sptr>&
19762{return priv_->subranges_;}
19763
19764array_type_def::~array_type_def()
19765{}
19766
19767// </array_type_def definitions>
19768
19769// <enum_type_decl definitions>
19770
19771class enum_type_decl::priv
19772{
19773 type_base_sptr underlying_type_;
19774 enumerators enumerators_;
19775 mutable enumerators sorted_enumerators_;
19776
19777 friend class enum_type_decl;
19778
19779 priv();
19780
19781public:
19782 priv(type_base_sptr underlying_type,
19784 : underlying_type_(underlying_type),
19785 enumerators_(enumerators)
19786 {}
19787}; // end class enum_type_decl::priv
19788
19789/// Constructor.
19790///
19791/// @param name the name of the type declaration.
19792///
19793/// @param locus the source location where the type was defined.
19794///
19795/// @param underlying_type the underlying type of the enum.
19796///
19797/// @param enums the enumerators of this enum type.
19798///
19799/// @param linkage_name the linkage name of the enum.
19800///
19801/// @param vis the visibility of the enum type.
19802enum_type_decl::enum_type_decl(const string& name,
19803 const location& locus,
19804 type_base_sptr underlying_type,
19805 enumerators& enums,
19806 const string& linkage_name,
19807 visibility vis)
19808 : type_or_decl_base(underlying_type->get_environment(),
19809 ENUM_TYPE
19810 | ABSTRACT_TYPE_BASE
19811 | ABSTRACT_DECL_BASE),
19812 type_base(underlying_type->get_environment(),
19813 underlying_type->get_size_in_bits(),
19814 underlying_type->get_alignment_in_bits()),
19815 decl_base(underlying_type->get_environment(),
19816 name, locus, linkage_name, vis),
19817 priv_(new priv(underlying_type, enums))
19818{
19820 for (enumerators::iterator e = get_enumerators().begin();
19821 e != get_enumerators().end();
19822 ++e)
19823 e->set_enum_type(this);
19824}
19825
19826/// Return the hash value of the current IR node.
19827///
19828/// Note that upon the first invocation, this member functions
19829/// computes the hash value and returns it. Subsequent invocations
19830/// just return the hash value that was previously calculated.
19831///
19832/// @return the hash value of the current IR node.
19833hash_t
19835{
19837 return h;
19838}
19839
19840/// Return the underlying type of the enum.
19841type_base_sptr
19843{return priv_->underlying_type_;}
19844
19845/// @return the list of enumerators of the enum.
19848{return priv_->enumerators_;}
19849
19850/// @return the list of enumerators of the enum.
19853{return priv_->enumerators_;}
19854
19855/// Get the lexicographically sorted vector of enumerators.
19856///
19857/// @return the lexicographically sorted vector of enumerators.
19860{
19861 if (priv_->sorted_enumerators_.empty())
19862 {
19863 for (auto e = get_enumerators().rbegin();
19864 e != get_enumerators().rend();
19865 ++e)
19866 priv_->sorted_enumerators_.push_back(*e);
19867
19868 std::sort(priv_->sorted_enumerators_.begin(),
19869 priv_->sorted_enumerators_.end(),
19870 [](const enum_type_decl::enumerator& l,
19872 {
19873 if (l.get_name() == r.get_name())
19874 return l.get_value() < r.get_value();
19875 return (l.get_name() < r.get_name());
19876 });
19877 }
19878
19879 return priv_->sorted_enumerators_;
19880}
19881
19882/// Get the pretty representation of the current instance of @ref
19883/// enum_type_decl.
19884///
19885/// @param internal set to true if the call is intended to get a
19886/// representation of the decl (or type) for the purpose of canonical
19887/// type comparison. This is mainly used in the function
19888/// type_base::get_canonical_type_for().
19889///
19890/// In other words if the argument for this parameter is true then the
19891/// call is meant for internal use (for technical use inside the
19892/// library itself), false otherwise. If you don't know what this is
19893/// for, then set it to false.
19894///
19895/// @param qualified_name if true, names emitted in the pretty
19896/// representation are fully qualified.
19897///
19898/// @return the pretty representation of the enum type.
19899string
19901 bool qualified_name) const
19902{
19903 string r = "enum ";
19904
19905 if (internal && get_is_anonymous())
19906 r += get_type_name(this, qualified_name, /*internal=*/true);
19907 else if (get_is_anonymous())
19908 r += get_enum_flat_representation(*this, "",
19909 /*one_line=*/true,
19910 qualified_name);
19911 else
19913 qualified_name);
19914 return r;
19915}
19916
19917/// This implements the ir_traversable_base::traverse pure virtual
19918/// function.
19919///
19920/// @param v the visitor used on the current instance.
19921///
19922/// @return true if the entire IR node tree got traversed, false
19923/// otherwise.
19924bool
19926{
19927 if (v.type_node_has_been_visited(this))
19928 return true;
19929
19930 if (visiting())
19931 return true;
19932
19933 if (v.visit_begin(this))
19934 {
19935 visiting(true);
19936 if (type_base_sptr t = get_underlying_type())
19937 t->traverse(v);
19938 visiting(false);
19939 }
19940
19941 bool result = v.visit_end(this);
19943 return result;
19944}
19945
19946/// Destructor for the enum type declaration.
19948{}
19949
19950/// Test if two enums differ, but not by a name change.
19951///
19952/// @param l the first enum to consider.
19953///
19954/// @param r the second enum to consider.
19955///
19956/// @return true iff @p l differs from @p r by anything but a name
19957/// change.
19958bool
19960 const enum_type_decl& r,
19961 change_kind* k)
19962{
19963 bool result = false;
19965 {
19966 result = true;
19967 if (k)
19968 *k |= SUBTYPE_CHANGE_KIND;
19969 else
19970 return true;
19971 }
19972
19973 enum_type_decl::enumerators::const_iterator i, j;
19974 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
19975 i != l.get_enumerators().end() && j != r.get_enumerators().end();
19976 ++i, ++j)
19977 if (*i != *j)
19978 {
19979 result = true;
19980 if (k)
19981 {
19983 break;
19984 }
19985 else
19986 return true;
19987 }
19988
19989 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
19990 {
19991 result = true;
19992 if (k)
19994 else
19995 return true;
19996 }
19997
19998 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
20001 string n_l = l.get_name();
20002 string n_r = r.get_name();
20003 local_r.set_qualified_name(qn_l);
20004 local_r.set_name(n_l);
20005
20006 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
20007 {
20008 result = true;
20009 if (k)
20010 {
20011 if (!l.decl_base::operator==(r))
20013 if (!l.type_base::operator==(r))
20015 }
20016 else
20017 {
20018 local_r.set_name(n_r);
20019 local_r.set_qualified_name(qn_r);
20020 return true;
20021 }
20022 }
20023 local_r.set_qualified_name(qn_r);
20024 local_r.set_name(n_r);
20025
20026 return result;
20027}
20028
20029/// Test if a given enumerator is found present in an enum.
20030///
20031/// This is a subroutine of the equals function for enums.
20032///
20033/// @param enr the enumerator to consider.
20034///
20035/// @param enom the enum to consider.
20036///
20037/// @return true iff the enumerator @p enr is present in the enum @p
20038/// enom.
20039bool
20041 const enum_type_decl &enom)
20042{
20043 for (const auto &e : enom.get_enumerators())
20044 if (e == enr)
20045 return true;
20046 return false;
20047}
20048
20049/// Check if two enumerators values are equal.
20050///
20051/// This function doesn't check if the names of the enumerators are
20052/// equal or not.
20053///
20054/// @param enr the first enumerator to consider.
20055///
20056/// @param enl the second enumerator to consider.
20057///
20058/// @return true iff @p enr has the same value as @p enl.
20059static bool
20060enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
20061 const enum_type_decl::enumerator &enl)
20062{return enr.get_value() == enl.get_value();}
20063
20064/// Detect if a given enumerator value is present in an enum.
20065///
20066/// This function looks inside the enumerators of a given enum and
20067/// detect if the enum contains at least one enumerator or a given
20068/// value. The function also detects if the enumerator value we are
20069/// looking at is present in the enum with a different name. An
20070/// enumerator with the same value but with a different name is named
20071/// a "redundant enumerator". The function returns the set of
20072/// enumerators that are redundant with the value we are looking at.
20073///
20074/// @param enr the enumerator to consider.
20075///
20076/// @param enom the enum to consider.
20077///
20078/// @param redundant_enrs if the function returns true, then this
20079/// vector is filled with enumerators that are redundant with the
20080/// value of @p enr.
20081///
20082/// @return true iff the function detects that @p enom contains
20083/// enumerators with the same value as @p enr.
20084static bool
20085is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
20086 const enum_type_decl &enom,
20087 vector<enum_type_decl::enumerator>& redundant_enrs)
20088{
20089 bool found = false;
20090 for (const auto &e : enom.get_enumerators())
20091 if (enumerators_values_are_equal(e, enr))
20092 {
20093 found = true;
20094 if (e != enr)
20095 redundant_enrs.push_back(e);
20096 }
20097
20098 return found;
20099}
20100
20101/// Check if an enumerator value is redundant in a given enum.
20102///
20103/// Given an enumerator value, this function detects if an enum
20104/// contains at least one enumerator with the the same value but with
20105/// a different name.
20106///
20107/// @param enr the enumerator to consider.
20108///
20109/// @param enom the enum to consider.
20110///
20111/// @return true iff @p enr is a redundant enumerator in enom.
20112static bool
20113is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
20114 const enum_type_decl &enom)
20115{
20116 vector<enum_type_decl::enumerator> redundant_enrs;
20117 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
20118 {
20119 if (!redundant_enrs.empty())
20120 return true;
20121 }
20122 return false;
20123}
20124
20125/// Compares two instances of @ref enum_type_decl.
20126///
20127/// If the two intances are different, set a bitfield to give some
20128/// insight about the kind of differences there are.
20129///
20130/// @param l the first artifact of the comparison.
20131///
20132/// @param r the second artifact of the comparison.
20133///
20134/// @param k a pointer to a bitfield that gives information about the
20135/// kind of changes there are between @p l and @p r. This one is set
20136/// iff @p k is non-null and the function returns false.
20137///
20138/// Please note that setting k to a non-null value does have a
20139/// negative performance impact because even if @p l and @p r are not
20140/// equal, the function keeps up the comparison in order to determine
20141/// the different kinds of ways in which they are different.
20142///
20143/// @return true if @p l equals @p r, false otherwise.
20144bool
20146{
20147 bool result = true;
20148
20149 //
20150 // Look through decl-only-enum.
20151 //
20152
20153 const enum_type_decl *def1 =
20156 : &l;
20157
20158 const enum_type_decl *def2 =
20161 : &r;
20162
20163 if (!!def1 != !!def2)
20164 {
20165 // One enum is decl-only while the other is not.
20166 // So the two enums are different.
20167 result = false;
20168 if (k)
20169 *k |= SUBTYPE_CHANGE_KIND;
20170 else
20172 }
20173
20174 //
20175 // At this point, both enums have the same state of decl-only-ness.
20176 // So we can compare oranges to oranges.
20177 //
20178
20179 if (!def1)
20180 def1 = &l;
20181 if (!def2)
20182 def2 = &r;
20183
20184 if (def1->get_underlying_type() != def2->get_underlying_type())
20185 {
20186 result = false;
20187 if (k)
20188 *k |= SUBTYPE_CHANGE_KIND;
20189 else
20191 }
20192
20193 if (!(def1->decl_base::operator==(*def2)
20194 && def1->type_base::operator==(*def2)))
20195 {
20196 result = false;
20197 if (k)
20198 {
20199 if (!def1->decl_base::operator==(*def2))
20201 if (!def1->type_base::operator==(*def2))
20203 }
20204 else
20206 }
20207
20208 // Now compare the enumerators.
20209
20210 // First in a naive (but potentially fast) way in case both enums
20211 // are equal in a naive manner.
20212
20213 if (def1->get_enumerators().size() == def2->get_enumerators().size())
20214 {
20215 bool equals = true;
20216 for (auto e1 = def1->get_enumerators().begin(),
20217 e2 = def2->get_enumerators().begin();
20218 (e1 != def1->get_enumerators().end()
20219 && e2 != def2->get_enumerators().end());
20220 ++e1, ++e2)
20221 {
20222 if (*e1 != *e2)
20223 {
20224 equals = false;
20225 break;
20226 }
20227 }
20228 if (equals)
20229 ABG_RETURN(result);
20230 }
20231
20232 // If the two enums where not naively equals, let's try a more
20233 // clever (and slow) way.
20234
20235 // Note that the order of declaration
20236 // of enumerators should not matter in the comparison.
20237 //
20238 // Also if an enumerator value is redundant, that shouldn't impact
20239 // the comparison.
20240 //
20241 // In that case, note that the two enums below are considered equal:
20242 //
20243 // enum foo
20244 // {
20245 // e0 = 0;
20246 // e1 = 1;
20247 // e2 = 2;
20248 // };
20249 //
20250 // enum foo
20251 // {
20252 // e0 = 0;
20253 // e1 = 1;
20254 // e2 = 2;
20255 // e_added = 1; // <-- this value is redundant with the value
20256 // // of the enumerator e1.
20257 // };
20258 //
20259 // Note however that in the case below, the enums are different.
20260 //
20261 // enum foo
20262 // {
20263 // e0 = 0;
20264 // e1 = 1;
20265 // };
20266 //
20267 // enum foo
20268 // {
20269 // e0 = 0;
20270 // e2 = 1; // <-- this enum value is present in the first version
20271 // // of foo, but is not redundant with any enumerator
20272 // // in the second version of of enum foo.
20273 // };
20274 //
20275 // These two enums are considered equal.
20276
20277 for(const auto &e : def1->get_enumerators())
20278 if (!is_enumerator_present_in_enum(e, *def2)
20279 && (!is_enumerator_value_redundant(e, *def2)
20280 || !is_enumerator_value_redundant(e, *def1)))
20281 {
20282 result = false;
20283 if (k)
20284 {
20286 break;
20287 }
20288 else
20290 }
20291
20292 for(const auto &e : def2->get_enumerators())
20293 if (!is_enumerator_present_in_enum(e, *def1)
20294 && (!is_enumerator_value_redundant(e, *def1)
20295 || !is_enumerator_value_redundant(e, *def2)))
20296 {
20297 result = false;
20298 if (k)
20299 {
20301 break;
20302 }
20303 else
20305 }
20306
20307 ABG_RETURN(result);
20308}
20309
20310/// Equality operator.
20311///
20312/// @param o the other enum to test against.
20313///
20314/// @return true iff @p o equals the current instance of enum type
20315/// decl.
20316bool
20318{
20319 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
20320 if (!op)
20321 return false;
20322 return try_canonical_compare(this, op);
20323}
20324
20325/// Equality operator.
20326///
20327/// @param o the other enum to test against.
20328///
20329/// @return true iff @p o is equals the current instance of enum type
20330/// decl.
20331bool
20333{
20334 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20335 if (!other)
20336 return false;
20337 return *this == *other;
20338}
20339
20340/// Equality operator for @ref enum_type_decl_sptr.
20341///
20342/// @param l the first operand to compare.
20343///
20344/// @param r the second operand to compare.
20345///
20346/// @return true iff @p l equals @p r.
20347bool
20349{
20350 if (!!l != !!r)
20351 return false;
20352 if (l.get() == r.get())
20353 return true;
20354 decl_base_sptr o = r;
20355 return *l == *o;
20356}
20357
20358/// Inequality operator for @ref enum_type_decl_sptr.
20359///
20360/// @param l the first operand to compare.
20361///
20362/// @param r the second operand to compare.
20363///
20364/// @return true iff @p l equals @p r.
20365bool
20367{return !operator==(l, r);}
20368
20369/// The type of the private data of an @ref
20370/// enum_type_decl::enumerator.
20371class enum_type_decl::enumerator::priv
20372{
20373 string name_;
20374 int64_t value_;
20375 string qualified_name_;
20376 enum_type_decl* enum_type_;
20377
20378 friend class enum_type_decl::enumerator;
20379
20380public:
20381
20382 priv()
20383 : enum_type_()
20384 {}
20385
20386 priv(const string& name,
20387 int64_t value,
20388 enum_type_decl* e = 0)
20389 : name_(name),
20390 value_(value),
20391 enum_type_(e)
20392 {}
20393}; // end class enum_type_def::enumerator::priv
20394
20395/// Default constructor of the @ref enum_type_decl::enumerator type.
20397 : priv_(new priv)
20398{}
20399
20400enum_type_decl::enumerator::~enumerator() = default;
20401
20402/// Constructor of the @ref enum_type_decl::enumerator type.
20403///
20404/// @param env the environment we are operating from.
20405///
20406/// @param name the name of the enumerator.
20407///
20408/// @param value the value of the enumerator.
20410 int64_t value)
20411 : priv_(new priv(name, value))
20412{}
20413
20414/// Copy constructor of the @ref enum_type_decl::enumerator type.
20415///
20416/// @param other enumerator to copy.
20418 : priv_(new priv(other.get_name(),
20419 other.get_value(),
20420 other.get_enum_type()))
20421{}
20422
20423/// Assignment operator of the @ref enum_type_decl::enumerator type.
20424///
20425/// @param o
20428{
20429 priv_->name_ = o.get_name();
20430 priv_->value_ = o.get_value();
20431 priv_->enum_type_ = o.get_enum_type();
20432 return *this;
20433}
20434
20435/// Equality operator
20436///
20437/// @param other the enumerator to compare to the current
20438/// instance of enum_type_decl::enumerator.
20439///
20440/// @return true if @p other equals the current instance of
20441/// enum_type_decl::enumerator.
20442bool
20444{
20445 bool names_equal = true;
20446 names_equal = (get_name() == other.get_name());
20447 return names_equal && (get_value() == other.get_value());
20448}
20449
20450/// Inequality operator.
20451///
20452/// @param other the other instance to compare against.
20453///
20454/// @return true iff @p other is different from the current instance.
20455bool
20457{return !operator==(other);}
20458
20459/// Getter for the name of the current instance of
20460/// enum_type_decl::enumerator.
20461///
20462/// @return a reference to the name of the current instance of
20463/// enum_type_decl::enumerator.
20464const string&
20466{return priv_->name_;}
20467
20468/// Getter for the qualified name of the current instance of
20469/// enum_type_decl::enumerator. The first invocation of the method
20470/// builds the qualified name, caches it and return a reference to the
20471/// cached qualified name. Subsequent invocations just return the
20472/// cached value.
20473///
20474/// @param internal set to true if the call is intended for an
20475/// internal use (for technical use inside the library itself), false
20476/// otherwise. If you don't know what this is for, then set it to
20477/// false.
20478///
20479/// @return the qualified name of the current instance of
20480/// enum_type_decl::enumerator.
20481const string&
20483{
20484 if (priv_->qualified_name_.empty())
20485 {
20486 priv_->qualified_name_ =
20487 get_enum_type()->get_qualified_name(internal)
20488 + "::"
20489 + get_name();
20490 }
20491 return priv_->qualified_name_;
20492}
20493
20494/// Setter for the name of @ref enum_type_decl::enumerator.
20495///
20496/// @param n the new name.
20497void
20499{priv_->name_ = n;}
20500
20501/// Getter for the value of @ref enum_type_decl::enumerator.
20502///
20503/// @return the value of the current instance of
20504/// enum_type_decl::enumerator.
20505int64_t
20507{return priv_->value_;}
20508
20509/// Setter for the value of @ref enum_type_decl::enumerator.
20510///
20511/// @param v the new value of the enum_type_decl::enumerator.
20512void
20514{priv_->value_= v;}
20515
20516/// Getter for the enum type that this enumerator is for.
20517///
20518/// @return the enum type that this enumerator is for.
20521{return priv_->enum_type_;}
20522
20523/// Setter for the enum type that this enumerator is for.
20524///
20525/// @param e the new enum type.
20526void
20528{priv_->enum_type_ = e;}
20529// </enum_type_decl definitions>
20530
20531// <typedef_decl definitions>
20532
20533/// Private data structure of the @ref typedef_decl.
20534struct typedef_decl::priv
20535{
20536 type_base_wptr underlying_type_;
20537
20538 priv(const type_base_sptr& t)
20539 : underlying_type_(t)
20540 {}
20541}; // end struct typedef_decl::priv
20542
20543/// Constructor of the typedef_decl type.
20544///
20545/// @param name the name of the typedef.
20546///
20547/// @param underlying_type the underlying type of the typedef.
20548///
20549/// @param locus the source location of the typedef declaration.
20550///
20551/// @param linkage_name the mangled name of the typedef.
20552///
20553/// @param vis the visibility of the typedef type.
20554typedef_decl::typedef_decl(const string& name,
20555 const type_base_sptr underlying_type,
20556 const location& locus,
20557 const string& linkage_name,
20558 visibility vis)
20559 : type_or_decl_base(underlying_type->get_environment(),
20560 TYPEDEF_TYPE
20561 | ABSTRACT_TYPE_BASE
20562 | ABSTRACT_DECL_BASE),
20563 type_base(underlying_type->get_environment(),
20564 underlying_type->get_size_in_bits(),
20565 underlying_type->get_alignment_in_bits()),
20566 decl_base(underlying_type->get_environment(),
20567 name, locus, linkage_name, vis),
20568 priv_(new priv(underlying_type))
20569{
20571}
20572
20573/// Constructor of the typedef_decl type.
20574///
20575/// @param name the name of the typedef.
20576///
20577/// @param env the environment of the current typedef.
20578///
20579/// @param locus the source location of the typedef declaration.
20580///
20581/// @param mangled_name the mangled name of the typedef.
20582///
20583/// @param vis the visibility of the typedef type.
20584typedef_decl::typedef_decl(const string& name,
20585 const environment& env,
20586 const location& locus,
20587 const string& mangled_name,
20588 visibility vis)
20589 : type_or_decl_base(env,
20590 TYPEDEF_TYPE
20591 | ABSTRACT_TYPE_BASE
20592 | ABSTRACT_DECL_BASE),
20593 type_base(env, /*size_in_bits=*/0,
20594 /*alignment_in_bits=*/0),
20595 decl_base(env, name, locus, mangled_name, vis),
20596 priv_(new priv(nullptr))
20597{
20599}
20600
20601/// Return the hash value of the current IR node.
20602///
20603/// Note that upon the first invocation, this member functions
20604/// computes the hash value and returns it. Subsequent invocations
20605/// just return the hash value that was previously calculated.
20606///
20607/// @return the hash value of the current IR node.
20608hash_t
20610{
20612 return h;
20613}
20614
20615/// Return the size of the typedef.
20616///
20617/// This function looks at the size of the underlying type and ensures
20618/// that it's the same as the size of the typedef.
20619///
20620/// @return the size of the typedef.
20621size_t
20623{
20624 if (!get_underlying_type())
20625 return 0;
20626 size_t s = get_underlying_type()->get_size_in_bits();
20627 if (s != type_base::get_size_in_bits())
20628 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
20630}
20631
20632/// Return the alignment of the typedef.
20633///
20634/// This function looks at the alignment of the underlying type and
20635/// ensures that it's the same as the alignment of the typedef.
20636///
20637/// @return the size of the typedef.
20638size_t
20640{
20641 if (!get_underlying_type())
20642 return 0;
20643 size_t s = get_underlying_type()->get_alignment_in_bits();
20645 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
20647}
20648
20649/// Compares two instances of @ref typedef_decl.
20650///
20651/// If the two intances are different, set a bitfield to give some
20652/// insight about the kind of differences there are.
20653///
20654/// @param l the first artifact of the comparison.
20655///
20656/// @param r the second artifact of the comparison.
20657///
20658/// @param k a pointer to a bitfield that gives information about the
20659/// kind of changes there are between @p l and @p r. This one is set
20660/// iff @p k is non-null and the function returns false.
20661///
20662/// Please note that setting k to a non-null value does have a
20663/// negative performance impact because even if @p l and @p r are not
20664/// equal, the function keeps up the comparison in order to determine
20665/// the different kinds of ways in which they are different.
20666///
20667/// @return true if @p l equals @p r, false otherwise.
20668bool
20670{
20671 bool result = true;
20672
20673 // No need to go further if the types have different names or
20674 // different size / alignment.
20675 if (!(l.decl_base::operator==(r)))
20676 {
20677 result = false;
20678 if (k)
20680 else
20682 }
20683
20685 {
20686 // Changes to the underlying type of a typedef are considered
20687 // local, a bit like for pointers.
20688 result = false;
20689 if (k)
20691 else
20693 }
20694
20695 ABG_RETURN(result);
20696}
20697
20698/// Equality operator
20699///
20700/// @param o the other typedef_decl to test against.
20701bool
20703{
20704 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
20705 if (!other)
20706 return false;
20707 return try_canonical_compare(this, other);
20708}
20709
20710/// Equality operator
20711///
20712/// @param o the other typedef_decl to test against.
20713///
20714/// @return true if the current instance of @ref typedef_decl equals
20715/// @p o.
20716bool
20718{
20719 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20720 if (!other)
20721 return false;
20722 return *this == *other;
20723}
20724
20725/// Build a pretty representation for a typedef_decl.
20726///
20727/// @param internal set to true if the call is intended to get a
20728/// representation of the decl (or type) for the purpose of canonical
20729/// type comparison. This is mainly used in the function
20730/// type_base::get_canonical_type_for().
20731///
20732/// In other words if the argument for this parameter is true then the
20733/// call is meant for internal use (for technical use inside the
20734/// library itself), false otherwise. If you don't know what this is
20735/// for, then set it to false.
20736
20737/// @param qualified_name if true, names emitted in the pretty
20738/// representation are fully qualified.
20739///
20740/// @return a copy of the pretty representation of the current
20741/// instance of typedef_decl.
20742string
20744 bool qualified_name) const
20745{
20746
20747 string result = "typedef ";
20748 if (qualified_name)
20749 result += get_qualified_name(internal);
20750 else
20751 result += get_name();
20752
20753 return result;
20754}
20755
20756/// Getter of the underlying type of the typedef.
20757///
20758/// @return the underlying_type.
20759type_base_sptr
20761{return priv_->underlying_type_.lock();}
20762
20763/// Setter ofthe underlying type of the typedef.
20764///
20765/// @param t the new underlying type of the typedef.
20766void
20768{
20769 priv_->underlying_type_ = t;
20770 set_size_in_bits(t->get_size_in_bits());
20771 set_alignment_in_bits(t->get_alignment_in_bits());
20772}
20773
20774/// Implementation of the virtual "get_qualified_name" method.
20775///
20776/// @param qualified_name the resuling qualified name of the typedef type.
20777///
20778/// @param internal if true, then it means the qualified name is for
20779/// "internal" purposes, meaning mainly for type canonicalization
20780/// purposes.
20781void
20783 bool internal) const
20784{qualified_name = get_qualified_name(internal);}
20785
20786/// Implementation of the virtual "get_qualified_name" method.
20787///
20788/// @param internal if true, then it means the qualified name is for
20789/// "internal" purposes, meaning mainly for type canonicalization
20790/// purposes.
20791///
20792/// @return the qualified name.
20793const interned_string&
20795{
20796 // Note that the qualified name has been already set by
20797 // qualified_name_setter::do_update, which is invoked by
20798 // update_qualified_name. The latter is itself invoked whenever the
20799 // typedef is added to its scope, in scope_decl::add_member_decl.
20800 if (internal)
20801 return decl_base::priv_->internal_qualified_name_;
20802 else
20803 return decl_base::priv_->qualified_name_;
20804}
20805
20806/// This implements the ir_traversable_base::traverse pure virtual
20807/// function.
20808///
20809/// @param v the visitor used on the current instance.
20810///
20811/// @return true if the entire IR node tree got traversed, false
20812/// otherwise.
20813bool
20815{
20816 if (v.type_node_has_been_visited(this))
20817 return true;
20818
20819 if (visiting())
20820 return true;
20821
20822 if (v.visit_begin(this))
20823 {
20824 visiting(true);
20825 if (type_base_sptr t = get_underlying_type())
20826 t->traverse(v);
20827 visiting(false);
20828 }
20829
20830 bool result = v.visit_end(this);
20832 return result;
20833}
20834
20835typedef_decl::~typedef_decl()
20836{}
20837// </typedef_decl definitions>
20838
20839// <var_decl definitions>
20840
20841struct var_decl::priv
20842{
20843 type_base_wptr type_;
20844 type_base* naked_type_;
20845 decl_base::binding binding_;
20846 elf_symbol_sptr symbol_;
20847 interned_string id_;
20848
20849 priv()
20850 : naked_type_(),
20851 binding_(decl_base::BINDING_GLOBAL)
20852 {}
20853
20854 priv(type_base_sptr t,
20856 : type_(t),
20857 naked_type_(t.get()),
20858 binding_(b)
20859 {}
20860
20861 /// Setter of the type of the variable.
20862 ///
20863 /// @param t the new variable type.
20864 void
20865 set_type(type_base_sptr t)
20866 {
20867 type_ = t;
20868 naked_type_ = t.get();
20869 }
20870}; // end struct var_decl::priv
20871
20872/// Constructor of the @ref var_decl type.
20873///
20874/// @param name the name of the variable declaration
20875///
20876/// @param type the type of the variable declaration
20877///
20878/// @param locus the source location where the variable was defined.
20879///
20880/// @param linkage_name the linkage name of the variable.
20881///
20882/// @param vis the visibility of of the variable.
20883///
20884/// @param bind the binding kind of the variable.
20885var_decl::var_decl(const string& name,
20886 type_base_sptr type,
20887 const location& locus,
20888 const string& linkage_name,
20889 visibility vis,
20890 binding bind)
20891 : type_or_decl_base(type->get_environment(),
20892 VAR_DECL | ABSTRACT_DECL_BASE),
20893 decl_base(type->get_environment(), name, locus, linkage_name, vis),
20894 priv_(new priv(type, bind))
20895{
20897}
20898
20899/// Getter of the type of the variable.
20900///
20901/// @return the type of the variable.
20902const type_base_sptr
20904{return priv_->type_.lock();}
20905
20906/// Setter of the type of the variable.
20907///
20908/// @param the new type of the variable.
20909void
20910var_decl::set_type(type_base_sptr& t)
20911{priv_->set_type(t);}
20912
20913/// Getter of the type of the variable.
20914///
20915/// This getter returns a bare pointer, as opposed to a smart pointer.
20916/// It's to be used on performance sensitive code paths identified by
20917/// careful profiling.
20918///
20919/// @return the type of the variable, as a bare pointer.
20920const type_base*
20922{return priv_->naked_type_;}
20923
20924/// Getter of the binding of the variable.
20925///
20926/// @return the biding of the variable.
20929{return priv_->binding_;}
20930
20931/// Setter of the binding of the variable.
20932///
20933/// @param b the new binding value.
20934void
20936{priv_->binding_ = b;}
20937
20938/// Sets the underlying ELF symbol for the current variable.
20939///
20940/// And underlyin$g ELF symbol for the current variable might exist
20941/// only if the corpus that this variable originates from was
20942/// constructed from an ELF binary file.
20943///
20944/// Note that comparing two variables that have underlying ELF symbols
20945/// involves comparing their underlying elf symbols. The decl name
20946/// for the variable thus becomes irrelevant in the comparison.
20947///
20948/// @param sym the new ELF symbol for this variable decl.
20949void
20951{
20952 priv_->symbol_ = sym;
20953 // The variable id cache that depends on the symbol must be
20954 // invalidated because the symbol changed.
20955 priv_->id_ = get_environment().intern("");
20956}
20957
20958/// Gets the the underlying ELF symbol for the current variable,
20959/// that was set using var_decl::set_symbol(). Please read the
20960/// documentation for that member function for more information about
20961/// "underlying ELF symbols".
20962///
20963/// @return sym the underlying ELF symbol for this variable decl, if
20964/// one exists.
20965const elf_symbol_sptr&
20967{return priv_->symbol_;}
20968
20969/// Create a new var_decl that is a clone of the current one.
20970///
20971/// @return the cloned var_decl.
20974{
20976 get_type(),
20977 get_location(),
20980 get_binding()));
20981
20982 v->set_symbol(get_symbol());
20983
20984 if (is_member_decl(*this))
20985 {
20989 get_member_is_static(*this),
20990 get_data_member_offset(*this));
20991 }
20992 else
20994
20995 return v;
20996}
20997/// Setter of the scope of the current var_decl.
20998///
20999/// Note that the decl won't hold a reference on the scope. It's
21000/// rather the scope that holds a reference on its members.
21001///
21002/// @param scope the new scope.
21003void
21004var_decl::set_scope(scope_decl* scope)
21005{
21006 if (!get_context_rel())
21007 set_context_rel(new dm_context_rel(scope));
21008 else
21009 get_context_rel()->set_scope(scope);
21010}
21011
21012/// Compares two instances of @ref var_decl without taking their type
21013/// into account.
21014///
21015/// If the two intances are different modulo their type, set a
21016/// bitfield to give some insight about the kind of differences there
21017/// are.
21018///
21019/// @param l the first artifact of the comparison.
21020///
21021/// @param r the second artifact of the comparison.
21022///
21023/// @param k a pointer to a bitfield that gives information about the
21024/// kind of changes there are between @p l and @p r. This one is set
21025/// iff @p k is non-null and the function returns false.
21026///
21027/// Please note that setting k to a non-null value does have a
21028/// negative performance impact because even if @p l and @p r are not
21029/// equal, the function keeps up the comparison in order to determine
21030/// the different kinds of ways in which they are different.
21031///
21032/// @return true if @p l equals @p r, false otherwise.
21033bool
21035{
21036 bool result = true;
21037
21038 // If there are underlying elf symbols for these variables,
21039 // compare them. And then compare the other parts.
21040 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
21041 if (!!s0 != !!s1)
21042 {
21043 result = false;
21044 if (k)
21046 else
21048 }
21049 else if (s0 && s0 != s1)
21050 {
21051 result = false;
21052 if (k)
21054 else
21056 }
21057 bool symbols_are_equal = (s0 && s1 && result);
21058
21059 if (symbols_are_equal)
21060 {
21061 // The variables have underlying elf symbols that are equal, so
21062 // now, let's compare the decl_base part of the variables w/o
21063 // considering their decl names.
21064 const environment& env = l.get_environment();
21065 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
21066 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
21067 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
21068 bool decl_bases_different = !l.decl_base::operator==(r);
21069 const_cast<var_decl&>(l).set_qualified_name(n1);
21070 const_cast<var_decl&>(r).set_qualified_name(n2);
21071
21072 if (decl_bases_different)
21073 {
21074 result = false;
21075 if (k)
21077 else
21079 }
21080 }
21081 else
21082 if (!l.decl_base::operator==(r))
21083 {
21084 result = false;
21085 if (k)
21087 else
21089 }
21090
21091 const dm_context_rel* c0 =
21092 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
21093 const dm_context_rel* c1 =
21094 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
21095 ABG_ASSERT(c0 && c1);
21096
21097 if (*c0 != *c1)
21098 {
21099 result = false;
21100 if (k)
21102 else
21104 }
21105
21106 ABG_RETURN(result);
21107}
21108
21109/// Compares two instances of @ref var_decl.
21110///
21111/// If the two intances are different, set a bitfield to give some
21112/// insight about the kind of differences there are.
21113///
21114/// @param l the first artifact of the comparison.
21115///
21116/// @param r the second artifact of the comparison.
21117///
21118/// @param k a pointer to a bitfield that gives information about the
21119/// kind of changes there are between @p l and @p r. This one is set
21120/// iff @p k is non-null and the function returns false.
21121///
21122/// Please note that setting k to a non-null value does have a
21123/// negative performance impact because even if @p l and @p r are not
21124/// equal, the function keeps up the comparison in order to determine
21125/// the different kinds of ways in which they are different.
21126///
21127/// @return true if @p l equals @p r, false otherwise.
21128bool
21129equals(const var_decl& l, const var_decl& r, change_kind* k)
21130{
21131 bool result = true;
21132
21133 // First test types of variables. This should be fast because in
21134 // the general case, most types should be canonicalized.
21135 if (*l.get_naked_type() != *r.get_naked_type())
21136 {
21137 result = false;
21138 if (k)
21139 {
21141 r.get_naked_type()))
21142 *k |= (LOCAL_TYPE_CHANGE_KIND);
21143 else
21144 *k |= SUBTYPE_CHANGE_KIND;
21145 }
21146 else
21148 }
21149
21150 result &= var_equals_modulo_types(l, r, k);
21151
21152 ABG_RETURN(result);
21153}
21154
21155/// Comparison operator of @ref var_decl.
21156///
21157/// @param o the instance of @ref var_decl to compare against.
21158///
21159/// @return true iff the current instance of @ref var_decl equals @p o.
21160bool
21162{
21163 const var_decl* other = dynamic_cast<const var_decl*>(&o);
21164 if (!other)
21165 return false;
21166
21167 return equals(*this, *other, 0);
21168}
21169
21170/// Return an ID that tries to uniquely identify the variable inside a
21171/// program or a library.
21172///
21173/// So if the variable has an underlying elf symbol, the ID is the
21174/// concatenation of the symbol name and its version. Otherwise, the
21175/// ID is the linkage name if its non-null. Otherwise, it's the
21176/// pretty representation of the variable.
21177///
21178/// @return the ID.
21181{
21182 if (priv_->id_.empty())
21183 {
21184 string repr = get_name();
21185 string sym_str;
21186 if (elf_symbol_sptr s = get_symbol())
21187 sym_str = s->get_id_string();
21188 else if (!get_linkage_name().empty())
21189 sym_str = get_linkage_name();
21190
21191 const environment& env = get_type()->get_environment();
21192 priv_->id_ = env.intern(repr);
21193 if (!sym_str.empty())
21194 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
21195 }
21196 return priv_->id_;
21197}
21198
21199/// Get the qualified name of a given variable or data member.
21200///
21201///
21202/// Note that if the current instance of @ref var_decl is an anonymous
21203/// data member, then the qualified name is actually the flat
21204/// representation (the definition) of the type of the anonymous data
21205/// member. We chose the flat representation because otherwise, the
21206/// name of an *anonymous* data member is empty, by construction, e.g:
21207///
21208/// struct foo {
21209/// int a;
21210/// union {
21211/// char b;
21212/// char c;
21213/// }; // <---- this data member is anonymous.
21214/// int d;
21215/// }
21216///
21217/// The string returned for the anonymous member here is going to be:
21218///
21219/// "union {char b; char c}"
21220///
21221/// @param internal if true then this is for a purpose to the library,
21222/// otherwise, it's for being displayed to users.
21223///
21224/// @return the resulting qualified name.
21225const interned_string&
21227{
21228 if (is_anonymous_data_member(this)
21229 && decl_base::get_qualified_name().empty())
21230 {
21231 // Display the anonymous data member in a way that makes sense.
21232 string r = get_pretty_representation(internal);
21234 }
21235
21236 return decl_base::get_qualified_name(internal);
21237}
21238
21239/// Build and return the pretty representation of this variable.
21240///
21241/// @param internal set to true if the call is intended to get a
21242/// representation of the decl (or type) for the purpose of canonical
21243/// type comparison. This is mainly used in the function
21244/// type_base::get_canonical_type_for().
21245///
21246/// In other words if the argument for this parameter is true then the
21247/// call is meant for internal use (for technical use inside the
21248/// library itself), false otherwise. If you don't know what this is
21249/// for, then set it to false.
21250///
21251/// @param qualified_name if true, names emitted in the pretty
21252/// representation are fully qualified.
21253///
21254/// @return a copy of the pretty representation of this variable.
21255string
21256var_decl::get_pretty_representation(bool internal, bool qualified_name) const
21257{
21258 string result;
21259
21260 if (is_member_decl(this) && get_member_is_static(this))
21261 result = "static ";
21262
21263 // Detect if the current instance of var_decl is a member of
21264 // an anonymous class or union.
21265 bool member_of_anonymous_class = false;
21266 if (class_or_union* scope = is_at_class_scope(this))
21267 if (scope->get_is_anonymous())
21268 member_of_anonymous_class = true;
21269
21270 type_base_sptr type = get_type();
21271 if (is_array_type(type, /*look_through_qualifiers=*/true)
21272 || is_pointer_type(type, /*look_through_qualifiers=*/true)
21273 || is_reference_type(type, /*look_through_qualifiers=*/true)
21274 || is_ptr_to_mbr_type(type, /*look_through_qualifiers=*/true))
21275 {
21276 string name;
21277 if (member_of_anonymous_class || !qualified_name)
21278 name = get_name();
21279 else
21280 name = get_qualified_name(internal);
21281
21282 if (qualified_type_def_sptr q = is_qualified_type(type))
21283 {
21284 string quals_repr =
21285 get_string_representation_of_cv_quals(q->get_cv_quals());
21286 if (!quals_repr.empty())
21287 name = quals_repr + " " + name;
21288 type = peel_qualified_type(type);
21289 }
21290
21291 name = string(" ") + name;
21292 if (array_type_def_sptr t = is_array_type(type))
21293 result += array_declaration_name(t, name, qualified_name, internal);
21294 else if (pointer_type_def_sptr t = is_pointer_type(type))
21295 result += pointer_declaration_name(t, name, qualified_name, internal);
21296 else if (reference_type_def_sptr t = is_reference_type(type))
21297 result += pointer_declaration_name(t, name, qualified_name, internal);
21298 else if (ptr_to_mbr_type_sptr t = is_ptr_to_mbr_type(type))
21299 result += ptr_to_mbr_declaration_name(t, name,
21300 qualified_name,
21301 internal);
21302 }
21303 else
21304 {
21305 if (/*The current var_decl is to be used as an anonymous data
21306 member. */
21307 get_name().empty())
21308 {
21309 // Display the anonymous data member in a way that
21310 // makes sense.
21311 result +=
21314 "", /*one_line=*/true, internal);
21315 }
21316 else if (data_member_has_anonymous_type(this))
21317 {
21320 "", /*one_line=*/true, internal);
21321 result += " ";
21322 if (!internal
21323 && (member_of_anonymous_class || !qualified_name))
21324 // It doesn't make sense to name the member of an
21325 // anonymous class or union like:
21326 // "__anonymous__::data_member_name". So let's just use
21327 // its non-qualified name.
21328 result += get_name();
21329 else
21330 result += get_qualified_name(internal);
21331 }
21332 else
21333 {
21334 result +=
21336 + " ";
21337
21338 if (!internal
21339 && (member_of_anonymous_class || !qualified_name))
21340 // It doesn't make sense to name the member of an
21341 // anonymous class or union like:
21342 // "__anonymous__::data_member_name". So let's just use
21343 // its non-qualified name.
21344 result += get_name();
21345 else
21346 result += get_qualified_name(internal);
21347 }
21348 }
21349 return result;
21350}
21351
21352/// Get a name that is valid even for an anonymous data member.
21353///
21354/// If the current @ref var_decl is an anonymous data member, then
21355/// return its pretty representation. As of now, that pretty
21356/// representation is actually its flat representation as returned by
21357/// get_class_or_union_flat_representation().
21358///
21359/// Otherwise, just return the name of the current @ref var_decl.
21360///
21361/// @param qualified if true, return the qualified name. This doesn't
21362/// have an effet if the current @ref var_decl represents an anonymous
21363/// data member.
21364string
21366{
21367 string name;
21368 if (is_anonymous_data_member(this))
21369 // This function is used in the comparison engine to determine
21370 // which anonymous data member was deleted. So it's not involved
21371 // in type comparison or canonicalization. We don't want to use
21372 // the 'internal' version of the pretty presentation.
21373 name = get_pretty_representation(/*internal=*/false, qualified);
21374 else
21375 name = get_name();
21376
21377 return name;
21378}
21379
21380/// This implements the ir_traversable_base::traverse pure virtual
21381/// function.
21382///
21383/// @param v the visitor used on the current instance.
21384///
21385/// @return true if the entire IR node tree got traversed, false
21386/// otherwise.
21387bool
21389{
21390 if (visiting())
21391 return true;
21392
21393 if (v.visit_begin(this))
21394 {
21395 visiting(true);
21396 if (type_base_sptr t = get_type())
21397 t->traverse(v);
21398 visiting(false);
21399 }
21400 return v.visit_end(this);
21401}
21402
21403var_decl::~var_decl()
21404{}
21405
21406// </var_decl definitions>
21407
21408/// This function is automatically invoked whenever an instance of
21409/// this type is canonicalized.
21410///
21411/// It's an overload of the virtual type_base::on_canonical_type_set.
21412///
21413/// We put here what is thus meant to be executed only at the point of
21414/// type canonicalization.
21415void
21417{
21418 priv_->cached_name_.clear();
21419 priv_->internal_cached_name_.clear();
21420}
21421
21422/// The most straightforward constructor for the function_type class.
21423///
21424/// @param return_type the return type of the function type.
21425///
21426/// @param parms the list of parameters of the function type.
21427/// Stricto sensu, we just need a list of types; we are using a list
21428/// of parameters (where each parameter also carries the name of the
21429/// parameter and its source location) to try and provide better
21430/// diagnostics whenever it makes sense. If it appears that this
21431/// wasts too many resources, we can fall back to taking just a
21432/// vector of types here.
21433///
21434/// @param size_in_bits the size of this type, in bits.
21435///
21436/// @param alignment_in_bits the alignment of this type, in bits.
21437///
21438/// @param size_in_bits the size of this type.
21439function_type::function_type(type_base_sptr return_type,
21440 const parameters& parms,
21441 size_t size_in_bits,
21442 size_t alignment_in_bits)
21443 : type_or_decl_base(return_type->get_environment(),
21444 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21445 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21446 priv_(new priv(parms, return_type))
21447{
21449
21450 for (parameters::size_type i = 0, j = 1;
21451 i < priv_->parms_.size();
21452 ++i, ++j)
21453 {
21454 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21455 // If the first parameter is artificial, then it certainly
21456 // means that this is a member function, and the first
21457 // parameter is the implicit this pointer. In that case, set
21458 // the index of that implicit parameter to zero. Otherwise,
21459 // the index of the first parameter starts at one.
21460 j = 0;
21461 priv_->parms_[i]->set_index(j);
21462 }
21463}
21464
21465/// A constructor for a function_type that takes no parameters.
21466///
21467/// @param return_type the return type of this function_type.
21468///
21469/// @param size_in_bits the size of this type, in bits.
21470///
21471/// @param alignment_in_bits the alignment of this type, in bits.
21472function_type::function_type(type_base_sptr return_type,
21473 size_t size_in_bits, size_t alignment_in_bits)
21474 : type_or_decl_base(return_type->get_environment(),
21475 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21476 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21477 priv_(new priv(return_type))
21478{
21480}
21481
21482/// A constructor for a function_type that takes no parameter and
21483/// that has no return_type yet. These missing parts can (and must)
21484/// be added later.
21485///
21486/// @param env the environment we are operating from.
21487///
21488/// @param size_in_bits the size of this type, in bits.
21489///
21490/// @param alignment_in_bits the alignment of this type, in bits.
21491function_type::function_type(const environment& env,
21492 size_t size_in_bits,
21493 size_t alignment_in_bits)
21494 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21495 type_base(env, size_in_bits, alignment_in_bits),
21496 priv_(new priv)
21497{
21499}
21500
21501/// Return the hash value of the current IR node.
21502///
21503/// Note that upon the first invocation, this member functions
21504/// computes the hash value and returns it. Subsequent invocations
21505/// just return the hash value that was previously calculated.
21506///
21507/// @return the hash value of the current IR node.
21508hash_t
21510{
21512 return h;
21513}
21514
21515/// Getter for the return type of the current instance of @ref
21516/// function_type.
21517///
21518/// @return the return type.
21519type_base_sptr
21521{return priv_->return_type_.lock();}
21522
21523/// Setter of the return type of the current instance of @ref
21524/// function_type.
21525///
21526/// @param t the new return type to set.
21527void
21529{priv_->return_type_ = t;}
21530
21531/// Getter for the set of parameters of the current intance of @ref
21532/// function_type.
21533///
21534/// @return the parameters of the current instance of @ref
21535/// function_type.
21538{return priv_->parms_;}
21539
21540/// Get the Ith parameter of the vector of parameters of the current
21541/// instance of @ref function_type.
21542///
21543/// Note that the first parameter is at index 0. That parameter is
21544/// the first parameter that comes after the possible implicit "this"
21545/// parameter, when the current instance @ref function_type is for a
21546/// member function. Otherwise, if the current instance of @ref
21547/// function_type is for a non-member function, the parameter at index
21548/// 0 is the first parameter of the function.
21549///
21550///
21551/// @param i the index of the parameter to return. If i is greater
21552/// than the index of the last parameter, then this function returns
21553/// an empty parameter (smart) pointer.
21554///
21555/// @return the @p i th parameter that is not implicit.
21558{
21559 parameter_sptr result;
21560 if (dynamic_cast<const method_type*>(this))
21561 {
21562 if (i + 1 < get_parameters().size())
21563 result = get_parameters()[i + 1];
21564 }
21565 else
21566 {
21567 if (i < get_parameters().size())
21568 result = get_parameters()[i];
21569 }
21570 return result;
21571}
21572
21573/// Setter for the parameters of the current instance of @ref
21574/// function_type.
21575///
21576/// @param p the new vector of parameters to set.
21577void
21579{
21580 priv_->parms_ = p;
21581 for (parameters::size_type i = 0, j = 1;
21582 i < priv_->parms_.size();
21583 ++i, ++j)
21584 {
21585 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21586 // If the first parameter is artificial, then it certainly
21587 // means that this is a member function, and the first
21588 // parameter is the implicit this pointer. In that case, set
21589 // the index of that implicit parameter to zero. Otherwise,
21590 // the index of the first parameter starts at one.
21591 j = 0;
21592 priv_->parms_[i]->set_index(j);
21593 }
21594}
21595
21596/// Append a new parameter to the vector of parameters of the current
21597/// instance of @ref function_type.
21598///
21599/// @param parm the parameter to append.
21600void
21602{
21603 parm->set_index(priv_->parms_.size());
21604 priv_->parms_.push_back(parm);
21605}
21606
21607/// Test if the current instance of @ref function_type is for a
21608/// variadic function.
21609///
21610/// A variadic function is a function that takes a variable number of
21611/// arguments.
21612///
21613/// @return true iff the current instance of @ref function_type is for
21614/// a variadic function.
21615bool
21617{
21618 return (!priv_->parms_.empty()
21619 && priv_->parms_.back()->get_variadic_marker());
21620}
21621
21622/// Compare two function types.
21623///
21624/// In case these function types are actually method types, this
21625/// function avoids comparing two parameters (of the function types)
21626/// if the types of the parameters are actually the types of the
21627/// classes of the method types. This prevents infinite recursion
21628/// during the comparison of two classes that are structurally
21629/// identical.
21630///
21631/// This is a subroutine of the equality operator of function_type.
21632///
21633/// @param lhs the first function type to consider
21634///
21635/// @param rhs the second function type to consider
21636///
21637/// @param k a pointer to a bitfield set by the function to give
21638/// information about the kind of changes carried by @p lhs and @p
21639/// rhs. It is set iff @p k is non-null and the function returns
21640/// false.
21641///
21642/// Please note that setting k to a non-null value does have a
21643/// negative performance impact because even if @p l and @p r are not
21644/// equal, the function keeps up the comparison in order to determine
21645/// the different kinds of ways in which they are different.
21646///
21647///@return true if lhs == rhs, false otherwise.
21648bool
21650{
21651#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
21652
21654
21655 {
21656 // First of all, let's see if these two function types haven't
21657 // already been compared. If so, and if the result of the
21658 // comparison has been cached, let's just re-use it, rather than
21659 // comparing them all over again.
21660 bool cached_result = false;
21661 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
21662 cached_result))
21663 ABG_RETURN(cached_result);
21664 }
21665
21667
21668 bool result = true;
21669
21670 if (!l.type_base::operator==(r))
21671 {
21672 result = false;
21673 if (k)
21675 else
21676 RETURN(result);
21677 }
21678
21679 class_or_union* l_class = 0, *r_class = 0;
21680 if (const method_type* m = dynamic_cast<const method_type*>(&l))
21681 l_class = m->get_class_type().get();
21682
21683 if (const method_type* m = dynamic_cast<const method_type*>(&r))
21684 r_class = m->get_class_type().get();
21685
21686 // Compare the names of the class of the method
21687
21688 if (!!l_class != !!r_class)
21689 {
21690 result = false;
21691 if (k)
21693 else
21694 RETURN(result);
21695 }
21696 else if (l_class
21697 && (l_class->get_qualified_name()
21698 != r_class->get_qualified_name()))
21699 {
21700 result = false;
21701 if (k)
21703 else
21704 RETURN(result);
21705 }
21706
21707 // Then compare the return type; Beware if it's t's a class type
21708 // that is the same as the method class name; we can recurse for
21709 // ever in that case.
21710
21711 decl_base* l_return_type_decl =
21713 decl_base* r_return_type_decl =
21715 bool compare_result_types = true;
21716 string l_rt_name = l_return_type_decl
21717 ? l_return_type_decl->get_qualified_name()
21718 : string();
21719 string r_rt_name = r_return_type_decl
21720 ? r_return_type_decl->get_qualified_name()
21721 : string();
21722
21723 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
21724 ||
21725 (r_class && (r_class->get_qualified_name() == r_rt_name)))
21726 compare_result_types = false;
21727
21728 if (compare_result_types)
21729 {
21730 // Let's not consider typedefs when comparing return types to
21731 // avoid spurious changes.
21732 //
21733 // TODO: We should also do this for parameter types, or rather,
21734 // we should teach the equality operators in the IR, at some
21735 // point, to peel typedefs off.
21736 if (l.get_return_type() != r.get_return_type())
21737 {
21738 result = false;
21739 if (k)
21740 {
21742 r.get_return_type()))
21744 else
21745 *k |= SUBTYPE_CHANGE_KIND;
21746 }
21747 else
21748 RETURN(result);
21749 }
21750 }
21751 else
21752 if (l_rt_name != r_rt_name)
21753 {
21754 result = false;
21755 if (k)
21756 *k |= SUBTYPE_CHANGE_KIND;
21757 else
21758 RETURN(result);
21759 }
21760
21761 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
21762 for (i = l.get_first_parm(), j = r.get_first_parm();
21763 i != l.get_parameters().end() && j != r.get_parameters().end();
21764 ++i, ++j)
21765 {
21766 if (**i != **j)
21767 {
21768 result = false;
21769 if (k)
21770 {
21771 if (!types_have_similar_structure((*i)->get_type(),
21772 (*j)->get_type()))
21774 else
21775 *k |= SUBTYPE_CHANGE_KIND;
21776 }
21777 else
21778 RETURN(result);
21779 }
21780 }
21781
21782 if ((i != l.get_parameters().end()
21783 || j != r.get_parameters().end()))
21784 {
21785 result = false;
21786 if (k)
21788 else
21789 RETURN(result);
21790 }
21791
21792 RETURN(result);
21793#undef RETURN
21794}
21795
21796/// Get the first parameter of the function.
21797///
21798/// If the function is a non-static member function, the parameter
21799/// returned is the first one following the implicit 'this' parameter.
21800///
21801/// @return the first non implicit parameter of the function.
21802function_type::parameters::const_iterator
21804{
21805 if (get_parameters().empty())
21806 return get_parameters().end();
21807
21808 bool is_method = dynamic_cast<const method_type*>(this);
21809
21810 parameters::const_iterator i = get_parameters().begin();
21811
21812 if (is_method && (*i)->get_is_artificial())
21813 ++i;
21814
21815 return i;
21816}
21817
21818/// Get the first parameter of the function.
21819///
21820/// Note that if the function is a non-static member function, the
21821/// parameter returned is the implicit 'this' parameter.
21822///
21823/// @return the first parameter of the function.
21824function_type::parameters::const_iterator
21826{return get_parameters().begin();}
21827
21828/// Get the name of the current @ref function_type.
21829///
21830/// The name is retrieved from a cache. If the cache is empty, this
21831/// function computes the name of the type, stores it in the cache and
21832/// returns it. Subsequent invocation of the function are going to
21833/// just hit the cache.
21834///
21835/// Note that if the type is *NOT* canonicalized then function type
21836/// name is never cached.
21837///
21838/// @param internal if true then it means the function type name is
21839/// going to be used for purposes that are internal to libabigail
21840/// itself. If you don't know what this is then you probably should
21841/// set this parameter to 'false'.
21842///
21843/// @return the name of the function type.
21844const interned_string&
21846{
21847 if (internal)
21848 {
21850 {
21851 if (priv_->internal_cached_name_.empty())
21852 priv_->internal_cached_name_ =
21853 get_function_type_name(this, /*internal=*/true);
21854 return priv_->internal_cached_name_;
21855 }
21856 else
21857 {
21858 priv_->temp_internal_cached_name_ =
21859 get_function_type_name(this, /*internal=*/true);
21860 return priv_->temp_internal_cached_name_;
21861 }
21862 }
21863 else
21864 {
21866 {
21867 if (priv_->cached_name_.empty())
21868 priv_->cached_name_ =
21869 get_function_type_name(this, /*internal=*/false);
21870 return priv_->cached_name_;
21871 }
21872 else
21873 {
21874 priv_->cached_name_ =
21875 get_function_type_name(this, /*internal=*/false);
21876 return priv_->cached_name_;
21877 }
21878 }
21879}
21880
21881/// Equality operator for function_type.
21882///
21883/// @param o the other function_type to compare against.
21884///
21885/// @return true iff the two function_type are equal.
21886bool
21888{
21889 const function_type* o = dynamic_cast<const function_type*>(&other);
21890 if (!o)
21891 return false;
21892 return try_canonical_compare(this, o);
21893}
21894
21895/// Return a copy of the pretty representation of the current @ref
21896/// function_type.
21897///
21898/// @param internal set to true if the call is intended to get a
21899/// representation of the decl (or type) for the purpose of canonical
21900/// type comparison. This is mainly used in the function
21901/// type_base::get_canonical_type_for().
21902///
21903/// In other words if the argument for this parameter is true then the
21904/// call is meant for internal use (for technical use inside the
21905/// library itself), false otherwise. If you don't know what this is
21906/// for, then set it to false.
21907///
21908/// @return a copy of the pretty representation of the current @ref
21909/// function_type.
21910string
21912 bool /*qualified_name*/) const
21913{return ir::get_pretty_representation(this, internal);}
21914
21915/// Traverses an instance of @ref function_type, visiting all the
21916/// sub-types and decls that it might contain.
21917///
21918/// @param v the visitor that is used to visit every IR sub-node of
21919/// the current node.
21920///
21921/// @return true if either
21922/// - all the children nodes of the current IR node were traversed
21923/// and the calling code should keep going with the traversing.
21924/// - or the current IR node is already being traversed.
21925/// Otherwise, returning false means that the calling code should not
21926/// keep traversing the tree.
21927bool
21929{
21930 // TODO: should we allow the walker to avoid visiting function type
21931 // twice? I think that if we do, then ir_node_visitor needs an
21932 // option to specifically disallow this feature for function types.
21933
21934 if (visiting())
21935 return true;
21936
21937 if (v.visit_begin(this))
21938 {
21939 visiting(true);
21940 bool keep_going = true;
21941
21942 if (type_base_sptr t = get_return_type())
21943 {
21944 if (!t->traverse(v))
21945 keep_going = false;
21946 }
21947
21948 if (keep_going)
21949 for (parameters::const_iterator i = get_parameters().begin();
21950 i != get_parameters().end();
21951 ++i)
21952 if (type_base_sptr parm_type = (*i)->get_type())
21953 if (!parm_type->traverse(v))
21954 break;
21955
21956 visiting(false);
21957 }
21958 return v.visit_end(this);
21959}
21960
21961function_type::~function_type()
21962{}
21963// </function_type>
21964
21965// <method_type>
21966
21967struct method_type::priv
21968{
21969 class_or_union_wptr class_type_;
21970 bool is_const;
21971
21972 priv()
21973 : is_const()
21974 {}
21975}; // end struct method_type::priv
21976
21977/// Constructor for instances of method_type.
21978///
21979/// Instances of method_decl must be of type method_type.
21980///
21981/// @param return_type the type of the return value of the method.
21982///
21983/// @param class_type the base type of the method type. That is, the
21984/// type of the class the method belongs to.
21985///
21986/// @param p the vector of the parameters of the method.
21987///
21988/// @param is_const whether this method type is for a const method.
21989/// Note that const-ness is a property of the method *type* and of the
21990/// relationship between a method *declaration* and its scope.
21991///
21992/// @param size_in_bits the size of an instance of method_type,
21993/// expressed in bits.
21994///
21995/// @param alignment_in_bits the alignment of an instance of
21996/// method_type, expressed in bits.
21997method_type::method_type (type_base_sptr return_type,
21998 class_or_union_sptr class_type,
21999 const std::vector<function_decl::parameter_sptr>& p,
22000 bool is_const,
22001 size_t size_in_bits,
22002 size_t alignment_in_bits)
22003 : type_or_decl_base(class_type->get_environment(),
22004 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22005 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22006 function_type(return_type, p, size_in_bits, alignment_in_bits),
22007 priv_(new priv)
22008{
22010 set_class_type(class_type);
22011 set_is_const(is_const);
22012}
22013
22014/// Constructor of instances of method_type.
22015///
22016///Instances of method_decl must be of type method_type.
22017///
22018/// @param return_type the type of the return value of the method.
22019///
22020/// @param class_type the type of the class the method belongs to.
22021/// The actual (dynamic) type of class_type must be a pointer
22022/// class_type. We are setting it to pointer to type_base here to
22023/// help client code that is compiled without rtti and thus cannot
22024/// perform dynamic casts.
22025///
22026/// @param p the vector of the parameters of the method type.
22027///
22028/// @param is_const whether this method type is for a const method.
22029/// Note that const-ness is a property of the method *type* and of the
22030/// relationship between a method *declaration* and its scope.
22031///
22032/// @param size_in_bits the size of an instance of method_type,
22033/// expressed in bits.
22034///
22035/// @param alignment_in_bits the alignment of an instance of
22036/// method_type, expressed in bits.
22037method_type::method_type(type_base_sptr return_type,
22038 type_base_sptr class_type,
22039 const std::vector<function_decl::parameter_sptr>& p,
22040 bool is_const,
22041 size_t size_in_bits,
22042 size_t alignment_in_bits)
22043 : type_or_decl_base(class_type->get_environment(),
22044 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22045 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22046 function_type(return_type, p, size_in_bits, alignment_in_bits),
22047 priv_(new priv)
22048{
22050 set_class_type(is_class_type(class_type));
22051 set_is_const(is_const);
22052}
22053
22054/// Constructor of the qualified_type_def
22055///
22056/// @param env the environment we are operating from.
22057///
22058/// @param size_in_bits the size of the type, expressed in bits.
22059///
22060/// @param alignment_in_bits the alignment of the type, expressed in bits
22061method_type::method_type(const environment& env,
22062 size_t size_in_bits,
22063 size_t alignment_in_bits)
22064 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22065 type_base(env, size_in_bits, alignment_in_bits),
22066 function_type(env, size_in_bits, alignment_in_bits),
22067 priv_(new priv)
22068{
22070}
22071
22072/// Constructor of instances of method_type.
22073///
22074/// When constructed with this constructor, and instane of method_type
22075/// must set a return type using method_type::set_return_type
22076///
22077/// @param class_typ the base type of the method type. That is, the
22078/// type of the class (or union) the method belongs to.
22079///
22080/// @param size_in_bits the size of an instance of method_type,
22081/// expressed in bits.
22082///
22083/// @param alignment_in_bits the alignment of an instance of
22084/// method_type, expressed in bits.
22085method_type::method_type(class_or_union_sptr class_type,
22086 bool is_const,
22087 size_t size_in_bits,
22088 size_t alignment_in_bits)
22089 : type_or_decl_base(class_type->get_environment(),
22090 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22091 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22092 function_type(class_type->get_environment(),
22093 size_in_bits,
22094 alignment_in_bits),
22095 priv_(new priv)
22096{
22098 set_class_type(class_type);
22099 set_is_const(is_const);
22100}
22101
22102/// Return the hash value of the current IR node.
22103///
22104/// Note that upon the first invocation, this member functions
22105/// computes the hash value and returns it. Subsequent invocations
22106/// just return the hash value that was previously calculated.
22107///
22108/// @return the hash value of the current IR node.
22109hash_t
22111{
22113 return h;
22114}
22115
22116/// Get the class type this method belongs to.
22117///
22118/// @return the class type.
22119class_or_union_sptr
22121{return class_or_union_sptr(priv_->class_type_);}
22122
22123/// Sets the class type of the current instance of method_type.
22124///
22125/// The class type is the type of the class the method belongs to.
22126///
22127/// @param t the new class type to set.
22128void
22129method_type::set_class_type(const class_or_union_sptr& t)
22130{
22131 if (!t)
22132 return;
22133
22134 priv_->class_type_ = t;
22135}
22136
22137/// Return a copy of the pretty representation of the current @ref
22138/// method_type.
22139///
22140/// @param internal set to true if the call is intended to get a
22141/// representation of the decl (or type) for the purpose of canonical
22142/// type comparison. This is mainly used in the function
22143/// type_base::get_canonical_type_for().
22144///
22145/// In other words if the argument for this parameter is true then the
22146/// call is meant for internal use (for technical use inside the
22147/// library itself), false otherwise. If you don't know what this is
22148/// for, then set it to false.
22149///
22150/// @return a copy of the pretty representation of the current @ref
22151/// method_type.
22152string
22154 bool /*qualified_name*/) const
22155{return ir::get_pretty_representation(*this, internal);}
22156
22157/// Setter of the "is-const" property of @ref method_type.
22158///
22159/// @param the new value of the "is-const" property.
22160void
22162{priv_->is_const = f;}
22163
22164/// Getter of the "is-const" property of @ref method_type.
22165///
22166/// @return true iff the "is-const" property was set.
22167bool
22169{return priv_->is_const;}
22170
22171/// Test if the current method type is for a static method or not.
22172///
22173/// @return true iff the current method_type denotes a the type of a
22174/// static method.
22175bool
22177{
22178 // Let's see if the first parameter is artificial and is a pointer
22179 // to an instance of the same class type as the current class.
22181 if (!get_parameters().empty())
22182 first_parm = get_parameters()[0];
22183 if (!first_parm)
22184 return true;
22185 if (!first_parm->get_is_artificial())
22186 return true;
22187
22188 type_base_sptr this_ptr_type = first_parm->get_type();
22189 // Sometimes, the type of the "this" pointer is "const class_type*
22190 // const". Meaning that the "this pointer" itself is const
22191 // qualified. So let's get the underlying non-qualified pointer.
22192 this_ptr_type = peel_qualified_type(this_ptr_type);
22193 if (!is_pointer_type(this_ptr_type))
22194 return true;
22195
22196 type_base_sptr candidate_class_type =
22197 is_pointer_type(this_ptr_type)->get_pointed_to_type();
22198 candidate_class_type = peel_qualified_type(candidate_class_type);
22199 if (is_class_type(candidate_class_type)
22200 && get_type_name(candidate_class_type) == get_type_name(get_class_type()))
22201 // At this point, we are sure we are looking at a *non-static*
22202 // method.
22203 return false;
22204
22205 return true;
22206}
22207
22208/// The destructor of method_type
22210{}
22211
22212// </method_type>
22213
22214// <function_decl definitions>
22215
22216struct function_decl::priv
22217{
22218 bool declared_inline_;
22219 decl_base::binding binding_;
22220 function_type_wptr type_;
22221 function_type* naked_type_;
22222 elf_symbol_sptr symbol_;
22223 interned_string id_;
22224
22225 priv()
22226 : declared_inline_(false),
22227 binding_(decl_base::BINDING_GLOBAL),
22228 naked_type_()
22229 {}
22230
22231 priv(function_type_sptr t,
22232 bool declared_inline,
22234 : declared_inline_(declared_inline),
22235 binding_(binding),
22236 type_(t),
22237 naked_type_(t.get())
22238 {}
22239
22240 priv(function_type_sptr t,
22241 bool declared_inline,
22244 : declared_inline_(declared_inline),
22245 binding_(binding),
22246 type_(t),
22247 naked_type_(t.get()),
22248 symbol_(s)
22249 {}
22250}; // end sruct function_decl::priv
22251
22252/// Constructor of the @ref function_decl.
22253///
22254/// @param name the name of the function.
22255///
22256/// @param function_type the type of the function.
22257///
22258/// @param declared_inline wether the function is declared inline.
22259///
22260/// @param locus the source location of the function.
22261///
22262/// @param mangled_name the linkage name of the function.
22263///
22264/// @param vis the visibility of the function.
22265///
22266/// @param bind the binding of the function.
22269 bool declared_inline,
22270 const location& locus,
22271 const string& mangled_name,
22272 visibility vis,
22273 binding bind)
22274 : type_or_decl_base(function_type->get_environment(),
22275 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22276 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
22277 priv_(new priv(function_type, declared_inline, bind))
22278{
22280}
22281
22282/// Constructor of the function_decl type.
22283///
22284/// This flavour of constructor is for when the pointer to the
22285/// instance of function_type that the client code has is presented as
22286/// a pointer to type_base. In that case, this constructor saves the
22287/// client code from doing a dynamic_cast to get the function_type
22288/// pointer.
22289///
22290/// @param name the name of the function declaration.
22291///
22292/// @param fn_type the type of the function declaration. The dynamic
22293/// type of this parameter should be 'pointer to function_type'
22294///
22295/// @param declared_inline whether this function was declared inline
22296///
22297/// @param locus the source location of the function declaration.
22298///
22299/// @param linkage_name the mangled name of the function declaration.
22300///
22301/// @param vis the visibility of the function declaration.
22302///
22303/// @param bind the kind of the binding of the function
22304/// declaration.
22306 type_base_sptr fn_type,
22307 bool declared_inline,
22308 const location& locus,
22309 const string& linkage_name,
22310 visibility vis,
22311 binding bind)
22312 : type_or_decl_base(fn_type->get_environment(),
22313 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22314 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
22315 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
22316 declared_inline,
22317 bind))
22318{
22320}
22321
22322/// Get the pretty representation of the current instance of @ref function_decl.
22323///
22324/// @param internal set to true if the call is intended to get a
22325/// representation of the decl (or type) for the purpose of canonical
22326/// type comparison. This is mainly used in the function
22327/// type_base::get_canonical_type_for().
22328///
22329/// In other words if the argument for this parameter is true then the
22330/// call is meant for internal use (for technical use inside the
22331/// library itself), false otherwise. If you don't know what this is
22332/// for, then set it to false.
22333///
22334/// @return the pretty representation for a function.
22335string
22337 bool qualified_name) const
22338{
22339 const method_decl* mem_fn =
22340 dynamic_cast<const method_decl*>(this);
22341
22342 string fn_prefix = mem_fn ? "method ": "function ";
22343 string result;
22344
22345 if (mem_fn
22346 && is_member_function(mem_fn)
22348 fn_prefix += "virtual ";
22349
22350 decl_base_sptr return_type;
22351 if ((mem_fn
22352 && is_member_function(mem_fn)
22353 && (get_member_function_is_dtor(*mem_fn)
22354 || get_member_function_is_ctor(*mem_fn))))
22355 /*cdtors do not have return types. */;
22356 else
22357 return_type = mem_fn
22358 ? get_type_declaration(mem_fn->get_type()->get_return_type())
22360
22361 result = get_pretty_representation_of_declarator(internal);
22362 if (return_type)
22363 {
22364 if (is_npaf_type(is_type(return_type))
22365 || !(is_pointer_to_function_type(is_type(return_type))
22366 || is_pointer_to_array_type(is_type(return_type))))
22367 result = get_type_name(is_type(return_type).get(), qualified_name,
22368 internal) + " " + result;
22369 else if (pointer_type_def_sptr p =
22371 result = add_outer_pointer_to_fn_type_expr(p, result,
22372 /*qualified=*/true,
22373 internal);
22374 else if(pointer_type_def_sptr p =
22375 is_pointer_to_array_type(is_type(return_type)))
22376 result = add_outer_pointer_to_array_type_expr(p, result,
22377 qualified_name,
22378 internal);
22379 else
22381 }
22382
22383 return fn_prefix + result;
22384}
22385
22386/// Compute and return the pretty representation for the part of the
22387/// function declaration that starts at the declarator. That is, the
22388/// return type and the other specifiers of the beginning of the
22389/// function's declaration ar omitted.
22390///
22391/// @param internal set to true if the call is intended to get a
22392/// representation of the decl (or type) for the purpose of canonical
22393/// type comparison. This is mainly used in the function
22394/// type_base::get_canonical_type_for().
22395///
22396/// In other words if the argument for this parameter is true then the
22397/// call is meant for internal use (for technical use inside the
22398/// library itself), false otherwise. If you don't know what this is
22399/// for, then set it to false.
22400///
22401/// @return the pretty representation for the part of the function
22402/// declaration that starts at the declarator.
22403string
22405{
22406 const method_decl* mem_fn =
22407 dynamic_cast<const method_decl*>(this);
22408
22409 string result;
22410
22411 if (mem_fn)
22412 {
22413 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
22414 + "::" + mem_fn->get_name();
22415 }
22416 else
22417 result += get_qualified_name();
22418
22419 std::ostringstream fn_parms;
22420 stream_pretty_representation_of_fn_parms(*get_type(),
22421 fn_parms,
22422 /*qualified=*/true,
22423 internal);
22424 result += fn_parms.str();
22425
22426 if (mem_fn
22427 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
22428 || is_method_type(mem_fn->get_type())->get_is_const()))
22429 result += " const";
22430
22431 return result;
22432}
22433
22434/// Getter for the first non-implicit parameter of a function decl.
22435///
22436/// If the function is a non-static member function, the parameter
22437/// returned is the first one following the implicit 'this' parameter.
22438///
22439/// @return the first non implicit parm.
22440function_decl::parameters::const_iterator
22442{
22443 if (get_parameters().empty())
22444 return get_parameters().end();
22445
22446 bool is_method = dynamic_cast<const method_decl*>(this);
22447
22448 parameters::const_iterator i = get_parameters().begin();
22449 if (is_method)
22450 ++i;
22451
22452 return i;
22453}
22454
22455/// Return the type of the current instance of @ref function_decl.
22456///
22457/// It's either a function_type or method_type.
22458/// @return the type of the current instance of @ref function_decl.
22459const shared_ptr<function_type>
22461{return priv_->type_.lock();}
22462
22463/// Fast getter of the type of the current instance of @ref function_decl.
22464///
22465/// Note that this function returns the underlying pointer managed by
22466/// the smart pointer returned by function_decl::get_type(). It's
22467/// faster than function_decl::get_type(). This getter is to be used
22468/// in code paths that are proven to be performance hot spots;
22469/// especially (for instance) when comparing function types. Those
22470/// are compared extremely frequently when libabigail is used to
22471/// handle huge binaries with a lot of functions.
22472///
22473/// @return the type of the current instance of @ref function_decl.
22474const function_type*
22476{return priv_->naked_type_;}
22477
22478void
22479function_decl::set_type(const function_type_sptr& fn_type)
22480{
22481 priv_->type_ = fn_type;
22482 priv_->naked_type_ = fn_type.get();
22483}
22484
22485/// This sets the underlying ELF symbol for the current function decl.
22486///
22487/// And underlyin$g ELF symbol for the current function decl might
22488/// exist only if the corpus that this function decl originates from
22489/// was constructed from an ELF binary file.
22490///
22491/// Note that comparing two function decls that have underlying ELF
22492/// symbols involves comparing their underlying elf symbols. The decl
22493/// name for the function thus becomes irrelevant in the comparison.
22494///
22495/// @param sym the new ELF symbol for this function decl.
22496void
22498{
22499 priv_->symbol_ = sym;
22500 // The function id cache that depends on the symbol must be
22501 // invalidated because the symbol changed.
22502 priv_->id_ = get_environment().intern("");
22503}
22504
22505/// Gets the the underlying ELF symbol for the current variable,
22506/// that was set using function_decl::set_symbol(). Please read the
22507/// documentation for that member function for more information about
22508/// "underlying ELF symbols".
22509///
22510/// @return sym the underlying ELF symbol for this function decl, if
22511/// one exists.
22512const elf_symbol_sptr&
22514{return priv_->symbol_;}
22515
22516/// Test if the function was declared inline.
22517///
22518/// @return true iff the function was declared inline.
22519bool
22521{return priv_->declared_inline_;}
22522
22523/// Set the property of the function being declared inline.
22524///
22525/// @param value true iff the function was declared inline.
22526void
22528{priv_->declared_inline_ = value;}
22529
22531function_decl::get_binding() const
22532{return priv_->binding_;}
22533
22534/// @return the return type of the current instance of function_decl.
22535const shared_ptr<type_base>
22537{return get_type()->get_return_type();}
22538
22539/// @return the parameters of the function.
22540const std::vector<shared_ptr<function_decl::parameter> >&
22542{return get_type()->get_parameters();}
22543
22544/// Append a parameter to the type of this function.
22545///
22546/// @param parm the parameter to append.
22547void
22548function_decl::append_parameter(shared_ptr<parameter> parm)
22549{get_type()->append_parameter(parm);}
22550
22551/// Append a vector of parameters to the type of this function.
22552///
22553/// @param parms the vector of parameters to append.
22554void
22555function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
22556{
22557 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
22558 i != parms.end();
22559 ++i)
22560 get_type()->append_parameter(*i);
22561}
22562
22563/// Create a new instance of function_decl that is a clone of the
22564/// current one.
22565///
22566/// @return the new clone.
22569{
22571 if (is_member_function(*this))
22572 {
22573 method_decl_sptr
22574 m(new method_decl(get_name(),
22575 get_type(),
22577 get_location(),
22580 get_binding()));
22582 ABG_ASSERT(scope);
22586 get_member_is_static(*this),
22590 f = m;
22591 }
22592 else
22593 {
22594 f.reset(new function_decl(get_name(),
22595 get_type(),
22597 get_location(),
22600 get_binding()));
22602 }
22603 f->set_symbol(get_symbol());
22604
22605 return f;
22606}
22607
22608/// Compares two instances of @ref function_decl.
22609///
22610/// If the two intances are different, set a bitfield to give some
22611/// insight about the kind of differences there are.
22612///
22613/// @param l the first artifact of the comparison.
22614///
22615/// @param r the second artifact of the comparison.
22616///
22617/// @param k a pointer to a bitfield that gives information about the
22618/// kind of changes there are between @p l and @p r. This one is set
22619/// iff @p k is non-null and the function returns false.
22620///
22621/// Please note that setting k to a non-null value does have a
22622/// negative performance impact because even if @p l and @p r are not
22623/// equal, the function keeps up the comparison in order to determine
22624/// the different kinds of ways in which they are different.
22625///
22626/// @return true if @p l equals @p r, false otherwise.
22627bool
22629{
22630 bool result = true;
22631
22632 // Compare function types
22633 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
22634 if (t0 == t1 || *t0 == *t1)
22635 ; // the types are equal, let's move on to compare the other
22636 // properties of the functions.
22637 else
22638 {
22639 result = false;
22640 if (k)
22641 {
22642 if (!types_have_similar_structure(t0, t1))
22644 else
22645 *k |= SUBTYPE_CHANGE_KIND;
22646 }
22647 else
22649 }
22650
22651 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
22652 if (!!s0 != !!s1)
22653 {
22654 result = false;
22655 if (k)
22657 else
22659 }
22660 else if (s0 && s0 != s1)
22661 {
22662 if (!elf_symbols_alias(s0, s1))
22663 {
22664 result = false;
22665 if (k)
22667 else
22669 }
22670 }
22671 bool symbols_are_equal = (s0 && s1 && result);
22672
22673 if (symbols_are_equal)
22674 {
22675 // The functions have underlying elf symbols that are equal,
22676 // so now, let's compare the decl_base part of the functions
22677 // w/o considering their decl names.
22678 interned_string n1 = l.get_name(), n2 = r.get_name();
22680 const_cast<function_decl&>(l).set_name("");
22681 const_cast<function_decl&>(l).set_linkage_name("");
22682 const_cast<function_decl&>(r).set_name("");
22683 const_cast<function_decl&>(r).set_linkage_name("");
22684
22685 bool decl_bases_different = !l.decl_base::operator==(r);
22686
22687 const_cast<function_decl&>(l).set_name(n1);
22688 const_cast<function_decl&>(l).set_linkage_name(ln1);
22689 const_cast<function_decl&>(r).set_name(n2);
22690 const_cast<function_decl&>(r).set_linkage_name(ln2);
22691
22692 if (decl_bases_different)
22693 {
22694 result = false;
22695 if (k)
22697 else
22699 }
22700 }
22701 else
22702 if (!l.decl_base::operator==(r))
22703 {
22704 result = false;
22705 if (k)
22707 else
22709 }
22710
22711 // Compare the remaining properties. Note that we don't take into
22712 // account the fact that the function was declared inline or not as
22713 // that doesn't have any impact on the final ABI.
22714 if (l.get_binding() != r.get_binding())
22715 {
22716 result = false;
22717 if (k)
22719 else
22721 }
22722
22724 {
22725 result = false;
22726 if (k)
22728 else
22730 }
22731
22733 {
22746 {
22747 result = false;
22748 if (k)
22750 else
22752 }
22753 }
22754
22755 ABG_RETURN(result);
22756}
22757
22758/// Comparison operator for @ref function_decl.
22759///
22760/// @param other the other instance of @ref function_decl to compare
22761/// against.
22762///
22763/// @return true iff the current instance of @ref function_decl equals
22764/// @p other.
22765bool
22767{
22768 const function_decl* o = dynamic_cast<const function_decl*>(&other);
22769 if (!o)
22770 return false;
22771 return equals(*this, *o, 0);
22772}
22773
22774/// Return true iff the function takes a variable number of
22775/// parameters.
22776///
22777/// @return true if the function taks a variable number
22778/// of parameters.
22779bool
22781{
22782 return (!get_parameters().empty()
22783 && get_parameters().back()->get_variadic_marker());
22784}
22785
22786/// Return an ID that tries to uniquely identify the function inside a
22787/// program or a library.
22788///
22789/// So if the function has an underlying elf symbol, the ID is the
22790/// concatenation of the symbol name and its version. Otherwise, the
22791/// ID is the linkage name if its non-null. Otherwise, it's the
22792/// pretty representation of the function.
22793///
22794/// @return the ID.
22797{
22798 if (priv_->id_.empty())
22799 {
22800 const environment& env = get_type()->get_environment();
22801 if (elf_symbol_sptr s = get_symbol())
22802 {
22803 string virtual_member_suffix;
22804 if (is_member_function(this))
22805 {
22806 method_decl* m = is_method_decl(this);
22807 ABG_ASSERT(m);
22809 {
22811 (m->get_type()->get_class_type(),
22812 /*look_through_decl_only=*/true))
22813 virtual_member_suffix += "/o";
22814 }
22815 }
22816 if (s->has_aliases())
22817 // The symbol has several aliases, so let's use a scheme
22818 // that allows all aliased functions to have different
22819 // IDs.
22820 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
22821 else
22822 // Let's use the full symbol name with its version as ID.
22823 priv_->id_ = env.intern(s->get_id_string());
22824
22825 if (!virtual_member_suffix.empty())
22826 priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
22827 }
22828 else if (!get_linkage_name().empty())
22829 priv_->id_= env.intern(get_linkage_name());
22830 else
22831 priv_->id_ = env.intern(get_pretty_representation());
22832 }
22833 return priv_->id_;
22834}
22835
22836/// Test if two function declarations are aliases.
22837///
22838/// Two functions declarations are aliases if their symbols are
22839/// aliases, in the ELF sense.
22840///
22841/// @param f1 the first function to consider.
22842///
22843/// @param f2 the second function to consider.
22844///
22845/// @return true iff @p f1 is an alias of @p f2
22846bool
22848{
22849 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
22850
22851 if (!s1 || !s2)
22852 return false;
22853
22854 return elf_symbols_alias(s1, s2);
22855}
22856
22857/// This implements the ir_traversable_base::traverse pure virtual
22858/// function.
22859///
22860/// @param v the visitor used on the current instance.
22861///
22862/// @return true if the entire IR node tree got traversed, false
22863/// otherwise.
22864bool
22866{
22867 if (visiting())
22868 return true;
22869
22870 if (v.visit_begin(this))
22871 {
22872 visiting(true);
22873 if (type_base_sptr t = get_type())
22874 t->traverse(v);
22875 visiting(false);
22876 }
22877 return v.visit_end(this);
22878}
22879
22880/// Destructor of the @ref function_decl type.
22882{delete priv_;}
22883
22884/// A deep comparison operator for a shared pointer to @ref function_decl
22885///
22886/// This function compares to shared pointers to @ref function_decl by
22887/// looking at the pointed-to instances of @ref function_dec
22888/// comparing them too. If the two pointed-to objects are equal then
22889/// this function returns true.
22890///
22891/// @param l the left-hand side argument of the equality operator.
22892///
22893/// @param r the right-hand side argument of the equality operator.
22894///
22895/// @return true iff @p l equals @p r.
22896bool
22898{
22899 if (l.get() == r.get())
22900 return true;
22901 if (!!l != !!r)
22902 return false;
22903
22904 return *l == *r;
22905}
22906
22907/// A deep inequality operator for smart pointers to functions.
22908///
22909/// @param l the left-hand side argument of the inequality operator.
22910///
22911/// @pram r the right-hand side argument of the inequality operator.
22912///
22913/// @return true iff @p is not equal to @p r.
22914bool
22916{return !operator==(l, r);}
22917
22918// <function_decl definitions>
22919
22920// <function_decl::parameter definitions>
22921
22922struct function_decl::parameter::priv
22923{
22924 type_base_wptr type_;
22925 unsigned index_;
22926 bool variadic_marker_;
22927
22928 priv()
22929 : index_(),
22930 variadic_marker_()
22931 {}
22932
22933 priv(type_base_sptr type,
22934 unsigned index,
22935 bool variadic_marker)
22936 : type_(type),
22937 index_(index),
22938 variadic_marker_(variadic_marker)
22939 {}
22940};// end struct function_decl::parameter::priv
22941
22942function_decl::parameter::parameter(const type_base_sptr type,
22943 unsigned index,
22944 const string& name,
22945 const location& loc,
22946 bool is_variadic)
22947 : type_or_decl_base(type->get_environment(),
22948 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22949 decl_base(type->get_environment(), name, loc),
22950 priv_(new priv(type, index, is_variadic))
22951{
22952 runtime_type_instance(this);
22953}
22954
22955function_decl::parameter::parameter(const type_base_sptr type,
22956 unsigned index,
22957 const string& name,
22958 const location& loc,
22959 bool is_variadic,
22960 bool is_artificial)
22961 : type_or_decl_base(type->get_environment(),
22962 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22963 decl_base(type->get_environment(), name, loc),
22964 priv_(new priv(type, index, is_variadic))
22965{
22966 runtime_type_instance(this);
22967 set_is_artificial(is_artificial);
22968}
22969
22970function_decl::parameter::parameter(const type_base_sptr type,
22971 const string& name,
22972 const location& loc,
22973 bool is_variadic,
22974 bool is_artificial)
22975 : type_or_decl_base(type->get_environment(),
22976 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22977 decl_base(type->get_environment(), name, loc),
22978 priv_(new priv(type, 0, is_variadic))
22979{
22980 runtime_type_instance(this);
22981 set_is_artificial(is_artificial);
22982}
22983
22984function_decl::parameter::parameter(const type_base_sptr type,
22985 unsigned index,
22986 bool variad)
22987 : type_or_decl_base(type->get_environment(),
22988 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22989 decl_base(type->get_environment(), "", location()),
22990 priv_(new priv(type, index, variad))
22991{
22992 runtime_type_instance(this);
22993}
22994
22995function_decl::parameter::~parameter() = default;
22996
22997const type_base_sptr
22998function_decl::parameter::get_type()const
22999{return priv_->type_.lock();}
23000
23001/// @return a copy of the type name of the parameter.
23002interned_string
23004{
23005 const environment& env = get_environment();
23006
23007 type_base_sptr t = get_type();
23008 string str;
23009 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
23010 str = "...";
23011 else
23012 {
23013 ABG_ASSERT(t);
23015 }
23016 return env.intern(str);
23017}
23018
23019/// @return a copy of the pretty representation of the type of the
23020/// parameter.
23021const string
23023{
23024 type_base_sptr t = get_type();
23025 string str;
23026 if (get_variadic_marker()
23027 || get_environment().is_variadic_parameter_type(t))
23028 str = "...";
23029 else
23030 {
23031 ABG_ASSERT(t);
23033 }
23034 return str;
23035}
23036
23037/// Get a name uniquely identifying the parameter in the function.
23038///
23039///@return the unique parm name id.
23042{
23043 const environment& env = get_environment();
23044
23045
23046 std::ostringstream o;
23047 o << "parameter-" << get_index();
23048
23049 return env.intern(o.str());
23050}
23051
23052unsigned
23053function_decl::parameter::get_index() const
23054{return priv_->index_;}
23055
23056void
23057function_decl::parameter::set_index(unsigned i)
23058{priv_->index_ = i;}
23059
23060
23061bool
23062function_decl::parameter::get_variadic_marker() const
23063{return priv_->variadic_marker_;}
23064
23065/// Compares two instances of @ref function_decl::parameter.
23066///
23067/// If the two intances are different, set a bitfield to give some
23068/// insight about the kind of differences there are.
23069///
23070/// @param l the first artifact of the comparison.
23071///
23072/// @param r the second artifact of the comparison.
23073///
23074/// @param k a pointer to a bitfield that gives information about the
23075/// kind of changes there are between @p l and @p r. This one is set
23076/// iff @p k is non-null and the function returns false.
23077///
23078/// Please note that setting k to a non-null value does have a
23079/// negative performance impact because even if @p l and @p r are not
23080/// equal, the function keeps up the comparison in order to determine
23081/// the different kinds of ways in which they are different.
23082///
23083/// @return true if @p l equals @p r, false otherwise.
23084bool
23086 const function_decl::parameter& r,
23087 change_kind* k)
23088{
23089 bool result = true;
23090
23091 if ((l.get_variadic_marker() != r.get_variadic_marker())
23092 || (l.get_index() != r.get_index())
23093 || (!!l.get_type() != !!r.get_type()))
23094 {
23095 result = false;
23096 if (k)
23097 {
23098 if (l.get_index() != r.get_index())
23100 if (l.get_variadic_marker() != r.get_variadic_marker()
23101 || !!l.get_type() != !!r.get_type())
23103 }
23104 else
23106 }
23107
23108 type_base_sptr l_type = l.get_type();
23109 type_base_sptr r_type = r.get_type();
23110
23111 if (l_type != r_type)
23112 {
23113 result = false;
23114 if (k)
23115 {
23116 if (!types_have_similar_structure(l_type, r_type))
23118 else
23119 *k |= SUBTYPE_CHANGE_KIND;
23120 }
23121 else
23123 }
23124
23125 ABG_RETURN(result);
23126}
23127
23128bool
23129function_decl::parameter::operator==(const parameter& o) const
23130{return equals(*this, o, 0);}
23131
23132bool
23133function_decl::parameter::operator==(const decl_base& o) const
23134{
23135 const function_decl::parameter* p =
23136 dynamic_cast<const function_decl::parameter*>(&o);
23137 if (!p)
23138 return false;
23139 return function_decl::parameter::operator==(*p);
23140}
23141
23142/// Non-member equality operator for @ref function_decl::parameter.
23143///
23144/// @param l the left-hand side of the equality operator
23145///
23146/// @param r the right-hand side of the equality operator
23147///
23148/// @return true iff @p l and @p r equals.
23149bool
23152{
23153 if (!!l != !!r)
23154 return false;
23155 if (!l)
23156 return true;
23157 return *l == *r;
23158}
23159
23160/// Non-member inequality operator for @ref function_decl::parameter.
23161///
23162/// @param l the left-hand side of the equality operator
23163///
23164/// @param r the right-hand side of the equality operator
23165///
23166/// @return true iff @p l and @p r different.
23167bool
23170{return !operator==(l, r);}
23171
23172/// Traverse the diff sub-tree under the current instance
23173/// function_decl.
23174///
23175/// @param v the visitor to invoke on each diff node of the sub-tree.
23176///
23177/// @return true if the traversing has to keep going on, false
23178/// otherwise.
23179bool
23181{
23182 if (visiting())
23183 return true;
23184
23185 if (v.visit_begin(this))
23186 {
23187 visiting(true);
23188 if (type_base_sptr t = get_type())
23189 t->traverse(v);
23190 visiting(false);
23191 }
23192 return v.visit_end(this);
23193}
23194
23195/// Compute the qualified name of the parameter.
23196///
23197/// @param internal set to true if the call is intended for an
23198/// internal use (for technical use inside the library itself), false
23199/// otherwise. If you don't know what this is for, then set it to
23200/// false.
23201///
23202/// @param qn the resulting qualified name.
23203void
23205 bool /*internal*/) const
23206{qualified_name = get_name();}
23207
23208/// Compute and return a copy of the pretty representation of the
23209/// current function parameter.
23210///
23211/// @param internal set to true if the call is intended to get a
23212/// representation of the decl (or type) for the purpose of canonical
23213/// type comparison. This is mainly used in the function
23214/// type_base::get_canonical_type_for().
23215///
23216/// In other words if the argument for this parameter is true then the
23217/// call is meant for internal use (for technical use inside the
23218/// library itself), false otherwise. If you don't know what this is
23219/// for, then set it to false.
23220///
23221/// @return a copy of the textual representation of the current
23222/// function parameter.
23223string
23225 bool qualified_name) const
23226{
23227 const environment& env = get_environment();
23228
23229 string type_repr;
23230 type_base_sptr t = get_type();
23231 if (!t)
23232 type_repr = "void";
23233 else if (env.is_variadic_parameter_type(t))
23234 type_repr = "...";
23235 else
23236 type_repr = ir::get_type_name(t, qualified_name, internal);
23237
23238 string result = type_repr;
23239 string parm_name = get_name_id();
23240
23241 if (!parm_name.empty())
23242 result += " " + parm_name;
23243
23244 return result;
23245}
23246
23247// </function_decl::parameter definitions>
23248
23249// <class_or_union definitions>
23250
23251/// A Constructor for instances of @ref class_or_union
23252///
23253/// @param env the environment we are operating from.
23254///
23255/// @param name the identifier of the class.
23256///
23257/// @param size_in_bits the size of an instance of @ref
23258/// class_or_union, expressed in bits
23259///
23260/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23261/// expressed in bits.
23262///
23263/// @param locus the source location of declaration point this class.
23264///
23265/// @param vis the visibility of instances of @ref class_or_union.
23266///
23267/// @param mem_types the vector of member types of this instance of
23268/// @ref class_or_union.
23269///
23270/// @param data_members the vector of data members of this instance of
23271/// @ref class_or_union.
23272///
23273/// @param member_fns the vector of member functions of this instance
23274/// of @ref class_or_union.
23275class_or_union::class_or_union(const environment& env, const string& name,
23276 size_t size_in_bits, size_t align_in_bits,
23277 const location& locus, visibility vis,
23278 member_types& mem_types,
23280 member_functions& member_fns)
23281 : type_or_decl_base(env,
23282 ABSTRACT_TYPE_BASE
23283 | ABSTRACT_DECL_BASE
23284 | ABSTRACT_SCOPE_TYPE_DECL
23285 | ABSTRACT_SCOPE_DECL),
23286 decl_base(env, name, locus, name, vis),
23287 type_base(env, size_in_bits, align_in_bits),
23288 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23289 priv_(new priv(data_members, member_fns))
23290{
23291 for (member_types::iterator i = mem_types.begin();
23292 i != mem_types.end();
23293 ++i)
23296
23297 for (data_members::iterator i = data_members.begin();
23298 i != data_members.end();
23299 ++i)
23300 if (!has_scope(*i))
23301 add_decl_to_scope(*i, this);
23302
23303 for (member_functions::iterator i = member_fns.begin();
23304 i != member_fns.end();
23305 ++i)
23306 if (!has_scope(static_pointer_cast<decl_base>(*i)))
23307 add_decl_to_scope(*i, this);
23308}
23309
23310/// A constructor for instances of @ref class_or_union.
23311///
23312/// @param env the environment we are operating from.
23313///
23314/// @param name the name of the class.
23315///
23316/// @param size_in_bits the size of an instance of @ref
23317/// class_or_union, expressed in bits
23318///
23319/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23320/// expressed in bits.
23321///
23322/// @param locus the source location of declaration point this class.
23323///
23324/// @param vis the visibility of instances of @ref class_or_union.
23325class_or_union::class_or_union(const environment& env, const string& name,
23326 size_t size_in_bits, size_t align_in_bits,
23327 const location& locus, visibility vis)
23328 : type_or_decl_base(env,
23329 ABSTRACT_TYPE_BASE
23330 | ABSTRACT_DECL_BASE
23331 | ABSTRACT_SCOPE_TYPE_DECL
23332 | ABSTRACT_SCOPE_DECL),
23333 decl_base(env, name, locus, name, vis),
23334 type_base(env, size_in_bits, align_in_bits),
23335 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23336 priv_(new priv)
23337{}
23338
23339/// Constructor of the @ref class_or_union type.
23340///
23341/// @param env the @ref environment we are operating from.
23342///
23343/// @param name the name of the @ref class_or_union.
23344///
23345/// @param is_declaration_only a boolean saying whether the instance
23346/// represents a declaration only, or not.
23347class_or_union::class_or_union(const environment& env, const string& name,
23348 bool is_declaration_only)
23349 : type_or_decl_base(env,
23350 ABSTRACT_TYPE_BASE
23351 | ABSTRACT_DECL_BASE
23352 | ABSTRACT_SCOPE_TYPE_DECL
23353 | ABSTRACT_SCOPE_DECL),
23354 decl_base(env, name, location(), name),
23355 type_base(env, 0, 0),
23356 scope_type_decl(env, name, 0, 0, location()),
23357 priv_(new priv)
23358{
23359 set_is_declaration_only(is_declaration_only);
23360}
23361
23362/// Return the hash value of the current IR node.
23363///
23364/// Note that upon the first invocation, this member functions
23365/// computes the hash value and returns it. Subsequent invocations
23366/// just return the hash value that was previously calculated.
23367///
23368/// @return the hash value of the current IR node.
23369hash_t
23371{
23372 class_or_union::hash do_hash;
23373 hash_t h = do_hash(this);
23374 return h;
23375}
23376
23377/// This implements the ir_traversable_base::traverse pure virtual
23378/// function.
23379///
23380/// @param v the visitor used on the member nodes of the translation
23381/// unit during the traversal.
23382///
23383/// @return true if the entire IR node tree got traversed, false
23384/// otherwise.
23385bool
23387{
23388 if (v.type_node_has_been_visited(this))
23389 return true;
23390
23391 if (visiting())
23392 return true;
23393
23394 if (v.visit_begin(this))
23395 {
23396 visiting(true);
23397 bool stop = false;
23398
23399 if (!stop)
23400 for (data_members::const_iterator i = get_data_members().begin();
23401 i != get_data_members().end();
23402 ++i)
23403 if (!(*i)->traverse(v))
23404 {
23405 stop = true;
23406 break;
23407 }
23408
23409 if (!stop)
23410 for (member_functions::const_iterator i= get_member_functions().begin();
23411 i != get_member_functions().end();
23412 ++i)
23413 if (!(*i)->traverse(v))
23414 {
23415 stop = true;
23416 break;
23417 }
23418
23419 if (!stop)
23420 for (member_types::const_iterator i = get_member_types().begin();
23421 i != get_member_types().end();
23422 ++i)
23423 if (!(*i)->traverse(v))
23424 {
23425 stop = true;
23426 break;
23427 }
23428
23429 if (!stop)
23430 for (member_function_templates::const_iterator i =
23432 i != get_member_function_templates().end();
23433 ++i)
23434 if (!(*i)->traverse(v))
23435 {
23436 stop = true;
23437 break;
23438 }
23439
23440 if (!stop)
23441 for (member_class_templates::const_iterator i =
23443 i != get_member_class_templates().end();
23444 ++i)
23445 if (!(*i)->traverse(v))
23446 {
23447 stop = true;
23448 break;
23449 }
23450 visiting(false);
23451 }
23452
23453 bool result = v.visit_end(this);
23455 return result;
23456}
23457
23458/// Destrcutor of the @ref class_or_union type.
23460{delete priv_;}
23461
23462/// Add a member declaration to the current instance of class_or_union.
23463/// The member declaration can be either a member type, data member,
23464/// member function, or member template.
23465///
23466/// @param d the member declaration to add.
23467decl_base_sptr
23468class_or_union::add_member_decl(const decl_base_sptr& d)
23469{return insert_member_decl(d);}
23470
23471/// Remove a given decl from the current @ref class_or_union scope.
23472///
23473/// Note that only type declarations are supported by this method for
23474/// now. Support for the other kinds of declaration is left as an
23475/// exercise for the interested reader of the code.
23476///
23477/// @param decl the declaration to remove from this @ref
23478/// class_or_union scope.
23479void
23481{
23482 type_base_sptr t = is_type(decl);
23483
23484 // For now we want to support just removing types from classes. For
23485 // other kinds of IR node, we need more work.
23486 ABG_ASSERT(t);
23487
23489}
23490
23491/// Fixup the members of the type of an anonymous data member.
23492///
23493/// Walk all data members of (the type of) a given anonymous data
23494/// member and set a particular property of the relationship between
23495/// each data member and its containing type.
23496///
23497/// That property records the fact that the data member belongs to the
23498/// anonymous data member we consider.
23499///
23500/// In the future, if there are other properties of this relationship
23501/// to set in this manner, they ought to be added here.
23502///
23503/// @param anon_dm the anonymous data member to consider.
23504void
23506{
23507 class_or_union * anon_dm_type =
23509 if (!anon_dm_type)
23510 return;
23511
23512 for (class_or_union::data_members::const_iterator it =
23513 anon_dm_type->get_non_static_data_members().begin();
23514 it != anon_dm_type->get_non_static_data_members().end();
23515 ++it)
23516 {
23517 dm_context_rel *rel =
23518 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
23519 ABG_ASSERT(rel);
23520 rel->set_anonymous_data_member(anon_dm.get());
23521 }
23522}
23523
23524/// Getter of the alignment of the @ref class_or_union type.
23525///
23526/// If this @ref class_or_union is a declaration of a definition that
23527/// is elsewhere, then the size of the definition is returned.
23528///
23529/// @return the alignment of the @ref class_or_union type.
23530size_t
23532{
23536
23538}
23539
23540/// Setter of the alignment of the class type.
23541///
23542/// If this class is a declaration of a definition that is elsewhere,
23543/// then the new alignment is set to the definition.
23544///
23545/// @param s the new alignment.
23546void
23548{
23552 else
23554}
23555
23556/// Setter of the size of the @ref class_or_union type.
23557///
23558/// If this @ref class_or_union is a declaration of a definition that
23559/// is elsewhere, then the new size is set to the definition.
23560///
23561/// @param s the new size.
23562void
23564{
23568 else
23570}
23571
23572/// Getter of the size of the @ref class_or_union type.
23573///
23574/// If this @ref class_or_union is a declaration of a definition that
23575/// is elsewhere, then the size of the definition is returned.
23576///
23577/// @return the size of the @ref class_or_union type.
23578size_t
23580{
23584
23586}
23587
23588/// Get the number of anonymous member classes contained in this
23589/// class.
23590///
23591/// @return the number of anonymous member classes contained in this
23592/// class.
23593size_t
23595{
23596 int result = 0;
23597 for (member_types::const_iterator it = get_member_types().begin();
23598 it != get_member_types().end();
23599 ++it)
23600 if (class_decl_sptr t = is_class_type(*it))
23601 if (t->get_is_anonymous())
23602 ++result;
23603
23604 return result;
23605}
23606
23607/// Get the number of anonymous member unions contained in this class.
23608///
23609/// @return the number of anonymous member unions contained in this
23610/// class.
23611size_t
23613{
23614 int result = 0;
23615 for (member_types::const_iterator it = get_member_types().begin();
23616 it != get_member_types().end();
23617 ++it)
23618 if (union_decl_sptr t = is_union_type(*it))
23619 if (t->get_is_anonymous())
23620 ++result;
23621
23622 return result;
23623}
23624
23625/// Get the number of anonymous member enums contained in this class.
23626///
23627/// @return the number of anonymous member enums contained in this
23628/// class.
23629size_t
23631{
23632 int result = 0;
23633 for (member_types::const_iterator it = get_member_types().begin();
23634 it != get_member_types().end();
23635 ++it)
23636 if (enum_type_decl_sptr t = is_enum_type(*it))
23637 if (t->get_is_anonymous())
23638 ++result;
23639
23640 return result;
23641}
23642
23643/// Add a data member to the current instance of class_or_union.
23644///
23645/// @param v a var_decl to add as a data member. A proper
23646/// class_or_union::data_member is created from @p v and added to the
23647/// class_or_union. This var_decl should not have been already added
23648/// to a scope.
23649///
23650/// @param access the access specifier for the data member.
23651///
23652/// @param is_laid_out whether the data member was laid out. That is,
23653/// if its offset has been computed. In the pattern of a class
23654/// template for instance, this would be set to false.
23655///
23656/// @param is_static whether the data memer is static.
23657///
23658/// @param offset_in_bits if @p is_laid_out is true, this is the
23659/// offset of the data member, expressed (oh, surprise) in bits.
23660void
23662 bool is_laid_out, bool is_static,
23663 size_t offset_in_bits)
23664{
23665 ABG_ASSERT(!has_scope(v));
23666
23667 priv_->data_members_.push_back(v);
23669 set_data_member_is_laid_out(v, is_laid_out);
23670 set_data_member_offset(v, offset_in_bits);
23671 set_member_access_specifier(v, access);
23672 set_member_is_static(v, is_static);
23673
23674 // Add the variable to the set of static or non-static data members,
23675 // if it's not already in there.
23676 bool is_already_in = false;
23677 if (is_static)
23678 {
23679 for (const auto& s_dm: priv_->static_data_members_)
23680 {
23681 if (s_dm == v)
23682 {
23683 is_already_in = true;
23684 break;
23685 }
23686 }
23687 if (!is_already_in)
23688 priv_->static_data_members_.push_back(v);
23689 }
23690 else
23691 {
23692 // If this is a non-static variable, add it to the set of
23693 // non-static variables, if it's not already in there.
23694 for (data_members::const_iterator i =
23695 priv_->non_static_data_members_.begin();
23696 i != priv_->non_static_data_members_.end();
23697 ++i)
23698 if (*i == v)
23699 {
23700 is_already_in = true;
23701 break;
23702 }
23703 if (!is_already_in)
23704 priv_->non_static_data_members_.push_back(v);
23705 }
23706
23707 // If v is an anonymous data member, then fixup its data members.
23708 // For now, the only thing the fixup does is to make the data
23709 // members of the anonymous data member be aware of their containing
23710 // anonymous data member. That is helpful to compute the absolute
23711 // bit offset of each of the members of the anonymous data member.
23713}
23714
23715/// Get the data members of this @ref class_or_union.
23716///
23717/// @return a vector of the data members of this @ref class_or_union.
23720{return priv_->data_members_;}
23721
23722/// Find a data member of a given name in the current @ref class_or_union.
23723///
23724/// @param name the name of the data member to find in the current
23725/// @ref class_or_union.
23726///
23727/// @return a pointer to the @ref var_decl that represents the data
23728/// member to find inside the current @ref class_or_union.
23729const var_decl_sptr
23730class_or_union::find_data_member(const string& name) const
23731{
23732 for (data_members::const_iterator i = get_data_members().begin();
23733 i != get_data_members().end();
23734 ++i)
23735 if ((*i)->get_name() == name)
23736 return *i;
23737
23738 // We haven't found a data member with the name 'name'. Let's look
23739 // closer again, this time in our anonymous data members.
23740 for (data_members::const_iterator i = get_data_members().begin();
23741 i != get_data_members().end();
23742 ++i)
23744 {
23745 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
23746 ABG_ASSERT(type);
23747 if (var_decl_sptr data_member = type->find_data_member(name))
23748 return data_member;
23749 }
23750
23751 return var_decl_sptr();
23752}
23753
23754/// Find an anonymous data member in the class.
23755///
23756/// @param v the anonymous data member to find.
23757///
23758/// @return the anonymous data member found, or nil if none was found.
23759const var_decl_sptr
23761{
23762 if (!v->get_name().empty())
23763 return var_decl_sptr();
23764
23765 for (data_members::const_iterator it = get_non_static_data_members().begin();
23766 it != get_non_static_data_members().end();
23767 ++it)
23768 {
23769 if (is_anonymous_data_member(*it))
23770 if ((*it)->get_pretty_representation(/*internal=*/false, true)
23771 == v->get_pretty_representation(/*internal=*/false, true))
23772 return *it;
23773 }
23774
23775 return var_decl_sptr();
23776}
23777
23778/// Find a given data member.
23779///
23780/// This function takes a @ref var_decl as an argument. If it has a
23781/// non-empty name, then it tries to find a data member which has the
23782/// same name as the argument.
23783///
23784/// If it has an empty name, then the @ref var_decl is considered as
23785/// an anonymous data member. In that case, this function tries to
23786/// find an anonymous data member which type equals that of the @ref
23787/// var_decl argument.
23788///
23789/// @param v this carries either the name of the data member we need
23790/// to look for, or the type of the anonymous data member we are
23791/// looking for.
23792const var_decl_sptr
23794{
23795 if (!v)
23796 return var_decl_sptr();
23797
23798 if (v->get_name().empty())
23800
23801 return find_data_member(v->get_name());
23802}
23803
23804
23805/// Get the non-static data members of this @ref class_or_union.
23806///
23807/// @return a vector of the non-static data members of this @ref
23808/// class_or_union.
23811{return priv_->non_static_data_members_;}
23812
23813/// Get the static data memebers of this @ref class_or_union.
23814///
23815/// @return a vector of the static data members of this @ref
23816/// class_or_union.
23819{return priv_->static_data_members_;}
23820
23821/// Add a member function.
23822///
23823/// @param f the new member function to add.
23824///
23825/// @param a the access specifier to use for the new member function.
23826///
23827/// @param is_static whether the new member function is static.
23828///
23829/// @param is_ctor whether the new member function is a constructor.
23830///
23831/// @param is_dtor whether the new member function is a destructor.
23832///
23833/// @param is_const whether the new member function is const.
23834void
23837 bool is_static, bool is_ctor,
23838 bool is_dtor, bool is_const)
23839{
23840 ABG_ASSERT(!has_scope(f));
23841
23843
23844 set_member_function_is_ctor(f, is_ctor);
23845 set_member_function_is_dtor(f, is_dtor);
23847 set_member_is_static(f, is_static);
23848 set_member_function_is_const(f, is_const);
23849
23850 priv_->member_functions_.push_back(f);
23851
23852 // Update the map of linkage name -> member functions. It's useful,
23853 // so that class_or_union::find_member_function() can function.
23854 if (!f->get_linkage_name().empty())
23855 priv_->mem_fns_map_[f->get_linkage_name()] = f;
23856}
23857
23858/// Get the member functions of this @ref class_or_union.
23859///
23860/// @return a vector of the member functions of this @ref
23861/// class_or_union.
23864{return priv_->member_functions_;}
23865
23866/// Find a method, using its linkage name as a key.
23867///
23868/// @param linkage_name the linkage name of the method to find.
23869///
23870/// @return the method found, or nil if none was found.
23871const method_decl*
23872class_or_union::find_member_function(const string& linkage_name) const
23873{
23874 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
23875}
23876
23877/// Find a method, using its linkage name as a key.
23878///
23879/// @param linkage_name the linkage name of the method to find.
23880///
23881/// @return the method found, or nil if none was found.
23883class_or_union::find_member_function(const string& linkage_name)
23884{
23885 string_mem_fn_sptr_map_type::const_iterator i =
23886 priv_->mem_fns_map_.find(linkage_name);
23887 if (i == priv_->mem_fns_map_.end())
23888 return 0;
23889 return i->second.get();
23890}
23891
23892/// Find a method, using its linkage name as a key.
23893///
23894/// @param linkage_name the linkage name of the method to find.
23895///
23896/// @return the method found, or nil if none was found.
23897method_decl_sptr
23899{
23900 string_mem_fn_sptr_map_type::const_iterator i =
23901 priv_->mem_fns_map_.find(linkage_name);
23902 if (i == priv_->mem_fns_map_.end())
23903 return 0;
23904 return i->second;
23905}
23906
23907/// Find a method (member function) using its signature (pretty
23908/// representation) as a key.
23909///
23910/// @param s the signature of the method.
23911///
23912/// @return the method found, or nil if none was found.
23913const method_decl*
23915{
23916 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
23917}
23918
23919/// Find a method (member function) using its signature (pretty
23920/// representation) as a key.
23921///
23922/// @param s the signature of the method.
23923///
23924/// @return the method found, or nil if none was found.
23927{
23928 string_mem_fn_ptr_map_type::const_iterator i =
23929 priv_->signature_2_mem_fn_map_.find(s);
23930 if (i == priv_->signature_2_mem_fn_map_.end())
23931 return 0;
23932 return i->second;
23933}
23934
23935/// Get the member function templates of this class.
23936///
23937/// @return a vector of the member function templates of this class.
23938const member_function_templates&
23940{return priv_->member_function_templates_;}
23941
23942/// Get the member class templates of this class.
23943///
23944/// @return a vector of the member class templates of this class.
23945const member_class_templates&
23947{return priv_->member_class_templates_;}
23948
23949/// Append a member function template to the @ref class_or_union.
23950///
23951/// @param m the member function template to append.
23952void
23953class_or_union::add_member_function_template(member_function_template_sptr m)
23954{
23955 decl_base* c = m->as_function_tdecl()->get_scope();
23956 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
23957 /// error message or something like a structured error.
23958 priv_->member_function_templates_.push_back(m);
23959 if (!c)
23960 scope_decl::add_member_decl(m->as_function_tdecl());
23961}
23962
23963/// Append a member class template to the @ref class_or_union.
23964///
23965/// @param m the member function template to append.
23966void
23968{
23969 decl_base* c = m->as_class_tdecl()->get_scope();
23970 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
23971 /// error message or something like a structured error.
23972 m->set_scope(this);
23973 priv_->member_class_templates_.push_back(m);
23974 if (!c)
23975 scope_decl::add_member_decl(m->as_class_tdecl());
23976}
23977
23978///@return true iff the current instance has no member.
23979bool
23981{
23982 return (get_member_types().empty()
23983 && priv_->data_members_.empty()
23984 && priv_->member_functions_.empty()
23985 && priv_->member_function_templates_.empty()
23986 && priv_->member_class_templates_.empty());
23987}
23988
23989/// Insert a data member to this @ref class_or_union type.
23990///
23991/// @param d the data member to insert.
23992///
23993/// @return the decl @p that got inserted.
23994decl_base_sptr
23996{
23997 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
23998 {
23999 add_data_member(v, public_access,
24000 /*is_laid_out=*/false,
24001 /*is_static=*/true,
24002 /*offset_in_bits=*/0);
24003 d = v;
24004 }
24005 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24006 add_member_function(f, public_access,
24007 /*is_static=*/false,
24008 /*is_ctor=*/false,
24009 /*is_dtor=*/false,
24010 /*is_const=*/false);
24011 else if (member_function_template_sptr f =
24012 dynamic_pointer_cast<member_function_template>(d))
24014 else if (member_class_template_sptr c =
24015 dynamic_pointer_cast<member_class_template>(d))
24017 else
24019
24020 return d;
24021}
24022
24023/// Equality operator.
24024///
24025/// @param other the other @ref class_or_union to compare against.
24026///
24027/// @return true iff @p other equals the current @ref class_or_union.
24028bool
24030{
24031 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
24032 if (!op)
24033 return false;
24034
24035 // If this is a decl-only type (and thus with no canonical type),
24036 // use the canonical type of the definition, if any.
24037 const class_or_union *l = 0;
24039 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
24040 if (l == 0)
24041 l = this;
24042
24043 // Likewise for the other class.
24044 const class_or_union *r = 0;
24045 if (op->get_is_declaration_only())
24046 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
24047 if (r == 0)
24048 r = op;
24049
24050 return try_canonical_compare(l, r);
24051}
24052
24053/// Equality operator.
24054///
24055/// @param other the other @ref class_or_union to compare against.
24056///
24057/// @return true iff @p other equals the current @ref class_or_union.
24058bool
24060{
24061 const decl_base* o = dynamic_cast<const decl_base*>(&other);
24062 if (!o)
24063 return false;
24064 return *this == *o;
24065}
24066
24067/// Equality operator.
24068///
24069/// @param other the other @ref class_or_union to compare against.
24070///
24071/// @return true iff @p other equals the current @ref class_or_union.
24072bool
24074{
24075 const decl_base& o = other;
24077}
24078
24079/// Compares two instances of @ref class_or_union.
24080///
24081/// If the two intances are different, set a bitfield to give some
24082/// insight about the kind of differences there are.
24083///
24084/// @param l the first artifact of the comparison.
24085///
24086/// @param r the second artifact of the comparison.
24087///
24088/// @param k a pointer to a bitfield that gives information about the
24089/// kind of changes there are between @p l and @p r. This one is set
24090/// iff it's non-null and if the function returns false.
24091///
24092/// Please note that setting k to a non-null value does have a
24093/// negative performance impact because even if @p l and @p r are not
24094/// equal, the function keeps up the comparison in order to determine
24095/// the different kinds of ways in which they are different.
24096///
24097/// @return true if @p l equals @p r, false otherwise.
24098bool
24100{
24101 // if one of the classes is declaration-only, look through it to
24102 // get its definition.
24103 bool l_is_decl_only = l.get_is_declaration_only();
24104 bool r_is_decl_only = r.get_is_declaration_only();
24105 if (l_is_decl_only || r_is_decl_only)
24106 {
24107 const class_or_union* def1 = l_is_decl_only
24109 : &l;
24110
24111 const class_or_union* def2 = r_is_decl_only
24113 : &r;
24114
24115 if (!def1 || !def2)
24116 {
24117 if (!l.get_is_anonymous()
24118 && !r.get_is_anonymous()
24119 && l_is_decl_only && r_is_decl_only
24121 // The two decl-only classes differ from their size. A
24122 // true decl-only class should not have a size property to
24123 // begin with. This comes from a DWARF oddity and can
24124 // results in a false positive, so let's not consider that
24125 // change.
24126 return true;
24127
24131 {
24132 const interned_string& q1 = l.get_scoped_name();
24133 const interned_string& q2 = r.get_scoped_name();
24134 if (q1 == q2)
24135 // Not using RETURN(true) here, because that causes
24136 // performance issues. We don't need to do
24137 // l.priv_->unmark_as_being_compared({l,r}) here because
24138 // we haven't marked l or r as being compared yet, and
24139 // doing so has a peformance cost that shows up on
24140 // performance profiles for *big* libraries.
24141 return true;
24142 else
24143 {
24144 if (k)
24146 // Not using RETURN(true) here, because that causes
24147 // performance issues. We don't need to do
24148 // l.priv_->unmark_as_being_compared({l,r}) here because
24149 // we haven't marked l or r as being compared yet, and
24150 // doing so has a peformance cost that shows up on
24151 // performance profiles for *big* libraries.
24153 }
24154 }
24155 else // A decl-only class is considered different from a
24156 // class definition of the same name.
24157 {
24158 if (!!def1 != !!def2)
24159 {
24160 if (k)
24163 }
24164
24165 // both definitions are empty
24166 if (!(l.decl_base::operator==(r)
24167 && l.type_base::operator==(r)))
24168 {
24169 if (k)
24172 }
24173
24174 return true;
24175 }
24176 }
24177
24178 bool val = *def1 == *def2;
24179 if (!val)
24180 if (k)
24182 ABG_RETURN(val);
24183 }
24184
24185 // No need to go further if the classes have different names or
24186 // different size / alignment.
24187 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
24188 {
24189 if (k)
24192 }
24193
24194 if (types_defined_same_linux_kernel_corpus_public(l, r))
24195 return true;
24196
24197 //TODO: Maybe remove this (cycle detection and canonical type
24198 //propagation handling) from here and have it only in the equal
24199 //overload for class_decl and union_decl because this one ( the
24200 //equal overload for class_or_union) is just a sub-routine of these
24201 //two above.
24202#define RETURN(value) \
24203 return return_comparison_result(l, r, value);
24204
24206
24208
24209 bool result = true;
24210
24211 //compare data_members
24212 {
24213 if (l.get_non_static_data_members().size()
24214 != r.get_non_static_data_members().size())
24215 {
24216 result = false;
24217 if (k)
24219 else
24220 RETURN(result);
24221 }
24222
24223 for (class_or_union::data_members::const_iterator
24224 d0 = l.get_non_static_data_members().begin(),
24225 d1 = r.get_non_static_data_members().begin();
24226 (d0 != l.get_non_static_data_members().end()
24227 && d1 != r.get_non_static_data_members().end());
24228 ++d0, ++d1)
24229 if (**d0 != **d1)
24230 {
24231 result = false;
24232 if (k)
24233 {
24234 // Report any representation change as being local.
24235 if (!types_have_similar_structure((*d0)->get_type(),
24236 (*d1)->get_type())
24237 || (*d0)->get_type() == (*d1)->get_type())
24239 else
24240 *k |= SUBTYPE_CHANGE_KIND;
24241 }
24242 else
24243 RETURN(result);
24244 }
24245 }
24246
24247 // Do not compare member functions. DWARF does not necessarily
24248 // all the member functions, be they virtual or not, in all
24249 // translation units. So we cannot have a clear view of them, per
24250 // class
24251
24252 // compare member function templates
24253 {
24254 if (l.get_member_function_templates().size()
24255 != r.get_member_function_templates().size())
24256 {
24257 result = false;
24258 if (k)
24260 else
24261 RETURN(result);
24262 }
24263
24264 for (member_function_templates::const_iterator
24265 fn_tmpl_it0 = l.get_member_function_templates().begin(),
24266 fn_tmpl_it1 = r.get_member_function_templates().begin();
24267 fn_tmpl_it0 != l.get_member_function_templates().end()
24268 && fn_tmpl_it1 != r.get_member_function_templates().end();
24269 ++fn_tmpl_it0, ++fn_tmpl_it1)
24270 if (**fn_tmpl_it0 != **fn_tmpl_it1)
24271 {
24272 result = false;
24273 if (k)
24274 {
24276 break;
24277 }
24278 else
24279 RETURN(result);
24280 }
24281 }
24282
24283 // compare member class templates
24284 {
24285 if (l.get_member_class_templates().size()
24286 != r.get_member_class_templates().size())
24287 {
24288 result = false;
24289 if (k)
24291 else
24292 RETURN(result);
24293 }
24294
24295 for (member_class_templates::const_iterator
24296 cl_tmpl_it0 = l.get_member_class_templates().begin(),
24297 cl_tmpl_it1 = r.get_member_class_templates().begin();
24298 cl_tmpl_it0 != l.get_member_class_templates().end()
24299 && cl_tmpl_it1 != r.get_member_class_templates().end();
24300 ++cl_tmpl_it0, ++cl_tmpl_it1)
24301 if (**cl_tmpl_it0 != **cl_tmpl_it1)
24302 {
24303 result = false;
24304 if (k)
24305 {
24307 break;
24308 }
24309 else
24310 RETURN(result);
24311 }
24312 }
24313
24314 RETURN(result);
24315#undef RETURN
24316}
24317
24318
24319/// Copy a method of a @ref class_or_union into a new @ref
24320/// class_or_union.
24321///
24322/// @param t the @ref class_or_union into which the method is to be copied.
24323///
24324/// @param method the method to copy into @p t.
24325///
24326/// @return the resulting newly copied method.
24327method_decl_sptr
24328copy_member_function(const class_or_union_sptr& t,
24329 const method_decl_sptr& method)
24330{return copy_member_function(t, method.get());}
24331
24332
24333/// Copy a method of a @ref class_or_union into a new @ref
24334/// class_or_union.
24335///
24336/// @param t the @ref class_or_union into which the method is to be copied.
24337///
24338/// @param method the method to copy into @p t.
24339///
24340/// @return the resulting newly copied method.
24341method_decl_sptr
24342copy_member_function(const class_or_union_sptr& t, const method_decl* method)
24343{
24344 ABG_ASSERT(t);
24345 ABG_ASSERT(method);
24346
24347 method_type_sptr old_type = method->get_type();
24348 ABG_ASSERT(old_type);
24349 method_type_sptr new_type(new method_type(old_type->get_return_type(),
24350 t,
24351 old_type->get_parameters(),
24352 old_type->get_is_const(),
24353 old_type->get_size_in_bits(),
24354 old_type->get_alignment_in_bits()));
24355 t->get_translation_unit()->bind_function_type_life_time(new_type);
24356
24357 method_decl_sptr
24358 new_method(new method_decl(method->get_name(),
24359 new_type,
24360 method->is_declared_inline(),
24361 method->get_location(),
24362 method->get_linkage_name(),
24363 method->get_visibility(),
24364 method->get_binding()));
24365 new_method->set_symbol(method->get_symbol());
24366
24367 if (class_decl_sptr class_type = is_class_type(t))
24368 class_type->add_member_function(new_method,
24372 get_member_is_static(*method),
24376 else
24377 t->add_member_function(new_method,
24379 get_member_is_static(*method),
24383 return new_method;
24384}
24385
24386// </class_or_union definitions>
24387
24388// <class_decl definitions>
24389
24390static void
24391sort_virtual_member_functions(class_decl::member_functions& mem_fns);
24392
24393/// The private data for the class_decl type.
24394struct class_decl::priv
24395{
24396 base_specs bases_;
24397 unordered_map<string, base_spec_sptr> bases_map_;
24398 member_functions virtual_mem_fns_;
24399 virtual_mem_fn_map_type virtual_mem_fns_map_;
24400 bool is_struct_;
24401
24402 priv()
24403 : is_struct_(false)
24404 {}
24405
24406 priv(bool is_struct, class_decl::base_specs& bases)
24407 : bases_(bases),
24408 is_struct_(is_struct)
24409 {
24410 }
24411
24412 priv(bool is_struct)
24413 : is_struct_(is_struct)
24414 {}
24415};// end struct class_decl::priv
24416
24417/// A Constructor for instances of \ref class_decl
24418///
24419/// @param env the environment we are operating from.
24420///
24421/// @param name the identifier of the class.
24422///
24423/// @param size_in_bits the size of an instance of class_decl, expressed
24424/// in bits
24425///
24426/// @param align_in_bits the alignment of an instance of class_decl,
24427/// expressed in bits.
24428///
24429/// @param locus the source location of declaration point this class.
24430///
24431/// @param vis the visibility of instances of class_decl.
24432///
24433/// @param bases the vector of base classes for this instance of class_decl.
24434///
24435/// @param mbrs the vector of member types of this instance of
24436/// class_decl.
24437///
24438/// @param data_mbrs the vector of data members of this instance of
24439/// class_decl.
24440///
24441/// @param mbr_fns the vector of member functions of this instance of
24442/// class_decl.
24443class_decl::class_decl(const environment& env, const string& name,
24444 size_t size_in_bits, size_t align_in_bits,
24445 bool is_struct, const location& locus,
24446 visibility vis, base_specs& bases,
24447 member_types& mbr_types,
24448 data_members& data_mbrs,
24449 member_functions& mbr_fns)
24450 : type_or_decl_base(env,
24451 CLASS_TYPE
24452 | ABSTRACT_TYPE_BASE
24453 | ABSTRACT_DECL_BASE
24454 | ABSTRACT_SCOPE_TYPE_DECL
24455 | ABSTRACT_SCOPE_DECL),
24456 decl_base(env, name, locus, name, vis),
24457 type_base(env, size_in_bits, align_in_bits),
24458 class_or_union(env, name, size_in_bits, align_in_bits,
24459 locus, vis, mbr_types, data_mbrs, mbr_fns),
24460 priv_(new priv(is_struct, bases))
24461{
24463}
24464
24465/// A Constructor for instances of @ref class_decl
24466///
24467/// @param env the environment we are operating from.
24468///
24469/// @param name the identifier of the class.
24470///
24471/// @param size_in_bits the size of an instance of class_decl, expressed
24472/// in bits
24473///
24474/// @param align_in_bits the alignment of an instance of class_decl,
24475/// expressed in bits.
24476///
24477/// @param locus the source location of declaration point this class.
24478///
24479/// @param vis the visibility of instances of class_decl.
24480///
24481/// @param bases the vector of base classes for this instance of class_decl.
24482///
24483/// @param mbrs the vector of member types of this instance of
24484/// class_decl.
24485///
24486/// @param data_mbrs the vector of data members of this instance of
24487/// class_decl.
24488///
24489/// @param mbr_fns the vector of member functions of this instance of
24490/// class_decl.
24491///
24492/// @param is_anonymous whether the newly created instance is
24493/// anonymous.
24494class_decl::class_decl(const environment& env, const string& name,
24495 size_t size_in_bits, size_t align_in_bits,
24496 bool is_struct, const location& locus,
24497 visibility vis, base_specs& bases,
24498 member_types& mbr_types, data_members& data_mbrs,
24499 member_functions& mbr_fns, bool is_anonymous)
24500 : type_or_decl_base(env,
24501 CLASS_TYPE
24502 | ABSTRACT_TYPE_BASE
24503 | ABSTRACT_DECL_BASE
24504 | ABSTRACT_SCOPE_TYPE_DECL
24505 | ABSTRACT_SCOPE_DECL),
24506 decl_base(env, name, locus,
24507 // If the class is anonymous then by default it won't
24508 // have a linkage name. Also, the anonymous class does
24509 // have an internal-only unique name that is generally
24510 // not taken into account when comparing classes; such a
24511 // unique internal-only name, when used as a linkage
24512 // name might introduce spurious comparison false
24513 // negatives.
24514 /*linkage_name=*/is_anonymous ? string() : name,
24515 vis),
24516 type_base(env, size_in_bits, align_in_bits),
24517 class_or_union(env, name, size_in_bits, align_in_bits,
24518 locus, vis, mbr_types, data_mbrs, mbr_fns),
24519 priv_(new priv(is_struct, bases))
24520{
24522 set_is_anonymous(is_anonymous);
24523}
24524
24525/// A constructor for instances of class_decl.
24526///
24527/// @param env the environment we are operating from.
24528///
24529/// @param name the name of the class.
24530///
24531/// @param size_in_bits the size of an instance of class_decl, expressed
24532/// in bits
24533///
24534/// @param align_in_bits the alignment of an instance of class_decl,
24535/// expressed in bits.
24536///
24537/// @param locus the source location of declaration point this class.
24538///
24539/// @param vis the visibility of instances of class_decl.
24540class_decl::class_decl(const environment& env, const string& name,
24541 size_t size_in_bits, size_t align_in_bits,
24542 bool is_struct, const location& locus,
24543 visibility vis)
24544 : type_or_decl_base(env,
24545 CLASS_TYPE
24546 | ABSTRACT_TYPE_BASE
24547 | ABSTRACT_DECL_BASE
24548 | ABSTRACT_SCOPE_TYPE_DECL
24549 | ABSTRACT_SCOPE_DECL),
24550 decl_base(env, name, locus, name, vis),
24551 type_base(env, size_in_bits, align_in_bits),
24552 class_or_union(env, name, size_in_bits, align_in_bits,
24553 locus, vis),
24554 priv_(new priv(is_struct))
24555{
24557}
24558
24559/// A constructor for instances of @ref class_decl.
24560///
24561/// @param env the environment we are operating from.
24562///
24563/// @param name the name of the class.
24564///
24565/// @param size_in_bits the size of an instance of class_decl, expressed
24566/// in bits
24567///
24568/// @param align_in_bits the alignment of an instance of class_decl,
24569/// expressed in bits.
24570///
24571/// @param locus the source location of declaration point this class.
24572///
24573/// @param vis the visibility of instances of class_decl.
24574///
24575/// @param is_anonymous whether the newly created instance is
24576/// anonymous.
24577class_decl:: class_decl(const environment& env, const string& name,
24578 size_t size_in_bits, size_t align_in_bits,
24579 bool is_struct, const location& locus,
24580 visibility vis, bool is_anonymous)
24581 : type_or_decl_base(env,
24582 CLASS_TYPE
24583 | ABSTRACT_TYPE_BASE
24584 | ABSTRACT_DECL_BASE
24585 | ABSTRACT_SCOPE_TYPE_DECL
24586 | ABSTRACT_SCOPE_DECL),
24587 decl_base(env, name, locus,
24588 // If the class is anonymous then by default it won't
24589 // have a linkage name. Also, the anonymous class does
24590 // have an internal-only unique name that is generally
24591 // not taken into account when comparing classes; such a
24592 // unique internal-only name, when used as a linkage
24593 // name might introduce spurious comparison false
24594 // negatives.
24595 /*linkage_name=*/ is_anonymous ? string() : name,
24596 vis),
24597 type_base(env, size_in_bits, align_in_bits),
24598 class_or_union(env, name, size_in_bits, align_in_bits,
24599 locus, vis),
24600 priv_(new priv(is_struct))
24601{
24603 set_is_anonymous(is_anonymous);
24604}
24605
24606/// A constuctor for instances of class_decl that represent a
24607/// declaration without definition.
24608///
24609/// @param env the environment we are operating from.
24610///
24611/// @param name the name of the class.
24612///
24613/// @param is_declaration_only a boolean saying whether the instance
24614/// represents a declaration only, or not.
24615class_decl::class_decl(const environment& env, const string& name,
24616 bool is_struct, bool is_declaration_only)
24617 : type_or_decl_base(env,
24618 CLASS_TYPE
24619 | ABSTRACT_TYPE_BASE
24620 | ABSTRACT_DECL_BASE
24621 | ABSTRACT_SCOPE_TYPE_DECL
24622 | ABSTRACT_SCOPE_DECL),
24623 decl_base(env, name, location(), name),
24624 type_base(env, 0, 0),
24625 class_or_union(env, name, is_declaration_only),
24626 priv_(new priv(is_struct))
24627{
24629}
24630
24631/// This method is invoked automatically right after the current
24632/// instance of @ref class_decl has been canonicalized.
24633///
24634/// Currently, the only thing it does is to sort the virtual member
24635/// functions vector.
24636void
24638{
24640
24641 for (class_decl::virtual_mem_fn_map_type::iterator i =
24642 priv_->virtual_mem_fns_map_.begin();
24643 i != priv_->virtual_mem_fns_map_.end();
24644 ++i)
24645 sort_virtual_member_functions(i->second);
24646}
24647
24648/// Set the "is-struct" flag of the class.
24649///
24650/// @param f the new value of the flag.
24651void
24653{priv_->is_struct_ = f;}
24654
24655/// Test if the class is a struct.
24656///
24657/// @return true iff the class is a struct.
24658bool
24660{return priv_->is_struct_;}
24661
24662/// Add a base specifier to this class.
24663///
24664/// @param b the new base specifier.
24665void
24667{
24668 priv_->bases_.push_back(b);
24669 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
24670}
24671
24672/// Get the base specifiers for this class.
24673///
24674/// @return a vector of the base specifiers.
24677{return priv_->bases_;}
24678
24679/// Find a base class of a given qualified name for the current class.
24680///
24681/// @param qualified_name the qualified name of the base class to look for.
24682///
24683/// @return a pointer to the @ref class_decl that represents the base
24684/// class of name @p qualified_name, if found.
24686class_decl::find_base_class(const string& qualified_name) const
24687{
24688 unordered_map<string, base_spec_sptr>::iterator i =
24689 priv_->bases_map_.find(qualified_name);
24690
24691 if (i != priv_->bases_map_.end())
24692 return i->second->get_base_class();
24693
24694 return class_decl_sptr();
24695}
24696
24697/// Get the virtual member functions of this class.
24698///
24699/// @param return a vector of the virtual member functions of this
24700/// class.
24703{return priv_->virtual_mem_fns_;}
24704
24705/// Get the map that associates a virtual table offset to the virtual
24706/// member functions with that virtual table offset.
24707///
24708/// Usually, there should be a 1:1 mapping between a given vtable
24709/// offset and virtual member functions of that vtable offset. But
24710/// because of some implementation details, there can be several C++
24711/// destructor functions that are *generated* by compilers, for a
24712/// given destructor that is defined in the source code. If the
24713/// destructor is virtual then those generated functions have some
24714/// DWARF attributes in common with the constructor that the user
24715/// actually defined in its source code. Among those attributes are
24716/// the vtable offset of the destructor.
24717///
24718/// @return the map that associates a virtual table offset to the
24719/// virtual member functions with that virtual table offset.
24722{return priv_->virtual_mem_fns_map_;}
24723
24724/// Sort the virtual member functions by their virtual index.
24725void
24727{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
24728
24729/// Getter of the pretty representation of the current instance of
24730/// @ref class_decl.
24731///
24732/// @param internal set to true if the call is intended to get a
24733/// representation of the decl (or type) for the purpose of canonical
24734/// type comparison. This is mainly used in the function
24735/// type_base::get_canonical_type_for().
24736///
24737/// In other words if the argument for this parameter is true then the
24738/// call is meant for internal use (for technical use inside the
24739/// library itself), false otherwise. If you don't know what this is
24740/// for, then set it to false.
24741///
24742/// @param qualified_name if true, names emitted in the pretty
24743/// representation are fully qualified.
24744///
24745/// @return the pretty representaion for a class_decl.
24746string
24748 bool qualified_name) const
24749{
24750 string cl = "class ";
24751 if (!internal && is_struct())
24752 cl = "struct ";
24753
24754 // When computing the pretty representation for internal purposes,
24755 // if an anonymous class is named by a typedef, then consider that
24756 // it has a name, which is the typedef name.
24757 if (get_is_anonymous())
24758 {
24759 if (internal && !get_name().empty())
24760 return cl + get_type_name(this, qualified_name, /*internal=*/true);
24762 /*one_line=*/true,
24763 internal);
24764
24765 }
24766
24767 string result = cl;
24768 if (qualified_name)
24769 result += get_qualified_name(internal);
24770 else
24771 result += get_name();
24772
24773 return result;
24774}
24775
24776decl_base_sptr
24777class_decl::insert_member_decl(decl_base_sptr d)
24778{
24779 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24780 add_member_function(f, public_access,
24781 /*is_virtual=*/false,
24782 /*vtable_offset=*/0,
24783 /*is_static=*/false,
24784 /*is_ctor=*/false,
24785 /*is_dtor=*/false,
24786 /*is_const=*/false);
24787 else
24789
24790 return d;
24791}
24792
24793/// The private data structure of class_decl::base_spec.
24794struct class_decl::base_spec::priv
24795{
24796 class_decl_wptr base_class_;
24797 long offset_in_bits_;
24798 bool is_virtual_;
24799
24800 priv(const class_decl_sptr& cl,
24801 long offset_in_bits,
24802 bool is_virtual)
24803 : base_class_(cl),
24804 offset_in_bits_(offset_in_bits),
24805 is_virtual_(is_virtual)
24806 {}
24807};
24808
24809/// Constructor for base_spec instances.
24810///
24811/// @param base the base class to consider
24812///
24813/// @param a the access specifier of the base class.
24814///
24815/// @param offset_in_bits if positive or null, represents the offset
24816/// of the base in the layout of its containing type.. If negative,
24817/// means that the current base is not laid out in its containing type.
24818///
24819/// @param is_virtual if true, means that the current base class is
24820/// virtual in it's containing type.
24821class_decl::base_spec::base_spec(const class_decl_sptr& base,
24823 long offset_in_bits,
24824 bool is_virtual)
24825 : type_or_decl_base(base->get_environment(),
24826 ABSTRACT_DECL_BASE),
24827 decl_base(base->get_environment(), base->get_name(), base->get_location(),
24828 base->get_linkage_name(), base->get_visibility()),
24829 member_base(a),
24830 priv_(new priv(base, offset_in_bits, is_virtual))
24831{
24833 set_qualified_name(base->get_qualified_name());
24834}
24835
24836/// Return the hash value of the current IR node.
24837///
24838/// Note that upon the first invocation, this member functions
24839/// computes the hash value and returns it. Subsequent invocations
24840/// just return the hash value that was previously calculated.
24841///
24842/// @return the hash value of the current IR node.
24843hash_t
24845{
24847 return h;
24848}
24849
24850/// Get the base class referred to by the current base class
24851/// specifier.
24852///
24853/// @return the base class.
24856{return priv_->base_class_.lock();}
24857
24858/// Getter of the "is-virtual" proprerty of the base class specifier.
24859///
24860/// @return true iff this specifies a virtual base class.
24861bool
24863{return priv_->is_virtual_;}
24864
24865/// Getter of the offset of the base.
24866///
24867/// @return the offset of the base.
24868long
24870{return priv_->offset_in_bits_;}
24871
24872/// Traverses an instance of @ref class_decl::base_spec, visiting all
24873/// the sub-types and decls that it might contain.
24874///
24875/// @param v the visitor that is used to visit every IR sub-node of
24876/// the current node.
24877///
24878/// @return true if either
24879/// - all the children nodes of the current IR node were traversed
24880/// and the calling code should keep going with the traversing.
24881/// - or the current IR node is already being traversed.
24882/// Otherwise, returning false means that the calling code should not
24883/// keep traversing the tree.
24884bool
24886{
24887 if (visiting())
24888 return true;
24889
24890 if (v.visit_begin(this))
24891 {
24892 visiting(true);
24893 get_base_class()->traverse(v);
24894 visiting(false);
24895 }
24896
24897 return v.visit_end(this);
24898}
24899
24900/// Constructor for base_spec instances.
24901///
24902/// Note that this constructor is for clients that don't support RTTI
24903/// and that have a base class of type_base, but of dynamic type
24904/// class_decl.
24905///
24906/// @param base the base class to consider. Must be a pointer to an
24907/// instance of class_decl
24908///
24909/// @param a the access specifier of the base class.
24910///
24911/// @param offset_in_bits if positive or null, represents the offset
24912/// of the base in the layout of its containing type.. If negative,
24913/// means that the current base is not laid out in its containing type.
24914///
24915/// @param is_virtual if true, means that the current base class is
24916/// virtual in it's containing type.
24917class_decl::base_spec::base_spec(const type_base_sptr& base,
24919 long offset_in_bits,
24920 bool is_virtual)
24922 ABSTRACT_DECL_BASE),
24927 member_base(a),
24928 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
24929 offset_in_bits,
24930 is_virtual))
24931{
24933}
24934
24935class_decl::base_spec::~base_spec() = default;
24936
24937/// Compares two instances of @ref class_decl::base_spec.
24938///
24939/// If the two intances are different, set a bitfield to give some
24940/// insight about the kind of differences there are.
24941///
24942/// @param l the first artifact of the comparison.
24943///
24944/// @param r the second artifact of the comparison.
24945///
24946/// @param k a pointer to a bitfield that gives information about the
24947/// kind of changes there are between @p l and @p r. This one is set
24948/// iff @p k is non-null and the function returns false.
24949///
24950/// Please note that setting k to a non-null value does have a
24951/// negative performance impact because even if @p l and @p r are not
24952/// equal, the function keeps up the comparison in order to determine
24953/// the different kinds of ways in which they are different.
24954///
24955/// @return true if @p l equals @p r, false otherwise.
24956bool
24958 const class_decl::base_spec& r,
24959 change_kind* k)
24960{
24961 if (!l.member_base::operator==(r))
24962 {
24963 if (k)
24966 }
24967
24969}
24970
24971/// Comparison operator for @ref class_decl::base_spec.
24972///
24973/// @param other the instance of @ref class_decl::base_spec to compare
24974/// against.
24975///
24976/// @return true if the current instance of @ref class_decl::base_spec
24977/// equals @p other.
24978bool
24980{
24981 const class_decl::base_spec* o =
24982 dynamic_cast<const class_decl::base_spec*>(&other);
24983
24984 if (!o)
24985 return false;
24986
24987 return equals(*this, *o, 0);
24988}
24989
24990/// Comparison operator for @ref class_decl::base_spec.
24991///
24992/// @param other the instance of @ref class_decl::base_spec to compare
24993/// against.
24994///
24995/// @return true if the current instance of @ref class_decl::base_spec
24996/// equals @p other.
24997bool
24999{
25000 const class_decl::base_spec* o =
25001 dynamic_cast<const class_decl::base_spec*>(&other);
25002 if (!o)
25003 return false;
25004
25005 return operator==(static_cast<const decl_base&>(*o));
25006}
25007
25008mem_fn_context_rel::~mem_fn_context_rel()
25009{
25010}
25011
25012/// A constructor for instances of method_decl.
25013///
25014/// @param name the name of the method.
25015///
25016/// @param type the type of the method.
25017///
25018/// @param declared_inline whether the method was
25019/// declared inline or not.
25020///
25021/// @param locus the source location of the method.
25022///
25023/// @param linkage_name the mangled name of the method.
25024///
25025/// @param vis the visibility of the method.
25026///
25027/// @param bind the binding of the method.
25028method_decl::method_decl(const string& name,
25029 method_type_sptr type,
25030 bool declared_inline,
25031 const location& locus,
25032 const string& linkage_name,
25033 visibility vis,
25034 binding bind)
25036 METHOD_DECL
25037 | ABSTRACT_DECL_BASE
25038 |FUNCTION_DECL),
25039 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25040 function_decl(name, static_pointer_cast<function_type>(type),
25041 declared_inline, locus, linkage_name, vis, bind)
25042{
25044 set_context_rel(new mem_fn_context_rel(0));
25045 set_member_function_is_const(*this, type->get_is_const());
25046}
25047
25048/// A constructor for instances of method_decl.
25049///
25050/// @param name the name of the method.
25051///
25052/// @param type the type of the method. Must be an instance of
25053/// method_type.
25054///
25055/// @param declared_inline whether the method was
25056/// declared inline or not.
25057///
25058/// @param locus the source location of the method.
25059///
25060/// @param linkage_name the mangled name of the method.
25061///
25062/// @param vis the visibility of the method.
25063///
25064/// @param bind the binding of the method.
25065method_decl::method_decl(const string& name,
25066 function_type_sptr type,
25067 bool declared_inline,
25068 const location& locus,
25069 const string& linkage_name,
25070 visibility vis,
25071 binding bind)
25072 : type_or_decl_base(type->get_environment(),
25073 METHOD_DECL
25074 | ABSTRACT_DECL_BASE
25075 | FUNCTION_DECL),
25076 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25077 function_decl(name, static_pointer_cast<function_type>
25078 (dynamic_pointer_cast<method_type>(type)),
25079 declared_inline, locus, linkage_name, vis, bind)
25080{
25082 set_context_rel(new mem_fn_context_rel(0));
25083}
25084
25085/// A constructor for instances of method_decl.
25086///
25087/// @param name the name of the method.
25088///
25089/// @param type the type of the method. Must be an instance of
25090/// method_type.
25091///
25092/// @param declared_inline whether the method was
25093/// declared inline or not.
25094///
25095/// @param locus the source location of the method.
25096///
25097/// @param linkage_name the mangled name of the method.
25098///
25099/// @param vis the visibility of the method.
25100///
25101/// @param bind the binding of the method.
25102method_decl::method_decl(const string& name,
25103 type_base_sptr type,
25104 bool declared_inline,
25105 const location& locus,
25106 const string& linkage_name,
25107 visibility vis,
25108 binding bind)
25109 : type_or_decl_base(type->get_environment(),
25110 METHOD_DECL
25111 | ABSTRACT_DECL_BASE
25112 | FUNCTION_DECL),
25113 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25114 function_decl(name, static_pointer_cast<function_type>
25115 (dynamic_pointer_cast<method_type>(type)),
25116 declared_inline, locus, linkage_name, vis, bind)
25117{
25119 set_context_rel(new mem_fn_context_rel(0));
25120}
25121
25122/// Set the linkage name of the method.
25123///
25124/// @param l the new linkage name of the method.
25125void
25127{
25128 string old_lname = get_linkage_name();
25130 // Update the linkage_name -> member function map of the containing
25131 // class declaration.
25132 if (!l.empty())
25133 {
25135 class_or_union_sptr cl = t->get_class_type();
25136 method_decl_sptr m(this, sptr_utils::noop_deleter());
25137 cl->priv_->mem_fns_map_[l] = m;
25138 if (!old_lname.empty() && l != old_lname)
25139 {
25140 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
25141 {
25142 ABG_ASSERT(m.get() == this);
25143 cl->priv_->mem_fns_map_.erase(old_lname);
25144 }
25145 }
25146 }
25147}
25148
25149method_decl::~method_decl()
25150{}
25151
25152const method_type_sptr
25154{
25155 method_type_sptr result;
25157 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
25158 return result;
25159}
25160
25161/// Set the containing class of a method_decl.
25162///
25163/// @param scope the new containing class_decl.
25164void
25165method_decl::set_scope(scope_decl* scope)
25166{
25167 if (!get_context_rel())
25168 set_context_rel(new mem_fn_context_rel(scope));
25169 else
25170 get_context_rel()->set_scope(scope);
25171}
25172
25173/// Equality operator for @ref method_decl_sptr.
25174///
25175/// This is a deep equality operator, as it compares the @ref
25176/// method_decl that is pointed-to by the smart pointer.
25177///
25178/// @param l the left-hand side argument of the equality operator.
25179///
25180/// @param r the righ-hand side argument of the equality operator.
25181///
25182/// @return true iff @p l equals @p r.
25183bool
25184operator==(const method_decl_sptr& l, const method_decl_sptr& r)
25185{
25186 if (l.get() == r.get())
25187 return true;
25188 if (!!l != !!r)
25189 return false;
25190
25191 return *l == *r;
25192}
25193
25194/// Inequality operator for @ref method_decl_sptr.
25195///
25196/// This is a deep equality operator, as it compares the @ref
25197/// method_decl that is pointed-to by the smart pointer.
25198///
25199/// @param l the left-hand side argument of the equality operator.
25200///
25201/// @param r the righ-hand side argument of the equality operator.
25202///
25203/// @return true iff @p l differs from @p r.
25204bool
25205operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
25206{return !operator==(l, r);}
25207
25208/// Test if a function_decl is actually a method_decl.
25209///
25210///@param d the @ref function_decl to consider.
25211///
25212/// @return the method_decl sub-object of @p d if inherits
25213/// a method_decl type.
25216{
25217 return dynamic_cast<method_decl*>
25218 (const_cast<type_or_decl_base*>(d));
25219}
25220
25221/// Test if a function_decl is actually a method_decl.
25222///
25223///@param d the @ref function_decl to consider.
25224///
25225/// @return the method_decl sub-object of @p d if inherits
25226/// a method_decl type.
25229{return is_method_decl(&d);}
25230
25231/// Test if a function_decl is actually a method_decl.
25232///
25233///@param d the @ref function_decl to consider.
25234///
25235/// @return the method_decl sub-object of @p d if inherits
25236/// a method_decl type.
25237method_decl_sptr
25239{return dynamic_pointer_cast<method_decl>(d);}
25240
25241/// A "less than" functor to sort a vector of instances of
25242/// method_decl that are virtual.
25243struct virtual_member_function_less_than
25244{
25245 /// The less than operator. First, it sorts the methods by their
25246 /// vtable index. If they have the same vtable index, it sorts them
25247 /// by the name of their ELF symbol. If they don't have elf
25248 /// symbols, it sorts them by considering their pretty
25249 /// representation.
25250 ///
25251 /// Note that this method expects virtual methods.
25252 ///
25253 /// @param f the first method to consider.
25254 ///
25255 /// @param s the second method to consider.
25256 ///
25257 /// @return true if method @p is less than method @s.
25258 bool
25259 operator()(const method_decl& f,
25260 const method_decl& s)
25261 {
25264
25265 ssize_t f_offset = get_member_function_vtable_offset(f);
25266 ssize_t s_offset = get_member_function_vtable_offset(s);
25267 if (f_offset != s_offset) return f_offset < s_offset;
25268
25269 string fn, sn;
25270 // Try the linkage names (important for destructors).
25271 fn = f.get_linkage_name();
25272 sn = s.get_linkage_name();
25273 if (fn != sn) return fn < sn;
25274
25275 // If the functions have symbols, then compare their symbol-id
25276 // string.
25277 elf_symbol_sptr f_sym = f.get_symbol();
25278 elf_symbol_sptr s_sym = s.get_symbol();
25279 if ((!f_sym) != (!s_sym)) return !f_sym;
25280 if (f_sym && s_sym)
25281 {
25282 fn = f_sym->get_id_string();
25283 sn = s_sym->get_id_string();
25284 if (fn != sn) return fn < sn;
25285 }
25286
25287 // None of the functions have symbols or linkage names that
25288 // distinguish them, so compare their pretty representation.
25291 if (fn != sn) return fn < sn;
25292
25293 /// If it's just the file paths that are different then sort them
25294 /// too.
25295 string fn_filepath, sn_filepath;
25296 unsigned line = 0, column = 0;
25297 location fn_loc = f.get_location(), sn_loc = s.get_location();
25298 if (fn_loc)
25299 fn_loc.expand(fn_filepath, line, column);
25300 if (sn_loc)
25301 sn_loc.expand(sn_filepath, line, column);
25302 return fn_filepath < sn_filepath;
25303 }
25304
25305 /// The less than operator. First, it sorts the methods by their
25306 /// vtable index. If they have the same vtable index, it sorts them
25307 /// by the name of their ELF symbol. If they don't have elf
25308 /// symbols, it sorts them by considering their pretty
25309 /// representation.
25310 ///
25311 /// Note that this method expects to take virtual methods.
25312 ///
25313 /// @param f the first method to consider.
25314 ///
25315 /// @param s the second method to consider.
25316 bool
25317 operator()(const method_decl_sptr f,
25318 const method_decl_sptr s)
25319 {return operator()(*f, *s);}
25320}; // end struct virtual_member_function_less_than
25321
25322/// Sort a vector of instances of virtual member functions.
25323///
25324/// @param mem_fns the vector of member functions to sort.
25325static void
25326sort_virtual_member_functions(class_decl::member_functions& mem_fns)
25327{
25328 virtual_member_function_less_than lt;
25329 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25330}
25331
25332/// Add a member function to the current instance of @ref class_or_union.
25333///
25334/// @param f a method_decl to add to the current class. This function
25335/// should not have been already added to a scope.
25336///
25337/// @param access the access specifier for the member function to add.
25338///
25339/// @param is_virtual if this is true then it means the function @p f
25340/// is a virtual function. That also means that the current instance
25341/// of @ref class_or_union is actually an instance of @ref class_decl.
25342///
25343/// @param vtable_offset the offset of the member function in the
25344/// virtual table. This parameter is taken into account only if @p
25345/// is_virtual is true.
25346///
25347/// @param is_static whether the member function is static.
25348///
25349/// @param is_ctor whether the member function is a constructor.
25350///
25351/// @param is_dtor whether the member function is a destructor.
25352///
25353/// @param is_const whether the member function is const.
25354void
25357 bool is_virtual,
25358 size_t vtable_offset,
25359 bool is_static, bool is_ctor,
25360 bool is_dtor, bool is_const)
25361{
25362 add_member_function(f, a, is_static, is_ctor,
25363 is_dtor, is_const);
25364
25365 if (class_decl* klass = is_class_type(this))
25366 {
25367 if (is_virtual)
25368 {
25369 set_member_function_virtuality(f, is_virtual, vtable_offset);
25370 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
25371 }
25372 }
25373}
25374
25375/// When a virtual member function has seen its virtualness set by
25376/// set_member_function_is_virtual(), this function ensures that the
25377/// member function is added to the specific vectors and maps of
25378/// virtual member function of its class.
25379///
25380/// @param method the method to fixup.
25381void
25382fixup_virtual_member_function(method_decl_sptr method)
25383{
25384 if (!method || !get_member_function_is_virtual(method))
25385 return;
25386
25387 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
25388
25389 class_decl::member_functions::const_iterator m;
25390 for (m = klass->priv_->virtual_mem_fns_.begin();
25391 m != klass->priv_->virtual_mem_fns_.end();
25392 ++m)
25393 if (m->get() == method.get()
25394 || (*m)->get_linkage_name() == method->get_linkage_name())
25395 break;
25396 if (m == klass->priv_->virtual_mem_fns_.end())
25397 klass->priv_->virtual_mem_fns_.push_back(method);
25398
25399 // Build or udpate the map that associates a vtable offset to the
25400 // number of virtual member functions that "point" to it.
25401 ssize_t voffset = get_member_function_vtable_offset(method);
25402 if (voffset == -1)
25403 return;
25404
25405 class_decl::virtual_mem_fn_map_type::iterator i =
25406 klass->priv_->virtual_mem_fns_map_.find(voffset);
25407 if (i == klass->priv_->virtual_mem_fns_map_.end())
25408 {
25409 class_decl::member_functions virtual_mem_fns_at_voffset;
25410 virtual_mem_fns_at_voffset.push_back(method);
25411 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
25412 }
25413 else
25414 {
25415 for (m = i->second.begin() ; m != i->second.end(); ++m)
25416 if (m->get() == method.get()
25417 || (*m)->get_linkage_name() == method->get_linkage_name())
25418 break;
25419 if (m == i->second.end())
25420 i->second.push_back(method);
25421 }
25422}
25423
25424/// Return true iff the class has no entity in its scope.
25425bool
25427{return priv_->bases_.empty() && has_no_member();}
25428
25429/// Test if the current instance of @ref class_decl has virtual member
25430/// functions.
25431///
25432/// @return true iff the current instance of @ref class_decl has
25433/// virtual member functions.
25434bool
25436{return !get_virtual_mem_fns().empty();}
25437
25438/// Test if the current instance of @ref class_decl has at least one
25439/// virtual base.
25440///
25441/// @return true iff the current instance of @ref class_decl has a
25442/// virtual member function.
25443bool
25445{
25446 for (base_specs::const_iterator b = get_base_specifiers().begin();
25447 b != get_base_specifiers().end();
25448 ++b)
25449 if ((*b)->get_is_virtual()
25450 || (*b)->get_base_class()->has_virtual_bases())
25451 return true;
25452
25453 return false;
25454}
25455
25456/// Test if the current instance has a vtable.
25457///
25458/// This is only valid for a C++ program.
25459///
25460/// Basically this function checks if the class has either virtual
25461/// functions, or virtual bases.
25462bool
25464{
25466 || has_virtual_bases())
25467 return true;
25468 return false;
25469}
25470
25471/// Get the highest vtable offset of all the virtual methods of the
25472/// class.
25473///
25474/// @return the highest vtable offset of all the virtual methods of
25475/// the class.
25476ssize_t
25478{
25479 ssize_t offset = -1;
25480 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
25481 get_virtual_mem_fns_map().begin();
25482 e != get_virtual_mem_fns_map().end();
25483 ++e)
25484 if (e->first > offset)
25485 offset = e->first;
25486
25487 return offset;
25488}
25489
25490/// Return the hash value of the current IR node.
25491///
25492/// Note that upon the first invocation, this member functions
25493/// computes the hash value and returns it. Subsequent invocations
25494/// just return the hash value that was previously calculated.
25495///
25496/// @return the hash value of the current IR node.
25497hash_t
25499{
25501 return h;
25502}
25503
25504/// Test if two methods are equal without taking their symbol or
25505/// linkage name into account.
25506///
25507/// @param f the first method.
25508///
25509/// @param s the second method.
25510///
25511/// @return true iff @p f equals @p s without taking their linkage
25512/// name or symbol into account.
25513static bool
25514methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
25515 const method_decl_sptr& s)
25516{
25517 method_decl_sptr first = f, second = s;
25518 elf_symbol_sptr saved_first_elf_symbol =
25519 first->get_symbol();
25520 elf_symbol_sptr saved_second_elf_symbol =
25521 second->get_symbol();
25522 interned_string saved_first_linkage_name =
25523 first->get_linkage_name();
25524 interned_string saved_second_linkage_name =
25525 second->get_linkage_name();
25526
25527 first->set_symbol(elf_symbol_sptr());
25528 first->set_linkage_name("");
25529 second->set_symbol(elf_symbol_sptr());
25530 second->set_linkage_name("");
25531
25532 bool equal = *first == *second;
25533
25534 first->set_symbol(saved_first_elf_symbol);
25535 first->set_linkage_name(saved_first_linkage_name);
25536 second->set_symbol(saved_second_elf_symbol);
25537 second->set_linkage_name(saved_second_linkage_name);
25538
25539 return equal;
25540}
25541
25542/// Test if a given method is equivalent to at least of other method
25543/// that is in a vector of methods.
25544///
25545/// Note that "equivalent" here means being equal without taking the
25546/// linkage name or the symbol of the methods into account.
25547///
25548/// This is a sub-routine of the 'equals' function that compares @ref
25549/// class_decl.
25550///
25551/// @param method the method to compare.
25552///
25553/// @param fns the vector of functions to compare @p method against.
25554///
25555/// @return true iff @p is equivalent to at least one method in @p
25556/// fns.
25557static bool
25558method_matches_at_least_one_in_vector(const method_decl_sptr& method,
25560{
25561 for (class_decl::member_functions::const_iterator i = fns.begin();
25562 i != fns.end();
25563 ++i)
25564 // Note that the comparison must be done in this order: method ==
25565 // *i This is to keep the consistency of the comparison. It's
25566 // important especially when doing type canonicalization. The
25567 // already canonicalize type is the left operand, and the type
25568 // being canonicalized is the right operand. This comes from the
25569 // code in type_base::get_canonical_type_for().
25570 if (methods_equal_modulo_elf_symbol(method, *i))
25571 return true;
25572
25573 return false;
25574}
25575
25576/// Compares two instances of @ref class_decl.
25577///
25578/// If the two intances are different, set a bitfield to give some
25579/// insight about the kind of differences there are.
25580///
25581/// @param l the first artifact of the comparison.
25582///
25583/// @param r the second artifact of the comparison.
25584///
25585/// @param k a pointer to a bitfield that gives information about the
25586/// kind of changes there are between @p l and @p r. This one is set
25587/// iff @p k is non-null and the function returns false.
25588///
25589/// Please note that setting k to a non-null value does have a
25590/// negative performance impact because even if @p l and @p r are not
25591/// equal, the function keeps up the comparison in order to determine
25592/// the different kinds of ways in which they are different.
25593///
25594/// @return true if @p l equals @p r, false otherwise.
25595bool
25597{
25598 {
25599 // First of all, let's see if these two types haven't already been
25600 // compared. If so, and if the result of the comparison has been
25601 // cached, let's just re-use it, rather than comparing them all
25602 // over again.
25603 bool result = false;
25604 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
25605 ABG_RETURN(result);
25606 }
25607
25608 // if one of the classes is declaration-only then we take a fast
25609 // path here.
25611 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
25612 static_cast<const class_or_union&>(r),
25613 k));
25614
25615 bool result = true;
25616 if (!equals(static_cast<const class_or_union&>(l),
25617 static_cast<const class_or_union&>(r),
25618 k))
25619 {
25620 result = false;
25621 if (!k)
25622 ABG_RETURN(result);
25623 }
25624
25626
25628
25629#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
25630
25631 // Compare bases.
25632 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
25633 {
25634 result = false;
25635 if (k)
25637 else
25638 RETURN(result);
25639 }
25640
25641 for (class_decl::base_specs::const_iterator
25642 b0 = l.get_base_specifiers().begin(),
25643 b1 = r.get_base_specifiers().begin();
25644 (b0 != l.get_base_specifiers().end()
25645 && b1 != r.get_base_specifiers().end());
25646 ++b0, ++b1)
25647 if (*b0 != *b1)
25648 {
25649 result = false;
25650 if (k)
25651 {
25652 if (!types_have_similar_structure((*b0)->get_base_class().get(),
25653 (*b1)->get_base_class().get()))
25655 else
25656 *k |= SUBTYPE_CHANGE_KIND;
25657 break;
25658 }
25659 RETURN(result);
25660 }
25661
25662 // Compare virtual member functions
25663
25664 // We look at the map that associates a given vtable offset to a
25665 // vector of virtual member functions that point to that offset.
25666 //
25667 // This is because there are cases where several functions can
25668 // point to the same virtual table offset.
25669 //
25670 // This is usually the case for virtual destructors. Even though
25671 // there can be only one virtual destructor declared in source
25672 // code, there are actually potentially up to three generated
25673 // functions for that destructor. Some of these generated
25674 // functions can be clones of other functions that are among those
25675 // generated ones. In any cases, they all have the same
25676 // properties, including the vtable offset property.
25677
25678 // So, there should be the same number of different vtable
25679 // offsets, the size of two maps must be equals.
25680 if (l.get_virtual_mem_fns_map().size()
25681 != r.get_virtual_mem_fns_map().size())
25682 {
25683 result = false;
25684 if (k)
25686 else
25687 RETURN(result);
25688 }
25689
25690 // Then, each virtual member function of a given vtable offset in
25691 // the first class type, must match an equivalent virtual member
25692 // function of a the same vtable offset in the second class type.
25693 //
25694 // By "match", I mean that the two virtual member function should
25695 // be equal if we don't take into account their symbol name or
25696 // their linkage name. This is because two destructor functions
25697 // clones (for instance) might have different linkage name, but
25698 // are still equivalent if their other properties are the same.
25699 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
25700 l.get_virtual_mem_fns_map().begin();
25701 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
25702 ++first_v_fn_entry)
25703 {
25704 unsigned voffset = first_v_fn_entry->first;
25705 const class_decl::member_functions& first_vfns =
25706 first_v_fn_entry->second;
25707
25708 const class_decl::virtual_mem_fn_map_type::const_iterator
25709 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
25710
25711 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
25712 {
25713 result = false;
25714 if (k)
25716 RETURN(result);
25717 }
25718
25719 const class_decl::member_functions& second_vfns =
25720 second_v_fn_entry->second;
25721
25722 bool matches = false;
25723 for (class_decl::member_functions::const_iterator i =
25724 first_vfns.begin();
25725 i != first_vfns.end();
25726 ++i)
25727 if (method_matches_at_least_one_in_vector(*i, second_vfns))
25728 {
25729 matches = true;
25730 break;
25731 }
25732
25733 if (!matches)
25734 {
25735 result = false;
25736 if (k)
25737 *k |= SUBTYPE_CHANGE_KIND;
25738 else
25739 RETURN(result);
25740 }
25741 }
25742
25743 RETURN(result);
25744#undef RETURN
25745}
25746
25747/// Copy a method of a class into a new class.
25748///
25749/// @param klass the class into which the method is to be copied.
25750///
25751/// @param method the method to copy into @p klass.
25752///
25753/// @return the resulting newly copied method.
25754method_decl_sptr
25755copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
25756{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
25757
25758/// Copy a method of a class into a new class.
25759///
25760/// @param klass the class into which the method is to be copied.
25761///
25762/// @param method the method to copy into @p klass.
25763///
25764/// @return the resulting newly copied method.
25765method_decl_sptr
25767{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
25768
25769/// Comparison operator for @ref class_decl.
25770///
25771/// @param other the instance of @ref class_decl to compare against.
25772///
25773/// @return true iff the current instance of @ref class_decl equals @p
25774/// other.
25775bool
25777{
25778 const class_decl* op = is_class_type(&other);
25779 if (!op)
25780 {
25781 if (class_or_union* cou = is_class_or_union_type(&other))
25782 return class_or_union::operator==(*cou);
25783 return false;
25784 }
25785
25786 // If this is a decl-only type (and thus with no canonical type),
25787 // use the canonical type of the definition, if any.
25788 const class_decl *l = 0;
25790 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
25791 if (l == 0)
25792 l = this;
25793
25794 ABG_ASSERT(l);
25795
25796 // Likewise for the other type.
25797 const class_decl *r = 0;
25798 if (op->get_is_declaration_only())
25799 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
25800 if (r == 0)
25801 r = op;
25802
25803 ABG_ASSERT(r);
25804
25805 return try_canonical_compare(l, r);
25806}
25807
25808/// Equality operator for class_decl.
25809///
25810/// Re-uses the equality operator that takes a decl_base.
25811///
25812/// @param other the other class_decl to compare against.
25813///
25814/// @return true iff the current instance equals the other one.
25815bool
25817{
25818 const decl_base* o = is_decl(&other);
25819 if (!o)
25820 return false;
25821 return *this == *o;
25822}
25823
25824/// Equality operator for class_decl.
25825///
25826/// Re-uses the equality operator that takes a decl_base.
25827///
25828/// @param other the other class_decl to compare against.
25829///
25830/// @return true iff the current instance equals the other one.
25831bool
25833{
25834 const decl_base& o = other;
25835 return *this == o;
25836}
25837
25838/// Comparison operator for @ref class_decl.
25839///
25840/// @param other the instance of @ref class_decl to compare against.
25841///
25842/// @return true iff the current instance of @ref class_decl equals @p
25843/// other.
25844bool
25846{
25847 const decl_base& o = other;
25848 return *this == o;
25849}
25850
25851/// Turn equality of shared_ptr of class_decl into a deep equality;
25852/// that is, make it compare the pointed to objects too.
25853///
25854/// @param l the shared_ptr of class_decl on left-hand-side of the
25855/// equality.
25856///
25857/// @param r the shared_ptr of class_decl on right-hand-side of the
25858/// equality.
25859///
25860/// @return true if the class_decl pointed to by the shared_ptrs are
25861/// equal, false otherwise.
25862bool
25864{
25865 if (l.get() == r.get())
25866 return true;
25867 if (!!l != !!r)
25868 return false;
25869
25870 return *l == *r;
25871}
25872
25873/// Turn inequality of shared_ptr of class_decl into a deep equality;
25874/// that is, make it compare the pointed to objects too.
25875///
25876/// @param l the shared_ptr of class_decl on left-hand-side of the
25877/// equality.
25878///
25879/// @param r the shared_ptr of class_decl on right-hand-side of the
25880/// equality.
25881///
25882/// @return true if the class_decl pointed to by the shared_ptrs are
25883/// different, false otherwise.
25884bool
25886{return !operator==(l, r);}
25887
25888/// Turn equality of shared_ptr of class_or_union into a deep
25889/// equality; that is, make it compare the pointed to objects too.
25890///
25891/// @param l the left-hand-side operand of the operator
25892///
25893/// @param r the right-hand-side operand of the operator.
25894///
25895/// @return true iff @p l equals @p r.
25896bool
25897operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
25898{
25899 if (l.get() == r.get())
25900 return true;
25901 if (!!l != !!r)
25902 return false;
25903
25904 return *l == *r;
25905}
25906
25907/// Turn inequality of shared_ptr of class_or_union into a deep
25908/// equality; that is, make it compare the pointed to objects too.
25909///
25910/// @param l the left-hand-side operand of the operator
25911///
25912/// @param r the right-hand-side operand of the operator.
25913///
25914/// @return true iff @p l is different from @p r.
25915bool
25916operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
25917{return !operator==(l, r);}
25918
25919/// This implements the ir_traversable_base::traverse pure virtual
25920/// function.
25921///
25922/// @param v the visitor used on the current instance and on its
25923/// members.
25924///
25925/// @return true if the entire IR node tree got traversed, false
25926/// otherwise.
25927bool
25929{
25930 if (v.type_node_has_been_visited(this))
25931 return true;
25932
25933 if (visiting())
25934 return true;
25935
25936 if (v.visit_begin(this))
25937 {
25938 visiting(true);
25939 bool stop = false;
25940
25941 for (base_specs::const_iterator i = get_base_specifiers().begin();
25942 i != get_base_specifiers().end();
25943 ++i)
25944 {
25945 if (!(*i)->traverse(v))
25946 {
25947 stop = true;
25948 break;
25949 }
25950 }
25951
25952 if (!stop)
25953 for (data_members::const_iterator i = get_data_members().begin();
25954 i != get_data_members().end();
25955 ++i)
25956 if (!(*i)->traverse(v))
25957 {
25958 stop = true;
25959 break;
25960 }
25961
25962 if (!stop)
25963 for (member_functions::const_iterator i= get_member_functions().begin();
25964 i != get_member_functions().end();
25965 ++i)
25966 if (!(*i)->traverse(v))
25967 {
25968 stop = true;
25969 break;
25970 }
25971
25972 if (!stop)
25973 for (member_types::const_iterator i = get_member_types().begin();
25974 i != get_member_types().end();
25975 ++i)
25976 if (!(*i)->traverse(v))
25977 {
25978 stop = true;
25979 break;
25980 }
25981
25982 if (!stop)
25983 for (member_function_templates::const_iterator i =
25985 i != get_member_function_templates().end();
25986 ++i)
25987 if (!(*i)->traverse(v))
25988 {
25989 stop = true;
25990 break;
25991 }
25992
25993 if (!stop)
25994 for (member_class_templates::const_iterator i =
25996 i != get_member_class_templates().end();
25997 ++i)
25998 if (!(*i)->traverse(v))
25999 {
26000 stop = true;
26001 break;
26002 }
26003 visiting(false);
26004 }
26005
26006 bool result = v.visit_end(this);
26008 return result;
26009}
26010
26011/// Destructor of the @ref class_decl type.
26013{delete priv_;}
26014
26015context_rel::~context_rel()
26016{}
26017
26018bool
26019member_base::operator==(const member_base& o) const
26020{
26022 && get_is_static() == o.get_is_static());
26023}
26024
26025/// Equality operator for smart pointers to @ref
26026/// class_decl::base_specs.
26027///
26028/// This compares the pointed-to objects.
26029///
26030/// @param l the first instance to consider.
26031///
26032/// @param r the second instance to consider.
26033///
26034/// @return true iff @p l equals @p r.
26035bool
26038{
26039 if (l.get() == r.get())
26040 return true;
26041 if (!!l != !!r)
26042 return false;
26043
26044 return *l == static_cast<const decl_base&>(*r);
26045}
26046
26047/// Inequality operator for smart pointers to @ref
26048/// class_decl::base_specs.
26049///
26050/// This compares the pointed-to objects.
26051///
26052/// @param l the first instance to consider.
26053///
26054/// @param r the second instance to consider.
26055///
26056/// @return true iff @p l is different from @p r.
26057bool
26060{return !operator==(l, r);}
26061
26062/// Test if an ABI artifact is a class base specifier.
26063///
26064/// @param tod the ABI artifact to consider.
26065///
26066/// @return a pointer to the @ref class_decl::base_spec sub-object of
26067/// @p tod iff it's a class base specifier.
26070{
26071 return dynamic_cast<class_decl::base_spec*>
26072 (const_cast<type_or_decl_base*>(tod));
26073}
26074
26075/// Test if an ABI artifact is a class base specifier.
26076///
26077/// @param tod the ABI artifact to consider.
26078///
26079/// @return a pointer to the @ref class_decl::base_spec sub-object of
26080/// @p tod iff it's a class base specifier.
26083{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
26084
26085bool
26086member_function_template::operator==(const member_base& other) const
26087{
26088 try
26089 {
26090 const member_function_template& o =
26091 dynamic_cast<const member_function_template&>(other);
26092
26093 if (!(is_constructor() == o.is_constructor()
26094 && is_const() == o.is_const()
26095 && member_base::operator==(o)))
26096 return false;
26097
26098 if (function_tdecl_sptr ftdecl = as_function_tdecl())
26099 {
26100 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
26101 if (other_ftdecl)
26102 return ftdecl->function_tdecl::operator==(*other_ftdecl);
26103 }
26104 }
26105 catch(...)
26106 {}
26107 return false;
26108}
26109
26110/// Equality operator for smart pointers to @ref
26111/// member_function_template. This is compares the
26112/// pointed-to instances.
26113///
26114/// @param l the first instance to consider.
26115///
26116/// @param r the second instance to consider.
26117///
26118/// @return true iff @p l equals @p r.
26119bool
26120operator==(const member_function_template_sptr& l,
26121 const member_function_template_sptr& r)
26122{
26123 if (l.get() == r.get())
26124 return true;
26125 if (!!l != !!r)
26126 return false;
26127
26128 return *l == *r;
26129}
26130
26131/// Inequality operator for smart pointers to @ref
26132/// member_function_template. This is compares the pointed-to
26133/// instances.
26134///
26135/// @param l the first instance to consider.
26136///
26137/// @param r the second instance to consider.
26138///
26139/// @return true iff @p l equals @p r.
26140bool
26141operator!=(const member_function_template_sptr& l,
26142 const member_function_template_sptr& r)
26143{return !operator==(l, r);}
26144
26145/// This implements the ir_traversable_base::traverse pure virtual
26146/// function.
26147///
26148/// @param v the visitor used on the current instance and on its
26149/// underlying function template.
26150///
26151/// @return true if the entire IR node tree got traversed, false
26152/// otherwise.
26153bool
26155{
26156 if (visiting())
26157 return true;
26158
26159 if (v.visit_begin(this))
26160 {
26161 visiting(true);
26162 if (function_tdecl_sptr f = as_function_tdecl())
26163 f->traverse(v);
26164 visiting(false);
26165 }
26166 return v.visit_end(this);
26167}
26168
26169/// Equality operator of the the @ref member_class_template class.
26170///
26171/// @param other the other @ref member_class_template to compare against.
26172///
26173/// @return true iff the current instance equals @p other.
26174bool
26176{
26177 try
26178 {
26179 const member_class_template& o =
26180 dynamic_cast<const member_class_template&>(other);
26181
26182 if (!member_base::operator==(o))
26183 return false;
26184
26185 return as_class_tdecl()->class_tdecl::operator==(o);
26186 }
26187 catch(...)
26188 {return false;}
26189}
26190
26191/// Equality operator of the the @ref member_class_template class.
26192///
26193/// @param other the other @ref member_class_template to compare against.
26194///
26195/// @return true iff the current instance equals @p other.
26196bool
26198{
26199 if (!decl_base::operator==(other))
26200 return false;
26201 return as_class_tdecl()->class_tdecl::operator==(other);
26202}
26203
26204/// Comparison operator for the @ref member_class_template
26205/// type.
26206///
26207/// @param other the other instance of @ref
26208/// member_class_template to compare against.
26209///
26210/// @return true iff the two instances are equal.
26211bool
26213{
26214 const decl_base* o = dynamic_cast<const decl_base*>(&other);
26215 return *this == *o;
26216}
26217
26218/// Comparison operator for the @ref member_class_template
26219/// type.
26220///
26221/// @param l the first argument of the operator.
26222///
26223/// @param r the second argument of the operator.
26224///
26225/// @return true iff the two instances are equal.
26226bool
26227operator==(const member_class_template_sptr& l,
26228 const member_class_template_sptr& r)
26229{
26230 if (l.get() == r.get())
26231 return true;
26232 if (!!l != !!r)
26233 return false;
26234
26235 return *l == *r;
26236}
26237
26238/// Inequality operator for the @ref member_class_template
26239/// type.
26240///
26241/// @param l the first argument of the operator.
26242///
26243/// @param r the second argument of the operator.
26244///
26245/// @return true iff the two instances are equal.
26246bool
26247operator!=(const member_class_template_sptr& l,
26248 const member_class_template_sptr& r)
26249{return !operator==(l, r);}
26250
26251/// This implements the ir_traversable_base::traverse pure virtual
26252/// function.
26253///
26254/// @param v the visitor used on the current instance and on the class
26255/// pattern of the template.
26256///
26257/// @return true if the entire IR node tree got traversed, false
26258/// otherwise.
26259bool
26261{
26262 if (visiting())
26263 return true;
26264
26265 if (v.visit_begin(this))
26266 {
26267 visiting(true);
26268 if (class_tdecl_sptr t = as_class_tdecl())
26269 t->traverse(v);
26270 visiting(false);
26271 }
26272 return v.visit_end(this);
26273}
26274
26275/// Streaming operator for class_decl::access_specifier.
26276///
26277/// @param o the output stream to serialize the access specifier to.
26278///
26279/// @param a the access specifier to serialize.
26280///
26281/// @return the output stream.
26282std::ostream&
26283operator<<(std::ostream& o, access_specifier a)
26284{
26285 string r;
26286
26287 switch (a)
26288 {
26289 case no_access:
26290 r = "none";
26291 break;
26292 case private_access:
26293 r = "private";
26294 break;
26295 case protected_access:
26296 r = "protected";
26297 break;
26298 case public_access:
26299 r= "public";
26300 break;
26301 };
26302 o << r;
26303 return o;
26304}
26305
26306/// Sets the static-ness property of a class member.
26307///
26308/// @param d the class member to set the static-ness property for.
26309/// Note that this must be a class member otherwise the function
26310/// aborts the current process.
26311///
26312/// @param s this must be true if the member is to be static, false
26313/// otherwise.
26314void
26316{
26318
26320 ABG_ASSERT(c);
26321
26322 c->set_is_static(s);
26323
26324 scope_decl* scope = d.get_scope();
26325
26326 if (class_or_union* cl = is_class_or_union_type(scope))
26327 {
26328 if (var_decl* v = is_var_decl(&d))
26329 {
26330 // First, find v in the set of data members.
26331 var_decl_sptr var;
26332 for (const auto& dm : cl->get_data_members())
26333 if (dm->get_name() == v->get_name())
26334 {
26335 var = dm;
26336 break;
26337 }
26338 if (!var)
26339 return;
26340
26341 if (s)
26342 {
26343 // remove from the non-static data members
26344 for (class_decl::data_members::iterator i =
26345 cl->priv_->non_static_data_members_.begin();
26346 i != cl->priv_->non_static_data_members_.end();
26347 ++i)
26348 {
26349 if ((*i)->get_name() == v->get_name())
26350 {
26351 cl->priv_->non_static_data_members_.erase(i);
26352 break;
26353 }
26354 }
26355
26356 // If it's not in the static data members, then add it
26357 // there.
26358 bool already_in_static_dms = false;
26359 for (const auto& s_dm : cl->priv_->static_data_members_)
26360 if (s_dm->get_name() == v->get_name())
26361 {
26362 already_in_static_dms = true;
26363 break;
26364 }
26365 if (!already_in_static_dms)
26366 cl->priv_->static_data_members_.push_back(var);
26367 }
26368 else // is non-static
26369 {
26370 // Remove from the static data members.
26371 for (class_or_union::data_members::iterator i =
26372 cl->priv_->static_data_members_.begin();
26373 i != cl->priv_->static_data_members_.end();
26374 ++i)
26375 if ((*i)->get_name() == v->get_name())
26376 {
26377 cl->priv_->static_data_members_.erase(i);
26378 break;
26379 }
26380
26381 // If it's not already in the non-static data members
26382 // then add it there.
26383 bool is_already_in_non_static_data_members = false;
26384 for (const auto& ns_dm : cl->priv_->non_static_data_members_)
26385 if (ns_dm->get_name() == v->get_name())
26386 {
26387 is_already_in_non_static_data_members = true;
26388 break;
26389 }
26390 if (!is_already_in_non_static_data_members)
26391 cl->priv_->non_static_data_members_.push_back(var);
26392 }
26393 }
26394 }
26395}
26396
26397/// Sets the static-ness property of a class member.
26398///
26399/// @param d the class member to set the static-ness property for.
26400/// Note that this must be a class member otherwise the function
26401/// aborts the current process.
26402///
26403/// @param s this must be true if the member is to be static, false
26404/// otherwise.
26405void
26406set_member_is_static(const decl_base_sptr& d, bool s)
26407{set_member_is_static(*d, s);}
26408
26409// </class_decl>
26410
26411// <union_decl>
26412
26413/// Constructor for the @ref union_decl type.
26414///
26415/// @param env the @ref environment we are operating from.
26416///
26417/// @param name the name of the union type.
26418///
26419/// @param size_in_bits the size of the union, in bits.
26420///
26421/// @param locus the location of the type.
26422///
26423/// @param vis the visibility of instances of @ref union_decl.
26424///
26425/// @param mbr_types the member types of the union.
26426///
26427/// @param data_mbrs the data members of the union.
26428///
26429/// @param member_fns the member functions of the union.
26430union_decl::union_decl(const environment& env, const string& name,
26431 size_t size_in_bits, const location& locus,
26432 visibility vis, member_types& mbr_types,
26433 data_members& data_mbrs, member_functions& member_fns)
26434 : type_or_decl_base(env,
26435 UNION_TYPE
26436 | ABSTRACT_TYPE_BASE
26437 | ABSTRACT_DECL_BASE),
26438 decl_base(env, name, locus, name, vis),
26439 type_base(env, size_in_bits, 0),
26440 class_or_union(env, name, size_in_bits, 0,
26441 locus, vis, mbr_types, data_mbrs, member_fns)
26442{
26444}
26445
26446/// Constructor for the @ref union_decl type.
26447///
26448/// @param env the @ref environment we are operating from.
26449///
26450/// @param name the name of the union type.
26451///
26452/// @param size_in_bits the size of the union, in bits.
26453///
26454/// @param locus the location of the type.
26455///
26456/// @param vis the visibility of instances of @ref union_decl.
26457///
26458/// @param mbr_types the member types of the union.
26459///
26460/// @param data_mbrs the data members of the union.
26461///
26462/// @param member_fns the member functions of the union.
26463///
26464/// @param is_anonymous whether the newly created instance is
26465/// anonymous.
26466union_decl::union_decl(const environment& env, const string& name,
26467 size_t size_in_bits, const location& locus,
26468 visibility vis, member_types& mbr_types,
26469 data_members& data_mbrs, member_functions& member_fns,
26470 bool is_anonymous)
26471 : type_or_decl_base(env,
26472 UNION_TYPE
26473 | ABSTRACT_TYPE_BASE
26474 | ABSTRACT_DECL_BASE),
26475 decl_base(env, name, locus,
26476 // If the class is anonymous then by default it won't
26477 // have a linkage name. Also, the anonymous class does
26478 // have an internal-only unique name that is generally
26479 // not taken into account when comparing classes; such a
26480 // unique internal-only name, when used as a linkage
26481 // name might introduce spurious comparison false
26482 // negatives.
26483 /*linkage_name=*/is_anonymous ? string() : name,
26484 vis),
26485 type_base(env, size_in_bits, 0),
26486 class_or_union(env, name, size_in_bits, 0,
26487 locus, vis, mbr_types, data_mbrs, member_fns)
26488{
26490 set_is_anonymous(is_anonymous);
26491}
26492
26493/// Constructor for the @ref union_decl type.
26494///
26495/// @param env the @ref environment we are operating from.
26496///
26497/// @param name the name of the union type.
26498///
26499/// @param size_in_bits the size of the union, in bits.
26500///
26501/// @param locus the location of the type.
26502///
26503/// @param vis the visibility of instances of @ref union_decl.
26504union_decl::union_decl(const environment& env, const string& name,
26505 size_t size_in_bits, const location& locus,
26506 visibility vis)
26507 : type_or_decl_base(env,
26508 UNION_TYPE
26509 | ABSTRACT_TYPE_BASE
26510 | ABSTRACT_DECL_BASE
26511 | ABSTRACT_SCOPE_TYPE_DECL
26512 | ABSTRACT_SCOPE_DECL),
26513 decl_base(env, name, locus, name, vis),
26514 type_base(env, size_in_bits, 0),
26515 class_or_union(env, name, size_in_bits,
26516 0, locus, vis)
26517{
26519}
26520
26521/// Constructor for the @ref union_decl type.
26522///
26523/// @param env the @ref environment we are operating from.
26524///
26525/// @param name the name of the union type.
26526///
26527/// @param size_in_bits the size of the union, in bits.
26528///
26529/// @param locus the location of the type.
26530///
26531/// @param vis the visibility of instances of @ref union_decl.
26532///
26533/// @param is_anonymous whether the newly created instance is
26534/// anonymous.
26535union_decl::union_decl(const environment& env, const string& name,
26536 size_t size_in_bits, const location& locus,
26537 visibility vis, bool is_anonymous)
26538 : type_or_decl_base(env,
26539 UNION_TYPE
26540 | ABSTRACT_TYPE_BASE
26541 | ABSTRACT_DECL_BASE
26542 | ABSTRACT_SCOPE_TYPE_DECL
26543 | ABSTRACT_SCOPE_DECL),
26544 decl_base(env, name, locus,
26545 // If the class is anonymous then by default it won't
26546 // have a linkage name. Also, the anonymous class does
26547 // have an internal-only unique name that is generally
26548 // not taken into account when comparing classes; such a
26549 // unique internal-only name, when used as a linkage
26550 // name might introduce spurious comparison false
26551 // negatives.
26552 /*linkage_name=*/is_anonymous ? string() : name,
26553 vis),
26554 type_base(env, size_in_bits, 0),
26555 class_or_union(env, name, size_in_bits,
26556 0, locus, vis)
26557{
26559 set_is_anonymous(is_anonymous);
26560}
26561
26562/// Constructor for the @ref union_decl type.
26563///
26564/// @param env the @ref environment we are operating from.
26565///
26566/// @param name the name of the union type.
26567///
26568/// @param is_declaration_only a boolean saying whether the instance
26569/// represents a declaration only, or not.
26570union_decl::union_decl(const environment& env,
26571 const string& name,
26572 bool is_declaration_only)
26573 : type_or_decl_base(env,
26574 UNION_TYPE
26575 | ABSTRACT_TYPE_BASE
26576 | ABSTRACT_DECL_BASE
26577 | ABSTRACT_SCOPE_TYPE_DECL
26578 | ABSTRACT_SCOPE_DECL),
26579 decl_base(env, name, location(), name),
26580 type_base(env, 0, 0),
26581 class_or_union(env, name, is_declaration_only)
26582{
26584}
26585
26586/// Return the hash value of the current IR node.
26587///
26588/// Note that upon the first invocation, this member functions
26589/// computes the hash value and returns it. Subsequent invocations
26590/// just return the hash value that was previously calculated.
26591///
26592/// @return the hash value of the current IR node.
26593hash_t
26595{
26597 return h;
26598}
26599
26600/// Getter of the pretty representation of the current instance of
26601/// @ref union_decl.
26602///
26603/// @param internal set to true if the call is intended to get a
26604/// representation of the decl (or type) for the purpose of canonical
26605/// type comparison. This is mainly used in the function
26606/// type_base::get_canonical_type_for().
26607///
26608/// In other words if the argument for this parameter is true then the
26609/// call is meant for internal use (for technical use inside the
26610/// library itself), false otherwise. If you don't know what this is
26611/// for, then set it to false.
26612///
26613/// @param qualified_name if true, names emitted in the pretty
26614/// representation are fully qualified.
26615///
26616/// @return the pretty representaion for a union_decl.
26617string
26619 bool qualified_name) const
26620{
26621 string repr;
26622 if (get_is_anonymous())
26623 {
26624 if (internal && !get_name().empty())
26625 repr = string("union ") +
26626 get_type_name(this, qualified_name, /*internal=*/true);
26627 else
26629 /*one_line=*/true,
26630 internal);
26631 }
26632 else
26633 {
26634 repr = "union ";
26635 if (qualified_name)
26636 repr += get_qualified_name(internal);
26637 else
26638 repr += get_name();
26639 }
26640
26641 return repr;
26642}
26643
26644/// Comparison operator for @ref union_decl.
26645///
26646/// @param other the instance of @ref union_decl to compare against.
26647///
26648/// @return true iff the current instance of @ref union_decl equals @p
26649/// other.
26650bool
26652{
26653 const union_decl* op = dynamic_cast<const union_decl*>(&other);
26654 if (!op)
26655 return false;
26656 return try_canonical_compare(this, op);
26657}
26658
26659/// Equality operator for union_decl.
26660///
26661/// Re-uses the equality operator that takes a decl_base.
26662///
26663/// @param other the other union_decl to compare against.
26664///
26665/// @return true iff the current instance equals the other one.
26666bool
26668{
26669 const decl_base *o = dynamic_cast<const decl_base*>(&other);
26670 if (!o)
26671 return false;
26672 return *this == *o;
26673}
26674
26675/// Equality operator for union_decl.
26676///
26677/// Re-uses the equality operator that takes a decl_base.
26678///
26679/// @param other the other union_decl to compare against.
26680///
26681/// @return true iff the current instance equals the other one.
26682bool
26684{
26685 const decl_base *o = dynamic_cast<const decl_base*>(&other);
26686 return *this == *o;
26687}
26688
26689/// Comparison operator for @ref union_decl.
26690///
26691/// @param other the instance of @ref union_decl to compare against.
26692///
26693/// @return true iff the current instance of @ref union_decl equals @p
26694/// other.
26695bool
26697{
26698 const decl_base& o = other;
26699 return *this == o;
26700}
26701
26702/// This implements the ir_traversable_base::traverse pure virtual
26703/// function.
26704///
26705/// @param v the visitor used on the current instance and on its
26706/// members.
26707///
26708/// @return true if the entire IR node tree got traversed, false
26709/// otherwise.
26710bool
26712{
26713 if (v.type_node_has_been_visited(this))
26714 return true;
26715
26716 if (visiting())
26717 return true;
26718
26719 if (v.visit_begin(this))
26720 {
26721 visiting(true);
26722 bool stop = false;
26723
26724 if (!stop)
26725 for (data_members::const_iterator i = get_data_members().begin();
26726 i != get_data_members().end();
26727 ++i)
26728 if (!(*i)->traverse(v))
26729 {
26730 stop = true;
26731 break;
26732 }
26733
26734 if (!stop)
26735 for (member_functions::const_iterator i= get_member_functions().begin();
26736 i != get_member_functions().end();
26737 ++i)
26738 if (!(*i)->traverse(v))
26739 {
26740 stop = true;
26741 break;
26742 }
26743
26744 if (!stop)
26745 for (member_types::const_iterator i = get_member_types().begin();
26746 i != get_member_types().end();
26747 ++i)
26748 if (!(*i)->traverse(v))
26749 {
26750 stop = true;
26751 break;
26752 }
26753
26754 if (!stop)
26755 for (member_function_templates::const_iterator i =
26757 i != get_member_function_templates().end();
26758 ++i)
26759 if (!(*i)->traverse(v))
26760 {
26761 stop = true;
26762 break;
26763 }
26764
26765 if (!stop)
26766 for (member_class_templates::const_iterator i =
26768 i != get_member_class_templates().end();
26769 ++i)
26770 if (!(*i)->traverse(v))
26771 {
26772 stop = true;
26773 break;
26774 }
26775 visiting(false);
26776 }
26777
26778 bool result = v.visit_end(this);
26780 return result;
26781}
26782
26783/// Destructor of the @ref union_decl type.
26785{}
26786
26787/// Compares two instances of @ref union_decl.
26788///
26789/// If the two intances are different, set a bitfield to give some
26790/// insight about the kind of differences there are.
26791///
26792/// @param l the first artifact of the comparison.
26793///
26794/// @param r the second artifact of the comparison.
26795///
26796/// @param k a pointer to a bitfield that gives information about the
26797/// kind of changes there are between @p l and @p r. This one is set
26798/// iff @p k is non-null and the function returns false.
26799///
26800/// Please note that setting k to a non-null value does have a
26801/// negative performance impact because even if @p l and @p r are not
26802/// equal, the function keeps up the comparison in order to determine
26803/// the different kinds of ways in which they are different.
26804///
26805/// @return true if @p l equals @p r, false otherwise.
26806bool
26808{
26809
26811
26812 {
26813 // First of all, let's see if these two types haven't already been
26814 // compared. If so, and if the result of the comparison has been
26815 // cached, let's just re-use it, rather than comparing them all
26816 // over again.
26817 bool result = false;
26818 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
26819 ABG_RETURN(result);
26820 }
26821
26822 bool result = equals(static_cast<const class_or_union&>(l),
26823 static_cast<const class_or_union&>(r),
26824 k);
26825
26827}
26828
26829/// Copy a method of a @ref union_decl into a new @ref
26830/// union_decl.
26831///
26832/// @param t the @ref union_decl into which the method is to be copied.
26833///
26834/// @param method the method to copy into @p t.
26835///
26836/// @return the resulting newly copied method.
26837method_decl_sptr
26838copy_member_function(const union_decl_sptr& union_type,
26839 const method_decl_sptr& f)
26840{return copy_member_function(union_type, f.get());}
26841
26842/// Copy a method of a @ref union_decl into a new @ref
26843/// union_decl.
26844///
26845/// @param t the @ref union_decl into which the method is to be copied.
26846///
26847/// @param method the method to copy into @p t.
26848///
26849/// @return the resulting newly copied method.
26850method_decl_sptr
26851copy_member_function(const union_decl_sptr& union_type,
26852 const method_decl* f)
26853{
26854 const class_or_union_sptr t = union_type;
26855 return copy_member_function(t, f);
26856}
26857
26858/// Turn equality of shared_ptr of union_decl into a deep equality;
26859/// that is, make it compare the pointed to objects too.
26860///
26861/// @param l the left-hand-side operand of the operator
26862///
26863/// @param r the right-hand-side operand of the operator.
26864///
26865/// @return true iff @p l equals @p r.
26866bool
26867operator==(const union_decl_sptr& l, const union_decl_sptr& r)
26868{
26869 if (l.get() == r.get())
26870 return true;
26871 if (!!l != !!r)
26872 return false;
26873
26874 return *l == *r;
26875}
26876
26877/// Turn inequality of shared_ptr of union_decl into a deep equality;
26878/// that is, make it compare the pointed to objects too.
26879///
26880/// @param l the left-hand-side operand of the operator
26881///
26882/// @param r the right-hand-side operand of the operator.
26883///
26884/// @return true iff @p l is different from @p r.
26885bool
26886operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
26887{return !operator==(l, r);}
26888// </union_decl>
26889
26890// <template_decl stuff>
26891
26892/// Data type of the private data of the @template_decl type.
26893class template_decl::priv
26894{
26895 friend class template_decl;
26896
26897 std::list<template_parameter_sptr> parms_;
26898public:
26899
26900 priv()
26901 {}
26902}; // end class template_decl::priv
26903
26904/// Add a new template parameter to the current instance of @ref
26905/// template_decl.
26906///
26907/// @param p the new template parameter to add.
26908void
26910{priv_->parms_.push_back(p);}
26911
26912/// Get the list of template parameters of the current instance of
26913/// @ref template_decl.
26914///
26915/// @return the list of template parameters.
26916const std::list<template_parameter_sptr>&
26918{return priv_->parms_;}
26919
26920/// Constructor.
26921///
26922/// @param env the environment we are operating from.
26923///
26924/// @param name the name of the template decl.
26925///
26926/// @param locus the source location where the template declaration is
26927/// defined.
26928///
26929/// @param vis the visibility of the template declaration.
26930template_decl::template_decl(const environment& env,
26931 const string& name,
26932 const location& locus,
26933 visibility vis)
26934 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
26935 decl_base(env, name, locus, /*mangled_name=*/"", vis),
26936 priv_(new priv)
26937{
26939}
26940
26941/// Destructor.
26943{}
26944
26945/// Equality operator.
26946///
26947/// @param o the other instance to compare against.
26948///
26949/// @return true iff @p equals the current instance.
26950bool
26952{
26953 const template_decl* other = dynamic_cast<const template_decl*>(&o);
26954 if (!other)
26955 return false;
26956 return *this == *other;
26957}
26958
26959/// Equality operator.
26960///
26961/// @param o the other instance to compare against.
26962///
26963/// @return true iff @p equals the current instance.
26964bool
26966{
26967 try
26968 {
26969 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
26970 for (t0 = get_template_parameters().begin(),
26971 t1 = o.get_template_parameters().begin();
26972 (t0 != get_template_parameters().end()
26973 && t1 != o.get_template_parameters().end());
26974 ++t0, ++t1)
26975 {
26976 if (**t0 != **t1)
26977 return false;
26978 }
26979
26980 if (t0 != get_template_parameters().end()
26981 || t1 != o.get_template_parameters().end())
26982 return false;
26983
26984 return true;
26985 }
26986 catch(...)
26987 {return false;}
26988}
26989
26990// </template_decl stuff>
26991
26992//<template_parameter>
26993
26994/// The type of the private data of the @ref template_parameter type.
26995class template_parameter::priv
26996{
26997 friend class template_parameter;
26998
26999 unsigned index_;
27000 template_decl_wptr template_decl_;
27001 mutable bool hashing_started_;
27002 mutable bool comparison_started_;
27003
27004 priv();
27005
27006public:
27007
27008 priv(unsigned index, template_decl_sptr enclosing_template_decl)
27009 : index_(index),
27010 template_decl_(enclosing_template_decl),
27011 hashing_started_(),
27012 comparison_started_()
27013 {}
27014}; // end class template_parameter::priv
27015
27016template_parameter::template_parameter(unsigned index,
27017 template_decl_sptr enclosing_template)
27018 : priv_(new priv(index, enclosing_template))
27019 {}
27020
27021unsigned
27022template_parameter::get_index() const
27023{return priv_->index_;}
27024
27026template_parameter::get_enclosing_template_decl() const
27027{return priv_->template_decl_.lock();}
27028
27029
27030bool
27031template_parameter::operator==(const template_parameter& o) const
27032{
27033 if (get_index() != o.get_index())
27034 return false;
27035
27036 if (priv_->comparison_started_)
27037 return true;
27038
27039 bool result = false;
27040
27041 // Avoid inifite loops due to the fact that comparison the enclosing
27042 // template decl might lead to comparing this very same template
27043 // parameter with another one ...
27044 priv_->comparison_started_ = true;
27045
27046 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
27047 ;
27048 else if (get_enclosing_template_decl()
27049 && (*get_enclosing_template_decl()
27050 != *o.get_enclosing_template_decl()))
27051 ;
27052 else
27053 result = true;
27054
27055 priv_->comparison_started_ = false;
27056
27057 return result;
27058}
27059
27060/// Inequality operator.
27061///
27062/// @param other the other instance to compare against.
27063///
27064/// @return true iff the other instance is different from the current
27065/// one.
27066bool
27068{return !operator==(other);}
27069
27070/// Destructor.
27072{}
27073
27074/// The type of the private data of the @ref type_tparameter type.
27075class type_tparameter::priv
27076{
27077 friend class type_tparameter;
27078}; // end class type_tparameter::priv
27079
27080/// Constructor of the @ref type_tparameter type.
27081///
27082/// @param index the index the type template parameter.
27083///
27084/// @param enclosing_tdecl the enclosing template declaration.
27085///
27086/// @param name the name of the template parameter.
27087///
27088/// @param locus the location of the declaration of this type template
27089/// parameter.
27090type_tparameter::type_tparameter(unsigned index,
27091 template_decl_sptr enclosing_tdecl,
27092 const string& name,
27093 const location& locus)
27094 : type_or_decl_base(enclosing_tdecl->get_environment(),
27095 ABSTRACT_DECL_BASE
27096 | ABSTRACT_TYPE_BASE
27097 | BASIC_TYPE),
27098 decl_base(enclosing_tdecl->get_environment(), name, locus),
27099 type_base(enclosing_tdecl->get_environment(), 0, 0),
27100 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
27101 template_parameter(index, enclosing_tdecl),
27102 priv_(new priv)
27103{
27105}
27106
27107/// Equality operator.
27108///
27109/// @param other the other template type parameter to compare against.
27110///
27111/// @return true iff @p other equals the current instance.
27112bool
27114{
27115 if (!type_decl::operator==(other))
27116 return false;
27117
27118 try
27119 {
27120 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27122 }
27123 catch (...)
27124 {return false;}
27125}
27126
27127/// Equality operator.
27128///
27129/// @param other the other template type parameter to compare against.
27130///
27131/// @return true iff @p other equals the current instance.
27132bool
27134{
27135 if (!type_decl::operator==(other))
27136 return false;
27137
27138 try
27139 {
27140 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27142 }
27143 catch (...)
27144 {return false;}
27145}
27146
27147/// Equality operator.
27148///
27149/// @param other the other template type parameter to compare against.
27150///
27151/// @return true iff @p other equals the current instance.
27152bool
27154{
27155 if (!decl_base::operator==(other))
27156 return false;
27157
27158 try
27159 {
27160 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27162 }
27163 catch (...)
27164 {return false;}
27165}
27166
27167/// Equality operator.
27168///
27169/// @param other the other template type parameter to compare against.
27170///
27171/// @return true iff @p other equals the current instance.
27172bool
27174{
27175 try
27176 {
27177 const type_base& o = dynamic_cast<const type_base&>(other);
27178 return *this == o;
27179 }
27180 catch(...)
27181 {return false;}
27182}
27183
27184/// Equality operator.
27185///
27186/// @param other the other template type parameter to compare against.
27187///
27188/// @return true iff @p other equals the current instance.
27189bool
27191{return *this == static_cast<const type_base&>(other);}
27192
27193type_tparameter::~type_tparameter()
27194{}
27195
27196/// The type of the private data of the @ref non_type_tparameter type.
27197class non_type_tparameter::priv
27198{
27199 friend class non_type_tparameter;
27200
27201 type_base_wptr type_;
27202
27203 priv();
27204
27205public:
27206
27207 priv(type_base_sptr type)
27208 : type_(type)
27209 {}
27210}; // end class non_type_tparameter::priv
27211
27212/// The constructor for the @ref non_type_tparameter type.
27213///
27214/// @param index the index of the template parameter.
27215///
27216/// @param enclosing_tdecl the enclosing template declaration that
27217/// holds this parameter parameter.
27218///
27219/// @param name the name of the template parameter.
27220///
27221/// @param type the type of the template parameter.
27222///
27223/// @param locus the location of the declaration of this template
27224/// parameter.
27225non_type_tparameter::non_type_tparameter(unsigned index,
27226 template_decl_sptr enclosing_tdecl,
27227 const string& name,
27228 type_base_sptr type,
27229 const location& locus)
27230 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
27231 decl_base(type->get_environment(), name, locus, ""),
27232 template_parameter(index, enclosing_tdecl),
27233 priv_(new priv(type))
27234{
27236}
27237
27238/// Getter for the type of the template parameter.
27239///
27240/// @return the type of the template parameter.
27241const type_base_sptr
27243{return priv_->type_.lock();}
27244
27245
27246bool
27248{
27249 if (!decl_base::operator==(other))
27250 return false;
27251
27252 try
27253 {
27254 const non_type_tparameter& o =
27255 dynamic_cast<const non_type_tparameter&>(other);
27256 return (template_parameter::operator==(o)
27257 && get_type() == o.get_type());
27258 }
27259 catch(...)
27260 {return false;}
27261}
27262
27263bool
27265{
27266 try
27267 {
27268 const decl_base& o = dynamic_cast<const decl_base&>(other);
27269 return *this == o;
27270 }
27271 catch(...)
27272 {return false;}
27273}
27274
27275non_type_tparameter::~non_type_tparameter()
27276{}
27277
27278// <template_tparameter stuff>
27279
27280/// Type of the private data of the @ref template_tparameter type.
27281class template_tparameter::priv
27282{
27283}; //end class template_tparameter::priv
27284
27285/// Constructor for the @ref template_tparameter.
27286///
27287/// @param index the index of the template parameter.
27288///
27289/// @param enclosing_tdecl the enclosing template declaration.
27290///
27291/// @param name the name of the template parameter.
27292///
27293/// @param locus the location of the declaration of the template
27294/// parameter.
27295template_tparameter::template_tparameter(unsigned index,
27296 template_decl_sptr enclosing_tdecl,
27297 const string& name,
27298 const location& locus)
27299 : type_or_decl_base(enclosing_tdecl->get_environment(),
27300 ABSTRACT_DECL_BASE
27301 | ABSTRACT_TYPE_BASE
27302 | BASIC_TYPE),
27303 decl_base(enclosing_tdecl->get_environment(), name, locus),
27304 type_base(enclosing_tdecl->get_environment(), 0, 0),
27305 type_decl(enclosing_tdecl->get_environment(), name,
27306 0, 0, locus, name, VISIBILITY_DEFAULT),
27307 type_tparameter(index, enclosing_tdecl, name, locus),
27308 template_decl(enclosing_tdecl->get_environment(), name, locus),
27309 priv_(new priv)
27310{
27312}
27313
27314/// Equality operator.
27315///
27316/// @param other the other template parameter to compare against.
27317///
27318/// @return true iff @p other equals the current instance.
27319bool
27321{
27322 try
27323 {
27324 const template_tparameter& o =
27325 dynamic_cast<const template_tparameter&>(other);
27326 return (type_tparameter::operator==(o)
27328 }
27329 catch(...)
27330 {return false;}
27331}
27332
27333/// Equality operator.
27334///
27335/// @param other the other template parameter to compare against.
27336///
27337/// @return true iff @p other equals the current instance.
27338bool
27340{
27341 try
27342 {
27343 const template_tparameter& o =
27344 dynamic_cast<const template_tparameter&>(other);
27345 return (type_tparameter::operator==(o)
27347 }
27348 catch(...)
27349 {return false;}
27350}
27351
27352bool
27354{
27355 try
27356 {
27357 const template_tparameter& other =
27358 dynamic_cast<const template_tparameter&>(o);
27359 return *this == static_cast<const type_base&>(other);
27360 }
27361 catch(...)
27362 {return false;}
27363}
27364
27365bool
27367{
27368 try
27369 {
27370 const template_tparameter& other =
27371 dynamic_cast<const template_tparameter&>(o);
27372 return type_base::operator==(other);
27373 }
27374 catch(...)
27375 {return false;}
27376}
27377
27378template_tparameter::~template_tparameter()
27379{}
27380
27381// </template_tparameter stuff>
27382
27383// <type_composition stuff>
27384
27385/// The type of the private data of the @ref type_composition type.
27386class type_composition::priv
27387{
27388 friend class type_composition;
27389
27390 type_base_wptr type_;
27391
27392 // Forbid this.
27393 priv();
27394
27395public:
27396
27397 priv(type_base_wptr type)
27398 : type_(type)
27399 {}
27400}; //end class type_composition::priv
27401
27402/// Constructor for the @ref type_composition type.
27403///
27404/// @param index the index of the template type composition.
27405///
27406/// @param tdecl the enclosing template parameter that owns the
27407/// composition.
27408///
27409/// @param t the resulting type.
27410type_composition::type_composition(unsigned index,
27411 template_decl_sptr tdecl,
27412 type_base_sptr t)
27413 : type_or_decl_base(tdecl->get_environment(),
27414 ABSTRACT_DECL_BASE),
27415 decl_base(tdecl->get_environment(), "", location()),
27416 template_parameter(index, tdecl),
27417 priv_(new priv(t))
27418{
27420}
27421
27422/// Getter for the resulting composed type.
27423///
27424/// @return the composed type.
27425const type_base_sptr
27427{return priv_->type_.lock();}
27428
27429/// Setter for the resulting composed type.
27430///
27431/// @param t the composed type.
27432void
27434{priv_->type_ = t;}
27435
27436type_composition::~type_composition()
27437{}
27438
27439// </type_composition stuff>
27440
27441//</template_parameter stuff>
27442
27443// <function_template>
27444
27445class function_tdecl::priv
27446{
27447 friend class function_tdecl;
27448
27449 function_decl_sptr pattern_;
27450 binding binding_;
27451
27452 priv();
27453
27454public:
27455
27456 priv(function_decl_sptr pattern, binding bind)
27457 : pattern_(pattern), binding_(bind)
27458 {}
27459
27460 priv(binding bind)
27461 : binding_(bind)
27462 {}
27463}; // end class function_tdecl::priv
27464
27465/// Constructor for a function template declaration.
27466///
27467/// @param env the environment we are operating from.
27468///
27469/// @param locus the location of the declaration.
27470///
27471/// @param vis the visibility of the declaration. This is the
27472/// visibility the functions instantiated from this template are going
27473/// to have.
27474///
27475/// @param bind the binding of the declaration. This is the binding
27476/// the functions instantiated from this template are going to have.
27477function_tdecl::function_tdecl(const environment& env,
27478 const location& locus,
27479 visibility vis,
27480 binding bind)
27481 : type_or_decl_base(env,
27482 ABSTRACT_DECL_BASE
27483 | TEMPLATE_DECL
27484 | ABSTRACT_SCOPE_DECL),
27485 decl_base(env, "", locus, "", vis),
27486 template_decl(env, "", locus, vis),
27487 scope_decl(env, "", locus),
27488 priv_(new priv(bind))
27489{
27491}
27492
27493/// Constructor for a function template declaration.
27494///
27495/// @param pattern the pattern of the template.
27496///
27497/// @param locus the location of the declaration.
27498///
27499/// @param vis the visibility of the declaration. This is the
27500/// visibility the functions instantiated from this template are going
27501/// to have.
27502///
27503/// @param bind the binding of the declaration. This is the binding
27504/// the functions instantiated from this template are going to have.
27505function_tdecl::function_tdecl(function_decl_sptr pattern,
27506 const location& locus,
27507 visibility vis,
27508 binding bind)
27509 : type_or_decl_base(pattern->get_environment(),
27510 ABSTRACT_DECL_BASE
27511 | TEMPLATE_DECL
27512 | ABSTRACT_SCOPE_DECL),
27513 decl_base(pattern->get_environment(), pattern->get_name(), locus,
27514 pattern->get_name(), vis),
27515 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
27516 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
27517 priv_(new priv(pattern, bind))
27518{
27520}
27521
27522/// Set a new pattern to the function template.
27523///
27524/// @param p the new pattern.
27525void
27527{
27528 priv_->pattern_ = p;
27529 add_decl_to_scope(p, this);
27530 set_name(p->get_name());
27531}
27532
27533/// Get the pattern of the function template.
27534///
27535/// @return the pattern.
27538{return priv_->pattern_;}
27539
27540/// Get the binding of the function template.
27541///
27542/// @return the binding
27545{return priv_->binding_;}
27546
27547/// Comparison operator for the @ref function_tdecl type.
27548///
27549/// @param other the other instance of @ref function_tdecl to compare against.
27550///
27551/// @return true iff the two instance are equal.
27552bool
27554{
27555 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
27556 if (o)
27557 return *this == *o;
27558 return false;
27559}
27560
27561/// Comparison operator for the @ref function_tdecl type.
27562///
27563/// @param other the other instance of @ref function_tdecl to compare against.
27564///
27565/// @return true iff the two instance are equal.
27566bool
27568{
27569 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
27570 if (o)
27571 return *this == *o;
27572 return false;
27573}
27574
27575/// Comparison operator for the @ref function_tdecl type.
27576///
27577/// @param o the other instance of @ref function_tdecl to compare against.
27578///
27579/// @return true iff the two instance are equal.
27580bool
27582{
27583 if (!(get_binding() == o.get_binding()
27584 && template_decl::operator==(o)
27585 && scope_decl::operator==(o)
27586 && !!get_pattern() == !!o.get_pattern()))
27587 return false;
27588
27589 if (get_pattern())
27590 return (*get_pattern() == *o.get_pattern());
27591
27592 return true;
27593}
27594
27595/// This implements the ir_traversable_base::traverse pure virtual
27596/// function.
27597///
27598/// @param v the visitor used on the current instance and on the
27599/// function pattern of the template.
27600///
27601/// @return true if the entire IR node tree got traversed, false
27602/// otherwise.
27603bool
27605{
27606 if (visiting())
27607 return true;
27608
27609 if (!v.visit_begin(this))
27610 {
27611 visiting(true);
27612 if (get_pattern())
27613 get_pattern()->traverse(v);
27614 visiting(false);
27615 }
27616 return v.visit_end(this);
27617}
27618
27619function_tdecl::~function_tdecl()
27620{}
27621
27622// </function_template>
27623
27624// <class template>
27625
27626/// Type of the private data of the the @ref class_tdecl type.
27627class class_tdecl::priv
27628{
27629 friend class class_tdecl;
27630 class_decl_sptr pattern_;
27631
27632public:
27633
27634 priv()
27635 {}
27636
27637 priv(class_decl_sptr pattern)
27638 : pattern_(pattern)
27639 {}
27640}; // end class class_tdecl::priv
27641
27642/// Constructor for the @ref class_tdecl type.
27643///
27644/// @param env the environment we are operating from.
27645///
27646/// @param locus the location of the declaration of the class_tdecl
27647/// type.
27648///
27649/// @param vis the visibility of the instance of class instantiated
27650/// from this template.
27651class_tdecl::class_tdecl(const environment& env,
27652 const location& locus,
27653 visibility vis)
27654 : type_or_decl_base(env,
27655 ABSTRACT_DECL_BASE
27656 | TEMPLATE_DECL
27657 | ABSTRACT_SCOPE_DECL),
27658 decl_base(env, "", locus, "", vis),
27659 template_decl(env, "", locus, vis),
27660 scope_decl(env, "", locus),
27661 priv_(new priv)
27662{
27664}
27665
27666/// Constructor for the @ref class_tdecl type.
27667///
27668/// @param pattern The details of the class template. This must NOT be a
27669/// null pointer. If you really this to be null, please use the
27670/// constructor above instead.
27671///
27672/// @param locus the source location of the declaration of the type.
27673///
27674/// @param vis the visibility of the instances of class instantiated
27675/// from this template.
27676class_tdecl::class_tdecl(class_decl_sptr pattern,
27677 const location& locus,
27678 visibility vis)
27679 : type_or_decl_base(pattern->get_environment(),
27680 ABSTRACT_DECL_BASE
27681 | TEMPLATE_DECL
27682 | ABSTRACT_SCOPE_DECL),
27683 decl_base(pattern->get_environment(), pattern->get_name(),
27684 locus, pattern->get_name(), vis),
27685 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
27686 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
27687 priv_(new priv(pattern))
27688{
27690}
27691
27692/// Setter of the pattern of the template.
27693///
27694/// @param p the new template.
27695void
27697{
27698 priv_->pattern_ = p;
27699 add_decl_to_scope(p, this);
27700 set_name(p->get_name());
27701}
27702
27703/// Getter of the pattern of the template.
27704///
27705/// @return p the new template.
27708{return priv_->pattern_;}
27709
27710bool
27712{
27713 try
27714 {
27715 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
27716
27717 if (!(template_decl::operator==(o)
27718 && scope_decl::operator==(o)
27719 && !!get_pattern() == !!o.get_pattern()))
27720 return false;
27721
27722 if (!get_pattern() || !o.get_pattern())
27723 return true;
27724
27725 return get_pattern()->decl_base::operator==(*o.get_pattern());
27726 }
27727 catch(...) {}
27728 return false;
27729}
27730
27731bool
27733{
27734 try
27735 {
27736 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
27737 return *this == static_cast<const decl_base&>(o);
27738 }
27739 catch(...)
27740 {return false;}
27741}
27742
27743bool
27745{return *this == static_cast<const decl_base&>(o);}
27746
27747/// This implements the ir_traversable_base::traverse pure virtual
27748/// function.
27749///
27750/// @param v the visitor used on the current instance and on the class
27751/// pattern of the template.
27752///
27753/// @return true if the entire IR node tree got traversed, false
27754/// otherwise.
27755bool
27757{
27758 if (visiting())
27759 return true;
27760
27761 if (v.visit_begin(this))
27762 {
27763 visiting(true);
27764 if (class_decl_sptr pattern = get_pattern())
27765 pattern->traverse(v);
27766 visiting(false);
27767 }
27768 return v.visit_end(this);
27769}
27770
27771class_tdecl::~class_tdecl()
27772{}
27773
27774/// This visitor checks if a given type as non-canonicalized sub
27775/// types.
27776class non_canonicalized_subtype_detector : public ir::ir_node_visitor
27777{
27778 type_base* type_;
27779 type_base* has_non_canonical_type_;
27780
27781private:
27782 non_canonicalized_subtype_detector();
27783
27784public:
27785 non_canonicalized_subtype_detector(type_base* type)
27786 : type_(type),
27787 has_non_canonical_type_()
27788 {}
27789
27790 /// Return true if the visitor detected that there is a
27791 /// non-canonicalized sub-type.
27792 ///
27793 /// @return true if the visitor detected that there is a
27794 /// non-canonicalized sub-type.
27795 type_base*
27796 has_non_canonical_type() const
27797 {return has_non_canonical_type_;}
27798
27799 /// The intent of this visitor handler is to avoid looking into
27800 /// sub-types of member functions of the type we are traversing.
27801 bool
27802 visit_begin(function_decl* f)
27803 {
27804 // Do not look at sub-types of non-virtual member functions.
27805 if (is_member_function(f)
27807 return false;
27808 return true;
27809 }
27810
27811 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
27812 /// the 'has_non_canonical_type' flag. And in any case, when
27813 /// visiting a sub-type, do not visit its children nodes. So this
27814 /// function only goes to the level below the level of the top-most
27815 /// type.
27816 ///
27817 /// @return true if we are at the same level as the top-most type,
27818 /// otherwise return false.
27819 bool
27820 visit_begin(type_base* t)
27821 {
27822 if (t != type_)
27823 {
27824 if (!t->get_canonical_type())
27825 // We are looking a sub-type of 'type_' which has no
27826 // canonical type. So tada! we found one! Get out right
27827 // now with the trophy.
27828 has_non_canonical_type_ = t;
27829
27830 return false;
27831 }
27832 return true;
27833 }
27834
27835 /// When we are done visiting a sub-type, if it's been flagged as
27836 /// been non-canonicalized, then stop the traversing.
27837 ///
27838 /// Otherwise, keep going.
27839 ///
27840 /// @return false iff the sub-type that has been visited is
27841 /// non-canonicalized.
27842 bool
27843 visit_end(type_base* )
27844 {
27845 if (has_non_canonical_type_)
27846 return false;
27847 return true;
27848 }
27849}; //end class non_canonicalized_subtype_detector
27850
27851/// Test if a type has sub-types that are non-canonicalized.
27852///
27853/// @param t the type which sub-types to consider.
27854///
27855/// @return true if a type has sub-types that are non-canonicalized.
27856type_base*
27858{
27859 if (!t)
27860 return 0;
27861
27862 non_canonicalized_subtype_detector v(t.get());
27863 t->traverse(v);
27864 return v.has_non_canonical_type();
27865}
27866
27867/// Tests if the change of a given type effectively comes from just
27868/// its sub-types. That is, if the type has changed but its type name
27869/// hasn't changed, then the change of the type mostly likely is a
27870/// sub-type change.
27871///
27872/// @param t_v1 the first version of the type.
27873///
27874/// @param t_v2 the second version of the type.
27875///
27876/// @return true iff the type changed and the change is about its
27877/// sub-types.
27878bool
27879type_has_sub_type_changes(const type_base_sptr t_v1,
27880 const type_base_sptr t_v2)
27881{
27882 type_base_sptr t1 = strip_typedef(t_v1);
27883 type_base_sptr t2 = strip_typedef(t_v2);
27884
27885 string repr1 = get_pretty_representation(t1, /*internal=*/false),
27886 repr2 = get_pretty_representation(t2, /*internal=*/false);
27887 return (t1 != t2 && repr1 == repr2);
27888}
27889
27890/// Make sure that the life time of a given (smart pointer to a) type
27891/// is the same as the life time of the libabigail library.
27892///
27893/// @param t the type to consider.
27894void
27895keep_type_alive(type_base_sptr t)
27896{
27897 const environment& env = t->get_environment();
27898 env.priv_->extra_live_types_.push_back(t);
27899}
27900
27901/// Hash an ABI artifact that is either a type or a decl.
27902///
27903/// This function intends to provides the fastest possible hashing for
27904/// types and decls, while being completely correct.
27905///
27906/// Note that if the artifact is a type and if it has a canonical
27907/// type, the hash value is going to be the pointer value of the
27908/// canonical type. Otherwise, this function computes a hash value
27909/// for the type by recursively walking the type members. This last
27910/// code path is possibly *very* slow and should only be used when
27911/// only handful of types are going to be hashed.
27912///
27913/// If the artifact is a decl, then a combination of the hash of its
27914/// type and the hash of the other properties of the decl is computed.
27915///
27916/// @param tod the type or decl to hash.
27917///
27918/// @return the resulting hash value.
27919size_t
27921{
27922 hash_t result = 0;
27923
27924 if (tod == 0)
27925 ;
27926 else if (const type_base* t = is_type(tod))
27927 result = hash_type(t);
27928 else if (const decl_base* d = is_decl(tod))
27929 {
27930 if (const scope_decl* s = is_scope_decl(d))
27931 {
27932 if (const global_scope* g = is_global_scope(s))
27933 result = reinterpret_cast<size_t>(g);
27934 else
27935 result = reinterpret_cast<size_t>(s);
27936 }
27937 else if (var_decl* v = is_var_decl(d))
27938 {
27939 ABG_ASSERT(v->get_type());
27940 hash_t h = hash_type_or_decl(v->get_type());
27941 string repr = v->get_pretty_representation(/*internal=*/true);
27942 std::hash<string> hash_string;
27943 h = hashing::combine_hashes(h, hash_string(repr));
27944 result = h;
27945 }
27946 else if (function_decl* f = is_function_decl(d))
27947 {
27948 ABG_ASSERT(f->get_type());
27949 hash_t h = hash_type_or_decl(f->get_type());
27950 string repr = f->get_pretty_representation(/*internal=*/true);
27951 std::hash<string> hash_string;
27952 h = hashing::combine_hashes(h, hash_string(repr));
27953 result = h;
27954 }
27956 {
27957 type_base_sptr parm_type = p->get_type();
27958 ABG_ASSERT(parm_type);
27959 std::hash<bool> hash_bool;
27960 std::hash<unsigned> hash_unsigned;
27961 hash_t h = hash_type_or_decl(parm_type);
27962 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
27963 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
27964 result = h;
27965 }
27966 else if (class_decl::base_spec *bs = is_class_base_spec(d))
27967 {
27968 member_base::hash hash_member;
27969 std::hash<size_t> hash_size;
27970 std::hash<bool> hash_bool;
27971 type_base_sptr type = bs->get_base_class();
27972 hash_t h = hash_type_or_decl(type);
27973 h = hashing::combine_hashes(h, hash_member(*bs));
27974 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
27975 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
27976 result = h;
27977 }
27978 else
27979 // This is a *really* *SLOW* path. If it shows up in a
27980 // performance profile, I bet it'd be a good idea to try to
27981 // avoid it altogether.
27982 // TODO: recode this function or get rid of it altogethe.
27983 abort();
27984 }
27985 else
27986 // We should never get here.
27987 abort();
27988 return *result;
27989}
27990
27991/// Hash an ABI artifact that is a type.
27992///
27993/// This function intends to provides the fastest possible hashing for
27994/// types while being completely correct.
27995///
27996/// Note that if the type artifact has a canonical type, the hash
27997/// value is going to be the pointer value of the canonical type.
27998/// Otherwise, this function computes a hash value for the type by
27999/// recursively walking the type members. This last code path is
28000/// possibly *very* slow and should only be used when only handful of
28001/// types are going to be hashed.
28002///
28003/// @param t the type or decl to hash.
28004///
28005/// @return the resulting hash value.
28006size_t
28008{return hash_as_canonical_type_or_constant(t);}
28009
28010/// Hash an ABI artifact that is either a type of a decl.
28011///
28012/// @param tod the ABI artifact to hash.
28013///
28014/// @return the hash value of the ABI artifact.
28015size_t
28017{return hash_type_or_decl(tod.get());}
28018
28019/// Get the hash value associated to an IR node.
28020///
28021/// Unlike type_or_decl_base::hash_value(), if the IR has no
28022/// associated hash value, an empty hash value is returned.
28023///
28024/// @param artefact the IR node to consider.
28025///
28026/// @return the hash value stored on the IR node or an empty hash if
28027/// no hash value is stored in the @p artefact.
28028hash_t
28030{
28031 const type_or_decl_base* artefactp = &artefact;
28032 if (decl_base *d = is_decl(artefactp))
28033 {
28035 if (d->type_or_decl_base::priv_->get_hashing_state()
28037 return d->type_or_decl_base::priv_->hash_value_;
28038 }
28039 else if (artefact.priv_->get_hashing_state() == hashing::HASHING_FINISHED_STATE)
28040 return artefact.priv_->hash_value_;
28041
28042 return hash_t();
28043}
28044
28045/// Test if a given type is allowed to be non canonicalized
28046///
28047/// This is a subroutine of hash_as_canonical_type_or_constant.
28048///
28049/// For now, the only types allowed to be non canonicalized in the
28050/// system are (typedefs & pointers to) decl-only class/union, the
28051/// void type and variadic parameter types.
28052///
28053/// @return true iff @p t is a one of the only types allowed to be
28054/// non-canonicalized in the system.
28055bool
28057{
28058 if (!t)
28059 return true;
28060
28061 return (// The IR nodes for the types below are unique across the
28062 // entire ABI corpus. Thus, no need to canonicalize them.
28063 // Maybe we could say otherwise and canonicalize them once
28064 // for all so that they can be removed from here.
28066
28067 // An IR node for the types below can be equal to several
28068 // other types (i.e, a decl-only type t equals a fully
28069 // defined type of the same name in ODR-supported
28070 // languages). Hence, they can't be given a canonical type.
28071 //
28072 // TODO: Maybe add a mode that would detect ODR violations
28073 // that would make a decl-only type co-exists with several
28074 // different definitions of the type in the ABI corpus.
28077 /*look_through_decl_only=*/true)
28079
28080}
28081
28082/// Test if a type is unique in the entire environment.
28083///
28084/// Examples of unique types are void, void* and variadic parameter
28085/// types.
28086///
28087/// @param t the type to test for.
28088///
28089/// @return true iff the type @p t is unique in the entire
28090/// environment.
28091bool
28092is_unique_type(const type_base_sptr& t)
28093{return is_unique_type(t.get());}
28094
28095/// Test if a type is unique in the entire environment.
28096///
28097/// Examples of unique types are void, void* and variadic parameter
28098/// types.
28099///
28100/// @param t the type to test for.
28101///
28102/// @return true iff the type @p t is unique in the entire
28103/// environment.
28104bool
28106{
28107 if (!t)
28108 return false;
28109
28110 const environment& env = t->get_environment();
28111 return (env.is_void_type(t)
28112 || env.is_void_pointer_type(t)
28113 || env.is_variadic_parameter_type(t));
28114}
28115
28116/// For a given type, return its exemplar type.
28117///
28118/// For a given type, its exemplar type is either its canonical type
28119/// or the canonical type of the definition type of a given
28120/// declaration-only type. If the neither of those two types exist,
28121/// then the exemplar type is the given type itself.
28122///
28123/// @param type the input to consider.
28124///
28125/// @return the exemplar type.
28126type_base*
28128{
28129 if (decl_base * decl = is_decl(type))
28130 {
28131 // Make sure we get the real definition of a decl-only type.
28132 decl = look_through_decl_only(decl);
28133 type = is_type(decl);
28134 ABG_ASSERT(type);
28135 }
28136 type_base *exemplar = type->get_naked_canonical_type();
28137 if (!exemplar)
28138 {
28139 // The type has no canonical type. Let's be sure that it's one
28140 // of those rare types that are allowed to be non canonicalized
28141 // in the system.
28142 exemplar = const_cast<type_base*>(type);
28144 }
28145 return exemplar;
28146}
28147
28148/// Test if a given type is allowed to be non canonicalized
28149///
28150/// This is a subroutine of hash_as_canonical_type_or_constant.
28151///
28152/// For now, the only types allowed to be non canonicalized in the
28153/// system are decl-only class/union and the void type.
28154///
28155/// @return true iff @p t is a one of the only types allowed to be
28156/// non-canonicalized in the system.
28157bool
28158is_non_canonicalized_type(const type_base_sptr& t)
28159{return is_non_canonicalized_type(t.get());}
28160
28161/// Hash a type by either returning the pointer value of its canonical
28162/// type or by returning a constant if the type doesn't have a
28163/// canonical type.
28164///
28165/// This is a subroutine of hash_type.
28166///
28167/// @param t the type to consider.
28168///
28169/// @return the hash value.
28170static size_t
28171hash_as_canonical_type_or_constant(const type_base *t)
28172{
28173 type_base *canonical_type = 0;
28174
28175 if (t)
28176 canonical_type = t->get_naked_canonical_type();
28177
28178 if (!canonical_type)
28179 {
28180 // If the type doesn't have a canonical type, maybe it's because
28181 // it's a declaration-only type? If that's the case, let's try
28182 // to get the canonical type of the definition of this
28183 // declaration.
28184 decl_base *decl = is_decl(t);
28185 if (decl
28186 && decl->get_is_declaration_only()
28188 {
28189 type_base *definition =
28191 ABG_ASSERT(definition);
28192 canonical_type = definition->get_naked_canonical_type();
28193 }
28194 }
28195
28196 if (canonical_type)
28197 return reinterpret_cast<size_t>(canonical_type);
28198
28199 // If we reached this point, it means we are seeing a
28200 // non-canonicalized type. It must be a decl-only class or a void
28201 // type, otherwise it means that for some weird reason, the type
28202 // hasn't been canonicalized. It should be!
28204
28205 return 0xDEADBABE;
28206}
28207
28208/// Test if the pretty representation of a given @ref function_decl is
28209/// lexicographically less then the pretty representation of another
28210/// @ref function_decl.
28211///
28212/// @param f the first @ref function_decl to consider for comparison.
28213///
28214/// @param s the second @ref function_decl to consider for comparison.
28215///
28216/// @return true iff the pretty representation of @p f is
28217/// lexicographically less than the pretty representation of @p s.
28218bool
28220{
28223
28224 if (fr != sr)
28225 return fr < sr;
28226
28227 fr = f.get_pretty_representation(/*internal=*/true),
28228 sr = s.get_pretty_representation(/*internal=*/true);
28229
28230 if (fr != sr)
28231 return fr < sr;
28232
28233 if (f.get_symbol())
28234 fr = f.get_symbol()->get_id_string();
28235 else if (!f.get_linkage_name().empty())
28236 fr = f.get_linkage_name();
28237
28238 if (s.get_symbol())
28239 sr = s.get_symbol()->get_id_string();
28240 else if (!s.get_linkage_name().empty())
28241 sr = s.get_linkage_name();
28242
28243 return fr < sr;
28244}
28245
28246/// Test if two types have similar structures, even though they are
28247/// (or can be) different.
28248///
28249/// const and volatile qualifiers are completely ignored.
28250///
28251/// typedef are resolved to their definitions; their names are ignored.
28252///
28253/// Two indirect types (pointers or references) have similar structure
28254/// if their underlying types are of the same kind and have the same
28255/// name. In the indirect types case, the size of the underlying type
28256/// does not matter.
28257///
28258/// Two direct types (i.e, non indirect) have a similar structure if
28259/// they have the same kind, name and size. Two class types have
28260/// similar structure if they have the same name, size, and if the
28261/// types of their data members have similar types.
28262///
28263/// @param first the first type to consider.
28264///
28265/// @param second the second type to consider.
28266///
28267/// @param indirect_type whether to do an indirect comparison
28268///
28269/// @return true iff @p first and @p second have similar structures.
28270bool
28271types_have_similar_structure(const type_base_sptr& first,
28272 const type_base_sptr& second,
28273 bool indirect_type)
28274{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
28275
28276/// Test if two types have similar structures, even though they are
28277/// (or can be) different.
28278///
28279/// const and volatile qualifiers are completely ignored.
28280///
28281/// typedef are resolved to their definitions; their names are ignored.
28282///
28283/// Two indirect types (pointers, references or arrays) have similar
28284/// structure if their underlying types are of the same kind and have
28285/// the same name. In the indirect types case, the size of the
28286/// underlying type does not matter.
28287///
28288/// Two direct types (i.e, non indirect) have a similar structure if
28289/// they have the same kind, name and size. Two class types have
28290/// similar structure if they have the same name, size, and if the
28291/// types of their data members have similar types.
28292///
28293/// @param first the first type to consider.
28294///
28295/// @param second the second type to consider.
28296///
28297/// @param indirect_type if true, then consider @p first and @p
28298/// second as being underlying types of indirect types. Meaning that
28299/// their size does not matter.
28300///
28301/// @return true iff @p first and @p second have similar structures.
28302bool
28304 const type_base* second,
28305 bool indirect_type)
28306{
28307 if (!!first != !!second)
28308 return false;
28309
28310 if (!first)
28311 return false;
28312
28313 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
28314 first = peel_qualified_or_typedef_type(first);
28315 second = peel_qualified_or_typedef_type(second);
28316
28317 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
28318 // various ty2 below cannot be null.
28319 if (typeid(*first) != typeid(*second))
28320 return false;
28321
28322 // Peel off matching pointers.
28323 if (const pointer_type_def* ty1 = is_pointer_type(first))
28324 {
28325 const pointer_type_def* ty2 = is_pointer_type(second);
28326 return types_have_similar_structure(ty1->get_pointed_to_type(),
28327 ty2->get_pointed_to_type(),
28328 /*indirect_type=*/true);
28329 }
28330
28331 // Peel off matching references.
28332 if (const reference_type_def* ty1 = is_reference_type(first))
28333 {
28334 const reference_type_def* ty2 = is_reference_type(second);
28335 if (ty1->is_lvalue() != ty2->is_lvalue())
28336 return false;
28337 return types_have_similar_structure(ty1->get_pointed_to_type(),
28338 ty2->get_pointed_to_type(),
28339 /*indirect_type=*/true);
28340 }
28341
28342 // Peel off matching pointer-to-member types.
28343 if (const ptr_to_mbr_type* ty1 = is_ptr_to_mbr_type(first))
28344 {
28345 const ptr_to_mbr_type* ty2 = is_ptr_to_mbr_type(second);
28346 return (types_have_similar_structure(ty1->get_member_type(),
28347 ty2->get_member_type(),
28348 /*indirect_type=*/true)
28349 && types_have_similar_structure(ty1->get_containing_type(),
28350 ty2->get_containing_type(),
28351 /*indirect_type=*/true));
28352 }
28353
28354 if (const type_decl* ty1 = is_type_decl(first))
28355 {
28356 const type_decl* ty2 = is_type_decl(second);
28357 if (!indirect_type)
28358 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28359 return false;
28360
28361 return ty1->get_name() == ty2->get_name();
28362 }
28363
28364 if (const enum_type_decl* ty1 = is_enum_type(first))
28365 {
28366 const enum_type_decl* ty2 = is_enum_type(second);
28367 if (!indirect_type)
28368 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28369 return false;
28370
28371 return (get_name(ty1->get_underlying_type())
28372 == get_name(ty2->get_underlying_type()));
28373 }
28374
28375 if (const class_decl* ty1 = is_class_type(first))
28376 {
28377 const class_decl* ty2 = is_class_type(second);
28378 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28379 && ty1->get_name() != ty2->get_name())
28380 return false;
28381
28382 if (!indirect_type)
28383 {
28384 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
28385 || (ty1->get_non_static_data_members().size()
28386 != ty2->get_non_static_data_members().size()))
28387 return false;
28388
28389 for (class_or_union::data_members::const_iterator
28390 i = ty1->get_non_static_data_members().begin(),
28391 j = ty2->get_non_static_data_members().begin();
28392 (i != ty1->get_non_static_data_members().end()
28393 && j != ty2->get_non_static_data_members().end());
28394 ++i, ++j)
28395 {
28396 var_decl_sptr dm1 = *i;
28397 var_decl_sptr dm2 = *j;
28398 if (!types_have_similar_structure(dm1->get_type().get(),
28399 dm2->get_type().get(),
28400 indirect_type))
28401 return false;
28402 }
28403 }
28404
28405 return true;
28406 }
28407
28408 if (const union_decl* ty1 = is_union_type(first))
28409 {
28410 const union_decl* ty2 = is_union_type(second);
28411 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28412 && ty1->get_name() != ty2->get_name())
28413 return false;
28414
28415 if (!indirect_type)
28416 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
28417
28418 return true;
28419 }
28420
28421 if (const array_type_def* ty1 = is_array_type(first))
28422 {
28423 const array_type_def* ty2 = is_array_type(second);
28424 // TODO: Handle int[5][2] vs int[2][5] better.
28425 if (!indirect_type)
28426 {
28427 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
28428 || ty1->get_dimension_count() != ty2->get_dimension_count())
28429 return false;
28430 }
28431
28432 if (!types_have_similar_structure(ty1->get_element_type(),
28433 ty2->get_element_type(),
28434 /*indirect_type=*/true))
28435 return false;
28436
28437 return true;
28438 }
28439
28440 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
28441 {
28443 if (ty1->get_upper_bound() != ty2->get_upper_bound()
28444 || ty1->get_lower_bound() != ty2->get_lower_bound()
28445 || ty1->get_language() != ty2->get_language()
28446 || !types_have_similar_structure(ty1->get_underlying_type(),
28447 ty2->get_underlying_type(),
28448 indirect_type))
28449 return false;
28450
28451 return true;
28452 }
28453
28454 if (const function_type* ty1 = is_function_type(first))
28455 {
28456 const function_type* ty2 = is_function_type(second);
28457 if (!types_have_similar_structure(ty1->get_return_type(),
28458 ty2->get_return_type(),
28459 indirect_type))
28460 return false;
28461
28462 if (ty1->get_parameters().size() != ty2->get_parameters().size())
28463 return false;
28464
28465 for (function_type::parameters::const_iterator
28466 i = ty1->get_parameters().begin(),
28467 j = ty2->get_parameters().begin();
28468 (i != ty1->get_parameters().end()
28469 && j != ty2->get_parameters().end());
28470 ++i, ++j)
28471 if (!types_have_similar_structure((*i)->get_type(),
28472 (*j)->get_type(),
28473 indirect_type))
28474 return false;
28475
28476 return true;
28477 }
28478
28479 // All kinds of type should have been handled at this point.
28481
28482 return false;
28483}
28484
28485/// Look for a data member of a given class, struct or union type and
28486/// return it.
28487///
28488/// The data member is designated by its name.
28489///
28490/// @param type the class, struct or union type to consider.
28491///
28492/// @param dm_name the name of the data member to lookup.
28493///
28494/// @return the data member iff it was found in @type or NULL if no
28495/// data member with that name was found.
28496const var_decl*
28498 const char* dm_name)
28499
28500{
28502 if (!cou)
28503 return 0;
28504
28505 return cou->find_data_member(dm_name).get();
28506}
28507
28508/// Look for a data member of a given class, struct or union type and
28509/// return it.
28510///
28511/// The data member is designated by its name.
28512///
28513/// @param type the class, struct or union type to consider.
28514///
28515/// @param dm the data member to lookup.
28516///
28517/// @return the data member iff it was found in @type or NULL if no
28518/// data member with that name was found.
28519const var_decl_sptr
28520lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
28521{
28522 class_or_union_sptr cou = is_class_or_union_type(type);
28523 if (!cou)
28524 return var_decl_sptr();
28525
28526 return cou->find_data_member(dm);
28527}
28528
28529/// Get the function parameter designated by its index.
28530///
28531/// Note that the first function parameter has index 0.
28532///
28533/// @param fun the function to consider.
28534///
28535/// @param parm_index the index of the function parameter to get.
28536///
28537/// @return the function parameter designated by its index, of NULL if
28538/// no function parameter with that index was found.
28541 unsigned parm_index)
28542{
28544 if (!fn)
28545 return 0;
28546
28547 const function_decl::parameters &parms = fn->get_type()->get_parameters();
28548 if (parms.size() <= parm_index)
28549 return 0;
28550
28551 return parms[parm_index].get();
28552}
28553
28554/// Build the internal name of the underlying type of an enum.
28555///
28556/// @param base_name the (unqualified) name of the enum the underlying
28557/// type is destined to.
28558///
28559/// @param is_anonymous true if the underlying type of the enum is to
28560/// be anonymous.
28561string
28563 bool is_anonymous,
28564 uint64_t size)
28565{
28566 std::ostringstream o;
28567
28568 if (is_anonymous)
28569 o << "unnamed-enum";
28570 else
28571 o << "enum-" << base_name;
28572
28573 o << "-underlying-type-" << size;
28574
28575 return o.str();
28576}
28577
28578/// Find the first data member of a class or union which name matches
28579/// a regular expression.
28580///
28581/// @param t the class or union to consider.
28582///
28583/// @param r the regular expression to consider.
28584///
28585/// @return the data member matched by @p r or nil if none was found.
28588 const regex::regex_t_sptr& r)
28589{
28590 for (auto data_member : t.get_data_members())
28591 {
28592 if (regex::match(r, data_member->get_name()))
28593 return data_member;
28594 }
28595
28596 return var_decl_sptr();
28597}
28598
28599/// Find the last data member of a class or union which name matches
28600/// a regular expression.
28601///
28602/// @param t the class or union to consider.
28603///
28604/// @param r the regular expression to consider.
28605///
28606/// @return the data member matched by @p r or nil if none was found.
28609 const regex::regex_t_sptr& regex)
28610{
28611 auto d = t.get_data_members().rbegin();
28612 auto e = t.get_data_members().rend();
28613 for (; d != e; ++d)
28614 {
28615 if (regex::match(regex, (*d)->get_name()))
28616 return *d;
28617 }
28618
28619 return var_decl_sptr();
28620}
28621
28622/// Emit the pretty representation of the parameters of a function
28623/// type.
28624///
28625/// @param fn_type the function type to consider.
28626///
28627/// @param o the output stream to emit the pretty representation to.
28628///
28629/// @param qualified if true, emit fully qualified names.
28630///
28631/// @param internal if true, then the result is to be used for the
28632/// purpose of type canonicalization.
28633static void
28634stream_pretty_representation_of_fn_parms(const function_type& fn_type,
28635 ostream& o, bool qualified,
28636 bool internal)
28637{
28638 o << "(";
28639 if (fn_type.get_parameters().empty())
28640 o << "void";
28641 else
28642 {
28643 type_base_sptr type;
28644 auto end = fn_type.get_parameters().end();
28645 auto first_parm = fn_type.get_first_non_implicit_parm();
28647 const environment& env = fn_type.get_environment();
28648 for (auto i = fn_type.get_first_non_implicit_parm(); i != end; ++i)
28649 {
28650 if (i != first_parm)
28651 o << ", ";
28652 parm = *i;
28653 type = parm->get_type();
28654 if (env.is_variadic_parameter_type(type))
28655 o << "...";
28656 else
28657 o << get_type_name(type, qualified, internal);
28658 }
28659 }
28660 o << ")";
28661}
28662
28663/// When constructing the name of a pointer to function type, add the
28664/// return type to the left of the existing type identifier, and the
28665/// parameters declarator to the right.
28666///
28667/// This function considers the name of the type as an expression.
28668///
28669/// The resulting type expr is going to be made of three parts:
28670/// left_expr inner_expr right_expr.
28671///
28672/// Suppose we want to build the type expression representing:
28673///
28674/// "an array of pointer to function taking a char parameter and
28675/// returning an int".
28676///
28677/// It's going to look like:
28678///
28679/// int(*a[])(char);
28680///
28681/// Suppose the caller of this function started to emit the inner
28682/// "a[]" part of the expression already. It thus calls this
28683/// function with that input "a[]" part. We consider that "a[]" as
28684/// the "type identifier".
28685///
28686/// So the inner_expr is going to be "(*a[])".
28687///
28688/// The left_expr part is "int". The right_expr part is "(char)".
28689///
28690/// In other words, this function adds the left_expr and right_expr to
28691/// the inner_expr. left_expr and right_expr are called "outer
28692/// pointer to function type expression".
28693///
28694/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28695/// array_declaration_name()
28696///
28697/// @param p the pointer to function type to consider.
28698///
28699/// @param input the type-id to use as the inner expression of the
28700/// overall pointer-to-function type expression
28701///
28702/// @param qualified if true then use qualified names in the resulting
28703/// type name.
28704///
28705/// @param internal if true then the resulting type name is going to
28706/// be used for type canonicalization purposes.
28707///
28708/// @return the name of the pointer to function type.
28709static string
28710add_outer_pointer_to_fn_type_expr(const type_base* p,
28711 const string& input,
28712 bool qualified, bool internal)
28713{
28714 if (!p)
28715 return "";
28716
28717 function_type_sptr pointed_to_fn;
28718 string star_or_ref;
28719
28720 if (const pointer_type_def* ptr = is_pointer_type(p))
28721 {
28722 pointed_to_fn = is_function_type(ptr->get_pointed_to_type());
28723 star_or_ref= "*";
28724 }
28725 else if (const reference_type_def* ref = is_reference_type(p))
28726 {
28727 star_or_ref = "&";
28728 pointed_to_fn = is_function_type(ref->get_pointed_to_type());
28729 }
28730
28731 if (!pointed_to_fn)
28732 return "";
28733
28734 if (pointed_to_fn->priv_->is_pretty_printing())
28735 // We have just detected a cycle while walking the sub-tree of
28736 // this function type for the purpose of printing its
28737 // representation. We need to get out of here pronto or else
28738 // we'll be spinning endlessly.
28739 return "";
28740
28741 // Let's mark thie function type to signify that we started walking
28742 // its subtree. This is to detect potential cycles and avoid
28743 // looping endlessly.
28744 pointed_to_fn->priv_->set_is_pretty_printing();
28745
28746 std::ostringstream left, right, inner;
28747
28748 inner << "(" << star_or_ref << input << ")";
28749
28750 type_base_sptr type;
28751 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
28752 qualified, internal);
28753
28754 type_base_sptr return_type = pointed_to_fn->get_return_type();
28755 string result;
28756
28757 if (is_npaf_type(return_type)
28758 || !(is_pointer_to_function_type(return_type)
28759 || is_pointer_to_array_type(return_type)))
28760 {
28761 if (return_type)
28762 left << get_type_name(return_type, qualified, internal);
28763 result = left.str() + " " + inner.str() + right.str();
28764 }
28765 else if (pointer_type_def_sptr p = is_pointer_to_function_type(return_type))
28766 {
28767 string inner_string = inner.str() + right.str();
28768 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
28769 qualified, internal);
28770 }
28771 else if (pointer_type_def_sptr p = is_pointer_to_array_type(return_type))
28772 {
28773 string inner_string = inner.str() + right.str();
28774 result = add_outer_pointer_to_array_type_expr(p, inner_string,
28775 qualified, internal);
28776 }
28777 else
28779
28780 // Lets unmark this function type to signify that we are done
28781 // walking its subtree. This was to detect potential cycles and
28782 // avoid looping endlessly.
28783 pointed_to_fn->priv_->unset_is_pretty_printing();
28784 return result;
28785}
28786
28787/// When constructing the name of a pointer to function type, add the
28788/// return type to the left of the existing type identifier, and the
28789/// parameters declarator to the right.
28790///
28791/// This function considers the name of the type as an expression.
28792///
28793/// The resulting type expr is going to be made of three parts:
28794/// left_expr inner_expr right_expr.
28795///
28796/// Suppose we want to build the type expression representing:
28797///
28798/// "an array of pointer to function taking a char parameter and
28799/// returning an int".
28800///
28801/// It's going to look like:
28802///
28803/// int(*a[])(char);
28804///
28805/// Suppose the caller of this function started to emit the inner
28806/// "a[]" part of the expression already. It thus calls this
28807/// function with that input "a[]" part. We consider that "a[]" as
28808/// the "type identifier".
28809///
28810/// So the inner_expr is going to be "(*a[])".
28811///
28812/// The left_expr part is "int". The right_expr part is "(char)".
28813///
28814/// In other words, this function adds the left_expr and right_expr to
28815/// the inner_expr. left_expr and right_expr are called "outer
28816/// pointer to function type expression".
28817///
28818/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28819/// array_declaration_name()
28820///
28821/// @param p the pointer to function type to consider.
28822///
28823/// @param input the type-id to use as the inner expression of the
28824/// overall pointer-to-function type expression
28825///
28826/// @param qualified if true then use qualified names in the resulting
28827/// type name.
28828///
28829/// @param internal if true then the resulting type name is going to
28830/// be used for type canonicalization purposes.
28831///
28832/// @return the name of the pointer to function type.
28833static string
28834add_outer_pointer_to_fn_type_expr(const type_base_sptr& p,
28835 const string& input,
28836 bool qualified, bool internal)
28837{return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
28838
28839/// When constructing the name of a pointer to array type, add the
28840/// array element type type to the left of the existing type
28841/// identifier, and the array declarator part to the right.
28842///
28843/// This function considers the name of the type as an expression.
28844///
28845/// The resulting type expr is going to be made of three parts:
28846/// left_expr inner_expr right_expr.
28847///
28848/// Suppose we want to build the type expression representing:
28849///
28850/// "a pointer to an array of int".
28851///
28852/// It's going to look like:
28853///
28854/// int(*foo)[];
28855///
28856/// Suppose the caller of this function started to emit the inner
28857/// "foo" part of the expression already. It thus calls this function
28858/// with that input "foo" part. We consider that "foo" as the "type
28859/// identifier".
28860///
28861/// So we are passed an input string that is "foo" and it's going to
28862/// be turned into the inner_expr part, which is going to be "(*foo)".
28863///
28864/// The left_expr part is "int". The right_expr part is "[]".
28865///
28866/// In other words, this function adds the left_expr and right_expr to
28867/// the inner_expr. left_expr and right_expr are called "outer
28868/// pointer to array type expression".
28869///
28870/// The model of this function was taken from the article "Reading C
28871/// type declaration", from Steve Friedl at
28872/// http://unixwiz.net/techtips/reading-cdecl.html.
28873///
28874/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28875/// array_declaration_name()
28876///
28877/// @param p the pointer to array type to consider.
28878///
28879/// @param input the type-id to start from as the inner part of the
28880/// final type name.
28881///
28882/// @param qualified if true then use qualified names in the resulting
28883/// type name.
28884///
28885/// @param internal if true then the resulting type name is going to
28886/// be used for type canonicalization purposes.
28887///
28888/// @return the name of the pointer to array type.
28889static string
28890add_outer_pointer_to_array_type_expr(const type_base* p,
28891 const string& input, bool qualified,
28892 bool internal)
28893{
28894 if (!p)
28895 return "";
28896
28897 string star_or_ref;
28898 type_base_sptr pointed_to_type;
28899
28900 if (const pointer_type_def *ptr = is_pointer_type(p))
28901 {
28902 pointed_to_type = ptr->get_pointed_to_type();
28903 star_or_ref = "*";
28904 }
28905 else if (const reference_type_def *ref = is_reference_type(p))
28906 {
28907 pointed_to_type = ref->get_pointed_to_type();
28908 star_or_ref = "&";
28909 }
28910
28911 array_type_def_sptr array = is_array_type(pointed_to_type);
28912 if (!array)
28913 return "";
28914
28915 std::ostringstream left, right, inner;
28916 inner << "(" << star_or_ref << input << ")";
28917 right << array->get_subrange_representation();
28918 string result;
28919
28920 type_base_sptr array_element_type = array->get_element_type();
28921
28922 if (is_npaf_type(array_element_type)
28923 || !(is_pointer_to_function_type(array_element_type)
28924 || is_pointer_to_array_type(array_element_type)))
28925 {
28926 left << get_type_name(array_element_type, qualified, internal);
28927 result = left.str() + inner.str() + right.str();
28928 }
28929 else if (pointer_type_def_sptr p =
28930 is_pointer_to_function_type(array_element_type))
28931 {
28932 string r = inner.str() + right.str();
28933 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
28934 }
28935 else if (pointer_type_def_sptr p =
28936 is_pointer_to_array_type(array_element_type))
28937 {
28938 string inner_string = inner.str() + right.str();
28939 result = add_outer_pointer_to_array_type_expr(p, inner_string,
28940 qualified, internal);
28941 }
28942 else
28944
28945 return result;
28946}
28947
28948/// When constructing the name of a pointer to array type, add the
28949/// array element type type to the left of the existing type
28950/// identifier, and the array declarator part to the right.
28951///
28952/// This function considers the name of the type as an expression.
28953///
28954/// The resulting type expr is going to be made of three parts:
28955/// left_expr inner_expr right_expr.
28956///
28957/// Suppose we want to build the type expression representing:
28958///
28959/// "a pointer to an array of int".
28960///
28961/// It's going to look like:
28962///
28963/// int(*foo)[];
28964///
28965/// Suppose the caller of this function started to emit the inner
28966/// "foo" part of the expression already. It thus calls this function
28967/// with that input "foo" part. We consider that "foo" as the "type
28968/// identifier".
28969///
28970/// So we are passed an input string that is "foo" and it's going to
28971/// be turned into the inner_expr part, which is going to be "(*foo)".
28972///
28973/// The left_expr part is "int". The right_expr part is "[]".
28974///
28975/// In other words, this function adds the left_expr and right_expr to
28976/// the inner_expr. left_expr and right_expr are called "outer
28977/// pointer to array type expression".
28978///
28979/// The model of this function was taken from the article "Reading C
28980/// type declaration", from Steve Friedl at
28981/// http://unixwiz.net/techtips/reading-cdecl.html.
28982///
28983/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28984/// array_declaration_name()
28985///
28986/// @param p the pointer to array type to consider.
28987///
28988/// @param input the type-id to start from as the inner part of the
28989/// final type name.
28990///
28991/// @param qualified if true then use qualified names in the resulting
28992/// type name.
28993///
28994/// @param internal if true then the resulting type name is going to
28995/// be used for type canonicalization purposes.
28996///
28997/// @return the name of the pointer to array type.
28998static string
28999add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
29000 const string& input, bool qualified,
29001 bool internal)
29002{return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
29003 input, qualified, internal);}
29004
29005/// When constructing the name of a pointer to mebmer type, add the
29006/// return type to the left of the existing type identifier, and the
29007/// parameters declarator to the right.
29008///
29009/// This function considers the name of the type as an expression.
29010///
29011/// The resulting type expr is going to be made of three parts:
29012/// left_expr inner_expr right_expr.
29013///
29014/// Suppose we want to build the type expression representing:
29015///
29016/// "an array of pointer to member function (of a containing struct
29017/// X) taking a char parameter and returning an int".
29018///
29019/// It's going to look like:
29020///
29021/// int (X::* a[])(char);
29022///
29023/// Suppose the caller of this function started to emit the inner
29024/// "a[]" part of the expression already. It thus calls this
29025/// function with that input "a[]" part. We consider that "a[]" as
29026/// the "type identifier".
29027///
29028/// So the inner_expr is going to be "(X::* a[])".
29029///
29030/// The left_expr part is "int". The right_expr part is "(char)".
29031///
29032/// In other words, this function adds the left_expr and right_expr to
29033/// the inner_expr. left_expr and right_expr are called "outer
29034/// pointer to member type expression".
29035///
29036/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29037///
29038/// @param p the pointer to member type to consider.
29039///
29040/// @param input the type-id to use as the inner expression of the
29041/// overall pointer-to-member type expression
29042///
29043/// @param qualified if true then use qualified names in the resulting
29044/// type name.
29045///
29046/// @param internal if true then the resulting type name is going to
29047/// be used for type canonicalization purposes.
29048///
29049/// @return the name of the pointer to member type.
29050static string
29051add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
29052 const string& input, bool qualified,
29053 bool internal)
29054{
29055 if (!p)
29056 return "";
29057
29058 std::ostringstream left, right, inner;
29059 type_base_sptr void_type = p->get_environment().get_void_type();
29060 string containing_type_name = get_type_name(p->get_containing_type(),
29061 qualified, internal);
29062 type_base_sptr mbr_type = p->get_member_type();
29063 string result;
29064 if (function_type_sptr fn_type = is_function_type(mbr_type))
29065 {
29066 inner << "(" << containing_type_name << "::*" << input << ")";
29067 stream_pretty_representation_of_fn_parms(*fn_type, right,
29068 qualified, internal);
29069 type_base_sptr return_type = fn_type->get_return_type();
29070 if (!return_type)
29071 return_type = void_type;
29072 if (is_npaf_type(return_type)
29073 || !(is_pointer_to_function_type(return_type)
29074 || is_pointer_to_array_type(return_type)
29075 || is_pointer_to_ptr_to_mbr_type(return_type)
29076 || is_ptr_to_mbr_type(return_type)))
29077 {
29078 left << get_type_name(return_type, qualified, internal) << " ";;
29079 result = left.str() + inner.str() + right.str();
29080 }
29081 else if (pointer_type_def_sptr p = is_pointer_type(return_type))
29082 {
29083 string inner_str = inner.str() + right.str();
29084 result = pointer_declaration_name(p, inner_str, qualified, internal);
29085 }
29086 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(return_type))
29087 {
29088 string inner_str = inner.str() + right.str();
29089 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
29090 qualified, internal);
29091 }
29092 else
29094 }
29095 else if (ptr_to_mbr_type_sptr ptr_mbr_type = is_ptr_to_mbr_type(mbr_type))
29096 {
29097 inner << "(" << containing_type_name << "::*" << input << ")";
29098 stream_pretty_representation_of_fn_parms(*fn_type, right,
29099 qualified, internal);
29100 string inner_str = inner.str() + right.str();
29101 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
29102 qualified, internal);
29103 }
29104 else
29105 {
29106 left << get_type_name(p->get_member_type(), qualified, internal) << " ";
29107 inner << containing_type_name << "::*" << input;
29108 result = left.str()+ inner.str();
29109 }
29110
29111 return result;
29112}
29113
29114/// When constructing the name of a pointer to mebmer type, add the
29115/// return type to the left of the existing type identifier, and the
29116/// parameters declarator to the right.
29117///
29118/// This function considers the name of the type as an expression.
29119///
29120/// The resulting type expr is going to be made of three parts:
29121/// left_expr inner_expr right_expr.
29122///
29123/// Suppose we want to build the type expression representing:
29124///
29125/// "an array of pointer to member function (of a containing struct
29126/// X) taking a char parameter and returning an int".
29127///
29128/// It's going to look like:
29129///
29130/// int (X::* a[])(char);
29131///
29132/// Suppose the caller of this function started to emit the inner
29133/// "a[]" part of the expression already. It thus calls this
29134/// function with that input "a[]" part. We consider that "a[]" as
29135/// the "type identifier".
29136///
29137/// So the inner_expr is going to be "(X::* a[])".
29138///
29139/// The left_expr part is "int". The right_expr part is "(char)".
29140///
29141/// In other words, this function adds the left_expr and right_expr to
29142/// the inner_expr. left_expr and right_expr are called "outer
29143/// pointer to member type expression".
29144///
29145/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29146///
29147/// @param p the pointer to member type to consider.
29148///
29149/// @param input the type-id to use as the inner expression of the
29150/// overall pointer-to-member type expression
29151///
29152/// @param qualified if true then use qualified names in the resulting
29153/// type name.
29154///
29155/// @param internal if true then the resulting type name is going to
29156/// be used for type canonicalization purposes.
29157///
29158/// @return the name of the pointer to member type.
29159static string
29160add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
29161 const string& input, bool qualified,
29162 bool internal)
29163{return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
29164
29165/// This adds the outer parts of a pointer to a pointer-to-member
29166/// expression.
29167///
29168/// Please read the comments of @ref add_outer_ptr_to_mbr_type_expr to
29169/// learn more about this function, which is similar.
29170///
29171/// This is a sub-routine of @ref pointer_declaration_name().
29172///
29173/// @param a pointer (or reference) to a pointer-to-member type.
29174///
29175/// @param input the inner type-id to add the outer parts to.
29176///
29177/// @param qualified if true then use qualified names in the resulting
29178/// type name.
29179///
29180/// @param internal if true then the resulting type name is going to
29181/// be used for type canonicalization purposes.
29182static string
29183add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
29184 const string& input, bool qualified,
29185 bool internal)
29186{
29187 if (!p)
29188 return "";
29189
29190 string star_or_ref;
29191 type_base_sptr pointed_to_type;
29192
29193 if (const pointer_type_def* ptr = is_pointer_type(p))
29194 {
29195 pointed_to_type = ptr->get_pointed_to_type();
29196 star_or_ref = "*";
29197 }
29198 else if (const reference_type_def* ref = is_reference_type(p))
29199 {
29200 pointed_to_type= ref->get_pointed_to_type();
29201 star_or_ref = "&";
29202 }
29203
29204 if (!pointed_to_type)
29205 return "";
29206
29207 ptr_to_mbr_type_sptr pointed_to_ptr_to_mbr =
29208 is_ptr_to_mbr_type(pointed_to_type);
29209 if (!pointed_to_ptr_to_mbr)
29210 return "";
29211
29212 std::ostringstream inner;
29213 inner << star_or_ref << input;
29214 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
29215 inner.str(),
29216 qualified, internal);
29217 return result;
29218}
29219
29220/// Emit the name of a pointer declaration.
29221///
29222/// @param the pointer to consider.
29223///
29224/// @param idname the name of the variable that has @p as a type or
29225/// the id of the type. If it's empty then the resulting name is
29226/// going to be the abstract name of the type.
29227///
29228/// @param qualified if true then the type name is going to be
29229/// fully qualified.
29230///
29231/// @param internal if true then the type name is going to be used for
29232/// type canonicalization purposes.
29233static interned_string
29234pointer_declaration_name(const type_base* ptr,
29235 const string& idname,
29236 bool qualified, bool internal)
29237{
29238 if (!ptr)
29239 return interned_string();
29240
29241 type_base_sptr pointed_to_type;
29242 string star_or_ref;
29243 if (const pointer_type_def* p = is_pointer_type(ptr))
29244 {
29245 pointed_to_type = p->get_pointed_to_type();
29246 star_or_ref = "*";
29247 }
29248 else if (const reference_type_def* p = is_reference_type(ptr))
29249 {
29250 pointed_to_type = p->get_pointed_to_type();
29251 star_or_ref = "&";
29252 }
29253
29254 if (!pointed_to_type)
29255 return interned_string();
29256
29257 string result;
29258 if (is_npaf_type(pointed_to_type)
29259 || !(is_function_type(pointed_to_type)
29260 || is_array_type(pointed_to_type)
29261 || is_ptr_to_mbr_type(pointed_to_type)))
29262 {
29263 result = get_type_name(pointed_to_type,
29264 qualified,
29265 internal)
29266 + star_or_ref;
29267
29268 if (!idname.empty())
29269 result += idname;
29270 }
29271 else
29272 {
29273 // derived type
29274 if (is_function_type(pointed_to_type))
29275 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
29276 qualified, internal);
29277 else if (is_array_type(pointed_to_type))
29278 result = add_outer_pointer_to_array_type_expr(ptr, idname,
29279 qualified, internal);
29280 else if (is_ptr_to_mbr_type(pointed_to_type))
29281 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
29282 qualified, internal);
29283 else
29285 }
29286 return ptr->get_environment().intern(result);
29287}
29288
29289
29290/// Emit the name of a pointer declaration.
29291///
29292/// @param the pointer to consider.
29293///
29294/// @param the name of the variable that has @p as a type. If it's
29295/// empty then the resulting name is going to be the abstract name of
29296/// the type.
29297///
29298/// @param qualified if true then the type name is going to be
29299/// fully qualified.
29300///
29301/// @param internal if true then the type name is going to be used for
29302/// type canonicalization purposes.
29303static interned_string
29304pointer_declaration_name(const type_base_sptr& ptr,
29305 const string& variable_name,
29306 bool qualified, bool internal)
29307{return pointer_declaration_name(ptr.get(), variable_name,
29308 qualified, internal);}
29309
29310/// Emit the name of a array declaration.
29311///
29312/// @param the array to consider.
29313///
29314/// @param the name of the variable that has @p as a type. If it's
29315/// empty then the resulting name is going to be the abstract name of
29316/// the type.
29317///
29318/// @param qualified if true then the type name is going to be
29319/// fully qualified.
29320///
29321/// @param internal if true then the type name is going to be used for
29322/// type canonicalization purposes.
29323static interned_string
29324array_declaration_name(const array_type_def* array,
29325 const string& variable_name,
29326 bool qualified, bool internal)
29327{
29328 if (!array)
29329 return interned_string();
29330
29331 type_base_sptr e_type = array->get_element_type();
29332 string e_type_repr =
29333 (e_type
29334 ? get_type_name(e_type, qualified, internal)
29335 : string("void"));
29336
29337 string result;
29338 if (is_ada_language(array->get_language()))
29339 {
29340 std::ostringstream o;
29341 if (!variable_name.empty())
29342 o << variable_name << " is ";
29343 o << "array ("
29344 << array->get_subrange_representation()
29345 << ") of " << e_type_repr;
29346 result = o.str();
29347 }
29348 else
29349 {
29350 if (is_npaf_type(e_type)
29351 || !(is_pointer_to_function_type(e_type)
29352 || is_pointer_to_array_type(e_type)
29354 || is_ptr_to_mbr_type(e_type)))
29355 {
29356 result = e_type_repr;
29357 if (!variable_name.empty())
29358 result += variable_name;
29359 result += array->get_subrange_representation();
29360 }
29361 else if (pointer_type_def_sptr p = is_pointer_type(e_type))
29362 {
29363 string s = variable_name + array->get_subrange_representation();
29364 result = pointer_declaration_name(p, s, qualified, internal);
29365 }
29366 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(e_type))
29367 {
29368 string s = variable_name + array->get_subrange_representation();
29369 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
29370 }
29371 else
29373 }
29374 return array->get_environment().intern(result);
29375}
29376
29377/// Emit the name of a array declaration.
29378///
29379/// @param the array to consider.
29380///
29381/// @param the name of the variable that has @p as a type. If it's
29382/// empty then the resulting name is going to be the abstract name of
29383/// the type.
29384///
29385/// @param qualified if true then the type name is going to be
29386/// fully qualified.
29387///
29388/// @param internal if true then the type name is going to be used for
29389/// type canonicalization purposes.
29390static interned_string
29391array_declaration_name(const array_type_def_sptr& array,
29392 const string& variable_name,
29393 bool qualified, bool internal)
29394{return array_declaration_name(array.get(), variable_name,
29395 qualified, internal);}
29396
29397/// Emit the name of a pointer-to-member declaration.
29398///
29399/// @param ptr the pointer-to-member to consider.
29400///
29401/// @param variable_name the name of the variable that has @p as a
29402/// type. If it's empty then the resulting name is going to be the
29403/// abstract name of the type.
29404///
29405/// @param qualified if true then the type name is going to be
29406/// fully qualified.
29407///
29408/// @param internal if true then the type name is going to be used for
29409/// type canonicalization purposes.
29410static interned_string
29411ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
29412 const string& variable_name,
29413 bool qualified, bool internal)
29414{
29415 if (!ptr)
29416 return interned_string();
29417
29418 string input = variable_name;
29419 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
29420 qualified, internal);
29421 return ptr->get_environment().intern(result);
29422}
29423
29424/// Emit the name of a pointer-to-member declaration.
29425///
29426/// @param ptr the pointer-to-member to consider.
29427///
29428/// @param variable_name the name of the variable that has @p as a
29429/// type. If it's empty then the resulting name is going to be the
29430/// abstract name of the type.
29431///
29432/// @param qualified if true then the type name is going to be
29433/// fully qualified.
29434///
29435/// @param internal if true then the type name is going to be used for
29436/// type canonicalization purposes.
29437static interned_string
29438ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
29439 const string& variable_name,
29440 bool qualified, bool internal)
29441{
29442 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
29443 qualified, internal);
29444}
29445
29446/// Sort types right before hashing and canonicalizing them.
29447///
29448/// @param types the vector of types to sort.
29449void
29450sort_types_for_hash_computing_and_c14n(vector<type_base_sptr>& types)
29451{
29452 sort_types_for_hash_computing_and_c14n(types.begin(), types.end());
29453}
29454
29455bool
29457{return true;}
29458
29459// <ir_node_visitor stuff>
29460
29461/// The private data structure of the ir_node_visitor type.
29462struct ir_node_visitor::priv
29463{
29464 pointer_set visited_ir_nodes;
29466
29467 priv()
29469 {}
29470}; // end struct ir_node_visitory::priv
29471
29472/// Default Constructor of the ir_node_visitor type.
29474 : priv_(new priv)
29475{}
29476
29477ir_node_visitor::~ir_node_visitor() = default;
29478
29479/// Set if the walker using this visitor is allowed to re-visit a type
29480/// node that was previously visited or not.
29481///
29482/// @param f if true, then the walker using this visitor is allowed to
29483/// re-visit a type node that was previously visited.
29484void
29486{priv_->allow_visiting_already_visited_type_node = f;}
29487
29488/// Get if the walker using this visitor is allowed to re-visit a type
29489/// node that was previously visited or not.
29490///
29491/// @return true iff the walker using this visitor is allowed to
29492/// re-visit a type node that was previously visited.
29493bool
29495{return priv_->allow_visiting_already_visited_type_node;}
29496
29497/// Mark a given type node as having been visited.
29498///
29499/// Note that for this function to work, the type node must have been
29500/// canonicalized. Otherwise the process is aborted.
29501///
29502/// @param p the type to mark as having been visited.
29503void
29505{
29507 return;
29508
29509 if (p == 0 || type_node_has_been_visited(p))
29510 return;
29511
29512 type_base* canonical_type = p->get_naked_canonical_type();
29514 {
29515 ABG_ASSERT(!canonical_type);
29516 canonical_type = p;
29517 }
29518 ABG_ASSERT(canonical_type);
29519
29520 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
29521 priv_->visited_ir_nodes.insert(canonical_ptr_value);
29522}
29523
29524/// Un-mark all visited type nodes.
29525///
29526/// That is, no type node is going to be considered as having been
29527/// visited anymore.
29528///
29529/// In other words, after invoking this funciton,
29530/// ir_node_visitor::type_node_has_been_visited() is going to return
29531/// false on all type nodes.
29532void
29534{priv_->visited_ir_nodes.clear();}
29535
29536/// Test if a given type node has been marked as visited.
29537///
29538/// @param p the type node to consider.
29539///
29540/// @return true iff the type node @p p has been marked as visited by
29541/// the function ir_node_visitor::mark_type_node_as_visited.
29542bool
29544{
29546 return false;
29547
29548 if (p == 0)
29549 return false;
29550
29551 type_base *canonical_type = p->get_naked_canonical_type();
29553 {
29554 ABG_ASSERT(!canonical_type);
29555 canonical_type = p;
29556 }
29557 ABG_ASSERT(canonical_type);
29558
29559 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
29560 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
29561 if (it == priv_->visited_ir_nodes.end())
29562 return false;
29563
29564 return true;
29565}
29566
29567bool
29568ir_node_visitor::visit_begin(decl_base*)
29569{return true;}
29570
29571bool
29572ir_node_visitor::visit_end(decl_base*)
29573{return true;}
29574
29575bool
29576ir_node_visitor::visit_begin(scope_decl*)
29577{return true;}
29578
29579bool
29580ir_node_visitor::visit_end(scope_decl*)
29581{return true;}
29582
29583bool
29584ir_node_visitor::visit_begin(type_base*)
29585{return true;}
29586
29587bool
29588ir_node_visitor::visit_end(type_base*)
29589{return true;}
29590
29591bool
29592ir_node_visitor::visit_begin(scope_type_decl* t)
29593{return visit_begin(static_cast<type_base*>(t));}
29594
29595bool
29596ir_node_visitor::visit_end(scope_type_decl* t)
29597{return visit_end(static_cast<type_base*>(t));}
29598
29599bool
29600ir_node_visitor::visit_begin(type_decl* t)
29601{return visit_begin(static_cast<type_base*>(t));}
29602
29603bool
29604ir_node_visitor::visit_end(type_decl* t)
29605{return visit_end(static_cast<type_base*>(t));}
29606
29607bool
29608ir_node_visitor::visit_begin(namespace_decl* d)
29609{return visit_begin(static_cast<decl_base*>(d));}
29610
29611bool
29612ir_node_visitor::visit_end(namespace_decl* d)
29613{return visit_end(static_cast<decl_base*>(d));}
29614
29615bool
29616ir_node_visitor::visit_begin(qualified_type_def* t)
29617{return visit_begin(static_cast<type_base*>(t));}
29618
29619bool
29620ir_node_visitor::visit_end(qualified_type_def* t)
29621{return visit_end(static_cast<type_base*>(t));}
29622
29623bool
29624ir_node_visitor::visit_begin(pointer_type_def* t)
29625{return visit_begin(static_cast<type_base*>(t));}
29626
29627bool
29628ir_node_visitor::visit_end(pointer_type_def* t)
29629{return visit_end(static_cast<type_base*>(t));}
29630
29631bool
29632ir_node_visitor::visit_begin(reference_type_def* t)
29633{return visit_begin(static_cast<type_base*>(t));}
29634
29635bool
29636ir_node_visitor::visit_end(reference_type_def* t)
29637{return visit_end(static_cast<type_base*>(t));}
29638
29639bool
29640ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
29641{return visit_begin(static_cast<type_base*>(t));}
29642
29643bool
29644ir_node_visitor::visit_end(ptr_to_mbr_type* t)
29645{return visit_end(static_cast<type_base*>(t));}
29646
29647bool
29648ir_node_visitor::visit_begin(array_type_def* t)
29649{return visit_begin(static_cast<type_base*>(t));}
29650
29651bool
29652ir_node_visitor::visit_end(array_type_def* t)
29653{return visit_end(static_cast<type_base*>(t));}
29654
29655bool
29656ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
29657{return visit_begin(static_cast<type_base*>(t));}
29658
29659bool
29660ir_node_visitor::visit_end(array_type_def::subrange_type* t)
29661{return visit_end(static_cast<type_base*>(t));}
29662
29663bool
29664ir_node_visitor::visit_begin(enum_type_decl* t)
29665{return visit_begin(static_cast<type_base*>(t));}
29666
29667bool
29668ir_node_visitor::visit_end(enum_type_decl* t)
29669{return visit_end(static_cast<type_base*>(t));}
29670
29671bool
29672ir_node_visitor::visit_begin(typedef_decl* t)
29673{return visit_begin(static_cast<type_base*>(t));}
29674
29675bool
29676ir_node_visitor::visit_end(typedef_decl* t)
29677{return visit_end(static_cast<type_base*>(t));}
29678
29679bool
29680ir_node_visitor::visit_begin(function_type* t)
29681{return visit_begin(static_cast<type_base*>(t));}
29682
29683bool
29684ir_node_visitor::visit_end(function_type* t)
29685{return visit_end(static_cast<type_base*>(t));}
29686
29687bool
29688ir_node_visitor::visit_begin(var_decl* d)
29689{return visit_begin(static_cast<decl_base*>(d));}
29690
29691bool
29692ir_node_visitor::visit_end(var_decl* d)
29693{return visit_end(static_cast<decl_base*>(d));}
29694
29695bool
29696ir_node_visitor::visit_begin(function_decl* d)
29697{return visit_begin(static_cast<decl_base*>(d));}
29698
29699bool
29700ir_node_visitor::visit_end(function_decl* d)
29701{return visit_end(static_cast<decl_base*>(d));}
29702
29703bool
29704ir_node_visitor::visit_begin(function_decl::parameter* d)
29705{return visit_begin(static_cast<decl_base*>(d));}
29706
29707bool
29708ir_node_visitor::visit_end(function_decl::parameter* d)
29709{return visit_end(static_cast<decl_base*>(d));}
29710
29711bool
29712ir_node_visitor::visit_begin(function_tdecl* d)
29713{return visit_begin(static_cast<decl_base*>(d));}
29714
29715bool
29716ir_node_visitor::visit_end(function_tdecl* d)
29717{return visit_end(static_cast<decl_base*>(d));}
29718
29719bool
29720ir_node_visitor::visit_begin(class_tdecl* d)
29721{return visit_begin(static_cast<decl_base*>(d));}
29722
29723bool
29724ir_node_visitor::visit_end(class_tdecl* d)
29725{return visit_end(static_cast<decl_base*>(d));}
29726
29727bool
29728ir_node_visitor::visit_begin(class_or_union* t)
29729{return visit_begin(static_cast<type_base*>(t));}
29730
29731bool
29732ir_node_visitor::visit_end(class_or_union* t)
29733{return visit_end(static_cast<type_base*>(t));}
29734
29735bool
29736ir_node_visitor::visit_begin(class_decl* t)
29737{return visit_begin(static_cast<type_base*>(t));}
29738
29739bool
29740ir_node_visitor::visit_end(class_decl* t)
29741{return visit_end(static_cast<type_base*>(t));}
29742
29743bool
29744ir_node_visitor::visit_begin(union_decl* t)
29745{return visit_begin(static_cast<type_base*>(t));}
29746
29747bool
29748ir_node_visitor::visit_end(union_decl* t)
29749{return visit_end(static_cast<type_base*>(t));}
29750
29751bool
29752ir_node_visitor::visit_begin(class_decl::base_spec* d)
29753{return visit_begin(static_cast<decl_base*>(d));}
29754
29755bool
29756ir_node_visitor::visit_end(class_decl::base_spec* d)
29757{return visit_end(static_cast<decl_base*>(d));}
29758
29759bool
29760ir_node_visitor::visit_begin(member_function_template* d)
29761{return visit_begin(static_cast<decl_base*>(d));}
29762
29763bool
29764ir_node_visitor::visit_end(member_function_template* d)
29765{return visit_end(static_cast<decl_base*>(d));}
29766
29767bool
29768ir_node_visitor::visit_begin(member_class_template* d)
29769{return visit_begin(static_cast<decl_base*>(d));}
29770
29771bool
29772ir_node_visitor::visit_end(member_class_template* d)
29773{return visit_end(static_cast<decl_base*>(d));}
29774
29775// </ir_node_visitor stuff>
29776
29777// <debugging facilities>
29778
29779/// Generate a different string at each invocation.
29780///
29781/// @return the resulting string.
29782static string
29783get_next_string()
29784{
29785 static __thread size_t counter;
29786 ++counter;
29787 std::ostringstream o;
29788 o << counter;
29789 return o.str();
29790}
29791
29792/// A hashing functor for a @ref function_decl
29793struct function_decl_hash
29794{
29795 size_t operator()(const function_decl* f) const
29796 {return reinterpret_cast<size_t>(f);}
29797
29798 size_t operator()(const function_decl_sptr& f) const
29799 {return operator()(f.get());}
29800};
29801
29802/// Convenience typedef for a hash map of pointer to function_decl and
29803/// string.
29804typedef unordered_map<const function_decl*, string,
29805 function_decl_hash,
29807
29808/// Return a string associated to a given function. Two functions
29809/// that compare equal would yield the same string, as far as this
29810/// routine is concerned. And two functions that are different would
29811/// yield different strings.
29812///
29813/// This is used to debug core diffing issues on functions. The
29814/// sequence of strings can be given to the 'testdiff2' program that
29815/// is in the tests/ directory of the source tree, to reproduce core
29816/// diffing issues on string and thus ease the debugging.
29817///
29818/// @param fn the function to generate a string for.
29819///
29820/// @param m the function_decl* <-> string map to be used by this
29821/// function to generate strings associated to a function.
29822///
29823/// @return the resulting string.
29824static const string&
29825fn_to_str(const function_decl* fn,
29827{
29828 fns_to_str_map_type::const_iterator i = m.find(fn);
29829 if (i != m.end())
29830 return i->second;
29831 string s = get_next_string();
29832 return m[fn]= s;
29833}
29834
29835/// Generate a sequence of string that matches a given sequence of
29836/// function. In the resulting sequence, each function is "uniquely
29837/// representated" by a string. For instance, if the same function "foo"
29838/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
29839/// we don't care about the actual string) would appear at index 1 and 3.
29840///
29841/// @param begin the beginning of the sequence of functions to consider.
29842///
29843/// @param end the end of the sequence of functions. This points to
29844/// one-passed-the-end of the actual sequence.
29845///
29846/// @param m the function_decl* <-> string map to be used by this
29847/// function to generate strings associated to a function.
29848///
29849/// @param o the output stream where to emit the generated list of
29850/// strings to.
29851static void
29852fns_to_str(vector<function_decl*>::const_iterator begin,
29853 vector<function_decl*>::const_iterator end,
29855 std::ostream& o)
29856{
29857 vector<function_decl*>::const_iterator i;
29858 for (i = begin; i != end; ++i)
29859 o << "'" << fn_to_str(*i, m) << "' ";
29860}
29861
29862/// For each sequence of functions given in argument, generate a
29863/// sequence of string that matches a given sequence of function. In
29864/// the resulting sequence, each function is "uniquely representated"
29865/// by a string. For instance, if the same function "foo" appears at
29866/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
29867/// care about the actual string) would appear at index 1 and 3.
29868///
29869/// @param a_begin the beginning of the sequence of functions to consider.
29870///
29871/// @param a_end the end of the sequence of functions. This points to
29872/// one-passed-the-end of the actual sequence.
29873///
29874/// @param b_begin the beginning of the second sequence of functions
29875/// to consider.
29876///
29877/// @param b_end the end of the second sequence of functions.
29878///
29879/// @param m the function_decl* <-> string map to be used by this
29880/// function to generate strings associated to a function.
29881///
29882/// @param o the output stream where to emit the generated list of
29883/// strings to.
29884static void
29885fns_to_str(vector<function_decl*>::const_iterator a_begin,
29886 vector<function_decl*>::const_iterator a_end,
29887 vector<function_decl*>::const_iterator b_begin,
29888 vector<function_decl*>::const_iterator b_end,
29890 std::ostream& o)
29891{
29892 fns_to_str(a_begin, a_end, m, o);
29893 o << "->|<- ";
29894 fns_to_str(b_begin, b_end, m, o);
29895 o << "\n";
29896}
29897
29898/// For each sequence of functions given in argument, generate a
29899/// sequence of string that matches a given sequence of function. In
29900/// the resulting sequence, each function is "uniquely representated"
29901/// by a string. For instance, if the same function "foo" appears at
29902/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
29903/// care about the actual string) would appear at index 1 and 3.
29904///
29905/// @param a_begin the beginning of the sequence of functions to consider.
29906///
29907/// @param a_end the end of the sequence of functions. This points to
29908/// one-passed-the-end of the actual sequence.
29909///
29910/// @param b_begin the beginning of the second sequence of functions
29911/// to consider.
29912///
29913/// @param b_end the end of the second sequence of functions.
29914///
29915/// @param o the output stream where to emit the generated list of
29916/// strings to.
29917void
29918fns_to_str(vector<function_decl*>::const_iterator a_begin,
29919 vector<function_decl*>::const_iterator a_end,
29920 vector<function_decl*>::const_iterator b_begin,
29921 vector<function_decl*>::const_iterator b_end,
29922 std::ostream& o)
29923{
29925 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
29926}
29927
29928// </debugging facilities>
29929
29930// </class template>
29931
29932}// end namespace ir
29933}//end namespace abigail
29934
29935namespace
29936{
29937
29938/// Update the qualified parent name, qualified name and scoped name
29939/// of a tree decl node.
29940///
29941/// @return true if the tree walking should continue, false otherwise.
29942///
29943/// @param d the tree node to take in account.
29944bool
29945qualified_name_setter::do_update(abigail::ir::decl_base* d)
29946{
29947 std::string parent_qualified_name;
29948 abigail::ir::scope_decl* parent = d->get_scope();
29949 if (parent)
29950 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
29951 else
29952 d->priv_->qualified_parent_name_ = abigail::interned_string();
29953
29954 const abigail::ir::environment& env = d->get_environment();
29955
29956 if (!d->priv_->qualified_parent_name_.empty())
29957 {
29958 if (d->get_name().empty())
29959 d->priv_->qualified_name_ = abigail::interned_string();
29960 else
29961 {
29962 d->priv_->qualified_name_ =
29963 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
29964 d->priv_->internal_qualified_name_ = env.intern(d->get_name());
29965 }
29966 }
29967 // Make sure the internal qualified name (used for type
29968 // canonicalization puroses) is always the qualified name. For
29969 // integral/real types however, only the non qualified type is used.
29970 if (!is_integral_type(d))
29971 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
29972
29973 if (d->priv_->scoped_name_.empty())
29974 {
29975 if (parent
29976 && !parent->get_is_anonymous()
29977 && !parent->get_name().empty())
29978 d->priv_->scoped_name_ =
29979 env.intern(parent->get_name() + "::" + d->get_name());
29980 else
29981 d->priv_->scoped_name_ =
29982 env.intern(d->get_name());
29983 }
29984
29985 if (!is_scope_decl(d))
29986 return false;
29987
29988 return true;
29989}
29990
29991/// This is called when we start visiting a decl node, during the
29992/// udpate of the qualified name of a given sub-tree.
29993///
29994/// @param d the decl node we are visiting.
29995///
29996/// @return true iff the traversal should keep going.
29997bool
29998qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
29999{return do_update(d);}
30000
30001/// This is called when we start visiting a type node, during the
30002/// udpate of the qualified name of a given sub-tree.
30003///
30004/// @param d the decl node we are visiting.
30005///
30006/// @return true iff the traversal should keep going.
30007bool
30008qualified_name_setter::visit_begin(abigail::ir::type_base* t)
30009{
30011 return do_update(d);
30012 return false;
30013}
30014}// end anonymous namespace.
This header declares filters for the diff trees resulting from comparing ABI Corpora.
The private data and functions of the abigail::ir::corpus type.
#define ABG_RETURN_FALSE
A macro used to return the "false" boolean from DIE comparison routines.
#define ABG_RETURN(value)
A macro used to return from DIE comparison routines.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
Definition: abg-fwd.h:1718
Declaration of types pertaining to the interned string pool used throughout Libabigail,...
This contains the private implementation of the suppression engine of libabigail.
#define CACHE_COMPARISON_RESULT_AND_RETURN(value)
Cache the result of a comparison between too artifacts (l & r) and return immediately.
Definition: abg-ir.cc:1114
#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:1000
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:2560
void set_signed(int64_t v)
Setter of the bound value as signed.
Definition: abg-ir.cc:18850
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:18818
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:18811
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition: abg-ir.cc:18825
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition: abg-ir.cc:18862
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition: abg-ir.cc:18833
bound_value()
Default constructor of the array_type_def::subrange_type::bound_value class.
Definition: abg-ir.cc:18783
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition: abg-ir.cc:18840
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++.
Definition: abg-ir.h:2545
void set_lower_bound(int64_t lb)
Setter of the lower bound.
Definition: abg-ir.cc:19041
bool is_non_finite() const
Test if the length of the subrange type is infinite.
Definition: abg-ir.cc:19068
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition: abg-ir.cc:19034
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:19008
string as_string() const
Return a string representation of the sub range.
Definition: abg-ir.cc:19090
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18989
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19290
bool operator!=(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:19229
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition: abg-ir.cc:19020
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:19000
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:19185
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition: abg-ir.cc:19027
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:19268
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition: abg-ir.cc:19113
uint64_t get_length() const
Getter of the length of the subrange type.
Definition: abg-ir.cc:19051
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition: abg-ir.cc:19083
The abstraction of an array type.
Definition: abg-ir.h:2519
virtual bool is_non_finite() const
Definition: abg-ir.cc:19641
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:19671
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:19397
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition: abg-ir.cc:19602
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition: abg-ir.cc:19617
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition: abg-ir.h:2537
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19734
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition: abg-ir.cc:19761
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:19580
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
Definition: abg-ir.h:2540
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:19450
translation_unit::language get_language() const
Get the language of the array.
Definition: abg-ir.cc:19569
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition: abg-ir.cc:19627
Abstraction of a base specifier in a class declaration.
Definition: abg-ir.h:4314
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
Definition: abg-ir.cc:24855
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition: abg-ir.cc:24862
long get_offset_in_bits() const
Getter of the offset of the base.
Definition: abg-ir.cc:24869
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:24844
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:24885
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Definition: abg-ir.cc:24979
Abstracts a class declaration.
Definition: abg-ir.h:4127
void is_struct(bool f)
Set the "is-struct" flag of the class.
Definition: abg-ir.cc:24652
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition: abg-ir.cc:25435
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:24721
bool is_struct() const
Test if the class is a struct.
Definition: abg-ir.cc:24659
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:25498
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition: abg-ir.cc:24676
virtual ~class_decl()
Destructor of the class_decl type.
Definition: abg-ir.cc:26012
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:24637
bool has_vtable() const
Test if the current instance has a vtable.
Definition: abg-ir.cc:25463
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition: abg-ir.cc:25477
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition: abg-ir.cc:25444
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:25928
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition: abg-ir.h:4145
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
Definition: abg-ir.cc:24666
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition: abg-ir.cc:24702
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition: abg-ir.cc:24726
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition: abg-ir.cc:25596
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition: abg-ir.cc:25776
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:24686
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition: abg-ir.cc:25426
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition: abg-ir.h:4146
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:24747
The base type of class_decl and union_decl.
Definition: abg-ir.h:3929
virtual size_t get_num_anonymous_member_classes() const
Get the number of anonymous member classes contained in this class.
Definition: abg-ir.cc:23594
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:23835
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:23760
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition: abg-ir.cc:23863
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
Definition: abg-ir.cc:23480
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition: abg-ir.cc:23939
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition: abg-ir.cc:23579
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition: abg-ir.cc:23612
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
Definition: abg-ir.cc:23953
unordered_map< ssize_t, member_functions > virtual_mem_fn_map_type
Convenience typedef.
Definition: abg-ir.h:3961
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition: abg-ir.h:3960
const data_members & get_data_members() const
Get the data members of this class_or_union.
Definition: abg-ir.cc:23719
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:23370
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:23661
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:23914
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:23898
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition: abg-ir.cc:23563
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
Definition: abg-ir.cc:23995
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:23468
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:23386
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition: abg-ir.cc:23967
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
Definition: abg-ir.cc:23810
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:23872
const data_members & get_static_data_members() const
Get the static data memebers of this class_or_union.
Definition: abg-ir.cc:23818
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:23505
vector< var_decl_sptr > data_members
Convenience typedef.
Definition: abg-ir.h:3959
virtual ~class_or_union()
Destrcutor of the class_or_union type.
Definition: abg-ir.cc:23459
bool has_no_member() const
Definition: abg-ir.cc:23980
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:24029
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26315
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition: abg-ir.cc:23531
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition: abg-ir.cc:23946
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition: abg-ir.cc:23547
vector< type_base_sptr > member_types
Convenience typedef.
Definition: abg-ir.h:3958
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
Definition: abg-ir.cc:23630
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:23730
Abstract a class template.
Definition: abg-ir.h:3749
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition: abg-ir.cc:27707
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
Definition: abg-ir.cc:27696
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:27756
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:27711
The abstraction of the relationship between an entity and its containing scope (its context)....
Definition: abg-ir.h:1256
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition: abg-corpus.h:25
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:1556
void set_definition_of_declaration(const decl_base_sptr &)
Set the definition of this declaration-only decl_base.
Definition: abg-ir.cc:15917
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:4829
virtual bool operator!=(const decl_base &) const
Inequality operator.
Definition: abg-ir.cc:5044
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current decl.
Definition: abg-ir.cc:4718
scope_decl * get_scope() const
Return the type containing the current decl, if any.
Definition: abg-ir.cc:4616
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
Definition: abg-ir.cc:4347
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:4409
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:5399
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
Definition: abg-ir.cc:4777
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
Definition: abg-ir.cc:4591
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:4813
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition: abg-ir.cc:4647
void clear_qualified_name()
Clear the qualified name of this decl.
Definition: abg-ir.cc:4340
virtual void set_name(const string &n)
Setter for the name of the decl.
Definition: abg-ir.cc:4479
const location & get_location() const
Get the location of a given declaration.
Definition: abg-ir.cc:4429
binding
ELF binding.
Definition: abg-ir.h:1607
typedef_decl_sptr get_naming_typedef() const
Getter for the naming typedef of the current decl.
Definition: abg-ir.cc:4539
virtual const interned_string & get_name() const
Getter for the name of the current decl.
Definition: abg-ir.cc:4635
virtual void set_scope(scope_decl *)
Setter of the scope of the current decl.
Definition: abg-ir.cc:5071
const interned_string & peek_qualified_name() const
Getter for the qualified name.
Definition: abg-ir.cc:4331
const context_rel * get_context_rel() const
Getter for the context relationship.
Definition: abg-ir.cc:4381
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Definition: abg-ir.cc:4492
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:8274
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
Definition: abg-ir.cc:4769
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:4797
friend void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5368
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
Definition: abg-ir.cc:4557
void set_location(const location &l)
Set the location for a given declaration.
Definition: abg-ir.cc:4467
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
Definition: abg-ir.cc:4502
void set_visibility(visibility v)
Setter for the visibility of the decl.
Definition: abg-ir.cc:4608
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4374
visibility get_visibility() const
Getter for the visibility of the decl.
Definition: abg-ir.cc:4601
visibility
ELF visibility.
Definition: abg-ir.h:1597
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Definition: abg-ir.cc:4820
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:5060
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition: abg-ir.cc:4785
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition: abg-ir.cc:4584
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5339
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6465
virtual ~decl_base()
Destructor of the decl_base type.
Definition: abg-ir.cc:5048
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:5033
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:4628
bool get_is_anonymous_or_has_anonymous_parent() const
Definition: abg-ir.cc:4525
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
Definition: abg-ir.cc:4514
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:4401
friend bool equals(const decl_base &, const decl_base &, change_kind *)
Compares two instances of decl_base.
Definition: abg-ir.cc:4962
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4360
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:4670
The abstraction for a data member context relationship. This relates a data member to its parent clas...
Definition: abg-ir.h:2966
const var_decl * get_anonymous_data_member() const
Return a non-nil value if this data member context relationship has an anonymous data member....
Definition: abg-ir.cc:3168
void set_anonymous_data_member(var_decl *)
Set the containing anonymous data member of this data member context relationship....
Definition: abg-ir.cc:3178
The abstraction of the version of an ELF symbol.
Definition: abg-ir.h:1203
version & operator=(const version &o)
Assign a version to the current one.
Definition: abg-ir.cc:3081
bool operator==(const version &o) const
Compares the current version against another one.
Definition: abg-ir.cc:3063
bool is_default() const
Getter for the 'is_default' property of the version.
Definition: abg-ir.cc:3043
const string & str() const
Getter for the version name.
Definition: abg-ir.cc:3029
bool operator!=(const version &o) const
Inequality operator.
Definition: abg-ir.cc:3072
Abstraction of an elf symbol.
Definition: abg-ir.h:932
const abg_compat::optional< std::string > & get_namespace() const
Getter of the 'namespace' property.
Definition: abg-ir.cc:2166
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:2489
elf_symbol_sptr get_next_common_instance() const
Get the next common instance of the current common symbol.
Definition: abg-ir.cc:2384
type get_type() const
Getter for the type of the current instance of elf_symbol.
Definition: abg-ir.cc:2000
const elf_symbol_sptr get_main_symbol() const
Get the main symbol of an alias chain.
Definition: abg-ir.cc:2221
void set_is_in_ksymtab(bool is_in_ksymtab)
Setter of the 'is-in-ksymtab' property.
Definition: abg-ir.cc:2145
bool has_aliases() const
Check if the current elf_symbol has an alias.
Definition: abg-ir.cc:2250
void set_name(const string &n)
Setter for the name of the current intance of elf_symbol.
Definition: abg-ir.cc:1990
bool is_suppressed() const
Getter for the 'is-suppressed' property.
Definition: abg-ir.cc:2182
binding
The binding of a symbol.
Definition: abg-ir.h:949
int get_number_of_aliases() const
Get the number of aliases to this elf symbol.
Definition: abg-ir.cc:2257
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:2510
void set_binding(binding b)
Setter for the binding of the current instance of elf_symbol.
Definition: abg-ir.cc:2035
void add_common_instance(const elf_symbol_sptr &)
Add a common instance to the current common elf symbol.
Definition: abg-ir.cc:2395
void add_alias(const elf_symbol_sptr &)
Add an alias to the current elf symbol.
Definition: abg-ir.cc:2274
void set_is_suppressed(bool is_suppressed)
Setter for the 'is-suppressed' property.
Definition: abg-ir.cc:2191
bool is_variable() const
Test if the current instance of elf_symbol is a variable symbol or not.
Definition: abg-ir.cc:2123
elf_symbol_sptr update_main_symbol(const std::string &)
Update the main symbol for a group of aliased symbols.
Definition: abg-ir.cc:2320
void set_size(size_t)
Setter of the size of the symbol.
Definition: abg-ir.cc:2021
const string & get_name() const
Getter for the name of the elf_symbol.
Definition: abg-ir.cc:1983
binding get_binding() const
Getter for the binding of the current instance of elf_symbol.
Definition: abg-ir.cc:2028
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:2576
bool is_function() const
Test if the current instance of elf_symbol is a function symbol or not.
Definition: abg-ir.cc:2114
type
The type of a symbol.
Definition: abg-ir.h:936
void set_version(const version &v)
Setter for the version of the current instance of elf_symbol.
Definition: abg-ir.cc:2049
const abg_compat::optional< uint32_t > & get_crc() const
Getter of the 'crc' property.
Definition: abg-ir.cc:2152
void set_visibility(visibility v)
Setter of the visibility of the current instance of elf_symbol.
Definition: abg-ir.cc:2060
bool does_alias(const elf_symbol &) const
Test if the current symbol aliases another one.
Definition: abg-ir.cc:2635
bool is_main_symbol() const
Tests whether this symbol is the main symbol.
Definition: abg-ir.cc:2235
void set_crc(const abg_compat::optional< uint32_t > &crc)
Setter of the 'crc' property.
Definition: abg-ir.cc:2159
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:1906
visibility
The visibility of the symbol.
Definition: abg-ir.h:958
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition: abg-ir.cc:2042
bool is_common_symbol() const
Return true if the symbol is a common one.
Definition: abg-ir.cc:2353
void set_index(size_t)
Setter for the index.
Definition: abg-ir.cc:1976
visibility get_visibility() const
Getter of the visibility of the current instance of elf_symbol.
Definition: abg-ir.cc:2068
bool has_other_common_instances() const
Return true if this common common symbol has other common instances.
Definition: abg-ir.cc:2369
size_t get_index() const
Getter for the index.
Definition: abg-ir.cc:1969
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
Definition: abg-ir.cc:2440
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:2467
const environment & get_environment() const
Getter of the environment used by the current instance of elf_symbol.
Definition: abg-ir.cc:1962
void set_type(type t)
Setter for the type of the current instance of elf_symbol.
Definition: abg-ir.cc:2007
bool is_public() const
Test if the current instance of elf_symbol is public or not.
Definition: abg-ir.cc:2098
bool is_in_ksymtab() const
Getter of the 'is-in-ksymtab' property.
Definition: abg-ir.cc:2137
size_t get_size() const
Getter of the size of the symbol.
Definition: abg-ir.cc:2014
bool is_defined() const
Test if the current instance of elf_symbol is defined or not.
Definition: abg-ir.cc:2076
void set_namespace(const abg_compat::optional< std::string > &ns)
Setter of the 'namespace' property.
Definition: abg-ir.cc:2173
elf_symbol_sptr get_next_alias() const
Get the next alias of the current symbol.
Definition: abg-ir.cc:2242
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:2621
The abstraction of an enumerator.
Definition: abg-ir.h:2844
enumerator()
Default constructor of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:20396
bool operator!=(const enumerator &other) const
Inequality operator.
Definition: abg-ir.cc:20456
void set_name(const string &n)
Setter for the name of enum_type_decl::enumerator.
Definition: abg-ir.cc:20498
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition: abg-ir.cc:20520
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition: abg-ir.cc:20465
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition: abg-ir.cc:20527
void set_value(int64_t v)
Setter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:20513
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:20482
int64_t get_value() const
Getter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:20506
bool operator==(const enumerator &other) const
Equality operator.
Definition: abg-ir.cc:20443
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:20427
Abstracts a declaration for an enum type.
Definition: abg-ir.h:2756
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition: abg-ir.h:2772
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:19834
virtual ~enum_type_decl()
Destructor for the enum type declaration.
Definition: abg-ir.cc:19947
const enumerators & get_enumerators() const
Definition: abg-ir.cc:19847
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
Definition: abg-ir.cc:19859
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19925
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition: abg-ir.cc:19842
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:20317
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:19900
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:3415
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:3482
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:3562
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:3699
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:3292
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:3514
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
Definition: abg-ir.cc:3343
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:3311
const config & get_config() const
Getter of the general configuration object.
Definition: abg-ir.cc:3552
environment()
Default constructor of the environment type.
Definition: abg-ir.cc:3193
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition: abg-ir.cc:3355
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:3722
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:3330
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:3451
virtual ~environment()
Destructor for the environment type.
Definition: abg-ir.cc:3198
bool canonicalization_started() const
Getter of a flag saying if the canonicalization process has started or not.
Definition: abg-ir.cc:3382
interned_string intern(const string &) const
Do intern a string.
Definition: abg-ir.cc:3545
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:3588
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Definition: abg-ir.cc:3206
Abstraction of a function parameter.
Definition: abg-ir.h:3287
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
Definition: abg-ir.cc:23204
interned_string get_type_name() const
Definition: abg-ir.cc:23003
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition: abg-ir.cc:23041
const string get_type_pretty_representation() const
Definition: abg-ir.cc:23022
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition: abg-ir.cc:23180
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:23224
Abstraction for a function declaration.
Definition: abg-ir.h:3117
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3139
string get_pretty_representation_of_declarator(bool internal=false) const
Compute and return the pretty representation for the part of the function declaration that starts at ...
Definition: abg-ir.cc:22404
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition: abg-ir.cc:22475
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:22865
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition: abg-ir.cc:22555
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition: abg-ir.cc:22780
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition: abg-ir.cc:22441
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition: abg-ir.cc:22460
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:22267
const type_base_sptr get_return_type() const
Definition: abg-ir.cc:22536
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition: abg-ir.cc:22568
const std::vector< parameter_sptr > & get_parameters() const
Definition: abg-ir.cc:22541
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition: abg-ir.cc:22548
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition: abg-ir.cc:22497
virtual ~function_decl()
Destructor of the function_decl type.
Definition: abg-ir.cc:22881
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:22513
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition: abg-ir.cc:22766
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3142
bool is_declared_inline() const
Test if the function was declared inline.
Definition: abg-ir.cc:22520
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:22336
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:22796
Abstract a function template declaration.
Definition: abg-ir.h:3704
binding get_binding() const
Get the binding of the function template.
Definition: abg-ir.cc:27544
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
Definition: abg-ir.cc:27526
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition: abg-ir.cc:27537
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:27604
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition: abg-ir.cc:27553
Abstraction of a function type.
Definition: abg-ir.h:3372
shared_ptr< function_decl::parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3382
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:21509
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:21928
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition: abg-ir.cc:21616
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:21825
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:21416
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition: abg-ir.cc:21887
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:21601
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition: abg-ir.cc:21578
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition: abg-ir.cc:21845
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:21557
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition: abg-ir.cc:21520
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition: abg-ir.cc:21528
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:21803
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition: abg-ir.cc:21537
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3384
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:21911
This abstracts the global scope of a given translation unit.
Definition: abg-ir.h:1953
The base class for the visitor type hierarchy used for traversing a translation unit.
Definition: abg-ir.h:4761
bool allow_visiting_already_visited_type_node() const
Get if the walker using this visitor is allowed to re-visit a type node that was previously visited o...
Definition: abg-ir.cc:29494
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition: abg-ir.cc:29543
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition: abg-ir.cc:29533
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition: abg-ir.cc:29473
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition: abg-ir.cc:29504
The entry point to manage locations.
Definition: abg-ir.h:449
location create_new_location(const std::string &fle, size_t lne, size_t col)
Insert the triplet representing a source locus into our internal vector of location triplet....
Definition: abg-ir.cc:507
void expand_location(const location &location, std::string &path, unsigned &line, unsigned &column) const
Given an instance of location type, return the triplet {path,line,column} that represents the source ...
Definition: abg-ir.cc:530
The source location of a token.
Definition: abg-ir.h:307
bool get_is_artificial() const
Test if the location is artificial.
Definition: abg-ir.h:348
unsigned get_value() const
Get the value of the location.
Definition: abg-ir.h:395
string expand(void) const
Expand the location into a string.
Definition: abg-ir.cc:472
void expand(std::string &path, unsigned &line, unsigned &column) const
Expand the current location into a tripplet file path, line and column number.
Definition: abg-ir.cc:452
Abstraction of a member function context relationship. This relates a member function to its parent c...
Definition: abg-ir.h:4447
bool is_constructor() const
Getter for the 'is-constructor' property.
Definition: abg-ir.h:4525
bool is_const() const
Getter for the 'is-const' property.
Definition: abg-ir.h:4560
size_t vtable_offset() const
Getter for the vtable offset property.
Definition: abg-ir.h:4505
bool is_destructor() const
Getter for the 'is-destructor' property.
Definition: abg-ir.h:4542
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition: abg-ir.h:3791
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition: abg-ir.h:3811
bool get_is_static() const
Definition: abg-ir.h:3823
Abstracts a member class template template.
Definition: abg-ir.h:4652
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
Definition: abg-ir.cc:26175
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26260
Abstract a member function template.
Definition: abg-ir.h:4597
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26154
Abstraction of the declaration of a method.
Definition: abg-ir.h:3839
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
Definition: abg-ir.cc:6362
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
Definition: abg-ir.cc:25126
const method_type_sptr get_type() const
Definition: abg-ir.cc:25153
Abstracts the type of a class member function.
Definition: abg-ir.h:3458
void set_class_type(const class_or_union_sptr &t)
Sets the class type of the current instance of method_type.
Definition: abg-ir.cc:22129
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:22110
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition: abg-ir.cc:22161
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
Definition: abg-ir.cc:22176
virtual ~method_type()
The destructor of method_type.
Definition: abg-ir.cc:22209
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:22153
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition: abg-ir.cc:22120
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition: abg-ir.cc:22168
The abstraction of a namespace declaration.
Definition: abg-ir.h:2178
bool is_empty_or_has_empty_sub_namespaces() const
Test if the current namespace_decl is empty or contains empty namespaces itself.
Definition: abg-ir.cc:17038
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17069
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition: abg-ir.cc:16972
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition: abg-ir.cc:17024
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:17010
Abstracts non type template parameters.
Definition: abg-ir.h:3614
const type_base_sptr get_type() const
Getter for the type of the template parameter.
Definition: abg-ir.cc:27242
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:27247
The abstraction of a pointer type.
Definition: abg-ir.h:2321
void set_pointed_to_type(const type_base_sptr &)
Set the pointed-to type of the pointer.
Definition: abg-ir.cc:17731
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:17862
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:17721
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:17648
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17956
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition: abg-ir.cc:17798
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition: abg-ir.cc:17842
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition: abg-ir.cc:17849
The abstraction of a pointer-to-member type.
Definition: abg-ir.h:2456
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Get the qualified name for the current ptr_to_mbr_type.
Definition: abg-ir.cc:18632
virtual const interned_string & get_name() const
Getter of the name of the current ptr-to-mbr-type.
Definition: abg-ir.cc:18542
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18555
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:18575
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
Definition: abg-ir.cc:18616
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:18683
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
Definition: abg-ir.cc:18566
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
Definition: abg-ir.cc:18708
The abstraction of a qualified type.
Definition: abg-ir.h:2207
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation for the virtual qualified name builder for qualified_type_def.
Definition: abg-ir.cc:17374
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition: abg-ir.cc:17499
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition: abg-ir.cc:17238
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:17226
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:17487
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition: abg-ir.h:2226
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:17164
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition: abg-ir.cc:17478
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17447
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition: abg-ir.cc:17473
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition: abg-ir.cc:17492
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition: abg-ir.cc:17318
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition: abg-ir.cc:17141
The internal representation of an integral type.
Definition: abg-ir-priv.h:48
void set_modifiers(modifiers_type)
Setter of the modifiers bitmap of the real_type.
Definition: abg-ir.cc:16414
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
Definition: abg-ir.cc:16437
base_type get_base_type() const
Getter of the base type of the real_type.
Definition: abg-ir.cc:16400
bool operator==(const real_type &) const
Equality operator for the real_type.
Definition: abg-ir.cc:16424
real_type()
Default constructor of the real_type.
Definition: abg-ir.cc:16370
modifiers_type
The modifiers of the base types above. Several modifiers can be combined for a given base type....
Definition: abg-ir-priv.h:88
@ LONG_LONG_MODIFIER
The "long long" modifier.
Definition: abg-ir-priv.h:99
@ LONG_MODIFIER
The "long" modifier.
Definition: abg-ir-priv.h:97
@ SIGNED_MODIFIER
The "signed" modifier.
Definition: abg-ir-priv.h:91
@ UNSIGNED_MODIFIER
The "unsigned" modier.
Definition: abg-ir-priv.h:93
@ SHORT_MODIFIER
The "short" modifier.
Definition: abg-ir-priv.h:95
base_type
The possible base types of integral types. We might have forgotten many of these, so do not hesitate ...
Definition: abg-ir-priv.h:56
@ WCHAR_T_BASE_TYPE
The "wchar_t" base type.
Definition: abg-ir-priv.h:72
@ CHAR32_T_BASE_TYPE
The "char32_t" base type.
Definition: abg-ir-priv.h:70
@ FLOAT_BASE_TYPE
The "float" base type.
Definition: abg-ir-priv.h:66
@ BOOL_BASE_TYPE
The "bool" base type in C++ or "_Bool" in C11.
Definition: abg-ir-priv.h:62
@ CHAR_BASE_TYPE
The "char" base type.
Definition: abg-ir-priv.h:60
@ CHAR16_T_BASE_TYPE
The "char16_t base type.
Definition: abg-ir-priv.h:68
@ INT_BASE_TYPE
The "int" base type.
Definition: abg-ir-priv.h:58
@ ARRAY_SIZE_BASE_TYPE
The aray size type used by Clang.
Definition: abg-ir-priv.h:78
@ DOUBLE_BASE_TYPE
The "double" base type.
Definition: abg-ir-priv.h:64
modifiers_type get_modifiers() const
Getter of the modifiers bitmap of the real_type.
Definition: abg-ir.cc:16407
Abstracts a reference type.
Definition: abg-ir.h:2387
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Build and return the qualified name of the current instance of the reference_type_def.
Definition: abg-ir.cc:18291
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:18148
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:18050
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18413
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:18158
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition: abg-ir.cc:18233
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:18392
A declaration that introduces a scope.
Definition: abg-ir.h:1824
virtual size_t get_num_anonymous_member_classes() const
Getter for the number of anonymous classes contained in this scope.
Definition: abg-ir.cc:7745
void remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
Definition: abg-ir.cc:7954
void insert_member_type(type_base_sptr t, declarations::iterator before)
Insert a member type.
Definition: abg-ir.cc:7912
void add_member_type(type_base_sptr t)
Add a member type to the current instance of class_or_union.
Definition: abg-ir.cc:7929
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
Definition: abg-ir.cc:7763
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
Definition: abg-ir.cc:7798
std::vector< scope_decl_sptr > scopes
Convenience typedef for a vector of scope_decl_sptr.
Definition: abg-ir.h:1835
bool is_empty() const
Test if the current scope is empty.
Definition: abg-ir.cc:7812
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:8244
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
Definition: abg-ir.cc:7887
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:8022
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
Definition: abg-ir.h:1831
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:7681
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:8196
virtual void remove_member_decl(decl_base_sptr member)
Remove a declaration from the current scope.
Definition: abg-ir.cc:8047
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:7858
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:7898
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7705
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:7669
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
Definition: abg-ir.cc:7973
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:8274
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:8150
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7723
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
Definition: abg-ir.cc:7781
A type that introduces a scope.
Definition: abg-ir.h:2155
virtual bool traverse(ir_node_visitor &)
Traverses an instance of scope_type_decl, visiting all the sub-types and decls that it might contain.
Definition: abg-ir.cc:16931
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition: abg-ir.cc:16893
The base class of templates.
Definition: abg-ir.h:3519
const std::list< template_parameter_sptr > & get_template_parameters() const
Get the list of template parameters of the current instance of template_decl.
Definition: abg-ir.cc:26917
virtual ~template_decl()
Destructor.
Definition: abg-ir.cc:26942
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:26909
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:26951
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition: abg-ir.h:3551
virtual ~template_parameter()
Destructor.
Definition: abg-ir.cc:27071
bool operator!=(const template_parameter &) const
Inequality operator.
Definition: abg-ir.cc:27067
Abstracts a template template parameter.
Definition: abg-ir.h:3647
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:27320
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:1395
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:1310
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:1427
bool operator==(const translation_unit &) const
Compare the current translation unit against another one.
Definition: abg-ir.cc:1437
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
Definition: abg-ir.cc:1353
char get_address_size() const
Getter of the address size in this translation unit.
Definition: abg-ir.cc:1388
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:1291
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
Definition: abg-ir.cc:1337
void set_language(language l)
Setter of the language of the source code of the translation unit.
Definition: abg-ir.cc:1254
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:1463
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
Definition: abg-ir.cc:1190
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
Definition: abg-ir.cc:1377
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:1411
const std::string & get_path() const
Get the path of the current translation unit.
Definition: abg-ir.cc:1267
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:1302
location_manager & get_loc_mgr()
Getter of the location manager for the current translation unit.
Definition: abg-ir.cc:1361
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
Definition: abg-ir.cc:1278
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse virtual function.
Definition: abg-ir.cc:1497
language
The language of the translation unit.
Definition: abg-ir.h:708
bool operator!=(const translation_unit &) const
Inequality operator.
Definition: abg-ir.cc:1452
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:1233
const environment & get_environment() const
Getter of the environment of the current translation_unit.
Definition: abg-ir.cc:1240
const type_maps & get_types() const
Getter of the types of the current translation_unit.
Definition: abg-ir.cc:1217
language get_language() const
Getter of the language of the source code of the translation unit.
Definition: abg-ir.cc:1247
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:1974
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
Definition: abg-ir.cc:16000
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition: abg-ir.cc:15976
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition: abg-ir.cc:16079
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:15946
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:16105
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:15679
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition: abg-ir.cc:16072
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition: abg-ir.cc:16065
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition: abg-ir.cc:16055
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition: abg-ir.cc:16093
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition: abg-ir.cc:16086
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition: abg-ir.cc:15960
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition: abg-ir.h:3682
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition: abg-ir.cc:27426
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition: abg-ir.cc:27433
A basic type declaration that introduces no scope.
Definition: abg-ir.h:2089
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation for the virtual qualified name builder for type_decl.
Definition: abg-ir.cc:16725
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:16565
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:16804
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:16663
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:16619
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:16784
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:1126
istring_type_base_wptrs_map_type & pointer_types()
Getter for the map that associates the name of a pointer type to the vector of instances of pointer_t...
Definition: abg-ir.cc:677
const istring_type_base_wptrs_map_type & basic_types() const
Getter for the map that associates the name of a basic type to the vector instances of type_decl_sptr...
Definition: abg-ir.cc:595
const istring_type_base_wptrs_map_type & subrange_types() const
Getter for the map that associates the name of a subrange type to the vector of instances of array_ty...
Definition: abg-ir.cc:740
The base class of both types and declarations.
Definition: abg-ir.h:1377
void set_translation_unit(translation_unit *)
Set the translation_unit this ABI artifact belongs to.
Definition: abg-ir.cc:4102
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:3915
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
Definition: abg-ir.cc:3904
location & get_artificial_location() const
Getter of the artificial location of the artifact.
Definition: abg-ir.cc:4062
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
Definition: abg-ir.cc:4069
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Definition: abg-ir.cc:4094
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:413
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:4015
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
Definition: abg-ir.cc:3938
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:3927
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
Definition: abg-ir.cc:4127
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
Definition: abg-ir.cc:3958
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition: abg-ir.cc:10769
friend hash_t peek_hash_value(const type_or_decl_base &)
Get the hash value associated to an IR node.
Definition: abg-ir.cc:28029
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:3993
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10374
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
Definition: abg-ir.cc:4044
type_or_decl_kind
This is a bitmap type which instance is meant to contain the runtime type of a given ABI artifact....
Definition: abg-ir.h:1389
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition: abg-ir.cc:4026
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
Definition: abg-ir.cc:10447
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Definition: abg-ir.cc:4119
Abstracts a type template parameter.
Definition: abg-ir.h:3580
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:27113
The abstraction of a typedef declaration.
Definition: abg-ir.h:2898
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation of the virtual "get_qualified_name" method.
Definition: abg-ir.cc:20782
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition: abg-ir.cc:20767
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition: abg-ir.cc:20622
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:20609
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:20814
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition: abg-ir.cc:20760
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:20702
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition: abg-ir.cc:20639
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:20743
Abstracts a union type declaration.
Definition: abg-ir.h:4372
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition: abg-ir.cc:26594
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26711
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition: abg-ir.cc:26651
virtual ~union_decl()
Destructor of the union_decl type.
Definition: abg-ir.cc:26784
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:26618
Abstracts a variable declaration.
Definition: abg-ir.h:3020
binding get_binding() const
Getter of the binding of the variable.
Definition: abg-ir.cc:20928
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition: abg-ir.cc:20910
void set_binding(binding b)
Setter of the binding of the variable.
Definition: abg-ir.cc:20935
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
Definition: abg-ir.cc:6023
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
Definition: abg-ir.cc:20973
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:21226
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:20921
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6168
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:20903
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:21388
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:21365
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition: abg-ir.cc:20950
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:20966
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition: abg-ir.cc:21161
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:21256
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:21180
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.
Definition: abg-hash.h:41
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:11372
real_type::modifiers_type operator~(real_type::modifiers_type l)
Bitwise one's complement operator for real_type::modifiers_type.
Definition: abg-ir.cc:16162
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:10966
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:19959
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:13455
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:12553
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition: abg-ir.cc:28056
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Definition: abg-ir.cc:6278
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
Definition: abg-ir.cc:7088
hash_t peek_hash_value(const type_or_decl_base &artefact)
Get the hash value associated to an IR node.
Definition: abg-ir.cc:28029
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:28007
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:11904
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:5605
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:5978
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:11232
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:8292
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:10341
class_decl_sptr is_class_type(const type_or_decl_base_sptr &d)
Test whether a type is a class.
Definition: abg-ir.cc:10787
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:11691
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:15838
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:5399
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:11149
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:9960
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:9943
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition: abg-fwd.h:269
access_specifier
Access specifier for class members.
Definition: abg-ir.h:888
size_t get_canonical_type_index(const type_base &t)
Getter of the canonical type index of a given type.
Definition: abg-ir.cc:345
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:13889
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:13370
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:8822
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition: abg-ir.cc:22847
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:11131
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:15420
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:14293
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:13783
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition: abg-ir.cc:6402
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:13938
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:13296
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:11326
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:10751
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:11407
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:26867
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:25382
void pop_composite_type_comparison_operands(const type_base &left, const type_base &right)
Pop a pair of operands from the stack of operands to the current type comparison.
Definition: abg-ir.cc:332
bool equals_modulo_cv_qualifier(const array_type_def *l, const array_type_def *r)
Test if two variables are equals modulo CV qualifiers.
Definition: abg-ir.cc:19530
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:13637
const scope_decl * is_scope_decl(const decl_base *d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5269
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
Definition: abg-ir.cc:7439
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:9470
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10434
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:13543
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition: abg-ir.cc:5696
bool is_template_parameter(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter.
Definition: abg-ir.cc:10308
translation_unit * get_translation_unit(const type_or_decl_base_sptr &decl)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:10170
bool is_anonymous_data_member(const var_decl &d)
Test if a var_decl is an anonymous data member.
Definition: abg-ir.cc:5798
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
Definition: abg-ir.cc:1509
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:10616
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:6997
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:26069
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
Definition: abg-ir.cc:5223
scope_decl * get_type_scope(const type_base_sptr &t)
Get the scope of a given type.
Definition: abg-ir.cc:8641
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:11810
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition: abg-ir.h:897
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:13725
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:13180
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:9857
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
Definition: abg-ir.cc:28127
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:12895
location get_location(const decl_base_sptr &decl)
Get the location of a given declaration.
Definition: abg-ir.cc:8603
const typedef_decl * is_typedef(const type_or_decl_base *t)
Test whether a type is a typedef.
Definition: abg-ir.cc:10668
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:16355
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:11638
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
Definition: abg-ir.cc:8299
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:7210
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:10025
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
Definition: abg-ir.cc:7372
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:13668
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
Definition: abg-ir.h:1332
@ LOCAL_TYPE_CHANGE_KIND
This means that a given IR artifact has a local type change.
Definition: abg-ir.h:1336
@ SUBTYPE_CHANGE_KIND
This means that a given IR artifact has changes in some of its sub-types, with respect to the other a...
Definition: abg-ir.h:1352
@ LOCAL_NON_TYPE_CHANGE_KIND
This means that a given IR artifact has a local non-type change. That is a change that is carried by ...
Definition: abg-ir.h:1341
var_decl_sptr find_last_data_member_matching_regexp(const class_or_union &t, const regex::regex_t_sptr &regex)
Find the last data member of a class or union which name matches a regular expression.
Definition: abg-ir.cc:28608
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:11306
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:5542
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:12915
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:11001
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:9502
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
Definition: abg-ir.cc:5303
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:1692
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:5923
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:11930
void unmark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being not compared anymore.
Definition: abg-ir.cc:1054
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:10010
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:5639
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:11060
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition: abg-ir.cc:10760
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:14866
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:6539
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:11503
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:13205
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:13843
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:10944
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:14166
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:9104
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:13808
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:7110
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:7157
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:14059
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:5882
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:5938
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:10574
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition: abg-ir.cc:6306
const function_type * is_function_type(const type_or_decl_base *t)
Test whether a type is a function_type.
Definition: abg-ir.cc:11473
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
Definition: abg-ir.cc:7046
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:28271
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:11553
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:10991
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:11622
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:5566
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:7233
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:6362
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:8542
bool is_anonymous_type(const type_base_sptr &t)
Test if a given type is anonymous.
Definition: abg-ir.cc:10510
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:6739
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:958
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:2888
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:11673
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:11766
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:10536
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10414
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:11562
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:11453
scope_decl_sptr is_scope_decl(const decl_base_sptr &d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5279
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:8510
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5368
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:11603
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition: abg-ir.cc:10638
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:10462
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
Definition: abg-ir.cc:6140
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
Definition: abg-ir.cc:9651
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:14949
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:2760
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:6941
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:21034
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:13155
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:3272
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:7335
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:10425
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:11246
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:2969
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
Definition: abg-ir.cc:1655
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:10701
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:10364
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:11533
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:13408
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:6391
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:6914
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:8318
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:3189
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:10710
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:28219
bool elf_symbols_alias(const elf_symbol &s1, const elf_symbol &s2)
Test if two symbols alias.
Definition: abg-ir.cc:2691
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:10277
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:9870
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:8579
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:27920
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:11734
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:11833
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:13502
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:2921
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:6424
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:5814
namespace_decl * is_namespace(const decl_base *d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:11682
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:7296
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:11345
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:29806
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition: abg-ir.cc:11839
bool try_canonical_compare(const T *l, const T *r)
Compare two types by comparing their canonical types if present.
Definition: abg-ir.cc:892
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:27857
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:1669
function_decl::parameter * is_function_parameter(const type_or_decl_base *tod)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10351
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:13315
class_or_union * is_at_class_scope(const decl_base &decl)
Tests whether a given decl is at class scope.
Definition: abg-ir.cc:10257
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
Definition: abg-ir.cc:4962
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6168
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:12862
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:2946
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:12167
weak_ptr< elf_symbol > elf_symbol_wptr
A convenience typedef for a weak pointer to elf_symbol.
Definition: abg-ir.h:900
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition: abg-ir.cc:6334
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:8859
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:14323
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:20040
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:9061
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
Definition: abg-ir.cc:7125
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:1579
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:10719
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:10931
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:14113
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:6053
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
Definition: abg-ir.cc:6097
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:6192
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:28540
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:11654
string get_pretty_representation(const method_type_sptr method, bool internal)
Get the pretty representation of a method type.
Definition: abg-ir.cc:9306
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
Definition: abg-ir.cc:1641
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10374
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:27895
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:25215
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition: abg-ir.cc:5288
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:9326
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:11823
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:8274
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:28562
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:10521
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5339
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:5991
const interned_string & get_node_name(var_decl_sptr node)
Gets the name of a var_decl node.
Definition: abg-ir.cc:12620
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:6604
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition: abg-ir.cc:6008
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:10544
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:1416
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:10234
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6465
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:11074
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:9623
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:10119
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:5854
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
Definition: abg-ir.cc:8590
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:11114
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:10130
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:8936
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:11705
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:11513
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:11040
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition: abg-ir.cc:9889
bool is_global_scope(const shared_ptr< scope_decl >scope)
Tests whether if a given scope is the global scope.
Definition: abg-ir.cc:10198
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:13763
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:6887
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:8889
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:11789
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
Definition: abg-ir.cc:10179
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:8480
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:6154
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:11166
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition: abg-ir.cc:5437
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:28587
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition: abg-ir.cc:10047
bool is_at_global_scope(const decl_base *decl)
Tests whether a given declaration is at global scope.
Definition: abg-ir.cc:10225
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26315
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:11718
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:28497
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:8998
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:8396
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
Definition: abg-ir.cc:7414
bool compare_using_locations(const decl_base *f, const decl_base *s)
Compare decls using their locations.
Definition: abg-ir.cc:3237
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:9593
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:1096
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:13988
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:11664
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
Definition: abg-ir.cc:1678
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
Definition: abg-ir.cc:15023
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition: abg-ir.cc:28092
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:14760
void mark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being compared.
Definition: abg-ir.cc:1019
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:8659
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:7492
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:8973
decl_base_sptr is_decl(const type_or_decl_base_sptr &d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10403
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:1711
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:8837
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
Definition: abg-ir.cc:10299
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10322
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:2979
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:27879
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:14231
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:10849
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:11483
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:11433
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:11186
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:8467
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol.
Definition: abg-ir.h:918
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:8556
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:3220
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:24328
decl_base_sptr get_type_declaration(const type_base_sptr t)
Get the declaration for a given type.
Definition: abg-ir.cc:10065
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:7182
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:15053
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:11098
type_decl * is_real_type(const type_or_decl_base *t)
Test if a type is a real type.
Definition: abg-ir.cc:10554
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:13470
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition: abg-ir.cc:5241
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:4893
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:11443
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:11030
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:11290
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition: abg-ir.cc:6219
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:6249
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:10980
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:13600
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:7607
Hasher for the class_or_union type.
Definition: abg-hash.h:230
bool is_printing_flat_representation() const
Getter of the 'is_printing_flat_representation_' boolean.
Definition: abg-ir-priv.h:1792
void unset_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to false.
Definition: abg-ir-priv.h:1782
void set_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to true.
Definition: abg-ir-priv.h:1772
A functor to sort decls somewhat topologically. That is, types are sorted in a way that makes the one...
Definition: abg-ir-priv.h:979
The private data of the environment type.
Definition: abg-ir-priv.h:538
Equality functor for instances of function_decl.
Definition: abg-ir.h:4722
The type of the private data of the function_type type.
Definition: abg-ir-priv.h:1800
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:29456
The hashing functor for member_base.
Definition: abg-hash.h:223
Private type to hold private members of translation_unit.
Definition: abg-ir-priv.h:151
Hash functor for instances of type_base.
Definition: abg-hash.h:91
Definition of the private data of type_base.
Definition: abg-ir-priv.h:461
The private data of type_or_decl_base.
Definition: abg-ir-priv.h:187
A predicate for deep equality of instances of shared_ptr<type_base>
Definition: abg-ir.h:2067
A functor to sort types somewhat topologically. That is, types are sorted in a way that makes the one...
Definition: abg-ir-priv.h:1085
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.