libabigail
Loading...
Searching...
No Matches
abg-ir.cc
Go to the documentation of this file.
1// C++ -*-
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// -*- Mode: C++ -*-
4
5// Copyright (C) 2013-2025 Red Hat, Inc.
6//
7//Author: Dodji Seketeli
8
9/// @file
10///
11/// Definitions for the Internal Representation artifacts of libabigail.
12
13#include <cxxabi.h>
14#include <cstdint>
15#include <functional>
16#include <iterator>
17#include <memory>
18#include <sstream>
19#include <typeinfo>
20#include <unordered_map>
21#include <utility>
22#include <vector>
23
24#include "abg-internal.h"
25// <headers defining libabigail's API go under here>
26ABG_BEGIN_EXPORT_DECLARATIONS
27
28#include "abg-interned-str.h"
29#include "abg-ir.h"
30#include "abg-corpus.h"
31#include "abg-regex.h"
32
33ABG_END_EXPORT_DECLARATIONS
34// </headers defining libabigail's API>
35
36#include "abg-corpus-priv.h"
37#include "abg-comp-filter.h"
38#include "abg-ir-priv.h"
39
40namespace
41{
42/// This internal type is a tree walking that is used to set the
43/// qualified name of a tree of decls and types. It used by the
44/// function update_qualified_name().
45class qualified_name_setter : public abigail::ir::ir_node_visitor
46{
47
48public:
49 bool
50 do_update(abigail::ir::decl_base* d);
51
52 bool
53 visit_begin(abigail::ir::decl_base* d);
54
55 bool
56 visit_begin(abigail::ir::type_base* d);
57}; // end class qualified_name_setter
58
59}// end anon namespace
60
61namespace abigail
62{
63
64// Inject.
65using std::string;
66using std::list;
67using std::vector;
68using std::unordered_map;
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
71
72/// Convenience typedef for a map of string -> string*.
73typedef unordered_map<string, string*> pool_map_type;
74
75/// The type of the private data structure of type @ref
76/// intered_string_pool.
77struct interned_string_pool::priv
78{
79 pool_map_type map;
80}; //end struc struct interned_string_pool::priv
81
82/// Default constructor.
84 : priv_(new priv)
85{
86 priv_->map[""] = 0;
87}
88
89/// Test if the interned string pool already contains a string with a
90/// given value.
91///
92/// @param s the string to test for.
93///
94/// @return true if the pool contains a string with the value @p s.
95bool
97{return priv_->map.find(s) != priv_->map.end();}
98
99/// Get a pointer to the interned string which has a given value.
100///
101/// @param s the value of the interned string to look for.
102///
103/// @return a pointer to the raw string of characters which has the
104/// value of @p s. Or null if no string with value @p s was interned.
105const char*
107{
108 unordered_map<string, string*>::const_iterator i =
109 priv_->map.find(s);
110 if (i == priv_->map.end())
111 return 0;
112 if (i->second)
113 return i->second->c_str();
114 return "";
115}
116
117/// Create an interned string with a given value.
118///
119/// @param str_value the value of the interned string to create.
120///
121/// @return the new created instance of @ref interned_string created.
123interned_string_pool::create_string(const std::string& str_value)
124{
125 string*& result = priv_->map[str_value];
126 if (!result && !str_value.empty())
127 result = new string(str_value);
128 return interned_string(result);
129}
130
131/// Destructor.
133{
134 for (pool_map_type::iterator i = priv_->map.begin();
135 i != priv_->map.end();
136 ++i)
137 if (i->second)
138 delete i->second;
139}
140
141/// Equality operator.
142///
143/// @param l the instance of std::string on the left-hand-side of the
144/// equality operator.
145///
146/// @param r the instance of @ref interned_string on the
147/// right-hand-side of the equality operator.
148///
149/// @return true iff the two string are equal.
150bool
151operator==(const std::string& l, const interned_string& r)
152{return r.operator==(l);}
153
154bool
155operator!=(const std::string& l, const interned_string& r)
156{return !(l == r);}
157
158/// Streaming operator.
159///
160/// Streams an instance of @ref interned_string to an output stream.
161///
162/// @param o the destination output stream.
163///
164/// @param s the instance of @ref interned_string to stream out.
165///
166/// @return the output stream this function just streamed to.
167std::ostream&
168operator<<(std::ostream& o, const interned_string& s)
169{
170 o << static_cast<std::string>(s);
171 return o;
172}
173
174/// Concatenation operator.
175///
176/// Concatenate two instances of @ref interned_string, builds an
177/// instance of std::string with the resulting string and return it.
178///
179/// @param s1 the first string to consider.
180///
181/// @param s2 the second string to consider.
182///
183/// @return the resuting concatenated string.
184std::string
185operator+(const interned_string& s1,const std::string& s2)
186{return static_cast<std::string>(s1) + s2;}
187
188/// Concatenation operator.
189///
190/// Concatenate two instances of @ref interned_string, builds an
191/// instance of std::string with the resulting string and return it.
192///
193/// @param s1 the first string to consider.
194///
195/// @param s2 the second string to consider.
196///
197/// @return the resuting concatenated string.
198std::string
199operator+(const std::string& s1, const interned_string& s2)
200{return s1 + static_cast<std::string>(s2);}
201
202namespace ir
203{
204
205static size_t
206hash_as_canonical_type_or_constant(const type_base *t);
207
208static bool
209has_generic_anonymous_internal_type_name(const decl_base *d);
210
211static interned_string
212get_generic_anonymous_internal_type_name(const decl_base *d);
213
214static string
215get_internal_real_type_name(const type_base*);
216
217static void
218update_qualified_name(decl_base * d);
219
220static void
221update_qualified_name(decl_base_sptr d);
222
223static interned_string
224pointer_declaration_name(const type_base* ptr,
225 const string& variable_name,
226 bool qualified, bool internal);
227
228static interned_string
229pointer_declaration_name(const type_base_sptr& ptr,
230 const string& variable_name,
231 bool qualified, bool internal);
232
233static interned_string
234ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
235 const string& variable_name,
236 bool qualified, bool internal);
237
238static interned_string
239ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
240 const string& variable_name,
241 bool qualified, bool internal);
242
243static interned_string
244array_declaration_name(const array_type_def* array,
245 const string& variable_name,
246 bool qualified, bool internal);
247
248static interned_string
249array_declaration_name(const array_type_def_sptr& array,
250 const string& variable_name,
251 bool qualified, bool internal);
252
253static void
254stream_pretty_representation_of_fn_parms(const function_type& fn_type,
255 ostream& o, bool qualified,
256 bool internal);
257static string
258add_outer_pointer_to_fn_type_expr(const type_base* pointer_to_fn,
259 const string& input, bool qualified,
260 bool internal);
261
262static string
263add_outer_pointer_to_fn_type_expr(const type_base_sptr& pointer_to_fn,
264 const string& input, bool qualified,
265 bool internal);
266
267static string
268add_outer_pointer_to_array_type_expr(const type_base* pointer_to_ar,
269 const string& input, bool qualified,
270 bool internal);
271
272static string
273add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
274 const string& input, bool qualified,
275 bool internal);
276
277static string
278add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
279 const string& input, bool qualified,
280 bool internal);
281
282static string
283add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
284 const string& input, bool qualified,
285 bool internal);
286
287static string
288add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
289 const string& input,
290 bool qualified, bool internal);
291
292void
293push_composite_type_comparison_operands(const type_base& left,
294 const type_base& right);
295
296void
297pop_composite_type_comparison_operands(const type_base& left,
298 const type_base& right);
299
300
301/// Push a pair of operands on the stack of operands of the current
302/// type comparison, during type canonicalization.
303///
304/// For more information on this, please look at the description of
305/// the environment::priv::right_type_comp_operands_ data member.
306///
307/// @param left the left-hand-side comparison operand to push.
308///
309/// @param right the right-hand-side comparison operand to push.
310void
312 const type_base& right)
313{
314 const environment& env = left.get_environment();
315 env.priv_->push_composite_type_comparison_operands(&left, &right);
316}
317
318/// Pop a pair of operands from the stack of operands to the current
319/// type comparison.
320///
321/// For more information on this, please look at the description of
322/// the environment::privright_type_comp_operands_ data member.
323///
324/// @param left the left-hand-side comparison operand we expect to
325/// pop from the top of the stack. If this doesn't match the
326/// operand found on the top of the stack, the function aborts.
327///
328/// @param right the right-hand-side comparison operand we expect to
329/// pop from the bottom of the stack. If this doesn't match the
330/// operand found on the top of the stack, the function aborts.
331void
333 const type_base& right)
334{
335 const environment& env = left.get_environment();
336 env.priv_->pop_composite_type_comparison_operands(&left, &right);
337}
338
339/// Getter of the canonical type index of a given type.
340///
341/// @param t the type to consider.
342///
343/// @return the CTI of the type.
344size_t
346{return t.priv_->canonical_type_index;}
347
348/// Getter of the canonical type index of a given type.
349///
350/// @param t the type to consider.
351///
352/// @return the CTI of the type.
353size_t
356
357/// Getter of the canonical type index of a given type.
358///
359/// @param t the type to consider.
360///
361/// @return the CTI of the type.
362size_t
363get_canonical_type_index(const type_base_sptr& t)
364{return get_canonical_type_index(t.get());}
365
366/// Test if a type originates from a corpus.
367///
368/// Note that this function supports testing if a type originates from
369/// a corpus group.
370///
371/// @param t the type to consider.
372///
373/// @param c the corpus or corpus group to consider.
374///
375/// @return true iff the type @p t originates from the corpus (or
376/// group) @p c.
377bool
378type_originates_from_corpus(type_base_sptr t, corpus_sptr& c)
379{
380 bool result = false;
381 if (c && t->get_corpus())
382 {
383 corpus_group_sptr g = is_corpus_group(c);
384 if (g)
385 {
386 if (t->get_corpus()->get_group() == g.get())
387 result = true;
388 }
389 else
390 {
391 if (t->get_corpus() == c.get())
392 result = true;
393 }
394 }
395 return result;
396}
397/// @brief the location of a token represented in its simplest form.
398/// Instances of this type are to be stored in a sorted vector, so the
399/// type must have proper relational operators.
400class expanded_location
401{
402 string path_;
403 unsigned line_;
404 unsigned column_;
405
406 expanded_location();
407
408public:
409
410 friend class location_manager;
411
412 expanded_location(const string& path, unsigned line, unsigned column)
413 : path_(path), line_(line), column_(column)
414 {}
415
416 bool
417 operator==(const expanded_location& l) const
418 {
419 return (path_ == l.path_
420 && line_ == l.line_
421 && column_ && l.column_);
422 }
423
424 bool
425 operator<(const expanded_location& l) const
426 {
427 if (path_ < l.path_)
428 return true;
429 else if (path_ > l.path_)
430 return false;
431
432 if (line_ < l.line_)
433 return true;
434 else if (line_ > l.line_)
435 return false;
436
437 return column_ < l.column_;
438 }
439};
440
441/// Expand the location into a tripplet path, line and column number.
442///
443/// @param path the output parameter where this function sets the
444/// expanded path.
445///
446/// @param line the output parameter where this function sets the
447/// expanded line.
448///
449/// @param column the ouptut parameter where this function sets the
450/// expanded column.
451void
452location::expand(std::string& path, unsigned& line, unsigned& column) const
453{
454 if (!get_location_manager())
455 {
456 // We don't have a location manager maybe because this location
457 // was just freshly instanciated. We still want to be able to
458 // expand to default values.
459 path = "";
460 line = 0;
461 column = 0;
462 return;
463 }
464 get_location_manager()->expand_location(*this, path, line, column);
465}
466
467
468/// Expand the location into a string.
469///
470/// @return the string representing the location.
471string
473{
474 string path, result;
475 unsigned line = 0, column = 0;
476 expand(path, line, column);
477
478 std::ostringstream o;
479 o << path << ":" << line << ":" << column;
480 return o.str();
481}
482
483struct location_manager::priv
484{
485 /// This sorted vector contains the expanded locations of the tokens
486 /// coming from a given ABI Corpus. The index of a given expanded
487 /// location in the table gives us an integer that is used to build
488 /// instance of location types.
489 std::vector<expanded_location> locs;
490};
491
492location_manager::location_manager()
493 : priv_(new location_manager::priv)
494{}
495
496location_manager::~location_manager() = default;
497
498/// Insert the triplet representing a source locus into our internal
499/// vector of location triplet. Return an instance of location type,
500/// built from an real type that represents the index of the
501/// source locus triplet into our source locus table.
502///
503/// @param file_path the file path of the source locus
504/// @param line the line number of the source location
505/// @param col the column number of the source location
506location
507location_manager::create_new_location(const std::string& file_path,
508 size_t line,
509 size_t col)
510{
511 expanded_location l(file_path, line, col);
512
513 // Just append the new expanded location to the end of the vector
514 // and return its index. Note that indexes start at 1.
515 priv_->locs.push_back(l);
516 return location(priv_->locs.size(), this);
517}
518
519/// Given an instance of location type, return the triplet
520/// {path,line,column} that represents the source locus. Note that
521/// the location must have been previously created from the function
522/// location_manager::create_new_location, otherwise this function yields
523/// unexpected results, including possibly a crash.
524///
525/// @param location the instance of location type to expand
526/// @param path the resulting path of the source locus
527/// @param line the resulting line of the source locus
528/// @param column the resulting colum of the source locus
529void
531 std::string& path,
532 unsigned& line,
533 unsigned& column) const
534{
535 if (location.value_ == 0)
536 return;
537 expanded_location &l = priv_->locs[location.value_ - 1];
538 path = l.path_;
539 line = l.line_;
540 column = l.column_;
541}
542
543typedef unordered_map<function_type_sptr,
544 bool,
546 type_shared_ptr_equal> fn_type_ptr_map;
547
548// <type_maps stuff>
549
550struct type_maps::priv
551{
552 mutable istring_type_base_wptrs_map_type basic_types_;
553 mutable istring_type_base_wptrs_map_type class_types_;
554 mutable istring_type_base_wptrs_map_type union_types_;
555 mutable istring_type_base_wptrs_map_type enum_types_;
556 mutable istring_type_base_wptrs_map_type typedef_types_;
557 mutable istring_type_base_wptrs_map_type qualified_types_;
558 mutable istring_type_base_wptrs_map_type pointer_types_;
559 mutable istring_type_base_wptrs_map_type ptr_to_mbr_types_;
560 mutable istring_type_base_wptrs_map_type reference_types_;
561 mutable istring_type_base_wptrs_map_type array_types_;
562 mutable istring_type_base_wptrs_map_type subrange_types_;
563 mutable istring_type_base_wptrs_map_type function_types_;
564 mutable vector<type_base_wptr> sorted_types_;
565}; // end struct type_maps::priv
566
567type_maps::type_maps()
568 : priv_(new priv)
569{}
570
571type_maps::~type_maps() = default;
572
573/// Test if the type_maps is empty.
574///
575/// @return true iff the type_maps is empty.
576bool
578{
579 return (basic_types().empty()
580 && class_types().empty()
581 && union_types().empty()
582 && enum_types().empty()
583 && typedef_types().empty()
585 && pointer_types().empty()
587 && array_types().empty()
588 && subrange_types().empty()
589 && function_types().empty());
590}
591
592/// Getter for the map that associates the name of a basic type to the
593/// vector instances of type_decl_sptr that represents that type.
596{return priv_->basic_types_;}
597
598/// Getter for the map that associates the name of a basic type to the
599/// vector of instances of @ref type_decl_sptr that represents that
600/// type.
603{return priv_->basic_types_;}
604
605/// Getter for the map that associates the name of a class type to the
606/// vector of instances of @ref class_decl_sptr that represents that
607/// type.
610{return priv_->class_types_;}
611
612/// Getter for the map that associates the name of a class type to the
613/// vector of instances of @ref class_decl_sptr that represents that
614/// type.
617{return priv_->class_types_;}
618
619/// Getter for the map that associates the name of a union type to the
620/// vector of instances of @ref union_decl_sptr that represents that
621/// type.
624{return priv_->union_types_;}
625
626/// Getter for the map that associates the name of a union type to the
627/// vector of instances of @ref union_decl_sptr that represents that
628/// type.
631{return priv_->union_types_;}
632
633/// Getter for the map that associates the name of an enum type to the
634/// vector of instances of @ref enum_type_decl_sptr that represents
635/// that type.
638{return priv_->enum_types_;}
639
640/// Getter for the map that associates the name of an enum type to the
641/// vector of instances of @ref enum_type_decl_sptr that represents
642/// that type.
645{return priv_->enum_types_;}
646
647/// Getter for the map that associates the name of a typedef to the
648/// vector of instances of @ref typedef_decl_sptr that represents tha
649/// type.
652{return priv_->typedef_types_;}
653
654/// Getter for the map that associates the name of a typedef to the
655/// vector of instances of @ref typedef_decl_sptr that represents tha
656/// type.
659{return priv_->typedef_types_;}
660
661/// Getter for the map that associates the name of a qualified type to
662/// the vector of instances of @ref qualified_type_def_sptr.
665{return priv_->qualified_types_;}
666
667/// Getter for the map that associates the name of a qualified type to
668/// the vector of instances of @ref qualified_type_def_sptr.
671{return priv_->qualified_types_;}
672
673/// Getter for the map that associates the name of a pointer type to
674/// the vector of instances of @ref pointer_type_def_sptr that
675/// represents that type.
678{return priv_->pointer_types_;}
679
680/// Getter for the map that associates the name of a pointer-to-member
681/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
682/// represents that type.
685{return priv_->ptr_to_mbr_types_;}
686
687/// Getter for the map that associates the name of a pointer-to-member
688/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
689/// represents that type.
692{return priv_->ptr_to_mbr_types_;}
693
694/// Getter for the map that associates the name of a pointer type to
695/// the vector of instances of @ref pointer_type_def_sptr that
696/// represents that type.
699{return priv_->pointer_types_;}
700
701/// Getter for the map that associates the name of a reference type to
702/// the vector of instances of @ref reference_type_def_sptr that
703/// represents that type.
706{return priv_->reference_types_;}
707
708/// Getter for the map that associates the name of a reference type to
709/// the vector of instances of @ref reference_type_def_sptr that
710/// represents that type.
713{return priv_->reference_types_;}
714
715/// Getter for the map that associates the name of an array type to
716/// the vector of instances of @ref array_type_def_sptr that
717/// represents that type.
720{return priv_->array_types_;}
721
722/// Getter for the map that associates the name of an array type to
723/// the vector of instances of @ref array_type_def_sptr that
724/// represents that type.
727{return priv_->array_types_;}
728
729/// Getter for the map that associates the name of a subrange type to
730/// the vector of instances of @ref array_type_def::subrange_sptr that
731/// represents that type.
734{return priv_->subrange_types_;}
735
736/// Getter for the map that associates the name of a subrange type to
737/// the vector of instances of @ref array_type_def::subrange_sptr that
738/// represents that type.
741{return priv_->subrange_types_;}
742
743/// Getter for the map that associates the name of a function type to
744/// the vector of instances of @ref function_type_sptr that represents
745/// that type.
748{return priv_->function_types_;}
749
750/// Getter for the map that associates the name of a function type to
751/// the vector of instances of @ref function_type_sptr that represents
752/// that type.
755{return priv_->function_types_;}
756
757/// A comparison functor to compare/sort types based on their pretty
758/// representations.
759struct type_name_comp
760{
761 /// Comparison operator for two instances of @ref type_base.
762 ///
763 /// This compares the two types by lexicographically comparing their
764 /// pretty representation.
765 ///
766 /// @param l the left-most type to compare.
767 ///
768 /// @param r the right-most type to compare.
769 ///
770 /// @return true iff @p l < @p r.
771 bool
772 operator()(type_base *l, type_base *r) const
773 {
774 if (l == 0 && r == 0)
775 return false;
776
777 string l_repr = get_pretty_representation(l);
778 string r_repr = get_pretty_representation(r);
779 return l_repr < r_repr;
780 }
781
782 /// Comparison operator for two instances of @ref type_base.
783 ///
784 /// This compares the two types by lexicographically comparing their
785 /// pretty representation.
786 ///
787 /// @param l the left-most type to compare.
788 ///
789 /// @param r the right-most type to compare.
790 ///
791 /// @return true iff @p l < @p r.
792 bool
793 operator()(const type_base_sptr &l, const type_base_sptr &r) const
794 {return operator()(l.get(), r.get());}
795
796 /// Comparison operator for two instances of @ref type_base.
797 ///
798 /// This compares the two types by lexicographically comparing their
799 /// pretty representation.
800 ///
801 /// @param l the left-most type to compare.
802 ///
803 /// @param r the right-most type to compare.
804 ///
805 /// @return true iff @p l < @p r.
806 bool
807 operator()(const type_base_wptr &l, const type_base_wptr &r) const
808 {return operator()(type_base_sptr(l), type_base_sptr(r));}
809}; // end struct type_name_comp
810
811#ifdef WITH_DEBUG_SELF_COMPARISON
812
813/// This is a function called when the ABG_RETURN* macros defined
814/// below return false.
815///
816/// The purpose of this function is to ease debugging. To know where
817/// the equality functions first compare non-equal, we can just set a
818/// breakpoint on this notify_equality_failed function and run the
819/// equality functions. Because all the equality functions use the
820/// ABG_RETURN* macros to return their values, this function is always
821/// called when any of those equality function return false.
822///
823/// @param l the first operand of the equality.
824///
825/// @param r the second operand of the equality.
826static void
827notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
828 const type_or_decl_base &r __attribute__((unused)))
829{}
830
831/// This is a function called when the ABG_RETURN* macros defined
832/// below return false.
833///
834/// The purpose of this function is to ease debugging. To know where
835/// the equality functions first compare non-equal, we can just set a
836/// breakpoint on this notify_equality_failed function and run the
837/// equality functions. Because all the equality functions use the
838/// ABG_RETURN* macros to return their values, this function is always
839/// called when any of those equality function return false.
840///
841/// @param l the first operand of the equality.
842///
843/// @param r the second operand of the equality.
844static void
845notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
846 const type_or_decl_base *r __attribute__((unused)))
847{}
848
849#define ABG_RETURN_EQUAL(l, r) \
850 do \
851 { \
852 if (l != r) \
853 notify_equality_failed(l, r); \
854 return (l == r); \
855 } \
856 while(false)
857
858
859#define ABG_RETURN_FALSE \
860 do \
861 { \
862 notify_equality_failed(l, r); \
863 return false; \
864 } while(false)
865
866#define ABG_RETURN(value) \
867 do \
868 { \
869 if (value == false) \
870 notify_equality_failed(l, r); \
871 return value; \
872 } while (false)
873
874#else // WITH_DEBUG_SELF_COMPARISON
875
876#define ABG_RETURN_FALSE return false
877#define ABG_RETURN(value) return (value)
878#define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
879#endif
880
881/// Get the canonical type of a given type T* as a T*.
882///
883/// Note that normally, canonical types are returned as @ref
884/// type_base* (un-typed form, kind of). This function returns the
885/// canonical type as a T*, just like the T* it is looking at.
886///
887///
888/// @param t the type to consider.
889///
890/// @return either the canonical type of @p t or @p t itself if it
891/// doesn't have any canonical type.
892template<typename T>
893T*
895{
896 if (!t)
897 return nullptr;
898 if (type_base* type = t->get_naked_canonical_type())
899 return dynamic_cast<T*>(type);
900 return t;
901}
902
903/// Compare two types by comparing their canonical types if present.
904///
905/// If the canonical types are not present (because the types have not
906/// yet been canonicalized, for instance) then the types are compared
907/// structurally.
908///
909/// @param l the first type to take into account in the comparison.
910///
911/// @param r the second type to take into account in the comparison.
912template<typename T>
913bool
914try_canonical_compare(const T *l, const T *r)
915{
916#if WITH_DEBUG_TYPE_CANONICALIZATION
917 // We are debugging the canonicalization of a type down the stack.
918 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
919 // type being canonicalized. We are at a point where we can compare
920 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
921 // have canonical types) or structural comparison.
922 //
923 // Because we are debugging the process of type canonicalization, we
924 // want to compare 'l' and 'r' canonically *AND* structurally. Both
925 // kinds of comparison should yield the same result, otherwise type
926 // canonicalization just failed for the subtype 'r' of the type
927 // being canonicalized.
928 //
929 // In concrete terms, this function is going to be called twice with
930 // the same pair {'l', 'r'} to compare: The first time with
931 // environment::priv_->use_canonical_type_comparison_ set to true,
932 // instructing us to compare them canonically, and the second time
933 // with that boolean set to false, instructing us to compare them
934 // structurally.
935 const environment&env = l->get_environment();
936 if (env.priv_->use_canonical_type_comparison_)
937 {
938 if (const type_base *lc = l->get_naked_canonical_type())
939 if (const type_base *rc = r->get_naked_canonical_type())
940 ABG_RETURN_EQUAL(lc, rc);
941 }
942
943 // If the two types have a non-empty hash value, then consider those
944 // hash values. If the hashes are different then the two types are
945 // different. If the hashes are equal then we'll compare then
946 // structurally.
947 if (hash_t l_hash = peek_hash_value(*l))
948 if (hash_t r_hash = peek_hash_value(*r))
949 if (l_hash != r_hash)
951
952 // If a type has a canonical type, use its canonical type, always.
955
956 return equals(*l, *r, 0);
957#else
958 if (const type_base *lc = l->get_naked_canonical_type())
959 if (const type_base *rc = r->get_naked_canonical_type())
960 ABG_RETURN_EQUAL(lc, rc);
961
962 // If the two types have a non-empty hash value, then consider those
963 // hash values. If the hashes are different then the two types are
964 // different. If the hashes are equal then we'll compare then
965 // structurally.
966 if (hash_t l_hash = peek_hash_value(*l))
967 if (hash_t r_hash = peek_hash_value(*r))
968 if (l_hash != r_hash)
970
971 // If a type has a canonical type, use its canonical type, always.
974
975 return equals(*l, *r, 0);
976#endif
977}
978
979/// Detect if a recursive comparison cycle is detected while
980/// structurally comparing two types (a.k.a member-wise comparison).
981///
982/// @param l the left-hand-side operand of the current comparison.
983///
984/// @param r the right-hand-side operand of the current comparison.
985///
986/// @return true iff a comparison cycle is detected.
987template<typename T>
988bool
990{
991 bool result = l.priv_->comparison_started(l, r);
992 return result ;
993}
994
995/// Detect if a recursive comparison cycle is detected while
996/// structurally comparing two @ref class_decl types.
997///
998/// @param l the left-hand-side operand of the current comparison.
999///
1000/// @param r the right-hand-side operand of the current comparison.
1001///
1002/// @return true iff a comparison cycle is detected.
1003template<>
1004bool
1006{
1007 return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
1008 static_cast<const class_or_union&>(r));
1009}
1010
1011/// This macro is to be used while comparing composite types that
1012/// might recursively refer to themselves. Comparing two such types
1013/// might get us into a cyle.
1014///
1015/// Practically, if we detect that we are already into comparing 'l'
1016/// and 'r'; then, this is a cycle.
1017//
1018/// To break the cycle, we assume the result of the comparison is true
1019/// for now. Comparing the other sub-types of l & r will tell us later
1020/// if l & r are actually different or not.
1021///
1022/// In the mean time, returning true from this macro should not be
1023/// used to propagate the canonical type of 'l' onto 'r' as we don't
1024/// know yet if l equals r. All the types that depend on l and r
1025/// can't (and that are in the comparison stack currently) can't have
1026/// their canonical type propagated either. So this macro disallows
1027/// canonical type propagation for those types that depend on a
1028/// recursively defined sub-type for now.
1029///
1030/// @param l the left-hand-side operand of the comparison.
1031#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
1032 do \
1033 { \
1034 if (is_comparison_cycle_detected(l, r)) \
1035 return true; \
1036 } \
1037 while(false)
1038
1039
1040/// Mark a pair of types as being compared.
1041///
1042/// This is helpful to later detect recursive cycles in the comparison
1043/// stack.
1044///
1045/// @param l the left-hand-side operand of the comparison.
1046///
1047/// @parm r the right-hand-side operand of the comparison.
1048template<typename T>
1049void
1051{
1052 l.priv_->mark_as_being_compared(l, r);
1054}
1055
1056/// Mark a pair of @ref class_decl types as being compared.
1057///
1058/// This is helpful to later detect recursive cycles in the comparison
1059/// stack.
1060///
1061/// @param l the left-hand-side operand of the comparison.
1062///
1063/// @parm r the right-hand-side operand of the comparison.
1064template<>
1065void
1067{
1068 return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
1069 static_cast<const class_or_union&>(r));
1070}
1071
1072/// Mark a pair of types as being not compared anymore.
1073///
1074/// This is helpful to later detect recursive cycles in the comparison
1075/// stack.
1076///
1077/// Note that the types must have been passed to
1078/// mark_types_as_being_compared prior to calling this function.
1079///
1080/// @param l the left-hand-side operand of the comparison.
1081///
1082/// @parm r the right-hand-side operand of the comparison.
1083template<typename T>
1084void
1086{
1087 l.priv_->unmark_as_being_compared(l, r);
1089}
1090
1091/// Mark a pair of @ref class_decl types as being not compared
1092/// anymore.
1093///
1094/// This is helpful to later detect recursive cycles in the comparison
1095/// stack.
1096///
1097/// Note that the types must have been passed to
1098/// mark_types_as_being_compared prior to calling this function.
1099///
1100/// @param l the left-hand-side operand of the comparison.
1101///
1102/// @parm r the right-hand-side operand of the comparison.
1103template<>
1104void
1106{
1107 return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
1108 static_cast<const class_or_union&>(r));
1109}
1110
1111/// Return the result of the comparison of two (sub) types.
1112///
1113/// The function does the necessary book keeping before returning the
1114/// result of the comparison of two (sub) types.
1115///
1116/// The book-keeping done is essentially about type comparison cycle detection.
1117///
1118/// @param l the left-hand-side operand of the type comparison
1119///
1120/// @param r the right-hand-side operand of the type comparison
1121///
1122/// @param value the result of the comparison of @p l and @p r.
1123///
1124/// @return the value @p value.
1125template<typename T>
1126bool
1127return_comparison_result(T& l, T& r, bool value)
1128{
1130 ABG_RETURN(value);
1131}
1132
1133#define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1134 do \
1135 { \
1136 bool res = return_comparison_result(l, r, value); \
1137 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1138 return res; \
1139 } while (false)
1140
1141/// Cache the result of a comparison between too artifacts (l & r) and
1142/// return immediately.
1143///
1144/// @param value the value to cache.
1145#define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1146 do \
1147 { \
1148 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1149 return value; \
1150 } while (false)
1151
1152/// Getter of all types types sorted by their pretty representation.
1153///
1154/// @return a sorted vector of all types sorted by their pretty
1155/// representation.
1156const vector<type_base_wptr>&
1158{
1159 if (priv_->sorted_types_.empty())
1160 {
1161 istring_type_base_wptrs_map_type::const_iterator i;
1162 vector<type_base_wptr>::const_iterator j;
1163
1164 for (i = basic_types().begin(); i != basic_types().end(); ++i)
1165 for (j = i->second.begin(); j != i->second.end(); ++j)
1166 priv_->sorted_types_.push_back(*j);
1167
1168 for (i = class_types().begin(); i != class_types().end(); ++i)
1169 for (j = i->second.begin(); j != i->second.end(); ++j)
1170 priv_->sorted_types_.push_back(*j);
1171
1172 for (i = union_types().begin(); i != union_types().end(); ++i)
1173 for (j = i->second.begin(); j != i->second.end(); ++j)
1174 priv_->sorted_types_.push_back(*j);
1175
1176 for (i = enum_types().begin(); i != enum_types().end(); ++i)
1177 for (j = i->second.begin(); j != i->second.end(); ++j)
1178 priv_->sorted_types_.push_back(*j);
1179
1180 for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
1181 for (j = i->second.begin(); j != i->second.end(); ++j)
1182 priv_->sorted_types_.push_back(*j);
1183
1184 type_name_comp comp;
1185 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1186 }
1187
1188 return priv_->sorted_types_;
1189}
1190
1191// </type_maps stuff>
1192
1193// <translation_unit stuff>
1194
1195/// Constructor of translation_unit.
1196///
1197/// @param env the environment of this translation unit. Please note
1198/// that the life time of the environment must be greater than the
1199/// life time of the translation unit because the translation uses
1200/// resources that are allocated in the environment.
1201///
1202/// @param path the location of the translation unit.
1203///
1204/// @param address_size the size of addresses in the translation unit,
1205/// in bits.
1206translation_unit::translation_unit(const environment& env,
1207 const std::string& path,
1208 char address_size)
1209 : priv_(new priv(env))
1210{
1211 priv_->path_ = path;
1212 priv_->address_size_ = address_size;
1213}
1214
1215/// Getter of the the global scope of the translation unit.
1216///
1217/// @return the global scope of the current translation unit. If
1218/// there is not global scope allocated yet, this function creates one
1219/// and returns it.
1220const scope_decl_sptr&
1222{
1223 return const_cast<translation_unit*>(this)->get_global_scope();
1224}
1225
1226/// Getter of the global scope of the translation unit.
1227///
1228/// @return the global scope of the current translation unit. If
1229/// there is not allocated yet, this function creates one and returns
1230/// it.
1233{
1234 if (!priv_->global_scope_)
1235 {
1236 priv_->global_scope_.reset
1237 (new global_scope(const_cast<translation_unit*>(this)));
1238 priv_->global_scope_->set_translation_unit
1239 (const_cast<translation_unit*>(this));
1240 }
1241 return priv_->global_scope_;
1242}
1243
1244/// Getter of the types of the current @ref translation_unit.
1245///
1246/// @return the maps of the types of the translation unit.
1247const type_maps&
1249{return priv_->types_;}
1250
1251/// Getter of the types of the current @ref translation_unit.
1252///
1253/// @return the maps of the types of the translation unit.
1254type_maps&
1256{return priv_->types_;}
1257
1258/// Get the vector of function types that are used in the current
1259/// translation unit.
1260///
1261/// @return the vector of function types that are used in the current
1262/// translation unit.
1263const vector<function_type_sptr>&
1265{return priv_->live_fn_types_;}
1266
1267/// Getter of the environment of the current @ref translation_unit.
1268///
1269/// @return the translation unit of the current translation unit.
1270const environment&
1272{return priv_->env_;}
1273
1274/// Getter of the language of the source code of the translation unit.
1275///
1276/// @return the language of the source code.
1279{return priv_->language_;}
1280
1281/// Setter of the language of the source code of the translation unit.
1282///
1283/// @param l the new language.
1284void
1286{priv_->language_ = l;}
1287
1288
1289/// Get the path of the current translation unit.
1290///
1291/// This path is relative to the build directory of the translation
1292/// unit as returned by translation_unit::get_compilation_dir_path.
1293///
1294/// @return the relative path of the compilation unit associated to
1295/// the current instance of translation_unit.
1296//
1297const std::string&
1299{return priv_->path_;}
1300
1301/// Set the path associated to the current instance of
1302/// translation_unit.
1303///
1304/// This path is relative to the build directory of the translation
1305/// unit as returned by translation_unit::get_compilation_dir_path.
1306///
1307/// @param a_path the new relative path to set.
1308void
1309translation_unit::set_path(const string& a_path)
1310{priv_->path_ = a_path;}
1311
1312
1313/// Get the path of the directory that was 'current' when the
1314/// translation unit was compiled.
1315///
1316/// Note that the path returned by translation_unit::get_path is
1317/// relative to the path returned by this function.
1318///
1319/// @return the compilation directory for the current translation
1320/// unit.
1321const std::string&
1323{return priv_->comp_dir_path_;}
1324
1325/// Set the path of the directory that was 'current' when the
1326/// translation unit was compiled.
1327///
1328/// Note that the path returned by translation_unit::get_path is
1329/// relative to the path returned by this function.
1330///
1331/// @param the compilation directory for the current translation unit.
1332void
1334{priv_->comp_dir_path_ = d;}
1335
1336/// Get the concatenation of the build directory and the relative path
1337/// of the translation unit.
1338///
1339/// @return the absolute path of the translation unit.
1340const std::string&
1342{
1343 if (priv_->abs_path_.empty())
1344 {
1345 string path;
1346 if (!priv_->path_.empty())
1347 {
1348 if (!priv_->comp_dir_path_.empty())
1349 {
1350 path = priv_->comp_dir_path_;
1351 path += "/";
1352 }
1353 path += priv_->path_;
1354 }
1355 priv_->abs_path_ = path;
1356 }
1357
1358 return priv_->abs_path_;
1359}
1360
1361/// Set the corpus this translation unit is a member of.
1362///
1363/// Note that adding a translation unit to a @ref corpus automatically
1364/// triggers a call to this member function.
1365///
1366/// @param corpus the corpus.
1367void
1369{priv_->corp = c;}
1370
1371/// Get the corpus this translation unit is a member of.
1372///
1373/// @return the parent corpus, or nil if this doesn't belong to any
1374/// corpus yet.
1375corpus*
1377{return priv_->corp;}
1378
1379/// Get the corpus this translation unit is a member of.
1380///
1381/// @return the parent corpus, or nil if this doesn't belong to any
1382/// corpus yet.
1383const corpus*
1385{return const_cast<translation_unit*>(this)->get_corpus();}
1386
1387/// Getter of the location manager for the current translation unit.
1388///
1389/// @return a reference to the location manager for the current
1390/// translation unit.
1393{return priv_->loc_mgr_;}
1394
1395/// const Getter of the location manager.
1396///
1397/// @return a const reference to the location manager for the current
1398/// translation unit.
1399const location_manager&
1401{return priv_->loc_mgr_;}
1402
1403/// Tests whether if the current translation unit contains ABI
1404/// artifacts or not.
1405///
1406/// @return true iff the current translation unit is empty.
1407bool
1409{
1410 if (!priv_->global_scope_)
1411 return true;
1412 return get_global_scope()->is_empty();
1413}
1414
1415/// Getter of the address size in this translation unit.
1416///
1417/// @return the address size, in bits.
1418char
1420{return priv_->address_size_;}
1421
1422/// Setter of the address size in this translation unit.
1423///
1424/// @param a the new address size in bits.
1425void
1427{priv_->address_size_= a;}
1428
1429/// Getter of the 'is_constructed" flag. It says if the translation
1430/// unit is fully constructed or not.
1431///
1432/// This flag is important for cases when comparison might depend on
1433/// if the translation unit is fully built or not. For instance, when
1434/// reading types from DWARF, the virtual methods of a class are not
1435/// necessarily fully constructed until we have reached the end of the
1436/// translation unit. In that case, before we've reached the end of
1437/// the translation unit, we might not take virtual functions into
1438/// account when comparing classes.
1439///
1440/// @return true if the translation unit is constructed.
1441bool
1443{return priv_->is_constructed_;}
1444
1445/// Setter of the 'is_constructed" flag. It says if the translation
1446/// unit is fully constructed or not.
1447///
1448/// This flag is important for cases when comparison might depend on
1449/// if the translation unit is fully built or not. For instance, when
1450/// reading types from DWARF, the virtual methods of a class are not
1451/// necessarily fully constructed until we have reached the end of the
1452/// translation unit. In that case, before we've reached the end of
1453/// the translation unit, we might not take virtual functions into
1454/// account when comparing classes.
1455///
1456/// @param f true if the translation unit is constructed.
1457void
1459{priv_->is_constructed_ = f;}
1460
1461/// Compare the current translation unit against another one.
1462///
1463/// @param other the other tu to compare against.
1464///
1465/// @return true if the two translation units are equal, false
1466/// otherwise.
1467bool
1469{
1470 if (get_address_size() != other.get_address_size())
1471 return false;
1472
1473 return *get_global_scope() == *other.get_global_scope();
1474}
1475
1476/// Inequality operator.
1477///
1478/// @param o the instance of @ref translation_unit to compare the
1479/// current instance against.
1480///
1481/// @return true iff the current instance is different from @p o.
1482bool
1485
1486/// Ensure that the life time of a function type is bound to the life
1487/// time of the current translation unit.
1488///
1489/// @param ftype the function time which life time to bind to the life
1490/// time of the current instance of @ref translation_unit. That is,
1491/// it's onlyh when the translation unit is destroyed that the
1492/// function type can be destroyed to.
1493void
1495{
1496 const environment& env = get_environment();
1497
1498 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1499
1500 interned_string repr = get_type_name(ftype);
1501 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1502 push_back(ftype);
1503
1504 // The function type must be out of the same environment as its
1505 // translation unit.
1506 {
1507 const environment& e = ftype->get_environment();
1508 ABG_ASSERT(&env == &e);
1509 }
1510
1511 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1512 ABG_ASSERT(existing_tu == this);
1513 else
1514 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1515
1517}
1518
1519/// This implements the ir_traversable_base::traverse virtual
1520/// function.
1521///
1522/// @param v the visitor used on the member nodes of the translation
1523/// unit during the traversal.
1524///
1525/// @return true if the entire type IR tree got traversed, false
1526/// otherwise.
1527bool
1530
1531translation_unit::~translation_unit()
1532{}
1533
1534/// Converts a translation_unit::language enumerator into a string.
1535///
1536/// @param l the language enumerator to translate.
1537///
1538/// @return the resulting string.
1539string
1541{
1542 switch (l)
1543 {
1544 case translation_unit::LANG_UNKNOWN:
1545 return "LANG_UNKNOWN";
1546 case translation_unit::LANG_Cobol74:
1547 return "LANG_Cobol74";
1548 case translation_unit::LANG_Cobol85:
1549 return "LANG_Cobol85";
1550 case translation_unit::LANG_C89:
1551 return "LANG_C89";
1552 case translation_unit::LANG_C99:
1553 return "LANG_C99";
1554 case translation_unit::LANG_C11:
1555 return "LANG_C11";
1556 case translation_unit::LANG_C17:
1557 return "LANG_C17";
1558 case translation_unit::LANG_C23:
1559 return "LANG_C23";
1560 case translation_unit::LANG_C:
1561 return "LANG_C";
1562 case translation_unit::LANG_C_plus_plus_03:
1563 return "LANG_C_plus_plus_03";
1564 case translation_unit::LANG_C_plus_plus_11:
1565 return "LANG_C_plus_plus_11";
1566 case translation_unit::LANG_C_plus_plus_14:
1567 return "LANG_C_plus_plus_14";
1568 case translation_unit::LANG_C_plus_plus_17:
1569 return "LANG_C_plus_plus_17";
1570 case translation_unit::LANG_C_plus_plus_20:
1571 return "LANG_C_plus_plus_20";
1572 case translation_unit::LANG_C_plus_plus_23:
1573 return "LANG_C_plus_plus_23";
1574 case translation_unit::LANG_C_plus_plus:
1575 return "LANG_C_plus_plus";
1576 case translation_unit::LANG_OCaml:
1577 return "LANG_OCaml";
1578 case translation_unit::LANG_Zig:
1579 return "LANG_Zig";
1580 case translation_unit::LANG_ObjC:
1581 return "LANG_ObjC";
1582 case translation_unit::LANG_ObjC_plus_plus:
1583 return "LANG_ObjC_plus_plus";
1584 case translation_unit::LANG_D:
1585 return "LANG_D";
1586 case translation_unit::LANG_Go:
1587 return "LANG_Go";
1588 case translation_unit::LANG_Rust:
1589 return "LANG_Rust";
1590 case translation_unit::LANG_Fortran77:
1591 return "LANG_Fortran77";
1592 case translation_unit::LANG_Fortran90:
1593 return "LANG_Fortran90";
1594 case translation_unit::LANG_Fortran95:
1595 return "LANG_Fortran95";
1596 case translation_unit::LANG_Fortran18:
1597 return "LANG_Fortran18";
1598 case translation_unit::LANG_Fortran23:
1599 return "LANG_Fortran23";
1600 case translation_unit::LANG_Ada83:
1601 return "LANG_Ada83";
1602 case translation_unit::LANG_Ada95:
1603 return "LANG_Ada95";
1604 case translation_unit::LANG_Ada2005:
1605 return "LANG_Ada2005";
1606 case translation_unit::LANG_Ada2012:
1607 return "LANG_Ada2012";
1608 case translation_unit::LANG_Pascal83:
1609 return "LANG_Pascal83";
1610 case translation_unit::LANG_Modula2:
1611 return "LANG_Modula2";
1612 case translation_unit::LANG_Java:
1613 return "LANG_Java";
1614 case translation_unit::LANG_Kotlin:
1615 return "LANG_Kotlin";
1616 case translation_unit::LANG_C_sharp:
1617 return "LANG_C_sharp";
1618 case translation_unit::LANG_Python:
1619 return "LANG_Python";
1620 case translation_unit::LANG_Ruby:
1621 return "LANG_Ruby";
1622 case translation_unit::LANG_PLI:
1623 return "LANG_PLI";
1624 case translation_unit::LANG_UPC:
1625 return "LANG_UPC";
1626 case translation_unit::LANG_Mips_Assembler:
1627 return "LANG_Mips_Assembler";
1628 case translation_unit::LANG_Assembly:
1629 return "LANG_Assembly";
1630 case translation_unit::LANG_Crystal:
1631 return "LANG_Crystal";
1632 case translation_unit::LANG_HIP:
1633 return "LANG_HIP";
1634 case translation_unit::LANG_Mojo:
1635 return "LANG_Mojo";
1636 case translation_unit::LANG_GLSL:
1637 return "LANG_GLSL";
1638 case translation_unit::LANG_GLSL_ES:
1639 return "LANG_GLSL_ES";
1640 case translation_unit::LANG_HLSL:
1641 return "LANG_HLSL";
1642 case translation_unit::LANG_OpenCL_CPP:
1643 return "LANG_OpenCL_CPP";
1644 case translation_unit::LANG_CPP_for_OpenCL:
1645 return "LANG_CPP_for_OpenCL";
1646 case translation_unit::LANG_SYCL:
1647 return "LANG_SYCL";
1648 case translation_unit::LANG_Odin:
1649 return "LANG_Odin";
1650 case translation_unit::LANG_P4:
1651 return "LANG_P4";
1652 case translation_unit::LANG_Metal:
1653 return "LANG_Metal";
1654 case translation_unit::LANG_Move:
1655 return "LANG_Move";
1656 case translation_unit::LANG_Hylo:
1657 return "LANG_Hylo";
1658 }
1659
1660 return "LANG_UNKNOWN";
1661}
1662
1663/// Parse a string representing a language into a
1664/// translation_unit::language enumerator into a string.
1665///
1666/// @param l the string representing the language.
1667///
1668/// @return the resulting translation_unit::language enumerator.
1671{
1672 if (l == "LANG_Cobol74")
1673 return translation_unit::LANG_Cobol74;
1674 else if (l == "LANG_Cobol85")
1675 return translation_unit::LANG_Cobol85;
1676 else if (l == "LANG_C89")
1677 return translation_unit::LANG_C89;
1678 else if (l == "LANG_C99")
1679 return translation_unit::LANG_C99;
1680 else if (l == "LANG_C11")
1681 return translation_unit::LANG_C11;
1682 else if (l == "LANG_C17")
1683 return translation_unit::LANG_C17;
1684 else if (l == "LANG_C23")
1685 return translation_unit::LANG_C23;
1686 else if (l == "LANG_C")
1687 return translation_unit::LANG_C;
1688 else if (l == "LANG_C_plus_plus_03")
1689 return translation_unit::LANG_C_plus_plus_03;
1690 else if (l == "LANG_C_plus_plus_11")
1691 return translation_unit::LANG_C_plus_plus_11;
1692 else if (l == "LANG_C_plus_plus_14")
1693 return translation_unit::LANG_C_plus_plus_14;
1694 else if (l == "LANG_C_plus_plus_17")
1695 return translation_unit::LANG_C_plus_plus_17;
1696 else if (l == "LANG_C_plus_plus_20")
1697 return translation_unit::LANG_C_plus_plus_20;
1698 else if (l == "LANG_C_plus_plus_23")
1699 return translation_unit::LANG_C_plus_plus_23;
1700 else if (l == "LANG_C_plus_plus")
1701 return translation_unit::LANG_C_plus_plus;
1702 else if (l == "LANG_OCaml")
1703 return translation_unit::LANG_OCaml;
1704 else if (l == "LANG_ObjC")
1705 return translation_unit::LANG_ObjC;
1706 else if (l == "LANG_ObjC_plus_plus")
1707 return translation_unit::LANG_ObjC_plus_plus;
1708 else if (l == "LANG_Zig")
1709 return translation_unit::LANG_Zig;
1710 else if (l == "LANG_Metal")
1711 return translation_unit::LANG_Metal;
1712 else if (l == "LANG_Fortran77")
1713 return translation_unit::LANG_Fortran77;
1714 else if (l == "LANG_Fortran90")
1715 return translation_unit::LANG_Fortran90;
1716 else if (l == "LANG_Fortran95")
1717 return translation_unit::LANG_Fortran95;
1718 else if (l == "LANG_Fortran18")
1719 return translation_unit::LANG_Fortran23;
1720 else if (l == "LANG_Ada83")
1721 return translation_unit::LANG_Ada83;
1722 else if (l == "LANG_Ada95")
1723 return translation_unit::LANG_Ada95;
1724 else if (l == "LANG_Ada2005")
1725 return translation_unit::LANG_Ada2005;
1726 else if (l == "LANG_Ada2012")
1727 return translation_unit::LANG_Ada2012;
1728 else if (l == "LANG_Pascal83")
1729 return translation_unit::LANG_Pascal83;
1730 else if (l == "LANG_Modula2")
1731 return translation_unit::LANG_Modula2;
1732 else if (l == "LANG_Java")
1733 return translation_unit::LANG_Java;
1734 else if (l == "LANG_Kotlin")
1735 return translation_unit::LANG_Kotlin;
1736 else if (l == "LANG_PLI")
1737 return translation_unit::LANG_PLI;
1738 else if (l == "LANG_UPC")
1739 return translation_unit::LANG_UPC;
1740 else if (l == "LANG_D")
1741 return translation_unit::LANG_D;
1742 else if (l == "LANG_Go")
1743 return translation_unit::LANG_Go;
1744 else if (l == "LANG_Rust")
1745 return translation_unit::LANG_Rust;
1746 else if (l == "LANG_Python")
1747 return translation_unit::LANG_Python;
1748 else if (l == "LANG_Ruby")
1749 return translation_unit::LANG_Ruby;
1750 else if (l == "LANG_Mips_Assembler")
1751 return translation_unit::LANG_Mips_Assembler;
1752 else if (l == "LANG_Assembly")
1753 return translation_unit::LANG_Assembly;
1754 else if (l == "LANG_Crystal")
1755 return translation_unit::LANG_Crystal;
1756 else if (l == "LANG_HIP")
1757 return translation_unit::LANG_HIP;
1758 else if (l == "LANG_C_sharp")
1759 return translation_unit::LANG_C_sharp;
1760 else if (l == "LANG_Mojo")
1761 return translation_unit::LANG_Mojo;
1762 else if (l == "LANG_GLSL")
1763 return translation_unit::LANG_GLSL;
1764 else if (l == "LANG_GLSL_ES")
1765 return translation_unit::LANG_GLSL_ES;
1766 else if (l == "LANG_HLSL")
1767 return translation_unit::LANG_HLSL;
1768 else if (l == "LANG_OpenCL_CPP")
1769 return translation_unit::LANG_OpenCL_CPP;
1770 else if (l == "LANG_CPP_for_OpenCL")
1771 return translation_unit::LANG_CPP_for_OpenCL;
1772 else if (l == "LANG_SYCL")
1773 return translation_unit::LANG_SYCL;
1774 else if (l == "LANG_Odin")
1775 return translation_unit::LANG_Odin;
1776 else if (l == "LANG_P4")
1777 return translation_unit::LANG_P4;
1778 else if (l == "LANG_Move")
1779 return translation_unit::LANG_Move;
1780 else if (l == "LANG_Hylo")
1781 return translation_unit::LANG_Hylo;
1782
1783 return translation_unit::LANG_UNKNOWN;
1784}
1785
1786/// Test if a language enumerator designates the C language.
1787///
1788/// @param l the language enumerator to consider.
1789///
1790/// @return true iff @p l designates the C language.
1791bool
1793{
1794 return (l == translation_unit::LANG_C89
1795 || l == translation_unit::LANG_C99
1796 || l == translation_unit::LANG_C11
1797 || l == translation_unit::LANG_C17
1798 || l == translation_unit::LANG_C23
1799 || l == translation_unit::LANG_C);
1800}
1801
1802/// Test if a language enumerator designates the C++ language.
1803///
1804/// @param l the language enumerator to consider.
1805///
1806/// @return true iff @p l designates the C++ language.
1807bool
1809{
1810 return (l == translation_unit::LANG_C_plus_plus_03
1811 || l == translation_unit::LANG_C_plus_plus_11
1812 || l == translation_unit::LANG_C_plus_plus_14
1813 || l == translation_unit::LANG_C_plus_plus_20
1814 || l == translation_unit::LANG_C_plus_plus_23
1815 || l == translation_unit::LANG_C_plus_plus);
1816}
1817
1818/// Test if a language enumerator designates the Java language.
1819///
1820/// @param l the language enumerator to consider.
1821///
1822/// @return true iff @p l designates the Java language.
1823bool
1825{return l == translation_unit::LANG_Java;}
1826
1827/// Test if a language enumerator designates the Ada language.
1828///
1829/// @param l the language enumerator to consider.
1830///
1831/// @return true iff @p l designates the Ada language.
1832bool
1834{
1835 return (l == translation_unit::LANG_Ada83
1836 || l == translation_unit::LANG_Ada95
1837 || l == translation_unit::LANG_Ada2005
1838 || l == translation_unit::LANG_Ada2012);
1839}
1840
1841/// A deep comparison operator for pointers to translation units.
1842///
1843/// @param l the first translation unit to consider for the comparison.
1844///
1845/// @param r the second translation unit to consider for the comparison.
1846///
1847/// @return true if the two translation units are equal, false otherwise.
1848bool
1850{
1851 if (l.get() == r.get())
1852 return true;
1853
1854 if (!!l != !!r)
1855 return false;
1856
1857 return *l == *r;
1858}
1859
1860/// A deep inequality operator for pointers to translation units.
1861///
1862/// @param l the first translation unit to consider for the comparison.
1863///
1864/// @param r the second translation unit to consider for the comparison.
1865///
1866/// @return true iff the two translation units are different.
1867bool
1869{return !operator==(l, r);}
1870
1871// </translation_unit stuff>
1872
1873// <elf_symbol stuff>
1874struct elf_symbol::priv
1875{
1876 const environment& env_;
1877 size_t index_;
1878 size_t size_;
1879 string name_;
1880 elf_symbol::type type_;
1881 elf_symbol::binding binding_;
1882 elf_symbol::version version_;
1883 elf_symbol::visibility visibility_;
1884 bool is_defined_;
1885 // This flag below says if the symbol is a common elf symbol. In
1886 // relocatable files, a common symbol is a symbol defined in a
1887 // section of kind SHN_COMMON.
1888 //
1889 // Note that a symbol of kind STT_COMMON is also considered a common
1890 // symbol. Here is what the gABI says about STT_COMMON and
1891 // SHN_COMMON:
1892 //
1893 // Symbols with type STT_COMMON label uninitialized common
1894 // blocks. In relocatable objects, these symbols are not
1895 // allocated and must have the special section index SHN_COMMON
1896 // (see below). In shared objects and executables these symbols
1897 // must be allocated to some section in the defining object.
1898 //
1899 // In relocatable objects, symbols with type STT_COMMON are
1900 // treated just as other symbols with index SHN_COMMON. If the
1901 // link-editor allocates space for the SHN_COMMON symbol in an
1902 // output section of the object it is producing, it must
1903 // preserve the type of the output symbol as STT_COMMON.
1904 //
1905 // When the dynamic linker encounters a reference to a symbol
1906 // that resolves to a definition of type STT_COMMON, it may (but
1907 // is not required to) change its symbol resolution rules as
1908 // follows: instead of binding the reference to the first symbol
1909 // found with the given name, the dynamic linker searches for
1910 // the first symbol with that name with type other than
1911 // STT_COMMON. If no such symbol is found, it looks for the
1912 // STT_COMMON definition of that name that has the largest size.
1913 bool is_common_;
1914 bool is_in_ksymtab_;
1917 bool is_suppressed_;
1918 elf_symbol_wptr main_symbol_;
1919 elf_symbol_wptr next_alias_;
1920 elf_symbol_wptr next_common_instance_;
1921 string id_string_;
1922
1923 priv(const environment& e)
1924 : env_(e),
1925 index_(),
1926 size_(),
1927 type_(elf_symbol::NOTYPE_TYPE),
1928 binding_(elf_symbol::GLOBAL_BINDING),
1929 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1930 is_defined_(false),
1931 is_common_(false),
1932 is_in_ksymtab_(false),
1933 crc_(),
1934 namespace_(),
1935 is_suppressed_(false)
1936 {}
1937
1938 priv(const environment& e,
1939 size_t i,
1940 size_t s,
1941 const string& n,
1944 bool d,
1945 bool c,
1946 const elf_symbol::version& ve,
1948 bool is_in_ksymtab,
1951 bool is_suppressed)
1952 : env_(e),
1953 index_(i),
1954 size_(s),
1955 name_(n),
1956 type_(t),
1957 binding_(b),
1958 version_(ve),
1959 visibility_(vi),
1960 is_defined_(d),
1961 is_common_(c),
1962 is_in_ksymtab_(is_in_ksymtab),
1963 crc_(crc),
1964 namespace_(ns),
1965 is_suppressed_(is_suppressed)
1966 {
1967 if (!is_common_)
1968 is_common_ = type_ == COMMON_TYPE;
1969 }
1970}; // end struct elf_symbol::priv
1971
1972/// Constructor of the @ref elf_symbol type.
1973///
1974/// Note that this constructor is private, so client code cannot use
1975/// it to create instances of @ref elf_symbol. Rather, client code
1976/// should use the @ref elf_symbol::create() function to create
1977/// instances of @ref elf_symbol instead.
1978///
1979/// @param e the environment we are operating from.
1980///
1981/// @param i the index of the symbol in the (ELF) symbol table.
1982///
1983/// @param s the size of the symbol.
1984///
1985/// @param n the name of the symbol.
1986///
1987/// @param t the type of the symbol.
1988///
1989/// @param b the binding of the symbol.
1990///
1991/// @param d true if the symbol is defined, false otherwise.
1992///
1993/// @param c true if the symbol is a common symbol, false otherwise.
1994///
1995/// @param ve the version of the symbol.
1996///
1997/// @param vi the visibility of the symbol.
1998///
1999/// @param crc the CRC (modversions) value of Linux Kernel symbols
2000///
2001/// @param ns the namespace of Linux Kernel symbols, if any
2002elf_symbol::elf_symbol(const environment& e,
2003 size_t i,
2004 size_t s,
2005 const string& n,
2006 type t,
2007 binding b,
2008 bool d,
2009 bool c,
2010 const version& ve,
2011 visibility vi,
2012 bool is_in_ksymtab,
2015 bool is_suppressed)
2016 : priv_(new priv(e,
2017 i,
2018 s,
2019 n,
2020 t,
2021 b,
2022 d,
2023 c,
2024 ve,
2025 vi,
2026 is_in_ksymtab,
2027 crc,
2028 ns,
2029 is_suppressed))
2030{}
2031
2032/// Factory of instances of @ref elf_symbol.
2033///
2034/// This is the function to use to create instances of @ref elf_symbol.
2035///
2036/// @param e the environment we are operating from.
2037///
2038/// @param i the index of the symbol in the (ELF) symbol table.
2039///
2040/// @param s the size of the symbol.
2041///
2042/// @param n the name of the symbol.
2043///
2044/// @param t the type of the symbol.
2045///
2046/// @param b the binding of the symbol.
2047///
2048/// @param d true if the symbol is defined, false otherwise.
2049///
2050/// @param c true if the symbol is a common symbol.
2051///
2052/// @param ve the version of the symbol.
2053///
2054/// @param vi the visibility of the symbol.
2055///
2056/// @param crc the CRC (modversions) value of Linux Kernel symbols
2057///
2058/// @param ns the namespace of Linux Kernel symbols, if any
2059///
2060/// @return a (smart) pointer to a newly created instance of @ref
2061/// elf_symbol.
2064 size_t i,
2065 size_t s,
2066 const string& n,
2067 type t,
2068 binding b,
2069 bool d,
2070 bool c,
2071 const version& ve,
2072 visibility vi,
2073 bool is_in_ksymtab,
2076 bool is_suppressed)
2077{
2078 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
2079 is_in_ksymtab, crc, ns, is_suppressed));
2080 sym->priv_->main_symbol_ = sym;
2081 return sym;
2082}
2083
2084/// Test textual equality between two symbols.
2085///
2086/// Textual equality means that the aliases of the compared symbols
2087/// are not taken into account. Only the name, type, and version of
2088/// the symbols are compared.
2089///
2090/// @parm l the first ELF symbol to take into consideration in the
2091/// comparison.
2092///
2093/// @param r the second ELF symbol to take into consideration in the
2094/// comparison.
2095///
2096/// @param k a pointer to a bitfield that gives information about the
2097/// kind of changes there are between @p l and @p r. This one is set
2098/// iff it's non-null and if the function returns false.
2099///
2100/// @return true iff the two symbols are textually equal.
2101static bool
2102textually_equals(const elf_symbol&l, const elf_symbol&r,
2103 change_kind* k = nullptr)
2104{
2105 bool equals = (l.get_name() == r.get_name()
2106 && l.get_type() == r.get_type()
2107 && l.is_public() == r.is_public()
2108 && l.is_defined() == r.is_defined()
2110 && l.get_version() == r.get_version()
2111 && l.get_crc() == r.get_crc()
2112 && l.get_namespace() == r.get_namespace());
2113
2114 if (!equals)
2115 if (k)
2117
2118 if (equals && l.is_variable())
2119 // These are variable symbols. Let's compare their symbol size.
2120 // The symbol size in this case is the size taken by the storage
2121 // of the variable. If that size changes, then it's an ABI
2122 // change.
2123 if (l.get_size() != r.get_size())
2124 {
2125 equals = false;
2126 if (k)
2128 }
2129
2130 return equals;
2131}
2132
2133/// Getter of the environment used by the current instance of @ref
2134/// elf_symbol.
2135///
2136/// @return the enviroment used by the current instance of @ref elf_symbol.
2137const environment&
2139{return priv_->env_;}
2140
2141/// Getter for the index
2142///
2143/// @return the index of the symbol.
2144size_t
2146{return priv_->index_;}
2147
2148/// Setter for the index.
2149///
2150/// @param s the new index.
2151void
2153{priv_->index_ = s;}
2154
2155/// Getter for the name of the @ref elf_symbol.
2156///
2157/// @return a reference to the name of the @ref symbol.
2158const string&
2160{return priv_->name_;}
2161
2162/// Setter for the name of the current intance of @ref elf_symbol.
2163///
2164/// @param n the new name.
2165void
2166elf_symbol::set_name(const string& n)
2167{
2168 priv_->name_ = n;
2169 priv_->id_string_.clear();
2170}
2171
2172/// Getter for the type of the current instance of @ref elf_symbol.
2173///
2174/// @return the type of the elf symbol.
2177{return priv_->type_;}
2178
2179/// Setter for the type of the current instance of @ref elf_symbol.
2180///
2181/// @param t the new symbol type.
2182void
2184{priv_->type_ = t;}
2185
2186/// Getter of the size of the symbol.
2187///
2188/// @return the size of the symbol, in bytes.
2189size_t
2191{return priv_->size_;}
2192
2193/// Setter of the size of the symbol.
2194///
2195/// @param size the new size of the symbol, in bytes.
2196void
2198{priv_->size_ = size;}
2199
2200/// Getter for the binding of the current instance of @ref elf_symbol.
2201///
2202/// @return the binding of the symbol.
2205{return priv_->binding_;}
2206
2207/// Setter for the binding of the current instance of @ref elf_symbol.
2208///
2209/// @param b the new binding.
2210void
2212{priv_->binding_ = b;}
2213
2214/// Getter for the version of the current instanc of @ref elf_symbol.
2215///
2216/// @return the version of the elf symbol.
2219{return priv_->version_;}
2220
2221/// Setter for the version of the current instance of @ref elf_symbol.
2222///
2223/// @param v the new version of the elf symbol.
2224void
2226{
2227 priv_->version_ = v;
2228 priv_->id_string_.clear();
2229}
2230
2231/// Setter of the visibility of the current instance of @ref
2232/// elf_symbol.
2233///
2234/// @param v the new visibility of the elf symbol.
2235void
2237{priv_->visibility_ = v;}
2238
2239/// Getter of the visibility of the current instance of @ref
2240/// elf_symbol.
2241///
2242/// @return the visibility of the elf symbol.
2245{return priv_->visibility_;}
2246
2247/// Test if the current instance of @ref elf_symbol is defined or not.
2248///
2249/// @return true if the current instance of @ref elf_symbol is
2250/// defined, false otherwise.
2251bool
2253{return priv_->is_defined_;}
2254
2255/// Sets a flag saying if the current instance of @ref elf_symbol is
2256/// defined
2257///
2258/// @param b the new value of the flag.
2259void
2261{priv_->is_defined_ = d;}
2262
2263/// Test if the current instance of @ref elf_symbol is public or not.
2264///
2265/// This tests if the symbol is defined, has default or protected
2266///visibility, and either:
2267/// - has global binding
2268/// - has weak binding
2269/// - or has a GNU_UNIQUE binding.
2270///
2271/// return true if the current instance of @ref elf_symbol is public,
2272/// false otherwise.
2273bool
2275{
2276 return (is_defined()
2277 && (get_binding() == GLOBAL_BINDING
2278 || get_binding() == WEAK_BINDING
2279 || get_binding() == GNU_UNIQUE_BINDING)
2280 && (get_visibility() == DEFAULT_VISIBILITY
2281 || get_visibility() == PROTECTED_VISIBILITY));
2282}
2283
2284/// Test if the current instance of @ref elf_symbol is a function
2285/// symbol or not.
2286///
2287/// @return true if the current instance of @ref elf_symbol is a
2288/// function symbol, false otherwise.
2289bool
2291{return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2292
2293/// Test if the current instance of @ref elf_symbol is a variable
2294/// symbol or not.
2295///
2296/// @return true if the current instance of @ref elf_symbol is a
2297/// variable symbol, false otherwise.
2298bool
2300{
2301 return (get_type() == OBJECT_TYPE
2302 || get_type() == TLS_TYPE
2303 // It appears that undefined variables have NOTYPE type.
2304 || (get_type() == NOTYPE_TYPE
2305 && !is_defined()));
2306}
2307
2308/// Getter of the 'is-in-ksymtab' property.
2309///
2310/// @return true iff the current symbol is in the Linux Kernel
2311/// specific 'ksymtab' symbol table.
2312bool
2314{return priv_->is_in_ksymtab_;}
2315
2316/// Setter of the 'is-in-ksymtab' property.
2317///
2318/// @param is_in_ksymtab this is true iff the current symbol is in the
2319/// Linux Kernel specific 'ksymtab' symbol table.
2320void
2322{priv_->is_in_ksymtab_ = is_in_ksymtab;}
2323
2324/// Getter of the 'crc' property.
2325///
2326/// @return the CRC (modversions) value for Linux Kernel symbols, if any
2329{return priv_->crc_;}
2330
2331/// Setter of the 'crc' property.
2332///
2333/// @param crc the new CRC (modversions) value for Linux Kernel symbols
2334void
2336{priv_->crc_ = crc;}
2337
2338/// Getter of the 'namespace' property.
2339///
2340/// @return the namespace for Linux Kernel symbols, if any
2343{return priv_->namespace_;}
2344
2345/// Setter of the 'namespace' property.
2346///
2347/// @param ns the new namespace for Linux Kernel symbols, if any
2348void
2350{priv_->namespace_ = ns;}
2351
2352/// Getter for the 'is-suppressed' property.
2353///
2354/// @return true iff the current symbol has been suppressed by a
2355/// suppression specification that was provided in the context that
2356/// led to the creation of the corpus this ELF symbol belongs to.
2357bool
2359{return priv_->is_suppressed_;}
2360
2361/// Setter for the 'is-suppressed' property.
2362///
2363/// @param true iff the current symbol has been suppressed by a
2364/// suppression specification that was provided in the context that
2365/// led to the creation of the corpus this ELF symbol belongs to.
2366void
2368{priv_->is_suppressed_ = is_suppressed;}
2369
2370/// @name Elf symbol aliases
2371///
2372/// An alias A for an elf symbol S is a symbol that is defined at the
2373/// same address as S. S is chained to A through the
2374/// elf_symbol::get_next_alias() method.
2375///
2376/// When there are several aliases to a symbol, the main symbol is the
2377/// the first symbol found in the symbol table for a given address.
2378///
2379/// The alias chain is circular. That means if S is the main symbol
2380/// and A is the alias, S is chained to A and A
2381/// is chained back to the main symbol S. The last alias in an alias
2382///chain is always chained to the main symbol.
2383///
2384/// Thus, when looping over the aliases of an elf_symbol A, detecting
2385/// an alias that is equal to the main symbol should logically be a
2386/// loop exit condition.
2387///
2388/// Accessing and adding aliases for instances of elf_symbol is done
2389/// through the member functions below.
2390
2391/// @{
2392
2393/// Get the main symbol of an alias chain.
2394///
2395///@return the main symbol.
2396const elf_symbol_sptr
2398{return priv_->main_symbol_.lock();}
2399
2400/// Get the main symbol of an alias chain.
2401///
2402///@return the main symbol.
2405{return priv_->main_symbol_.lock();}
2406
2407/// Tests whether this symbol is the main symbol.
2408///
2409/// @return true iff this symbol is the main symbol.
2410bool
2412{return get_main_symbol().get() == this;}
2413
2414/// Get the next alias of the current symbol.
2415///
2416///@return the alias, or NULL if there is no alias.
2419{return priv_->next_alias_.lock();}
2420
2421
2422/// Check if the current elf_symbol has an alias.
2423///
2424///@return true iff the current elf_symbol has an alias.
2425bool
2427{return bool(get_next_alias());}
2428
2429/// Get the number of aliases to this elf symbol
2430///
2431/// @return the number of aliases to this elf symbol.
2432int
2434{
2435 int result = 0;
2436
2438 a && a.get() != get_main_symbol().get();
2439 a = a->get_next_alias())
2440 ++result;
2441
2442 return result;
2443}
2444
2445/// Add an alias to the current elf symbol.
2446///
2447/// @param alias the new alias. Note that this elf_symbol should *NOT*
2448/// have aliases prior to the invocation of this function.
2449void
2451{
2452 if (!alias)
2453 return;
2454
2455 ABG_ASSERT(!alias->has_aliases());
2457
2458 if (has_aliases())
2459 {
2460 elf_symbol_sptr last_alias;
2462 a && !a->is_main_symbol();
2463 a = a->get_next_alias())
2464 {
2465 if (a->get_next_alias()->is_main_symbol())
2466 {
2467 ABG_ASSERT(last_alias == 0);
2468 last_alias = a;
2469 }
2470 }
2471 ABG_ASSERT(last_alias);
2472
2473 last_alias->priv_->next_alias_ = alias;
2474 }
2475 else
2476 priv_->next_alias_ = alias;
2477
2478 alias->priv_->next_alias_ = get_main_symbol();
2479 alias->priv_->main_symbol_ = get_main_symbol();
2480}
2481
2482/// Update the main symbol for a group of aliased symbols
2483///
2484/// If after the construction of the symbols (in order of discovery), the
2485/// actual main symbol can be identified (e.g. as the symbol that actually is
2486/// defined in the code), this method offers a way of updating the main symbol
2487/// through one of the aliased symbols.
2488///
2489/// For that, locate the new main symbol by name and update all references to
2490/// the main symbol among the group of aliased symbols.
2491///
2492/// @param name the name of the main symbol
2493///
2494/// @return the new main elf_symbol
2496elf_symbol::update_main_symbol(const std::string& name)
2497{
2499 if (!has_aliases() || get_name() == name)
2500 return get_main_symbol();
2501
2502 // find the new main symbol
2503 elf_symbol_sptr new_main;
2504 // we've already checked this; check the rest of the aliases
2505 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2506 a = a->get_next_alias())
2507 if (a->get_name() == name)
2508 {
2509 new_main = a;
2510 break;
2511 }
2512
2513 if (!new_main)
2514 return get_main_symbol();
2515
2516 // now update all main symbol references
2517 priv_->main_symbol_ = new_main;
2518 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2519 a = a->get_next_alias())
2520 a->priv_->main_symbol_ = new_main;
2521
2522 return new_main;
2523}
2524
2525/// Return true if the symbol is a common one.
2526///
2527/// @return true iff the symbol is common.
2528bool
2530{return priv_->is_common_;}
2531
2532/// Return true if this common common symbol has other common instances.
2533///
2534/// A common instance of a given common symbol is another common
2535/// symbol with the same name. Those exist in relocatable files. The
2536/// linker normally allocates all the instances into a common block in
2537/// the final output file.
2538///
2539/// Note that the current object must be a common symbol, otherwise,
2540/// this function aborts.
2541///
2542/// @return true iff the current common symbol has other common
2543/// instances.
2544bool
2550
2551/// Get the next common instance of the current common symbol.
2552///
2553/// A common instance of a given common symbol is another common
2554/// symbol with the same name. Those exist in relocatable files. The
2555/// linker normally allocates all the instances into a common block in
2556/// the final output file.
2557///
2558/// @return the next common instance, or nil if there is not any.
2561{return priv_->next_common_instance_.lock();}
2562
2563/// Add a common instance to the current common elf symbol.
2564///
2565/// Note that this symbol must be the main symbol. Being the main
2566/// symbol means being the first common symbol to appear in the symbol
2567/// table.
2568///
2569/// @param common the other common instance to add.
2570void
2572{
2573 if (!common)
2574 return;
2575
2576 ABG_ASSERT(!common->has_other_common_instances());
2579
2581 {
2582 elf_symbol_sptr last_common_instance;
2584 c && (c.get() != get_main_symbol().get());
2585 c = c->get_next_common_instance())
2586 {
2587 if (c->get_next_common_instance().get() == get_main_symbol().get())
2588 {
2589 ABG_ASSERT(last_common_instance == 0);
2590 last_common_instance = c;
2591 }
2592 }
2593 ABG_ASSERT(last_common_instance);
2594
2595 last_common_instance->priv_->next_common_instance_ = common;
2596 }
2597 else
2598 priv_->next_common_instance_ = common;
2599
2600 common->priv_->next_common_instance_ = get_main_symbol();
2601 common->priv_->main_symbol_ = get_main_symbol();
2602}
2603
2604/// Get a string that is representative of a given elf_symbol.
2605///
2606/// If the symbol has a version, then the ID string is the
2607/// concatenation of the name of the symbol, the '@' character, and
2608/// the version of the symbol. If the version is the default version
2609/// of the symbol then the '@' character is replaced by a "@@" string.
2610///
2611/// Otherwise, if the symbol does not have any version, this function
2612/// returns the name of the symbol.
2613///
2614/// @return a the ID string.
2615const string&
2617{
2618 if (priv_->id_string_.empty())
2619 {
2620 string s = get_name ();
2621
2622 if (!get_version().is_empty())
2623 {
2624 if (get_version().is_default())
2625 s += "@@";
2626 else
2627 s += "@";
2628 s += get_version().str();
2629 }
2630 priv_->id_string_ = s;
2631 }
2632
2633 return priv_->id_string_;
2634}
2635
2636/// From the aliases of the current symbol, lookup one with a given name.
2637///
2638/// @param name the name of symbol alias we are looking for.
2639///
2640/// @return the symbol alias that has the name @p name, or nil if none
2641/// has been found.
2643elf_symbol::get_alias_from_name(const string& name) const
2644{
2645 if (name == get_name())
2646 return elf_symbol_sptr(priv_->main_symbol_);
2647
2649 a && a.get() != get_main_symbol().get();
2650 a = a->get_next_alias())
2651 if (a->get_name() == name)
2652 return a;
2653
2654 return elf_symbol_sptr();
2655}
2656
2657/// In the list of aliases of a given elf symbol, get the alias that
2658/// equals this current symbol.
2659///
2660/// @param other the elf symbol to get the potential aliases from.
2661///
2662/// @return the alias of @p other that texually equals the current
2663/// symbol, or nil if no alias textually equals the current symbol.
2666{
2667 for (elf_symbol_sptr a = other.get_next_alias();
2668 a && a.get() != a->get_main_symbol().get();
2669 a = a->get_next_alias())
2670 if (textually_equals(*this, *a))
2671 return a;
2672 return elf_symbol_sptr();
2673}
2674
2675/// Return a comma separated list of the id of the current symbol as
2676/// well as the id string of its aliases.
2677///
2678/// @param syms a map of all the symbols of the corpus the current
2679/// symbol belongs to.
2680///
2681/// @param include_symbol_itself if set to true, then the name of the
2682/// current symbol is included in the list of alias names that is emitted.
2683///
2684/// @return the string.
2685string
2687 bool include_symbol_itself) const
2688{
2689 string result;
2690
2691 if (include_symbol_itself)
2692 result = get_id_string();
2693
2694 vector<elf_symbol_sptr> aliases;
2695 compute_aliases_for_elf_symbol(*this, syms, aliases);
2696 if (!aliases.empty() && include_symbol_itself)
2697 result += ", ";
2698
2699 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2700 i != aliases.end();
2701 ++i)
2702 {
2703 if (i != aliases.begin())
2704 result += ", ";
2705 result += (*i)->get_id_string();
2706 }
2707 return result;
2708}
2709
2710/// Return a comma separated list of the id of the current symbol as
2711/// well as the id string of its aliases.
2712///
2713/// @param include_symbol_itself if set to true, then the name of the
2714/// current symbol is included in the list of alias names that is emitted.
2715///
2716/// @return the string.
2717string
2718elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2719{
2720 vector<elf_symbol_sptr> aliases;
2721 if (include_symbol_itself)
2722 aliases.push_back(get_main_symbol());
2723
2725 a && a.get() != get_main_symbol().get();
2726 a = a->get_next_alias())
2727 aliases.push_back(a);
2728
2729 string result;
2730 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2731 i != aliases.end();
2732 ++i)
2733 {
2734 if (i != aliases.begin())
2735 result += ", ";
2736 result += (*i)->get_id_string();
2737 }
2738
2739 return result;
2740}
2741
2742/// Given the ID of a symbol, get the name and the version of said
2743/// symbol.
2744///
2745/// @param id the symbol ID to consider.
2746///
2747/// @param name the symbol name extracted from the ID. This is set
2748/// only if the function returned true.
2749///
2750/// @param ver the symbol version extracted from the ID.
2751bool
2753 string& name,
2754 string& ver)
2755{
2756 name.clear(), ver.clear();
2757
2758 string::size_type i = id.find('@');
2759 if (i == string::npos)
2760 {
2761 name = id;
2762 return true;
2763 }
2764
2765 name = id.substr(0, i);
2766 ++i;
2767
2768 if (i >= id.size())
2769 return true;
2770
2771 string::size_type j = id.find('@', i);
2772 if (j == string::npos)
2773 j = i;
2774 else
2775 ++j;
2776
2777 if (j >= id.size())
2778 {
2779 ver = "";
2780 return true;
2781 }
2782
2783 ver = id.substr(j);
2784 return true;
2785}
2786
2787///@}
2788
2789/// Test if two main symbols are textually equal, or, if they have
2790/// aliases that are textually equal.
2791///
2792/// @param other the symbol to compare against.
2793///
2794/// @return true iff the current instance of elf symbol equals the @p
2795/// other.
2796bool
2798{
2799 bool are_equal = textually_equals(*this, other);
2800 if (!are_equal)
2801 are_equal = bool(get_alias_which_equals(other));
2802 return are_equal;
2803}
2804
2805/// Test if the current symbol aliases another one.
2806///
2807/// @param o the other symbol to test against.
2808///
2809/// @return true iff the current symbol aliases @p o.
2810bool
2812{
2813 if (*this == o)
2814 return true;
2815
2816 if (get_main_symbol() == o.get_main_symbol())
2817 return true;
2818
2820 a && !a->is_main_symbol();
2821 a = a->get_next_alias())
2822 {
2823 if (o == *a)
2824 return true;
2825 }
2826 return false;
2827}
2828
2829/// Equality operator for smart pointers to elf_symbol.
2830///
2831/// @param lhs the first elf symbol to consider.
2832///
2833/// @param rhs the second elf symbol to consider.
2834///
2835/// @return true iff @p lhs equals @p rhs.
2836bool
2838{
2839 if (!!lhs != !!rhs)
2840 return false;
2841
2842 if (!lhs)
2843 return true;
2844
2845 return *lhs == *rhs;
2846}
2847
2848/// Inequality operator for smart pointers to elf_symbol.
2849///
2850/// @param lhs the first elf symbol to consider.
2851///
2852/// @param rhs the second elf symbol to consider.
2853///
2854/// @return true iff @p lhs is different from @p rhs.
2855bool
2857{return !operator==(lhs, rhs);}
2858
2859/// Test if two symbols alias.
2860///
2861/// @param s1 the first symbol to consider.
2862///
2863/// @param s2 the second symbol to consider.
2864///
2865/// @return true if @p s1 aliases @p s2.
2866bool
2868{return s1.does_alias(s2) || s2.does_alias(s1);}
2869
2870void
2871compute_aliases_for_elf_symbol(const elf_symbol& sym,
2872 const string_elf_symbols_map_type& symtab,
2873 vector<elf_symbol_sptr>& aliases)
2874{
2875
2876 if (elf_symbol_sptr a = sym.get_next_alias())
2877 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2878 aliases.push_back(a);
2879 else
2880 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2881 i != symtab.end();
2882 ++i)
2883 for (elf_symbols::const_iterator j = i->second.begin();
2884 j != i->second.end();
2885 ++j)
2886 {
2887 if (**j == sym)
2888 for (elf_symbol_sptr s = (*j)->get_next_alias();
2889 s && !s->is_main_symbol();
2890 s = s->get_next_alias())
2891 aliases.push_back(s);
2892 else
2893 for (elf_symbol_sptr s = (*j)->get_next_alias();
2894 s && !s->is_main_symbol();
2895 s = s->get_next_alias())
2896 if (*s == sym)
2897 aliases.push_back(*j);
2898 }
2899}
2900
2901/// Test if two symbols alias.
2902///
2903/// @param s1 the first symbol to consider.
2904///
2905/// @param s2 the second symbol to consider.
2906///
2907/// @return true if @p s1 aliases @p s2.
2908bool
2910{
2911 if (!!s1 != !!s2)
2912 return false;
2913 if (s1 == s2)
2914 return true;
2915 return elf_symbols_alias(*s1, *s2);
2916}
2917
2918/// Test if two symbols alias.
2919///
2920/// @param s1 the first symbol to consider.
2921///
2922/// @param s2 the second symbol to consider.
2923///
2924/// @return true if @p s1 aliases @p s2.
2925bool
2927{return elf_symbols_alias(s1.get(), s2.get());}
2928
2929/// Serialize an instance of @ref symbol_type and stream it to a given
2930/// output stream.
2931///
2932/// @param o the output stream to serialize the symbole type to.
2933///
2934/// @param t the symbol type to serialize.
2935std::ostream&
2936operator<<(std::ostream& o, elf_symbol::type t)
2937{
2938 string repr;
2939
2940 switch (t)
2941 {
2942 case elf_symbol::NOTYPE_TYPE:
2943 repr = "unspecified symbol type";
2944 break;
2945 case elf_symbol::OBJECT_TYPE:
2946 repr = "variable symbol type";
2947 break;
2948 case elf_symbol::FUNC_TYPE:
2949 repr = "function symbol type";
2950 break;
2951 case elf_symbol::SECTION_TYPE:
2952 repr = "section symbol type";
2953 break;
2954 case elf_symbol::FILE_TYPE:
2955 repr = "file symbol type";
2956 break;
2957 case elf_symbol::COMMON_TYPE:
2958 repr = "common data object symbol type";
2959 break;
2960 case elf_symbol::TLS_TYPE:
2961 repr = "thread local data object symbol type";
2962 break;
2963 case elf_symbol::GNU_IFUNC_TYPE:
2964 repr = "indirect function symbol type";
2965 break;
2966 default:
2967 {
2968 std::ostringstream s;
2969 s << "unknown symbol type (" << (char)t << ')';
2970 repr = s.str();
2971 }
2972 break;
2973 }
2974
2975 o << repr;
2976 return o;
2977}
2978
2979/// Serialize an instance of @ref symbol_binding and stream it to a
2980/// given output stream.
2981///
2982/// @param o the output stream to serialize the symbole type to.
2983///
2984/// @param b the symbol binding to serialize.
2985std::ostream&
2986operator<<(std::ostream& o, elf_symbol::binding b)
2987{
2988 string repr;
2989
2990 switch (b)
2991 {
2992 case elf_symbol::LOCAL_BINDING:
2993 repr = "local binding";
2994 break;
2995 case elf_symbol::GLOBAL_BINDING:
2996 repr = "global binding";
2997 break;
2998 case elf_symbol::WEAK_BINDING:
2999 repr = "weak binding";
3000 break;
3001 case elf_symbol::GNU_UNIQUE_BINDING:
3002 repr = "GNU unique binding";
3003 break;
3004 default:
3005 {
3006 std::ostringstream s;
3007 s << "unknown binding (" << (unsigned char) b << ")";
3008 repr = s.str();
3009 }
3010 break;
3011 }
3012
3013 o << repr;
3014 return o;
3015}
3016
3017/// Serialize an instance of @ref elf_symbol::visibility and stream it
3018/// to a given output stream.
3019///
3020/// @param o the output stream to serialize the symbole type to.
3021///
3022/// @param v the symbol visibility to serialize.
3023std::ostream&
3024operator<<(std::ostream& o, elf_symbol::visibility v)
3025{
3026 string repr;
3027
3028 switch (v)
3029 {
3030 case elf_symbol::DEFAULT_VISIBILITY:
3031 repr = "default visibility";
3032 break;
3033 case elf_symbol::PROTECTED_VISIBILITY:
3034 repr = "protected visibility";
3035 break;
3036 case elf_symbol::HIDDEN_VISIBILITY:
3037 repr = "hidden visibility";
3038 break;
3039 case elf_symbol::INTERNAL_VISIBILITY:
3040 repr = "internal visibility";
3041 break;
3042 default:
3043 {
3044 std::ostringstream s;
3045 s << "unknown visibility (" << (unsigned char) v << ")";
3046 repr = s.str();
3047 }
3048 break;
3049 }
3050
3051 o << repr;
3052 return o;
3053}
3054
3055/// Convert a string representing a symbol type into an
3056/// elf_symbol::type.
3057///
3058///@param s the string to convert.
3059///
3060///@param t the resulting elf_symbol::type.
3061///
3062/// @return true iff the conversion completed successfully.
3063bool
3065{
3066 if (s == "no-type")
3067 t = elf_symbol::NOTYPE_TYPE;
3068 else if (s == "object-type")
3069 t = elf_symbol::OBJECT_TYPE;
3070 else if (s == "func-type")
3071 t = elf_symbol::FUNC_TYPE;
3072 else if (s == "section-type")
3073 t = elf_symbol::SECTION_TYPE;
3074 else if (s == "file-type")
3075 t = elf_symbol::FILE_TYPE;
3076 else if (s == "common-type")
3077 t = elf_symbol::COMMON_TYPE;
3078 else if (s == "tls-type")
3079 t = elf_symbol::TLS_TYPE;
3080 else if (s == "gnu-ifunc-type")
3081 t = elf_symbol::GNU_IFUNC_TYPE;
3082 else
3083 return false;
3084
3085 return true;
3086}
3087
3088/// Convert a string representing a an elf symbol binding into an
3089/// elf_symbol::binding.
3090///
3091/// @param s the string to convert.
3092///
3093/// @param b the resulting elf_symbol::binding.
3094///
3095/// @return true iff the conversion completed successfully.
3096bool
3098{
3099 if (s == "local-binding")
3100 b = elf_symbol::LOCAL_BINDING;
3101 else if (s == "global-binding")
3102 b = elf_symbol::GLOBAL_BINDING;
3103 else if (s == "weak-binding")
3104 b = elf_symbol::WEAK_BINDING;
3105 else if (s == "gnu-unique-binding")
3106 b = elf_symbol::GNU_UNIQUE_BINDING;
3107 else
3108 return false;
3109
3110 return true;
3111}
3112
3113/// Convert a string representing a an elf symbol visibility into an
3114/// elf_symbol::visibility.
3115///
3116/// @param s the string to convert.
3117///
3118/// @param b the resulting elf_symbol::visibility.
3119///
3120/// @return true iff the conversion completed successfully.
3121bool
3123{
3124 if (s == "default-visibility")
3125 v = elf_symbol::DEFAULT_VISIBILITY;
3126 else if (s == "protected-visibility")
3127 v = elf_symbol::PROTECTED_VISIBILITY;
3128 else if (s == "hidden-visibility")
3129 v = elf_symbol::HIDDEN_VISIBILITY;
3130 else if (s == "internal-visibility")
3131 v = elf_symbol::INTERNAL_VISIBILITY;
3132 else
3133 return false;
3134
3135 return true;
3136}
3137
3138/// Test if the type of an ELF symbol denotes a function symbol.
3139///
3140/// @param t the type of the ELF symbol.
3141///
3142/// @return true iff elf symbol type @p t denotes a function symbol
3143/// type.
3144bool
3146{return t == elf_symbol::FUNC_TYPE;}
3147
3148/// Test if the type of an ELF symbol denotes a function symbol.
3149///
3150/// @param t the type of the ELF symbol.
3151///
3152/// @return true iff elf symbol type @p t denotes a function symbol
3153/// type.
3154bool
3156{return t == elf_symbol::OBJECT_TYPE;}
3157
3158// <elf_symbol::version stuff>
3159
3160struct elf_symbol::version::priv
3161{
3162 string version_;
3163 bool is_default_;
3164
3165 priv()
3166 : is_default_(false)
3167 {}
3168
3169 priv(const string& v,
3170 bool d)
3171 : version_(v),
3172 is_default_(d)
3173 {}
3174}; // end struct elf_symbol::version::priv
3175
3176elf_symbol::version::version()
3177 : priv_(new priv)
3178{}
3179
3180/// @param v the name of the version.
3181///
3182/// @param is_default true if this is a default version.
3183elf_symbol::version::version(const string& v,
3184 bool is_default)
3185 : priv_(new priv(v, is_default))
3186{}
3187
3188elf_symbol::version::version(const elf_symbol::version& v)
3189 : priv_(new priv(v.str(), v.is_default()))
3190{
3191}
3192
3193elf_symbol::version::~version() = default;
3194
3195/// Cast the version_type into a string that is its name.
3196///
3197/// @return the name of the version.
3198elf_symbol::version::operator const string&() const
3199{return priv_->version_;}
3200
3201/// Getter for the version name.
3202///
3203/// @return the version name.
3204const string&
3206{return priv_->version_;}
3207
3208/// Setter for the version name.
3209///
3210/// @param s the version name.
3211void
3213{priv_->version_ = s;}
3214
3215/// Getter for the 'is_default' property of the version.
3216///
3217/// @return true iff this is a default version.
3218bool
3220{return priv_->is_default_;}
3221
3222/// Setter for the 'is_default' property of the version.
3223///
3224/// @param f true if this is the default version.
3225void
3227{priv_->is_default_ = f;}
3228
3229bool
3230elf_symbol::version::is_empty() const
3231{return str().empty();}
3232
3233/// Compares the current version against another one.
3234///
3235/// @param o the other version to compare the current one to.
3236///
3237/// @return true iff the current version equals @p o.
3238bool
3240{return str() == o.str();}
3241
3242/// Inequality operator.
3243///
3244/// @param o the version to compare against the current one.
3245///
3246/// @return true iff both versions are different.
3247bool
3249{return !operator==(o);}
3250
3251/// Assign a version to the current one.
3252///
3253/// @param o the other version to assign to this one.
3254///
3255/// @return a reference to the assigned version.
3258{
3259 str(o.str());
3260 is_default(o.is_default());
3261 return *this;
3262}
3263
3264// </elf_symbol::version stuff>
3265
3266// </elf_symbol stuff>
3267
3268// <class dm_context_rel stuff>
3269struct dm_context_rel::priv
3270{
3271 bool is_laid_out_;
3272 size_t offset_in_bits_;
3273 var_decl* anonymous_data_member_;
3274
3275 priv(bool is_static = false)
3276 : is_laid_out_(!is_static),
3277 offset_in_bits_(0),
3278 anonymous_data_member_()
3279 {}
3280
3281 priv(bool is_laid_out, size_t offset_in_bits)
3282 : is_laid_out_(is_laid_out),
3283 offset_in_bits_(offset_in_bits),
3284 anonymous_data_member_()
3285 {}
3286}; //end struct dm_context_rel::priv
3287
3288dm_context_rel::dm_context_rel()
3289 : context_rel(),
3290 priv_(new priv)
3291{}
3292
3293dm_context_rel::dm_context_rel(scope_decl* s,
3294 bool is_laid_out,
3295 size_t offset_in_bits,
3297 bool is_static)
3298 : context_rel(s, a, is_static),
3299 priv_(new priv(is_laid_out, offset_in_bits))
3300{}
3301
3302dm_context_rel::dm_context_rel(scope_decl* s)
3303 : context_rel(s),
3304 priv_(new priv())
3305{}
3306
3307bool
3308dm_context_rel::get_is_laid_out() const
3309{return priv_->is_laid_out_;}
3310
3311void
3312dm_context_rel::set_is_laid_out(bool f)
3313{priv_->is_laid_out_ = f;}
3314
3315size_t
3316dm_context_rel::get_offset_in_bits() const
3317{return priv_->offset_in_bits_;}
3318
3319void
3320dm_context_rel::set_offset_in_bits(size_t o)
3321{priv_->offset_in_bits_ = o;}
3322
3323bool
3324dm_context_rel::operator==(const dm_context_rel& o) const
3325{
3326 if (!context_rel::operator==(o))
3327 return false;
3328
3329 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3330 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3331}
3332
3333bool
3334dm_context_rel::operator!=(const dm_context_rel& o) const
3335{return !operator==(o);}
3336
3337/// Return a non-nil value if this data member context relationship
3338/// has an anonymous data member. That means, if the data member this
3339/// relation belongs to is part of an anonymous data member.
3340///
3341/// @return the containing anonymous data member of this data member
3342/// relationship. Nil if there is none.
3343const var_decl*
3345{return priv_->anonymous_data_member_;}
3346
3347/// Set the containing anonymous data member of this data member
3348/// context relationship. That means that the data member this
3349/// relation belongs to is part of an anonymous data member.
3350///
3351/// @param anon_dm the containing anonymous data member of this data
3352/// member relationship. Nil if there is none.
3353void
3355{priv_->anonymous_data_member_ = anon_dm;}
3356
3357dm_context_rel::~dm_context_rel()
3358{}
3359// </class dm_context_rel stuff>
3360
3361// <environment stuff>
3362
3363/// Convenience typedef for a map of interned_string -> bool.
3364typedef unordered_map<interned_string,
3366
3367
3368/// Default constructor of the @ref environment type.
3370 :priv_(new priv)
3371{}
3372
3373/// Destructor for the @ref environment type.
3376
3377/// Getter the map of canonical types.
3378///
3379/// @return the map of canonical types. The key of the map is the
3380/// hash of the canonical type and its value if the canonical type.
3383{return priv_->canonical_types_;}
3384
3385/// Getter the map of canonical types.
3386///
3387/// @return the map of canonical types. The key of the map is the
3388/// hash of the canonical type and its value if the canonical type.
3392
3393/// Helper to detect if a type is either a reference, a pointer, or a
3394/// qualified type.
3395bool
3397{
3398 if (is_pointer_type(t)
3399 || is_reference_type(t)
3400 || is_qualified_type(t))
3401 return true;
3402 return false;
3403}
3404
3405/// Compare decls using their locations.
3406///
3407/// @param f the first decl to compare.
3408///
3409/// @param s the second decl to compare.
3410///
3411/// @return true if @p f compares less than @p s.
3412bool
3414 const decl_base *s)
3415{
3416 // If a decl has artificial location, then use that one over the
3417 // natural one.
3420
3421 ABG_ASSERT(fl.get_value() && sl.get_value());
3422 if (fl.get_is_artificial() == sl.get_is_artificial())
3423 {
3424 // The locations of the two artfifacts have the same
3425 // artificial-ness so they can be compared.
3426 string p1, p2;
3427 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3428 fl.expand(p1, l1, c1);
3429 sl.expand(p2, l2, c2);
3430 if (p1 != p2)
3431 return p1 < p2;
3432 if (l1 != l2)
3433 return l1 < l2;
3434 if (c1 != c2)
3435 return c1 < c2;
3436 }
3437
3438 return (get_pretty_representation(f, /*internal=*/false)
3439 < get_pretty_representation(s, /*internal=*/false));
3440}
3441
3442/// Sort types in a hopefully stable manner.
3443///
3444/// @param types a set of types with canonical types to sort.
3445///
3446/// @param result the resulting sorted vector.
3447void
3449 vector<type_base_sptr>& result)
3450{
3451 for (auto t: types)
3452 result.push_back(t);
3453
3454 type_topo_comp comp;
3455 std::stable_sort(result.begin(), result.end(), comp);
3456}
3457
3458/// Get the unique @ref type_decl that represents a "void" type for
3459/// the current environment. This node must be the only one
3460/// representing a void type in the system.
3461///
3462/// Note that upon first use of this IR node (by the relevant
3463/// front-end, for instance) it must be added to a scope using e.g,
3464/// the @ref add_decl_to_scope() function.
3465///
3466/// @return the @ref type_decl that represents a "void" type.
3467const type_base_sptr&
3469{
3470 if (!priv_->void_type_)
3471 priv_->void_type_.reset(new type_decl(*this,
3472 intern("void"),
3473 0, 0, location()));
3474 return priv_->void_type_;
3475}
3476
3477/// Getter of the "pointer-to-void" IR node that is shared across the
3478/// ABI corpus. This node must be the only one representing a void
3479/// pointer type in the system.
3480///
3481/// Note that upon first use of this IR node (by the relevant
3482/// front-end, for instance) it must be added to a scope using e.g,
3483/// the @ref add_decl_to_scope() function.
3484///
3485/// @return the "pointer-to-void" IR node.
3486const type_base_sptr&
3488{
3489 if (!priv_->void_pointer_type_)
3490 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3491 0, 0, location()));
3492 return priv_->void_pointer_type_;
3493}
3494
3495/// Get a @ref type_decl instance that represents a the type of a
3496/// variadic function parameter. This node must be the only one
3497/// representing a variadic parameter type in the system.
3498///
3499/// Note that upon first use of this IR node (by the relevant
3500/// front-end, for instance) it must be added to a scope using e.g,
3501/// the @ref add_decl_to_scope() function.
3502///
3503/// @return the Get a @ref type_decl instance that represents a the
3504/// type of a variadic function parameter.
3505const type_base_sptr&
3507{
3508 if (!priv_->variadic_marker_type_)
3509 priv_->variadic_marker_type_.
3511 0, 0, location()));
3512 return priv_->variadic_marker_type_;
3513}
3514
3515/// Getter of the name of the variadic parameter type.
3516///
3517/// @return the name of the variadic parameter type.
3518string&
3520{
3521 static string variadic_parameter_type_name = "variadic parameter type";
3522 return variadic_parameter_type_name;
3523}
3524
3525/// Test if the canonicalization of types created out of the current
3526/// environment is done.
3527///
3528/// @return true iff the canonicalization of types created out of the current
3529/// environment is done.
3530bool
3532{return priv_->canonicalization_is_done_;}
3533
3534/// Set a flag saying if the canonicalization of types created out of
3535/// the current environment is done or not.
3536///
3537/// Note that this function must only be called by internal code of
3538/// the library that creates ABI artifacts (e.g, read an abi corpus
3539/// from elf or from our own xml format and creates representations of
3540/// types out of it) and thus needs to canonicalize types to speed-up
3541/// further type comparison.
3542///
3543/// @param f the new value of the flag.
3544void
3546{
3547 priv_->canonicalization_is_done_ = f;
3548 if (priv_->canonicalization_is_done_)
3550}
3551
3552/// Getter of a flag saying if the canonicalization process has
3553/// started or not.
3554///
3555/// @return the flag saying if the canonicalization process has
3556/// started or not.
3557bool
3559{return priv_->canonicalization_started_;}
3560
3561/// Setter of a flag saying if the canonicalization process has
3562/// started or not.
3563///
3564/// @param f the new value of the flag saying if the canonicalization
3565/// process has started or not.
3566void
3568{priv_->canonicalization_started_ = f;}
3569
3570/// Getter of the "decl-only-class-equals-definition" flag.
3571///
3572/// Usually, a declaration-only class named 'struct foo' compares
3573/// equal to any class definition named "struct foo'. This is at
3574/// least true for C++.
3575///
3576/// In C, though, because there can be multiple definitions of 'struct
3577/// foo' in the binary, a declaration-only "struct foo" might be
3578/// considered to *NOT* resolve to any of the struct foo defined. In
3579/// that case, the declaration-only "struct foo" is considered
3580/// different from the definitions.
3581///
3582/// This flag controls the behaviour of the comparison of an
3583/// unresolved decl-only class against a definition of the same name.
3584///
3585/// If set to false, the the declaration equals the definition. If
3586/// set to false, then the decalration is considered different from
3587/// the declaration.
3588///
3589/// @return the value of the "decl-only-class-equals-definition" flag.
3590bool
3592{return priv_->decl_only_class_equals_definition_;}
3593
3594/// Setter of the "decl-only-class-equals-definition" flag.
3595///
3596/// Usually, a declaration-only class named 'struct foo' compares
3597/// equal to any class definition named "struct foo'. This is at
3598/// least true for C++.
3599///
3600/// In C, though, because there can be multiple definitions of 'struct
3601/// foo' in the binary, a declaration-only "struct foo" might be
3602/// considered to *NOT* resolve to any of the struct foo defined. In
3603/// that case, the declaration-only "struct foo" is considered
3604/// different from the definitions.
3605///
3606/// This flag controls the behaviour of the comparison of an
3607/// unresolved decl-only class against a definition of the same name.
3608///
3609/// If set to false, the the declaration equals the definition. If
3610/// set to false, then the decalration is considered different from
3611/// the declaration.
3612///
3613/// @param the new value of the "decl-only-class-equals-definition"
3614/// flag.
3615void
3617{priv_->decl_only_class_equals_definition_ = f;}
3618
3619/// Test if a given type is a void type as defined in the current
3620/// environment.
3621///
3622/// @param t the type to consider.
3623///
3624/// @return true iff @p t is a void type as defined in the current
3625/// environment.
3626bool
3627environment::is_void_type(const type_base_sptr& t) const
3628{
3629 if (!t)
3630 return false;
3631 return is_void_type(t.get());
3632}
3633
3634/// Test if a given type is a void type as defined in the current
3635/// environment.
3636///
3637/// @param t the type to consider.
3638///
3639/// @return true iff @p t is a void type as defined in the current
3640/// environment.
3641bool
3643{
3644 if (!t)
3645 return false;
3646 return (t == get_void_type().get()
3647 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3648}
3649
3650/// Test if a given type is the same as the void pointer type of the
3651/// environment.
3652///
3653/// @param t the IR type to test.
3654///
3655/// @return true iff @p t is the void pointer returned by
3656/// environment::get_void_pointer_type().
3657bool
3658environment::is_void_pointer_type(const type_base_sptr& t) const
3659{
3660 if (!t)
3661 return false;
3662
3663 return t.get() == get_void_pointer_type().get();
3664}
3665
3666/// Test if a given type is the same as the void pointer type of the
3667/// environment.
3668///
3669/// @param t the IR type to test.
3670///
3671/// @return true iff @p t is the void pointer returned by
3672/// environment::get_void_pointer_type().
3673bool
3675{
3676 if (!t)
3677 return false;
3678
3679 return t == get_void_pointer_type().get();
3680}
3681
3682/// Test if a type is a variadic parameter type as defined in the
3683/// current environment.
3684///
3685/// @param t the type to consider.
3686///
3687/// @return true iff @p t is a variadic parameter type as defined in
3688/// the current environment.
3689bool
3691{
3692 if (!t)
3693 return false;
3694 return t == get_variadic_parameter_type().get();
3695}
3696
3697/// Test if a type is a variadic parameter type as defined in the
3698/// current environment.
3699///
3700/// @param t the type to consider.
3701///
3702/// @return true iff @p t is a variadic parameter type as defined in
3703/// the current environment.
3704bool
3705environment::is_variadic_parameter_type(const type_base_sptr& t) const
3706{return is_variadic_parameter_type(t.get());}
3707
3708/// Do intern a string.
3709///
3710/// If a value of this string already exists in the interned string
3711/// pool of the current environment, then this function returns a new
3712/// interned_string pointing to that already existing string.
3713/// Otherwise, a new string is created, stored in the interned string
3714/// pool and a new interned_string instance is created to point to
3715/// that new intrerned string, and it's return.
3716///
3717/// @param s the value of the string to intern.
3718///
3719/// @return the interned string.
3721environment::intern(const string& s) const
3722{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3723
3724/// Getter of the general configuration object.
3725///
3726/// @return the configuration object.
3727const config&
3729{return priv_->config_;}
3730
3731/// Getter for a property that says if the user actually did set the
3732/// analyze_exported_interfaces_only() property. If not, it means
3733/// the default behaviour prevails.
3734///
3735/// @return tru iff the user did set the
3736/// analyze_exported_interfaces_only() property.
3737bool
3739{return priv_->analyze_exported_interfaces_only_.has_value();}
3740
3741/// Setter for the property that controls if we are to restrict the
3742/// analysis to the types that are only reachable from the exported
3743/// interfaces only, or if the set of types should be more broad than
3744/// that. Typically, we'd restrict the analysis to types reachable
3745/// from exported interfaces only (stricto sensu, that would really be
3746/// only the types that are part of the ABI of well designed
3747/// libraries) for performance reasons.
3748///
3749/// @param f the value of the flag.
3750void
3752{priv_->analyze_exported_interfaces_only_ = f;}
3753
3754/// Getter for the property that controls if we are to restrict the
3755/// analysis to the types that are only reachable from the exported
3756/// interfaces only, or if the set of types should be more broad than
3757/// that. Typically, we'd restrict the analysis to types reachable
3758/// from exported interfaces only (stricto sensu, that would really be
3759/// only the types that are part of the ABI of well designed
3760/// libraries) for performance reasons.
3761///
3762/// @param f the value of the flag.
3763bool
3765{return priv_->analyze_exported_interfaces_only_.value_or(false);}
3766
3767#ifdef WITH_DEBUG_SELF_COMPARISON
3768/// Setter of the corpus of the input corpus of the self comparison
3769/// that takes place when doing "abidw --debug-abidiff <binary>".
3770///
3771/// The first invocation of this function sets the first corpus of the
3772/// self comparison. The second invocation of this very same function
3773/// sets the second corpus of the self comparison. That second corpus
3774/// is supposed to come from the abixml serialization of the first
3775/// corpus.
3776///
3777/// @param c the corpus of the input binary or the corpus of the
3778/// abixml serialization of the initial binary input.
3779void
3780environment::set_self_comparison_debug_input(const corpus_sptr& c)
3781{
3782 self_comparison_debug_is_on(true);
3783 if (priv_->first_self_comparison_corpus_.expired())
3784 priv_->first_self_comparison_corpus_ = c;
3785 else if (priv_->second_self_comparison_corpus_.expired()
3786 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3787 priv_->second_self_comparison_corpus_ = c;
3788}
3789
3790/// Getter for the corpora of the input binary and the intermediate
3791/// abixml of the self comparison that takes place when doing
3792/// 'abidw --debug-abidiff <binary>'.
3793///
3794/// @param first_corpus output parameter that is set to the corpus of
3795/// the input corpus.
3796///
3797/// @param second_corpus output parameter that is set to the corpus of
3798/// the second corpus.
3799void
3800environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3801 corpus_sptr& second_corpus)
3802{
3803 first_corpus = priv_->first_self_comparison_corpus_.lock();
3804 second_corpus = priv_->second_self_comparison_corpus_.lock();
3805}
3806
3807/// Turn on/off the self comparison debug mode.
3808///
3809/// @param f true iff the self comparison debug mode is turned on.
3810void
3811environment::self_comparison_debug_is_on(bool f)
3812{priv_->self_comparison_debug_on_ = f;}
3813
3814/// Test if we are in the process of the 'self-comparison
3815/// debugging' as triggered by 'abidw --debug-abidiff' command.
3816///
3817/// @return true if self comparison debug is on.
3818bool
3819environment::self_comparison_debug_is_on() const
3820{return priv_->self_comparison_debug_on_;}
3821#endif
3822
3823#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3824/// Set the "type canonicalization debugging" mode, triggered by using
3825/// the command: "abidw --debug-tc".
3826///
3827/// @param flag if true then the type canonicalization debugging mode
3828/// is enabled.
3829void
3830environment::debug_type_canonicalization_is_on(bool flag)
3831{priv_->debug_type_canonicalization_ = flag;}
3832
3833/// Getter of the "type canonicalization debugging" mode, triggered by
3834/// using the command: "abidw --debug-tc".
3835///
3836/// @return true iff the type canonicalization debugging mode is
3837/// enabled.
3838bool
3839environment::debug_type_canonicalization_is_on() const
3840{return priv_->debug_type_canonicalization_;}
3841
3842/// Setter of the "DIE canonicalization debugging" mode, triggered by
3843/// using the command: "abidw --debug-dc".
3844///
3845/// @param flag true iff the DIE canonicalization debugging mode is
3846/// enabled.
3847void
3848environment::debug_die_canonicalization_is_on(bool flag)
3849{priv_->debug_die_canonicalization_ = flag;}
3850
3851/// Getter of the "DIE canonicalization debugging" mode, triggered by
3852/// using the command: "abidw --debug-dc".
3853///
3854/// @return true iff the DIE canonicalization debugging mode is
3855/// enabled.
3856bool
3857environment::debug_die_canonicalization_is_on() const
3858{return priv_->debug_die_canonicalization_;}
3859#endif // WITH_DEBUG_TYPE_CANONICALIZATION
3860
3861/// Get the vector of canonical types which have a given "string
3862/// representation".
3863///
3864/// @param 'name', the textual representation of the type as returned
3865/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3866/// /*qualified=*/true)
3867///
3868/// This is useful to for debugging purposes as it's handy to use from
3869/// inside a debugger like GDB.
3870///
3871/// @return a pointer to the vector of canonical types having the
3872/// representation @p name, or nullptr if no type with that
3873/// representation exists.
3874const vector<type_base_sptr>*
3876{
3877 auto ti = get_canonical_types_map().find(name);
3878 if (ti == get_canonical_types_map().end())
3879 return nullptr;
3880 return &ti->second;
3881}
3882
3883/// Get a given canonical type which has a given "string
3884/// representation".
3885///
3886/// @param 'name', the textual representation of the type as returned
3887/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3888/// /*qualified=*/true).
3889///
3890/// @param index, the index of the type in the vector of types that
3891/// all have the same textual representation @p 'name'. That vector
3892/// is returned by the function environment::get_canonical_types().
3893///
3894/// @return the canonical type which has the representation @p name,
3895/// and which is at index @p index in the vector of canonical types
3896/// having that same textual representation.
3897type_base*
3898environment::get_canonical_type(const char* name, unsigned index)
3899{
3900 const vector<type_base_sptr> *types = get_canonical_types(name);
3901 if (!types ||index >= types->size())
3902 return nullptr;
3903 return (*types)[index].get();
3904}
3905
3906#ifdef WITH_DEBUG_SELF_COMPARISON
3907/// Get the set of abixml type-id and the pointer value of the
3908/// (canonical) type it's associated to.
3909///
3910/// This is useful for debugging purposes, especially in the context
3911/// of the use of the command:
3912/// 'abidw --debug-abidiff <binary>'.
3913///
3914/// @return the set of abixml type-id and the pointer value of the
3915/// (canonical) type it's associated to.
3916const unordered_map<string, uintptr_t>&
3917environment::get_type_id_canonical_type_map() const
3918{return priv_->get_type_id_canonical_type_map();}
3919
3920/// Get the set of abixml type-id and the pointer value of the
3921/// (canonical) type it's associated to.
3922///
3923/// This is useful for debugging purposes, especially in the context
3924/// of the use of the command:
3925/// 'abidw --debug-abidiff <binary>'.
3926///
3927/// @return the set of abixml type-id and the pointer value of the
3928/// (canonical) type it's associated to.
3929unordered_map<string, uintptr_t>&
3930environment::get_type_id_canonical_type_map()
3931{return priv_->get_type_id_canonical_type_map();}
3932
3933/// Getter of the map that associates the values of type pointers to
3934/// their type-id strings.
3935///
3936/// Note that this map is populated at abixml reading time, (by
3937/// build_type()) when a given XML element representing a type is
3938/// read into a corresponding abigail::ir::type_base.
3939///
3940/// This is used only for the purpose of debugging the
3941/// self-comparison process. That is, when invoking "abidw
3942/// --debug-abidiff".
3943///
3944/// @return the map that associates the values of type pointers to
3945/// their type-id strings.
3946const unordered_map<uintptr_t, string>&
3947environment::get_pointer_type_id_map() const
3948{return priv_->get_pointer_type_id_map();}
3949
3950/// Getter of the map that associates the values of type pointers to
3951/// their type-id strings.
3952///
3953/// Note that this map is populated at abixml reading time, (by
3954/// build_type()) when a given XML element representing a type is
3955/// read into a corresponding abigail::ir::type_base.
3956///
3957/// This is used only for the purpose of debugging the
3958/// self-comparison process. That is, when invoking "abidw
3959/// --debug-abidiff".
3960///
3961/// @return the map that associates the values of type pointers to
3962/// their type-id strings.
3963unordered_map<uintptr_t, string>&
3964environment::get_pointer_type_id_map()
3965{return priv_->get_pointer_type_id_map();}
3966
3967/// Getter of the type-id that corresponds to the value of a pointer
3968/// to abigail::ir::type_base that was created from the abixml reader.
3969///
3970/// That value is retrieved from the map returned from
3971/// environment::get_pointer_type_id_map().
3972///
3973/// That map is populated at abixml reading time, (by build_type())
3974/// when a given XML element representing a type is read into a
3975/// corresponding abigail::ir::type_base.
3976///
3977/// This is used only for the purpose of debugging the
3978/// self-comparison process. That is, when invoking "abidw
3979/// --debug-abidiff".
3980///
3981/// @return the type-id strings that corresponds
3982string
3983environment::get_type_id_from_pointer(uintptr_t ptr) const
3984{return priv_->get_type_id_from_pointer(ptr);}
3985
3986/// Getter of the type-id that corresponds to the value of an
3987/// abigail::ir::type_base that was created from the abixml reader.
3988///
3989/// That value is retrieved from the map returned from
3990/// environment::get_pointer_type_id_map().
3991///
3992/// That map is populated at abixml reading time, (by build_type())
3993/// when a given XML element representing a type is read into a
3994/// corresponding abigail::ir::type_base.
3995///
3996/// This is used only for the purpose of debugging the
3997/// self-comparison process. That is, when invoking "abidw
3998/// --debug-abidiff".
3999///
4000/// @return the type-id strings that corresponds
4001string
4002environment::get_type_id_from_type(const type_base *t) const
4003{return priv_->get_type_id_from_type(t);}
4004
4005/// Getter of the canonical type of the artifact designated by a
4006/// type-id.
4007///
4008/// That type-id was generated by the abixml writer at the emitting
4009/// time of the abixml file. The corresponding canonical type was
4010/// stored in the map returned by
4011/// environment::get_type_id_canonical_type_map().
4012///
4013/// This is useful for debugging purposes, especially in the context
4014/// of the use of the command:
4015/// 'abidw --debug-abidiff <binary>'.
4016///
4017/// @return the set of abixml type-id and the pointer value of the
4018/// (canonical) type it's associated to.
4019uintptr_t
4020environment::get_canonical_type_from_type_id(const char* type_id) const
4021{return priv_->get_canonical_type_from_type_id(type_id);}
4022#endif
4023
4024// </environment stuff>
4025
4026// <type_or_decl_base stuff>
4027
4028/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
4029/// bitmap type.
4033{
4034 return static_cast<type_or_decl_base::type_or_decl_kind>
4035 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4036}
4037
4038/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4039/// bitmap type.
4043{
4044 l = l | r;
4045 return l;
4046}
4047
4048/// bitwise "AND" operator for the
4049/// type_or_decl_base::type_or_decl_kind bitmap type.
4053{
4054 return static_cast<type_or_decl_base::type_or_decl_kind>
4055 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4056}
4057
4058/// bitwise "A&=" operator for the
4059/// type_or_decl_base::type_or_decl_kind bitmap type.
4063{
4064 l = l & r;
4065 return l;
4066}
4067
4068/// Constructor of @ref type_or_decl_base.
4069///
4070/// @param the environment the current ABI artifact is constructed
4071/// from.
4072///
4073/// @param k the runtime identifier bitmap of the type being built.
4074type_or_decl_base::type_or_decl_base(const environment& e,
4075 enum type_or_decl_kind k)
4076 :priv_(new priv(e, k))
4077{}
4078
4079/// The destructor of the @ref type_or_decl_base type.
4082
4083/// Getter of the flag that says if the artefact is artificial.
4084///
4085/// Being artificial means it was not explicitely mentionned in the
4086/// source code, but was rather artificially created by the compiler
4087/// or libabigail.
4088///
4089/// @return true iff the declaration is artificial.
4090bool
4092{return priv_->is_artificial_;}
4093
4094/// Setter of the flag that says if the artefact is artificial.
4095///
4096/// Being artificial means the artefact was not explicitely
4097/// mentionned in the source code, but was rather artificially created
4098/// by the compiler or by libabigail.
4099///
4100/// @param f the new value of the flag that says if the artefact is
4101/// artificial.
4102void
4104{priv_->is_artificial_ = f;}
4105
4106/// Getter for the "kind" property of @ref type_or_decl_base type.
4107///
4108/// This property holds the identifier bitmap of the runtime type of
4109/// an ABI artifact.
4110///
4111/// @return the runtime type identifier bitmap of the current ABI
4112/// artifact.
4115{return priv_->kind();}
4116
4117/// Setter for the "kind" property of @ref type_or_decl_base type.
4118///
4119/// This property holds the identifier bitmap of the runtime type of
4120/// an ABI artifact.
4121///
4122/// @param the runtime type identifier bitmap of the current ABI
4123/// artifact.
4124void
4126{priv_->kind(k);}
4127
4128/// Getter of the pointer to the runtime type sub-object of the
4129/// current instance.
4130///
4131/// @return the pointer to the runtime type sub-object of the current
4132/// instance.
4133const void*
4135{return priv_->rtti_;}
4136
4137/// Getter of the pointer to the runtime type sub-object of the
4138/// current instance.
4139///
4140/// @return the pointer to the runtime type sub-object of the current
4141/// instance.
4142void*
4144{return priv_->rtti_;}
4145
4146/// Setter of the pointer to the runtime type sub-object of the
4147/// current instance.
4148///
4149/// @param i the new pointer to the runtime type sub-object of the
4150/// current instance.
4151void
4153{
4154 priv_->rtti_ = i;
4155 if (type_base* t = dynamic_cast<type_base*>(this))
4156 priv_->type_or_decl_ptr_ = t;
4157 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4158 priv_->type_or_decl_ptr_ = d;
4159}
4160
4161/// Getter of the pointer to either the type_base sub-object of the
4162/// current instance if it's a type, or to the decl_base sub-object of
4163/// the current instance if it's a decl.
4164///
4165/// @return the pointer to either the type_base sub-object of the
4166/// current instance if it's a type, or to the decl_base sub-object of
4167/// the current instance if it's a decl.
4168const void*
4171
4172/// Getter of the pointer to either the type_base sub-object of the
4173/// current instance if it's a type, or to the decl_base sub-object of
4174/// the current instance if it's a decl.
4175///
4176/// @return the pointer to either the type_base sub-object of the
4177/// current instance if it's a type, or to the decl_base sub-object of
4178/// the current instance if it's a decl.
4179void*
4181{return priv_->type_or_decl_ptr_;}
4182
4183/// Return the hash value of the current IR node.
4184///
4185/// Note that upon the first invocation, this member functions
4186/// computes the hash value and returns it. Subsequent invocations
4187/// just return the hash value that was previously calculated.
4188///
4189/// @return the hash value of the current IR node.
4190hash_t
4192{return priv_->hash_value_;}
4193
4194void
4195type_or_decl_base::set_hash_value(hash_t h) const
4196{priv_->set_hash_value(h);}
4197
4198/// Getter of the environment of the current ABI artifact.
4199///
4200/// @return the environment of the artifact.
4201const environment&
4203{return priv_->env_;}
4204
4205/// Setter of the artificial location of the artificat.
4206///
4207/// The artificial location is a location that was artificially
4208/// generated by libabigail, not generated by the original emitter of
4209/// the ABI meta-data. For instance, when reading an XML element from
4210/// an abixml file, the artificial location is the source location of
4211/// the XML element within the file, not the value of the
4212/// 'location'property that might be carried by the element.
4213///
4214/// Artificial locations might be useful to ensure that abixml emitted
4215/// by the abixml writer are sorted the same way as the input abixml
4216/// read by the reader.
4217///
4218/// @param l the new artificial location.
4219void
4221{priv_->artificial_location_ = l;}
4222
4223/// Getter of the artificial location of the artifact.
4224///
4225/// The artificial location is a location that was artificially
4226/// generated by libabigail, not generated by the original emitter of
4227/// the ABI meta-data. For instance, when reading an XML element from
4228/// an abixml file, the artificial location is the source location of
4229/// the XML element within the file, not the value of the
4230/// 'location'property that might be carried by the element.
4231///
4232/// Artificial locations might be useful to ensure that the abixml
4233/// emitted by the abixml writer is sorted the same way as the input
4234/// abixml read by the reader.
4235///
4236/// @return the new artificial location.
4237location&
4239{return priv_->artificial_location_;}
4240
4241/// Test if the current ABI artifact carries an artificial location.
4242///
4243/// @return true iff the current ABI artifact carries an artificial location.
4244bool
4246{
4247 return (priv_->artificial_location_
4248 && priv_->artificial_location_.get_is_artificial());
4249}
4250
4251/// Get the @ref corpus this ABI artifact belongs to.
4252///
4253/// @return the corpus this ABI artifact belongs to, or nil if it
4254/// belongs to none for now.
4255corpus*
4257{
4259 if (!tu)
4260 return 0;
4261 return tu->get_corpus();
4262}
4263
4264
4265/// Get the @ref corpus this ABI artifact belongs to.
4266///
4267/// @return the corpus this ABI artifact belongs to, or nil if it
4268/// belongs to none for now.
4269const corpus*
4271{return const_cast<type_or_decl_base*>(this)->get_corpus();}
4272
4273/// Set the @ref translation_unit this ABI artifact belongs to.
4274///
4275/// Note that adding an ABI artifact to a containining on should
4276/// invoke this member function.
4277void
4279{priv_->translation_unit_ = tu;}
4280
4281
4282/// Get the @ref translation_unit this ABI artifact belongs to.
4283///
4284/// @return the translation unit this ABI artifact belongs to, or nil
4285/// if belongs to none for now.
4288{return priv_->translation_unit_;}
4289
4290/// Get the @ref translation_unit this ABI artifact belongs to.
4291///
4292/// @return the translation unit this ABI artifact belongs to, or nil
4293/// if belongs to none for now.
4294const translation_unit*
4297
4298/// Traverse the the ABI artifact.
4299///
4300/// @param v the visitor used to traverse the sub-tree nodes of the
4301/// artifact.
4302bool
4305
4306/// Non-member equality operator for the @type_or_decl_base type.
4307///
4308/// @param lr the left-hand operand of the equality.
4309///
4310/// @param rr the right-hand operatnr of the equality.
4311///
4312/// @return true iff @p lr equals @p rr.
4313bool
4315{
4316 const type_or_decl_base* l = &lr;
4317 const type_or_decl_base* r = &rr;
4318
4319 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4320 *dr = dynamic_cast<const decl_base*>(r);
4321
4322 if (!!dl != !!dr)
4323 return false;
4324
4325 if (dl && dr)
4326 return *dl == *dr;
4327
4328 const type_base* tl = dynamic_cast<const type_base*>(l),
4329 *tr = dynamic_cast<const type_base*>(r);
4330
4331 if (!!tl != !!tr)
4332 return false;
4333
4334 if (tl && tr)
4335 return *tl == *tr;
4336
4337 return false;
4338}
4339
4340/// Non-member equality operator for the @type_or_decl_base type.
4341///
4342/// @param l the left-hand operand of the equality.
4343///
4344/// @param r the right-hand operatnr of the equality.
4345///
4346/// @return true iff @p l equals @p r.
4347bool
4349{
4350 if (!! l != !!r)
4351 return false;
4352
4353 if (!l)
4354 return true;
4355
4356 return *r == *l;
4357}
4358
4359/// Non-member inequality operator for the @type_or_decl_base type.
4360///
4361/// @param l the left-hand operand of the equality.
4362///
4363/// @param r the right-hand operator of the equality.
4364///
4365/// @return true iff @p l is different from @p r.
4366bool
4369
4370// </type_or_decl_base stuff>
4371
4372// <Decl definition>
4373
4374struct decl_base::priv
4375{
4376 bool in_pub_sym_tab_;
4377 bool is_anonymous_;
4378 location location_;
4379 context_rel *context_;
4380 interned_string name_;
4381 interned_string qualified_parent_name_;
4382 // This temporary qualified name is the cache used for the qualified
4383 // name before the type associated to this decl (if applicable) is
4384 // canonicalized. Once the type is canonicalized, the cached use is
4385 // the data member qualified_parent_name_ above.
4386 interned_string temporary_qualified_name_;
4387 // This is the fully qualified name of the decl. It contains the
4388 // name of the decl and the qualified name of its scope. So if in
4389 // the parent scopes of the decl, there is one anonymous struct,
4390 // somewhere in the name, there is going to by an
4391 // __anonymous_struct__ string, even if the anonymous struct is not
4392 // the direct containing scope of this decl.
4393 interned_string qualified_name_;
4394 interned_string temporary_internal_qualified_name_;
4395 interned_string internal_qualified_name_;
4396 interned_string internal_cached_repr_;
4397 interned_string cached_repr_;
4398 // Unline qualified_name_, scoped_name_ contains the name of the
4399 // decl and the name of its scope; not the qualified name of the
4400 // scope.
4401 interned_string scoped_name_;
4402 interned_string linkage_name_;
4403 visibility visibility_;
4404 decl_base_sptr declaration_;
4405 decl_base_wptr definition_of_declaration_;
4406 decl_base* naked_definition_of_declaration_;
4407 bool is_declaration_only_;
4408 typedef_decl_sptr naming_typedef_;
4409
4410 priv()
4411 : in_pub_sym_tab_(false),
4412 is_anonymous_(true),
4413 context_(),
4414 visibility_(VISIBILITY_DEFAULT),
4415 naked_definition_of_declaration_(),
4416 is_declaration_only_(false)
4417 {}
4418
4419 priv(interned_string name, interned_string linkage_name, visibility vis)
4420 : in_pub_sym_tab_(false),
4421 context_(),
4422 name_(name),
4423 qualified_name_(name),
4424 linkage_name_(linkage_name),
4425 visibility_(vis),
4426 naked_definition_of_declaration_(),
4427 is_declaration_only_(false)
4428 {
4429 is_anonymous_ = name_.empty();
4430 }
4431
4432 ~priv()
4433 {
4434 delete context_;
4435 }
4436};// end struct decl_base::priv
4437
4438/// Constructor for the @ref decl_base type.
4439///
4440/// @param e the environment the current @ref decl_base is being
4441/// created in.
4442///
4443/// @param name the name of the declaration.
4444///
4445/// @param locus the location where to find the declaration in the
4446/// source code.
4447///
4448/// @param linkage_name the linkage name of the declaration.
4449///
4450/// @param vis the visibility of the declaration.
4451decl_base::decl_base(const environment& e,
4452 const string& name,
4453 const location& locus,
4454 const string& linkage_name,
4455 visibility vis)
4456 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4457 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4458{
4459 set_location(locus);
4460}
4461
4462/// Constructor.
4463///
4464/// @param e the environment this instance of @ref decl_base is
4465/// created in.
4466///
4467/// @param name the name of the declaration being constructed.
4468///
4469/// @param locus the source location of the declaration being constructed.
4470///
4471/// @param linkage_name the linkage name of the declaration being
4472/// constructed.
4473///
4474/// @param vis the visibility of the declaration being constructed.
4475decl_base::decl_base(const environment& e,
4476 const interned_string& name,
4477 const location& locus,
4478 const interned_string& linkage_name,
4479 visibility vis)
4480 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4481 priv_(new priv(name, linkage_name, vis))
4482{
4483 set_location(locus);
4484}
4485
4486/// Constructor for the @ref decl_base type.
4487///
4488///@param environment the environment this instance of @ref decl_base
4489/// is being constructed in.
4490///
4491/// @param l the location where to find the declaration in the source
4492/// code.
4493decl_base::decl_base(const environment& e, const location& l)
4494 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4495 priv_(new priv())
4496{
4497 set_location(l);
4498}
4499
4500/// Getter for the qualified name.
4501///
4502/// Unlike decl_base::get_qualified_name() this doesn't try to update
4503/// the qualified name.
4504///
4505/// @return the qualified name.
4506const interned_string&
4508{return priv_->qualified_name_;}
4509
4510/// Clear the qualified name of this decl.
4511///
4512/// This is useful to ensure that the cache for the qualified name of
4513/// the decl is refreshed right after type canonicalization, for
4514/// instance.
4515void
4517{priv_->qualified_name_.clear();}
4518
4519/// Setter for the qualified name.
4520///
4521/// @param n the new qualified name.
4522void
4524{priv_->qualified_name_ = n;}
4525
4526/// Getter of the temporary qualified name of the current declaration.
4527///
4528/// This temporary qualified name is used as a qualified name cache by
4529/// the type for which this is the declaration (when applicable)
4530/// before the type is canonicalized. Once the type is canonicalized,
4531/// it's the result of decl_base::peek_qualified_name() that becomes
4532/// the qualified name cached.
4533///
4534/// @return the temporary qualified name.
4535const interned_string&
4537{return priv_->temporary_qualified_name_;}
4538
4539/// Setter for the temporary qualified name of the current
4540/// declaration.
4541///
4542///@param n the new temporary qualified name.
4543///
4544/// This temporary qualified name is used as a qualified name cache by
4545/// the type for which this is the declaration (when applicable)
4546/// before the type is canonicalized. Once the type is canonicalized,
4547/// it's the result of decl_base::peek_qualified_name() that becomes
4548/// the qualified name cached.
4549void
4551{priv_->temporary_qualified_name_ = n;}
4552
4553///Getter for the context relationship.
4554///
4555///@return the context relationship for the current decl_base.
4556const context_rel*
4558{return priv_->context_;}
4559
4560///Getter for the context relationship.
4561///
4562///@return the context relationship for the current decl_base.
4565{return priv_->context_;}
4566
4567void
4568decl_base::set_context_rel(context_rel *c)
4569{priv_->context_ = c;}
4570
4571/// Test if the decl is defined in a ELF symbol table as a public
4572/// symbol.
4573///
4574/// @return true iff the decl is defined in a ELF symbol table as a
4575/// public symbol.
4576bool
4578{return priv_->in_pub_sym_tab_;}
4579
4580/// Set the flag saying if this decl is from a symbol that is in
4581/// a public symbols table, defined as public (global or weak).
4582///
4583/// @param f the new flag value.
4584void
4586{priv_->in_pub_sym_tab_ = f;}
4587
4588/// Get the location of a given declaration.
4589///
4590/// The location is an abstraction for the tripplet {file path,
4591/// line, column} that defines where the declaration appeared in the
4592/// source code.
4593///
4594/// To get the value of the tripplet {file path, line, column} from
4595/// the @ref location, you need to use the
4596/// location_manager::expand_location() method.
4597///
4598/// The instance of @ref location_manager that you want is
4599/// accessible from the instance of @ref translation_unit that the
4600/// current instance of @ref decl_base belongs to, via a call to
4601/// translation_unit::get_loc_mgr().
4602///
4603/// @return the location of the current instance of @ref decl_base.
4604const location&
4606{return priv_->location_;}
4607
4608/// Set the location for a given declaration.
4609///
4610/// The location is an abstraction for the tripplet {file path,
4611/// line, column} that defines where the declaration appeared in the
4612/// source code.
4613///
4614/// To create a location from a tripplet {file path, line, column},
4615/// you need to use the method @ref
4616/// location_manager::create_new_location().
4617///
4618/// Note that there can be two kinds of location. An artificial
4619/// location and a non-artificial one. The non-artificial location is
4620/// the one emitted by the original emitter of the ABI artifact, for
4621/// instance, if the ABI artifact comes from debug info, then the
4622/// source location that is present in the debug info represent a
4623/// non-artificial location. When looking at an abixml file on the
4624/// other hand, the value of the 'location' attribute of an XML
4625/// element describing an artifact is the non-artificial location.
4626/// The artificial location is the location (line number from the
4627/// beginning of the file) of the XML element within the abixml file.
4628///
4629/// So, if the location that is being set is artificial, note that the
4630/// type_or_decl_base::has_artificial_location() method of this decl will
4631/// subsequently return true and that artificial location will have to
4632/// be retrieved using type_or_decl_base::get_artificial_location().
4633/// If the location is non-artificial however,
4634/// type_or_decl_base::has_artificial_location() will subsequently
4635/// return false and the non-artificial location will have to be
4636/// retrieved using decl_base::get_location().
4637///
4638/// The instance of @ref location_manager that you want is
4639/// accessible from the instance of @ref translation_unit that the
4640/// current instance of @ref decl_base belongs to, via a call to
4641/// translation_unit::get_loc_mgr().
4642void
4644{
4645 if (l.get_is_artificial())
4647 else
4648 priv_->location_ = l;
4649}
4650
4651/// Setter for the name of the decl.
4652///
4653/// @param n the new name to set.
4654void
4655decl_base::set_name(const string& n)
4656{
4657 priv_->name_ = get_environment().intern(n);
4658 priv_->is_anonymous_ = n.empty();
4659}
4660
4661/// Test if the current declaration is anonymous.
4662///
4663/// Being anonymous means that the declaration was created without a
4664/// name. This can usually happen for enum or struct types.
4665///
4666/// @return true iff the type is anonymous.
4667bool
4669{return priv_->is_anonymous_;}
4670
4671/// Set the "is_anonymous" flag of the current declaration.
4672///
4673/// Being anonymous means that the declaration was created without a
4674/// name. This can usually happen for enum or struct types.
4675///
4676/// @param f the new value of the flag.
4677void
4679{priv_->is_anonymous_ = f;}
4680
4681
4682/// Get the "has_anonymous_parent" flag of the current declaration.
4683///
4684/// Having an anoymous parent means having a anonymous parent scope
4685/// (containing type or namespace) which is either direct or indirect.
4686///
4687/// @return true iff the current decl has a direct or indirect scope
4688/// which is anonymous.
4689bool
4691{
4692 scope_decl *scope = get_scope();
4693 if (!scope)
4694 return false;
4695 return scope->get_is_anonymous();
4696}
4697
4698/// @return the logical "OR" of decl_base::get_is_anonymous() and
4699/// decl_base::get_has_anonymous_parent().
4700bool
4703
4704/// Getter for the naming typedef of the current decl.
4705///
4706/// Consider the C idiom:
4707///
4708/// typedef struct {int member;} foo_type;
4709///
4710/// In that idiom, foo_type is the naming typedef of the anonymous
4711/// struct that is declared.
4712///
4713/// @return the naming typedef, if any. Otherwise, returns nil.
4716{return priv_->naming_typedef_;}
4717
4718/// Set the naming typedef of the current instance of @ref decl_base.
4719///
4720/// Consider the C idiom:
4721///
4722/// typedef struct {int member;} foo_type;
4723///
4724/// In that idiom, foo_type is the naming typedef of the anonymous
4725/// struct that is declared.
4726///
4727/// After completion of this function, the decl will not be considered
4728/// anonymous anymore. It's name is going to be the name of the
4729/// naming typedef.
4730///
4731/// @param typedef_type the new naming typedef.
4732void
4734{
4735 // A naming typedef is usually for an anonymous type.
4737 // Whe the typedef-named decl is saved into abixml, it's
4738 // not anonymous anymore. Its name is the typedef name.
4739 // So when we read it back, we must still be able to
4740 // apply the naming typedef to the decl.
4741 || t->get_name() == get_name());
4742 // Only non canonicalized types can be edited this way.
4743 ABG_ASSERT(is_type(this)
4744 && is_type(this)->get_naked_canonical_type() == nullptr);
4745
4746 priv_->naming_typedef_ = t;
4747 set_name(t->get_name());
4748 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4749 set_qualified_name(get_environment().intern(qualified_name));
4750 set_is_anonymous(false);
4751 // Now that the qualified type of the decl has changed, let's update
4752 // the qualified names of the member types of this decls.
4753 update_qualified_name(this);
4754}
4755
4756/// Getter for the mangled name.
4757///
4758/// @return the new mangled name.
4759const interned_string&
4761{return priv_->linkage_name_;}
4762
4763/// Setter for the linkage name.
4764///
4765/// @param m the new linkage name.
4766void
4768{
4769 const environment& env = get_environment();
4770 priv_->linkage_name_ = env.intern(m);
4771}
4772
4773/// Getter for the visibility of the decl.
4774///
4775/// @return the new visibility.
4778{return priv_->visibility_;}
4779
4780/// Setter for the visibility of the decl.
4781///
4782/// @param v the new visibility.
4783void
4785{priv_->visibility_ = v;}
4786
4787/// Return the type containing the current decl, if any.
4788///
4789/// @return the type that contains the current decl, or NULL if there
4790/// is none.
4793{
4794 if (priv_->context_)
4795 return priv_->context_->get_scope();
4796 return 0;
4797}
4798
4799/// Return a copy of the qualified name of the parent of the current
4800/// decl.
4801///
4802/// @return the newly-built qualified name of the of the current decl.
4803const interned_string&
4805{return priv_->qualified_parent_name_;}
4806
4807/// Getter for the name of the current decl.
4808///
4809/// @return the name of the current decl.
4810const interned_string&
4812{return priv_->name_;}
4813
4814/// Compute the qualified name of the decl.
4815///
4816/// @param qn the resulting qualified name.
4817///
4818/// @param internal set to true if the call is intended for an
4819/// internal use (for technical use inside the library itself), false
4820/// otherwise. If you don't know what this is for, then set it to
4821/// false.
4822void
4824{qn = get_qualified_name(internal);}
4825
4826/// Get the pretty representatin of the current declaration.
4827///
4828///
4829/// @param internal set to true if the call is intended to get a
4830/// representation of the decl (or type) for the purpose of canonical
4831/// type comparison. This is mainly used in the function
4832/// type_base::get_canonical_type_for().
4833///
4834/// In other words if the argument for this parameter is true then the
4835/// call is meant for internal use (for technical use inside the
4836/// library itself), false otherwise. If you don't know what this is
4837/// for, then set it to false.
4838///
4839/// @param qualified_name if true, names emitted in the pretty
4840/// representation are fully qualified.
4841///
4842/// @return the default pretty representation for a decl. This is
4843/// basically the fully qualified name of the decl optionally prefixed
4844/// with a meaningful string to add context for the user.
4845string
4847 bool qualified_name) const
4848{
4849 if (internal
4850 && get_is_anonymous()
4851 && has_generic_anonymous_internal_type_name(this))
4852 {
4853 // We are looking at an anonymous enum, union or class and we
4854 // want an *internal* pretty representation for it. All
4855 // anonymous types of this kind in the same namespace must have
4856 // the same internal representation for type canonicalization to
4857 // work properly.
4858 //
4859 // OK, in practise, we are certainly looking at an enum because
4860 // classes and unions should have their own overloaded virtual
4861 // member function for this.
4862 string name = get_generic_anonymous_internal_type_name(this);
4863 if (qualified_name && !get_qualified_parent_name().empty())
4864 name = get_qualified_parent_name() + "::" + name;
4865 return name;
4866 }
4867
4868 if (qualified_name)
4869 return get_qualified_name(internal);
4870 return get_name();
4871}
4872
4873/// Get the pretty representation of the current decl.
4874///
4875/// The pretty representation is retrieved from a cache. If the cache
4876/// is empty, this function computes the pretty representation, put it
4877/// in the cache and returns it.
4878///
4879/// Please note that if this function is called too early in the life
4880/// cycle of the decl (before it is fully constructed), then the
4881/// pretty representation that is cached is going to represent a
4882/// non-complete (and thus wrong) representation of the decl. Thus
4883/// this function must be called only once the decl is fully
4884/// constructed.
4885///
4886/// @param internal if true, then the pretty representation is to be
4887/// used for purpuses that are internal to the libabigail library
4888/// itself. If you don't know what this means, then you probably
4889/// should set this parameter to "false".
4890///
4891/// @return a reference to a cached @ref interned_string holding the
4892/// pretty representation of the current decl.
4893const interned_string&
4895{
4896 if (internal)
4897 {
4898 if (priv_->internal_cached_repr_.empty())
4899 {
4900 string r = ir::get_pretty_representation(this, internal);
4901 priv_->internal_cached_repr_ = get_environment().intern(r);
4902 }
4903 return priv_->internal_cached_repr_;
4904 }
4905
4906 if (priv_->cached_repr_.empty())
4907 {
4908 string r = ir::get_pretty_representation(this, internal);
4909 priv_->cached_repr_ = get_environment().intern(r);
4910 }
4911
4912 return priv_->cached_repr_;
4913}
4914
4915/// Return the qualified name of the decl.
4916///
4917/// This is the fully qualified name of the decl. It's made of the
4918/// concatenation of the name of the decl with the qualified name of
4919/// its scope.
4920///
4921/// Note that the value returned by this function is computed by @ref
4922/// update_qualified_name when the decl is added to its scope.
4923///
4924/// @param internal set to true if the call is intended for an
4925/// internal use (for technical use inside the library itself), false
4926/// otherwise. If you don't know what this is for, then set it to
4927/// false.
4928///
4929/// @return the resulting qualified name.
4930const interned_string&
4931decl_base::get_qualified_name(bool /*internal*/) const
4932{return priv_->qualified_name_;}
4933
4934/// Return the scoped name of the decl.
4935///
4936/// This is made of the concatenation of the name of the decl with the
4937/// name of its scope. It doesn't contain the qualified name of its
4938/// scope, unlike what is returned by decl_base::get_qualified_name.
4939///
4940/// Note that the value returned by this function is computed by @ref
4941/// update_qualified_name when the decl is added to its scope.
4942///
4943/// @return the scoped name of the decl.
4944const interned_string&
4946{return priv_->scoped_name_;}
4947
4948/// If this @ref decl_base is a definition, get its earlier
4949/// declaration.
4950///
4951/// @return the earlier declaration of the class, if any.
4952const decl_base_sptr
4954{return priv_->declaration_;}
4955
4956/// set the earlier declaration of this @ref decl_base definition.
4957///
4958/// @param d the earlier declaration to set. Note that it's set only
4959/// if it's a pure declaration.
4960void
4962{
4963 if (d && d->get_is_declaration_only())
4964 priv_->declaration_ = d;
4965}
4966
4967
4968/// If this @ref decl_base is declaration-only, get its definition, if
4969/// any.
4970///
4971/// @return the definition of this decl-only @ref decl_base.
4972const decl_base_sptr
4974{return priv_->definition_of_declaration_.lock();}
4975
4976/// If this @ref decl_base is declaration-only, get its definition,
4977/// if any.
4978///
4979/// Note that this function doesn't return a smart pointer, but rather
4980/// the underlying pointer managed by the smart pointer. So it's as
4981/// fast as possible. This getter is to be used in code paths that
4982/// are proven to be performance hot spots; especially, when comparing
4983/// sensitive types like enums, classes or unions. Those are compared
4984/// extremely frequently and thus, their access to the definition of
4985/// declaration must be fast.
4986///
4987/// @return the definition of the declaration.
4988const decl_base*
4990{return priv_->naked_definition_of_declaration_;}
4991
4992/// Test if a @ref decl_base is a declaration-only decl.
4993///
4994/// @return true iff the current @ref decl_base is declaration-only.
4995bool
4997{return priv_->is_declaration_only_;}
4998
4999/// Set a flag saying if the @ref enum_type_decl is a declaration-only
5000/// @ref enum_type_decl.
5001///
5002/// @param f true if the @ref enum_type_decl is a declaration-only
5003/// @ref enum_type_decl.
5004void
5006{
5007 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
5008
5009 priv_->is_declaration_only_ = f;
5010
5011 if (update_types_lookup_map)
5012 if (scope_decl* s = get_scope())
5013 {
5014 scope_decl::declarations::iterator i;
5015 if (s->find_iterator_for_member(this, i))
5017 else
5019 }
5020}
5021
5024{
5025 return static_cast<change_kind>(static_cast<unsigned>(l)
5026 | static_cast<unsigned>(r));
5027}
5028
5031{
5032 return static_cast<change_kind>(static_cast<unsigned>(l)
5033 & static_cast<unsigned>(r));
5034}
5035
5038{
5039 l = l | r;
5040 return l;
5041}
5042
5045{
5046 l = l & r;
5047 return l;
5048}
5049
5050/// Compare the properties that belong to the "is-a-member-relation"
5051/// of a decl.
5052///
5053/// For instance, access specifiers are part of the
5054/// "is-a-member-relation" of a decl.
5055///
5056/// This comparison however doesn't take decl names into account. So
5057/// typedefs for instance are decls that we want to compare with this
5058/// function.
5059///
5060/// This function is a sub-routine of the more general 'equals'
5061/// overload for instances of decl_base.
5062///
5063/// @param l the left-hand side operand of the comparison.
5064///
5065/// @param r the right-hand side operand of the comparison.
5066///
5067/// @return true iff @p l compare equals, as a member decl, to @p r.
5068bool
5070 const decl_base& r,
5071 change_kind* k)
5072{
5073 bool result = true;
5074 if (is_member_decl(l) && is_member_decl(r))
5075 {
5076 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
5077 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
5078
5079 access_specifier la = no_access, ra = no_access;
5080 bool member_types_or_functions =
5081 ((is_type(l) && is_type(r))
5082 || (is_function_decl(l) && is_function_decl(r)));
5083
5084 if (member_types_or_functions)
5085 {
5086 // Access specifiers on member types in DWARF is not
5087 // reliable; in the same DSO, the same struct can be either
5088 // a class or a struct, and the access specifiers of its
5089 // member types are not necessarily given, so they
5090 // effectively can be considered differently, again, in the
5091 // same DSO. So, here, let's avoid considering those!
5092 // during comparison.
5093 la = r1->get_access_specifier();
5094 ra = r2->get_access_specifier();
5095 r1->set_access_specifier(no_access);
5096 r2->set_access_specifier(no_access);
5097 }
5098
5099 bool rels_are_different = *r1 != *r2;
5100
5101 if (member_types_or_functions)
5102 {
5103 // restore the access specifiers.
5104 r1->set_access_specifier(la);
5105 r2->set_access_specifier(ra);
5106 }
5107
5108 if (rels_are_different)
5109 {
5110 result = false;
5111 if (k)
5113 }
5114 }
5115 ABG_RETURN(result);
5116}
5117
5118/// Compares two instances of @ref decl_base.
5119///
5120/// If the two intances are different, set a bitfield to give some
5121/// insight about the kind of differences there are.
5122///
5123/// @param l the first artifact of the comparison.
5124///
5125/// @param r the second artifact of the comparison.
5126///
5127/// @param k a pointer to a bitfield that gives information about the
5128/// kind of changes there are between @p l and @p r. This one is set
5129/// iff it's non-null and if the function returns false.
5130///
5131/// Please note that setting k to a non-null value does have a
5132/// negative performance impact because even if @p l and @p r are not
5133/// equal, the function keeps up the comparison in order to determine
5134/// the different kinds of ways in which they are different.
5135///
5136/// @return true if @p l equals @p r, false otherwise.
5137bool
5138equals(const decl_base& l, const decl_base& r, change_kind* k)
5139{
5140 bool result = true;
5141 const interned_string &l_linkage_name = l.get_linkage_name();
5142 const interned_string &r_linkage_name = r.get_linkage_name();
5143 if (!l_linkage_name.empty() && !r_linkage_name.empty())
5144 {
5145 if (l_linkage_name != r_linkage_name)
5146 {
5147 // Linkage names are different. That usually means the two
5148 // decls are different, unless we are looking at two
5149 // function declarations which have two different symbols
5150 // that are aliases of each other.
5151 const function_decl *f1 = is_function_decl(&l),
5152 *f2 = is_function_decl(&r);
5153 if (f1 && f2 && function_decls_alias(*f1, *f2))
5154 ;// The two functions are aliases, so they are not
5155 // different.
5156 else
5157 {
5158 result = false;
5159 if (k)
5161 else
5163 }
5164 }
5165 }
5166
5167 if (r.get_is_anonymous() && l.get_is_anonymous())
5168 // We are looking at too anonymous types (or two members of
5169 // anonymous types) with one not yet been added to the IR. That
5170 // means we want to compare just the object part of the
5171 // anonymous type and not their qualified names. This is used
5172 // when looking up an anonymous type inside a class type.
5173 ABG_RETURN(result);
5174
5175 // This is the name of the decls that we want to compare.
5176 interned_string ln = l.get_name(), rn = r.get_name();
5177
5178 /// If both of the current decls have an anonymous scope then let's
5179 /// compare their name component by component by properly handling
5180 /// anonymous scopes. That's the slow path.
5181 ///
5182 /// Otherwise, let's just compare their name, the obvious way.
5183 /// That's the fast path because in that case the names are
5184 /// interned_string and comparing them is much faster.
5185 bool decls_are_same = (ln == rn);
5186
5187 if (!decls_are_same)
5188 {
5189 result = false;
5190 if (k)
5192 else
5194 }
5195
5196 result &= maybe_compare_as_member_decls(l, r, k);
5197
5198 ABG_RETURN(result);
5199}
5200
5201/// Return true iff the two decls have the same name.
5202///
5203/// This function doesn't test if the scopes of the the two decls are
5204/// equal.
5205///
5206/// Note that this virtual function is to be implemented by classes
5207/// that extend the \p decl_base class.
5208bool
5210{return equals(*this, other, 0);}
5211
5212/// Inequality operator.
5213///
5214/// @param other to other instance of @ref decl_base to compare the
5215/// current instance to.
5216///
5217/// @return true iff the current instance of @ref decl_base is
5218/// different from @p other.
5219bool
5221{return !operator==(other);}
5222
5223/// Destructor of the @ref decl_base type.
5225{delete priv_;}
5226
5227/// This implements the ir_traversable_base::traverse pure virtual
5228/// function.
5229///
5230/// @param v the visitor used on the member nodes of the translation
5231/// unit during the traversal.
5232///
5233/// @return true if the entire IR node tree got traversed, false
5234/// otherwise.
5235bool
5237{
5238 // Do nothing in the base class.
5239 return true;
5240}
5241
5242/// Setter of the scope of the current decl.
5243///
5244/// Note that the decl won't hold a reference on the scope. It's
5245/// rather the scope that holds a reference on its members.
5246void
5248{
5249 if (!priv_->context_)
5250 priv_->context_ = new context_rel(scope);
5251 else
5252 priv_->context_->set_scope(scope);
5253}
5254
5255// </decl_base definition>
5256
5257/// Streaming operator for the decl_base::visibility.
5258///
5259/// @param o the output stream to serialize the visibility to.
5260///
5261/// @param v the visibility to serialize.
5262///
5263/// @return the output stream.
5264std::ostream&
5265operator<<(std::ostream& o, decl_base::visibility v)
5266{
5267 string r;
5268 switch (v)
5269 {
5270 case decl_base::VISIBILITY_NONE:
5271 r = "none";
5272 break;
5273 case decl_base::VISIBILITY_DEFAULT:
5274 r = "default";
5275 break;
5276 case decl_base::VISIBILITY_PROTECTED:
5277 r = "protected";
5278 break;
5279 case decl_base::VISIBILITY_HIDDEN:
5280 r = "hidden";
5281 break;
5282 case decl_base::VISIBILITY_INTERNAL:
5283 r = "internal";
5284 break;
5285 }
5286 return o;
5287}
5288
5289/// Streaming operator for decl_base::binding.
5290///
5291/// @param o the output stream to serialize the visibility to.
5292///
5293/// @param b the binding to serialize.
5294///
5295/// @return the output stream.
5296std::ostream&
5297operator<<(std::ostream& o, decl_base::binding b)
5298{
5299 string r;
5300 switch (b)
5301 {
5302 case decl_base::BINDING_NONE:
5303 r = "none";
5304 break;
5305 case decl_base::BINDING_LOCAL:
5306 r = "local";
5307 break;
5308 case decl_base::BINDING_GLOBAL:
5309 r = "global";
5310 break;
5311 case decl_base::BINDING_WEAK:
5312 r = "weak";
5313 break;
5314 }
5315 o << r;
5316 return o;
5317}
5318
5319/// Turn equality of shared_ptr of decl_base into a deep equality;
5320/// that is, make it compare the pointed to objects, not just the
5321/// pointers.
5322///
5323/// @param l the shared_ptr of decl_base on left-hand-side of the
5324/// equality.
5325///
5326/// @param r the shared_ptr of decl_base on right-hand-side of the
5327/// equality.
5328///
5329/// @return true if the decl_base pointed to by the shared_ptrs are
5330/// equal, false otherwise.
5331bool
5332operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5333{
5334 if (l.get() == r.get())
5335 return true;
5336 if (!!l != !!r)
5337 return false;
5338
5339 return *l == *r;
5340}
5341
5342/// Inequality operator of shared_ptr of @ref decl_base.
5343///
5344/// This is a deep equality operator, that is, it compares the
5345/// pointed-to objects, rather than just the pointers.
5346///
5347/// @param l the left-hand-side operand.
5348///
5349/// @param r the right-hand-side operand.
5350///
5351/// @return true iff @p l is different from @p r.
5352bool
5353operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5354{return !operator==(l, r);}
5355
5356/// Turn equality of shared_ptr of type_base into a deep equality;
5357/// that is, make it compare the pointed to objects too.
5358///
5359/// @param l the shared_ptr of type_base on left-hand-side of the
5360/// equality.
5361///
5362/// @param r the shared_ptr of type_base on right-hand-side of the
5363/// equality.
5364///
5365/// @return true if the type_base pointed to by the shared_ptrs are
5366/// equal, false otherwise.
5367bool
5368operator==(const type_base_sptr& l, const type_base_sptr& r)
5369{
5370 if (l.get() == r.get())
5371 return true;
5372 if (!!l != !!r)
5373 return false;
5374
5375 return *l == *r;
5376}
5377
5378/// Turn inequality of shared_ptr of type_base into a deep equality;
5379/// that is, make it compare the pointed to objects..
5380///
5381/// @param l the shared_ptr of type_base on left-hand-side of the
5382/// equality.
5383///
5384/// @param r the shared_ptr of type_base on right-hand-side of the
5385/// equality.
5386///
5387/// @return true iff the type_base pointed to by the shared_ptrs are
5388/// different.
5389bool
5390operator!=(const type_base_sptr& l, const type_base_sptr& r)
5391{return !operator==(l, r);}
5392
5393/// Tests if a declaration has got a scope.
5394///
5395/// @param d the declaration to consider.
5396///
5397/// @return true if the declaration has got a scope, false otherwise.
5398bool
5400{return (d.get_scope());}
5401
5402/// Tests if a declaration has got a scope.
5403///
5404/// @param d the declaration to consider.
5405///
5406/// @return true if the declaration has got a scope, false otherwise.
5407bool
5408has_scope(const decl_base_sptr d)
5409{return has_scope(*d.get());}
5410
5411/// Tests if a declaration is a class member.
5412///
5413/// @param d the declaration to consider.
5414///
5415/// @return true if @p d is a class member, false otherwise.
5416bool
5417is_member_decl(const decl_base_sptr d)
5418{return is_at_class_scope(d) || is_method_decl(d);}
5419
5420/// Tests if a declaration is a class member.
5421///
5422/// @param d the declaration to consider.
5423///
5424/// @return true if @p d is a class member, false otherwise.
5425bool
5428
5429/// Tests if a declaration is a class member.
5430///
5431/// @param d the declaration to consider.
5432///
5433/// @return true if @p d is a class member, false otherwise.
5434bool
5437
5438/// Test if a declaration is a @ref scope_decl.
5439///
5440/// @param d the declaration to take in account.
5441///
5442/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5443/// if d is a @ref scope_decl.
5444const scope_decl*
5446{return dynamic_cast<const scope_decl*>(d);}
5447
5448/// Test if a declaration is a @ref scope_decl.
5449///
5450/// @param d the declaration to take in account.
5451///
5452/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5453/// if d is a @ref scope_decl.
5455is_scope_decl(const decl_base_sptr& d)
5456{return dynamic_pointer_cast<scope_decl>(d);}
5457
5458/// Tests if a type is a class member.
5459///
5460/// @param t the type to consider.
5461///
5462/// @return true if @p t is a class member type, false otherwise.
5463bool
5464is_member_type(const type_base_sptr& t)
5465{
5466 decl_base_sptr d = get_type_declaration(t);
5467 return is_member_decl(d);
5468}
5469
5470/// Test if a type is user-defined.
5471///
5472/// A type is considered user-defined if it's a
5473/// struct/class/union/enum that is *NOT* artificial.
5474///
5475/// @param t the type to consider.
5476///
5477/// @return true iff the type @p t is user-defined.
5478bool
5480{
5481 if (t == 0)
5482 return false;
5483
5485 decl_base *d = is_decl(t);
5486
5488 && d && !d->get_is_artificial())
5489 return true;
5490
5491 return false;
5492}
5493
5494/// Test if a type is user-defined.
5495///
5496/// A type is considered user-defined if it's a
5497/// struct/class/union/enum.
5498///
5499///
5500/// @param t the type to consider.
5501///
5502/// @return true iff the type @p t is user-defined.
5503bool
5504is_user_defined_type(const type_base_sptr& t)
5505{return is_user_defined_type(t.get());}
5506
5507/// Gets the access specifier for a class member.
5508///
5509/// @param d the declaration of the class member to consider. Note
5510/// that this must be a class member otherwise the function aborts the
5511/// current process.
5512///
5513/// @return the access specifier for the class member @p d.
5516{
5518
5519 const context_rel* c = d.get_context_rel();
5520 ABG_ASSERT(c);
5521
5522 return c->get_access_specifier();
5523}
5524
5525/// Gets the access specifier for a class member.
5526///
5527/// @param d the declaration of the class member to consider. Note
5528/// that this must be a class member otherwise the function aborts the
5529/// current process.
5530///
5531/// @return the access specifier for the class member @p d.
5533get_member_access_specifier(const decl_base_sptr& d)
5534{return get_member_access_specifier(*d);}
5535
5536/// Sets the access specifier for a class member.
5537///
5538/// @param d the class member to set the access specifier for. Note
5539/// that this must be a class member otherwise the function aborts the
5540/// current process.
5541///
5542/// @param a the new access specifier to set the class member to.
5543void
5546{
5548
5550 ABG_ASSERT(c);
5551
5552 c->set_access_specifier(a);
5553}
5554
5555/// Sets the access specifier for a class member.
5556///
5557/// @param d the class member to set the access specifier for. Note
5558/// that this must be a class member otherwise the function aborts the
5559/// current process.
5560///
5561/// @param a the new access specifier to set the class member to.
5562void
5563set_member_access_specifier(const decl_base_sptr& d,
5566
5567/// Gets a flag saying if a class member is static or not.
5568///
5569/// @param d the declaration for the class member to consider. Note
5570/// that this must be a class member otherwise the function aborts the
5571/// current process.
5572///
5573/// @return true if the class member @p d is static, false otherwise.
5574bool
5576{
5578
5579 const context_rel* c = d.get_context_rel();
5580 ABG_ASSERT(c);
5581
5582 return c->get_is_static();
5583}
5584
5585/// Gets a flag saying if a class member is static or not.
5586///
5587/// @param d the declaration for the class member to consider. Note
5588/// that this must be a class member otherwise the function aborts the
5589/// current process.
5590///
5591/// @return true if the class member @p d is static, false otherwise.
5592bool
5595
5596/// Gets a flag saying if a class member is static or not.
5597///
5598/// @param d the declaration for the class member to consider. Note
5599/// that this must be a class member otherwise the function aborts the
5600/// current process.
5601///
5602/// @return true if the class member @p d is static, false otherwise.
5603bool
5604get_member_is_static(const decl_base_sptr& d)
5605{return get_member_is_static(*d);}
5606
5607/// Test if a var_decl is a data member.
5608///
5609/// @param v the var_decl to consider.
5610///
5611/// @return true if @p v is data member, false otherwise.
5612bool
5614{return is_at_class_scope(v);}
5615
5616/// Test if a var_decl is a data member.
5617///
5618/// @param v the var_decl to consider.
5619///
5620/// @return true if @p v is data member, false otherwise.
5621bool
5623{return is_data_member(*v);}
5624
5625/// Test if a var_decl is a data member.
5626///
5627/// @param v the var_decl to consider.
5628///
5629/// @return true if @p v is data member, false otherwise.
5630bool
5633
5634/// Test if a decl is a data member.
5635///
5636/// @param d the decl to consider.
5637///
5638/// @return a pointer to the data member iff @p d is a data member, or
5639/// a null pointer.
5641is_data_member(const decl_base_sptr& d)
5642{
5643 if (var_decl_sptr v = is_var_decl(d))
5644 {
5645 if (is_data_member(v))
5646 return v;
5647 }
5648 return var_decl_sptr();
5649}
5650
5651/// Test if a decl is a data member.
5652///
5653/// @param d the decl to consider.
5654///
5655/// @return a pointer to the data member iff @p d is a data member, or
5656/// a null pointer.
5659{
5660 if (var_decl_sptr v = is_var_decl(d))
5661 {
5662 if (is_data_member(v))
5663 return v;
5664 }
5665 return var_decl_sptr();
5666}
5667
5668/// Test if a decl is a data member.
5669///
5670/// @param d the decl to consider.
5671///
5672/// @return a pointer to the data member iff @p d is a data member, or
5673/// a null pointer.
5674var_decl*
5676{
5677 if (var_decl *v = is_var_decl(d))
5678 if (is_data_member(v))
5679 return v;
5680 return 0;
5681}
5682
5683/// Test if a decl is a data member.
5684///
5685/// @param d the decl to consider.
5686///
5687/// @return a pointer to the data member iff @p d is a data member, or
5688/// a null pointer.
5689var_decl*
5691{
5692 if (var_decl *v = is_var_decl(d))
5693 if (is_data_member(v))
5694 return v;
5695 return 0;
5696}
5697
5698/// Get the first non-anonymous data member of a given anonymous data
5699/// member.
5700///
5701/// E.g:
5702///
5703/// struct S
5704/// {
5705/// union // <-- for this anonymous data member, the function
5706/// // returns a.
5707/// {
5708/// int a;
5709/// charb;
5710/// };
5711/// };
5712///
5713/// @return anon_dm the anonymous data member to consider.
5714///
5715/// @return the first non-anonymous data member of @p anon_dm. If no
5716/// data member was found then this function returns @p anon_dm.
5717const var_decl_sptr
5719{
5720 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5721 return anon_dm;
5722
5723 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5724 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5725
5726 if (is_anonymous_data_member(first))
5728
5729 return first;
5730}
5731
5732/// In the context of a given class or union, this function returns
5733/// the data member that is located after a given data member.
5734///
5735/// @param klass the class or union to consider.
5736///
5737/// @param the data member to consider.
5738///
5739/// @return the data member that is located right after @p
5740/// data_member.
5741const var_decl_sptr
5743 const var_decl_sptr &data_member)
5744{
5745 if (!klass ||!data_member)
5746 return var_decl_sptr();
5747
5748 for (class_or_union::data_members::const_iterator it =
5749 klass->get_non_static_data_members().begin();
5750 it != klass->get_non_static_data_members().end();
5751 ++it)
5752 if (**it == *data_member)
5753 {
5754 ++it;
5755 if (it != klass->get_non_static_data_members().end())
5757 break;
5758 }
5759
5760 return var_decl_sptr();
5761}
5762
5763/// In the context of a given class or union, this function returns
5764/// the data member that is located after a given data member.
5765///
5766/// @param klass the class or union to consider.
5767///
5768/// @param the data member to consider.
5769///
5770/// @return the data member that is located right after @p
5771/// data_member.
5772const var_decl_sptr
5773get_next_data_member(const class_or_union_sptr& klass,
5774 const var_decl_sptr &data_member)
5775{return get_next_data_member(klass.get(), data_member);}
5776
5777/// Get the last data member of a class type.
5778///
5779/// @param klass the class type to consider.
5782{return klass.get_non_static_data_members().back();}
5783
5784/// Get the last data member of a class type.
5785///
5786/// @param klass the class type to consider.
5790
5791/// Get the last data member of a class type.
5792///
5793/// @param klass the class type to consider.
5795get_last_data_member(const class_or_union_sptr &klass)
5796{return get_last_data_member(klass.get());}
5797
5798/// Collect all the non-anonymous data members of a class or union type.
5799///
5800/// If the class contains any anonymous data member, this function
5801/// looks through it to collect the non-anonymous data members that it
5802/// contains. The function also looks through the base classes of the
5803/// current type.
5804///
5805/// @param cou the class or union type to consider.
5806///
5807/// @param dms output parameter. This is populated by the function
5808/// with a map containing the non-anonymous data members that were
5809/// collected. The key of the map is the name of the data member.
5810/// This is set iff the function returns true.
5811///
5812/// @return true iff at least one non-anonymous data member was
5813/// collected.
5814bool
5817{
5818 if (!cou)
5819 return false;
5820
5821 bool result = false;
5822 class_decl* klass = is_class_type(cou);
5823 if (klass)
5824 // First look into base classes for data members.
5826 result |= collect_non_anonymous_data_members(base->get_base_class().get(), dms);
5827
5828 // Then look into our data members
5829 for (var_decl_sptr member : cou->get_non_static_data_members())
5830 {
5831 if (is_anonymous_data_member(member))
5832 {
5833 class_or_union_sptr cl = anonymous_data_member_to_class_or_union(member);
5834 ABG_ASSERT(cl);
5835 result |= collect_non_anonymous_data_members(cl.get(), dms);
5836 }
5837 else
5838 {
5839 dms[member->get_name()] = member;
5840 result = true;
5841 }
5842 }
5843 return result;
5844}
5845
5846/// Collect all the non-anonymous data members of a class or union type.
5847///
5848/// If the class contains any anonymous data member, this function
5849/// looks through it to collect the non-anonymous data members that it
5850/// contains. The function also also looks through the base classes
5851/// of the current type.
5852///
5853/// @param cou the class or union type to consider.
5854///
5855/// @param dms output parameter. This is populated by the function
5856/// with a map containing the non-anonymous data members that were
5857/// collected. The key of the map is the name of the data member.
5858/// This is set iff the function returns true.
5859///
5860/// @return true iff at least one non-anonymous data member was
5861/// collected.
5862bool
5864{return collect_non_anonymous_data_members(cou.get(), dms);}
5865
5866/// Test if a decl is an anonymous data member.
5867///
5868/// @param d the decl to consider.
5869///
5870/// @return true iff @p d is an anonymous data member.
5871bool
5874
5875/// Test if a decl is an anonymous data member.
5876///
5877/// @param d the decl to consider.
5878///
5879/// @return the var_decl representing the data member iff @p d is an
5880/// anonymous data member.
5881const var_decl*
5883{
5884 if (const var_decl* v = is_data_member(d))
5885 {
5887 return v;
5888 }
5889 return 0;
5890}
5891
5892/// Test if a decl is an anonymous data member.
5893///
5894/// @param d the decl to consider.
5895///
5896/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5897/// it's an anonymous data member. Otherwise returns a nil pointer.
5898const var_decl*
5900{
5901 if (const var_decl* v = is_data_member(d))
5902 {
5904 return v;
5905 }
5906 return 0;
5907}
5908
5909/// Test if a decl is an anonymous data member.
5910///
5911/// @param d the decl to consider.
5912///
5913/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5914/// it's an anonymous data member. Otherwise returns a nil pointer.
5917{
5918 if (var_decl_sptr v = is_data_member(d))
5919 {
5921 return v;
5922 }
5923 return var_decl_sptr();
5924}
5925
5926/// Test if a decl is an anonymous data member.
5927///
5928/// @param d the decl to consider.
5929///
5930/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5931/// it's an anonymous data member. Otherwise returns a nil pointer.
5933is_anonymous_data_member(const decl_base_sptr& d)
5934{
5935 if (var_decl_sptr v = is_data_member(d))
5936 return is_anonymous_data_member(v);
5937 return var_decl_sptr();
5938}
5939
5940/// Test if a @ref var_decl is an anonymous data member.
5941///
5942/// @param d the @ref var_decl to consider.
5943///
5944/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5945/// it's an anonymous data member. Otherwise returns a nil pointer.
5948{
5949 if (is_anonymous_data_member(d.get()))
5950 return d;
5951 return var_decl_sptr();
5952}
5953
5954/// Test if a @ref var_decl is an anonymous data member.
5955///
5956/// @param d the @ref var_decl to consider.
5957///
5958/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5959/// it's an anonymous data member. Otherwise returns a nil pointer.
5960const var_decl*
5962{
5963 if (d && is_anonymous_data_member(*d))
5964 return d;
5965 return 0;
5966}
5967
5968/// Test if a @ref var_decl is an anonymous data member.
5969///
5970/// @param d the @ref var_decl to consider.
5971///
5972/// @return true iff @p d is an anonymous data member.
5973bool
5975{
5976 return (is_data_member(d)
5977 && d.get_is_anonymous()
5978 && d.get_name().empty()
5980}
5981
5982/// Test if a @ref var_decl is a data member belonging to an anonymous
5983/// type.
5984///
5985/// @param d the @ref var_decl to consider.
5986///
5987/// @return true iff @p d is a data member belonging to an anonymous
5988/// type.
5989bool
5991{
5992 if (is_data_member(d))
5993 {
5994 scope_decl* scope = d.get_scope();
5995 if (scope && scope->get_is_anonymous())
5996 return true;
5997 }
5998 return false;
5999}
6000
6001/// Test if a @ref var_decl is a data member belonging to an anonymous
6002/// type.
6003///
6004/// @param d the @ref var_decl to consider.
6005///
6006/// @return true iff @p d is a data member belonging to an anonymous
6007/// type.
6008bool
6011
6012/// Test if a @ref var_decl is a data member belonging to an anonymous
6013/// type.
6014///
6015/// @param d the @ref var_decl to consider.
6016///
6017/// @return true iff @p d is a data member belonging to an anonymous
6018/// type.
6019bool
6022
6023/// Get the @ref class_or_union type of a given anonymous data member.
6024///
6025/// @param d the anonymous data member to consider.
6026///
6027/// @return the @ref class_or_union type of the anonymous data member
6028/// @p d.
6031{
6032 if ((d = is_anonymous_data_member(d)))
6033 return is_class_or_union_type(d->get_type().get());
6034 return 0;
6035}
6036
6037/// Get the @ref class_or_union type of a given anonymous data member.
6038///
6039/// @param d the anonymous data member to consider.
6040///
6041/// @return the @ref class_or_union type of the anonymous data member
6042/// @p d.
6043class_or_union_sptr
6045{
6047 return is_class_or_union_type(d.get_type());
6048 return class_or_union_sptr();
6049}
6050
6051/// Test if a data member has annonymous type or not.
6052///
6053/// @param d the data member to consider.
6054///
6055/// @return the anonymous class or union type iff @p turns out to have
6056/// an anonymous type. Otherwise, returns nil.
6057const class_or_union_sptr
6059{
6060 if (is_data_member(d))
6061 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
6062 if (cou->get_is_anonymous())
6063 return cou;
6064
6065 return class_or_union_sptr();
6066}
6067
6068/// Test if a data member has annonymous type or not.
6069///
6070/// @param d the data member to consider.
6071///
6072/// @return the anonymous class or union type iff @p turns out to have
6073/// an anonymous type. Otherwise, returns nil.
6074const class_or_union_sptr
6076{
6077 if (d)
6079 return class_or_union_sptr();
6080}
6081
6082/// Test if a data member has annonymous type or not.
6083///
6084/// @param d the data member to consider.
6085///
6086/// @return the anonymous class or union type iff @p turns out to have
6087/// an anonymous type. Otherwise, returns nil.
6088const class_or_union_sptr
6091
6092/// Get the @ref class_or_union type of a given anonymous data member.
6093///
6094/// @param d the anonymous data member to consider.
6095///
6096/// @return the @ref class_or_union type of the anonymous data member
6097/// @p d.
6098class_or_union_sptr
6100{
6102 return is_class_or_union_type(v->get_type());
6103 return class_or_union_sptr();
6104}
6105
6106/// Test if a given anonymous data member exists in a class or union.
6107///
6108/// @param anon_dm the anonymous data member to consider.
6109///
6110/// @param clazz the class to consider.
6111///
6112/// @return true iff @p anon_dm exists in the @clazz.
6113bool
6115 const class_or_union& clazz)
6116{
6117 if (!anon_dm.get_is_anonymous()
6118 || !is_class_or_union_type(anon_dm.get_type()))
6119 return false;
6120
6121 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
6122 ABG_ASSERT(cl);
6123
6124 // Look for the presence of each data member of anon_dm in clazz.
6125 //
6126 // If one data member of anon_dm is not present in clazz, then the
6127 // data member anon_dm is considered to not exist in clazz.
6128 for (auto anon_dm_m : cl->get_non_static_data_members())
6129 {
6130 // If the data member anon_dm_m is not an anonymous data member,
6131 // it's easy to look for it.
6132 if (!is_anonymous_data_member(anon_dm_m))
6133 {
6134 if (!clazz.find_data_member(anon_dm_m->get_name()))
6135 return false;
6136 }
6137 // If anon_dm_m is itself an anonymous data member then recurse
6138 else
6139 {
6140 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
6141 return false;
6142 }
6143 }
6144
6145 return true;
6146}
6147
6148/// Test if a given decl is anonymous or has a naming typedef.
6149///
6150/// @param d the decl to consider.
6151///
6152/// @return true iff @p d is anonymous or has a naming typedef.
6153bool
6155{
6156 if (d.get_is_anonymous() || d.get_naming_typedef())
6157 return true;
6158 return false;
6159}
6160
6161/// Set the offset of a data member into its containing class.
6162///
6163/// @param m the data member to consider.
6164///
6165/// @param o the offset, in bits.
6166void
6168{
6170
6171 dm_context_rel* ctxt_rel =
6172 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6173 ABG_ASSERT(ctxt_rel);
6174
6175 ctxt_rel->set_offset_in_bits(o);
6176}
6177
6178/// Get the offset of a data member.
6179///
6180/// @param m the data member to consider.
6181///
6182/// @return the offset (in bits) of @p m in its containing class.
6183uint64_t
6185{
6187 const dm_context_rel* ctxt_rel =
6188 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6189 ABG_ASSERT(ctxt_rel);
6190 return ctxt_rel->get_offset_in_bits();
6191}
6192
6193/// Get the offset of a data member.
6194///
6195/// @param m the data member to consider.
6196///
6197/// @return the offset (in bits) of @p m in its containing class.
6198uint64_t
6201
6202/// Get the offset of a data member.
6203///
6204/// @param m the data member to consider.
6205///
6206/// @return the offset (in bits) of @p m in its containing class.
6207uint64_t
6208get_data_member_offset(const decl_base_sptr d)
6209{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6210
6211/// Get the offset of the non-static data member that comes after a
6212/// given one.
6213///
6214/// If there is no data member after after the one given to this
6215/// function (maybe because the given one is the last data member of
6216/// the class type) then the function return false.
6217///
6218/// @param klass the class to consider.
6219///
6220/// @param dm the data member before the one we want to retrieve.
6221///
6222/// @param offset out parameter. This parameter is set by the
6223/// function to the offset of the data member that comes right after
6224/// the data member @p dm, iff the function returns true.
6225///
6226/// @return true iff the data member coming right after @p dm was
6227/// found.
6228bool
6230 const var_decl_sptr& dm,
6231 uint64_t& offset)
6232{
6233 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6234 if (!next_dm)
6235 return false;
6236 offset = get_data_member_offset(next_dm);
6237 return true;
6238}
6239
6240/// Get the offset of the non-static data member that comes after a
6241/// given one.
6242///
6243/// If there is no data member after after the one given to this
6244/// function (maybe because the given one is the last data member of
6245/// the class type) then the function return false.
6246///
6247/// @param klass the class to consider.
6248///
6249/// @param dm the data member before the one we want to retrieve.
6250///
6251/// @param offset out parameter. This parameter is set by the
6252/// function to the offset of the data member that comes right after
6253/// the data member @p dm, iff the function returns true.
6254///
6255/// @return true iff the data member coming right after @p dm was
6256/// found.
6257bool
6258get_next_data_member_offset(const class_or_union_sptr& klass,
6259 const var_decl_sptr& dm,
6260 uint64_t& offset)
6261{return get_next_data_member_offset(klass.get(), dm, offset);}
6262
6263/// Get the absolute offset of a data member.
6264///
6265/// If the data member is part of an anonymous data member then this
6266/// returns the absolute offset -- relative to the beginning of the
6267/// containing class of the anonymous data member.
6268///
6269/// @param m the data member to consider.
6270///
6271/// @return the aboslute offset of the data member @p m.
6272uint64_t
6274{
6276 const dm_context_rel* ctxt_rel =
6277 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6278 ABG_ASSERT(ctxt_rel);
6279
6280 const var_decl *containing_anonymous_data_member =
6281 ctxt_rel->get_anonymous_data_member();
6282
6283 uint64_t containing_anonymous_data_member_offset = 0;
6284 if (containing_anonymous_data_member)
6285 containing_anonymous_data_member_offset =
6286 get_absolute_data_member_offset(*containing_anonymous_data_member);
6287
6288 return (ctxt_rel->get_offset_in_bits()
6289 +
6290 containing_anonymous_data_member_offset);
6291}
6292
6293/// Get the absolute offset of a data member.
6294///
6295/// If the data member is part of an anonymous data member then this
6296/// returns the absolute offset -- relative to the beginning of the
6297/// containing class of the anonymous data member.
6298///
6299/// @param m the data member to consider.
6300///
6301/// @return the aboslute offset of the data member @p m.
6302uint64_t
6304{
6305 if (!m)
6306 return 0;
6308}
6309
6310/// Get the size of a given variable.
6311///
6312/// @param v the variable to consider.
6313///
6314/// @return the size of variable @p v.
6315uint64_t
6317{
6318 type_base_sptr t = v->get_type();
6319 ABG_ASSERT(t);
6320
6321 return t->get_size_in_bits();
6322}
6323
6324/// Set a flag saying if a data member is laid out.
6325///
6326/// @param m the data member to consider.
6327///
6328/// @param l true if @p m is to be considered as laid out.
6329void
6331{
6333 dm_context_rel* ctxt_rel =
6334 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6335 ctxt_rel->set_is_laid_out(l);
6336}
6337
6338/// Test whether a data member is laid out.
6339///
6340/// @param m the data member to consider.
6341///
6342/// @return true if @p m is laid out, false otherwise.
6343bool
6345{
6347 const dm_context_rel* ctxt_rel =
6348 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6349
6350 return ctxt_rel->get_is_laid_out();
6351}
6352
6353/// Test whether a data member is laid out.
6354///
6355/// @param m the data member to consider.
6356///
6357/// @return true if @p m is laid out, false otherwise.
6358bool
6361
6362/// Test whether a function_decl is a member function.
6363///
6364/// @param f the function_decl to test.
6365///
6366/// @return true if @p f is a member function, false otherwise.
6367bool
6370
6371/// Test whether a function_decl is a member function.
6372///
6373/// @param f the function_decl to test.
6374///
6375/// @return true if @p f is a member function, false otherwise.
6376bool
6379
6380/// Test whether a function_decl is a member function.
6381///
6382/// @param f the function_decl to test.
6383///
6384/// @return true if @p f is a member function, false otherwise.
6385bool
6388
6389/// Test whether a member function is a constructor.
6390///
6391/// @param f the member function to test.
6392///
6393/// @return true if @p f is a constructor, false otherwise.
6394bool
6396{
6398
6399 const method_decl* m = is_method_decl(&f);
6400 ABG_ASSERT(m);
6401
6402 const mem_fn_context_rel* ctxt =
6403 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6404
6405 return ctxt->is_constructor();
6406}
6407
6408/// Test whether a member function is a constructor.
6409///
6410/// @param f the member function to test.
6411///
6412/// @return true if @p f is a constructor, false otherwise.
6413bool
6416
6417
6418/// Setter for the is_ctor property of the member function.
6419///
6420/// @param f the member function to set.
6421///
6422/// @param f the new boolean value of the is_ctor property. Is true
6423/// if @p f is a constructor, false otherwise.
6424void
6426{
6428
6429 method_decl* m = is_method_decl(&f);
6430 ABG_ASSERT(m);
6431
6432 mem_fn_context_rel* ctxt =
6433 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6434
6435 ctxt->is_constructor(c);
6436}
6437
6438/// Setter for the is_ctor property of the member function.
6439///
6440/// @param f the member function to set.
6441///
6442/// @param f the new boolean value of the is_ctor property. Is true
6443/// if @p f is a constructor, false otherwise.
6444void
6447
6448/// Test whether a member function is a destructor.
6449///
6450/// @param f the function to test.
6451///
6452/// @return true if @p f is a destructor, false otherwise.
6453bool
6455{
6457
6458 const method_decl* m = is_method_decl(&f);
6459 ABG_ASSERT(m);
6460
6461 const mem_fn_context_rel* ctxt =
6462 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6463
6464 return ctxt->is_destructor();
6465}
6466
6467/// Test whether a member function is a destructor.
6468///
6469/// @param f the function to test.
6470///
6471/// @return true if @p f is a destructor, false otherwise.
6472bool
6475
6476/// Set the destructor-ness property of a member function.
6477///
6478/// @param f the function to set.
6479///
6480/// @param d true if @p f is a destructor, false otherwise.
6481void
6483{
6485
6486 method_decl* m = is_method_decl(&f);
6487 ABG_ASSERT(m);
6488
6489 mem_fn_context_rel* ctxt =
6490 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6491
6492 ctxt->is_destructor(d);
6493}
6494
6495/// Set the destructor-ness property of a member function.
6496///
6497/// @param f the function to set.
6498///
6499/// @param d true if @p f is a destructor, false otherwise.
6500void
6503
6504/// Test whether a member function is const.
6505///
6506/// @param f the function to test.
6507///
6508/// @return true if @p f is const, false otherwise.
6509bool
6511{
6513
6514 const method_decl* m = is_method_decl(&f);
6515 ABG_ASSERT(m);
6516
6517 const mem_fn_context_rel* ctxt =
6518 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6519
6520 return ctxt->is_const();
6521}
6522
6523/// Test whether a member function is const.
6524///
6525/// @param f the function to test.
6526///
6527/// @return true if @p f is const, false otherwise.
6528bool
6531
6532/// set the const-ness property of a member function.
6533///
6534/// @param f the function to set.
6535///
6536/// @param is_const the new value of the const-ness property of @p f
6537void
6539{
6541
6542 method_decl* m = is_method_decl(&f);
6543 ABG_ASSERT(m);
6544
6545 mem_fn_context_rel* ctxt =
6546 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6547
6548 ctxt->is_const(is_const);
6549}
6550
6551/// set the const-ness property of a member function.
6552///
6553/// @param f the function to set.
6554///
6555/// @param is_const the new value of the const-ness property of @p f
6556void
6559
6560/// Test if a virtual member function has a vtable offset set.
6561///
6562/// @param f the virtual member function to consider.
6563///
6564/// @return true iff the virtual member function has its vtable offset
6565/// set, i.e, if the vtable offset of @p is different from -1.
6566bool
6569
6570/// Get the vtable offset of a member function.
6571///
6572/// @param f the member function to consider.
6573///
6574/// @return the vtable offset of @p f. Note that a vtable offset of
6575/// value -1 means that the member function does *NOT* yet have a
6576/// vtable offset associated to it.
6577ssize_t
6579{
6581
6582 const method_decl* m =
6583 dynamic_cast<const method_decl*>(&f);
6584 ABG_ASSERT(m);
6585
6586 const mem_fn_context_rel* ctxt =
6587 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6588
6589 return ctxt->vtable_offset();
6590}
6591
6592/// Get the vtable offset of a member function.
6593///
6594/// @param f the member function to consider.
6595///
6596/// @return the vtable offset of @p f. Note that a vtable offset of
6597/// value -1 means that the member function does *NOT* yet have a
6598/// vtable offset associated to it.
6599ssize_t
6602
6603/// Set the vtable offset of a member function.
6604///
6605/// @param f the member function to consider.
6606///
6607/// @param s the new vtable offset. Please note that a vtable offset
6608/// of value -1 means that the virtual member function does not (yet)
6609/// have any vtable offset associated to it.
6610static void
6611set_member_function_vtable_offset(function_decl& f, ssize_t s)
6612{
6614
6615 method_decl* m = is_method_decl(&f);
6616 ABG_ASSERT(m);
6617
6618 mem_fn_context_rel* ctxt =
6619 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6620
6621 ctxt->vtable_offset(s);
6622}
6623
6624/// Get the vtable offset of a member function.
6625///
6626/// @param f the member function to consider.
6627///
6628/// @param s the new vtable offset. Please note that a vtable offset
6629/// of value -1 means that the virtual member function does not (yet)
6630/// have any vtable offset associated to it.
6631static void
6632set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
6633{return set_member_function_vtable_offset(*f, s);}
6634
6635/// Test if a given member function is virtual.
6636///
6637/// @param mem_fn the member function to consider.
6638///
6639/// @return true iff a @p mem_fn is virtual.
6640bool
6642{
6644
6645 const method_decl* m =
6646 dynamic_cast<const method_decl*>(&f);
6647 ABG_ASSERT(m);
6648
6649 const mem_fn_context_rel* ctxt =
6650 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6651
6652 return ctxt->is_virtual();
6653}
6654
6655/// Test if a given member function is virtual.
6656///
6657/// @param mem_fn the member function to consider.
6658///
6659/// @return true iff a @p mem_fn is virtual.
6660bool
6662{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6663
6664/// Test if a given member function is virtual.
6665///
6666/// @param mem_fn the member function to consider.
6667///
6668/// @return true iff a @p mem_fn is virtual.
6669bool
6671{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6672
6673/// Set the virtual-ness of a member function.
6674///
6675/// @param f the member function to consider.
6676///
6677/// @param is_virtual set to true if the function is virtual.
6678static void
6679set_member_function_is_virtual(function_decl& f, bool is_virtual)
6680{
6682
6683 method_decl* m = is_method_decl(&f);
6684 ABG_ASSERT(m);
6685
6686 mem_fn_context_rel* ctxt =
6687 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6688
6689 ctxt->is_virtual(is_virtual);
6690}
6691
6692/// Set the virtual-ness of a member function.
6693///
6694/// @param f the member function to consider.
6695///
6696/// @param is_virtual set to true if the function is virtual.
6697static void
6698set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
6699{
6700 if (fn)
6701 {
6702 set_member_function_is_virtual(*fn, is_virtual);
6704 }
6705}
6706
6707/// Set the virtual-ness of a member fcuntion
6708///
6709/// @param fn the member function to consider.
6710///
6711/// @param is_virtual whether the function is virtual.
6712///
6713/// @param voffset the virtual offset of the virtual function.
6714void
6716 bool is_virtual,
6717 ssize_t voffset)
6718{
6719 // Setting the offset must come first because the second function
6720 // does assume the voffset is set, in case of virtuality
6721 set_member_function_vtable_offset(fn, voffset);
6722 set_member_function_is_virtual(fn, is_virtual);
6723}
6724
6725/// Set the virtual-ness of a member fcuntion
6726///
6727/// @param fn the member function to consider.
6728///
6729/// @param is_virtual whether the function is virtual.
6730///
6731/// @param voffset the virtual offset of the virtual function.
6732void
6734 bool is_virtual,
6735 ssize_t voffset)
6736{
6737 if (fn)
6738 set_member_function_virtuality(*fn, is_virtual, voffset);
6739}
6740
6741/// Set the virtual-ness of a member fcuntion
6742///
6743/// @param fn the member function to consider.
6744///
6745/// @param is_virtual whether the function is virtual.
6746///
6747/// @param voffset the virtual offset of the virtual function.
6748void
6750 bool is_virtual,
6751 ssize_t voffset)
6752{
6753 set_member_function_vtable_offset(fn, voffset);
6754 set_member_function_is_virtual(fn, is_virtual);
6755}
6756
6757/// Recursively returns the the underlying type of a typedef. The
6758/// return type should not be a typedef of anything anymore.
6759///
6760///
6761/// Also recursively strip typedefs from the sub-types of the type
6762/// given in arguments.
6763///
6764/// Note that this function builds types in which typedefs are
6765/// stripped off. Usually, types are held by their scope, so their
6766/// life time is bound to the life time of their scope. But as this
6767/// function cannot really insert the built type into it's scope, it
6768/// must ensure that the newly built type stays live long enough.
6769///
6770/// So, if the newly built type has a canonical type, this function
6771/// returns the canonical type. Otherwise, this function ensure that
6772/// the newly built type has a life time that is the same as the life
6773/// time of the entire libabigail library.
6774///
6775/// @param type the type to strip the typedefs from.
6776///
6777/// @return the resulting type stripped from its typedefs, or just
6778/// return @p type if it has no typedef in any of its sub-types.
6779type_base_sptr
6780strip_typedef(const type_base_sptr type)
6781{
6782 if (!type)
6783 return type;
6784
6785 // If type is a class type then do not try to strip typedefs from it.
6786 // And if it has no canonical type (which can mean that it's a
6787 // declaration-only class), then, make sure its live for ever and
6788 // return it.
6789 if (class_decl_sptr cl = is_class_type(type))
6790 {
6791 if (!cl->get_canonical_type())
6792 keep_type_alive(type);
6793 return type;
6794 }
6795
6796 const environment& env = type->get_environment();
6797 type_base_sptr t = type;
6798
6799 if (const typedef_decl_sptr ty = is_typedef(t))
6800 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6801 else if (const reference_type_def_sptr ty = is_reference_type(t))
6802 {
6803 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6804 env));
6805 ABG_ASSERT(p);
6806 t.reset(new reference_type_def(p,
6807 ty->is_lvalue(),
6808 ty->get_size_in_bits(),
6809 ty->get_alignment_in_bits(),
6810 ty->get_location()));
6811 }
6812 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6813 {
6814 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6815 env));
6816 ABG_ASSERT(p);
6817 t.reset(new pointer_type_def(p,
6818 ty->get_size_in_bits(),
6819 ty->get_alignment_in_bits(),
6820 ty->get_location()));
6821 }
6822 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6823 {
6824 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6825 env));
6826 ABG_ASSERT(p);
6827 t.reset(new qualified_type_def(p,
6828 ty->get_cv_quals(),
6829 ty->get_location()));
6830 }
6831 else if (const array_type_def_sptr ty = is_array_type(t))
6832 {
6833 type_base_sptr p = strip_typedef(ty->get_element_type());
6834 ABG_ASSERT(p);
6835 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6836 }
6837 else if (const method_type_sptr ty = is_method_type(t))
6838 {
6840 for (function_decl::parameters::const_iterator i =
6841 ty->get_parameters().begin();
6842 i != ty->get_parameters().end();
6843 ++i)
6844 {
6846 type_base_sptr typ = strip_typedef(p->get_type());
6847 ABG_ASSERT(typ);
6849 (new function_decl::parameter(typ,
6850 p->get_index(),
6851 p->get_name(),
6852 p->get_location(),
6853 p->get_variadic_marker(),
6854 p->get_is_artificial()));
6855 parm.push_back(stripped);
6856 }
6857 type_base_sptr p = strip_typedef(ty->get_return_type());
6858 ABG_ASSERT(!!p == !!ty->get_return_type());
6859 t.reset(new method_type(p, ty->get_class_type(),
6860 parm, ty->get_is_const(),
6861 ty->get_size_in_bits(),
6862 ty->get_alignment_in_bits()));
6863 }
6864 else if (const function_type_sptr ty = is_function_type(t))
6865 {
6867 for (function_decl::parameters::const_iterator i =
6868 ty->get_parameters().begin();
6869 i != ty->get_parameters().end();
6870 ++i)
6871 {
6873 type_base_sptr typ = strip_typedef(p->get_type());
6874 ABG_ASSERT(typ);
6876 (new function_decl::parameter(typ,
6877 p->get_index(),
6878 p->get_name(),
6879 p->get_location(),
6880 p->get_variadic_marker(),
6881 p->get_is_artificial()));
6882 parm.push_back(stripped);
6883 }
6884 type_base_sptr p = strip_typedef(ty->get_return_type());
6885 ABG_ASSERT(!!p == !!ty->get_return_type());
6886 t.reset(new function_type(p, parm,
6887 ty->get_size_in_bits(),
6888 ty->get_alignment_in_bits()));
6889 }
6890
6891 if (!t->get_translation_unit())
6892 t->set_translation_unit(type->get_translation_unit());
6893
6894 if (!(type->get_canonical_type() && canonicalize(t)))
6895 keep_type_alive(t);
6896
6897 return t->get_canonical_type() ? t->get_canonical_type() : t;
6898}
6899
6900/// Strip qualification from a qualified type, when it makes sense.
6901///
6902/// DWARF constructs "const reference". This is redundant because a
6903/// reference is always const. It also constructs the useless "const
6904/// void" type. The issue is these redundant types then leak into the
6905/// IR and make for bad diagnostics.
6906///
6907/// This function thus strips the const qualifier from the type in
6908/// that case. It might contain code to strip other cases like this
6909/// in the future.
6910///
6911/// @param t the type to strip const qualification from.
6912///
6913/// @return the stripped type or just return @p t.
6914decl_base_sptr
6915strip_useless_const_qualification(const qualified_type_def_sptr t)
6916{
6917 if (!t)
6918 return t;
6919
6920 decl_base_sptr result = t;
6921 type_base_sptr u = t->get_underlying_type();
6922 const environment& env = t->get_environment();
6923
6924 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6925 && (is_reference_type(u)))
6926 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6927 && env.is_void_type(u))
6928 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6929 // Let's strip the const qualifier because a reference is always
6930 // 'const' and a const void doesn't make sense. They will just
6931 // lead to spurious changes later down the pipeline, that we'll
6932 // have to deal with by doing painful and error-prone editing of
6933 // the diff IR. Dropping that useless and inconsistent artefact
6934 // right here seems to be a good way to go.
6935 result = is_decl(u);
6936
6937 return result;
6938}
6939
6940/// Merge redundant qualifiers from a tree of qualified types.
6941///
6942/// Suppose a tree of qualified types leads to:
6943///
6944/// const virtual const restrict const int;
6945///
6946/// Suppose the IR tree of qualified types ressembles (with C meaning
6947/// const, V meaning virtual and R meaning restrict):
6948///
6949/// [C|V]-->[C|R] -->[C] --> [int].
6950///
6951/// This function walks the IR and remove the redundant CV qualifiers
6952/// so the IR becomes:
6953///
6954/// [C|V] --> [R] --> [] -->[int].
6955///
6956/// Note that the empty qualified type (noted []) represents a
6957/// qualified type with no qualifier. It's rare, but it can exist.
6958/// I've put it here just for the sake of example.
6959///
6960/// The resulting IR thus represents the (merged) type:
6961///
6962/// const virtual restrict int.
6963///
6964/// This function is a sub-routine of the overload @ref
6965/// strip_useless_const_qualification which doesn't return any value.
6966///
6967/// @param t the qualified type to consider.
6968///
6969/// @param redundant_quals the (redundant) qualifiers to be removed
6970/// from the qualifiers of the underlying types of @p t.
6971///
6972/// @return the underlying type of @p t which might have had its
6973/// redundant qualifiers removed.
6974static qualified_type_def_sptr
6975strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
6976 qualified_type_def::CV redundant_quals)
6977{
6978 if (!t)
6979 return t;
6980
6981 // We must NOT edit canonicalized types.
6982 ABG_ASSERT(!t->get_canonical_type());
6983
6984 qualified_type_def_sptr underlying_qualified_type =
6985 is_qualified_type(t->get_underlying_type());
6986
6987 // Let's build 'currated qualifiers' that are the qualifiers of the
6988 // current type from which redundant qualifiers are removed.
6989 qualified_type_def::CV currated_quals = t->get_cv_quals();
6990
6991 // Remove the redundant qualifiers from these currated qualifiers
6992 currated_quals &= ~redundant_quals;
6993 t->set_cv_quals(currated_quals);
6994
6995 // The redundant qualifiers, moving forward, is now the union of the
6996 // previous set of redundant qualifiers and the currated qualifiers.
6997 redundant_quals |= currated_quals;
6998
6999 qualified_type_def_sptr result = t;
7000 if (underlying_qualified_type)
7001 // Now remove the redundant qualifiers from the qualified types
7002 // potentially carried by the underlying type.
7003 result =
7004 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
7005 redundant_quals);
7006
7007 return result;
7008}
7009
7010/// Merge redundant qualifiers from a tree of qualified types.
7011///
7012/// Suppose a tree of qualified types leads to:
7013///
7014/// const virtual const restrict const int;
7015///
7016/// Suppose the IR tree of qualified types ressembles (with C meaning
7017/// const, V meaning virtual and R meaning restrict):
7018///
7019/// [C|V]-->[C|R] -->[C] --> [int].
7020///
7021/// This function walks the IR and remove the redundant CV qualifiers
7022/// so the IR becomes:
7023///
7024/// [C|V] --> [R] --> [] -->[int].
7025///
7026/// Note that the empty qualified type (noted []) represents a
7027/// qualified type with no qualifier. It's rare, but it can exist.
7028/// I've put it here just for the sake of example.
7029///
7030/// The resulting IR thus represents the (merged) type:
7031///
7032/// const virtual restrict int.
7033///
7034/// @param t the qualified type to consider. The IR below the
7035/// argument to this parameter will be edited to remove redundant
7036/// qualifiers where applicable.
7037void
7038strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
7039{
7040 if (!t)
7041 return;
7042
7043 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
7044 strip_redundant_quals_from_underyling_types(t, redundant_quals);
7045}
7046
7047/// Return the leaf underlying type node of a @ref typedef_decl node.
7048///
7049/// If the underlying type of a @ref typedef_decl node is itself a
7050/// @ref typedef_decl node, then recursively look at the underlying
7051/// type nodes to get the first one that is not a a @ref typedef_decl
7052/// node. This is what a leaf underlying type node means.
7053///
7054/// Otherwise, if the underlying type node of @ref typedef_decl is
7055/// *NOT* a @ref typedef_decl node, then just return the underlying
7056/// type node.
7057///
7058/// And if the type node considered is not a @ref typedef_decl node,
7059/// then just return it.
7060///
7061/// @return the leaf underlying type node of a @p type.
7062type_base_sptr
7063peel_typedef_type(const type_base_sptr& type)
7064{
7065 typedef_decl_sptr t = is_typedef(type);
7066 if (!t)
7067 return type;
7068
7069 if (is_typedef(t->get_underlying_type()))
7070 return peel_typedef_type(t->get_underlying_type());
7071 return t->get_underlying_type();
7072}
7073
7074/// Return the leaf underlying type node of a @ref typedef_decl node.
7075///
7076/// If the underlying type of a @ref typedef_decl node is itself a
7077/// @ref typedef_decl node, then recursively look at the underlying
7078/// type nodes to get the first one that is not a a @ref typedef_decl
7079/// node. This is what a leaf underlying type node means.
7080///
7081/// Otherwise, if the underlying type node of @ref typedef_decl is
7082/// *NOT* a @ref typedef_decl node, then just return the underlying
7083/// type node.
7084///
7085/// And if the type node considered is not a @ref typedef_decl node,
7086/// then just return it.
7087///
7088/// @return the leaf underlying type node of a @p type.
7089const type_base*
7091{
7092 const typedef_decl* t = is_typedef(type);
7093 if (!t)
7094 return type;
7095
7096 return peel_typedef_type(t->get_underlying_type()).get();
7097}
7098
7099/// Return the leaf pointed-to type node of a @ref pointer_type_def
7100/// node.
7101///
7102/// If the pointed-to type of a @ref pointer_type_def node is itself a
7103/// @ref pointer_type_def node, then recursively look at the
7104/// pointed-to type nodes to get the first one that is not a a @ref
7105/// pointer_type_def node. This is what a leaf pointed-to type node
7106/// means.
7107///
7108/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7109/// *NOT* a @ref pointer_type_def node, then just return the
7110/// pointed-to type node.
7111///
7112/// And if the type node considered is not a @ref pointer_type_def
7113/// node, then just return it.
7114///
7115/// @return the leaf pointed-to type node of a @p type.
7116type_base_sptr
7117peel_pointer_type(const type_base_sptr& type)
7118{
7120 if (!t)
7121 return type;
7122
7123 if (is_pointer_type(t->get_pointed_to_type()))
7124 return peel_pointer_type(t->get_pointed_to_type());
7125 return t->get_pointed_to_type();
7126}
7127
7128/// Return the leaf pointed-to type node of a @ref pointer_type_def
7129/// node.
7130///
7131/// If the pointed-to type of a @ref pointer_type_def node is itself a
7132/// @ref pointer_type_def node, then recursively look at the
7133/// pointed-to type nodes to get the first one that is not a a @ref
7134/// pointer_type_def node. This is what a leaf pointed-to type node
7135/// means.
7136///
7137/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7138/// *NOT* a @ref pointer_type_def node, then just return the
7139/// pointed-to type node.
7140///
7141/// And if the type node considered is not a @ref pointer_type_def
7142/// node, then just return it.
7143///
7144/// @return the leaf pointed-to type node of a @p type.
7145const type_base*
7147{
7148 const pointer_type_def* t = is_pointer_type(type);
7149 if (!t)
7150 return type;
7151
7152 return peel_pointer_type(t->get_pointed_to_type()).get();
7153}
7154
7155/// Return the leaf pointed-to type node of a @ref reference_type_def
7156/// node.
7157///
7158/// If the pointed-to type of a @ref reference_type_def node is itself
7159/// a @ref reference_type_def node, then recursively look at the
7160/// pointed-to type nodes to get the first one that is not a a @ref
7161/// reference_type_def node. This is what a leaf pointed-to type node
7162/// means.
7163///
7164/// Otherwise, if the pointed-to type node of @ref reference_type_def
7165/// is *NOT* a @ref reference_type_def node, then just return the
7166/// pointed-to type node.
7167///
7168/// And if the type node considered is not a @ref reference_type_def
7169/// node, then just return it.
7170///
7171/// @return the leaf pointed-to type node of a @p type.
7172type_base_sptr
7173peel_reference_type(const type_base_sptr& type)
7174{
7176 if (!t)
7177 return type;
7178
7179 if (is_reference_type(t->get_pointed_to_type()))
7180 return peel_reference_type(t->get_pointed_to_type());
7181 return t->get_pointed_to_type();
7182}
7183
7184/// Return the leaf pointed-to type node of a @ref reference_type_def
7185/// node.
7186///
7187/// If the pointed-to type of a @ref reference_type_def node is itself
7188/// a @ref reference_type_def node, then recursively look at the
7189/// pointed-to type nodes to get the first one that is not a a @ref
7190/// reference_type_def node. This is what a leaf pointed-to type node
7191/// means.
7192///
7193/// Otherwise, if the pointed-to type node of @ref reference_type_def
7194/// is *NOT* a @ref reference_type_def node, then just return the
7195/// pointed-to type node.
7196///
7197/// And if the type node considered is not a @ref reference_type_def
7198/// node, then just return it.
7199///
7200/// @return the leaf pointed-to type node of a @p type.
7201const type_base*
7203{
7204 const reference_type_def* t = is_reference_type(type);
7205 if (!t)
7206 return type;
7207
7208 return peel_reference_type(t->get_pointed_to_type()).get();
7209}
7210
7211/// Return the leaf element type of an array.
7212///
7213/// If the element type is itself an array, then recursively return
7214/// the element type of that array itself.
7215///
7216/// @param type the array type to consider. If this is not an array
7217/// type, this type is returned by the function.
7218///
7219/// @return the leaf element type of the array @p type, or, if it's
7220/// not an array type, then just return @p.
7221const type_base_sptr
7222peel_array_type(const type_base_sptr& type)
7223{
7224 const array_type_def_sptr t = is_array_type(type);
7225 if (!t)
7226 return type;
7227
7228 return peel_array_type(t->get_element_type());
7229}
7230
7231/// Return the leaf element type of an array.
7232///
7233/// If the element type is itself an array, then recursively return
7234/// the element type of that array itself.
7235///
7236/// @param type the array type to consider. If this is not an array
7237/// type, this type is returned by the function.
7238///
7239/// @return the leaf element type of the array @p type, or, if it's
7240/// not an array type, then just return @p.
7241const type_base*
7243{
7244 const array_type_def* t = is_array_type(type);
7245 if (!t)
7246 return type;
7247
7248 return peel_array_type(t->get_element_type()).get();
7249}
7250
7251/// Return the leaf underlying type of a qualified type.
7252///
7253/// If the underlying type is itself a qualified type, then
7254/// recursively return the first underlying type of that qualified
7255/// type to return the first underlying type that is not a qualified type.
7256///
7257/// If the underlying type is NOT a qualified type, then just return
7258/// that underlying type.
7259///
7260/// @param type the qualified type to consider.
7261///
7262/// @return the leaf underlying type.
7263const type_base*
7265{
7266 const qualified_type_def* t = is_qualified_type(type);
7267 if (!t)
7268 return type;
7269
7270 return peel_qualified_type(t->get_underlying_type().get());
7271}
7272
7273/// Return the leaf underlying type of a qualified type.
7274///
7275/// If the underlying type is itself a qualified type, then
7276/// recursively return the first underlying type of that qualified
7277/// type to return the first underlying type that is not a qualified type.
7278///
7279/// If the underlying type is NOT a qualified type, then just return
7280/// that underlying type.
7281///
7282/// @param type the qualified type to consider.
7283///
7284/// @return the leaf underlying type.
7285const type_base_sptr
7286peel_qualified_type(const type_base_sptr& type)
7287{
7288 const qualified_type_def_sptr t = is_qualified_type(type);
7289 if (!t)
7290 return type;
7291
7292 return peel_qualified_type(t->get_underlying_type());
7293}
7294
7295/// Test if a given qualified type is const.
7296///
7297/// @pram t the qualified type to consider.
7298///
7299/// @return true iff @p t is a const qualified type.
7300bool
7301is_const_qualified_type(const qualified_type_def_sptr& t)
7302{
7303 if (!t)
7304 return false;
7305
7306 if (t->get_cv_quals() == qualified_type_def::CV_CONST)
7307 return true;
7308
7309 return false;
7310}
7311
7312/// Test if a given type is const-qualified.
7313///
7314/// @pram t the type to consider.
7315///
7316/// @return true iff @p t is a const qualified type.
7317bool
7318is_const_qualified_type(const type_base_sptr& t)
7319{
7320 qualified_type_def_sptr q = is_qualified_type(t);
7321 if (!q)
7322 return false;
7323 return is_const_qualified_type(q);
7324}
7325
7326/// If a qualified type is const, then return its underlying type.
7327///
7328/// @param q the qualified type to consider.
7329///
7330/// @return the underlying type of @p q if it's a const-qualified
7331/// type, otherwise, return @p q itself.
7332type_base_sptr
7333peel_const_qualified_type(const qualified_type_def_sptr& q)
7334{
7335 if (!q)
7336 return q;
7337
7339 return q->get_underlying_type();
7340
7341 return q;
7342}
7343
7344/// Return the leaf underlying type of a qualified or typedef type.
7345///
7346/// If the underlying type is itself a qualified or typedef type, then
7347/// recursively return the first underlying type of that qualified or
7348/// typedef type to return the first underlying type that is not a
7349/// qualified or typedef type.
7350///
7351/// If the underlying type is NOT a qualified nor a typedef type, then
7352/// just return that underlying type.
7353///
7354/// @param type the qualified or typedef type to consider.
7355///
7356/// @return the leaf underlying type.
7357type_base*
7359{
7360 while (is_typedef(type) || is_qualified_type(type))
7361 {
7362 if (const typedef_decl* t = is_typedef(type))
7363 type = peel_typedef_type(t);
7364
7365 if (const qualified_type_def* t = is_qualified_type(type))
7366 type = peel_qualified_type(t);
7367 }
7368
7369 return const_cast<type_base*>(type);
7370}
7371
7372/// Return the leaf underlying type of a qualified or typedef type.
7373///
7374/// If the underlying type is itself a qualified or typedef type, then
7375/// recursively return the first underlying type of that qualified or
7376/// typedef type to return the first underlying type that is not a
7377/// qualified or typedef type.
7378///
7379/// If the underlying type is NOT a qualified nor a typedef type, then
7380/// just return that underlying type.
7381///
7382/// @param type the qualified or typedef type to consider.
7383///
7384/// @return the leaf underlying type.
7385type_base_sptr
7386peel_qualified_or_typedef_type(const type_base_sptr &t)
7387{
7388 type_base_sptr type = t;
7389 while (is_typedef(type) || is_qualified_type(type))
7390 {
7391 if (typedef_decl_sptr t = is_typedef(type))
7392 type = peel_typedef_type(t);
7393
7394 if (qualified_type_def_sptr t = is_qualified_type(type))
7395 type = peel_qualified_type(t);
7396 }
7397
7398 return type;
7399}
7400
7401/// Return the leaf underlying or pointed-to type node of a @ref
7402/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7403/// or @ref array_type_def node.
7404///
7405/// @param type the type to peel.
7406///
7407/// @return the leaf underlying or pointed-to type node of @p type.
7408type_base_sptr
7410{
7411 type_base_sptr typ = type;
7412 while (is_typedef(typ)
7413 || is_pointer_type(typ)
7414 || is_reference_type(typ)
7415 || is_array_type(typ))
7416 {
7417 if (typedef_decl_sptr t = is_typedef(typ))
7418 typ = peel_typedef_type(t);
7419
7421 typ = peel_pointer_type(t);
7422
7424 typ = peel_reference_type(t);
7425
7426 if (const array_type_def_sptr t = is_array_type(typ))
7427 typ = peel_array_type(t);
7428 }
7429
7430 return typ;
7431}
7432
7433/// Return the leaf underlying or pointed-to type node of a @ref
7434/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7435/// node.
7436///
7437/// @param type the type to peel.
7438///
7439/// @return the leaf underlying or pointed-to type node of @p type.
7440type_base*
7442{
7443 while (is_typedef(type)
7444 || is_pointer_type(type)
7445 || is_reference_type(type)
7446 || is_array_type(type))
7447 {
7448 if (const typedef_decl* t = is_typedef(type))
7449 type = peel_typedef_type(t);
7450
7451 if (const pointer_type_def* t = is_pointer_type(type))
7452 type = peel_pointer_type(t);
7453
7454 if (const reference_type_def* t = is_reference_type(type))
7455 type = peel_reference_type(t);
7456
7457 if (const array_type_def* t = is_array_type(type))
7458 type = peel_array_type(t);
7459 }
7460
7461 return const_cast<type_base*>(type);
7462}
7463
7464/// Return the leaf underlying or pointed-to type node of a @ref
7465/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7466/// node.
7467///
7468/// @param type the type to peel.
7469///
7470/// @return the leaf underlying or pointed-to type node of @p type.
7471type_base*
7473 bool peel_qual_type)
7474{
7475 while (is_typedef(type)
7476 || is_pointer_type(type)
7477 || is_reference_type(type)
7478 || is_array_type(type)
7479 || (peel_qual_type && is_qualified_type(type)))
7480 {
7481 if (const typedef_decl* t = is_typedef(type))
7482 type = peel_typedef_type(t);
7483
7484 if (const pointer_type_def* t = is_pointer_type(type))
7485 type = peel_pointer_type(t);
7486
7487 if (const reference_type_def* t = is_reference_type(type))
7488 type = peel_reference_type(t);
7489
7490 if (const array_type_def* t = is_array_type(type))
7491 type = peel_array_type(t);
7492
7493 if (peel_qual_type)
7494 if (const qualified_type_def* t = is_qualified_type(type))
7495 type = peel_qualified_type(t);
7496 }
7497
7498 return const_cast<type_base*>(type);
7499}
7500
7501/// Return the leaf underlying or pointed-to type node of a, @ref
7502/// pointer_type_def, @ref reference_type_def or @ref
7503/// qualified_type_def type node.
7504///
7505/// @param type the type to peel.
7506///
7507/// @param peel_qualified_type if true, also peel qualified types.
7508///
7509/// @return the leaf underlying or pointed-to type node of @p type.
7510type_base*
7512 bool peel_qual_type)
7513{
7514 while (is_pointer_type(type)
7515 || is_reference_type(type)
7516 || is_array_type(type)
7517 || (peel_qual_type && is_qualified_type(type)))
7518 {
7519 if (const pointer_type_def* t = is_pointer_type(type))
7520 type = peel_pointer_type(t);
7521
7522 if (const reference_type_def* t = is_reference_type(type))
7523 type = peel_reference_type(t);
7524
7525 if (const array_type_def* t = is_array_type(type))
7526 type = peel_array_type(t);
7527
7528 if (peel_qual_type)
7529 if (const qualified_type_def* t = is_qualified_type(type))
7530 type = peel_qualified_type(t);
7531 }
7532
7533 return const_cast<type_base*>(type);
7534}
7535
7536/// Clone an array type.
7537///
7538/// Note that the element type of the new array is shared witht the
7539/// old one.
7540///
7541/// @param array the array type to clone.
7542///
7543/// @return a newly built array type. Note that it needs to be added
7544/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7545/// bound to the one of that scope. Otherwise, its lifetime is bound
7546/// to the lifetime of its containing shared pointer.
7549{
7550 vector<array_type_def::subrange_sptr> subranges;
7551
7552 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7553 array->get_subranges().begin();
7554 i != array->get_subranges().end();
7555 ++i)
7556 {
7558 (new array_type_def::subrange_type(array->get_environment(),
7559 (*i)->get_name(),
7560 (*i)->get_lower_bound(),
7561 (*i)->get_upper_bound(),
7562 (*i)->get_underlying_type(),
7563 (*i)->get_location(),
7564 (*i)->get_language()));
7565 subrange->is_non_finite((*i)->is_non_finite());
7566 if (scope_decl *scope = (*i)->get_scope())
7567 add_decl_to_scope(subrange, scope);
7568 subranges.push_back(subrange);
7569 }
7570
7571 array_type_def_sptr result
7572 (new array_type_def(array->get_element_type(),
7573 subranges, array->get_location()));
7574
7575 return result;
7576}
7577
7578/// Clone a typedef type.
7579///
7580/// Note that the underlying type of the newly constructed typedef is
7581/// shared with the old one.
7582///
7583/// @param t the typedef to clone.
7584///
7585/// @return the newly constructed typedef. Note that it needs to be
7586/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7587/// to be bound to the one of that scope. Otherwise, its lifetime is
7588/// bound to the lifetime of its containing shared pointer.
7591{
7592 if (!t)
7593 return t;
7594
7595 typedef_decl_sptr result
7596 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7597 t->get_location(), t->get_linkage_name(),
7598 t->get_visibility()));
7599 return result;
7600}
7601
7602/// Clone a qualifiend type.
7603///
7604/// Note that underlying type of the newly constructed qualified type
7605/// is shared with the old one.
7606///
7607/// @param t the qualified type to clone.
7608///
7609/// @return the newly constructed qualified type. Note that it needs
7610/// to be added to a scope (e.g, using add_decl_to_scope) for its
7611/// lifetime to be bound to the one of that scope. Otherwise, its
7612/// lifetime is bound to the lifetime of its containing shared
7613/// pointer.
7614qualified_type_def_sptr
7615clone_qualified_type(const qualified_type_def_sptr& t)
7616{
7617 if (!t)
7618 return t;
7619
7620 qualified_type_def_sptr result
7621 (new qualified_type_def(t->get_underlying_type(),
7622 t->get_cv_quals(), t->get_location()));
7623
7624 return result;
7625}
7626
7627/// Clone a typedef, an array or a qualified tree.
7628///
7629/// @param type the typedef, array or qualified tree to clone. any
7630/// order.
7631///
7632/// @return the cloned type, or NULL if @type was neither a typedef,
7633/// array nor a qualified type.
7634static type_base_sptr
7635clone_typedef_array_qualified_type(type_base_sptr type)
7636{
7637 if (!type)
7638 return type;
7639
7640 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7641 type_base_sptr result;
7642
7643 if (typedef_decl_sptr t = is_typedef(type))
7644 result = clone_typedef(is_typedef(t));
7645 else if (qualified_type_def_sptr t = is_qualified_type(type))
7646 result = clone_qualified_type(t);
7647 else if (array_type_def_sptr t = is_array_type(type))
7648 result = clone_array(t);
7649 else
7650 return type_base_sptr();
7651
7652 if (scope)
7653 add_decl_to_scope(is_decl(result), scope);
7654
7655 return result;
7656}
7657
7658/// Clone a type tree made of an array or a typedef of array.
7659///
7660/// Note that this can be a tree which root node is a typedef an which
7661/// sub-tree can be any arbitrary combination of typedef, qualified
7662/// type and arrays.
7663///
7664/// @param t the array or typedef of qualified array to consider.
7665///
7666/// @return a clone of @p t.
7667type_base_sptr
7668clone_array_tree(const type_base_sptr t)
7669{
7671
7672 scope_decl* scope = is_decl(t)->get_scope();
7673 type_base_sptr result = clone_typedef_array_qualified_type(t);
7674 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7675
7676 type_base_sptr subtree;
7677 if (typedef_decl_sptr type = is_typedef(result))
7678 {
7679 type_base_sptr s =
7680 clone_typedef_array_qualified_type(type->get_underlying_type());
7681 if (s)
7682 {
7683 subtree = s;
7684 type->set_underlying_type(subtree);
7685 }
7686 }
7687 else if (array_type_def_sptr type = is_array_type(result))
7688 {
7689 type_base_sptr s =
7690 clone_typedef_array_qualified_type(type->get_element_type());
7691 if (s)
7692 {
7693 subtree = s;
7694 type->set_element_type(subtree);
7695 }
7696 }
7697 add_decl_to_scope(is_decl(subtree), scope);
7698
7699 for (;;)
7700 {
7701 if (typedef_decl_sptr t = is_typedef(subtree))
7702 {
7703 type_base_sptr s =
7704 clone_typedef_array_qualified_type(t->get_underlying_type());
7705 if (s)
7706 {
7707 scope_decl* scope =
7708 is_decl(t->get_underlying_type())->get_scope();
7709 ABG_ASSERT(scope);
7710 add_decl_to_scope(is_decl(s), scope);
7711 t->set_underlying_type (s);
7712 subtree = s;
7713 }
7714 else
7715 break;
7716 }
7717 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7718 {
7719 type_base_sptr s =
7720 clone_typedef_array_qualified_type(t->get_underlying_type());
7721 if (s)
7722 {
7723 scope_decl* scope =
7724 is_decl(t->get_underlying_type())->get_scope();
7725 ABG_ASSERT(scope);
7726 add_decl_to_scope(is_decl(s), scope);
7727 t->set_underlying_type(s);
7728 subtree = s;
7729 }
7730 else
7731 break;
7732 }
7733 else if (array_type_def_sptr t = is_array_type(subtree))
7734 {
7735 type_base_sptr e = t->get_element_type();
7736 if (is_typedef(e) || is_qualified_type(e))
7737 {
7738 type_base_sptr s =
7739 clone_typedef_array_qualified_type(e);
7740 if (s)
7741 {
7742 scope_decl* scope = is_decl(e)->get_scope();
7743 ABG_ASSERT(scope);
7744 add_decl_to_scope(is_decl(s), scope);
7745 t->set_element_type(s);
7746 }
7747 else
7748 break;
7749 }
7750 break;
7751 }
7752 else
7753 break;
7754 }
7755 return result;
7756}
7757
7758/// Update the qualified name of a given sub-tree.
7759///
7760/// @param d the sub-tree for which to update the qualified name.
7761static void
7762update_qualified_name(decl_base * d)
7763{
7764 ::qualified_name_setter setter;
7765 d->traverse(setter);
7766}
7767
7768/// Update the qualified name of a given sub-tree.
7769///
7770/// @param d the sub-tree for which to update the qualified name.
7771static void
7772update_qualified_name(decl_base_sptr d)
7773{return update_qualified_name(d.get());}
7774
7775// <scope_decl stuff>
7776
7777/// Hash a type by returning the pointer value of its canonical type.
7778///
7779/// @param l the type to hash.
7780///
7781/// @return the the pointer value of the canonical type of @p l.
7782size_t
7783canonical_type_hash::operator()(const type_base_sptr& l) const
7784{return operator()(l.get());}
7785
7786/// Hash a (canonical) type by returning its pointer value
7787///
7788/// @param l the canonical type to hash.
7789///
7790/// @return the pointer value of the canonical type of @p l.
7791size_t
7793{return reinterpret_cast<size_t>(l);}
7794
7795struct scope_decl::priv
7796{
7797 declarations members_;
7798 declarations sorted_members_;
7799 type_base_sptrs_type member_types_;
7800 type_base_sptrs_type sorted_member_types_;
7801 scopes member_scopes_;
7802 canonical_type_sptr_set_type canonical_types_;
7803 type_base_sptrs_type sorted_canonical_types_;
7804 bool clear_sorted_member_types_cache_ = false;
7805}; // end struct scope_decl::priv
7806
7807/// Constructor of the @ref scope_decl type.
7808///
7809/// @param the environment to use for the new instance.
7810///
7811/// @param the name of the scope decl.
7812///
7813/// @param locus the source location where the scope_decl is defined.
7814///
7815/// @param vis the visibility of the declaration.
7816scope_decl::scope_decl(const environment& env,
7817 const string& name,
7818 const location& locus,
7819 visibility vis)
7820 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7821 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7822 priv_(new priv)
7823{}
7824
7825/// Constructor of the @ref scope_decl type.
7826///
7827/// @param the environment to use for the new instance.
7828///
7829/// @param l the source location where the scope_decl is defined.
7830///
7831/// @param vis the visibility of the declaration.
7832scope_decl::scope_decl(const environment& env, location& l)
7833 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7834 decl_base(env, "", l),
7835 priv_(new priv)
7836{}
7837
7838/// @eturn the set of canonical types of the the current scope.
7841{return priv_->canonical_types_;}
7842
7843/// @eturn the set of canonical types of the the current scope.
7846{return const_cast<scope_decl*>(this)->get_canonical_types();}
7847
7848/// Return a vector of sorted canonical types of the current scope.
7849///
7850/// The types are sorted "almost topologically". That means, they are
7851/// sorted using the lexicographic order of the string representing
7852/// the location their definition point. If a type doesn't have a
7853/// location, then its pretty representation is used.
7854///
7855/// @return a vector of sorted canonical types of the current scope.
7858{
7859 if (priv_->sorted_canonical_types_.empty())
7860 {
7861 for (canonical_type_sptr_set_type::const_iterator e =
7862 get_canonical_types().begin();
7863 e != get_canonical_types().end();
7864 ++e)
7865 priv_->sorted_canonical_types_.push_back(*e);
7866
7867 type_topo_comp comp;
7868 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7869 priv_->sorted_canonical_types_.end(),
7870 comp);
7871 }
7872 return priv_->sorted_canonical_types_;
7873}
7874
7875/// Getter for the member declarations carried by the current @ref
7876/// scope_decl.
7877///
7878/// @return the member declarations carried by the current @ref
7879/// scope_decl.
7882{return priv_->members_;}
7883
7884/// Getter for the member declarations carried by the current @ref
7885/// scope_decl.
7886///
7887/// @return the member declarations carried by the current @ref
7888/// scope_decl.
7891{return priv_->members_;}
7892
7893/// Getter for the sorted member declarations carried by the current
7894/// @ref scope_decl.
7895///
7896/// @return the sorted member declarations carried by the current @ref
7897/// scope_decl. The declarations are sorted topologically.
7900{
7901 decl_topo_comp comp;
7902 if (priv_->sorted_members_.empty())
7903 {
7904 for (declarations::const_iterator i = get_member_decls().begin();
7905 i != get_member_decls().end();
7906 ++i)
7907 priv_->sorted_members_.push_back(*i);
7908
7909 std::stable_sort(priv_->sorted_members_.begin(),
7910 priv_->sorted_members_.end(),
7911 comp);
7912 }
7913 return priv_->sorted_members_;
7914}
7915
7916/// Getter for the number of anonymous classes contained in this
7917/// scope.
7918///
7919/// @return the number of anonymous classes contained in this scope.
7920size_t
7922{
7923 int result = 0;
7924 for (declarations::const_iterator it = get_member_decls().begin();
7925 it != get_member_decls().end();
7926 ++it)
7927 if (class_decl_sptr t = is_class_type(*it))
7928 if (t->get_is_anonymous())
7929 ++result;
7930
7931 return result;
7932}
7933
7934/// Getter for the number of anonymous unions contained in this
7935/// scope.
7936///
7937/// @return the number of anonymous unions contained in this scope.
7938size_t
7940{
7941 int result = 0;
7942 for (declarations::const_iterator it = get_member_decls().begin();
7943 it != get_member_decls().end();
7944 ++it)
7945 if (union_decl_sptr t = is_union_type(*it))
7946 if (t->get_is_anonymous())
7947 ++result;
7948
7949 return result;
7950}
7951
7952/// Getter for the number of anonymous enums contained in this
7953/// scope.
7954///
7955/// @return the number of anonymous enums contained in this scope.
7956size_t
7958{
7959 int result = 0;
7960 for (declarations::const_iterator it = get_member_decls().begin();
7961 it != get_member_decls().end();
7962 ++it)
7963 if (enum_type_decl_sptr t = is_enum_type(*it))
7964 if (t->get_is_anonymous())
7965 ++result;
7966
7967 return result;
7968}
7969
7970/// Getter for the scopes carried by the current scope.
7971///
7972/// @return the scopes carried by the current scope.
7975{return priv_->member_scopes_;}
7976
7977/// Getter for the scopes carried by the current scope.
7978///
7979/// @return the scopes carried by the current scope.
7980const scope_decl::scopes&
7982{return priv_->member_scopes_;}
7983
7984/// Test if the current scope is empty.
7985///
7986/// @return true iff the current scope is empty.
7987bool
7989{
7990 return (get_member_decls().empty()
7991 && get_canonical_types().empty());
7992}
7993
7994/// Set the translation unit of a decl
7995///
7996/// It also perform some IR integrity checks.
7997///
7998/// This is a sub-routine of scope_decl::{insert,add}_member_decl.
7999///
8000/// @param decl the decl to set the translation unit for.
8001///
8002/// @param tu the translation unit to set.
8003static void
8004maybe_set_translation_unit(const decl_base_sptr& decl,
8005 translation_unit* tu)
8006{
8007 ABG_ASSERT(tu);
8008
8009 if (translation_unit* existing_tu = decl->get_translation_unit())
8010 // The decl already belongs to a translation unit.
8011 // Either:
8012 //
8013 // 1/ it's a unique type, in which case we should not add it to
8014 // any translation unique since unique types are "logically"
8015 // supposed to belong to no translation unit in particular, as
8016 // they are unique.
8017 //
8018 // 2/ or the decl was already added to this translation unit.
8019 ABG_ASSERT(tu == existing_tu || is_unique_type(is_type(decl)));
8020 else
8021 decl->set_translation_unit(tu);
8022}
8023
8024/// Add a member decl to this scope. Note that user code should not
8025/// use this, but rather use add_decl_to_scope.
8026///
8027/// Note that this function updates the qualified name of the member
8028/// decl that is added. It also sets the scope of the member. Thus,
8029/// it ABG_ASSERTs that member should not have its scope set, prior to
8030/// calling this function.
8031///
8032/// @param member the new member decl to add to this scope.
8033decl_base_sptr
8034scope_decl::add_member_decl(const decl_base_sptr& member)
8035{
8036 ABG_ASSERT(!has_scope(member));
8037
8038 member->set_scope(this);
8039 priv_->members_.push_back(member);
8040 if (is_type(member))
8041 {
8042 priv_->member_types_.push_back(is_type(member));
8043 priv_->clear_sorted_member_types_cache_ = true;
8044 }
8045
8046 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8047 priv_->member_scopes_.push_back(m);
8048
8049 update_qualified_name(member);
8050
8052 maybe_set_translation_unit(member, tu);
8053
8055
8056 return member;
8057}
8058
8059/// Get the member types of this @ref scope_decl.
8060///
8061/// @return a vector of the member types of this ref class_or_union.
8064{return priv_->member_types_;}
8065
8066/// Find a member type of a given name, inside the current @ref
8067/// scope_decl.
8068///
8069/// @param name the name of the member type to look for.
8070///
8071/// @return a pointer to the @ref type_base that represents the member
8072/// type of name @p name, for the current scope.
8073type_base_sptr
8074scope_decl::find_member_type(const string& name) const
8075{
8076 for (auto t : get_member_types())
8077 if (get_type_name(t, /*qualified*/false) == name)
8078 return t;
8079 return type_base_sptr();
8080}
8081
8082/// Insert a member type.
8083///
8084/// @param t the type to insert in the @ref scope_decl type.
8085///
8086/// @param an iterator right before which @p t has to be inserted.
8087void
8089 declarations::iterator before)
8090{
8091 decl_base_sptr d = get_type_declaration(t);
8092 ABG_ASSERT(d);
8093 ABG_ASSERT(!has_scope(d));
8094
8095 priv_->member_types_.push_back(t);
8096 priv_->clear_sorted_member_types_cache_= true;
8097 insert_member_decl(d, before);
8098}
8099
8100/// Add a member type to the current instance of class_or_union.
8101///
8102/// @param t the member type to add. It must not have been added to a
8103/// scope, otherwise this will violate an ABG_ASSERTion.
8104void
8107
8108/// Add a member type to the current instance of class_or_union.
8109///
8110/// @param t the type to be added as a member type to the current
8111/// instance of class_or_union. An instance of class_or_union::member_type
8112/// will be created out of @p t and and added to the the class.
8113///
8114/// @param a the access specifier for the member type to be created.
8115type_base_sptr
8117{
8118 decl_base_sptr d = get_type_declaration(t);
8119 ABG_ASSERT(d);
8121 add_member_type(t);
8123 return t;
8124}
8125
8126/// Remove a member type from the current @ref class_or_union scope.
8127///
8128/// @param t the type to remove.
8129void
8131{
8132 for (auto i = priv_->member_types_.begin();
8133 i != priv_->member_types_.end();
8134 ++i)
8135 {
8136 if (*((*i)) == *t)
8137 {
8138 priv_->member_types_.erase(i);
8139 return;
8140 }
8141 }
8142}
8143
8144/// Get the sorted member types of this @ref scope_decl
8145///
8146/// @return a vector of the sorted member types of this ref
8147/// class_or_union.
8150{
8151 if (priv_->clear_sorted_member_types_cache_)
8152 {
8153 priv_->sorted_member_types_.clear();
8154 priv_->clear_sorted_member_types_cache_ = false;
8155 }
8156
8157 if (priv_->sorted_member_types_.empty())
8158 {
8159 unordered_set<type_base_sptr> canonical_pointer_types;
8160 for (auto t : get_member_types())
8161 {
8163 priv_->sorted_member_types_.push_back(t);
8164 else if (auto c = t->get_canonical_type())
8165 canonical_pointer_types.insert(c);
8166 else
8167 canonical_pointer_types.insert(t);
8168 }
8169
8170 for (auto t : canonical_pointer_types)
8171 priv_->sorted_member_types_.push_back(t);
8172
8173 type_topo_comp comp;
8174 std::stable_sort(priv_->sorted_member_types_.begin(),
8175 priv_->sorted_member_types_.end(),
8176 comp);
8177 }
8178
8179 const ir::environment& env = get_environment();
8181 priv_->clear_sorted_member_types_cache_ = true;
8182
8183 return priv_->sorted_member_types_;
8184}
8185
8186/// Insert a member decl to this scope, right before an element
8187/// pointed to by a given iterator. Note that user code should not
8188/// use this, but rather use insert_decl_into_scope.
8189///
8190/// Note that this function updates the qualified name of the inserted
8191/// member.
8192///
8193/// @param member the new member decl to add to this scope.
8194///
8195/// @param before an interator pointing to the element before which
8196/// the new member should be inserted.
8197decl_base_sptr
8199 declarations::iterator before)
8200{
8201 ABG_ASSERT(!member->get_scope());
8202
8203 member->set_scope(this);
8204 priv_->members_.insert(before, member);
8205
8206 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8207 priv_-> member_scopes_.push_back(m);
8208
8209 update_qualified_name(member);
8210
8212 maybe_set_translation_unit(member, tu);
8213
8215
8216 return member;
8217}
8218
8219/// Remove a declaration from the current scope.
8220///
8221/// @param member the declaration to remove from the scope.
8222void
8224{
8225 for (declarations::iterator i = priv_->members_.begin();
8226 i != priv_->members_.end();
8227 ++i)
8228 {
8229 if (**i == *member)
8230 {
8231 priv_->members_.erase(i);
8232 // Do not access i after this point as it's invalided by the
8233 // erase call.
8234 break;
8235 }
8236 }
8237
8238 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8239 if (scope)
8240 {
8241 for (scopes::iterator i = priv_->member_scopes_.begin();
8242 i != priv_->member_scopes_.end();
8243 ++i)
8244 {
8245 if (**i == *member)
8246 {
8247 priv_->member_scopes_.erase(i);
8248 break;
8249 }
8250 }
8251 }
8252
8253 member->set_scope(nullptr);
8254 member->set_translation_unit(nullptr);
8255}
8256
8257/// Compares two instances of @ref scope_decl.
8258///
8259/// If the two intances are different, set a bitfield to give some
8260/// insight about the kind of differences there are.
8261///
8262/// @param l the first artifact of the comparison.
8263///
8264/// @param r the second artifact of the comparison.
8265///
8266/// @param k a pointer to a bitfield that gives information about the
8267/// kind of changes there are between @p l and @p r. This one is set
8268/// iff @p k is non-null and the function returns false.
8269///
8270/// Please note that setting k to a non-null value does have a
8271/// negative performance impact because even if @p l and @p r are not
8272/// equal, the function keeps up the comparison in order to determine
8273/// the different kinds of ways in which they are different.
8274///
8275/// @return true if @p l equals @p r, false otherwise.
8276bool
8278{
8279 bool result = true;
8280
8281 if (!l.decl_base::operator==(r))
8282 {
8283 result = false;
8284 if (k)
8286 else
8288 }
8289
8290 scope_decl::declarations::const_iterator i, j;
8291 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8292 i != l.get_member_decls().end() && j != r.get_member_decls().end();
8293 ++i, ++j)
8294 {
8295 if (**i != **j)
8296 {
8297 result = false;
8298 if (k)
8299 {
8300 *k |= SUBTYPE_CHANGE_KIND;
8301 break;
8302 }
8303 else
8305 }
8306 }
8307
8308 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8309 {
8310 result = false;
8311 if (k)
8313 else
8315 }
8316
8317 ABG_RETURN(result);
8318}
8319
8320/// Return true iff both scopes have the same names and have the same
8321/// member decls.
8322///
8323/// This function doesn't check for equality of the scopes of its
8324/// arguments.
8325bool
8327{
8328 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8329 if (!other)
8330 return false;
8331
8332 return equals(*this, *other, 0);
8333}
8334
8335/// Equality operator for @ref scope_decl_sptr.
8336///
8337/// @param l the left hand side operand of the equality operator.
8338///
8339/// @pram r the right hand side operand of the equalify operator.
8340///
8341/// @return true iff @p l equals @p r.
8342bool
8344{
8345 if (!!l != !!r)
8346 return false;
8347 if (l.get() == r.get())
8348 return true;
8349 return *l == *r;
8350}
8351
8352/// Inequality operator for @ref scope_decl_sptr.
8353///
8354/// @param l the left hand side operand of the equality operator.
8355///
8356/// @pram r the right hand side operand of the equalify operator.
8357///
8358/// @return true iff @p l equals @p r.
8359bool
8361{return !operator==(l, r);}
8362
8363/// Find a member of the current scope and return an iterator on it.
8364///
8365/// @param decl the scope member to find.
8366///
8367/// @param i the iterator to set to the member @p decl. This is set
8368/// iff the function returns true.
8369///
8370/// @return true if the member decl was found, false otherwise.
8371bool
8373 declarations::iterator& i)
8374{
8375 if (!decl)
8376 return false;
8377
8378 if (get_member_decls().empty())
8379 {
8380 i = get_member_decls().end();
8381 return false;
8382 }
8383
8384 for (declarations::iterator it = get_member_decls().begin();
8385 it != get_member_decls().end();
8386 ++it)
8387 {
8388 if ((*it).get() == decl)
8389 {
8390 i = it;
8391 return true;
8392 }
8393 }
8394
8395 return false;
8396}
8397
8398/// Find a member of the current scope and return an iterator on it.
8399///
8400/// @param decl the scope member to find.
8401///
8402/// @param i the iterator to set to the member @p decl. This is set
8403/// iff the function returns true.
8404///
8405/// @return true if the member decl was found, false otherwise.
8406bool
8408 declarations::iterator& i)
8409{return find_iterator_for_member(decl.get(), i);}
8410
8411/// This implements the ir_traversable_base::traverse pure virtual
8412/// function.
8413///
8414/// @param v the visitor used on the current instance of scope_decl
8415/// and on its member nodes.
8416///
8417/// @return true if the traversal of the tree should continue, false
8418/// otherwise.
8419bool
8421{
8422 if (visiting())
8423 return true;
8424
8425 if (v.visit_begin(this))
8426 {
8427 visiting(true);
8428 for (scope_decl::declarations::const_iterator i =
8429 get_member_decls().begin();
8430 i != get_member_decls ().end();
8431 ++i)
8432 if (!(*i)->traverse(v))
8433 break;
8434 visiting(false);
8435 }
8436 return v.visit_end(this);
8437}
8438
8439scope_decl::~scope_decl()
8440{}
8441
8442/// Appends a declaration to a given scope, if the declaration
8443/// doesn't already belong to one and if the declaration is not for a
8444/// type that is supposed to be unique.
8445///
8446/// @param decl the declaration to add to the scope
8447///
8448/// @param scope the scope to append the declaration to
8449decl_base_sptr
8450add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8451{
8452 if (!scope)
8453 return decl;
8454
8455 if (scope && decl && !decl->get_scope())
8456 decl = scope->add_member_decl(decl);
8457
8458 return decl;
8459}
8460
8461/// Appends a declaration to a given scope, if the declaration doesn't
8462/// already belong to a scope.
8463///
8464/// @param decl the declaration to add append to the scope
8465///
8466/// @param scope the scope to append the decl to
8467decl_base_sptr
8468add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8469{return add_decl_to_scope(decl, scope.get());}
8470
8471/// Remove a given decl from its scope
8472///
8473/// @param decl the decl to remove from its scope.
8474void
8475remove_decl_from_scope(decl_base_sptr decl)
8476{
8477 if (!decl)
8478 return;
8479
8480 scope_decl* scope = decl->get_scope();
8481 scope->remove_member_decl(decl);
8482}
8483
8484/// Inserts a declaration into a given scope, before a given IR child
8485/// node of the scope.
8486///
8487/// @param decl the declaration to insert into the scope.
8488///
8489/// @param before an iterator pointing to the child IR node before
8490/// which to insert the declaration.
8491///
8492/// @param scope the scope into which to insert the declaration.
8493decl_base_sptr
8494insert_decl_into_scope(decl_base_sptr decl,
8495 scope_decl::declarations::iterator before,
8496 scope_decl* scope)
8497{
8498 if (scope && decl && !decl->get_scope())
8499 {
8500 decl_base_sptr d = scope->insert_member_decl(decl, before);
8501 decl = d;
8502 }
8503 return decl;
8504}
8505
8506/// Inserts a declaration into a given scope, before a given IR child
8507/// node of the scope.
8508///
8509/// @param decl the declaration to insert into the scope.
8510///
8511/// @param before an iterator pointing to the child IR node before
8512/// which to insert the declaration.
8513///
8514/// @param scope the scope into which to insert the declaration.
8515decl_base_sptr
8516insert_decl_into_scope(decl_base_sptr decl,
8517 scope_decl::declarations::iterator before,
8518 scope_decl_sptr scope)
8519{return insert_decl_into_scope(decl, before, scope.get());}
8520
8521/// Constructor of the @ref global_scope type.
8522///
8523/// @param tu the translation unit the scope belongs to.
8524global_scope::global_scope(translation_unit *tu)
8525 : type_or_decl_base(tu->get_environment(),
8526 GLOBAL_SCOPE_DECL
8527 | ABSTRACT_DECL_BASE
8528 | ABSTRACT_SCOPE_DECL),
8529 decl_base(tu->get_environment(), "", location()),
8530 scope_decl(tu->get_environment(), "", location()),
8531 translation_unit_(tu)
8532{
8533 runtime_type_instance(this);
8534}
8535
8536/// return the global scope as seen by a given declaration.
8537///
8538/// @param decl the declaration to consider.
8539///
8540/// @return the global scope of the decl, or a null pointer if the
8541/// decl is not yet added to a translation_unit.
8542const global_scope*
8544{
8545 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8546 return s;
8547
8548 scope_decl* scope = decl.get_scope();
8549 while (scope && !dynamic_cast<global_scope*>(scope))
8550 scope = scope->get_scope();
8551
8552 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8553}
8554
8555/// return the global scope as seen by a given declaration.
8556///
8557/// @param decl the declaration to consider.
8558///
8559/// @return the global scope of the decl, or a null pointer if the
8560/// decl is not yet added to a translation_unit.
8561const global_scope*
8563{return get_global_scope(*decl);}
8564
8565/// Return the global scope as seen by a given declaration.
8566///
8567/// @param decl the declaration to consider.
8568///
8569/// @return the global scope of the decl, or a null pointer if the
8570/// decl is not yet added to a translation_unit.
8571const global_scope*
8572get_global_scope(const shared_ptr<decl_base> decl)
8573{return get_global_scope(decl.get());}
8574
8575/// Return the a scope S containing a given declaration and that is
8576/// right under a given scope P.
8577///
8578/// Note that @p scope must come before @p decl in topological
8579/// order.
8580///
8581/// @param decl the decl for which to find a scope.
8582///
8583/// @param scope the scope under which the resulting scope must be.
8584///
8585/// @return the resulting scope.
8586const scope_decl*
8588 const scope_decl* scope)
8589{
8590 if (!decl)
8591 return 0;
8592
8593 if (scope == 0)
8594 return get_global_scope(decl);
8595
8596 // Handle the case where decl is a scope itself.
8597 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8598 if (!s)
8599 s = decl->get_scope();
8600
8601 if (is_global_scope(s))
8602 return scope;
8603
8604 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8605 // same. The caller needs to be prepared to deal with this case.
8606 if (s == scope)
8607 return s;
8608
8609 while (s && !is_global_scope(s) && s->get_scope() != scope)
8610 s = s->get_scope();
8611
8612 if (!s || is_global_scope(s))
8613 // SCOPE must come before decl in topological order, but I don't
8614 // know how to ensure that ...
8615 return scope;
8616 ABG_ASSERT(s);
8617
8618 return s;
8619}
8620
8621/// Return the a scope S containing a given declaration and that is
8622/// right under a given scope P.
8623///
8624/// @param decl the decl for which to find a scope.
8625///
8626/// @param scope the scope under which the resulting scope must be.
8627///
8628/// @return the resulting scope.
8629const scope_decl*
8630get_top_most_scope_under(const decl_base_sptr decl,
8631 const scope_decl* scope)
8632{return get_top_most_scope_under(decl.get(), scope);}
8633
8634/// Return the a scope S containing a given declaration and that is
8635/// right under a given scope P.
8636///
8637/// @param decl the decl for which to find a scope.
8638///
8639/// @param scope the scope under which the resulting scope must be.
8640///
8641/// @return the resulting scope.
8642const scope_decl*
8643get_top_most_scope_under(const decl_base_sptr decl,
8644 const scope_decl_sptr scope)
8645{return get_top_most_scope_under(decl, scope.get());}
8646
8647// </scope_decl stuff>
8648
8649
8650/// Get the string representation of a CV qualifier bitmap.
8651///
8652/// @param cv_quals the bitmap of CV qualifiers to consider.
8653///
8654/// @return the string representation.
8655string
8657{
8658 string repr;
8659 if (cv_quals & qualified_type_def::CV_RESTRICT)
8660 repr = "restrict";
8661 if (cv_quals & qualified_type_def::CV_CONST)
8662 {
8663 if (!repr.empty())
8664 repr += ' ';
8665 repr += "const";
8666 }
8667 if (cv_quals & qualified_type_def::CV_VOLATILE)
8668 {
8669 if (!repr.empty())
8670 repr += ' ';
8671 repr += "volatile";
8672 }
8673 return repr;
8674}
8675
8676/// Build and return a copy of the name of an ABI artifact that is
8677/// either a type or a decl.
8678///
8679/// @param tod the ABI artifact to get the name for.
8680///
8681/// @param qualified if yes, return the qualified name of @p tod;
8682/// otherwise, return the non-qualified name;
8683///
8684/// @return the name of @p tod.
8685string
8686get_name(const type_or_decl_base *tod, bool qualified)
8687{
8688 string result;
8689
8690 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8691
8692 if (type_base* t = dynamic_cast<type_base*>(a))
8693 result = get_type_name(t, qualified);
8694 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8695 {
8696 if (qualified)
8697 result = d->get_qualified_name();
8698 else
8699 result = d->get_name();
8700 }
8701 else
8702 // We should never reach this point.
8703 abort();
8704
8705 return result;
8706}
8707
8708/// Build and return a copy of the name of an ABI artifact that is
8709/// either a type of a decl.
8710///
8711/// @param tod the ABI artifact to get the name for.
8712///
8713/// @param qualified if yes, return the qualified name of @p tod;
8714/// otherwise, return the non-qualified name;
8715///
8716/// @return the name of @p tod.
8717string
8718get_name(const type_or_decl_base_sptr& tod, bool qualified)
8719{return get_name(tod.get(), qualified);}
8720
8721/// Build and return a qualified name from a name and its scope.
8722///
8723/// The name is supposed to be for an entity that is part of the
8724/// scope.
8725///
8726/// @param the scope to consider.
8727///
8728/// @param name of the name to consider.
8729///
8730/// @return a copy of the string that represents the qualified name.
8731string
8732build_qualified_name(const scope_decl* scope, const string& name)
8733{
8734 if (name.empty())
8735 return "";
8736
8737 string qualified_name;
8738 if (scope)
8739 qualified_name = scope->get_qualified_name();
8740
8741 if (qualified_name.empty())
8742 qualified_name = name;
8743 else
8744 qualified_name = qualified_name + "::" + name;
8745
8746 return qualified_name;
8747}
8748
8749/// Build and return the qualified name of a type in its scope.
8750///
8751/// @param scope the scope of the type to consider.
8752///
8753/// @param type the type to consider.
8754string
8755build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8756{return build_qualified_name(scope, get_name((type)));}
8757
8758// </scope_decl stuff>
8759
8760/// Get the location of the declaration of a given type.
8761///
8762/// @param type the type to consider.
8763///
8764/// @return the location of the declaration of type @p type.
8766get_location(const type_base_sptr& type)
8767{
8768 if (decl_base_sptr decl = get_type_declaration(type))
8769 return get_location(decl);
8770 return location();
8771}
8772
8773/// Get the location of a given declaration.
8774///
8775/// @param decl the declaration to consider.
8776///
8777/// @return the location of the declaration @p decl.
8779get_location(const decl_base_sptr& decl)
8780{
8781 location loc = decl->get_location();
8782 if (!loc)
8783 {
8784 if (class_or_union_sptr c = is_class_or_union_type(decl))
8785 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8786 {
8787 c = is_class_or_union_type(c->get_definition_of_declaration());
8788 loc = c->get_location();
8789 }
8790 }
8791 return loc;
8792}
8793
8794/// Get the scope of a given type.
8795///
8796/// @param t the type to consider.
8797///
8798/// @return the scope of type @p t or 0 if the type has no scope yet.
8801{
8802 if (!t)
8803 return 0;
8804
8806 if (d)
8807 return d->get_scope();
8808 return 0;
8809}
8810
8811/// Get the scope of a given type.
8812///
8813/// @param t the type to consider.
8814///
8815/// @return the scope of type @p t or 0 if the type has no scope yet.
8817get_type_scope(const type_base_sptr& t)
8818{return get_type_scope(t.get());}
8819
8820/// Get the name of a given type and return a copy of it.
8821///
8822/// @param t the type to consider.
8823///
8824/// @param qualified if true then return the qualified name of the
8825/// type.
8826///
8827/// @param internal set to true if the call is intended for an
8828/// internal use (for technical use inside the library itself), false
8829/// otherwise. If you don't know what this is for, then set it to
8830/// false.
8831///
8832/// @return a copy of the type name if the type has a name, or the
8833/// empty string if it does not.
8835get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8836{return get_type_name(t.get(), qualified, internal);}
8837
8838/// Return true iff a decl is for a type type that has a generic
8839/// anonymous internal type name.
8840///
8841/// @param d the decl to considier.
8842///
8843/// @return true iff @p d is for a type type that has a generic
8844/// anonymous internal type name.
8845static bool
8846has_generic_anonymous_internal_type_name(const decl_base *d)
8847{
8848 return (is_class_or_union_type(d)
8849 || is_enum_type(d)
8850 || is_subrange_type(d));
8851}
8852
8853/// Return the generic internal name of an anonymous type.
8854///
8855/// For internal purposes, we want to define a generic name for all
8856/// anonymous types of a certain kind. For instance, all anonymous
8857/// structs will be have a generic name of "__anonymous_struct__", all
8858/// anonymous unions will have a generic name of
8859/// "__anonymous_union__", etc.
8860///
8861/// That generic name can be used as a hash to put all anonymous types
8862/// of a certain kind in the same hash table bucket, for instance.
8863static interned_string
8864get_generic_anonymous_internal_type_name(const decl_base *d)
8865{
8866 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8867
8868 const environment&env = d->get_environment();
8869
8870 interned_string result;
8871 if (is_class_type(d))
8872 result =
8874 else if (is_union_type(d))
8875 result =
8877 else if (is_enum_type(d))
8878 result =
8880 else if (is_subrange_type(d))
8881 result =
8883 else
8885
8886 return result;
8887}
8888
8889/// Get the internal name for a given real type.
8890///
8891/// All real types that have the modifiers 'short, long or long
8892/// long' have the same internal name. This is so that they can all
8893/// have the same canonical type if they are of the same size.
8894/// Otherwise, 'long int' and 'long long int' would have different
8895/// canonical types even though they are equivalent from an ABI point
8896/// of view.
8897///
8898/// @param t the real type to consider
8899///
8900/// @return the internal name for @p t if it's an integral type, or
8901/// the empty string if @p t is not a real type.
8902static string
8903get_internal_real_type_name(const type_base* t)
8904{
8905 string name;
8906 type_decl *type = is_real_type(t);
8907
8908 if (!type)
8909 return name;
8910
8911 real_type int_type;
8912 if (parse_real_type(type->get_name(), int_type))
8913 name = int_type.to_string(/*internal=*/true);
8914
8915 return name;
8916}
8917
8918/// Get the name of a given type and return a copy of it.
8919///
8920/// @param t the type to consider.
8921///
8922/// @param qualified if true then return the qualified name of the
8923/// type.
8924///
8925/// @param internal set to true if the call is intended for an
8926/// internal use (for technical use inside the library itself), false
8927/// otherwise. If you don't know what this is for, then set it to
8928/// false.
8929///
8930/// @return a copy of the type name if the type has a name, or the
8931/// empty string if it does not.
8932interned_string
8933get_type_name(const type_base* t, bool qualified, bool internal)
8934{
8935 interned_string empty_string;
8936
8937 if (!t)
8938 return empty_string;
8939
8940 const decl_base* d = dynamic_cast<const decl_base*>(t);
8941 if (!d)
8942 {
8943 const function_type* fn_type = is_function_type(t);
8944 if (!fn_type)
8945 return empty_string;
8946 return fn_type->get_cached_name(internal);
8947 }
8948
8949 const environment&env = d->get_environment();
8950
8951 // All anonymous types of a given kind get to have the same internal
8952 // name for internal purpose. This to allow them to be compared
8953 // among themselves during type canonicalization.
8954 if (internal)
8955 {
8956 if (d->get_is_anonymous() && !is_type_decl(t))
8957 {
8958 // Note that anonymous type_decl that are used for
8959 // enumerators are not handled here because they don't have
8960 // generic internal type names.
8961 string r;
8962 r += get_generic_anonymous_internal_type_name(d);
8963 return t->get_environment().intern(r);
8964 }
8965
8966 if (is_typedef(t))
8967 return d->get_name();
8968
8969 if (qualified)
8970 return d->get_qualified_name(internal);
8971
8972 return env.intern(get_internal_real_type_name(t));
8973 }
8974
8975 if (d->get_is_anonymous())
8976 {
8978 return env.intern
8980 /*one_line=*/true,
8981 internal, qualified));
8982 }
8983
8984 if (qualified)
8985 return d->get_qualified_name(internal);
8986 return d->get_name();
8987}
8988
8989/// Get the name of a given type and return a copy of it.
8990///
8991/// @param t the type to consider.
8992///
8993/// @param qualified if true then return the qualified name of the
8994/// type.
8995///
8996/// @param internal set to true if the call is intended for an
8997/// internal use (for technical use inside the library itself), false
8998/// otherwise. If you don't know what this is for, then set it to
8999/// false.
9000///
9001/// @return a copy of the type name if the type has a name, or the
9002/// empty string if it does not.
9004get_type_name(const type_base& t, bool qualified, bool internal)
9005{return get_type_name(&t, qualified, internal);}
9006
9007/// Get the name of the pointer to a given type.
9008///
9009/// @param pointed_to_type the pointed-to-type to consider.
9010///
9011/// @param qualified this is true if the resulting name should be of a
9012/// pointer to a *fully-qualified* pointed-to-type.
9013///
9014/// @param internal true if the name is for libabigail-internal
9015/// purposes.
9016///
9017/// @return the name (string representation) of the pointer.
9020 bool qualified, bool internal)
9021{
9022 const environment& env = pointed_to_type.get_environment();
9023 string tn = get_type_name(pointed_to_type, qualified, internal);
9024 tn = tn + "*";
9025
9026 return env.intern(tn);
9027}
9028
9029/// Get the name of the reference to a given type.
9030///
9031/// @param pointed_to_type the pointed-to-type to consider.
9032///
9033/// @param qualified this is true if the resulting name should be of a
9034/// reference to a *fully-qualified* pointed-to-type.
9035///
9036/// @param internal true if the name is for libabigail-internal
9037/// purposes.
9038///
9039/// @return the name (string representation) of the reference.
9042 bool lvalue_reference,
9043 bool qualified, bool internal)
9044{
9045 const environment& env = pointed_to_type.get_environment();
9046
9047 string name = get_type_name(pointed_to_type, qualified, internal);
9048 if (lvalue_reference)
9049 name = name + "&";
9050 else
9051 name = name + "&&";
9052
9053 return env.intern(name);
9054}
9055
9056/// Get the name of a qualified type, given the underlying type and
9057/// its qualifiers.
9058///
9059/// @param underlying_type the underlying type to consider.
9060///
9061/// @param quals the CV qualifiers of the name.
9062///
9063/// @param qualified true if we should consider the fully qualified
9064/// name of @p underlying_type.
9065///
9066/// @param internal true if the result is to be used for
9067/// libabigail-internal purposes.
9068///
9069/// @return the name (string representation) of the qualified type.
9071get_name_of_qualified_type(const type_base_sptr& underlying_type,
9073 bool qualified, bool internal)
9074{
9075 const environment& env = underlying_type->get_environment();
9076
9077 string quals_repr = get_string_representation_of_cv_quals(quals);
9078 string name = get_type_name(underlying_type, qualified, internal);
9079
9080 if (quals_repr.empty() && internal)
9081 // We are asked to return the internal name, that might be used
9082 // for type canonicalization. For that canonicalization, we need
9083 // to make a difference between a no-op qualified type which
9084 // underlying type is foo (the qualified type is named "none
9085 // foo"), and the name of foo, which is just "foo".
9086 //
9087 // Please remember that this has to be kept in sync with what is
9088 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
9089 // change this code here, please change that code there too.
9090 quals_repr = "";
9091
9092 if (!quals_repr.empty())
9093 {
9094 if (is_pointer_type(peel_qualified_type(underlying_type))
9095 || is_reference_type(peel_qualified_type(underlying_type)))
9096 {
9097 name += " ";
9098 name += quals_repr;
9099 }
9100 else
9101 name = quals_repr + " " + name;
9102 }
9103
9104 return env.intern(name);
9105}
9106
9107/// Get the name of a given function type and return a copy of it.
9108///
9109/// @param fn_type the function type to consider.
9110///
9111/// @param internal set to true if the call is intended for an
9112/// internal use (for technical use inside the library itself), false
9113/// otherwise. If you don't know what this is for, then set it to
9114/// false.
9115///
9116/// @return a copy of the function type name
9119 bool internal)
9120{return get_function_type_name(fn_type.get(), internal);}
9121
9122/// Get the name of a given function type and return a copy of it.
9123///
9124/// @param fn_type the function type to consider.
9125///
9126/// @param internal set to true if the call is intended for an
9127/// internal use (for technical use inside the library itself), false
9128/// otherwise. If you don't know what this is for, then set it to
9129/// false.
9130///
9131/// @return a copy of the function type name
9134 bool internal)
9135{
9136 ABG_ASSERT(fn_type);
9137
9138 if (const method_type* method = is_method_type(fn_type))
9139 return get_method_type_name(method, internal);
9140
9141 return get_function_type_name(*fn_type, internal);
9142}
9143
9144/// Get the name of a given function type and return a copy of it.
9145///
9146/// @param fn_type the function type to consider.
9147///
9148/// @param internal set to true if the call is intended for an
9149/// internal use (for technical use inside the library itself), false
9150/// otherwise. If you don't know what this is for, then set it to
9151/// false.
9152///
9153/// @return a copy of the function type name
9156 bool internal)
9157{
9158 std::ostringstream o;
9159 // When the function name is used for internal purposes (e.g, for
9160 // canonicalization), we want its representation to stay the same,
9161 // regardless of typedefs. So let's strip typedefs from the return
9162 // type.
9163 type_base_sptr return_type = fn_type.get_return_type();
9164 const environment& env = fn_type.get_environment();
9165
9166 o << get_type_name(return_type, /*qualified=*/true, internal) << " ";
9167 stream_pretty_representation_of_fn_parms(fn_type, o,
9168 /*qualified=*/true,
9169 internal);
9170 return env.intern(o.str());
9171}
9172
9173/// Get the ID of a function, or, if the ID can designate several
9174/// different functions, get its pretty representation.
9175///
9176/// @param fn the function to consider
9177///
9178/// @return the function ID of pretty representation of @p fn.
9181{
9182 ABG_ASSERT(fn);
9183
9184 interned_string result = fn->get_environment().intern(fn->get_id());
9185
9186 if (const corpus *c = fn->get_corpus())
9187 {
9189 c->get_exported_decls_builder();
9190 if (b->fn_id_maps_to_several_fns(fn))
9191 result = fn->get_environment().intern(fn->get_pretty_representation());
9192 }
9193
9194 return result;
9195}
9196
9197/// Get the name of a given method type and return a copy of it.
9198///
9199/// @param fn_type the function type to consider.
9200///
9201/// @param internal set to true if the call is intended for an
9202/// internal use (for technical use inside the library itself), false
9203/// otherwise. If you don't know what this is for, then set it to
9204/// false.
9205///
9206/// @return a copy of the function type name
9209 bool internal)
9210{return get_method_type_name(fn_type.get(), internal);}
9211
9212/// Get the name of a given method type and return a copy of it.
9213///
9214/// @param fn_type the function type to consider.
9215///
9216/// @param internal set to true if the call is intended for an
9217/// internal use (for technical use inside the library itself), false
9218/// otherwise. If you don't know what this is for, then set it to
9219/// false.
9220///
9221/// @return a copy of the function type name
9224 bool internal)
9225{
9226 if (fn_type)
9227 return get_method_type_name(*fn_type, internal);
9228
9229 return interned_string();
9230}
9231
9232/// Get the name of a given method type and return a copy of it.
9233///
9234/// @param fn_type the function type to consider.
9235///
9236/// @param internal set to true if the call is intended for an
9237/// internal use (for technical use inside the library itself), false
9238/// otherwise. If you don't know what this is for, then set it to
9239/// false.
9240///
9241/// @return a copy of the function type name
9244 bool internal)
9245{
9246 std::ostringstream o;
9247 // When the function name is used for internal purposes (e.g, for
9248 // canonicalization), we want its representation to stay the same,
9249 // regardless of typedefs. So let's strip typedefs from the return
9250 // type.
9251 type_base_sptr return_type = fn_type.get_return_type();
9252
9253 const environment& env = fn_type.get_environment();
9254
9255 if (return_type)
9256 o << get_type_name(return_type, /*qualified=*/true, internal);
9257 else
9258 // There are still some abixml files out there in which "void"
9259 // can be expressed as an empty type.
9260 o << "void";
9261
9262 class_or_union_sptr class_type = fn_type.get_class_type();
9263 ABG_ASSERT(class_type);
9264
9265 o << " (" << class_type->get_qualified_name(internal) << "::*) ";
9266 stream_pretty_representation_of_fn_parms(fn_type, o,
9267 /*qualified=*/true,
9268 internal);
9269
9270 return env.intern(o.str());
9271}
9272
9273/// Build and return a copy of the pretty representation of an ABI
9274/// artifact that could be either a type of a decl.
9275///
9276/// param tod the ABI artifact to consider.
9277///
9278/// @param internal set to true if the call is intended for an
9279/// internal use (for technical use inside the library itself), false
9280/// otherwise. If you don't know what this is for, then set it to
9281/// false.
9282///
9283/// @return a copy of the pretty representation of an ABI artifact
9284/// that could be either a type of a decl.
9285string
9287{
9288 string result;
9289
9290 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9291 result = get_pretty_representation(t, internal);
9292 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9293 result = get_pretty_representation(d, internal);
9294 else
9295 // We should never reach this point
9296 abort();
9297
9298 return result;
9299}
9300
9301/// Build and return a copy of the pretty representation of an ABI
9302/// artifact that could be either a type of a decl.
9303///
9304/// param tod the ABI artifact to consider.
9305///
9306/// @param internal set to true if the call is intended for an
9307/// internal use (for technical use inside the library itself), false
9308/// otherwise. If you don't know what this is for, then set it to
9309/// false.
9310///
9311/// @return a copy of the pretty representation of an ABI artifact
9312/// that could be either a type of a decl.
9313string
9315{return get_pretty_representation(tod.get(), internal);}
9316
9317/// Get a copy of the pretty representation of a decl.
9318///
9319/// @param d the decl to consider.
9320///
9321/// @param internal set to true if the call is intended for an
9322/// internal use (for technical use inside the library itself), false
9323/// otherwise. If you don't know what this is for, then set it to
9324/// false.
9325///
9326/// @return the pretty representation of the decl.
9327string
9328get_pretty_representation(const decl_base* d, bool internal)
9329{
9330 if (!d)
9331 return "";
9332 return d->get_pretty_representation(internal);
9333}
9334
9335/// Get a copy of the pretty representation of a type.
9336///
9337/// @param d the type to consider.
9338///
9339/// @param internal set to true if the call is intended for an
9340/// internal use (for technical use inside the library itself), false
9341/// otherwise. If you don't know what this is for, then set it to
9342/// false.
9343///
9344/// @return the pretty representation of the type.
9345string
9346get_pretty_representation(const type_base* t, bool internal)
9347{
9348 if (!t)
9349 return "void";
9350 if (const function_type* fn_type = is_function_type(t))
9351 return get_pretty_representation(fn_type, internal);
9352
9353 const decl_base* d = get_type_declaration(t);
9354 ABG_ASSERT(d);
9355 return get_pretty_representation(d, internal);
9356}
9357
9358/// Get a copy of the pretty representation of a decl.
9359///
9360/// @param d the decl to consider.
9361///
9362/// @param internal set to true if the call is intended for an
9363/// internal use (for technical use inside the library itself), false
9364/// otherwise. If you don't know what this is for, then set it to
9365/// false.
9366///
9367/// @return the pretty representation of the decl.
9368string
9369get_pretty_representation(const decl_base_sptr& d, bool internal)
9370{return get_pretty_representation(d.get(), internal);}
9371
9372/// Get a copy of the pretty representation of a type.
9373///
9374/// @param d the type to consider.
9375///
9376/// @param internal set to true if the call is intended for an
9377/// internal use (for technical use inside the library itself), false
9378/// otherwise. If you don't know what this is for, then set it to
9379/// false.
9380///
9381/// @return the pretty representation of the type.
9382string
9383get_pretty_representation(const type_base_sptr& t, bool internal)
9384{return get_pretty_representation(t.get(), internal);}
9385
9386/// Get the pretty representation of a function type.
9387///
9388/// @param fn_type the function type to consider.
9389///
9390/// @param internal set to true if the call is intended for an
9391/// internal use (for technical use inside the library itself), false
9392/// otherwise. If you don't know what this is for, then set it to
9393/// false.
9394///
9395/// @return the string represenation of the function type.
9396string
9398 bool internal)
9399{return get_pretty_representation(fn_type.get(), internal);}
9400
9401/// Get the pretty representation of a function type.
9402///
9403/// @param fn_type the function type to consider.
9404///
9405/// @param internal set to true if the call is intended for an
9406/// internal use (for technical use inside the library itself), false
9407/// otherwise. If you don't know what this is for, then set it to
9408/// false.
9409///
9410/// @return the string represenation of the function type.
9411string
9412get_pretty_representation(const function_type* fn_type, bool internal)
9413{
9414 if (!fn_type)
9415 return "void";
9416
9417 if (const method_type* method = is_method_type(fn_type))
9418 return get_pretty_representation(method, internal);
9419
9420 return get_pretty_representation(*fn_type, internal);
9421}
9422
9423/// Get the pretty representation of a function type.
9424///
9425/// @param fn_type the function type to consider.
9426///
9427/// @param internal set to true if the call is intended for an
9428/// internal use (for technical use inside the library itself), false
9429/// otherwise. If you don't know what this is for, then set it to
9430/// false.
9431///
9432/// @return the string represenation of the function type.
9433string
9434get_pretty_representation(const function_type& fn_type, bool internal)
9435{
9436 std::ostringstream o;
9437 o << "function type " << get_function_type_name(fn_type, internal);
9438 return o.str();
9439}
9440
9441/// Get the pretty representation of a method type.
9442///
9443/// @param method the method type to consider.
9444///
9445/// @param internal set to true if the call is intended for an
9446/// internal use (for technical use inside the library itself), false
9447/// otherwise. If you don't know what this is for, then set it to
9448/// false.
9449///
9450/// @return the string represenation of the method type.
9451string
9452get_pretty_representation(const method_type& method, bool internal)
9453{
9454 std::ostringstream o;
9455 o << "method type " << get_method_type_name(method, internal);
9456 return o.str();
9457}
9458
9459/// Get the pretty representation of a method type.
9460///
9461/// @param method the method type to consider.
9462///
9463/// @param internal set to true if the call is intended for an
9464/// internal use (for technical use inside the library itself), false
9465/// otherwise. If you don't know what this is for, then set it to
9466/// false.
9467///
9468/// @return the string represenation of the method type.
9469string
9470get_pretty_representation(const method_type* method, bool internal)
9471{
9472 if (!method)
9473 return "void";
9474 return get_pretty_representation(*method, internal);
9475}
9476
9477/// Get the pretty representation of a method type.
9478///
9479/// @param method the method type to consider.
9480///
9481/// @param internal set to true if the call is intended for an
9482/// internal use (for technical use inside the library itself), false
9483/// otherwise. If you don't know what this is for, then set it to
9484/// false.
9485///
9486/// @return the string represenation of the method type.
9487string
9489{return get_pretty_representation(method.get(), internal);}
9490
9491/// Get the flat representation of an instance of @ref class_or_union
9492/// type.
9493///
9494/// The flat representation of a given @ref class_or_union type is the
9495/// actual definition of the type, for instance:
9496///
9497/// struct foo {int a; char b;}
9498///
9499///@param cou the instance of @ref class_or_union to consider.
9500///
9501///@param indent the identation spaces to use in the representation.
9502///
9503///@param one_line if true, then the flat representation stands on one
9504///line. Otherwise, it stands on multiple lines.
9505///
9506///@return the resulting flat representation.
9507string
9509 const string& indent,
9510 bool one_line,
9511 bool internal,
9512 bool qualified_names)
9513{
9514 string repr;
9515 string local_indent = " ";
9516
9517 if (class_decl* clazz = is_class_type(&cou))
9518 {
9519 repr = indent;
9520 if (!internal && clazz->is_struct())
9521 repr += "struct";
9522 else
9523 repr += "class";
9524 }
9525 else if (is_union_type(cou))
9526 repr = indent + "union";
9527 else
9528 return "";
9529
9530 repr += " ";
9531
9532 string name = cou.get_qualified_name();
9533
9534 if (!cou.get_is_anonymous())
9535 repr += name;
9536
9537 if (cou.priv_->is_printing_flat_representation())
9538 {
9539 // We have just detected a cycle while walking the sub-tree
9540 // of this class or union type for the purpose of printing
9541 // its flat representation. We need to get out of here
9542 // pronto or else we'll be spinning endlessly.
9543 repr += "{}";
9544 return repr;
9545 }
9546
9547 // Let's mark this class or union type to signify that we started
9548 // walking its sub-tree. This is to detect potential cycles and
9549 // avoid looping endlessly.
9551
9552 repr += "{";
9553
9554 if (!one_line)
9555 repr += "\n";
9556
9557 string real_indent;
9559 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9560 dm != dmems.end();
9561 ++dm)
9562 {
9563 if (dm != dmems.begin())
9564 {
9565 if (one_line)
9566 real_indent = " ";
9567 else
9568 real_indent = "\n" + indent + local_indent;
9569 }
9570
9572 repr +=
9575 real_indent, one_line, internal, qualified_names);
9576 else
9577 {
9578 if (one_line)
9579 {
9580 if (dm != dmems.begin())
9581 repr += real_indent;
9582 repr += (*dm)->get_pretty_representation(internal,
9583 qualified_names);
9584 }
9585 else
9586 repr +=
9587 real_indent+ (*dm)->get_pretty_representation(internal,
9588 qualified_names);
9589 }
9590 repr += ";";
9591 }
9592
9593 if (one_line)
9594 repr += "}";
9595 else
9596 repr += indent + "}";
9597
9598 // Let's unmark this class or union type to signify that we are done
9599 // walking its sub-tree. This was to detect potential cycles and
9600 // avoid looping endlessly.
9602
9603 return repr;
9604}
9605
9606/// Get the flat representation of an instance of @ref class_or_union
9607/// type.
9608///
9609/// The flat representation of a given @ref class_or_union type is the
9610/// actual definition of the type, for instance:
9611///
9612/// struct foo {int a; char b;}
9613///
9614///@param cou the instance of @ref class_or_union to consider.
9615///
9616///@param indent the identation spaces to use in the representation.
9617///
9618///@param one_line if true, then the flat representation stands on one
9619///line. Otherwise, it stands on multiple lines.
9620///
9621///@return the resulting flat representation.
9622string
9624 const string& indent,
9625 bool one_line,
9626 bool internal,
9627 bool qualified_names)
9628{
9629 if (cou)
9630 return get_class_or_union_flat_representation(*cou, indent, one_line,
9631 internal, qualified_names);
9632 return "";
9633}
9634
9635/// Get the flat representation of an instance of @ref class_or_union
9636/// type.
9637///
9638/// The flat representation of a given @ref class_or_union type is the
9639/// actual definition of the type, for instance:
9640///
9641/// struct foo {int a; char b;}
9642///
9643///@param cou the instance of @ref class_or_union to consider.
9644///
9645///@param indent the identation spaces to use in the representation.
9646///
9647///@param one_line if true, then the flat representation stands on one
9648///line. Otherwise, it stands on multiple lines.
9649///
9650///@return the resulting flat representation.
9651string
9652get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9653 const string& indent,
9654 bool one_line,
9655 bool internal,
9656 bool qualified_names)
9658 indent,
9659 one_line,
9660 internal,
9661 qualified_names);}
9662
9663/// Get the flat representation of an instance of @ref enum_type_decl
9664/// type.
9665///
9666/// The flat representation of a given @ref enum_type_decl type is the
9667/// actual definition of the type, for instance:
9668///
9669/// enum {E_0 =0, E_1 = 1}
9670///
9671///@param enum_type the enum type to consider.
9672///
9673///@param indent the identation spaces to use in the representation.
9674///
9675///@param one_line if true, then the flat representation stands on one
9676///line. Otherwise, it stands on multiple lines.
9677///
9678///@param qualified_names use qualified names when applicable.
9679///Typically, if this is true, the name of the enum is going to be
9680///qualified.
9681///
9682///@return the resulting flat representation.
9683string
9685 const string& indent, bool one_line,
9686 bool qualified_names)
9687{
9688 string repr;
9689 std::ostringstream o;
9690 string local_indent = " ";
9691
9692 repr = indent + "enum ";
9693
9694 if (!enum_type.get_is_anonymous())
9695 o << (qualified_names
9696 ? enum_type.get_qualified_name()
9697 : enum_type.get_name()) + " ";
9698
9699 o << "{";
9700
9701 if (!one_line)
9702 o << "\n";
9703
9704 for (const auto &enumerator : enum_type.get_sorted_enumerators())
9705 {
9706 if (!one_line)
9707 o << "\n" + indent;
9708
9709 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
9710 }
9711
9712 if (!one_line)
9713 o << "\n" + indent << "}";
9714 else
9715 o << "}";
9716
9717 repr =o.str();
9718
9719 return repr;
9720}
9721
9722/// Get the flat representation of an instance of @ref enum_type_decl
9723/// type.
9724///
9725/// The flat representation of a given @ref enum_type_decl type is the
9726/// actual definition of the type, for instance:
9727///
9728/// enum {E_0 =0, E_1 = 1}
9729///
9730///@param enum_type the enum type to consider.
9731///
9732///@param indent the identation spaces to use in the representation.
9733///
9734///@param one_line if true, then the flat representation stands on one
9735///line. Otherwise, it stands on multiple lines.
9736///
9737///@param qualified_names use qualified names when applicable.
9738///Typically, if this is true, the name of the enum is going to be
9739///qualified.
9740///
9741///@return the resulting flat representation.
9742string
9744 const string& indent, bool one_line,
9745 bool qualified_names)
9746{
9747 if (!enum_type)
9748 return "";
9749
9750 return get_enum_flat_representation(*enum_type, indent,
9751 one_line, qualified_names);
9752}
9753
9754/// Get the flat representation of an instance of @ref enum_type_decl
9755/// type.
9756///
9757/// The flat representation of a given @ref enum_type_decl type is the
9758/// actual definition of the type, for instance:
9759///
9760/// enum {E_0 =0, E_1 = 1}
9761///
9762///@param enum_type the enum type to consider.
9763///
9764///@param indent the identation spaces to use in the representation.
9765///
9766///@param one_line if true, then the flat representation stands on one
9767///line. Otherwise, it stands on multiple lines.
9768///
9769///@param qualified_names use qualified names when applicable.
9770///Typically, if this is true, the name of the enum is going to be
9771///qualified.
9772///
9773///@return the resulting flat representation.
9774string
9776 const string& indent, bool one_line,
9777 bool qualified_names)
9778{
9779 return get_enum_flat_representation(enum_type.get(),
9780 indent, one_line,
9781 qualified_names);
9782}
9783
9784/// Get the flat representation of an instance of @ref enum_type_decl
9785/// type.
9786///
9787/// The flat representation of a given @ref enum_type_decl type is the
9788/// actual definition of the type, for instance:
9789///
9790/// enum {E_0 =0, E_1 = 1}
9791///
9792///@param enum_type the enum type to consider.
9793///
9794///@param indent the identation spaces to use in the representation.
9795///
9796///@param one_line if true, then the flat representation stands on one
9797///line. Otherwise, it stands on multiple lines.
9798///
9799///@param qualified_names use qualified names when applicable.
9800///Typically, if this is true, the name of the enum is going to be
9801///qualified.
9802///
9803///@return the resulting flat representation.
9804string
9806 const string& indent,
9807 bool one_line,
9808 bool internal,
9809 bool qualified_name)
9810
9811{
9812 string repr;
9813 if (const class_or_union* cou = is_class_or_union_type(&coe))
9814 repr = get_class_or_union_flat_representation(cou, indent, one_line,
9815 internal, qualified_name);
9816 else if (const enum_type_decl* enom = is_enum_type(&coe))
9817 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9818
9819 return repr;
9820}
9821
9822/// Get the textual representation of a type for debugging purposes.
9823///
9824/// If the type is a class/union, this shows the data members, virtual
9825/// member functions, size, pointer value of its canonical type, etc.
9826/// Otherwise, this just shows the name of the artifact as returned by
9827/// type_or_decl_base:get_pretty_representation().
9828///
9829/// @param artifact the artifact to show a debugging representation of.
9830///
9831/// @return a debugging string representation of @p artifact.
9832string
9834{
9835 string nil_str;
9836 if (!artifact)
9837 return nil_str;
9838
9839 class_or_union * c = is_class_or_union_type(artifact);
9840 if (c)
9841 {
9842 class_decl *clazz = is_class_type(c);
9843 string name = c->get_qualified_name();
9844 std::ostringstream o;
9845 if (clazz)
9846 {
9847 if (clazz->is_struct())
9848 o << "struct ";
9849 else
9850 o << "class ";
9851 }
9852 else if (is_union_type(c))
9853 o << "union ";
9854 o << name;
9855
9856 if (clazz)
9857 {
9858 if (!clazz->get_base_specifiers().empty())
9859 o << " :" << std::endl;
9860 for (auto &b : clazz->get_base_specifiers())
9861 {
9862 o << " ";
9863 if (b->get_is_virtual())
9864 o << "virtual ";
9865 o << b->get_base_class()->get_qualified_name()
9866 << " // hash: ";
9867 hash_t h = peek_hash_value(*b->get_base_class());
9868 if (h)
9869 o << std::hex << *h << std::dec;
9870 else
9871 o << "none";
9872 o << std::endl;
9873 }
9874 }
9875 o << std::endl
9876 << "{"
9877 << " // size in bits: " << c->get_size_in_bits() << "\n"
9878 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9879 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9880 << " // translation unit: "
9881 << (c->get_translation_unit()
9883 : nil_str)
9884 << std::endl
9885 << " // @: " << std::hex << is_type(c)
9886 << ", @canonical: " << c->get_canonical_type().get() << std::dec << "\n"
9887 << " // hash: " ;
9888
9889 hash_t h = peek_hash_value(*c);
9890 if (h)
9891 o << std::hex << *h << std::dec;
9892 else
9893 o << "none";
9894 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*c);
9895 o << "\n\n";
9896
9897
9898 for (auto member_type : c->get_sorted_member_types())
9899 {
9900 o << " "
9901 << member_type->get_pretty_representation(/*internal=*/false,
9902 /*qualified=*/false)
9903 << ";";
9904 if (member_type->get_canonical_type())
9905 {
9906 o << " // uses canonical type: '@"
9907 << std::hex << member_type->get_canonical_type().get() << "'";
9908 o << " / h:";
9909 hash_t h = peek_hash_value(*member_type);
9910 o << std::hex << *h << std::dec;
9911 if (get_canonical_type_index(*member_type))
9912 o << "#" << get_canonical_type_index(*member_type);
9913 }
9914 o << "\n";
9915 }
9916
9917 if (!c->get_sorted_member_types().empty())
9918 o << std::endl;
9919
9920 for (auto m : c->get_data_members())
9921 {
9922 type_base_sptr t = m->get_type();
9924
9925 o << " "
9926 << m->get_pretty_representation(/*internal=*/false,
9927 /*qualified=*/false)
9928 << ";";
9929
9930 if (t && t->get_canonical_type())
9931 o << " // uses canonical type '@"
9932 << std::hex << t->get_canonical_type().get() << "'";
9933
9934 o << "/ h:";
9935 hash_t h = peek_hash_value(*m->get_type());
9936 if (h)
9937 o << std::hex << *h << std::dec;
9938 else
9939 o << "none";
9940 o << std::endl;
9941 }
9942
9943 if (!c->get_data_members().empty())
9944 o << std::endl;
9945
9946 if (clazz && clazz->has_vtable())
9947 {
9948 o << " // virtual member functions\n\n";
9949 for (auto f : clazz->get_virtual_mem_fns())
9950 {
9951 o << " " << f->get_pretty_representation(/*internal=*/false,
9952 /*qualified=*/false)
9953 << " // voffset: " << get_member_function_vtable_offset(f)
9954 << ", h: ";
9955 hash_t h = peek_hash_value(*f->get_type());
9956 if (h)
9957 o << std::hex << *h << std::dec;
9958 else
9959 o << "none";
9960 o << ";" << std::endl;
9961 }
9962 }
9963
9964 o << "};" << std::endl;
9965
9966 return o.str();
9967 }
9968 else if (const enum_type_decl* e = is_enum_type(artifact))
9969 {
9970 string name = e->get_qualified_name();
9971 std::ostringstream o;
9972 o << "enum " << name
9973 << " : "
9974 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9975 true)
9976 << "\n"
9977 << "{\n"
9978 << " // size in bits: " << e->get_size_in_bits() << "\n"
9979 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9980 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9981 << " // translation unit: "
9982 << e->get_translation_unit()->get_absolute_path() << "\n"
9983 << " // @: " << std::hex << is_type(e)
9984 << ", @canonical: " << e->get_canonical_type().get() << std::dec << "\n"
9985 << " // hash: ";
9986
9987 hash_t h = peek_hash_value(*e);
9988 if (h)
9989 o << std::hex << *h << std::dec;
9990 else
9991 o << "none";
9992 o << "\n" << " // cti: " << std::dec << get_canonical_type_index(*e);
9993 o << "\n\n";
9994
9995 for (const auto &enom : e->get_enumerators())
9996 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9997
9998 o << "};\n";
9999
10000 return o.str();
10001 }
10002 else if (type_base *t = is_type(artifact))
10003 {
10004 std::ostringstream o;
10005 o << t->get_pretty_representation(/*internal=*/true,
10006 /*qualified=*/true)
10007 << " // cti: " << get_canonical_type_index(*t)
10008 << "\n";
10009 return o.str();
10010 }
10011
10012 return artifact->get_pretty_representation(/*internal=*/true,
10013 /*qualified=*/true);
10014}
10015
10016/// Get a given data member, referred to by its name, of a class type.
10017///
10018/// @param clazz the class to consider.
10019///
10020/// @param member_name name of the data member to get.
10021///
10022/// @return the resulting data member or nullptr if none was found.
10024get_data_member(class_or_union *clazz, const char* member_name)
10025{
10026 if (!clazz)
10027 return var_decl_sptr();
10028 return clazz->find_data_member(member_name);
10029}
10030
10031/// Get a given data member, referred to by its name, of a class type.
10032///
10033/// @param clazz the class to consider.
10034///
10035/// @param member_name name of the data member to get.
10036///
10037/// @return the resulting data member or nullptr if none was found.
10039get_data_member(type_base *clazz, const char* member_name)
10040{return get_data_member(is_class_or_union_type(clazz), member_name);}
10041
10042/// Get the non-artificial (natural) location of a decl.
10043///
10044/// If the decl doesn't have a natural location then return its
10045/// artificial one.
10046///
10047/// @param decl the decl to consider.
10048///
10049/// @return the natural location @p decl if it has one; otherwise,
10050/// return its artificial one.
10051const location&
10053{
10054 ABG_ASSERT(decl);
10055
10056 if (decl->get_location())
10057 return decl->get_location();
10058 return decl->get_artificial_location();
10059}
10060
10061/// Get the artificial location of a decl.
10062///
10063/// If the decl doesn't have an artificial location then return its
10064/// natural one.
10065///
10066/// @param decl the decl to consider.
10067///
10068/// @return the artificial location @p decl if it has one; otherwise,
10069/// return its natural one.
10070const location&
10072{
10073 ABG_ASSERT(decl);
10074
10075 if (decl->has_artificial_location())
10076 return decl->get_artificial_location();
10077 return decl->get_location();
10078}
10079
10080/// Emit a textual representation of an artifact to std error stream
10081/// for debugging purposes.
10082///
10083/// This is useful to invoke from within a command line debugger like
10084/// GDB to help make sense of a given ABI artifact.
10085///
10086/// @param artifact the ABI artifact to emit the debugging
10087/// representation for.
10088///
10089/// @return the artifact @p artifact.
10091debug(const type_or_decl_base* artifact)
10092{
10093 std::cerr << get_debug_representation(artifact) << std::endl;
10094 return const_cast<type_or_decl_base*>(artifact);
10095}
10096
10097/// Emit a textual representation of an artifact to std error stream
10098/// for debugging purposes.
10099///
10100/// This is useful to invoke from within a command line debugger like
10101/// GDB to help make sense of a given ABI artifact.
10102///
10103/// @param artifact the ABI artifact to emit the debugging
10104/// representation for.
10105///
10106/// @return the artifact @p artifact.
10107type_base*
10108debug(const type_base* artifact)
10109{
10110 debug(static_cast<const type_or_decl_base*>(artifact));
10111 return const_cast<type_base*>(artifact);
10112}
10113
10114/// Emit a textual representation of an artifact to std error stream
10115/// for debugging purposes.
10116///
10117/// This is useful to invoke from within a command line debugger like
10118/// GDB to help make sense of a given ABI artifact.
10119///
10120/// @param artifact the ABI artifact to emit the debugging
10121/// representation for.
10122///
10123/// @return the artifact @p artifact.
10124decl_base*
10125debug(const decl_base* artifact)
10126{
10127 debug(static_cast<const type_or_decl_base*>(artifact));
10128 return const_cast<decl_base*>(artifact);
10129}
10130
10131/// Test if two ABI artifacts are equal.
10132///
10133/// This can be useful when used from the command line of a debugger
10134/// like GDB.
10135///
10136/// @param l the first ABI artifact to consider in the comparison.
10137///
10138/// @param r the second ABI artifact to consider in the comparison.
10139///
10140/// @return true iff @p l equals @p r.
10141bool
10143{
10144 if (!!l != !!r)
10145 return false;
10146 if (!l && !r)
10147 return true;
10148
10149 return (*l == *r);
10150}
10151
10152/// Emit a trace of a comparison operand stack.
10153///
10154/// @param vect the operand stack to emit the trace for.
10155///
10156/// @param o the output stream to emit the trace to.
10157static void
10158debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
10159{
10160 for (auto t : vect)
10161 {
10162 o << "|" << t->get_pretty_representation()
10163 << "@" << std::hex << t << std::dec;
10164 }
10165 if (!vect.empty())
10166 o << "|";
10167}
10168
10169/// Construct a trace of the two comparison operand stacks.
10170///
10171/// @param the environment in which the comparison operand stacks are.
10172///
10173/// @return a string representing the trace.
10174static string
10175print_comp_stack(const environment& env)
10176{
10177 std::ostringstream o;
10178 o << "left-operands: ";
10179 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
10180 o << "\n" << "right-operands: ";
10181 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10182 o << "\n";
10183 return o.str();
10184}
10185
10186/// Emit a trace of the two comparison operands stack on the standard
10187/// error stream.
10188///
10189/// @param env the environment the comparison operands stack belong
10190/// to.
10191void
10193{
10194 std::cerr << print_comp_stack(env);
10195 std::cerr << std::endl;
10196}
10197
10198/// By looking at the language of the TU a given ABI artifact belongs
10199/// to, test if the ONE Definition Rule should apply.
10200///
10201/// To date, it applies to c++, java and ada.
10202///
10203/// @param artifact the ABI artifact to consider.
10204///
10205/// @return true iff the One Definition Rule should apply.
10206bool
10208{
10209 if (!artifact.get_translation_unit())
10210 return false;
10211
10213 artifact.get_translation_unit()->get_language();
10214
10216 || is_java_language(l)
10217 || is_ada_language(l))
10218 return true;
10219
10220 return false;
10221}
10222
10223/// Get the declaration for a given type.
10224///
10225/// @param t the type to consider.
10226///
10227/// @return the declaration for the type to return.
10228const decl_base*
10230{return dynamic_cast<const decl_base*>(t);}
10231
10232/// Get the declaration for a given type.
10233///
10234/// @param t the type to consider.
10235///
10236/// @return the declaration for the type to return.
10237decl_base*
10239{return dynamic_cast<decl_base*>(t);}
10240
10241/// Get the declaration for a given type.
10242///
10243/// @param t the type to consider.
10244///
10245/// @return the declaration for the type to return.
10246decl_base_sptr
10247get_type_declaration(const type_base_sptr t)
10248{return dynamic_pointer_cast<decl_base>(t);}
10249
10250/// Test if two classes have the same layout.
10251///
10252/// Test if all the types and offsets of the members are equal,
10253/// regardless of their access modifiers.
10254///
10255/// @param f the first class to take into account.
10256///
10257/// @param s the second class to take into account.
10258///
10259/// @return true iff @p s and @p f are class types with the same
10260/// layout.
10261bool
10262classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
10263{
10264#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10265#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10266#endif
10267
10268#ifdef ENSURE_NO_ENDLESS_LOOP
10269#undef ENSURE_NO_ENDLESS_LOOP
10270#endif
10271
10272#define RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(VALUE) \
10273 do \
10274 { \
10275 auto t1 = is_class_or_union_type(f); \
10276 auto t2 = is_class_or_union_type(s); \
10277 t1->priv_->comparing_class_layouts_.erase(t2.get()); \
10278 t2->priv_->comparing_class_layouts_.erase(t1.get()); \
10279 return VALUE; \
10280 } while (false)
10281
10282#define ENSURE_NO_ENDLESS_LOOP \
10283 do \
10284 { \
10285 auto t1 = is_class_or_union_type(f); \
10286 auto t2 = is_class_or_union_type(s); \
10287 const auto& END = t1->priv_->comparing_class_layouts_.end(); \
10288 if (t1->priv_->comparing_class_layouts_.find(t2.get()) != END \
10289 || t2->priv_->comparing_class_layouts_.find(t1.get()) != END) \
10290 return true; \
10291 t1->priv_->comparing_class_layouts_.insert(t2.get()); \
10292 t2->priv_->comparing_class_layouts_.insert(t1.get()); \
10293 } while (false)
10294
10297
10298 if (!fc
10299 || !sc
10300 || (fc->get_qualified_name() != sc->get_qualified_name())
10301 || (fc->get_size_in_bits() != sc->get_size_in_bits())
10302 || (fc->get_data_members().size() != sc->get_data_members().size()))
10303 return false;
10304
10305 if (*fc == *sc)
10306 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
10307
10308 // Compare the types and offsets of data members one by one.
10309 for (auto f_decl_it = fc->get_data_members().begin(),
10310 s_decl_it = sc->get_data_members().begin();
10311 (f_decl_it != fc->get_data_members().end()
10312 && s_decl_it != sc->get_data_members().end());
10313 ++f_decl_it, ++s_decl_it)
10314 {
10315 var_decl_sptr dm1 = *f_decl_it, dm2 = *s_decl_it;
10316 type_base_sptr dm1_type = dm1->get_type(), dm2_type = dm2->get_type();
10317
10318 if (*dm1_type != *dm2_type
10320 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10321 }
10322
10323 // Compare the layout of base types
10324 for (auto f_bs_it = fc->get_base_specifiers().begin(),
10325 s_bs_it = sc->get_base_specifiers().end();
10326 (f_bs_it != fc->get_base_specifiers().end()
10327 && s_bs_it != sc->get_base_specifiers().end());
10328 ++f_bs_it, ++s_bs_it)
10329 {
10330 class_decl::base_spec_sptr f_bs = *f_bs_it, s_bs = *s_bs_it;
10331 if ((f_bs->get_is_virtual() != s_bs->get_is_virtual())
10332 || (f_bs->get_offset_in_bits() != s_bs->get_offset_in_bits()))
10333 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10334
10335 class_decl_sptr fb = f_bs->get_base_class(), sb = s_bs->get_base_class();
10336 if (!classes_have_same_layout(fb, sb))
10337 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10338 }
10339
10340 if (fc->has_vtable() != sc->has_vtable())
10341 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10342
10343 // Compare virtual function types
10344 ENSURE_NO_ENDLESS_LOOP;
10345 if (fc->has_vtable())
10346 {
10347 if (fc->get_virtual_mem_fns().size() > sc->get_virtual_mem_fns().size())
10348 // Some virtual member function got removed. Bad.
10349 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10350
10351 for (auto it1 = fc->get_virtual_mem_fns().begin(),
10352 it2 = sc->get_virtual_mem_fns().begin();
10353 (it1 != fc->get_virtual_mem_fns().end()
10354 && it2 != sc->get_virtual_mem_fns().end());
10355 ++it1, ++it2)
10356 {
10357 method_decl_sptr method1 = *it1;
10358 method_decl_sptr method2 = *it2;
10359
10362 || !types_are_compatible(method1->get_type(),
10363 method2->get_type()))
10364 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
10365 }
10366 }
10367
10368 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
10369
10370#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10371#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10372#endif
10373
10374#ifdef ENSURE_NO_ENDLESS_LOOP
10375#undef ENSURE_NO_ENDLESS_LOOP
10376#endif
10377}
10378
10379/// Test if two types are equal modulo a typedef or CV qualifiers.
10380///
10381/// Type A and B are compatible if
10382///
10383/// - A and B are equal
10384/// - or A and B are integral types with harmless name change
10385/// - or if one type is a typedef of the other one.
10386/// - or if one type is the CV qualified version of the other
10387/// - or if A and B are classes with the same layout.
10388/// - or if A and B are pointers, references or arrays of
10389/// compatible types
10390///
10391/// @param type1 the first type to consider.
10392///
10393/// @param type2 the second type to consider.
10394///
10395/// @return true iff @p type1 and @p type2 are compatible.
10396bool
10397types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
10398{
10399 if (!type1 || !type2)
10400 return false;
10401
10402 if (type1 == type2 || *type1 == *type2)
10403 return true;
10404
10405 type_base_sptr t1 = peel_qualified_or_typedef_type(type1);
10406 type_base_sptr t2 = peel_qualified_or_typedef_type(type2);
10407
10408 if (t1 && t2 && *t1 == *t2)
10409 return true;
10410
10412 return true;
10413
10414 if (is_pointer_type(t1) && is_pointer_type(t2))
10415 {
10418 return types_are_compatible(t1, t2);
10419 }
10420
10421 if (is_reference_type(t1) && is_reference_type(t2))
10422 {
10423 t1 = is_reference_type(t1)->get_pointed_to_type();
10424 t2 = is_reference_type(t2)->get_pointed_to_type();
10425 return types_are_compatible(t1, t2);
10426 }
10427
10428 if (is_array_type(t1) && is_array_type(t2))
10429 {
10432 type_base_sptr e1 = a1->get_element_type();
10433 type_base_sptr e2 = a2->get_element_type();
10436
10437 if ((a1->get_size_in_bits() != a2->get_size_in_bits())
10438 || (a1->get_dimension_count() != a2->get_dimension_count())
10439 || !types_are_compatible(e1, e2))
10440 return false;
10441
10442 return true;
10443 }
10444
10445 if (function_type_sptr fn_type1 = is_function_type(t1))
10446 if (function_type_sptr fn_type2 = is_function_type(t2))
10447 {
10448 // Compare return types
10449 if (!types_are_compatible(fn_type1->get_return_type(),
10450 fn_type2->get_return_type()))
10451 return false;
10452
10453 // Compare parameter types, omitting the implicit parameter to
10454 // avoid infinite recursion when we are being called from
10455 // classes_have_same_layout on classes with virtual member
10456 // functions.
10457 if (fn_type1->get_parameters().size()
10458 != fn_type2->get_parameters().size())
10459 return false;
10460
10461 for (auto p1 = fn_type1->get_first_non_implicit_parm(),
10462 p2 = fn_type2->get_first_non_implicit_parm();
10463 (p1 != fn_type1->get_parameters().end()
10464 && p2 != fn_type2->get_parameters().end());
10465 ++p1, ++p2)
10466 if (!types_are_compatible((*p1)->get_type(),
10467 (*p2)->get_type()))
10468 return false;
10469
10470 return true;
10471 }
10472
10473 if (classes_have_same_layout(t1, t2))
10474 return true;
10475
10476 return false;
10477}
10478
10479/// Test if two types are equal modulo a typedef.
10480///
10481/// Type A and B are compatible if
10482///
10483/// - A and B are equal
10484/// - or if one type is a typedef of the other one.
10485///
10486/// @param type1 the declaration of the first type to consider.
10487///
10488/// @param type2 the declaration of the second type to consider.
10489///
10490/// @return true iff @p type1 and @p type2 are compatible.
10491bool
10492types_are_compatible(const decl_base_sptr d1,
10493 const decl_base_sptr d2)
10494{return types_are_compatible(is_type(d1), is_type(d2));}
10495
10496/// Return the translation unit a declaration belongs to.
10497///
10498/// @param decl the declaration to consider.
10499///
10500/// @return the resulting translation unit, or null if the decl is not
10501/// yet added to a translation unit.
10504{
10505 translation_unit* result =
10506 const_cast<translation_unit*>(t.get_translation_unit());
10507
10508 if (result)
10509 return result;
10510
10511 if (decl_base* decl = is_decl(&t))
10512 {
10513 scope_decl* scope = decl->get_scope();
10514 while (scope)
10515 {
10516 result = scope->get_translation_unit();
10517 if (result)
10518 break;
10519 scope = scope->get_scope();
10520 }
10521 }
10522
10523 return result;
10524}
10525
10526/// Return the translation unit a declaration belongs to.
10527///
10528/// @param decl the declaration to consider.
10529///
10530/// @return the resulting translation unit, or null if the decl is not
10531/// yet added to a translation unit.
10534{return decl ? get_translation_unit(*decl) : nullptr;}
10535
10536/// Return the translation unit a declaration belongs to.
10537///
10538/// @param decl the declaration to consider.
10539///
10540/// @return the resulting translation unit, or null if the decl is not
10541/// yet added to a translation unit.
10545
10546/// Tests whether if a given scope is the global scope.
10547///
10548/// @param scope the scope to consider.
10549///
10550/// @return true iff the current scope is the global one.
10551bool
10553{return !!dynamic_cast<const global_scope*>(&scope);}
10554
10555/// Tests whether if a given scope is the global scope.
10556///
10557/// @param scope the scope to consider.
10558///
10559/// @return the @ref global_scope* representing the scope @p scope or
10560/// 0 if @p scope is not a global scope.
10561const global_scope*
10563{return dynamic_cast<const global_scope*>(scope);}
10564
10565/// Tests whether if a given scope is the global scope.
10566///
10567/// @param scope the scope to consider.
10568///
10569/// @return true iff the current scope is the global one.
10570bool
10571is_global_scope(const shared_ptr<scope_decl>scope)
10572{return is_global_scope(scope.get());}
10573
10574/// Tests whether a given declaration is at global scope.
10575///
10576/// @param decl the decl to consider.
10577///
10578/// @return true iff decl is at global scope.
10579bool
10581{return (is_global_scope(decl.get_scope()));}
10582
10583/// Tests whether a given declaration is at global scope.
10584///
10585/// @param decl the decl to consider.
10586///
10587/// @return true iff decl is at global scope.
10588bool
10589is_at_global_scope(const decl_base_sptr decl)
10590{return (decl && is_global_scope(decl->get_scope()));}
10591
10592/// Tests whether a given declaration is at global scope.
10593///
10594/// @param decl the decl to consider.
10595///
10596/// @return true iff decl is at global scope.
10597bool
10599{return is_at_global_scope(*decl);}
10600
10601/// Tests whether a given decl is at class scope.
10602///
10603/// @param decl the decl to consider.
10604///
10605/// @return true iff decl is at class scope.
10607is_at_class_scope(const decl_base_sptr decl)
10608{return is_at_class_scope(decl.get());}
10609
10610/// Tests whether a given decl is at class scope.
10611///
10612/// @param decl the decl to consider.
10613///
10614/// @return true iff decl is at class scope.
10617{
10618 if (!decl)
10619 return 0;
10620
10621 return is_at_class_scope(*decl);
10622}
10623
10624/// Tests whether a given decl is at class scope.
10625///
10626/// @param decl the decl to consider.
10627///
10628/// @return true iff decl is at class scope.
10631{
10632 scope_decl* scope = decl.get_scope();
10633 if (class_or_union* cl = is_class_type(scope))
10634 return cl;
10635 if (class_or_union* cl = is_union_type(scope))
10636 return cl;
10637 return 0;
10638}
10639
10640/// Find a data member inside an anonymous data member.
10641///
10642/// An anonymous data member has a type which is a class or union.
10643/// This function looks for a data member inside the type of that
10644/// anonymous data member.
10645///
10646/// @param anon_dm the anonymous data member to consider.
10647///
10648/// @param name the name of the data member to look for.
10651 const string& name)
10652{
10653 const class_or_union* containing_class_or_union =
10655
10656 if (!containing_class_or_union)
10657 return var_decl_sptr();
10658
10659 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10660 return result;
10661}
10662
10663/// Tests whether a given decl is at template scope.
10664///
10665/// Note that only template parameters , types that are compositions,
10666/// and template patterns (function or class) can be at template scope.
10667///
10668/// @param decl the decl to consider.
10669///
10670/// @return true iff the decl is at template scope.
10671bool
10672is_at_template_scope(const shared_ptr<decl_base> decl)
10673{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10674
10675/// Tests whether a decl is a template parameter.
10676///
10677/// @param decl the decl to consider.
10678///
10679/// @return true iff decl is a template parameter.
10680bool
10681is_template_parameter(const shared_ptr<decl_base> decl)
10682{
10683 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10684 || dynamic_pointer_cast<non_type_tparameter>(decl)
10685 || dynamic_pointer_cast<template_tparameter>(decl)));
10686}
10687
10688/// Test whether a declaration is a @ref function_decl.
10689///
10690/// @param d the declaration to test for.
10691///
10692/// @return a shared pointer to @ref function_decl if @p d is a @ref
10693/// function_decl. Otherwise, a nil shared pointer.
10696{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10697
10698/// Test whether a declaration is a @ref function_decl.
10699///
10700/// @param d the declaration to test for.
10701///
10702/// @return true if @p d is a function_decl.
10703bool
10706
10707/// Test whether a declaration is a @ref function_decl.
10708///
10709/// @param d the declaration to test for.
10710///
10711/// @return a shared pointer to @ref function_decl if @p d is a @ref
10712/// function_decl. Otherwise, a nil shared pointer.
10715{return dynamic_pointer_cast<function_decl>(d);}
10716
10717/// Test whether a declaration is a @ref function_decl.
10718///
10719/// @param d the declaration to test for.
10720///
10721/// @return a pointer to @ref function_decl if @p d is a @ref
10722/// function_decl. Otherwise, a nil shared pointer.
10725{
10726 return dynamic_cast<function_decl::parameter*>
10727 (const_cast<type_or_decl_base*>(tod));
10728}
10729
10730/// Test whether an ABI artifact is a @ref function_decl.
10731///
10732/// @param tod the declaration to test for.
10733///
10734/// @return a pointer to @ref function_decl if @p d is a @ref
10735/// function_decl. Otherwise, a nil shared pointer.
10738{return dynamic_pointer_cast<function_decl::parameter>(tod);}
10739
10740/// Test if an ABI artifact is a declaration.
10741///
10742/// @param d the artifact to consider.
10743///
10744/// @param return the declaration sub-object of @p d if it's a
10745/// declaration, or NULL if it is not.
10746decl_base*
10748{
10749 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10750 {
10751 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10752 // The artifact is a decl-only (like a function or a
10753 // variable). That is, it's not a type that also has a
10754 // declaration. In this case, we are in the fast path and we
10755 // have a pointer to the decl sub-object handy. Just return
10756 // it ...
10757 return reinterpret_cast<decl_base*>
10758 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10759
10760 // ... Otherwise, we are in the slow path, which is that the
10761 // artifact is a type which has a declaration. In that case,
10762 // let's use the slow dynamic_cast because we don't have the
10763 // pointer to the decl sub-object handily present.
10764 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10765 }
10766 return 0;
10767}
10768
10769/// Test if an ABI artifact is a declaration.
10770///
10771/// @param d the artifact to consider.
10772///
10773/// @param return the declaration sub-object of @p d if it's a
10774/// declaration, or NULL if it is not.
10775decl_base_sptr
10777{return dynamic_pointer_cast<decl_base>(d);}
10778
10779/// Test if an ABI artifact is a declaration.
10780///
10781/// This is done using a slow path that uses dynamic_cast.
10782///
10783/// @param d the artifact to consider.
10784///
10785/// @param return the declaration sub-object of @p d if it's a
10786decl_base*
10788{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10789
10790/// Test if an ABI artifact is a declaration.
10791///
10792/// This is done using a slow path that uses dynamic_cast.
10793///
10794/// @param d the artifact to consider.
10795///
10796/// @param return the declaration sub-object of @p d if it's a
10797decl_base_sptr
10799{return dynamic_pointer_cast<decl_base>(t);}
10800
10801/// Test whether a declaration is a type.
10802///
10803/// @param d the IR artefact to test for.
10804///
10805/// @return true if the artifact is a type, false otherwise.
10806bool
10808{
10809 if (dynamic_cast<const type_base*>(&tod))
10810 return true;
10811 return false;
10812}
10813
10814/// Test whether a declaration is a type.
10815///
10816/// @param d the IR artefact to test for.
10817///
10818/// @return true if the artifact is a type, false otherwise.
10819type_base*
10821{
10822 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10823 return reinterpret_cast<type_base*>
10824 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10825
10826 return 0;
10827}
10828
10829/// Test whether a declaration is a type.
10830///
10831/// @param d the IR artefact to test for.
10832///
10833/// @return true if the artifact is a type, false otherwise.
10834type_base_sptr
10836{return dynamic_pointer_cast<type_base>(tod);}
10837
10838/// Test whether a declaration is a type.
10839///
10840/// @param d the declaration to test for.
10841///
10842/// @return true if the declaration is a type, false otherwise.
10843
10844/// Test if a given type is anonymous.
10845///
10846/// Note that this function considers that an anonymous class that is
10847/// named by a typedef is not anonymous anymore. This is the C idiom:
10848///
10849/// typedef struct {int member;} s_type;
10850///
10851/// The typedef s_type becomes the name of the originally anonymous
10852/// struct.
10853///
10854/// @param t the type to consider.
10855///
10856/// @return true iff @p t is anonymous.
10857bool
10859{
10860 const decl_base* d = get_type_declaration(t);
10861 if (d)
10862 if (d->get_is_anonymous())
10863 {
10865 {
10866 // An anonymous class that is named by a typedef is not
10867 // considered anonymous anymore.
10868 if (!cou->get_naming_typedef())
10869 return true;
10870 }
10871 else
10872 return true;
10873 }
10874 return false;
10875}
10876
10877/// Test if a given type is anonymous.
10878///
10879/// @param t the type to consider.
10880///
10881/// @return true iff @p t is anonymous.
10882bool
10883is_anonymous_type(const type_base_sptr& t)
10884{return is_anonymous_type(t.get());}
10885
10886/// Test if a type is a neither a pointer, an array nor a function
10887/// type.
10888///
10889/// @param t the type to consider.
10890///
10891/// @return true if the @p t is NOT a pointer, an array nor a
10892/// function.
10893bool
10894is_npaf_type(const type_base_sptr& t)
10895{
10896 if (!(is_pointer_type(t)
10897 || is_array_type(t)
10898 || is_function_type(t)
10899 || is_ptr_to_mbr_type(t)))
10900 return true;
10901 return false;
10902}
10903
10904/// Test whether a type is a type_decl (a builtin type).
10905///
10906/// @return the type_decl* for @t if it's type_decl, otherwise, return
10907/// nil.
10908const type_decl*
10910{return dynamic_cast<const type_decl*>(t);}
10911
10912/// Test whether a type is a type_decl (a builtin type).
10913///
10914/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10915/// return nil.
10918{return dynamic_pointer_cast<type_decl>(t);}
10919
10920/// Test if a type is a real type.
10921///
10922/// @param t the type to test.
10923///
10924/// @return the real type @p t can be converted to, or nil if @p
10925/// is not a real type.
10926type_decl*
10928{
10929 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10930 if (!type)
10931 return nullptr;
10932
10933 real_type int_type;
10934 if (!parse_real_type(type->get_name(), int_type))
10935 return nullptr;
10936
10937 return type;
10938}
10939
10940/// Test if a type is a real type.
10941///
10942/// @param t the type to test.
10943///
10944/// @return the real type @p t can be converted to, or nil if @p is
10945/// not a real type.
10948{
10949 const type_decl_sptr type = is_type_decl(t);
10950 if (!type)
10951 return type_decl_sptr();
10952
10953 real_type int_type;
10954 if (!parse_real_type(type->get_name(), int_type))
10955 return type_decl_sptr();
10956
10957 return type;
10958}
10959
10960/// Test if a type is an integral type.
10961///
10962/// @param t the type to test.
10963///
10964/// @return the integral type @p t can be converted to, or nil if @p
10965/// is not an integral type.
10966type_decl*
10968{
10969 type_decl* type = is_real_type(t);
10970 if (!type)
10971 return nullptr;
10972
10973 real_type rt;
10974 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10977 return nullptr;
10978
10979 return type;
10980}
10981
10982/// Test if a type is an integral type.
10983///
10984/// @param t the type to test.
10985///
10986/// @return the integral type @p t can be converted to, or nil if @p
10987/// is not an integral type.
10990{
10991 type_decl_sptr type = is_real_type(t);
10992 if (!type)
10993 return type;
10994
10995 real_type rt;
10996 ABG_ASSERT(parse_real_type(type->get_name(), rt));
10999 return type_decl_sptr();
11000
11001 return type;
11002}
11003
11004/// Test whether a type is a typedef.
11005///
11006/// @param t the type to test for.
11007///
11008/// @return the typedef declaration of the @p t, or NULL if it's not a
11009/// typedef.
11012{return dynamic_pointer_cast<typedef_decl>(t);}
11013
11014/// Test whether a type is a typedef.
11015///
11016/// @param t the declaration of the type to test for.
11017///
11018/// @return the typedef declaration of the @p t, or NULL if it's not a
11019/// typedef.
11020const typedef_decl*
11022{return dynamic_cast<const typedef_decl*>(t);}
11023
11024/// Test whether a type is a typedef.
11025///
11026/// @param t the declaration of the type to test for.
11027///
11028/// @return the typedef declaration of the @p t, or NULL if it's not a
11029/// typedef.
11032{return dynamic_cast<typedef_decl*>(t);}
11033
11034/// Test whether a type is a typedef.
11035///
11036/// @param t the declaration of the type to test for.
11037///
11038/// @return the typedef declaration of the @p t, or NULL if it's not a
11039/// typedef.
11040const typedef_decl*
11042{return dynamic_cast<const typedef_decl*>(t);}
11043
11044/// Test if a type is an enum. This function looks through typedefs.
11045///
11046/// @parm t the type to consider.
11047///
11048/// @return the enum_decl if @p t is an @ref enum_decl or null
11049/// otherwise.
11050const enum_type_decl*
11052{
11053 if (!t)
11054 return nullptr;
11055
11056 type_base* ty = const_cast<type_base*>(peel_typedef_type(t));
11057 return is_enum_type(ty);
11058}
11059
11060/// Test if a type is an enum. This function looks through typedefs.
11061///
11062/// @parm t the type to consider.
11063///
11064/// @return the enum_decl if @p t is an @ref enum_decl or null
11065/// otherwise.
11067is_compatible_with_enum_type(const type_base_sptr& t)
11068{
11069 if (!t)
11070 return enum_type_decl_sptr();
11071
11072 // Normally we should strip typedefs entirely, but this is
11073 // potentially costly, especially on binaries with huge changesets
11074 // like the Linux Kernel. So we just get the leaf types for now.
11075 //
11076 // Maybe there should be an option by which users accepts to pay the
11077 // CPU usage toll in exchange for finer filtering?
11078
11079 // type_base_sptr ty = strip_typedef(t);
11080 type_base_sptr ty = peel_typedef_type(t);;
11081 return is_enum_type(ty);
11082}
11083
11084/// Test if a type is an enum. This function looks through typedefs.
11085///
11086/// @parm t the type to consider.
11087///
11088/// @return the enum_decl if @p t is an @ref enum_decl or null
11089/// otherwise.
11091is_compatible_with_enum_type(const decl_base_sptr& t)
11093
11094/// Test if a decl is an enum_type_decl
11095///
11096/// @param d the decl to test for.
11097///
11098/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
11099const enum_type_decl*
11101{return dynamic_cast<const enum_type_decl*>(d);}
11102
11103/// Test if a decl is an enum_type_decl
11104///
11105/// @param d the decl to test for.
11106///
11107/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
11110{return dynamic_pointer_cast<enum_type_decl>(d);}
11111
11112/// Test if a type is a class. This function looks through typedefs.
11113///
11114/// @parm t the type to consider.
11115///
11116/// @return the class_decl if @p t is a class_decl or null otherwise.
11117const class_decl*
11119{
11120 if(!t)
11121 return nullptr;
11122
11123 const type_base* ty = peel_typedef_type(t);
11124 return is_class_type(ty);
11125}
11126
11127/// Test if a type is a class. This function looks through typedefs.
11128///
11129/// @parm t the type to consider.
11130///
11131/// @return the class_decl if @p t is a class_decl or null otherwise.
11133is_compatible_with_class_type(const type_base_sptr& t)
11134{
11135 if (!t)
11136 return class_decl_sptr();
11137
11138 // Normally we should strip typedefs entirely, but this is
11139 // potentially costly, especially on binaries with huge changesets
11140 // like the Linux Kernel. So we just get the leaf types for now.
11141 //
11142 // Maybe there should be an option by which users accepts to pay the
11143 // CPU usage toll in exchange for finer filtering?
11144
11145 // type_base_sptr ty = strip_typedef(t);
11146 type_base_sptr ty = peel_typedef_type(t);
11147 return is_class_type(ty);
11148}
11149
11150/// Test if a type is a class. This function looks through typedefs.
11151///
11152/// @parm t the type to consider.
11153///
11154/// @return the class_decl if @p t is a class_decl or null otherwise.
11156is_compatible_with_class_type(const decl_base_sptr& t)
11158
11159/// Test whether a type is a class.
11160///
11161/// @parm t the type to consider.
11162///
11163/// @return true iff @p t is a class_decl.
11164bool
11166{return is_class_type(&t);}
11167
11168/// Test whether a type is a class.
11169///
11170/// @parm t the type to consider.
11171///
11172/// @return the class_decl if @p t is a class_decl or null otherwise.
11175{
11176 if (!t)
11177 return 0;
11178
11179 if (t->kind() & type_or_decl_base::CLASS_TYPE)
11180 return reinterpret_cast<class_decl*>
11181 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
11182
11183 return 0;
11184}
11185
11186/// Test whether a type is a class.
11187///
11188/// @parm t the type to consider.
11189///
11190/// @return the class_decl if @p t is a class_decl or null otherwise.
11193{return dynamic_pointer_cast<class_decl>(d);}
11194
11195/// Test if the last data member of a class is an array with
11196/// non-finite data member.
11197///
11198/// The flexible data member idiom is a well known C idiom:
11199/// https://en.wikipedia.org/wiki/Flexible_array_member.
11200///
11201/// @param klass the class to consider.
11202///
11203/// @return the data member which type is a flexible array, if any, or
11204/// nil.
11207{
11208 var_decl_sptr nil;
11210 if (dms.empty())
11211 return nil;
11212
11213 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11214 {// The type of the last data member is an array.
11215 if (array->is_non_finite())
11216 // The array has a non-finite size. We are thus looking at a
11217 // flexible array data member. Let's return it.
11218 return dms.back();
11219 }
11220
11221 return nil;
11222}
11223
11224/// Test if the last data member of a class is an array with
11225/// non-finite data member.
11226///
11227/// The flexible data member idiom is a well known C idiom:
11228/// https://en.wikipedia.org/wiki/Flexible_array_member.
11229///
11230/// @param klass the class to consider.
11231///
11232/// @return the data member which type is a flexible array, if any, or
11233/// nil.
11236{
11237 if (!klass)
11238 return var_decl_sptr();
11239
11240 return has_flexible_array_data_member(*klass);
11241}
11242
11243/// Test if the last data member of a class is an array with
11244/// non-finite data member.
11245///
11246/// The flexible data member idiom is a well known C idiom:
11247/// https://en.wikipedia.org/wiki/Flexible_array_member.
11248///
11249/// @param klass the class to consider.
11250///
11251/// @return the data member which type is a flexible array, if any, or
11252/// nil.
11256
11257/// Test if the last data member of a class is an array with
11258/// one element.
11259///
11260/// An array with one element is a way to mimic the flexible data
11261/// member idiom that was later standardized in C99.
11262///
11263/// To learn more about the flexible data member idiom, please
11264/// consider reading :
11265/// https://en.wikipedia.org/wiki/Flexible_array_member.
11266///
11267/// The various ways of representing that idiom pre-standardization
11268/// are presented in this article:
11269/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11270///
11271/// @param klass the class to consider.
11272///
11273/// @return the data member which type is a fake flexible array, if
11274/// any, or nil.
11277{
11278 var_decl_sptr nil;
11280 if (dms.empty())
11281 return nil;
11282
11283 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
11284 {// The type of the last data member is an array.
11285 if (array->get_subranges().size() == 1
11286 && array->get_subranges()[0]->get_length() == 1)
11287 // The array has a size of one. We are thus looking at a
11288 // "fake" flexible array data member. Let's return it.
11289 return dms.back();
11290 }
11291
11292 return nil;
11293}
11294
11295/// Test if the last data member of a class is an array with
11296/// one element.
11297///
11298/// An array with one element is a way to mimic the flexible data
11299/// member idiom that was later standardized in C99.
11300///
11301/// To learn more about the flexible data member idiom, please
11302/// consider reading :
11303/// https://en.wikipedia.org/wiki/Flexible_array_member.
11304///
11305/// The various ways of representing that idiom pre-standardization
11306/// are presented in this article:
11307/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11308///
11309/// @param klass the class to consider.
11310///
11311/// @return the data member which type is a fake flexible array, if
11312/// any, or nil.
11316
11317/// Test if the last data member of a class is an array with
11318/// one element.
11319///
11320/// An array with one element is a way to mimic the flexible data
11321/// member idiom that was later standardized in C99.
11322///
11323/// To learn more about the flexible data member idiom, please
11324/// consider reading :
11325/// https://en.wikipedia.org/wiki/Flexible_array_member.
11326///
11327/// The various ways of representing that idiom pre-standardization
11328/// are presented in this article:
11329/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
11330///
11331/// @param klass the class to consider.
11332///
11333/// @return the data member which type is a fake flexible array, if
11334/// any, or nil.
11338
11339/// Test wheter a type is a declaration-only class.
11340///
11341/// @param t the type to considier.
11342///
11343/// @param look_through_decl_only if true, then look through the
11344/// decl-only class to see if it actually has a class definition in
11345/// the same ABI corpus.
11346///
11347/// @return true iff @p t is a declaration-only class.
11348bool
11351{
11352 if (class_or_union *klass = is_class_or_union_type(t))
11353 {
11355 klass = look_through_decl_only_class(klass);
11356 return klass->get_is_declaration_only();
11357 }
11358 return false;
11359}
11360
11361/// Test wheter a type is a declaration-only class.
11362///
11363/// @param t the type to considier.
11364///
11365/// @param look_through_decl_only if true, then look through the
11366/// decl-only class to see if it actually has a class definition in
11367/// the same ABI corpus.
11368///
11369/// @return true iff @p t is a declaration-only class.
11370bool
11374
11375/// Test wheter a type is a declaration-only class.
11376///
11377/// @param t the type to considier.
11378///
11379/// @param look_through_decl_only if true, then look through the
11380/// decl-only class to see if it actually has a class definition in
11381/// the same ABI corpus.
11382///
11383/// @return true iff @p t is a declaration-only class.
11384bool
11388
11389/// Test if a type is a @ref class_or_union.
11390///
11391/// @param t the type to consider.
11392///
11393/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11394/// nil otherwise.
11397{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
11398
11399/// Test if a type is a @ref class_or_union.
11400///
11401/// @param t the type to consider.
11402///
11403/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11404/// nil otherwise.
11405shared_ptr<class_or_union>
11406is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
11407{return dynamic_pointer_cast<class_or_union>(t);}
11408
11409/// Test if two class or union types are of the same kind.
11410///
11411/// @param first the first type to consider.
11412///
11413/// @param second the second type to consider.
11414///
11415/// @return true iff @p first is of the same kind as @p second.
11416bool
11418 const class_or_union* second)
11419{
11420 if ((is_class_type(first) && is_class_type(second))
11421 || (is_union_type(first) && is_union_type(second)))
11422 return true;
11423
11424 return false;
11425}
11426
11427/// Test if two class or union types are of the same kind.
11428///
11429/// @param first the first type to consider.
11430///
11431/// @param second the second type to consider.
11432///
11433/// @return true iff @p first is of the same kind as @p second.
11434bool
11435class_or_union_types_of_same_kind(const class_or_union_sptr& first,
11436 const class_or_union_sptr& second)
11437{return class_or_union_types_of_same_kind(first.get(), second.get());}
11438
11439/// Test if a type is a @ref union_decl.
11440///
11441/// @param t the type to consider.
11442///
11443/// @return true iff @p t is a union_decl.
11444bool
11446{return is_union_type(&t);}
11447
11448/// Test if a type is a @ref union_decl.
11449///
11450/// @param t the type to consider.
11451///
11452/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11453/// otherwise.
11456{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
11457
11458/// Test if a type is a @ref union_decl.
11459///
11460/// @param t the type to consider.
11461///
11462/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11463/// otherwise.
11464union_decl_sptr
11465is_union_type(const shared_ptr<type_or_decl_base>& t)
11466{return dynamic_pointer_cast<union_decl>(t);}
11467
11468/// Test whether a type is a pointer_type_def.
11469///
11470/// @param t the type to test.
11471///
11472/// @param look_through_decl_only if this is true, then look through
11473/// qualified types to see if the underlying type is a
11474/// pointer_type_def.
11475///
11476/// @return the @ref pointer_type_def_sptr if @p t is a
11477/// pointer_type_def, null otherwise.
11478const pointer_type_def*
11480 bool look_through_qualifiers)
11481{
11482 if (!t)
11483 return 0;
11484
11485 const type_base* type = is_type(t);
11486 if (look_through_qualifiers)
11487 type = peel_qualified_type(is_type(t));
11488
11489 return dynamic_cast<pointer_type_def*>(const_cast<type_base*>(type));
11490}
11491
11492/// Test whether a type is a pointer_type_def.
11493///
11494/// @param t the type to test.
11495///
11496/// @param look_through_decl_only if this is true, then look through
11497/// qualified types to see if the underlying type is a
11498/// pointer_type_def.
11499///
11500/// @return the @ref pointer_type_def_sptr if @p t is a
11501/// pointer_type_def, null otherwise.
11504 bool look_through_qualifiers)
11505{
11506 type_base_sptr type = is_type(t);
11507 if (look_through_qualifiers)
11508 type = peel_qualified_type(type);
11509 return dynamic_pointer_cast<pointer_type_def>(type);
11510}
11511
11512/// Test if a type is a pointer to function type.
11513///
11514/// @param t the type to consider.
11515///
11516/// @return the @ref pointer_type_def_sptr iff @p t is a pointer to
11517/// function type.
11519is_pointer_to_function_type(const type_base_sptr& t)
11520{
11522 {
11523 if (is_function_type(p->get_pointed_to_type()))
11524 return p;
11525 }
11526 return pointer_type_def_sptr();
11527}
11528
11529/// Test if a type is a pointer to array type.
11530///
11531/// @param t the type to consider.
11532///
11533/// @return the pointer_type_def_sptr iff @p t is a pointer to array
11534/// type.
11536is_pointer_to_array_type(const type_base_sptr& t)
11537{
11539 {
11540 if (is_array_type(p->get_pointed_to_type()))
11541 return p;
11542 }
11543 return pointer_type_def_sptr();
11544}
11545
11546/// Test if we are looking at a pointer to a
11547/// neither-a-pointer-to-an-array-nor-a-function type.
11548///
11549/// @param t the type to consider.
11550///
11551/// @return the @ref pointer_type_def_sptr type iff @p t is a
11552/// neither-a-pointer-an-array-nor-a-function type.
11554is_pointer_to_npaf_type(const type_base_sptr& t)
11555{
11557 {
11558 if (is_npaf_type(p->get_pointed_to_type()))
11559 return p;
11560 }
11561 return pointer_type_def_sptr();
11562}
11563
11564/// Test if we are looking at a pointer to pointer to member type.
11565///
11566/// @param t the type to consider.
11567///
11568/// @return the @ref pointer_type_def_sptr type iff @p t is a pointer
11569/// to pointer to member type.
11571is_pointer_to_ptr_to_mbr_type(const type_base_sptr& t)
11572{
11574 {
11575 if (is_ptr_to_mbr_type(p->get_pointed_to_type()))
11576 return p;
11577 }
11578 return pointer_type_def_sptr();
11579}
11580
11581/// Test if a type is a typedef, pointer or reference to a decl-only
11582/// class/union.
11583///
11584/// This looks into qualified types too.
11585///
11586/// @param t the type to consider.
11587///
11588/// @return true iff @p t is a type is a typedef, pointer or reference
11589/// to a decl-only class/union.
11590bool
11592{
11593 const type_base * type =
11594 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11595
11597 /*look_through_decl_only=*/true))
11598 return true;
11599
11600 return false;
11601}
11602
11603/// Test if a type is a typedef of a class or union type, or a typedef
11604/// of a qualified class or union type.
11605///
11606/// Note that if the type is directly a class or union type, the
11607/// function returns true as well.
11608///
11609/// @param t the type to consider.
11610///
11611/// @return true iff @p t is a typedef of a class or union type, or a
11612/// typedef of a qualified class or union type.
11613bool
11615{
11616 if (!t)
11617 return false;
11618
11621 return true;
11622
11623return false;
11624}
11625
11626/// Test if a type is a typedef of a class or union type, or a typedef
11627/// of a qualified class or union type.
11628///
11629/// Note that if the type is directly a class or union type, the
11630/// function returns true as well.
11631///
11632/// @param t the type to consider.
11633///
11634/// @return true iff @p t is a typedef of a class or union type, or a
11635/// typedef of a qualified class or union type.
11636bool
11639
11640/// Test whether a type is a reference_type_def.
11641///
11642/// @param t the type to test.
11643///
11644/// @param look_through_decl_only if this is true, then look through
11645/// qualified types to see if the underlying type is a
11646/// reference_type_def.
11647///
11648/// @return the @ref reference_type_def_sptr if @p t is a
11649/// reference_type_def, null otherwise.
11652 bool look_through_qualifiers)
11653{
11654 const type_base* type = is_type(t);
11655 if (!type)
11656 return nullptr;
11657
11658 if (look_through_qualifiers)
11659 type = peel_qualified_type(type);
11660 return dynamic_cast<reference_type_def*>(const_cast<type_base*>(type));
11661}
11662
11663/// Test whether a type is a reference_type_def.
11664///
11665/// @param t the type to test.
11666///
11667/// @param look_through_decl_only if this is true, then look through
11668/// qualified types to see if the underlying type is a
11669/// reference_type_def.
11670///
11671/// @return the @ref reference_type_def_sptr if @p t is a
11672/// reference_type_def, null otherwise.
11673const reference_type_def*
11675 bool look_through_qualifiers)
11676{
11677 const type_base* type = is_type(t);
11678
11679 if (look_through_qualifiers)
11680 type = peel_qualified_type(type);
11681 return dynamic_cast<const reference_type_def*>(type);
11682}
11683
11684/// Test whether a type is a reference_type_def.
11685///
11686/// @param t the type to test.
11687///
11688/// @param look_through_decl_only if this is true, then look through
11689/// qualified types to see if the underlying type is a
11690/// reference_type_def.
11691///
11692/// @return the @ref reference_type_def_sptr if @p t is a
11693/// reference_type_def, null otherwise.
11696 bool look_through_qualifiers)
11697{
11698 type_base_sptr type = is_type(t);
11699 if (look_through_qualifiers)
11700 type = peel_qualified_type(type);
11701 return dynamic_pointer_cast<reference_type_def>(type);
11702}
11703
11704/// Test whether a type is a @ref ptr_to_mbr_type.
11705///
11706/// @param t the type to test.
11707///
11708/// @return the @ref ptr_to_mbr_type* if @p t is a @ref
11709/// ptr_to_mbr_type type, null otherwise.
11710const ptr_to_mbr_type*
11712 bool look_through_qualifiers)
11713{
11714 const type_base* type = is_type(t);
11715 if (look_through_qualifiers)
11716 type = peel_qualified_type(type);
11717 return dynamic_cast<const ptr_to_mbr_type*>(type);
11718}
11719
11720/// Test whether a type is a @ref ptr_to_mbr_type_sptr.
11721///
11722/// @param t the type to test.
11723///
11724/// @param look_through_decl_only if this is true, then look through
11725/// qualified types to see if the underlying type is a
11726/// ptr_to_mbr_type..
11727///
11728/// @return the @ref ptr_to_mbr_type_sptr if @p t is a @ref
11729/// ptr_to_mbr_type type, null otherwise.
11732 bool look_through_qualifiers)
11733{
11734 type_base_sptr type = is_type(t);
11735 if (look_through_qualifiers)
11736 type = peel_qualified_type(type);
11737 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
11738}
11739
11740/// Test if a type is equivalent to a pointer to void type.
11741///
11742/// Note that this looks trough typedefs or CV qualifiers to look for
11743/// the void pointer.
11744///
11745/// @param type the type to consider.
11746///
11747/// @return the actual void pointer if @p is eqivalent to a void
11748/// pointer or NULL if it's not.
11749const type_base*
11751{
11752 type = peel_qualified_or_typedef_type(type);
11753
11754 const pointer_type_def * t = is_pointer_type(type);
11755 if (!t)
11756 return 0;
11757
11758 // Look through typedefs in the pointed-to type as well.
11759 type_base * ty = t->get_pointed_to_type().get();
11761 if (ty && ty->get_environment().is_void_type(ty))
11762 return ty;
11763
11764 return 0;
11765}
11766
11767/// Test if a type is equivalent to a pointer to void type.
11768///
11769/// Note that this looks trough typedefs or CV qualifiers to look for
11770/// the void pointer.
11771///
11772/// @param type the type to consider.
11773///
11774/// @return the actual void pointer if @p is eqivalent to a void
11775/// pointer or NULL if it's not.
11776const type_base*
11779
11780/// Test if a type is a pointer to void type.
11781///
11782/// @param type the type to consider.
11783///
11784/// @return the actual void pointer if @p is a void pointer or NULL if
11785/// it's not.
11786const type_base*
11788{
11789 if (!t)
11790 return nullptr;
11791
11792 if (t->get_environment().get_void_pointer_type().get() == t)
11793 return t;
11794
11795 const pointer_type_def* ptr = is_pointer_type(t);
11796 if (!ptr)
11797 return nullptr;
11798
11800 return t;
11801
11802 return nullptr;
11803}
11804
11805/// Test if a type is a pointer to void type.
11806///
11807/// @param type the type to consider.
11808///
11809/// @return the actual void pointer if @p is a void pointer or NULL if
11810/// it's not.
11811const type_base_sptr
11812is_void_pointer_type(const type_base_sptr& t)
11813{
11814 type_base_sptr nil;
11815 if (!t)
11816 return nil;
11817
11818 if (t->get_environment().get_void_pointer_type().get() == t.get())
11819 return t;
11820
11821 const pointer_type_def* ptr = is_pointer_type(t.get());
11822 if (!ptr)
11823 return nil;
11824
11825 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11826 return t;
11827
11828 return nil;
11829}
11830
11831/// Test whether a type is a reference_type_def.
11832///
11833/// @param t the type to test.
11834///
11835/// @return the @ref reference_type_def_sptr if @p t is a
11836/// reference_type_def, null otherwise.
11839{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11840
11841/// Test whether a type is a qualified_type_def.
11842///
11843/// @param t the type to test.
11844///
11845/// @return the @ref qualified_type_def_sptr if @p t is a
11846/// qualified_type_def, null otherwise.
11847qualified_type_def_sptr
11849{return dynamic_pointer_cast<qualified_type_def>(t);}
11850
11851/// Test whether a type is a function_type.
11852///
11853/// @param t the type to test.
11854///
11855/// @return the @ref function_type_sptr if @p t is a
11856/// function_type, null otherwise.
11859{return dynamic_pointer_cast<function_type>(t);}
11860
11861/// Test whether a type is a function_type.
11862///
11863/// @param t the type to test.
11864///
11865/// @return the @ref function_type_sptr if @p t is a
11866/// function_type, null otherwise.
11869{return dynamic_cast<function_type*>(t);}
11870
11871/// Test whether a type is a function_type.
11872///
11873/// @param t the type to test.
11874///
11875/// @return the @ref function_type_sptr if @p t is a
11876/// function_type, null otherwise.
11877const function_type*
11879{return dynamic_cast<const function_type*>(t);}
11880
11881/// Test whether a type is a method_type.
11882///
11883/// @param t the type to test.
11884///
11885/// @return the @ref method_type_sptr if @p t is a
11886/// method_type, null otherwise.
11889{return dynamic_pointer_cast<method_type>(t);}
11890
11891/// Test whether a type is a method_type.
11892///
11893/// @param t the type to test.
11894///
11895/// @return the @ref method_type_sptr if @p t is a
11896/// method_type, null otherwise.
11897const method_type*
11899{return dynamic_cast<const method_type*>(t);}
11900
11901/// Test whether a type is a method_type.
11902///
11903/// @param t the type to test.
11904///
11905/// @return the @ref method_type_sptr if @p t is a
11906/// method_type, null otherwise.
11909{return dynamic_cast<method_type*>(t);}
11910
11911/// If a class (or union) is a decl-only class, get its definition.
11912/// Otherwise, just return the initial class.
11913///
11914/// @param the_class the class (or union) to consider.
11915///
11916/// @return either the definition of the class, or the class itself.
11920
11921/// If a class (or union) is a decl-only class, get its definition.
11922/// Otherwise, just return the initial class.
11923///
11924/// @param the_class the class (or union) to consider.
11925///
11926/// @return either the definition of the class, or the class itself.
11927class_or_union_sptr
11930
11931/// If a class (or union) is a decl-only class, get its definition.
11932/// Otherwise, just return the initial class.
11933///
11934/// @param klass the class (or union) to consider.
11935///
11936/// @return either the definition of the class, or the class itself.
11937class_or_union_sptr
11938look_through_decl_only_class(class_or_union_sptr klass)
11940
11941/// If an enum is a decl-only enum, get its definition.
11942/// Otherwise, just return the initial enum.
11943///
11944/// @param the_enum the enum to consider.
11945///
11946/// @return either the definition of the enum, or the enum itself.
11950
11951/// If an enum is a decl-only enum, get its definition.
11952/// Otherwise, just return the initial enum.
11953///
11954/// @param enom the enum to consider.
11955///
11956/// @return either the definition of the enum, or the enum itself.
11960
11961/// If a decl is decl-only get its definition. Otherwise, just return nil.
11962///
11963/// @param d the decl to consider.
11964///
11965/// @return either the definition of the decl, or nil.
11966decl_base_sptr
11968{
11969 decl_base_sptr decl;
11972
11973 if (!decl)
11974 return decl;
11975
11976 while (decl->get_is_declaration_only()
11977 && decl->get_definition_of_declaration())
11978 decl = decl->get_definition_of_declaration();
11979
11980 return decl;
11981}
11982
11983/// If a decl is decl-only enum, get its definition. Otherwise, just
11984/// return the initial decl.
11985///
11986/// @param d the decl to consider.
11987///
11988/// @return either the definition of the enum, or the decl itself.
11989decl_base*
11991{
11992 if (!d)
11993 return d;
11994
11995 decl_base* result = look_through_decl_only(*d).get();
11996 if (!result)
11997 result = d;
11998
11999 return result;
12000}
12001
12002/// If a decl is decl-only get its definition. Otherwise, just return nil.
12003///
12004/// @param d the decl to consider.
12005///
12006/// @return either the definition of the decl, or nil.
12007decl_base_sptr
12008look_through_decl_only(const decl_base_sptr& d)
12009{
12010 if (!d)
12011 return d;
12012
12013 decl_base_sptr result = look_through_decl_only(*d);
12014 if (!result)
12015 result = d;
12016
12017 return result;
12018}
12019
12020/// If a type is is decl-only, then get its definition. Otherwise,
12021/// just return the initial type.
12022///
12023/// @param d the decl to consider.
12024///
12025/// @return either the definition of the decl, or the initial type.
12026type_base*
12028{
12029 decl_base* d = is_decl(t);
12030 if (!d)
12031 return t;
12033 return is_type(d);
12034}
12035
12036/// If a type is is decl-only, then get its definition. Otherwise,
12037/// just return the initial type.
12038///
12039/// @param d the decl to consider.
12040///
12041/// @return either the definition of the decl, or the initial type.
12042type_base_sptr
12043look_through_decl_only_type(const type_base_sptr& t)
12044{
12045 decl_base_sptr d = is_decl(t);
12046 if (!d)
12047 return t;
12049 return is_type(d);
12050}
12051
12052/// Tests if a declaration is a variable declaration.
12053///
12054/// @param decl the decl to test.
12055///
12056/// @return the var_decl_sptr iff decl is a variable declaration; nil
12057/// otherwise.
12058var_decl*
12060{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
12061
12062/// Tests if a declaration is a variable declaration.
12063///
12064/// @param decl the decl to test.
12065///
12066/// @return the var_decl_sptr iff decl is a variable declaration; nil
12067/// otherwise.
12070{return dynamic_pointer_cast<var_decl>(decl);}
12071
12072/// Tests if a declaration is a namespace declaration.
12073///
12074/// @param d the decalration to consider.
12075///
12076/// @return the namespace declaration if @p d is a namespace.
12078is_namespace(const decl_base_sptr& d)
12079{return dynamic_pointer_cast<namespace_decl>(d);}
12080
12081/// Tests if a declaration is a namespace declaration.
12082///
12083/// @param d the decalration to consider.
12084///
12085/// @return the namespace declaration if @p d is a namespace.
12088{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
12089
12090/// Tests whether a decl is a template parameter composition type.
12091///
12092/// @param decl the declaration to consider.
12093///
12094/// @return true iff decl is a template parameter composition type.
12095bool
12096is_template_parm_composition_type(const shared_ptr<decl_base> decl)
12097{
12098 return (decl
12099 && is_at_template_scope(decl)
12100 && is_type(decl)
12101 && !is_template_parameter(decl));
12102}
12103
12104/// Test whether a decl is the pattern of a function template.
12105///
12106/// @param decl the decl to consider.
12107///
12108/// @return true iff decl is the pattern of a function template.
12109bool
12110is_function_template_pattern(const shared_ptr<decl_base> decl)
12111{
12112 return (decl
12113 && dynamic_pointer_cast<function_decl>(decl)
12114 && dynamic_cast<template_decl*>(decl->get_scope()));
12115}
12116
12117/// Test if a type is an array_type_def.
12118///
12119/// @param type the type to consider.
12120///
12121/// @return true iff @p type is an array_type_def.
12124 bool look_through_qualifiers)
12125{
12126 const type_base* t = is_type(type);
12127
12128 if (look_through_qualifiers)
12129 t = peel_qualified_type(t);
12130 return dynamic_cast<array_type_def*>(const_cast<type_base*>(t));
12131}
12132
12133/// Test if a type is an array_type_def.
12134///
12135/// @param type the type to consider.
12136///
12137/// @return true iff @p type is an array_type_def.
12140 bool look_through_qualifiers)
12141{
12142 type_base_sptr t = is_type(type);
12143
12144 if (look_through_qualifiers)
12145 t = peel_qualified_type(t);
12146 return dynamic_pointer_cast<array_type_def>(t);
12147}
12148
12149/// Tests if the element of a given array is a qualified type.
12150///
12151/// @param array the array type to consider.
12152///
12153/// @return the qualified element of the array iff it's a qualified
12154/// type. Otherwise, return a nil object.
12155qualified_type_def_sptr
12157{
12158 if (!array)
12159 return qualified_type_def_sptr();
12160
12161 return is_qualified_type(array->get_element_type());
12162}
12163
12164/// Test if an array type is an array to a qualified element type.
12165///
12166/// @param type the array type to consider.
12167///
12168/// @return true the array @p type iff it's an array to a qualified
12169/// element type.
12171is_array_of_qualified_element(const type_base_sptr& type)
12172{
12173 if (array_type_def_sptr array = is_array_type(type))
12175 return array;
12176
12177 return array_type_def_sptr();
12178}
12179
12180/// Test if a type is a typedef of an array.
12181///
12182/// Note that the function looks through qualified and typedefs types
12183/// of the underlying type of the current typedef. In other words, if
12184/// we are looking at a typedef of a CV-qualified array, or at a
12185/// typedef of a CV-qualified typedef of an array, this function will
12186/// still return TRUE.
12187///
12188/// @param t the type to consider.
12189///
12190/// @return true if t is a typedef which underlying type is an array.
12191/// That array might be either cv-qualified array or a typedef'ed
12192/// array, or a combination of both.
12194is_typedef_of_array(const type_base_sptr& t)
12195{
12196 array_type_def_sptr result;
12197
12198 if (typedef_decl_sptr typdef = is_typedef(t))
12199 {
12200 type_base_sptr u =
12201 peel_qualified_or_typedef_type(typdef->get_underlying_type());
12202 result = is_array_type(u);
12203 }
12204
12205 return result;
12206}
12207
12208/// Test if a type is an array_type_def::subrange_type.
12209///
12210/// @param type the type to consider.
12211///
12212/// @return the array_type_def::subrange_type which @p type is a type
12213/// of, or nil if it's not of that type.
12216{
12217 return dynamic_cast<array_type_def::subrange_type*>
12218 (const_cast<type_or_decl_base*>(type));
12219}
12220
12221/// Test if a type is an array_type_def::subrange_type.
12222///
12223/// @param type the type to consider.
12224///
12225/// @return the array_type_def::subrange_type which @p type is a type
12226/// of, or nil if it's not of that type.
12229{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
12230
12231/// Tests whether a decl is a template.
12232///
12233/// @param decl the decl to consider.
12234///
12235/// @return true iff decl is a function template, class template, or
12236/// template template parameter.
12237bool
12238is_template_decl(const decl_base_sptr& decl)
12239{return decl && dynamic_pointer_cast<template_decl>(decl);}
12240
12241/// This enum describe the kind of entity to lookup, while using the
12242/// lookup API.
12244{
12245 LOOKUP_ENTITY_TYPE,
12246 LOOKUP_ENTITY_VAR,
12247};
12248
12249/// Find the first relevant delimiter (the "::" string) in a fully
12250/// qualified C++ type name, starting from a given position. The
12251/// delimiter returned separates a type name from the name of its
12252/// context.
12253///
12254/// This is supposed to work correctly on names in cases like this:
12255///
12256/// foo<ns1::name1, ns2::name2>
12257///
12258/// In that case when called with with parameter @p begin set to 0, no
12259/// delimiter is returned, because the type name in this case is:
12260/// 'foo<ns1::name1, ns2::name2>'.
12261///
12262/// But in this case:
12263///
12264/// foo<p1, bar::name>::some_type
12265///
12266/// The "::" returned is the one right before 'some_type'.
12267///
12268/// @param fqn the fully qualified name of the type to consider.
12269///
12270/// @param begin the position from which to look for the delimiter.
12271///
12272/// @param delim_pos out parameter. Is set to the position of the
12273/// delimiter iff the function returned true.
12274///
12275/// @return true iff the function found and returned the delimiter.
12276static bool
12277find_next_delim_in_cplus_type(const string& fqn,
12278 size_t begin,
12279 size_t& delim_pos)
12280{
12281 int angle_count = 0;
12282 bool found = false;
12283 size_t i = begin;
12284 for (; i < fqn.size(); ++i)
12285 {
12286 if (fqn[i] == '<')
12287 ++angle_count;
12288 else if (fqn[i] == '>')
12289 --angle_count;
12290 else if (i + 1 < fqn.size()
12291 && !angle_count
12292 && fqn[i] == ':'
12293 && fqn[i+1] == ':')
12294 {
12295 delim_pos = i;
12296 found = true;
12297 break;
12298 }
12299 }
12300 return found;
12301}
12302
12303/// Decompose a fully qualified name into the list of its components.
12304///
12305/// @param fqn the fully qualified name to decompose.
12306///
12307/// @param comps the resulting list of component to fill.
12308void
12309fqn_to_components(const string& fqn,
12310 list<string>& comps)
12311{
12312 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
12313 do
12314 {
12315 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
12316 comp_end = fqn_size;
12317
12318 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
12319 comps.push_back(comp);
12320
12321 comp_begin = comp_end + 2;
12322 if (comp_begin >= fqn_size)
12323 break;
12324 } while (true);
12325}
12326
12327/// Turn a set of qualified name components (that name a type) into a
12328/// qualified name string.
12329///
12330/// @param comps the name components
12331///
12332/// @return the resulting string, which would be the qualified name of
12333/// a type.
12334string
12335components_to_type_name(const list<string>& comps)
12336{
12337 string result;
12338 for (list<string>::const_iterator c = comps.begin();
12339 c != comps.end();
12340 ++c)
12341 if (c == comps.begin())
12342 result = *c;
12343 else
12344 result += "::" + *c;
12345 return result;
12346}
12347
12348/// This predicate returns true if a given container iterator points
12349/// to the last element of the container, false otherwise.
12350///
12351/// @tparam T the type of the container of the iterator.
12352///
12353/// @param container the container the iterator points into.
12354///
12355/// @param i the iterator to consider.
12356///
12357/// @return true iff the iterator points to the last element of @p
12358/// container.
12359template<typename T>
12360static bool
12361iterator_is_last(T& container,
12362 typename T::const_iterator i)
12363{
12364 typename T::const_iterator next = i;
12365 ++next;
12366 return (next == container.end());
12367}
12368
12369//--------------------------------
12370// <type and decls lookup stuff>
12371// ------------------------------
12372
12373/// Lookup all the type*s* that have a given fully qualified name.
12374///
12375/// @param type_name the fully qualified name of the type to
12376/// lookup.
12377///
12378/// @param type_map the map to look into.
12379///
12380/// @return the vector containing the types named @p type_name. If
12381/// the lookup didn't yield any type, then this function returns nil.
12382static const type_base_wptrs_type*
12383lookup_types_in_map(const interned_string& type_name,
12384 const istring_type_base_wptrs_map_type& type_map)
12385{
12386 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12387 if (i != type_map.end())
12388 return &i->second;
12389 return 0;
12390}
12391
12392/// Lookup a type (with a given name) in a map that associates a type
12393/// name to a type. If there are several types with a given name,
12394/// then try to return the first one that is not decl-only.
12395/// Otherwise, return the last of such types, that is, the last one
12396/// that got registered.
12397///
12398/// @tparam TypeKind the type of the type this function is supposed to
12399/// return.
12400///
12401/// @param type_name the name of the type to lookup.
12402///
12403/// @param type_map the map in which to look.
12404///
12405/// @return a shared_ptr to the type found. If no type was found or
12406/// if the type found was not of type @p TypeKind then the function
12407/// returns nil.
12408template <class TypeKind>
12409static shared_ptr<TypeKind>
12410lookup_type_in_map(const interned_string& type_name,
12411 const istring_type_base_wptrs_map_type& type_map)
12412{
12413 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12414 if (i != type_map.end())
12415 {
12416 // Walk the types that have the name "type_name" and return the
12417 // first one that is not declaration-only ...
12418 for (auto j : i->second)
12419 {
12420 type_base_sptr t(j);
12421 decl_base_sptr d = is_decl(t);
12422 if (d && !d->get_is_declaration_only())
12423 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
12424 }
12425 // ... or return the last type with the name "type_name" that
12426 // was recorded. It's likely to be declaration-only if we
12427 // reached this point.
12428 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
12429 }
12430 return shared_ptr<TypeKind>();
12431}
12432
12433/// Lookup a basic type from a translation unit.
12434///
12435/// This is done by looking the type up in the type map that is
12436/// maintained in the translation unit. So this is as fast as
12437/// possible.
12438///
12439/// @param type_name the name of the basic type to look for.
12440///
12441/// @param tu the translation unit to look into.
12442///
12443/// @return the basic type found or nil if no basic type was found.
12446{
12447 return lookup_type_in_map<type_decl>(type_name,
12448 tu.get_types().basic_types());
12449}
12450
12451/// Lookup a basic type from a translation unit.
12452///
12453/// This is done by looking the type up in the type map that is
12454/// maintained in the translation unit. So this is as fast as
12455/// possible.
12456///
12457/// @param type_name the name of the basic type to look for.
12458///
12459/// @param tu the translation unit to look into.
12460///
12461/// @return the basic type found or nil if no basic type was found.
12463lookup_basic_type(const string& type_name, const translation_unit& tu)
12464{
12465 const environment& env = tu.get_environment();
12466
12467 interned_string s = env.intern(type_name);
12468 return lookup_basic_type(s, tu);
12469}
12470
12471/// Lookup a class type from a translation unit.
12472///
12473/// This is done by looking the type up in the type map that is
12474/// maintained in the translation unit. So this is as fast as
12475/// possible.
12476///
12477/// @param fqn the fully qualified name of the class type node to look
12478/// up.
12479///
12480/// @param tu the translation unit to perform lookup from.
12481///
12482/// @return the declaration of the class type IR node found, NULL
12483/// otherwise.
12485lookup_class_type(const string& fqn, const translation_unit& tu)
12486{
12487 const environment& env = tu.get_environment();
12488 interned_string s = env.intern(fqn);
12489 return lookup_class_type(s, tu);
12490}
12491
12492/// Lookup a class type from a translation unit.
12493///
12494/// This is done by looking the type up in the type map that is
12495/// maintained in the translation unit. So this is as fast as
12496/// possible.
12497///
12498/// @param type_name the name of the class type to look for.
12499///
12500/// @param tu the translation unit to look into.
12501///
12502/// @return the class type found or nil if no class type was found.
12505{
12506 return lookup_type_in_map<class_decl>(type_name,
12507 tu.get_types().class_types());
12508}
12509
12510/// Lookup a union type from a translation unit.
12511///
12512/// This is done by looking the type up in the type map that is
12513/// maintained in the translation unit. So this is as fast as
12514/// possible.
12515///
12516/// @param type_name the name of the union type to look for.
12517///
12518/// @param tu the translation unit to look into.
12519///
12520/// @return the union type found or nil if no union type was found.
12521union_decl_sptr
12523{
12524 return lookup_type_in_map<union_decl>(type_name,
12525 tu.get_types().union_types());
12526}
12527
12528/// Lookup a union type from a translation unit.
12529///
12530/// This is done by looking the type up in the type map that is
12531/// maintained in the translation unit. So this is as fast as
12532/// possible.
12533///
12534/// @param fqn the fully qualified name of the type to lookup.
12535///
12536/// @param tu the translation unit to look into.
12537///
12538/// @return the union type found or nil if no union type was found.
12539union_decl_sptr
12540lookup_union_type(const string& fqn, const translation_unit& tu)
12541{
12542 const environment& env = tu.get_environment();
12543 interned_string s = env.intern(fqn);
12544 return lookup_union_type(s, tu);
12545}
12546
12547/// Lookup a union type in a given corpus, from its location.
12548///
12549/// @param loc the location of the union type to look for.
12550///
12551/// @param corp the corpus to look it from.
12552///
12553/// @return the resulting union_decl.
12554union_decl_sptr
12556{
12559 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
12560
12561 return result;
12562}
12563
12564/// Lookup a union type in a given corpus, from its location.
12565///
12566/// @param loc the location of the union type to look for.
12567///
12568/// @param corp the corpus to look it from.
12569///
12570/// @return the resulting union_decl.
12571union_decl_sptr
12572lookup_union_type_per_location(const string& loc, const corpus& corp)
12573{
12574 const environment& env = corp.get_environment();
12575 return lookup_union_type_per_location(env.intern(loc), corp);
12576}
12577
12578/// Lookup an enum type from a translation unit.
12579///
12580/// This is done by looking the type up in the type map that is
12581/// maintained in the translation unit. So this is as fast as
12582/// possible.
12583///
12584/// @param type_name the name of the enum type to look for.
12585///
12586/// @param tu the translation unit to look into.
12587///
12588/// @return the enum type found or nil if no enum type was found.
12591{
12592 return lookup_type_in_map<enum_type_decl>(type_name,
12593 tu.get_types().enum_types());
12594}
12595
12596/// Lookup an enum type from a translation unit.
12597///
12598/// This is done by looking the type up in the type map that is
12599/// maintained in the translation unit. So this is as fast as
12600/// possible.
12601///
12602/// @param type_name the name of the enum type to look for.
12603///
12604/// @param tu the translation unit to look into.
12605///
12606/// @return the enum type found or nil if no enum type was found.
12608lookup_enum_type(const string& type_name, const translation_unit& tu)
12609{
12610 const environment& env = tu.get_environment();
12611 interned_string s = env.intern(type_name);
12612 return lookup_enum_type(s, tu);
12613}
12614
12615/// Lookup a typedef type from a translation unit.
12616///
12617/// This is done by looking the type up in the type map that is
12618/// maintained in the translation unit. So this is as fast as
12619/// possible.
12620///
12621/// @param type_name the name of the typedef type to look for.
12622///
12623/// @param tu the translation unit to look into.
12624///
12625/// @return the typedef type found or nil if no typedef type was
12626/// found.
12629 const translation_unit& tu)
12630{
12631 return lookup_type_in_map<typedef_decl>(type_name,
12632 tu.get_types().typedef_types());
12633}
12634
12635/// Lookup a typedef type from a translation unit.
12636///
12637/// This is done by looking the type up in the type map that is
12638/// maintained in the translation unit. So this is as fast as
12639/// possible.
12640///
12641/// @param type_name the name of the typedef type to look for.
12642///
12643/// @param tu the translation unit to look into.
12644///
12645/// @return the typedef type found or nil if no typedef type was
12646/// found.
12648lookup_typedef_type(const string& type_name, const translation_unit& tu)
12649{
12650 const environment& env = tu.get_environment();
12651 interned_string s = env.intern(type_name);
12652 return lookup_typedef_type(s, tu);
12653}
12654
12655/// Lookup a qualified type from a translation unit.
12656///
12657/// This is done by looking the type up in the type map that is
12658/// maintained in the translation unit. So this is as fast as
12659/// possible.
12660///
12661/// @param type_name the name of the qualified type to look for.
12662///
12663/// @param tu the translation unit to look into.
12664///
12665/// @return the qualified type found or nil if no qualified type was
12666/// found.
12667qualified_type_def_sptr
12669 const translation_unit& tu)
12670{
12671 const type_maps& m = tu.get_types();
12672 return lookup_type_in_map<qualified_type_def>(type_name,
12673 m.qualified_types());
12674}
12675
12676/// Lookup a qualified type from a translation unit.
12677///
12678/// This is done by looking the type up in the type map that is
12679/// maintained in the translation unit. So this is as fast as
12680/// possible.
12681///
12682/// @param underlying_type the underying type of the qualified type to
12683/// look up.
12684///
12685/// @param quals the CV-qualifiers of the qualified type to look for.
12686///
12687/// @param tu the translation unit to look into.
12688///
12689/// @return the qualified type found or nil if no qualified type was
12690/// found.
12691qualified_type_def_sptr
12692lookup_qualified_type(const type_base_sptr& underlying_type,
12694 const translation_unit& tu)
12695{
12696 interned_string type_name = get_name_of_qualified_type(underlying_type,
12697 quals);
12698 return lookup_qualified_type(type_name, tu);
12699}
12700
12701/// Lookup a pointer type from a translation unit.
12702///
12703/// This is done by looking the type up in the type map that is
12704/// maintained in the translation unit. So this is as fast as
12705/// possible.
12706///
12707/// @param type_name the name of the pointer type to look for.
12708///
12709/// @param tu the translation unit to look into.
12710///
12711/// @return the pointer type found or nil if no pointer type was
12712/// found.
12715 const translation_unit& tu)
12716{
12717 const type_maps& m = tu.get_types();
12718 return lookup_type_in_map<pointer_type_def>(type_name,
12719 m.pointer_types());
12720}
12721
12722/// Lookup a pointer type from a translation unit.
12723///
12724/// This is done by looking the type up in the type map that is
12725/// maintained in the translation unit. So this is as fast as
12726/// possible.
12727///
12728/// @param type_name the name of the pointer type to look for.
12729///
12730/// @param tu the translation unit to look into.
12731///
12732/// @return the pointer type found or nil if no pointer type was
12733/// found.
12735lookup_pointer_type(const string& type_name, const translation_unit& tu)
12736{
12737 const environment& env = tu.get_environment();
12738 interned_string s = env.intern(type_name);
12739 return lookup_pointer_type(s, tu);
12740}
12741
12742/// Lookup a pointer type from a translation unit.
12743///
12744/// This is done by looking the type up in the type map that is
12745/// maintained in the translation unit. So this is as fast as
12746/// possible.
12747///
12748/// @param pointed_to_type the pointed-to-type of the pointer to look for.
12749///
12750/// @param tu the translation unit to look into.
12751///
12752/// @return the pointer type found or nil if no pointer type was
12753/// found.
12755lookup_pointer_type(const type_base_sptr& pointed_to_type,
12756 const translation_unit& tu)
12757{
12758 type_base_sptr t = look_through_decl_only_type(pointed_to_type);
12760 return lookup_pointer_type(type_name, tu);
12761}
12762
12763/// Lookup a reference type from a translation unit.
12764///
12765/// This is done by looking the type up in the type map that is
12766/// maintained in the translation unit. So this is as fast as
12767/// possible.
12768///
12769/// @param type_name the name of the reference type to look for.
12770///
12771/// @param tu the translation unit to look into.
12772///
12773/// @return the reference type found or nil if no reference type was
12774/// found.
12777 const translation_unit& tu)
12778{
12779 const type_maps& m = tu.get_types();
12780 return lookup_type_in_map<reference_type_def>(type_name,
12781 m.reference_types());
12782}
12783
12784/// Lookup a reference type from a translation unit.
12785///
12786/// This is done by looking the type up in the type map that is
12787/// maintained in the translation unit. So this is as fast as
12788/// possible.
12789///
12790/// @param pointed_to_type the pointed-to-type of the reference to
12791/// look up.
12792///
12793/// @param tu the translation unit to look into.
12794///
12795/// @return the reference type found or nil if no reference type was
12796/// found.
12798lookup_reference_type(const type_base_sptr& pointed_to_type,
12799 bool lvalue_reference,
12800 const translation_unit& tu)
12801{
12802 interned_string type_name =
12804 lvalue_reference);
12805 return lookup_reference_type(type_name, tu);
12806}
12807
12808/// Lookup an array type from a translation unit.
12809///
12810/// This is done by looking the type up in the type map that is
12811/// maintained in the translation unit. So this is as fast as
12812/// possible.
12813///
12814/// @param type_name the name of the array type to look for.
12815///
12816/// @param tu the translation unit to look into.
12817///
12818/// @return the array type found or nil if no array type was found.
12821 const translation_unit& tu)
12822{
12823 const type_maps& m = tu.get_types();
12824 return lookup_type_in_map<array_type_def>(type_name,
12825 m.array_types());
12826}
12827
12828/// Lookup a function type from a translation unit.
12829///
12830/// This is done by looking the type up in the type map that is
12831/// maintained in the translation unit. So this is as fast as
12832/// possible.
12833///
12834/// @param type_name the name of the type to lookup.
12835///
12836/// @param tu the translation unit to look into.
12837///
12838/// @return the function type found, or NULL of none was found.
12841 const translation_unit& tu)
12842{
12843 const type_maps& m = tu.get_types();
12844 return lookup_type_in_map<function_type>(type_name,
12845 m.function_types());
12846}
12847
12848/// Lookup a function type from a translation unit.
12849///
12850/// This walks all the function types held by the translation unit and
12851/// compare their sub-type *names*. If the names match then return
12852/// the function type found in the translation unit.
12853///
12854/// @param t the function type to look for.
12855///
12856/// @param tu the translation unit to look into.
12857///
12858/// @return the function type found, or NULL of none was found.
12861 const translation_unit& tu)
12862{
12863 interned_string type_name = get_type_name(t);
12864 return lookup_function_type(type_name, tu);
12865}
12866
12867/// Lookup a function type from a translation unit.
12868///
12869/// This is done by looking the type up in the type map that is
12870/// maintained in the translation unit. So this is as fast as
12871/// possible.
12872///
12873/// @param t the function type to look for.
12874///
12875/// @param tu the translation unit to look into.
12876///
12877/// @return the function type found, or NULL of none was found.
12880 const translation_unit& tu)
12881{return lookup_function_type(*t, tu);}
12882
12883/// Lookup a type in a translation unit.
12884///
12885/// @param fqn the fully qualified name of the type to lookup.
12886///
12887/// @param tu the translation unit to consider.
12888///
12889/// @return the declaration of the type if found, NULL otherwise.
12890const type_base_sptr
12892 const translation_unit& tu)
12893{
12894 type_base_sptr result;
12895 ((result = lookup_typedef_type(fqn, tu))
12896 || (result = lookup_class_type(fqn, tu))
12897 || (result = lookup_union_type(fqn, tu))
12898 || (result = lookup_enum_type(fqn, tu))
12899 || (result = lookup_qualified_type(fqn, tu))
12900 || (result = lookup_pointer_type(fqn, tu))
12901 || (result = lookup_reference_type(fqn, tu))
12902 || (result = lookup_array_type(fqn, tu))
12903 || (result = lookup_function_type(fqn, tu))
12904 || (result = lookup_basic_type(fqn, tu)));
12905
12906 return result;
12907}
12908
12909/// Lookup a type in a translation unit, starting from the global
12910/// namespace.
12911///
12912/// @param fqn the fully qualified name of the type to lookup.
12913///
12914/// @param tu the translation unit to consider.
12915///
12916/// @return the declaration of the type if found, NULL otherwise.
12917type_base_sptr
12918lookup_type(const string& fqn, const translation_unit& tu)
12919{
12920 const environment&env = tu.get_environment();
12921 interned_string ifqn = env.intern(fqn);
12922 return lookup_type(ifqn, tu);
12923}
12924
12925/// Lookup a type from a translation unit.
12926///
12927/// @param fqn the components of the fully qualified name of the node
12928/// to look up.
12929///
12930/// @param tu the translation unit to perform lookup from.
12931///
12932/// @return the declaration of the IR node found, NULL otherwise.
12933const type_base_sptr
12934lookup_type(const type_base_sptr type,
12935 const translation_unit& tu)
12936{
12937 interned_string type_name = get_type_name(type);
12938 return lookup_type(type_name, tu);
12939}
12940
12941/// Lookup a type in a scope.
12942///
12943/// This is really slow as it walks the member types of the scope in
12944/// sequence to find the type with a given name.
12945///
12946/// If possible, users should prefer looking up types from the
12947/// enclosing translation unit or even ABI corpus because both the
12948/// translation unit and the corpus have a map of type, indexed by
12949/// their name. Looking up a type from those maps is thus much
12950/// faster.
12951///
12952/// @param fqn the fully qualified name of the type to lookup.
12953///
12954/// @param skope the scope to look into.
12955///
12956/// @return the declaration of the type if found, NULL otherwise.
12957const type_base_sptr
12958lookup_type_in_scope(const string& fqn,
12959 const scope_decl_sptr& skope)
12960{
12961 list<string> comps;
12962 fqn_to_components(fqn, comps);
12963 return lookup_type_in_scope(comps, skope);
12964}
12965
12966/// Lookup a @ref var_decl in a scope.
12967///
12968/// @param fqn the fuly qualified name of the @var_decl to lookup.
12969///
12970/// @param skope the scope to look into.
12971///
12972/// @return the declaration of the @ref var_decl if found, NULL
12973/// otherwise.
12974const decl_base_sptr
12976 const scope_decl_sptr& skope)
12977{
12978 list<string> comps;
12979 fqn_to_components(fqn, comps);
12980 return lookup_var_decl_in_scope(comps, skope);
12981}
12982
12983/// A generic function (template) to get the name of a node, whatever
12984/// node it is. This has to be specialized for the kind of node we
12985/// want.
12986///
12987/// Note that a node is a member of a scope.
12988///
12989/// @tparam NodeKind the kind of node to consider.
12990///
12991/// @param node the node to get the name from.
12992///
12993/// @return the name of the node.
12994template<typename NodeKind>
12995static const interned_string&
12996get_node_name(shared_ptr<NodeKind> node);
12997
12998/// Gets the name of a class_decl node.
12999///
13000/// @param node the decl_base node to get the name from.
13001///
13002/// @return the name of the node.
13003template<>
13004const interned_string&
13005get_node_name(class_decl_sptr node)
13006{return node->get_name();}
13007
13008/// Gets the name of a type_base node.
13009///
13010/// @param node the type_base node to get the name from.
13011///
13012/// @return the name of the node.
13013template<>
13014const interned_string&
13015get_node_name(type_base_sptr node)
13016{return get_type_declaration(node)->get_name();}
13017
13018/// Gets the name of a var_decl node.
13019///
13020/// @param node the var_decl node to get the name from.
13021///
13022/// @return the name of the node.
13023template<>
13024const interned_string&
13025get_node_name(var_decl_sptr node)
13026{return node->get_name();}
13027
13028/// Generic function to get the declaration of a given node, whatever
13029/// it is. There has to be specializations for the kind of the nodes
13030/// we want to support.
13031///
13032/// @tparam NodeKind the type of the node we are looking at.
13033///
13034/// @return the declaration.
13035template<typename NodeKind>
13036static decl_base_sptr
13037convert_node_to_decl(shared_ptr<NodeKind> node);
13038
13039/// Lookup a node in a given scope.
13040///
13041/// @tparam the type of the node to lookup.
13042///
13043/// @param fqn the components of the fully qualified name of the node
13044/// to lookup.
13045///
13046/// @param skope the scope to look into.
13047///
13048/// @return the declaration of the looked up node, or NULL if it
13049/// wasn't found.
13050template<typename NodeKind>
13051static const type_or_decl_base_sptr
13052lookup_node_in_scope(const list<string>& fqn,
13053 const scope_decl_sptr& skope)
13054{
13055 type_or_decl_base_sptr resulting_decl;
13056 shared_ptr<NodeKind> node;
13057 bool it_is_last = false;
13058 scope_decl_sptr cur_scope = skope, new_scope, scope;
13059
13060 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
13061 {
13062 new_scope.reset();
13063 it_is_last = iterator_is_last(fqn, c);
13064 for (scope_decl::declarations::const_iterator m =
13065 cur_scope->get_member_decls().begin();
13066 m != cur_scope->get_member_decls().end();
13067 ++m)
13068 {
13069 if (!it_is_last)
13070 {
13071 // looking for a scope
13072 scope = dynamic_pointer_cast<scope_decl>(*m);
13073 if (scope && scope->get_name() == *c)
13074 {
13075 new_scope = scope;
13076 break;
13077 }
13078 }
13079 else
13080 {
13081 //looking for a final type.
13082 node = dynamic_pointer_cast<NodeKind>(*m);
13083 if (node && get_node_name(node) == *c)
13084 {
13085 if (class_decl_sptr cl =
13086 dynamic_pointer_cast<class_decl>(node))
13087 if (cl->get_is_declaration_only()
13088 && !cl->get_definition_of_declaration())
13089 continue;
13090 resulting_decl = node;
13091 break;
13092 }
13093 }
13094 }
13095 if (!new_scope && !resulting_decl)
13096 return decl_base_sptr();
13097 cur_scope = new_scope;
13098 }
13099 ABG_ASSERT(resulting_decl);
13100 return resulting_decl;
13101}
13102
13103/// lookup a type in a scope.
13104///
13105///
13106/// This is really slow as it walks the member types of the scope in
13107/// sequence to find the type with a given name.
13108///
13109/// If possible, users should prefer looking up types from the
13110/// enclosing translation unit or even ABI corpus because both the
13111/// translation unit and the corpus have a map of type, indexed by
13112/// their name. Looking up a type from those maps is thus much
13113/// faster.
13114///
13115/// @param comps the components of the fully qualified name of the
13116/// type to lookup.
13117///
13118/// @param skope the scope to look into.
13119///
13120/// @return the declaration of the type found.
13121const type_base_sptr
13122lookup_type_in_scope(const list<string>& comps,
13123 const scope_decl_sptr& scope)
13124{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
13125
13126/// lookup a type in a scope.
13127///
13128/// This is really slow as it walks the member types of the scope in
13129/// sequence to find the type with a given name.
13130///
13131/// If possible, users should prefer looking up types from the
13132/// enclosing translation unit or even ABI corpus because both the
13133/// translation unit and the corpus have a map of type, indexed by
13134/// their name. Looking up a type from those maps is thus much
13135/// faster.
13136///
13137/// @param type the type to look for.
13138///
13139/// @param access_path a vector of scopes the path of scopes to follow
13140/// before reaching the scope into which to look for @p type. Note
13141/// that the deepest scope (the one immediately containing @p type) is
13142/// at index 0 of this vector, and the top-most scope is the last
13143/// element of the vector.
13144///
13145/// @param scope the top-most scope into which to look for @p type.
13146///
13147/// @return the scope found in @p scope, or NULL if it wasn't found.
13148static const type_base_sptr
13150 const vector<scope_decl*>& access_path,
13151 const scope_decl* scope)
13152{
13153 vector<scope_decl*> a = access_path;
13154 type_base_sptr result;
13155
13156 scope_decl* first_scope = 0;
13157 if (!a.empty())
13158 {
13159 first_scope = a.back();
13160 ABG_ASSERT(first_scope->get_name() == scope->get_name());
13161 a.pop_back();
13162 }
13163
13164 if (a.empty())
13165 {
13166 interned_string n = get_type_name(type, false);
13167 for (scope_decl::declarations::const_iterator i =
13168 scope->get_member_decls().begin();
13169 i != scope->get_member_decls().end();
13170 ++i)
13171 if (is_type(*i) && (*i)->get_name() == n)
13172 {
13173 result = is_type(*i);
13174 break;
13175 }
13176 }
13177 else
13178 {
13179 first_scope = a.back();
13180 interned_string scope_name, cur_scope_name = first_scope->get_name();
13181 for (scope_decl::scopes::const_iterator i =
13182 scope->get_member_scopes().begin();
13183 i != scope->get_member_scopes().end();
13184 ++i)
13185 {
13186 scope_name = (*i)->get_name();
13187 if (scope_name == cur_scope_name)
13188 {
13189 result = lookup_type_in_scope(type, a, (*i).get());
13190 break;
13191 }
13192 }
13193 }
13194 return result;
13195}
13196
13197/// lookup a type in a scope.
13198///
13199/// This is really slow as it walks the member types of the scope in
13200/// sequence to find the type with a given name.
13201///
13202/// If possible, users should prefer looking up types from the
13203/// enclosing translation unit or even ABI corpus because both the
13204/// translation unit and the corpus have a map of type, indexed by
13205/// their name. Looking up a type from those maps is thus much
13206/// faster.
13207///
13208/// @param type the type to look for.
13209///
13210/// @param scope the top-most scope into which to look for @p type.
13211///
13212/// @return the scope found in @p scope, or NULL if it wasn't found.
13213static const type_base_sptr
13214lookup_type_in_scope(const type_base_sptr type,
13215 const scope_decl* scope)
13216{
13217 if (!type || is_function_type(type))
13218 return type_base_sptr();
13219
13220 decl_base_sptr type_decl = get_type_declaration(type);
13221 ABG_ASSERT(type_decl);
13222 vector<scope_decl*> access_path;
13223 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
13224 {
13225 access_path.push_back(s);
13226 if (is_global_scope(s))
13227 break;
13228 }
13229 return lookup_type_in_scope(*type, access_path, scope);
13230}
13231
13232/// Lookup a type from a translation unit by walking the scopes of the
13233/// translation unit in sequence and looking into them.
13234///
13235/// This is really slow as it walks the member types of the scopes in
13236/// sequence to find the type with a given name.
13237///
13238/// If possible, users should prefer looking up types from the
13239/// translation unit or even ABI corpus in a more direct way, by using
13240/// the lookup_type() functins.
13241///
13242///
13243/// This is because both the translation unit and the corpus have a
13244/// map of types, indexed by their name. Looking up a type from those
13245/// maps is thus much faster. @param fqn the components of the fully
13246/// qualified name of the node to look up.
13247///
13248/// @param tu the translation unit to perform lookup from.
13249///
13250/// @return the declaration of the IR node found, NULL otherwise.
13251const type_base_sptr
13252lookup_type_through_scopes(const type_base_sptr type,
13253 const translation_unit& tu)
13254{
13255 if (function_type_sptr fn_type = is_function_type(type))
13256 return lookup_function_type(fn_type, tu);
13257 return lookup_type_in_scope(type, tu.get_global_scope().get());
13258}
13259
13260/// lookup a var_decl in a scope.
13261///
13262/// @param comps the components of the fully qualified name of the
13263/// var_decl to lookup.
13264///
13265/// @param skope the scope to look into.
13266const decl_base_sptr
13267lookup_var_decl_in_scope(const std::list<string>& comps,
13268 const scope_decl_sptr& skope)
13269{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
13270
13271/// Lookup an IR node from a translation unit.
13272///
13273/// @tparam NodeKind the type of the IR node to lookup from the
13274/// translation unit.
13275///
13276/// @param fqn the components of the fully qualified name of the node
13277/// to look up.
13278///
13279/// @param tu the translation unit to perform lookup from.
13280///
13281/// @return the declaration of the IR node found, NULL otherwise.
13282template<typename NodeKind>
13283static const type_or_decl_base_sptr
13284lookup_node_in_translation_unit(const list<string>& fqn,
13285 const translation_unit& tu)
13286{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
13287
13288/// Lookup a type from a translation unit by walking its scopes in
13289/// sequence and by looking into them.
13290///
13291/// This is much slower than using the lookup_type() function.
13292///
13293/// @param fqn the components of the fully qualified name of the node
13294/// to look up.
13295///
13296/// @param tu the translation unit to perform lookup from.
13297///
13298/// @return the declaration of the IR node found, NULL otherwise.
13299type_base_sptr
13300lookup_type_through_scopes(const list<string>& fqn,
13301 const translation_unit& tu)
13302{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
13303
13304
13305/// Lookup a class type from a translation unit by walking its scopes
13306/// in sequence and by looking into them.
13307///
13308/// This is much slower than using the lookup_class_type() function
13309/// because it walks all the scopes of the translation unit in
13310/// sequence and lookup the types to find one that has a given name.
13311///
13312/// @param fqn the components of the fully qualified name of the class
13313/// type node to look up.
13314///
13315/// @param tu the translation unit to perform lookup from.
13316///
13317/// @return the declaration of the class type IR node found, NULL
13318/// otherwise.
13320lookup_class_type_through_scopes(const list<string>& fqn,
13321 const translation_unit& tu)
13322{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
13323
13324/// Lookup a basic type from all the translation units of a given
13325/// corpus.
13326///
13327/// @param fqn the components of the fully qualified name of the basic
13328/// type node to look up.
13329///
13330/// @param tu the translation unit to perform lookup from.
13331///
13332/// @return the declaration of the basic type IR node found, NULL
13333/// otherwise.
13334static type_decl_sptr
13335lookup_basic_type_through_translation_units(const interned_string& type_name,
13336 const corpus& abi_corpus)
13337{
13338 type_decl_sptr result;
13339
13340 for (translation_units::const_iterator tu =
13341 abi_corpus.get_translation_units().begin();
13342 tu != abi_corpus.get_translation_units().end();
13343 ++tu)
13344 if ((result = lookup_basic_type(type_name, **tu)))
13345 break;
13346
13347 return result;
13348}
13349
13350/// Lookup a union type from all the translation units of a given
13351/// corpus.
13352///
13353/// @param fqn the components of the fully qualified name of the union
13354/// type node to look up.
13355///
13356/// @param tu the translation unit to perform lookup from.
13357///
13358/// @return the declaration of the union type IR node found, NULL
13359/// otherwise.
13360static union_decl_sptr
13361lookup_union_type_through_translation_units(const interned_string& type_name,
13362 const corpus & abi_corpus)
13363{
13364 union_decl_sptr result;
13365
13366 for (translation_units::const_iterator tu =
13367 abi_corpus.get_translation_units().begin();
13368 tu != abi_corpus.get_translation_units().end();
13369 ++tu)
13370 if ((result = lookup_union_type(type_name, **tu)))
13371 break;
13372
13373 return result;
13374}
13375
13376/// Lookup an enum type from all the translation units of a given
13377/// corpus.
13378///
13379/// @param fqn the components of the fully qualified name of the enum
13380/// type node to look up.
13381///
13382/// @param tu the translation unit to perform lookup from.
13383///
13384/// @return the declaration of the enum type IR node found, NULL
13385/// otherwise.
13387lookup_enum_type_through_translation_units(const interned_string& type_name,
13388 const corpus & abi_corpus)
13389{
13390 enum_type_decl_sptr result;
13391
13392 for (translation_units::const_iterator tu =
13393 abi_corpus.get_translation_units().begin();
13394 tu != abi_corpus.get_translation_units().end();
13395 ++tu)
13396 if ((result = lookup_enum_type(type_name, **tu)))
13397 break;
13398
13399 return result;
13400}
13401
13402/// Lookup a typedef type definition in all the translation units of a
13403/// given ABI corpus.
13404///
13405/// @param @param qn the fully qualified name of the typedef type to lookup.
13406///
13407/// @param abi_corpus the ABI corpus which to look the type up in.
13408///
13409/// @return the type definition if any was found, or a NULL pointer.
13410static typedef_decl_sptr
13411lookup_typedef_type_through_translation_units(const interned_string& type_name,
13412 const corpus & abi_corpus)
13413{
13414 typedef_decl_sptr result;
13415
13416 for (translation_units::const_iterator tu =
13417 abi_corpus.get_translation_units().begin();
13418 tu != abi_corpus.get_translation_units().end();
13419 ++tu)
13420 if ((result = lookup_typedef_type(type_name, **tu)))
13421 break;
13422
13423 return result;
13424}
13425
13426/// Lookup a qualified type definition in all the translation units of a
13427/// given ABI corpus.
13428///
13429/// @param @param qn the fully qualified name of the qualified type to
13430/// lookup.
13431///
13432/// @param abi_corpus the ABI corpus which to look the type up in.
13433///
13434/// @return the type definition if any was found, or a NULL pointer.
13435static qualified_type_def_sptr
13436lookup_qualified_type_through_translation_units(const interned_string& t_name,
13437 const corpus & abi_corpus)
13438{
13439 qualified_type_def_sptr result;
13440
13441 for (translation_units::const_iterator tu =
13442 abi_corpus.get_translation_units().begin();
13443 tu != abi_corpus.get_translation_units().end();
13444 ++tu)
13445 if ((result = lookup_qualified_type(t_name, **tu)))
13446 break;
13447
13448 return result;
13449}
13450
13451/// Lookup a pointer type definition in all the translation units of a
13452/// given ABI corpus.
13453///
13454/// @param @param qn the fully qualified name of the pointer type to
13455/// lookup.
13456///
13457/// @param abi_corpus the ABI corpus which to look the type up in.
13458///
13459/// @return the type definition if any was found, or a NULL pointer.
13461lookup_pointer_type_through_translation_units(const interned_string& type_name,
13462 const corpus & abi_corpus)
13463{
13464 pointer_type_def_sptr result;
13465
13466 for (translation_units::const_iterator tu =
13467 abi_corpus.get_translation_units().begin();
13468 tu != abi_corpus.get_translation_units().end();
13469 ++tu)
13470 if ((result = lookup_pointer_type(type_name, **tu)))
13471 break;
13472
13473 return result;
13474}
13475
13476/// Lookup a reference type definition in all the translation units of a
13477/// given ABI corpus.
13478///
13479/// @param @param qn the fully qualified name of the reference type to
13480/// lookup.
13481///
13482/// @param abi_corpus the ABI corpus which to look the type up in.
13483///
13484/// @return the type definition if any was found, or a NULL pointer.
13486lookup_reference_type_through_translation_units(const interned_string& t_name,
13487 const corpus & abi_corpus)
13488{
13490
13491 for (translation_units::const_iterator tu =
13492 abi_corpus.get_translation_units().begin();
13493 tu != abi_corpus.get_translation_units().end();
13494 ++tu)
13495 if ((result = lookup_reference_type(t_name, **tu)))
13496 break;
13497
13498 return result;
13499}
13500
13501/// Lookup a array type definition in all the translation units of a
13502/// given ABI corpus.
13503///
13504/// @param @param qn the fully qualified name of the array type to
13505/// lookup.
13506///
13507/// @param abi_corpus the ABI corpus which to look the type up in.
13508///
13509/// @return the type definition if any was found, or a NULL pointer.
13511lookup_array_type_through_translation_units(const interned_string& type_name,
13512 const corpus & abi_corpus)
13513{
13514 array_type_def_sptr result;
13515
13516 for (translation_units::const_iterator tu =
13517 abi_corpus.get_translation_units().begin();
13518 tu != abi_corpus.get_translation_units().end();
13519 ++tu)
13520 if ((result = lookup_array_type(type_name, **tu)))
13521 break;
13522
13523 return result;
13524}
13525
13526/// Lookup a function type definition in all the translation units of
13527/// a given ABI corpus.
13528///
13529/// @param @param qn the fully qualified name of the function type to
13530/// lookup.
13531///
13532/// @param abi_corpus the ABI corpus which to look the type up in.
13533///
13534/// @return the type definition if any was found, or a NULL pointer.
13535static function_type_sptr
13536lookup_function_type_through_translation_units(const interned_string& type_name,
13537 const corpus & abi_corpus)
13538{
13539 function_type_sptr result;
13540
13541 for (translation_units::const_iterator tu =
13542 abi_corpus.get_translation_units().begin();
13543 tu != abi_corpus.get_translation_units().end();
13544 ++tu)
13545 if ((result = lookup_function_type(type_name, **tu)))
13546 break;
13547
13548 return result;
13549}
13550
13551/// Lookup a type definition in all the translation units of a given
13552/// ABI corpus.
13553///
13554/// @param @param qn the fully qualified name of the type to lookup.
13555///
13556/// @param abi_corpus the ABI corpus which to look the type up in.
13557///
13558/// @return the type definition if any was found, or a NULL pointer.
13559type_base_sptr
13561 const corpus& abi_corpus)
13562{
13563 type_base_sptr result;
13564
13565 for (translation_units::const_iterator tu =
13566 abi_corpus.get_translation_units().begin();
13567 tu != abi_corpus.get_translation_units().end();
13568 ++tu)
13569 if ((result = lookup_type(qn, **tu)))
13570 break;
13571
13572 return result;
13573}
13574
13575/// Lookup a type from a given translation unit present in a give corpus.
13576///
13577/// @param type_name the name of the type to look for.
13578///
13579/// @parm tu_path the path of the translation unit to consider.
13580///
13581/// @param corp the corpus to consider.
13582///
13583/// @return the resulting type, if any.
13584type_base_sptr
13586 const string& tu_path,
13587 const corpus& corp)
13588{
13589 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
13590 if (i == corp.priv_->path_tu_map.end())
13591 return type_base_sptr();
13592
13593 translation_unit_sptr tu = i->second;
13594 ABG_ASSERT(tu);
13595
13596 type_base_sptr t = lookup_type(type_name, *tu);
13597 return t;
13598}
13599
13600/// Look into an ABI corpus for a function type.
13601///
13602/// @param fn_type the function type to be looked for in the ABI
13603/// corpus.
13604///
13605/// @param corpus the ABI corpus into which to look for the function
13606/// type.
13607///
13608/// @return the function type found in the corpus.
13611 const corpus& corpus)
13612{
13613 ABG_ASSERT(fn_t);
13614
13615 function_type_sptr result;
13616
13617 if ((result = lookup_function_type(fn_t, corpus)))
13618 return result;
13619
13620 for (translation_units::const_iterator i =
13621 corpus.get_translation_units().begin();
13622 i != corpus.get_translation_units().end();
13623 ++i)
13625 **i)))
13626 return result;
13627
13628 return result;
13629}
13630
13631/// Look into a given corpus to find a type which has the same
13632/// qualified name as a giventype.
13633///
13634/// If the per-corpus type map is non-empty (because the corpus allows
13635/// the One Definition Rule) then the type islooked up in that
13636/// per-corpus type map. Otherwise, the type is looked-up in each
13637/// translation unit.
13638///
13639/// @param t the type which has the same qualified name as the type we
13640/// are looking for.
13641///
13642/// @param corp the ABI corpus to look into for the type.
13644lookup_basic_type(const type_decl& t, const corpus& corp)
13645{return lookup_basic_type(t.get_name(), corp);}
13646
13647/// Look into a given corpus to find a basic type which has a given
13648/// qualified name.
13649///
13650/// If the per-corpus type map is non-empty (because the corpus allows
13651/// the One Definition Rule) then the type islooked up in that
13652/// per-corpus type map. Otherwise, the type is looked-up in each
13653/// translation unit.
13654///
13655/// @param qualified_name the qualified name of the basic type to look
13656/// for.
13657///
13658/// @param corp the corpus to look into.
13660lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
13661{
13663 type_decl_sptr result;
13664
13665 if (!m.empty())
13666 result = lookup_type_in_map<type_decl>(qualified_name, m);
13667 else
13668 result = lookup_basic_type_through_translation_units(qualified_name, corp);
13669
13670 return result;
13671}
13672
13673/// Lookup a @ref type_decl type from a given corpus, by its location.
13674///
13675/// @param loc the location to consider.
13676///
13677/// @param corp the corpus to consider.
13678///
13679/// @return the resulting basic type, if any.
13682 const corpus &corp)
13683{
13686 type_decl_sptr result;
13687
13688 result = lookup_type_in_map<type_decl>(loc, m);
13689
13690 return result;
13691}
13692
13693/// Lookup a @ref type_decl type from a given corpus, by its location.
13694///
13695/// @param loc the location to consider.
13696///
13697/// @param corp the corpus to consider.
13698///
13699/// @return the resulting basic type, if any.
13701lookup_basic_type_per_location(const string &loc, const corpus &corp)
13702{
13703 const environment& env = corp.get_environment();
13704 return lookup_basic_type_per_location(env.intern(loc), corp);
13705}
13706
13707/// Look into a given corpus to find a basic type which has a given
13708/// qualified name.
13709///
13710/// If the per-corpus type map is non-empty (because the corpus allows
13711/// the One Definition Rule) then the type islooked up in that
13712/// per-corpus type map. Otherwise, the type is looked-up in each
13713/// translation unit.
13714///
13715/// @param qualified_name the qualified name of the basic type to look
13716/// for.
13717///
13718/// @param corp the corpus to look into.
13720lookup_basic_type(const string& qualified_name, const corpus& corp)
13721{
13722 return lookup_basic_type(corp.get_environment().intern(qualified_name),
13723 corp);
13724}
13725
13726/// Look into a given corpus to find a class type which has the same
13727/// qualified name as a given type.
13728///
13729/// If the per-corpus type map is non-empty (because the corpus allows
13730/// the One Definition Rule) then the type islooked up in that
13731/// per-corpus type map. Otherwise, the type is looked-up in each
13732/// translation unit.
13733///
13734/// @param t the class decl type which has the same qualified name as
13735/// the type we are looking for.
13736///
13737/// @param corp the corpus to look into.
13740{
13742 return lookup_class_type(s, corp);
13743}
13744
13745/// Look into a given corpus to find a class type which has a given
13746/// qualified name.
13747///
13748/// If the per-corpus type map is non-empty (because the corpus allows
13749/// the One Definition Rule) then the type islooked up in that
13750/// per-corpus type map. Otherwise, the type is looked-up in each
13751/// translation unit.
13752///
13753/// @param qualified_name the qualified name of the type to look for.
13754///
13755/// @param corp the corpus to look into.
13757lookup_class_type(const string& qualified_name, const corpus& corp)
13758{
13759 interned_string s = corp.get_environment().intern(qualified_name);
13760 return lookup_class_type(s, corp);
13761}
13762
13763/// Look into a given corpus to find a class type which has a given
13764/// qualified name.
13765///
13766/// If the per-corpus type map is non-empty (because the corpus allows
13767/// the One Definition Rule) then the type islooked up in that
13768/// per-corpus type map. Otherwise, the type is looked-up in each
13769/// translation unit.
13770///
13771/// @param qualified_name the qualified name of the type to look for.
13772///
13773/// @param corp the corpus to look into.
13775lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13776{
13778
13779 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13780
13781 return result;
13782}
13783
13784/// Look into a given corpus to find the class type*s* that have a
13785/// given qualified name.
13786///
13787/// @param qualified_name the qualified name of the type to look for.
13788///
13789/// @param corp the corpus to look into.
13790///
13791/// @return the vector of class types named @p qualified_name.
13793lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13794{
13796
13797 return lookup_types_in_map(qualified_name, m);
13798}
13799
13800/// Look into a given corpus to find the class type*s* that have a
13801/// given qualified name and that are declaration-only.
13802///
13803/// @param qualified_name the qualified name of the type to look for.
13804///
13805/// @param corp the corpus to look into.
13806///
13807/// @param result the vector of decl-only class types named @p
13808/// qualified_name. This is populated iff the function returns true.
13809///
13810/// @return true iff @p result was populated with the decl-only
13811/// classes named @p qualified_name.
13812bool
13814 const corpus& corp,
13815 type_base_wptrs_type& result)
13816{
13818
13819 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13820 if (!v)
13821 return false;
13822
13823 for (auto type : *v)
13824 {
13825 type_base_sptr t(type);
13827 if (c->get_is_declaration_only()
13828 && !c->get_definition_of_declaration())
13829 result.push_back(type);
13830 }
13831
13832 return !result.empty();
13833}
13834
13835/// Look into a given corpus to find the union type*s* that have a
13836/// given qualified name.
13837///
13838/// @param qualified_name the qualified name of the type to look for.
13839///
13840/// @param corp the corpus to look into.
13841///
13842/// @return the vector of union types named @p qualified_name.
13844lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13845{
13847
13848 return lookup_types_in_map(qualified_name, m);
13849}
13850
13851/// Look into a given corpus to find the class type*s* that have a
13852/// given qualified name.
13853///
13854/// @param qualified_name the qualified name of the type to look for.
13855///
13856/// @param corp the corpus to look into.
13857///
13858/// @return the vector of class types which name is @p qualified_name.
13860lookup_class_types(const string& qualified_name, const corpus& corp)
13861{
13862 interned_string s = corp.get_environment().intern(qualified_name);
13863 return lookup_class_types(s, corp);
13864}
13865
13866/// Look into a given corpus to find the union types that have a given
13867/// qualified name.
13868///
13869/// @param qualified_name the qualified name of the type to look for.
13870///
13871/// @param corp the corpus to look into.
13872///
13873/// @return the vector of union types which name is @p qualified_name.
13875lookup_union_types(const string& qualified_name, const corpus& corp)
13876{
13877 interned_string s = corp.get_environment().intern(qualified_name);
13878 return lookup_union_types(s, corp);
13879}
13880
13881/// Look up a @ref class_decl from a given corpus by its location.
13882///
13883/// @param loc the location to consider.
13884///
13885/// @param corp the corpus to consider.
13886///
13887/// @return the resulting class decl, if any.
13890 const corpus& corp)
13891{
13894 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13895
13896 return result;
13897}
13898
13899/// Look up a @ref class_decl from a given corpus by its location.
13900///
13901/// @param loc the location to consider.
13902///
13903/// @param corp the corpus to consider.
13904///
13905/// @return the resulting class decl, if any.
13907lookup_class_type_per_location(const string &loc, const corpus &corp)
13908{
13909 const environment& env = corp.get_environment();
13910 return lookup_class_type_per_location(env.intern(loc), corp);
13911}
13912
13913/// Look into a given corpus to find a union type which has a given
13914/// qualified name.
13915///
13916/// If the per-corpus type map is non-empty (because the corpus allows
13917/// the One Definition Rule) then the type islooked up in that
13918/// per-corpus type map. Otherwise, the type is looked-up in each
13919/// translation unit.
13920///
13921/// @param qualified_name the qualified name of the type to look for.
13922///
13923/// @param corp the corpus to look into.
13924union_decl_sptr
13925lookup_union_type(const interned_string& type_name, const corpus& corp)
13926{
13928
13929 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13930 if (!result)
13931 result = lookup_union_type_through_translation_units(type_name, corp);
13932
13933 return result;
13934}
13935
13936/// Look into a given corpus to find a union type which has a given
13937/// qualified name.
13938///
13939/// If the per-corpus type map is non-empty (because the corpus allows
13940/// the One Definition Rule) then the type islooked up in that
13941/// per-corpus type map. Otherwise, the type is looked-up in each
13942/// translation unit.
13943///
13944/// @param qualified_name the qualified name of the type to look for.
13945///
13946/// @param corp the corpus to look into.
13947union_decl_sptr
13948lookup_union_type(const string& type_name, const corpus& corp)
13949{
13950 interned_string s = corp.get_environment().intern(type_name);
13951 return lookup_union_type(s, corp);
13952}
13953
13954/// Look into a given corpus to find an enum type which has the same
13955/// qualified name as a given enum type.
13956///
13957/// If the per-corpus type map is non-empty (because the corpus allows
13958/// the One Definition Rule) then the type islooked up in that
13959/// per-corpus type map. Otherwise, the type is looked-up in each
13960/// translation unit.
13961///
13962/// @param t the enum type which has the same qualified name as the
13963/// type we are looking for.
13964///
13965/// @param corp the corpus to look into.
13968{
13970 return lookup_enum_type(s, corp);
13971}
13972
13973/// Look into a given corpus to find an enum type which has a given
13974/// qualified name.
13975///
13976/// If the per-corpus type map is non-empty (because the corpus allows
13977/// the One Definition Rule) then the type islooked up in that
13978/// per-corpus type map. Otherwise, the type is looked-up in each
13979/// translation unit.
13980///
13981/// @param qualified_name the qualified name of the enum type to look
13982/// for.
13983///
13984/// @param corp the corpus to look into.
13986lookup_enum_type(const string& qualified_name, const corpus& corp)
13987{
13988 interned_string s = corp.get_environment().intern(qualified_name);
13989 return lookup_enum_type(s, corp);
13990}
13991
13992/// Look into a given corpus to find an enum type which has a given
13993/// qualified name.
13994///
13995/// If the per-corpus type map is non-empty (because the corpus allows
13996/// the One Definition Rule) then the type islooked up in that
13997/// per-corpus type map. Otherwise, the type is looked-up in each
13998/// translation unit.
13999///
14000/// @param qualified_name the qualified name of the enum type to look
14001/// for.
14002///
14003/// @param corp the corpus to look into.
14005lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
14006{
14008
14009 enum_type_decl_sptr result =
14010 lookup_type_in_map<enum_type_decl>(qualified_name, m);
14011 if (!result)
14012 result = lookup_enum_type_through_translation_units(qualified_name, corp);
14013
14014 return result;
14015}
14016
14017/// Look into a given corpus to find the enum type*s* that have a
14018/// given qualified name.
14019///
14020/// @param qualified_name the qualified name of the type to look for.
14021///
14022/// @param corp the corpus to look into.
14023///
14024/// @return the vector of enum types that which name is @p qualified_name.
14026lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
14027{
14029
14030 return lookup_types_in_map(qualified_name, m);
14031}
14032
14033/// Look into a given corpus to find the enum type*s* that have a
14034/// given qualified name.
14035///
14036/// @param qualified_name the qualified name of the type to look for.
14037///
14038/// @param corp the corpus to look into.
14039///
14040/// @return the vector of enum types that which name is @p qualified_name.
14042lookup_enum_types(const string& qualified_name, const corpus& corp)
14043{
14044 interned_string s = corp.get_environment().intern(qualified_name);
14045 return lookup_enum_types(s, corp);
14046}
14047
14048/// Look up an @ref enum_type_decl from a given corpus, by its location.
14049///
14050/// @param loc the location to consider.
14051///
14052/// @param corp the corpus to look the type from.
14053///
14054/// @return the resulting enum type, if any.
14057{
14060 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
14061
14062 return result;
14063}
14064
14065/// Look up an @ref enum_type_decl from a given corpus, by its location.
14066///
14067/// @param loc the location to consider.
14068///
14069/// @param corp the corpus to look the type from.
14070///
14071/// @return the resulting enum type, if any.
14073lookup_enum_type_per_location(const string &loc, const corpus &corp)
14074{
14075 const environment& env = corp.get_environment();
14076 return lookup_enum_type_per_location(env.intern(loc), corp);
14077}
14078
14079/// Look into a given corpus to find a typedef type which has the
14080/// same qualified name as a given typedef type.
14081///
14082/// If the per-corpus type map is non-empty (because the corpus allows
14083/// the One Definition Rule) then the type islooked up in that
14084/// per-corpus type map. Otherwise, the type is looked-up in each
14085/// translation unit.
14086///
14087/// @param t the typedef type which has the same qualified name as the
14088/// typedef type we are looking for.
14089///
14090/// @param corp the corpus to look into.
14093{
14095 return lookup_typedef_type(s, corp);
14096}
14097
14098/// Look into a given corpus to find a typedef type which has the
14099/// same qualified name as a given typedef type.
14100///
14101/// If the per-corpus type map is non-empty (because the corpus allows
14102/// the One Definition Rule) then the type islooked up in that
14103/// per-corpus type map. Otherwise, the type is looked-up in each
14104/// translation unit.
14105///
14106/// @param t the typedef type which has the same qualified name as the
14107/// typedef type we are looking for.
14108///
14109/// @param corp the corpus to look into.
14111lookup_typedef_type(const string& qualified_name, const corpus& corp)
14112{
14113 interned_string s = corp.get_environment().intern(qualified_name);
14114 return lookup_typedef_type(s, corp);
14115}
14116
14117/// Look into a given corpus to find a typedef type which has a
14118/// given qualified name.
14119///
14120/// If the per-corpus type map is non-empty (because the corpus allows
14121/// the One Definition Rule) then the type islooked up in that
14122/// per-corpus type map. Otherwise, the type is looked-up in each
14123/// translation unit.
14124///
14125/// @param qualified_name the qualified name of the typedef type to
14126/// look for.
14127///
14128/// @param corp the corpus to look into.
14130lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
14131{
14133
14134 typedef_decl_sptr result =
14135 lookup_type_in_map<typedef_decl>(qualified_name, m);
14136 if (!result)
14137 result = lookup_typedef_type_through_translation_units(qualified_name,
14138 corp);
14139
14140 return result;
14141}
14142
14143/// Lookup a @ref typedef_decl from a corpus, by its location.
14144///
14145/// @param loc the location to consider.
14146///
14147/// @param corp the corpus to consider.
14148///
14149/// @return the typedef_decl found, if any.
14152{
14155 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
14156
14157 return result;
14158}
14159
14160/// Lookup a @ref typedef_decl from a corpus, by its location.
14161///
14162/// @param loc the location to consider.
14163///
14164/// @param corp the corpus to consider.
14165///
14166/// @return the typedef_decl found, if any.
14168lookup_typedef_type_per_location(const string &loc, const corpus &corp)
14169{
14170 const environment& env = corp.get_environment();
14171 return lookup_typedef_type_per_location(env.intern(loc), corp);
14172}
14173
14174/// Look into a corpus to find a class, union or typedef type which
14175/// has a given qualified name.
14176///
14177/// If the per-corpus type map is non-empty (because the corpus allows
14178/// the One Definition Rule) then the type islooked up in that
14179/// per-corpus type map. Otherwise, the type is looked-up in each
14180/// translation unit.
14181///
14182/// @param qualified_name the name of the type to find.
14183///
14184/// @param corp the corpus to look into.
14185///
14186/// @return the typedef or class type found.
14187type_base_sptr
14188lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
14189{
14190 type_base_sptr result = lookup_class_type(qualified_name, corp);
14191 if (!result)
14192 result = lookup_union_type(qualified_name, corp);
14193
14194 if (!result)
14195 result = lookup_typedef_type(qualified_name, corp);
14196 return result;
14197}
14198
14199/// Look into a corpus to find a class, typedef or enum type which has
14200/// a given qualified name.
14201///
14202/// If the per-corpus type map is non-empty (because the corpus allows
14203/// the One Definition Rule) then the type islooked up in that
14204/// per-corpus type map. Otherwise, the type is looked-up in each
14205/// translation unit.
14206///
14207/// @param qualified_name the qualified name of the type to look for.
14208///
14209/// @param corp the corpus to look into.
14210///
14211/// @return the typedef, class or enum type found.
14212type_base_sptr
14213lookup_class_typedef_or_enum_type(const string& qualified_name,
14214 const corpus& corp)
14215{
14216 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
14217 if (!result)
14218 result = lookup_enum_type(qualified_name, corp);
14219
14220 return result;
14221}
14222
14223/// Look into a given corpus to find a qualified type which has the
14224/// same qualified name as a given type.
14225///
14226/// @param t the type which has the same qualified name as the
14227/// qualified type we are looking for.
14228///
14229/// @param corp the corpus to look into.
14230///
14231/// @return the qualified type found.
14232qualified_type_def_sptr
14234{
14236 return lookup_qualified_type(s, corp);
14237}
14238
14239/// Look into a given corpus to find a qualified type which has a
14240/// given qualified name.
14241///
14242/// @param qualified_name the qualified name of the type to look for.
14243///
14244/// @param corp the corpus to look into.
14245///
14246/// @return the type found.
14247qualified_type_def_sptr
14248lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
14249{
14251 corp.get_types().qualified_types();
14252
14253 qualified_type_def_sptr result =
14254 lookup_type_in_map<qualified_type_def>(qualified_name, m);
14255
14256 if (!result)
14257 result = lookup_qualified_type_through_translation_units(qualified_name,
14258 corp);
14259
14260 return result;
14261}
14262
14263/// Look into a given corpus to find a pointer type which has the same
14264/// qualified name as a given pointer type.
14265///
14266/// @param t the pointer type which has the same qualified name as the
14267/// type we are looking for.
14268///
14269/// @param corp the corpus to look into.
14270///
14271/// @return the pointer type found.
14274{
14276 return lookup_pointer_type(s, corp);
14277}
14278
14279/// Look into a given corpus to find a pointer type which has a given
14280/// qualified name.
14281///
14282/// If the per-corpus type map is non-empty (because the corpus allows
14283/// the One Definition Rule) then the type islooked up in that
14284/// per-corpus type map. Otherwise, the type is looked-up in each
14285/// translation unit.
14286///
14287/// @param qualified_name the qualified name of the pointer type to
14288/// look for.
14289///
14290/// @param corp the corpus to look into.
14291///
14292/// @return the pointer type found.
14294lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
14295{
14297
14298 pointer_type_def_sptr result =
14299 lookup_type_in_map<pointer_type_def>(qualified_name, m);
14300 if (!result)
14301 result = lookup_pointer_type_through_translation_units(qualified_name,
14302 corp);
14303
14304 return result;
14305}
14306
14307/// Look into a given corpus to find a reference type which has the
14308/// same qualified name as a given reference type.
14309///
14310/// If the per-corpus type map is non-empty (because the corpus allows
14311/// the One Definition Rule) then the type islooked up in that
14312/// per-corpus type map. Otherwise, the type is looked-up in each
14313/// translation unit.
14314///
14315/// @param t the reference type which has the same qualified name as
14316/// the reference type we are looking for.
14317///
14318/// @param corp the corpus to look into.
14319///
14320/// @return the reference type found.
14323{
14325 return lookup_reference_type(s, corp);
14326}
14327
14328/// Look into a given corpus to find a reference type which has a
14329/// given qualified name.
14330///
14331/// If the per-corpus type map is non-empty (because the corpus allows
14332/// the One Definition Rule) then the type islooked up in that
14333/// per-corpus type map. Otherwise, the type is looked-up in each
14334/// translation unit.
14335///
14336/// @param qualified_name the qualified name of the reference type to
14337/// look for.
14338///
14339/// @param corp the corpus to look into.
14340///
14341/// @return the reference type found.
14343lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
14344{
14346 corp.get_types().reference_types();
14347
14349 lookup_type_in_map<reference_type_def>(qualified_name, m);
14350 if (!result)
14351 result = lookup_reference_type_through_translation_units(qualified_name,
14352 corp);
14353
14354 return result;
14355}
14356
14357/// Look into a given corpus to find an array type which has a given
14358/// qualified name.
14359///
14360/// If the per-corpus type map is non-empty (because the corpus allows
14361/// the One Definition Rule) then the type islooked up in that
14362/// per-corpus type map. Otherwise, the type is looked-up in each
14363/// translation unit.
14364///
14365/// @param qualified_name the qualified name of the array type to look
14366/// for.
14367///
14368/// @param corp the corpus to look into.
14369///
14370/// @return the array type found.
14373{
14375 return lookup_array_type(s, corp);
14376}
14377
14378/// Look into a given corpus to find an array type which has the same
14379/// qualified name as a given array type.
14380///
14381/// If the per-corpus type map is non-empty (because the corpus allows
14382/// the One Definition Rule) then the type islooked up in that
14383/// per-corpus type map. Otherwise, the type is looked-up in each
14384/// translation unit.
14385///
14386/// @param t the type which has the same qualified name as the type we
14387/// are looking for.
14388///
14389/// @param corp the corpus to look into.
14390///
14391/// @return the type found.
14393lookup_array_type(const interned_string& qualified_name, const corpus& corp)
14394{
14396
14397 array_type_def_sptr result =
14398 lookup_type_in_map<array_type_def>(qualified_name, m);
14399 if (!result)
14400 result = lookup_array_type_through_translation_units(qualified_name, corp);
14401
14402 return result;
14403}
14404
14405/// Look into a given corpus to find a function type which has the same
14406/// qualified name as a given function type.
14407///
14408/// If the per-corpus type map is non-empty (because the corpus allows
14409/// the One Definition Rule) then the type islooked up in that
14410/// per-corpus type map. Otherwise, the type is looked-up in each
14411/// translation unit.
14412///
14413/// @param t the function type which has the same qualified name as
14414/// the function type we are looking for.
14415///
14416/// @param corp the corpus to look into.
14417///
14418/// @return the function type found.
14421{
14422 interned_string type_name = get_type_name(t);
14423 return lookup_function_type(type_name, corp);
14424}
14425
14426/// Look into a given corpus to find a function type which has the same
14427/// qualified name as a given function type.
14428///
14429/// If the per-corpus type map is non-empty (because the corpus allows
14430/// the One Definition Rule) then the type islooked up in that
14431/// per-corpus type map. Otherwise, the type is looked-up in each
14432/// translation unit.
14433///
14434/// @param t the function type which has the same qualified name as
14435/// the function type we are looking for.
14436///
14437/// @param corp the corpus to look into.
14438///
14439/// @return the function type found.
14442 const corpus& corpus)
14443{
14444 if (fn_t)
14445 return lookup_function_type(*fn_t, corpus);
14446 return function_type_sptr();
14447}
14448
14449/// Look into a given corpus to find a function type which has a given
14450/// qualified name.
14451///
14452/// If the per-corpus type map is non-empty (because the corpus allows
14453/// the One Definition Rule) then the type islooked up in that
14454/// per-corpus type map. Otherwise, the type is looked-up in each
14455/// translation unit.
14456///
14457/// @param qualified_name the qualified name of the function type to
14458/// look for.
14459///
14460/// @param corp the corpus to look into.
14461///
14462/// @return the function type found.
14464lookup_function_type(const interned_string& qualified_name, const corpus& corp)
14465{
14467
14468 function_type_sptr result =
14469 lookup_type_in_map<function_type>(qualified_name, m);
14470 if (!result)
14471 result = lookup_function_type_through_translation_units(qualified_name,
14472 corp);
14473
14474 return result;
14475}
14476
14477/// Look into a given corpus to find a type which has a given
14478/// qualified name.
14479///
14480/// If the per-corpus type map is non-empty (because the corpus allows
14481/// the One Definition Rule) then the type islooked up in that
14482/// per-corpus type map. Otherwise, the type is looked-up in each
14483/// translation unit.
14484///
14485/// @param qualified_name the qualified name of the function type to
14486/// look for.
14487///
14488/// @param corp the corpus to look into.
14489///
14490/// @return the function type found.
14491type_base_sptr
14492lookup_type(const interned_string& n, const corpus& corp)
14493{
14494 type_base_sptr result;
14495
14496 ((result = lookup_basic_type(n, corp))
14497 || (result = lookup_class_type(n, corp))
14498 || (result = lookup_union_type(n, corp))
14499 || (result = lookup_enum_type(n, corp))
14500 || (result = lookup_typedef_type(n, corp))
14501 || (result = lookup_qualified_type(n, corp))
14502 || (result = lookup_pointer_type(n, corp))
14503 || (result = lookup_reference_type(n, corp))
14504 || (result = lookup_array_type(n, corp))
14505 || (result= lookup_function_type(n, corp)));
14506
14507 return result;
14508}
14509
14510/// Lookup a type from a corpus, by its location.
14511///
14512/// @param loc the location to consider.
14513///
14514/// @param corp the corpus to look the type from.
14515///
14516/// @return the resulting type, if any found.
14517type_base_sptr
14519{
14520 // TODO: finish this.
14521
14522 //TODO: when we fully support types indexed by their location, this
14523 //function should return a vector of types because at each location,
14524 //there can be several types that are defined (yay, C and C++,
14525 //*sigh*).
14526
14527 type_base_sptr result;
14528 ((result = lookup_basic_type_per_location(loc, corp))
14529 || (result = lookup_class_type_per_location(loc, corp))
14530 || (result = lookup_union_type_per_location(loc, corp))
14531 || (result = lookup_enum_type_per_location(loc, corp))
14532 || (result = lookup_typedef_type_per_location(loc, corp)));
14533
14534 return result;
14535}
14536
14537/// Look into a given corpus to find a type
14538///
14539/// If the per-corpus type map is non-empty (because the corpus allows
14540/// the One Definition Rule) then the type islooked up in that
14541/// per-corpus type map. Otherwise, the type is looked-up in each
14542/// translation unit.
14543///
14544/// @param qualified_name the qualified name of the function type to
14545/// look for.
14546///
14547/// @param corp the corpus to look into.
14548///
14549/// @return the function type found.
14550type_base_sptr
14551lookup_type(const type_base&t, const corpus& corp)
14552{
14554 return lookup_type(n, corp);
14555}
14556
14557/// Look into a given corpus to find a type
14558///
14559/// If the per-corpus type map is non-empty (because the corpus allows
14560/// the One Definition Rule) then the type islooked up in that
14561/// per-corpus type map. Otherwise, the type is looked-up in each
14562/// translation unit.
14563///
14564/// @param qualified_name the qualified name of the function type to
14565/// look for.
14566///
14567/// @param corp the corpus to look into.
14568///
14569/// @return the function type found.
14570type_base_sptr
14571lookup_type(const type_base_sptr&t, const corpus& corp)
14572{
14573 if (t)
14574 return lookup_type(*t, corp);
14575 return type_base_sptr();
14576}
14577
14578/// Update the map that associates a fully qualified name of a given
14579/// type to that type.
14580///
14581///
14582/// @param type the type we are considering.
14583///
14584/// @param types_map the map to update. It's a map that assciates a
14585/// fully qualified name of a type to the type itself.
14586///
14587/// @param use_type_name_as_key if true, use the name of the type as
14588/// the key to look it up later. If false, then use the location of
14589/// the type as a key to look it up later.
14590///
14591/// @return true iff the type was added to the map.
14592template<typename TypeKind>
14593bool
14594maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
14596 bool use_type_name_as_key = true)
14597{
14599
14600 if (use_type_name_as_key)
14601 s = get_type_name(type);
14602 else if (location l = type->get_location())
14603 {
14604 string str = l.expand();
14605 s = type->get_environment().intern(str);
14606 }
14607
14608 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14609 bool result = false;
14610
14611 if (i == types_map.end())
14612 {
14613 types_map[s].push_back(type);
14614 result = true;
14615 }
14616 else
14617 i->second.push_back(type);
14618
14619 return result;
14620}
14621
14622/// This is the specialization for type @ref class_decl of the
14623/// function template:
14624///
14625/// maybe_update_types_lookup_map<T>(scope_decl*,
14626/// const shared_ptr<T>&,
14627/// istring_type_base_wptrs_map_type&)
14628///
14629/// @param class_type the type to consider.
14630///
14631/// @param types_map the type map to update.
14632///
14633/// @return true iff the type was added to the map.
14634template<>
14635bool
14638 bool use_type_name_as_key)
14639{
14640 class_decl_sptr type = class_type;
14641
14642 bool update_qname_map = true;
14643 if (type->get_is_declaration_only())
14644 {
14645 // Let's try to look through decl-only classes to get their
14646 // definition. But if the class doesn't have a definition then
14647 // we'll keep it.
14648 if (class_decl_sptr def =
14649 is_class_type(class_type->get_definition_of_declaration()))
14650 type = def;
14651 }
14652
14653 if (!update_qname_map)
14654 return false;
14655
14657 if (use_type_name_as_key)
14658 {
14659 string qname = type->get_qualified_name();
14660 s = type->get_environment().intern(qname);
14661 }
14662 else if (location l = type->get_location())
14663 {
14664 string str = l.expand();
14665 s = type->get_environment().intern(str);
14666 }
14667
14668 bool result = false;
14669 istring_type_base_wptrs_map_type::iterator i = map.find(s);
14670 if (i == map.end())
14671 {
14672 map[s].push_back(type);
14673 result = true;
14674 }
14675 else
14676 i->second.push_back(type);
14677
14678 return result;
14679}
14680
14681/// This is the specialization for type @ref function_type of the
14682/// function template:
14683///
14684/// maybe_update_types_lookup_map<T>(scope_decl*,
14685/// const shared_ptr<T>&,
14686/// istring_type_base_wptrs_map_type&)
14687///
14688/// @param scope the scope of the type to consider.
14689///
14690/// @param class_type the type to consider.
14691///
14692/// @param types_map the type map to update.
14693///
14694/// @return true iff the type was added to the map.
14695template<>
14696bool
14698(const function_type_sptr& type,
14700 bool /*use_type_name_as_key*/)
14701{
14702 bool result = false;
14704 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14705 if (i == types_map.end())
14706 {
14707 types_map[s].push_back(type);
14708 result = true;
14709 }
14710 else
14711 i->second.push_back(type);
14712
14713 return result;
14714}
14715
14716/// Update the map that associates the fully qualified name of a basic
14717/// type with the type itself.
14718///
14719/// The per-translation unit type map is updated if no type with this
14720/// name was already existing in that map.
14721///
14722/// If no type with this name did already exist in the per-corpus type
14723/// map, then that per-corpus type map is updated. Otherwise, that
14724/// type is erased from that per-corpus map.
14725///
14726/// @param basic_type the basic type to consider.
14727void
14729{
14730 if (translation_unit *tu = basic_type->get_translation_unit())
14731 maybe_update_types_lookup_map<type_decl>
14732 (basic_type, tu->get_types().basic_types());
14733
14734 if (corpus *type_corpus = basic_type->get_corpus())
14735 {
14736 maybe_update_types_lookup_map<type_decl>
14737 (basic_type,
14738 type_corpus->priv_->get_types().basic_types());
14739
14740 maybe_update_types_lookup_map<type_decl>
14741 (basic_type,
14742 type_corpus->get_type_per_loc_map().basic_types(),
14743 /*use_type_name_as_key*/false);
14744
14745 if (corpus *group = type_corpus->get_group())
14746 {
14747 maybe_update_types_lookup_map<type_decl>
14748 (basic_type,
14749 group->priv_->get_types().basic_types());
14750
14751 maybe_update_types_lookup_map<type_decl>
14752 (basic_type,
14753 group->get_type_per_loc_map().basic_types(),
14754 /*use_type_name_as_key*/false);
14755 }
14756 }
14757
14758}
14759
14760/// Update the map that associates the fully qualified name of a class
14761/// type with the type itself.
14762///
14763/// The per-translation unit type map is updated if no type with this
14764/// name was already existing in that map.
14765///
14766/// If no type with this name did already exist in the per-corpus type
14767/// map, then that per-corpus type map is updated. Otherwise, that
14768/// type is erased from that per-corpus map.
14769///
14770/// @param class_type the class type to consider.
14771void
14773{
14774 if (translation_unit *tu = class_type->get_translation_unit())
14776 (class_type, tu->get_types().class_types());
14777
14778 if (corpus *type_corpus = class_type->get_corpus())
14779 {
14781 (class_type,
14782 type_corpus->priv_->get_types().class_types());
14783
14785 (class_type,
14786 type_corpus->get_type_per_loc_map().class_types(),
14787 /*use_type_name_as_key*/false);
14788
14789 if (corpus *group = type_corpus->get_group())
14790 {
14792 (class_type,
14793 group->priv_->get_types().class_types());
14794
14796 (class_type,
14797 group->get_type_per_loc_map().class_types(),
14798 /*use_type_name_as_key*/false);
14799 }
14800 }
14801}
14802
14803/// Update the map that associates the fully qualified name of a union
14804/// type with the type itself.
14805///
14806/// The per-translation unit type map is updated if no type with this
14807/// name was already existing in that map.
14808///
14809/// If no type with this name did already exist in the per-corpus type
14810/// map, then that per-corpus type map is updated. Otherwise, that
14811/// type is erased from that per-corpus map.
14812///
14813/// @param union_type the union type to consider.
14814void
14815maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14816{
14817 if (translation_unit *tu = union_type->get_translation_unit())
14818 maybe_update_types_lookup_map<union_decl>
14819 (union_type, tu->get_types().union_types());
14820
14821 if (corpus *type_corpus = union_type->get_corpus())
14822 {
14823 maybe_update_types_lookup_map<union_decl>
14824 (union_type,
14825 type_corpus->priv_->get_types().union_types());
14826
14827 maybe_update_types_lookup_map<union_decl>
14828 (union_type,
14829 type_corpus->get_type_per_loc_map().union_types(),
14830 /*use_type_name_as_key*/false);
14831
14832 if (corpus *group = type_corpus->get_group())
14833 {
14834 maybe_update_types_lookup_map<union_decl>
14835 (union_type,
14836 group->priv_->get_types().union_types());
14837
14838 maybe_update_types_lookup_map<union_decl>
14839 (union_type,
14840 group->get_type_per_loc_map().union_types(),
14841 /*use_type_name_as_key*/false);
14842 }
14843 }
14844}
14845
14846/// Update the map that associates the fully qualified name of an enum
14847/// type with the type itself.
14848///
14849/// The per-translation unit type map is updated if no type with this
14850/// name was already existing in that map.
14851///
14852/// If no type with this name did already exist in the per-corpus type
14853/// map, then that per-corpus type map is updated. Otherwise, that
14854/// type is erased from that per-corpus map.
14855///
14856/// @param enum_type the type to consider.
14857void
14859{
14860 if (translation_unit *tu = enum_type->get_translation_unit())
14861 maybe_update_types_lookup_map<enum_type_decl>
14862 (enum_type, tu->get_types().enum_types());
14863
14864 if (corpus *type_corpus = enum_type->get_corpus())
14865 {
14866 maybe_update_types_lookup_map<enum_type_decl>
14867 (enum_type,
14868 type_corpus->priv_->get_types().enum_types());
14869
14870 maybe_update_types_lookup_map<enum_type_decl>
14871 (enum_type,
14872 type_corpus->get_type_per_loc_map().enum_types(),
14873 /*use_type_name_as_key*/false);
14874
14875 if (corpus *group = type_corpus->get_group())
14876 {
14877 maybe_update_types_lookup_map<enum_type_decl>
14878 (enum_type,
14879 group->priv_->get_types().enum_types());
14880
14881 maybe_update_types_lookup_map<enum_type_decl>
14882 (enum_type,
14883 group->get_type_per_loc_map().enum_types(),
14884 /*use_type_name_as_key*/false);
14885 }
14886 }
14887
14888}
14889
14890/// Update the map that associates the fully qualified name of a
14891/// typedef type with the type itself.
14892///
14893/// The per-translation unit type map is updated if no type with this
14894/// name was already existing in that map.
14895///
14896/// If no type with this name did already exist in the per-corpus type
14897/// map, then that per-corpus type map is updated. Otherwise, that
14898/// type is erased from that per-corpus map.
14899///
14900/// @param typedef_type the type to consider.
14901void
14903{
14904 if (translation_unit *tu = typedef_type->get_translation_unit())
14905 maybe_update_types_lookup_map<typedef_decl>
14906 (typedef_type, tu->get_types().typedef_types());
14907
14908 if (corpus *type_corpus = typedef_type->get_corpus())
14909 {
14910 maybe_update_types_lookup_map<typedef_decl>
14911 (typedef_type,
14912 type_corpus->priv_->get_types().typedef_types());
14913
14914 maybe_update_types_lookup_map<typedef_decl>
14915 (typedef_type,
14916 type_corpus->get_type_per_loc_map().typedef_types(),
14917 /*use_type_name_as_key*/false);
14918
14919 if (corpus *group = type_corpus->get_group())
14920 {
14921 maybe_update_types_lookup_map<typedef_decl>
14922 (typedef_type,
14923 group->priv_->get_types().typedef_types());
14924
14925 maybe_update_types_lookup_map<typedef_decl>
14926 (typedef_type,
14927 group->get_type_per_loc_map().typedef_types(),
14928 /*use_type_name_as_key*/false);
14929 }
14930 }
14931}
14932
14933/// Update the map that associates the fully qualified name of a
14934/// qualified type with the type itself.
14935///
14936/// The per-translation unit type map is updated if no type with this
14937/// name was already existing in that map.
14938///
14939/// If no type with this name did already exist in the per-corpus type
14940/// map, then that per-corpus type map is updated. Otherwise, that
14941/// type is erased from that per-corpus map.
14942///
14943/// @param qualified_type the type to consider.
14944void
14945maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14946{
14947 if (translation_unit *tu = qualified_type->get_translation_unit())
14948 maybe_update_types_lookup_map<qualified_type_def>
14949 (qualified_type, tu->get_types().qualified_types());
14950
14951 if (corpus *type_corpus = qualified_type->get_corpus())
14952 {
14953 maybe_update_types_lookup_map<qualified_type_def>
14954 (qualified_type,
14955 type_corpus->priv_->get_types().qualified_types());
14956
14957 if (corpus *group = type_corpus->get_group())
14958 {
14959 maybe_update_types_lookup_map<qualified_type_def>
14960 (qualified_type,
14961 group->priv_->get_types().qualified_types());
14962 }
14963 }
14964}
14965
14966/// Update the map that associates the fully qualified name of a
14967/// pointer type with the type itself.
14968///
14969/// The per-translation unit type map is updated if no type with this
14970/// name was already existing in that map.
14971///
14972/// If no type with this name did already exist in the per-corpus type
14973/// map, then that per-corpus type map is updated. Otherwise, that
14974/// type is erased from that per-corpus map.
14975///
14976/// @param pointer_type the type to consider.
14977void
14979{
14980 if (translation_unit *tu = pointer_type->get_translation_unit())
14981 maybe_update_types_lookup_map<pointer_type_def>
14982 (pointer_type, tu->get_types().pointer_types());
14983
14984 if (corpus *type_corpus = pointer_type->get_corpus())
14985 {
14986 maybe_update_types_lookup_map<pointer_type_def>
14987 (pointer_type,
14988 type_corpus->priv_->get_types().pointer_types());
14989
14990 if (corpus *group = type_corpus->get_group())
14991 {
14992 maybe_update_types_lookup_map<pointer_type_def>
14993 (pointer_type,
14994 group->priv_->get_types().pointer_types());
14995 }
14996 }
14997}
14998
14999/// Update the map that associates the fully qualified name of a
15000/// pointer-to-member type with the type itself.
15001///
15002/// The per-translation unit type map is updated if no type with this
15003/// name was already existing in that map.
15004///
15005/// If no type with this name did already exist in the per-corpus type
15006/// map, then that per-corpus type map is updated. Otherwise, that
15007/// type is erased from that per-corpus map.
15008///
15009/// @param ptr_to_mbr_type the type to consider.
15010void
15012{
15013 if (translation_unit *tu = ptr_to_member->get_translation_unit())
15014 maybe_update_types_lookup_map<ptr_to_mbr_type>
15015 (ptr_to_member, tu->get_types().ptr_to_mbr_types());
15016
15017 if (corpus *type_corpus = ptr_to_member->get_corpus())
15018 {
15019 maybe_update_types_lookup_map<ptr_to_mbr_type>
15020 (ptr_to_member,
15021 type_corpus->priv_->get_types().ptr_to_mbr_types());
15022
15023 if (corpus *group = type_corpus->get_group())
15024 {
15025 maybe_update_types_lookup_map<ptr_to_mbr_type>
15026 (ptr_to_member,
15027 group->priv_->get_types().ptr_to_mbr_types());
15028 }
15029 }
15030}
15031
15032/// Update the map that associates the fully qualified name of a
15033/// reference type with the type itself.
15034///
15035/// The per-translation unit type map is updated if no type with this
15036/// name was already existing in that map.
15037///
15038/// If no type with this name did already exist in the per-corpus type
15039/// map, then that per-corpus type map is updated. Otherwise, that
15040/// type is erased from that per-corpus map.
15041///
15042/// @param reference_type the type to consider.
15043void
15045{
15046 if (translation_unit *tu = reference_type->get_translation_unit())
15047 maybe_update_types_lookup_map<reference_type_def>
15048 (reference_type, tu->get_types().reference_types());
15049
15050 if (corpus *type_corpus = reference_type->get_corpus())
15051 {
15052 maybe_update_types_lookup_map<reference_type_def>
15053 (reference_type,
15054 type_corpus->priv_->get_types().reference_types());
15055
15056 if (corpus *group = type_corpus->get_group())
15057 {
15058 maybe_update_types_lookup_map<reference_type_def>
15059 (reference_type,
15060 group->priv_->get_types().reference_types());
15061 }
15062 }
15063}
15064
15065/// Update the map that associates the fully qualified name of a type
15066/// with the type itself.
15067///
15068/// The per-translation unit type map is updated if no type with this
15069/// name was already existing in that map.
15070///
15071/// If no type with this name did already exist in the per-corpus type
15072/// map, then that per-corpus type map is updated. Otherwise, that
15073/// type is erased from that per-corpus map.
15074///
15075/// @param array_type the type to consider.
15076void
15078{
15079 if (translation_unit *tu = array_type->get_translation_unit())
15080 maybe_update_types_lookup_map<array_type_def>
15081 (array_type, tu->get_types().array_types());
15082
15083 if (corpus *type_corpus = array_type->get_corpus())
15084 {
15085 maybe_update_types_lookup_map<array_type_def>
15086 (array_type,
15087 type_corpus->priv_->get_types().array_types());
15088
15089 maybe_update_types_lookup_map<array_type_def>
15090 (array_type,
15091 type_corpus->get_type_per_loc_map().array_types(),
15092 /*use_type_name_as_key*/false);
15093
15094 if (corpus *group = type_corpus->get_group())
15095 {
15096 maybe_update_types_lookup_map<array_type_def>
15097 (array_type,
15098 group->priv_->get_types().array_types());
15099
15100 maybe_update_types_lookup_map<array_type_def>
15101 (array_type,
15102 group->get_type_per_loc_map().array_types(),
15103 /*use_type_name_as_key*/false);
15104 }
15105 }
15106}
15107
15108/// Update the map that associates the fully qualified name of a type
15109/// with the type itself.
15110///
15111/// The per-translation unit type map is updated if no type with this
15112/// name was already existing in that map.
15113///
15114/// If no type with this name did already exist in the per-corpus type
15115/// map, then that per-corpus type map is updated. Otherwise, that
15116/// type is erased from that per-corpus map.
15117///
15118/// @param subrange_type the type to consider.
15119void
15121(const array_type_def::subrange_sptr& subrange_type)
15122{
15123 if (translation_unit *tu = subrange_type->get_translation_unit())
15124 maybe_update_types_lookup_map<array_type_def::subrange_type>
15125 (subrange_type, tu->get_types().subrange_types());
15126
15127 if (corpus *type_corpus = subrange_type->get_corpus())
15128 {
15129 maybe_update_types_lookup_map<array_type_def::subrange_type>
15130 (subrange_type,
15131 type_corpus->priv_->get_types().subrange_types());
15132
15133 maybe_update_types_lookup_map<array_type_def::subrange_type>
15134 (subrange_type,
15135 type_corpus->get_type_per_loc_map().subrange_types(),
15136 /*use_type_name_as_key*/false);
15137
15138 if (corpus *group = subrange_type->get_corpus())
15139 {
15140 maybe_update_types_lookup_map<array_type_def::subrange_type>
15141 (subrange_type,
15142 group->priv_->get_types().subrange_types());
15143
15144 maybe_update_types_lookup_map<array_type_def::subrange_type>
15145 (subrange_type,
15146 group->get_type_per_loc_map().subrange_types(),
15147 /*use_type_name_as_key*/false);
15148 }
15149 }
15150}
15151
15152/// Update the map that associates the fully qualified name of a
15153/// function type with the type itself.
15154///
15155/// The per-translation unit type map is updated if no type with this
15156/// name was already existing in that map.
15157///
15158/// If no type with this name did already exist in the per-corpus type
15159/// map, then that per-corpus type map is updated. Otherwise, that
15160/// type is erased from that per-corpus map.
15161///
15162/// @param scope the scope of the function type.
15163/// @param fn_type the type to consider.
15164void
15166{
15167 if (translation_unit *tu = fn_type->get_translation_unit())
15169 (fn_type, tu->get_types().function_types());
15170
15171 if (corpus *type_corpus = fn_type->get_corpus())
15172 {
15174 (fn_type,
15175 type_corpus->priv_->get_types().function_types());
15176
15177 if (corpus *group = fn_type->get_corpus())
15178 {
15180 (fn_type,
15181 group->priv_->get_types().function_types());
15182 }
15183 }
15184}
15185
15186/// Update the map that associates the fully qualified name of a type
15187/// declaration with the type itself.
15188///
15189/// The per-translation unit type map is updated if no type with this
15190/// name was already existing in that map.
15191///
15192/// If no type with this name did already exist in the per-corpus type
15193/// map, then that per-corpus type map is updated. Otherwise, that
15194/// type is erased from that per-corpus map.
15195///
15196/// @param decl the declaration of the type to consider.
15197void
15198maybe_update_types_lookup_map(const decl_base_sptr& decl)
15199{
15200 if (!is_type(decl))
15201 return;
15202
15203 if (type_decl_sptr basic_type = is_type_decl(decl))
15205 else if (class_decl_sptr class_type = is_class_type(decl))
15207 else if (union_decl_sptr union_type = is_union_type(decl))
15209 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
15211 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
15212 maybe_update_types_lookup_map(typedef_type);
15213 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
15214 maybe_update_types_lookup_map(qualified_type);
15215 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
15216 maybe_update_types_lookup_map(pointer_type);
15217 else if (ptr_to_mbr_type_sptr ptr_to_member = is_ptr_to_mbr_type(decl))
15218 maybe_update_types_lookup_map(ptr_to_member);
15219 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
15220 maybe_update_types_lookup_map(reference_type);
15221 else if (array_type_def_sptr array_type = is_array_type(decl))
15223 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
15224 maybe_update_types_lookup_map(subrange_type);
15225 else if (function_type_sptr fn_type = is_function_type(decl))
15227 else
15229}
15230
15231/// Update the map that associates the fully qualified name of a type
15232/// with the type itself.
15233///
15234/// The per-translation unit type map is updated if no type with this
15235/// name was already existing in that map.
15236///
15237/// If no type with this name did already exist in the per-corpus type
15238/// map, then that per-corpus type map is updated. Otherwise, that
15239/// type is erased from that per-corpus map.
15240///
15241/// @param type the type to consider.
15242void
15243maybe_update_types_lookup_map(const type_base_sptr& type)
15244{
15245 if (decl_base_sptr decl = get_type_declaration(type))
15247 else if (function_type_sptr fn_type = is_function_type(type))
15249 else
15251}
15252
15253//--------------------------------
15254// </type and decls lookup stuff>
15255// ------------------------------
15256
15257/// In a translation unit, lookup a given type or synthesize it if
15258/// it's a qualified type.
15259///
15260/// So this function first looks the type up in the translation unit.
15261/// If it's found, then OK, it's returned. Otherwise, if it's a
15262/// qualified, reference or pointer or function type (a composite
15263/// type), lookup the underlying type, synthesize the type we want
15264/// from it and return it.
15265///
15266/// If the underlying types is not not found, then give up and return
15267/// nil.
15268///
15269/// @return the type that was found or the synthesized type.
15270type_base_sptr
15271synthesize_type_from_translation_unit(const type_base_sptr& type,
15272 translation_unit& tu)
15273{
15274 type_base_sptr result;
15275
15276 result = lookup_type(type, tu);
15277
15278 if (!result)
15279 {
15280 if (qualified_type_def_sptr qual = is_qualified_type(type))
15281 {
15282 type_base_sptr underlying_type =
15283 synthesize_type_from_translation_unit(qual->get_underlying_type(),
15284 tu);
15285 if (underlying_type)
15286 {
15287 result.reset(new qualified_type_def(underlying_type,
15288 qual->get_cv_quals(),
15289 qual->get_location()));
15290 }
15291 }
15292 else if (pointer_type_def_sptr p = is_pointer_type(type))
15293 {
15294 type_base_sptr pointed_to_type =
15295 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
15296 tu);
15297 if (pointed_to_type)
15298 {
15299 result.reset(new pointer_type_def(pointed_to_type,
15300 p->get_size_in_bits(),
15301 p->get_alignment_in_bits(),
15302 p->get_location()));
15303 }
15304 }
15305 else if (reference_type_def_sptr r = is_reference_type(type))
15306 {
15307 type_base_sptr pointed_to_type =
15308 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
15309 if (pointed_to_type)
15310 {
15311 result.reset(new reference_type_def(pointed_to_type,
15312 r->is_lvalue(),
15313 r->get_size_in_bits(),
15314 r->get_alignment_in_bits(),
15315 r->get_location()));
15316 }
15317 }
15318 else if (function_type_sptr f = is_function_type(type))
15320
15321 if (result)
15322 {
15324 canonicalize(result);
15325 }
15326 }
15327
15328 if (result)
15329 tu.priv_->synthesized_types_.push_back(result);
15330
15331 return result;
15332}
15333
15334/// In a translation unit, lookup the sub-types that make up a given
15335/// function type and if the sub-types are all found, synthesize and
15336/// return a function_type with them.
15337///
15338/// This function is like lookup_function_type_in_translation_unit()
15339/// execept that it constructs the function type from the sub-types
15340/// found in the translation, rather than just looking for the
15341/// function types held by the translation unit. This can be useful
15342/// if the translation unit doesnt hold the function type we are
15343/// looking for (i.e, lookup_function_type_in_translation_unit()
15344/// returned NULL) but we still want to see if the sub-types of the
15345/// function types are present in the translation unit.
15346///
15347/// @param fn_type the function type to consider.
15348///
15349/// @param tu the translation unit to look into.
15350///
15351/// @return the resulting synthesized function type if all its
15352/// sub-types have been found, NULL otherwise.
15355 translation_unit& tu)
15356{
15358
15359 const environment& env = tu.get_environment();
15360
15361 type_base_sptr return_type = fn_type.get_return_type();
15362 type_base_sptr result_return_type;
15363 if (!return_type || env.is_void_type(return_type))
15364 result_return_type = env.get_void_type();
15365 else
15366 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
15367 if (!result_return_type)
15368 return nil;
15369
15371 type_base_sptr parm_type;
15373 for (function_type::parameters::const_iterator i =
15374 fn_type.get_parameters().begin();
15375 i != fn_type.get_parameters().end();
15376 ++i)
15377 {
15378 type_base_sptr t = (*i)->get_type();
15379 parm_type = synthesize_type_from_translation_unit(t, tu);
15380 if (!parm_type)
15381 return nil;
15382 parm.reset(new function_decl::parameter(parm_type,
15383 (*i)->get_index(),
15384 (*i)->get_name(),
15385 (*i)->get_location(),
15386 (*i)->get_variadic_marker(),
15387 (*i)->get_is_artificial()));
15388 parms.push_back(parm);
15389 }
15390
15391 class_or_union_sptr class_type;
15392 const method_type* method = is_method_type(&fn_type);
15393 if (method)
15394 {
15395 class_type = is_class_or_union_type
15397 ABG_ASSERT(class_type);
15398 }
15399
15400 function_type_sptr result_fn_type;
15401
15402 if (class_type)
15403 result_fn_type.reset(new method_type(result_return_type,
15404 class_type,
15405 parms,
15406 method->get_is_const(),
15407 fn_type.get_size_in_bits(),
15408 fn_type.get_alignment_in_bits()));
15409 else
15410 result_fn_type.reset(new function_type(result_return_type,
15411 parms,
15412 fn_type.get_size_in_bits(),
15413 fn_type.get_alignment_in_bits()));
15414
15415 tu.priv_->synthesized_types_.push_back(result_fn_type);
15416 tu.bind_function_type_life_time(result_fn_type);
15417
15418 canonicalize(result_fn_type);
15419 return result_fn_type;
15420}
15421
15422/// Demangle a C++ mangled name and return the resulting string
15423///
15424/// @param mangled_name the C++ mangled name to demangle.
15425///
15426/// @return the resulting mangled name.
15427string
15428demangle_cplus_mangled_name(const string& mangled_name)
15429{
15430 if (mangled_name.empty())
15431 return "";
15432
15433 size_t l = 0;
15434 int status = 0;
15435 char * str = abi::__cxa_demangle(mangled_name.c_str(),
15436 NULL, &l, &status);
15437 string demangled_name = mangled_name;
15438 if (str)
15439 {
15440 ABG_ASSERT(status == 0);
15441 demangled_name = str;
15442 free(str);
15443 str = 0;
15444 }
15445 return demangled_name;
15446}
15447
15448/// Return either the type given in parameter if it's non-null, or the
15449/// void type.
15450///
15451/// @param t the type to consider.
15452///
15453/// @param env the environment to use. If NULL, just abort the
15454/// process.
15455///
15456/// @return either @p t if it is non-null, or the void type.
15457type_base_sptr
15458type_or_void(const type_base_sptr t, const environment& env)
15459{
15460 type_base_sptr r;
15461
15462 if (t)
15463 r = t;
15464 else
15465 r = type_base_sptr(env.get_void_type());
15466
15467 return r;
15468}
15469
15470global_scope::~global_scope()
15471{
15472}
15473
15474/// Test if two types are eligible to the "Linux Kernel Fast Type
15475/// Comparison Optimization", a.k.a LKFTCO.
15476///
15477/// Two types T1 and T2 (who are presumably of the same name and kind)
15478/// are eligible to the LKFTCO if they fulfill the following criteria/
15479///
15480/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
15481/// either class, union or enums.
15482///
15483/// 2/ They are defined in the same translation unit.
15484///
15485/// @param t1 the first type to consider.
15486///
15487/// @param t2 the second type to consider.
15488///
15489/// @return true iff t1 and t2 are eligible to the LKFTCO.
15490static bool
15491types_defined_same_linux_kernel_corpus_public(const type_base& t1,
15492 const type_base& t2)
15493{
15494 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
15495 string t1_file_path, t2_file_path;
15496
15497 /// If the t1 (and t2) are classes/unions/enums from the same linux
15498 /// kernel corpus, let's move on. Otherwise bail out.
15499 if (!(t1_corpus && t2_corpus
15500 && t1_corpus == t2_corpus
15501 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
15502 && (is_class_or_union_type(&t1)
15503 || is_enum_type(&t1))))
15504 return false;
15505
15506 class_or_union *c1 = 0, *c2 = 0;
15507 c1 = is_class_or_union_type(&t1);
15508 c2 = is_class_or_union_type(&t2);
15509
15510 // Two anonymous class types with no naming typedefs cannot be
15511 // eligible to this optimization.
15512 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
15513 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
15514 return false;
15515
15516 // Two anonymous classes with naming typedefs should have the same
15517 // typedef name.
15518 if (c1
15519 && c2
15520 && c1->get_is_anonymous() && c1->get_naming_typedef()
15521 && c2->get_is_anonymous() && c2->get_naming_typedef())
15522 if (c1->get_naming_typedef()->get_name()
15523 != c2->get_naming_typedef()->get_name())
15524 return false;
15525
15526 // Two anonymous enum types cannot be eligible to this optimization.
15527 if (const enum_type_decl *e1 = is_enum_type(&t1))
15528 if (const enum_type_decl *e2 = is_enum_type(&t2))
15529 if (e1->get_is_anonymous() || e2->get_is_anonymous())
15530 return false;
15531
15532 // Look through declaration-only types. That is, get the associated
15533 // definition type.
15536
15537 if (c1 && c2)
15538 {
15539 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
15540 {
15541 if (c1->get_environment().decl_only_class_equals_definition())
15542 // At least one of classes/union is declaration-only.
15543 // Because we are in a context in which a declaration-only
15544 // class/union is equal to all definitions of that
15545 // class/union, we can assume that the two types are
15546 // equal.
15547 return true;
15548 }
15549 }
15550
15551 if (t1.get_size_in_bits() != t2.get_size_in_bits())
15552 return false;
15553
15554 // Look at the file names of the locations of t1 and t2. If they
15555 // are equal, then t1 and t2 are defined in the same file.
15556 {
15557 location l;
15558
15559 if (c1)
15560 l = c1->get_location();
15561 else
15562 l = dynamic_cast<const decl_base&>(t1).get_location();
15563
15564 unsigned line = 0, col = 0;
15565 if (l)
15566 l.expand(t1_file_path, line, col);
15567 if (c2)
15568 l = c2->get_location();
15569 else
15570 l = dynamic_cast<const decl_base&>(t2).get_location();
15571 if (l)
15572 l.expand(t2_file_path, line, col);
15573 }
15574
15575 if (t1_file_path.empty() || t2_file_path.empty())
15576 return false;
15577
15578 if (t1_file_path == t2_file_path)
15579 return true;
15580
15581 return false;
15582}
15583
15584
15585/// Compare a type T against a canonical type.
15586///
15587/// This function is called during the canonicalization process of the
15588/// type T. T is called the "candidate type" because it's in the
15589/// process of being canonicalized. Meaning, it's going to be
15590/// compared to a canonical type C. If T equals C, then the canonical
15591/// type of T is C.
15592///
15593/// The purpose of this function is to allow the debugging of the
15594/// canonicalization of T, if that debugging is activated by
15595/// configuring the libabigail package with
15596/// --enable-debug-type-canonicalization and by running "abidw
15597/// --debug-tc". In that case, T is going to be compared to C twice:
15598/// once with canonical equality and once with structural equality.
15599/// The two comparisons must be equal. Otherwise, the
15600/// canonicalization process is said to be faulty and this function
15601/// aborts.
15602///
15603/// This is a sub-routine of type_base::get_canonical_type_for.
15604///
15605/// @param canonical_type the canonical type to compare the candidate
15606/// type against.
15607///
15608/// @param candidate_type the candidate type to compare against the
15609/// canonical type.
15610///
15611/// @return true iff @p canonical_type equals @p candidate_type.
15612///
15613static bool
15614compare_types_during_canonicalization(const type_base& canonical_type,
15615 const type_base& candidate_type)
15616{
15617#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
15618 const environment& env = canonical_type.get_environment();
15619 if (env.debug_type_canonicalization_is_on())
15620 {
15621 bool canonical_equality = false, structural_equality = false;
15622 env.priv_->allow_type_comparison_results_caching(false);
15623 env.priv_->use_canonical_type_comparison_ = false;
15624 structural_equality = canonical_type == candidate_type;
15625 env.priv_->use_canonical_type_comparison_ = true;
15626 canonical_equality = canonical_type == candidate_type;
15627 env.priv_->allow_type_comparison_results_caching(true);
15628 if (canonical_equality != structural_equality)
15629 {
15630 std::cerr << "structural & canonical equality different for type: "
15631 << canonical_type.get_pretty_representation(true, true)
15632 << std::endl;
15634 }
15635 return structural_equality;
15636 }
15637#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
15638 return canonical_type == candidate_type;
15639}
15640
15641/// Compare a canonical type against a candidate canonical type.
15642///
15643/// This is ultimately a sub-routine of the
15644/// type_base::get_canonical_type_for().
15645///
15646/// The goal of this function is to ease debugging because it can be
15647/// called from within type_base::get_canonical_type_for() from the
15648/// prompt of the debugger (with some breakpoint appropriately set) to
15649/// debug the comparison that happens during type canonicalization,
15650/// between a candidate type being canonicalized, and an existing
15651/// canonical type that is registered in the system, in as returned by
15652/// environment::get_canonical_types()
15653///
15654/// @param canonical_type the canonical type to consider.
15655///
15656/// @param candidate_type the candidate type that is being
15657/// canonicalized, and thus compared to @p canonical_type.
15658///
15659/// @return true iff @p canonical_type compares equal to @p
15660/// candidate_type.
15661static bool
15662compare_canonical_type_against_candidate(const type_base& canonical_type,
15663 const type_base& candidate_type)
15664{
15665 environment& env = const_cast<environment&>(canonical_type.get_environment());
15666
15667 // Before the "*it == it" comparison below is done, let's
15668 // perform on-the-fly-canonicalization. For C types, let's
15669 // consider that an unresolved struct declaration 'struct S'
15670 // is different from a definition 'struct S'. This is
15671 // because normally, at this point all the declarations of
15672 // struct S that are compatible with the definition of
15673 // struct S have already been resolved to that definition,
15674 // during the DWARF parsing. The remaining unresolved
15675 // declaration are thus considered different. With this
15676 // setup we can properly handle cases of two *different*
15677 // struct S being defined in the same binary (in different
15678 // translation units), and a third struct S being only
15679 // declared as an opaque type in a third translation unit of
15680 // its own, with no definition in there. In that case, the
15681 // declaration-only struct S should be left alone and not
15682 // resolved to any of the two definitions of struct S.
15683 bool saved_decl_only_class_equals_definition =
15684 env.decl_only_class_equals_definition();
15685
15686 // Compare types by considering that decl-only classes don't
15687 // equal their definition.
15688 env.decl_only_class_equals_definition(false);
15689 env.priv_->allow_type_comparison_results_caching(true);
15690 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
15691 candidate_type)
15692 || compare_types_during_canonicalization(canonical_type,
15693 candidate_type));
15694 // Restore the state of the on-the-fly-canonicalization and
15695 // the decl-only-class-being-equal-to-a-matching-definition
15696 // flags.
15697 env.priv_->clear_type_comparison_results_cache();
15698 env.priv_->allow_type_comparison_results_caching(false);
15699 env.decl_only_class_equals_definition
15700 (saved_decl_only_class_equals_definition);
15701 return equal;
15702}
15703
15704/// Compare a canonical type against a candidate canonical type.
15705///
15706/// This is ultimately a sub-routine of the
15707/// type_base::get_canonical_type_for().
15708///
15709/// The goal of this function is to ease debugging because it can be
15710/// called from within type_base::get_canonical_type_for() from the
15711/// prompt of the debugger (with some breakpoint appropriately set) to
15712/// debug the comparison that happens during type canonicalization,
15713/// between a candidate type being canonicalized, and an existing
15714/// canonical type that is registered in the system, in as returned by
15715/// environment::get_canonical_types()
15716///
15717/// @param canonical_type the canonical type to consider.
15718///
15719/// @param candidate_type the candidate type that is being
15720/// canonicalized, and thus compared to @p canonical_type.
15721///
15722/// @return true iff @p canonical_type compares equal to @p
15723/// candidate_type.
15724static bool
15725compare_canonical_type_against_candidate(const type_base* canonical_type,
15726 const type_base* candidate_type)
15727{
15728 return compare_canonical_type_against_candidate(*canonical_type,
15729 *candidate_type);
15730}
15731
15732/// Compare a canonical type against a candidate canonical type.
15733///
15734/// This is ultimately a sub-routine of the
15735/// type_base::get_canonical_type_for().
15736///
15737/// The goal of this function is to ease debugging because it can be
15738/// called from within type_base::get_canonical_type_for() from the
15739/// prompt of the debugger (with some breakpoint appropriately set) to
15740/// debug the comparison that happens during type canonicalization,
15741/// between a candidate type being canonicalized, and an existing
15742/// canonical type that is registered in the system, in as returned by
15743/// environment::get_canonical_types()
15744///
15745/// @param canonical_type the canonical type to consider.
15746///
15747/// @param candidate_type the candidate type that is being
15748/// canonicalized, and thus compared to @p canonical_type.
15749///
15750/// @return true iff @p canonical_type compares equal to @p
15751/// candidate_type.
15752static bool
15753compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15754 const type_base_sptr& candidate_type)
15755{
15756 return compare_canonical_type_against_candidate(canonical_type.get(),
15757 candidate_type.get());
15758}
15759
15760/// Test if a candidate for type canonicalization coming from ABIXML
15761/// matches a canonical type by first looking at their hash values.
15762///
15763/// If the two hash values are equal then the candidate is
15764/// structurally compared to the canonical type. If the two hashes
15765/// are different then the two types are considered different and the
15766/// function returns nullptr.
15767///
15768/// If the candidate doesn't come from ABIXML then the function
15769/// returns nullptr.
15770///
15771/// @param cncls the vector of canonical types to consider.
15772///
15773/// @param type the candidate to consider for canonicalization.
15774///
15775/// @return the canonical type from @p cncls that matches the
15776/// candidate @p type.
15777static type_base_sptr
15778candidate_matches_a_canonical_type_hash(const vector<type_base_sptr>& cncls,
15779 type_base& type)
15780{
15781 if (type.get_corpus()
15782 && type.get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
15783 && peek_hash_value(type))
15784 {
15785 // The candidate type comes from ABIXML and does have a stashed
15786 // hash value coming from the ABIXML.
15787
15788 // Let's see if we find a potential canonical type whose hash
15789 // matches the stashed hash and whose canonical type index
15790 // matches it too.
15791 for (const auto& c : cncls)
15792 if (peek_hash_value(type) == peek_hash_value(*c))
15794 // We found a potential canonical type which hash matches the
15795 // stashed hash of the candidate type. Let's compare them to
15796 // see if they match.
15797 if (compare_canonical_type_against_candidate(*c, type))
15798 return c;
15799
15800 // Let's do the same things, but just consideing hash values.
15801 for (const auto& c : cncls)
15802 if (peek_hash_value(type) == peek_hash_value(*c))
15803 // We found a potential canonical type which hash matches the
15804 // stashed hash of the candidate type. Let's compare them to
15805 // see if they match.
15806 if (compare_canonical_type_against_candidate(*c, type))
15807 return c;
15808 }
15809
15810 return nullptr;
15811}
15812
15813/// Test if we should attempt to compute a hash value for a given
15814/// type.
15815///
15816/// For now this function returns true only for types originating from
15817/// ELF. For types originating from ABIXML, for instance, the
15818/// function return false, meaning that types originating from ABIXML
15819/// should NOT be hashed.
15820///
15821/// @param t the type to consider.
15822///
15823/// @return true iff @p type should be considered for hashing.
15824bool
15826{
15827 if (t.get_corpus()
15828 && (t.get_corpus()->get_origin() & corpus::ELF_ORIGIN))
15829 return true;
15830 return false;
15831}
15832
15833/// Compute the canonical type for a given instance of @ref type_base.
15834///
15835/// Consider two types T and T'. The canonical type of T, denoted
15836/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
15837/// otherwise, to compare two types, one just needs to compare their
15838/// canonical types using pointer equality. That makes type
15839/// comparison faster than the structural comparison performed by the
15840/// abigail::ir::equals() overloads.
15841///
15842/// If there is not yet any canonical type for @p t, then @p t is its
15843/// own canonical type. Otherwise, this function returns the
15844/// canonical type of @p t which is the canonical type that has the
15845/// same hash value as @p t and that structurally equals @p t. Note
15846/// that after invoking this function, the life time of the returned
15847/// canonical time is then equals to the life time of the current
15848/// process.
15849///
15850/// @param t a smart pointer to instance of @ref type_base we want to
15851/// compute a canonical type for.
15852///
15853/// @return the canonical type for the current instance of @ref
15854/// type_base.
15855type_base_sptr
15856type_base::get_canonical_type_for(type_base_sptr t)
15857{
15858 if (!t)
15859 return t;
15860
15861 environment& env = const_cast<environment&>(t->get_environment());
15862
15864 // This type should not be canonicalized!
15865 return type_base_sptr();
15866
15867 if (is_decl(t))
15869
15870 // Look through decl-only types (classes, unions and enums)
15871 bool decl_only_class_equals_definition =
15873
15874 class_or_union_sptr class_or_union = is_class_or_union_type(t);
15875
15876 // In the context of types from C++ or languages where we assume the
15877 // "One Definition Rule", we assume that a declaration-only
15878 // non-anonymous class equals all fully defined classes of the same
15879 // name.
15880 //
15881 // Otherwise, all classes, including declaration-only classes are
15882 // canonicalized and only canonical comparison is going to be used
15883 // in the system.
15884 if (decl_only_class_equals_definition)
15885 if (class_or_union)
15887 return type_base_sptr();
15888
15889 class_decl_sptr is_class = is_class_type(t);
15890 if (t->get_canonical_type())
15891 return t->get_canonical_type();
15892
15893 // For classes and union, ensure that an anonymous class doesn't
15894 // have a linkage name. If it does in the future, then me must be
15895 // mindful that the linkage name respects the type identity
15896 // constraints which states that "if two linkage names are different
15897 // then the two types are different".
15901
15902 // We want the pretty representation of the type, but for an
15903 // internal use, not for a user-facing purpose.
15904 //
15905 // If two classe types Foo are declared, one as a class and the
15906 // other as a struct, but are otherwise equivalent, we want their
15907 // pretty representation to be the same. Hence the 'internal'
15908 // argument of ir::get_pretty_representation() is set to true here.
15909 // So in this case, the pretty representation of Foo is going to be
15910 // "class Foo", regardless of its struct-ness. This also applies to
15911 // composite types which would have "class Foo" as a sub-type.
15912 string repr = t->get_cached_pretty_representation(/*internal=*/true);
15913
15914 // If 't' already has a canonical type 'inside' its corpus
15915 // (t_corpus), then this variable is going to contain that canonical
15916 // type.
15917 type_base_sptr canonical_type_present_in_corpus;
15920
15921 type_base_sptr result;
15922 environment::canonical_types_map_type::iterator i = types.find(repr);
15923
15924 if (i == types.end())
15925 {
15926 vector<type_base_sptr> v;
15927 v.push_back(t);
15928 types[repr] = v;
15929 result = t;
15930 }
15931 else
15932 {
15933 vector<type_base_sptr> &v = i->second;
15934 // Look at the canonical types and if the current candidate type
15935 // coming from abixml has the same hash as one of the canonical
15936 // types, then compare the current candidate with the one with a
15937 // matching hash.
15938 result = candidate_matches_a_canonical_type_hash(v, *t);
15939
15940 // Let's compare 't' structurally (i.e, compare its sub-types
15941 // recursively) against the canonical types of the system. If it
15942 // equals a given canonical type C, then it means C is the
15943 // canonical type of 't'. Otherwise, if 't' is different from
15944 // all the canonical types of the system, then it means 't' is a
15945 // canonical type itself.
15946 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15947 !result && it != v.rend();
15948 ++it)
15949 {
15950 bool equal = compare_canonical_type_against_candidate(*it, t);
15951 if (equal)
15952 {
15953 result = *it;
15954 break;
15955 }
15956 }
15957#ifdef WITH_DEBUG_SELF_COMPARISON
15958 if (env.self_comparison_debug_is_on())
15959 {
15960 // So we are debugging the canonicalization process,
15961 // possibly via the use of 'abidw --debug-abidiff <binary>'.
15962 corpus_sptr corp1, corp2;
15963 env.get_self_comparison_debug_inputs(corp1, corp2);
15964 if (corp1 && corp2 && type_originates_from_corpus(t, corp2)
15965 && corp1->get_origin() != corp2->get_origin()
15966 && corp2->get_origin() & corpus::NATIVE_XML_ORIGIN)
15967 {
15968 // If 't' comes from the second corpus, then it *must*
15969 // be equal to its matching canonical type coming from
15970 // the first corpus because the second corpus is the
15971 // abixml representation of the first corpus. In other
15972 // words, all types coming from the second corpus must
15973 // have canonical types coming from the first corpus.
15974 if (result)
15975 {
15976 if (!env.priv_->
15977 check_canonical_type_from_abixml_during_self_comp(t,
15978 result))
15979 {
15980 // The canonical type of the type re-read from abixml
15981 // type doesn't match the canonical type that was
15982 // initially serialized down.
15983 uintptr_t should_have_canonical_type = 0;
15984 string type_id = env.get_type_id_from_type(t.get());
15985 if (type_id.empty())
15986 type_id = "type-id-<not-found>";
15987 else
15988 should_have_canonical_type =
15989 env.get_canonical_type_from_type_id(type_id.c_str());
15990 std::cerr << "error: wrong canonical type for '"
15991 << repr
15992 << "' / type: @"
15993 << std::hex
15994 << t.get()
15995 << "/ canon: @"
15996 << result.get()
15997 << ", type-id: '"
15998 << type_id
15999 << "'. Should have had canonical type: "
16000 << std::hex
16001 << should_have_canonical_type
16002 << std::dec
16003 << std::endl;
16004 }
16005 }
16006 else //!result
16007 {
16008 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
16009 string type_id = env.get_type_id_from_pointer(ptr_val);
16010 if (type_id.empty())
16011 type_id = "type-id-<not-found>";
16012 // We are in the case where 't' is different from all
16013 // the canonical types of the same name that come from
16014 // the first corpus.
16015 //
16016 // If 't' indeed comes from the second corpus then this
16017 // clearly is a canonicalization failure.
16018 //
16019 // There was a problem either during the serialization
16020 // of 't' into abixml, or during the de-serialization
16021 // from abixml into abigail::ir. Further debugging is
16022 // needed to determine what that root cause problem is.
16023 //
16024 // Note that the first canonicalization problem of this
16025 // kind must be fixed before looking at the subsequent
16026 // ones, because the later might well just be
16027 // consequences of the former.
16028 std::cerr << "error: wrong induced canonical type for '"
16029 << repr
16030 << "' from second corpus"
16031 << ", ptr: " << std::hex << t.get()
16032 << " type-id: " << type_id
16033 << " /hash="
16034 << *t->hash_value()
16035 << std::dec
16036 << std::endl;
16037 }
16038 }
16039 if (result)
16040 {
16041 if (!is_type_decl(t))
16042 if (hash_t t_hash = peek_hash_value(*t))
16043 if (hash_t result_hash = peek_hash_value(*result))
16044 if (t_hash != result_hash)
16045 {
16046 std::cerr << "error: type hash mismatch"
16047 << " between type: '"
16048 << repr
16049 << "' @ "
16050 << std::hex
16051 << t.get()
16052 << "/hash="
16053 << *t->hash_value()
16054 << " and its computed canonical type @"
16055 << std::hex
16056 << result.get()
16057 << "/hash="
16058 << std::hex
16059 << *result->hash_value()
16060 << std::dec
16061 << std::endl;
16062 }
16063 }
16064 }
16065#endif //WITH_DEBUG_SELF_COMPARISON
16066
16067 if (!result)
16068 {
16069 v.push_back(t);
16070 result = t;
16071 // we need to generate a canonical type index to sort these
16072 // types that have the same representation and potentially
16073 // same hash value but are canonically different.
16074 t->priv_->canonical_type_index = v.size();
16075 }
16076 }
16077
16078 return result;
16079}
16080
16081/// This method is invoked automatically right after the current
16082/// instance of @ref class_decl has been canonicalized.
16083void
16086
16087/// This is a subroutine of the canonicalize() function.
16088///
16089/// When the canonical type C of type T has just been computed, there
16090/// can be cases where T has member functions that C doesn't have.
16091///
16092/// This is possible because non virtual member functions are not
16093/// taken in account when comparing two types.
16094///
16095/// In that case, this function updates C so that it contains the
16096/// member functions.
16097///
16098/// There can also be cases where C has a method M which is not linked
16099/// to any underlying symbol, whereas in T, M is to link to an
16100/// underlying symbol. In that case, this function updates M in C so
16101/// that it's linked to the same underlying symbol as for M in T.
16102static void
16103maybe_adjust_canonical_type(const type_base_sptr& canonical,
16104 const type_base_sptr& type)
16105{
16106 if (type->get_naked_canonical_type())
16107 return;
16108
16109 class_decl_sptr canonical_class = is_class_type(canonical);
16110
16111 if (class_decl_sptr cl = is_class_type(type))
16112 {
16114 if (canonical_class
16115 && canonical_class.get() != cl.get())
16116 {
16117 // Set symbols of member functions that might be missing
16118 // theirs.
16119 for (class_decl::member_functions::const_iterator i =
16120 cl->get_member_functions().begin();
16121 i != cl->get_member_functions().end();
16122 ++i)
16123 if ((*i)->get_symbol())
16124 {
16125 if (method_decl *m = canonical_class->
16126 find_member_function((*i)->get_linkage_name()))
16127 {
16128 elf_symbol_sptr s1 = (*i)->get_symbol();
16129 if (s1 && !m->get_symbol())
16130 // Method 'm' in the canonical type is not
16131 // linked to the underlying symbol of '*i'.
16132 // Let's link it now. have th
16133 m->set_symbol(s1);
16134 }
16135 else
16136 if (!is_anonymous_type(cl)
16137 && canonical_class->get_corpus()
16138 && cl->get_corpus()
16139 && (cl->get_corpus() == canonical_class->get_corpus()))
16140 // There is a member function defined and publicly
16141 // exported in the other class and the canonical
16142 // class doesn't have that member function. This
16143 // should not have happened! For instance, the
16144 // DWARF reader does merge the member functions of
16145 // classes having the same name so that all of them
16146 // end-up having the same member functions. What's
16147 // going on here?
16149 }
16150
16151 // Set symbols of static data members that might be missing
16152 // theirs.
16153 for (const auto& data_member : cl->get_data_members())
16154 {
16155 if (!get_member_is_static(data_member))
16156 continue;
16157 elf_symbol_sptr sym = data_member->get_symbol();
16158 if (!sym)
16159 continue;
16160 const auto& canonical_data_member =
16161 canonical_class->find_data_member(data_member->get_name());
16162 if (!canonical_data_member)
16163 {
16164 // Two classes my be equivalent (same name, non-static
16165 // sub-objects) and yet not have the same number of
16166 // static data members, if they are coming from
16167 // different corpora. If they are in the same corpus,
16168 // however then that means there is a problem!
16169 if (!is_anonymous_type(cl)
16170 && canonical_class->get_corpus()
16171 && cl->get_corpus()
16172 && canonical_class->get_corpus() == cl->get_corpus())
16174
16175 continue;
16176 }
16177
16178 if (!canonical_data_member->get_symbol())
16179 canonical_data_member->set_symbol(sym);
16180 }
16181 }
16182 }
16183
16184 // Make sure the virtual member functions with exported symbols are
16185 // all added to the set of exported functions of the corpus.
16186
16187 // If we are looking at a non-canonicalized class (for instance, a
16188 // decl-only class that has virtual member functions), let's pretend
16189 // it does have a canonical class so that we can perform the
16190 // necessary virtual member function adjustments
16191 if (class_decl_sptr cl = is_class_type(type))
16193 {
16194 ABG_ASSERT(!canonical_class);
16195 canonical_class = cl;
16196 }
16197
16198 if (canonical_class)
16199 {
16200 if (auto abi_corpus = canonical_class->get_corpus())
16201 {
16202 for (auto& fn : canonical_class->get_member_functions())
16203 {
16204 if (elf_symbol_sptr sym = fn->get_symbol())
16205 {
16206 if (sym->is_defined() && sym->is_public())
16207 {
16208 fn->set_is_in_public_symbol_table(true);
16209 auto b = abi_corpus->get_exported_decls_builder();
16210 b->maybe_add_fn_to_exported_fns(fn.get());
16211 }
16212 else if (!sym->is_defined())
16213 abi_corpus->get_undefined_functions().insert(fn.get());
16214 }
16215 }
16216 }
16217 }
16218
16219 // If an artificial function type equals a non-artfificial one in
16220 // the system, then the canonical type of both should be deemed
16221 // non-artificial. This is important because only non-artificial
16222 // canonical function types are emitted out into abixml, so if don't
16223 // do this we risk missing to emit some function types.
16224 if (is_function_type(type))
16225 if (type->get_is_artificial() != canonical->get_is_artificial())
16226 canonical->set_is_artificial(false);
16227}
16228
16229/// Compute the canonical type of a given type.
16230///
16231/// It means that after invoking this function, comparing the intance
16232/// instance @ref type_base and another one (on which
16233/// type_base::enable_canonical_equality() would have been invoked as
16234/// well) is performed by just comparing the pointer values of the
16235/// canonical types of both types. That equality comparison is
16236/// supposedly faster than structural comparison of the types.
16237///
16238/// @param t a smart pointer to the instance of @ref type_base for
16239/// which to compute the canonical type. After this call,
16240/// t->get_canonical_type() will return the newly computed canonical
16241/// type.
16242///
16243/// @param do_log if true then logs are emitted about canonicalization
16244/// progress.
16245///
16246/// @param show_stats if true and if @p do_log is true as well, then
16247/// more detailed logs are emitted about canonicalization.
16248///
16249/// @return the canonical type computed for @p t.
16250type_base_sptr
16251canonicalize(type_base_sptr t, bool do_log, bool show_stats)
16252{
16253 if (!t)
16254 return t;
16255
16256 if (t->get_canonical_type())
16257 return t->get_canonical_type();
16258
16259 if (do_log && show_stats)
16260 std::cerr << "Canonicalization of type '"
16261 << t->get_pretty_representation(true, true)
16262 << "/@#" << std::hex << t.get() << ": ";
16263
16265
16266 if (do_log && show_stats)
16267 tmr.start();
16268 type_base_sptr canonical = type_base::get_canonical_type_for(t);
16269
16270 if (do_log && show_stats)
16271 tmr.stop();
16272
16273 if (do_log && show_stats)
16274 std::cerr << tmr << "\n";
16275
16276 maybe_adjust_canonical_type(canonical, t);
16277
16278 t->priv_->canonical_type = canonical;
16279 t->priv_->naked_canonical_type = canonical.get();
16280
16281 if (canonical)
16282 if (!t->priv_->canonical_type_index)
16283 t->priv_->canonical_type_index = canonical->priv_->canonical_type_index;
16284
16285 if (class_decl_sptr cl = is_class_type(t))
16286 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
16287 if ((canonical = d->get_canonical_type()))
16288 {
16289 d->priv_->canonical_type = canonical;
16290 d->priv_->naked_canonical_type = canonical.get();
16291 }
16292
16293 if (canonical)
16294 {
16295 if (decl_base_sptr d = is_decl_slow(canonical))
16296 {
16297 scope_decl *scope = d->get_scope();
16298 // Add the canonical type to the set of canonical types
16299 // belonging to its scope.
16300 if (scope)
16301 {
16302 if (is_type(scope))
16303 // The scope in question is itself a type (e.g, a class
16304 // or union). Let's call that type ST. We want to add
16305 // 'canonical' to the set of canonical types belonging
16306 // to ST.
16307 if (type_base_sptr c = is_type(scope)->get_canonical_type())
16308 // We want to add 'canonical' to the set of
16309 // canonical types belonging to the canonical type
16310 // of ST. That way, just looking at the canonical
16311 // type of ST is enough to get the types that belong
16312 // to the scope of the class of equivalence of ST.
16313 scope = is_scope_decl(is_decl(c)).get();
16314 scope->get_canonical_types().insert(canonical);
16315 }
16316 // else, if the type doesn't have a scope, it's not meant to be
16317 // emitted. This can be the case for the result of the
16318 // function strip_typedef, for instance.
16319 }
16320 }
16321
16322 t->on_canonical_type_set();
16323 return canonical;
16324}
16325
16326/// Set the definition of this declaration-only @ref decl_base.
16327///
16328/// @param d the new definition to set.
16329void
16331{
16333 priv_->definition_of_declaration_ = d;
16334 if (type_base *t = is_type(this))
16335 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
16336 t->priv_->canonical_type = canonical_type;
16337
16338 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
16339}
16340
16341/// The constructor of @ref type_base.
16342///
16343/// @param s the size of the type, in bits.
16344///
16345/// @param a the alignment of the type, in bits.
16346type_base::type_base(const environment& e, size_t s, size_t a)
16347 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
16348 priv_(new priv(s, a))
16349{}
16350
16351/// Return the hash value of the current IR node.
16352///
16353/// Note that upon the first invocation, this member functions
16354/// computes the hash value and returns it. Subsequent invocations
16355/// just return the hash value that was previously calculated.
16356///
16357/// @return the hash value of the current IR node.
16358hash_t
16360{
16361 type_base::hash do_hash;
16362 return do_hash(this);
16363}
16364
16365/// Getter of the canonical type of the current instance of @ref
16366/// type_base.
16367///
16368/// @return a smart pointer to the canonical type of the current
16369/// intance of @ref type_base, or an empty smart pointer if the
16370/// current instance of @ref type_base doesn't have any canonical
16371/// type.
16372type_base_sptr
16374{return priv_->canonical_type.lock();}
16375
16376/// Getter of the canonical type pointer.
16377///
16378/// Note that this function doesn't return a smart pointer, but rather
16379/// the underlying pointer managed by the smart pointer. So it's as
16380/// fast as possible. This getter is to be used in code paths that
16381/// are proven to be performance hot spots; especially, when comparing
16382/// sensitive types like class, function, pointers and reference
16383/// types. Those are compared extremely frequently and thus, their
16384/// accessing the canonical type must be fast.
16385///
16386/// @return the canonical type pointer, not managed by a smart
16387/// pointer.
16388type_base*
16390{return priv_->naked_canonical_type;}
16391
16392/// Get the pretty representation of the current type.
16393///
16394/// The pretty representation is retrieved from a cache. If the cache
16395/// is empty, this function computes the pretty representation, put it
16396/// in the cache and returns it.
16397///
16398/// Please note that if this function is called too early in the life
16399/// cycle of the type (before the type is fully constructed), then the
16400/// pretty representation that is cached is going to represent a
16401/// non-complete (and thus wrong) representation of the type. Thus
16402/// this function must be called only once the type is fully
16403/// constructed.
16404///
16405/// @param internal if true, then the pretty representation is to be
16406/// used for purpuses that are internal to the libabigail library
16407/// itself. If you don't know what this means, then you probably
16408/// should set this parameter to "false".
16409///
16410/// @return a reference to a cached @ref interned_string holding the
16411/// pretty representation of the current type.
16412const interned_string&
16414{
16415 if (internal)
16416 {
16417 if (priv_->internal_cached_repr_.empty())
16418 {
16419 string r = ir::get_pretty_representation(this, internal);
16420 priv_->internal_cached_repr_ = get_environment().intern(r);
16421 }
16422 return priv_->internal_cached_repr_;
16423 }
16424
16425 if (priv_->cached_repr_.empty())
16426 {
16427 string r = ir::get_pretty_representation(this, internal);
16428 priv_->cached_repr_ = get_environment().intern(r);
16429 }
16430
16431 return priv_->cached_repr_;
16432}
16433
16434/// Compares two instances of @ref type_base.
16435///
16436/// If the two intances are different, set a bitfield to give some
16437/// insight about the kind of differences there are.
16438///
16439/// @param l the first artifact of the comparison.
16440///
16441/// @param r the second artifact of the comparison.
16442///
16443/// @param k a pointer to a bitfield that gives information about the
16444/// kind of changes there are between @p l and @p r. This one is set
16445/// iff @p is non-null and if the function returns false.
16446///
16447/// Please note that setting k to a non-null value does have a
16448/// negative performance impact because even if @p l and @p r are not
16449/// equal, the function keeps up the comparison in order to determine
16450/// the different kinds of ways in which they are different.
16451///
16452/// @return true if @p l equals @p r, false otherwise.
16453bool
16454equals(const type_base& l, const type_base& r, change_kind* k)
16455{
16456 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
16458 if (!result)
16459 if (k)
16461 ABG_RETURN(result);
16462}
16463
16464/// Return true iff both type declarations are equal.
16465///
16466/// Note that this doesn't test if the scopes of both types are equal.
16467bool
16469{return equals(*this, other, 0);}
16470
16471/// Inequality operator.
16472///
16473///@param other the instance of @ref type_base to compare the current
16474/// instance against.
16475///
16476/// @return true iff the current instance is different from @p other.
16477bool
16479{return !operator==(other);}
16480
16481/// Setter for the size of the type.
16482///
16483/// @param s the new size -- in bits.
16484void
16486{priv_->size_in_bits = s;}
16487
16488/// Getter for the size of the type.
16489///
16490/// @return the size in bits of the type.
16491size_t
16493{return priv_->size_in_bits;}
16494
16495/// Setter for the alignment of the type.
16496///
16497/// @param a the new alignment -- in bits.
16498void
16500{priv_->alignment_in_bits = a;}
16501
16502/// Getter for the alignment of the type.
16503///
16504/// @return the alignment of the type in bits.
16505size_t
16507{return priv_->alignment_in_bits;}
16508
16509/// Default implementation of traversal for types. This function does
16510/// nothing. It must be implemented by every single new type that is
16511/// written.
16512///
16513/// Please look at e.g, class_decl::traverse() for an example of how
16514/// to implement this.
16515///
16516/// @param v the visitor used to visit the type.
16517bool
16519{
16520 if (v.type_node_has_been_visited(this))
16521 return true;
16522
16523 v.visit_begin(this);
16524 bool result = v.visit_end(this);
16526
16527 return result;
16528}
16529
16530type_base::~type_base()
16531{delete priv_;}
16532
16533// </type_base definitions>
16534
16535// <real_type definitions>
16536
16537/// Bitwise OR operator for real_type::modifiers_type.
16538///
16539/// @param l the left-hand side operand.
16540///
16541/// @param r the right-hand side operand.
16542///
16543/// @return the result of the bitwise OR.
16546{
16547 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16548 |
16549 static_cast<unsigned>(r));
16550}
16551
16552/// Bitwise AND operator for real_type::modifiers_type.
16553///
16554/// @param l the left-hand side operand.
16555///
16556/// @param r the right-hand side operand.
16557///
16558/// @return the result of the bitwise AND.
16561{
16562 return static_cast<real_type::modifiers_type>(static_cast<unsigned>(l)
16563 &
16564 static_cast<unsigned>(r));
16565}
16566
16567/// Bitwise one's complement operator for real_type::modifiers_type.
16568///
16569/// @param l the left-hand side operand.
16570///
16571/// @param r the right-hand side operand.
16572///
16573/// @return the result of the bitwise one's complement operator.
16576{
16577 return static_cast<real_type::modifiers_type>(~static_cast<unsigned>(l));
16578}
16579
16580/// Bitwise |= operator for real_type::modifiers_type.
16581///
16582/// @param l the left-hand side operand.
16583///
16584/// @param r the right-hand side operand.
16585///
16586/// @return the result of the bitwise |=.
16589{
16590 l = l | r;
16591 return l;
16592}
16593
16594/// Bitwise &= operator for real_type::modifiers_type.
16595///
16596/// @param l the left-hand side operand.
16597///
16598/// @param r the right-hand side operand.
16599///
16600/// @return the result of the bitwise &=.
16603{
16604 l = l & r;
16605 return l;
16606}
16607
16608/// Parse a word containing one real type modifier.
16609///
16610/// A word is considered to be a string of characters that doesn't
16611/// contain any white space.
16612///
16613/// @param word the word to parse. It is considered to be a string of
16614/// characters that doesn't contain any white space.
16615///
16616/// @param modifiers out parameter. It's set by this function to the
16617/// parsed modifier iff the function returned true.
16618///
16619/// @return true iff @word was successfully parsed.
16620static bool
16621parse_real_type_modifier(const string& word,
16622 real_type::modifiers_type &modifiers)
16623{
16624 if (word == "signed")
16625 modifiers |= real_type::SIGNED_MODIFIER;
16626 else if (word == "unsigned")
16627 modifiers |= real_type::UNSIGNED_MODIFIER;
16628 else if (word == "short")
16629 modifiers |= real_type::SHORT_MODIFIER;
16630 else if (word == "long")
16631 modifiers |= real_type::LONG_MODIFIER;
16632 else if (word == "long long")
16633 modifiers |= real_type::LONG_LONG_MODIFIER;
16634 else
16635 return false;
16636
16637 return true;
16638}
16639
16640/// Parse a base type of a real type from a string.
16641///
16642/// @param type_name the type name to parse.
16643///
16644/// @param base out parameter. This is set to the resulting base type
16645/// parsed, iff the function returned true.
16646///
16647/// @return true iff the function could successfully parse the base
16648/// type.
16649static bool
16650parse_base_real_type(const string& type_name,
16652{
16653 if (type_name == "int")
16655 else if (type_name == "char")
16657 else if (type_name == "bool" || type_name == "_Bool")
16659 else if (type_name == "double")
16661 else if (type_name =="float")
16663 else if (type_name == "char16_t")
16665 else if (type_name == "char32_t")
16667 else if (type_name == "wchar_t")
16669 else if (type_name == "__ARRAY_SIZE_TYPE__")
16671 else if (type_name == "sizetype")
16672 base = real_type::SIZE_BASE_TYPE;
16673 else if (type_name == "ssizetype")
16674 base = real_type::SSIZE_BASE_TYPE;
16675 else if (type_name == "bitsizetype")
16676 base = real_type::BIT_SIZE_BASE_TYPE;
16677 else if (type_name == "sbitsizetype")
16678 base = real_type::SBIT_SIZE_BASE_TYPE;
16679 else
16680 return false;
16681
16682 return true;
16683}
16684
16685/// Parse a real type from a string.
16686///
16687/// @param type_name the string containing the real type to parse.
16688///
16689/// @param base out parameter. Is set by this function to the base
16690/// type of the real type, iff the function returned true.
16691///
16692/// @param modifiers out parameter If set by this function to the
16693/// modifier of the real type, iff the function returned true.
16694///
16695/// @return true iff the function could parse a real type from @p
16696/// type_name.
16697static bool
16698parse_real_type(const string& type_name,
16700 real_type::modifiers_type& modifiers)
16701{
16702 string input = type_name;
16703 string::size_type len = input.length();
16704 string::size_type cur_pos = 0, prev_pos = 0;
16705 string cur_word, prev_word;
16706 bool ok = false;
16707
16708 while (cur_pos < len)
16709 {
16710 if (cur_pos < len && isspace(input[cur_pos]))
16711 do
16712 ++cur_pos;
16713 while (cur_pos < len && isspace(input[cur_pos]));
16714
16715 prev_pos = cur_pos;
16716 cur_pos = input.find(' ', prev_pos);
16717 prev_word = cur_word;
16718 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16719
16720 if (cur_pos < len
16721 && cur_word == "long"
16722 && prev_word != "long")
16723 {
16724 if (cur_pos < len && isspace(input[cur_pos]))
16725 do
16726 ++cur_pos;
16727 while (cur_pos < len && isspace(input[cur_pos]));
16728 prev_pos = cur_pos;
16729
16730 cur_pos = input.find(' ', prev_pos);
16731 string saved_prev_word = prev_word;
16732 prev_word = cur_word;
16733 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16734 if (cur_word == "long")
16735 cur_word = "long long";
16736 else
16737 {
16738 cur_pos = prev_pos;
16739 cur_word = prev_word;
16740 prev_word = saved_prev_word;
16741 }
16742 }
16743
16744 if (!parse_real_type_modifier(cur_word, modifiers))
16745 {
16746 if (!parse_base_real_type(cur_word, base))
16747 return false;
16748 else
16749 ok = true;
16750 }
16751 else
16752 ok = true;
16753 }
16754
16755 return ok;
16756}
16757
16758/// Parse a real type from a string.
16759///
16760/// @param str the string containing the real type to parse.
16761///
16762///@param type the resulting @ref real_type. Is set to the result
16763///of the parse, iff the function returns true.
16764///
16765/// @return true iff the function could parse a real type from @p
16766/// str.
16767bool
16768parse_real_type(const string& str, real_type& type)
16769{
16771 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16772
16773 if (!parse_real_type(str, base_type, modifiers))
16774 return false;
16775
16776 // So this is a real type.
16777 real_type int_type(base_type, modifiers);
16778 type = int_type;
16779 return true;
16780}
16781
16782/// Default constructor of the @ref real_type.
16784 : base_(INT_BASE_TYPE),
16785 modifiers_(NO_MODIFIER)
16786{}
16787
16788/// Constructor of the @ref real_type.
16789///
16790/// @param b the base type of the real type.
16791///
16792/// @param m the modifiers of the real type.
16794 : base_(b), modifiers_(m)
16795{}
16796
16797/// Constructor of the @ref real_type.
16798///
16799/// @param the name of the real type to parse to initialize the
16800/// current instance of @ref real_type.
16801real_type::real_type(const string& type_name)
16802 : base_(INT_BASE_TYPE),
16803 modifiers_(NO_MODIFIER)
16804{
16805 bool could_parse = parse_real_type(type_name, base_, modifiers_);
16806 ABG_ASSERT(could_parse);
16807}
16808
16809/// Getter of the base type of the @ref real_type.
16810///
16811/// @return the base type of the @ref real_type.
16814{return base_;}
16815
16816/// Getter of the modifiers bitmap of the @ref real_type.
16817///
16818/// @return the modifiers bitmap of the @ref real_type.
16821{return modifiers_;}
16822
16823/// Setter of the modifiers bitmap of the @ref real_type.
16824///
16825/// @param m the new modifiers.
16826void
16828{modifiers_ = m;}
16829
16830/// Equality operator for the @ref real_type.
16831///
16832/// @param other the other real type to compare against.
16833///
16834/// @return true iff @p other equals the current instance of @ref
16835/// real_type.
16836bool
16838{return base_ == other.base_ && modifiers_ == other.modifiers_;}
16839
16840/// Return the string representation of the current instance of @ref
16841/// real_type.
16842///
16843/// @param internal if true the string representation is to be used
16844/// for internal purposes. In general, it means it's for type
16845/// canonicalization purposes.
16846///
16847/// @return the string representation of the current instance of @ref
16848/// real_type.
16849string
16850real_type::to_string(bool internal) const
16851{
16852 string result;
16853
16854 // Look at modifiers ...
16855 if (modifiers_ & SIGNED_MODIFIER)
16856 result += "signed ";
16857 if (modifiers_ & UNSIGNED_MODIFIER)
16858 result += "unsigned ";
16859 if (!internal)
16860 {
16861 // For canonicalization purposes, we won't emit the "short, long, or
16862 // long long" modifiers. This is because on some platforms, "long
16863 // int" and "long long int" might have the same size. In those
16864 // cases, we want the two types to be equivalent if they have the
16865 // same size. If they don't have the same internal string
16866 // representation, they'd automatically have different canonical
16867 // types and thus be canonically different.
16868 if (modifiers_ & SHORT_MODIFIER)
16869 result += "short ";
16870 if (modifiers_ & LONG_MODIFIER)
16871 result += "long ";
16872 if (modifiers_ & LONG_LONG_MODIFIER)
16873 result += "long long ";
16874 }
16875
16876 // ... and look at base types.
16877 if (base_ == INT_BASE_TYPE)
16878 result += "int";
16879 else if (base_ == CHAR_BASE_TYPE)
16880 result += "char";
16881 else if (base_ == BOOL_BASE_TYPE)
16882 result += "bool";
16883 else if (base_ == DOUBLE_BASE_TYPE)
16884 result += "double";
16885 else if (base_ == FLOAT_BASE_TYPE)
16886 result += "float";
16887 else if (base_ == CHAR16_T_BASE_TYPE)
16888 result += "char16_t";
16889 else if (base_ == CHAR32_T_BASE_TYPE)
16890 result += "char32_t";
16891 else if (base_ == WCHAR_T_BASE_TYPE)
16892 result += "wchar_t";
16893 else if (base_ == ARRAY_SIZE_BASE_TYPE)
16894 result += "__ARRAY_SIZE_TYPE__";
16895 else if (base_ == SIZE_BASE_TYPE)
16896 result += "sizetype";
16897 else if (base_ == SSIZE_BASE_TYPE)
16898 result += "ssizetype";
16899 else if (base_ == BIT_SIZE_BASE_TYPE)
16900 result += "bitsizetype";
16901 else if (base_ == SBIT_SIZE_BASE_TYPE)
16902 result += "sbitsizetype";
16903 return result;
16904}
16905
16906/// Convert the current instance of @ref real_type into its string
16907/// representation.
16908///
16909/// @return the string representation of the current instance of @ref
16910/// real_type.
16911real_type::operator string() const
16912{return to_string();}
16913
16914// </real_type definitions>
16915
16916//<type_decl definitions>
16917
16918/// Constructor.
16919///
16920/// @param env the environment we are operating from.
16921///
16922/// @param name the name of the type declaration.
16923///
16924/// @param size_in_bits the size of the current type_decl, in bits.
16925///
16926/// @param alignment_in_bits the alignment of the current typ, in
16927/// bits.
16928///
16929/// @param locus the source location of the current type declaration.
16930///
16931/// @param linkage_name the linkage_name of the current type declaration.
16932///
16933/// @param vis the visibility of the type declaration.
16934type_decl::type_decl(const environment& env,
16935 const string& name,
16936 size_t size_in_bits,
16937 size_t alignment_in_bits,
16938 const location& locus,
16939 const string& linkage_name,
16940 visibility vis)
16941
16942 : type_or_decl_base(env,
16943 BASIC_TYPE
16944 | ABSTRACT_TYPE_BASE
16945 | ABSTRACT_DECL_BASE),
16946 decl_base(env, name, locus, linkage_name, vis),
16947 type_base(env, size_in_bits, alignment_in_bits)
16948{
16950
16952 real_type::modifiers_type modifiers = real_type::NO_MODIFIER;
16953 real_type int_type(base_type, modifiers);
16954 if (parse_real_type(name, int_type))
16955 {
16956 // Convert the real_type into its canonical string
16957 // representation.
16958 string real_type_name = int_type;
16959
16960 // Set the name of this type_decl to the canonical string
16961 // representation above
16962 set_name(real_type_name);
16964
16965 if (!get_linkage_name().empty())
16966 set_linkage_name(real_type_name);
16967 }
16968}
16969
16970/// Return the hash value of the current IR node.
16971///
16972/// Note that upon the first invocation, this member functions
16973/// computes the hash value and returns it. Subsequent invocations
16974/// just return the hash value that was previously calculated.
16975///
16976/// @return the hash value of the current IR node.
16977hash_t
16979{
16981 return h;
16982}
16983
16984/// Compares two instances of @ref type_decl.
16985///
16986/// If the two intances are different, set a bitfield to give some
16987/// insight about the kind of differences there are.
16988///
16989/// @param l the first artifact of the comparison.
16990///
16991/// @param r the second artifact of the comparison.
16992///
16993/// @param k a pointer to a bitfield that gives information about the
16994/// kind of changes there are between @p l and @p r. This one is set
16995/// iff @p k is non-null and the function returns false.
16996///
16997/// Please note that setting k to a non-null value does have a
16998/// negative performance impact because even if @p l and @p r are not
16999/// equal, the function keeps up the comparison in order to determine
17000/// the different kinds of ways in which they are different.
17001///
17002/// @return true if @p l equals @p r, false otherwise.
17003bool
17004equals(const type_decl& l, const type_decl& r, change_kind* k)
17005{
17006 bool result = false;
17007
17008 // Consider the types as decls to compare their decls-related
17009 // properties.
17010 result = equals(static_cast<const decl_base&>(l),
17011 static_cast<const decl_base&>(r),
17012 k);
17013 if (!k && !result)
17015
17016 // Now consider the types a "types' to compare their size-related
17017 // properties.
17018 result &= equals(static_cast<const type_base&>(l),
17019 static_cast<const type_base&>(r),
17020 k);
17021 ABG_RETURN(result);
17022}
17023
17024/// Return true if both types equals.
17025///
17026/// This operator re-uses the overload that takes a decl_base.
17027///
17028/// Note that this does not check the scopes of any of the types.
17029///
17030/// @param o the other type_decl to check agains.
17031bool
17033{
17034 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17035 if (!other)
17036 return false;
17037 return *this == *other;
17038}
17039
17040/// Return true if both types equals.
17041///
17042/// Note that this does not check the scopes of any of the types.
17043///
17044/// @param o the other type_decl to check against.
17045bool
17047{
17048 const type_decl* other = dynamic_cast<const type_decl*>(&o);
17049 if (!other)
17050 return false;
17051 return try_canonical_compare(this, other);
17052}
17053
17054/// Return true if both types equals.
17055///
17056/// Note that this does not check the scopes of any of the types.
17057///
17058/// @param o the other type_decl to check against.
17059///
17060/// @return true iff the current isntance equals @p o
17061bool
17063{
17064 const decl_base& other = o;
17065 return *this == other;
17066}
17067
17068/// Return true if both types equals.
17069///
17070/// Note that this does not check the scopes of any of the types.
17071///
17072/// @param o the other type_decl to check against.
17073///
17074/// @return true iff the current isntance equals @p o
17075bool
17077{return !operator==(o);}
17078
17079/// Return true if both types equals.
17080///
17081/// Note that this does not check the scopes of any of the types.
17082///
17083/// @param o the other type_decl to check against.
17084///
17085/// @return true iff the current isntance equals @p o
17086bool
17088{return !operator==(o);}
17089
17090/// Inequality operator.
17091///
17092/// @param o the other type to compare against.
17093///
17094/// @return true iff the current instance is different from @p o.
17095bool
17097{return !operator==(o);}
17098
17099/// Equality operator for @ref type_decl_sptr.
17100///
17101/// @param l the first operand to compare.
17102///
17103/// @param r the second operand to compare.
17104///
17105/// @return true iff @p l equals @p r.
17106bool
17108{
17109 if (!!l != !!r)
17110 return false;
17111 if (l.get() == r.get())
17112 return true;
17113 return *l == *r;
17114}
17115
17116/// Inequality operator for @ref type_decl_sptr.
17117///
17118/// @param l the first operand to compare.
17119///
17120/// @param r the second operand to compare.
17121///
17122/// @return true iff @p l is different from @p r.
17123bool
17125{return !operator==(l, r);}
17126
17127/// Implementation for the virtual qualified name builder for @ref
17128/// type_decl.
17129///
17130/// @param qualified_name the output parameter to hold the resulting
17131/// qualified name.
17132///
17133/// @param internal set to true if the call is intended for an
17134/// internal use (for technical use inside the library itself), false
17135/// otherwise. If you don't know what this is for, then set it to
17136/// false.
17137void
17139 bool internal) const
17140{qualified_name = get_qualified_name(internal);}
17141
17142/// Implementation for the virtual qualified name builder for @ref
17143/// type_decl.
17144///
17145/// @param qualified_name the output parameter to hold the resulting
17146/// qualified name.
17147///
17148/// @param internal set to true if the call is intended for an
17149/// internal use (for technical use inside the library itself), false
17150/// otherwise. If you don't know what this is for, then set it to
17151/// false.
17152const interned_string&
17154{
17155 const environment& env = get_environment();
17156
17157
17158 if (internal)
17159 if (is_real_type(this))
17160 {
17162 {
17163 if (decl_base::priv_->internal_qualified_name_.empty())
17164 decl_base::priv_->internal_qualified_name_ =
17165 env.intern(get_internal_real_type_name(this));
17166 return decl_base::priv_->internal_qualified_name_;
17167 }
17168 else
17169 {
17170 decl_base::priv_->temporary_internal_qualified_name_ =
17171 env.intern(get_internal_real_type_name(this));
17172 return decl_base::priv_->temporary_internal_qualified_name_;
17173 }
17174 }
17175
17176 return decl_base::get_qualified_name(/*internal=*/false);
17177}
17178
17179/// Get the pretty representation of the current instance of @ref
17180/// type_decl.
17181///
17182/// @param internal set to true if the call is intended to get a
17183/// representation of the decl (or type) for the purpose of canonical
17184/// type comparison. This is mainly used in the function
17185/// type_base::get_canonical_type_for().
17186///
17187/// In other words if the argument for this parameter is true then the
17188/// call is meant for internal use (for technical use inside the
17189/// library itself), false otherwise. If you don't know what this is
17190/// for, then set it to false.
17191///
17192/// @param qualified_name if true, names emitted in the pretty
17193/// representation are fully qualified.
17194///
17195/// @return the pretty representatin of the @ref type_decl.
17196string
17198 bool qualified_name) const
17199{
17200 if (internal)
17201 if (is_real_type(this))
17202 return get_internal_real_type_name(this);
17203
17204 if (qualified_name)
17205 return get_qualified_name(internal);
17206 return get_name();
17207}
17208
17209/// This implements the ir_traversable_base::traverse pure virtual
17210/// function.
17211///
17212/// @param v the visitor used on the current instance.
17213///
17214/// @return true if the entire IR node tree got traversed, false
17215/// otherwise.
17216bool
17218{
17219 if (v.type_node_has_been_visited(this))
17220 return true;
17221
17222 v.visit_begin(this);
17223 bool result = v.visit_end(this);
17225
17226 return result;
17227}
17228
17229type_decl::~type_decl()
17230{}
17231//</type_decl definitions>
17232
17233// <scope_type_decl definitions>
17234
17235/// Constructor.
17236///
17237/// @param env the environment we are operating from.
17238///
17239/// @param name the name of the type.
17240///
17241/// @param size_in_bits the size of the type, in bits.
17242///
17243/// @param alignment_in_bits the alignment of the type, in bits.
17244///
17245/// @param locus the source location where the type is defined.
17246///
17247/// @param vis the visibility of the type.
17248scope_type_decl::scope_type_decl(const environment& env,
17249 const string& name,
17250 size_t size_in_bits,
17251 size_t alignment_in_bits,
17252 const location& locus,
17253 visibility vis)
17254 : type_or_decl_base(env,
17255 ABSTRACT_SCOPE_TYPE_DECL
17256 | ABSTRACT_TYPE_BASE
17257 | ABSTRACT_DECL_BASE),
17258 decl_base(env, name, locus, "", vis),
17259 type_base(env, size_in_bits, alignment_in_bits),
17260 scope_decl(env, name, locus)
17261{}
17262
17263/// Compares two instances of @ref scope_type_decl.
17264///
17265/// If the two intances are different, set a bitfield to give some
17266/// insight about the kind of differences there are.
17267///
17268/// @param l the first artifact of the comparison.
17269///
17270/// @param r the second artifact of the comparison.
17271///
17272/// @param k a pointer to a bitfield that gives information about the
17273/// kind of changes there are between @p l and @p r. This one is set
17274/// iff @p k is non-null and the function returns false.
17275///
17276/// Please note that setting k to a non-null value does have a
17277/// negative performance impact because even if @p l and @p r are not
17278/// equal, the function keeps up the comparison in order to determine
17279/// the different kinds of ways in which they are different.
17280///
17281/// @return true if @p l equals @p r, false otherwise.
17282bool
17284{
17285 bool result = equals(static_cast<const scope_decl&>(l),
17286 static_cast<const scope_decl&>(r),
17287 k);
17288
17289 if (!k && !result)
17291
17292 result &= equals(static_cast<const type_base&>(l),
17293 static_cast<const type_base&>(r),
17294 k);
17295
17296 ABG_RETURN(result);
17297}
17298
17299/// Equality operator between two scope_type_decl.
17300///
17301/// Note that this function does not consider the scope of the scope
17302/// types themselves.
17303///
17304/// @return true iff both scope types are equal.
17305bool
17307{
17308 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
17309 if (!other)
17310 return false;
17311 return try_canonical_compare(this, other);
17312}
17313
17314/// Equality operator between two scope_type_decl.
17315///
17316/// This re-uses the equality operator that takes a decl_base.
17317///
17318/// @param o the other scope_type_decl to compare against.
17319///
17320/// @return true iff both scope types are equal.
17321bool
17323{
17324 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17325 if (!other)
17326 return false;
17327
17328 return *this == *other;
17329}
17330
17331/// Traverses an instance of @ref scope_type_decl, visiting all the
17332/// sub-types and decls that it might contain.
17333///
17334/// @param v the visitor that is used to visit every IR sub-node of
17335/// the current node.
17336///
17337/// @return true if either
17338/// - all the children nodes of the current IR node were traversed
17339/// and the calling code should keep going with the traversing.
17340/// - or the current IR node is already being traversed.
17341/// Otherwise, returning false means that the calling code should not
17342/// keep traversing the tree.
17343bool
17345{
17346 if (visiting())
17347 return true;
17348
17349 if (v.type_node_has_been_visited(this))
17350 return true;
17351
17352 if (v.visit_begin(this))
17353 {
17354 visiting(true);
17355 for (scope_decl::declarations::const_iterator i =
17356 get_member_decls().begin();
17357 i != get_member_decls ().end();
17358 ++i)
17359 if (!(*i)->traverse(v))
17360 break;
17361 visiting(false);
17362 }
17363
17364 bool result = v.visit_end(this);
17366
17367 return result;
17368}
17369
17370scope_type_decl::~scope_type_decl()
17371{}
17372// </scope_type_decl definitions>
17373
17374// <namespace_decl>
17375
17376/// Constructor.
17377///
17378/// @param the environment we are operatin from.
17379///
17380/// @param name the name of the namespace.
17381///
17382/// @param locus the source location where the namespace is defined.
17383///
17384/// @param vis the visibility of the namespace.
17386 const string& name,
17387 const location& locus,
17388 visibility vis)
17389 // We need to call the constructor of decl_base directly here
17390 // because it is virtually inherited by scope_decl. Note that we
17391 // just implicitely call the default constructor for scope_decl
17392 // here, as what we really want is to initialize the decl_base
17393 // subobject. Wow, virtual inheritance is useful, but setting it
17394 // up is ugly.
17395 : type_or_decl_base(env,
17396 NAMESPACE_DECL
17397 | ABSTRACT_DECL_BASE
17398 | ABSTRACT_SCOPE_DECL),
17399 decl_base(env, name, locus, "", vis),
17400 scope_decl(env, name, locus)
17401{
17403}
17404
17405/// Build and return a copy of the pretty representation of the
17406/// namespace.
17407///
17408/// @param internal set to true if the call is intended to get a
17409/// representation of the decl (or type) for the purpose of canonical
17410/// type comparison. This is mainly used in the function
17411/// type_base::get_canonical_type_for().
17412///
17413/// In other words if the argument for this parameter is true then the
17414/// call is meant for internal use (for technical use inside the
17415/// library itself), false otherwise. If you don't know what this is
17416/// for, then set it to false.
17417///
17418/// @param qualified_name if true, names emitted in the pretty
17419/// representation are fully qualified.
17420///
17421/// @return a copy of the pretty representation of the namespace.
17422string
17424 bool qualified_name) const
17425{
17426 string r =
17427 "namespace " + scope_decl::get_pretty_representation(internal,
17428 qualified_name);
17429 return r;
17430}
17431
17432/// Return true iff both namespaces and their members are equal.
17433///
17434/// Note that this function does not check if the scope of these
17435/// namespaces are equal.
17436bool
17438{
17439 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
17440 if (!other)
17441 return false;
17442 return scope_decl::operator==(*other);
17443}
17444
17445/// Test if the current namespace_decl is empty or contains empty
17446/// namespaces itself.
17447///
17448/// @return true iff the current namespace_decl is empty or contains
17449/// empty itself.
17450bool
17452{
17453 if (is_empty())
17454 return true;
17455
17456 for (declarations::const_iterator i = get_member_decls().begin();
17457 i != get_member_decls().end();
17458 ++i)
17459 {
17460 if (!is_namespace(*i))
17461 return false;
17462
17464 ABG_ASSERT(ns);
17465
17466 if (!ns->is_empty_or_has_empty_sub_namespaces())
17467 return false;
17468 }
17469
17470 return true;
17471}
17472
17473/// This implements the ir_traversable_base::traverse pure virtual
17474/// function.
17475///
17476/// @param v the visitor used on the current instance and on its
17477/// member nodes.
17478///
17479/// @return true if the entire IR node tree got traversed, false
17480/// otherwise.
17481bool
17483{
17484 if (visiting())
17485 return true;
17486
17487 if (v.visit_begin(this))
17488 {
17489 visiting(true);
17490 scope_decl::declarations::const_iterator i;
17491 for (i = get_member_decls().begin();
17492 i != get_member_decls ().end();
17493 ++i)
17494 {
17496 dynamic_pointer_cast<ir_traversable_base>(*i);
17497 if (t)
17498 if (!t->traverse (v))
17499 break;
17500 }
17501 visiting(false);
17502 }
17503 return v.visit_end(this);
17504}
17505
17506namespace_decl::~namespace_decl()
17507{
17508}
17509
17510// </namespace_decl>
17511
17512// <qualified_type_def>
17513
17514/// Type of the private data of qualified_type_def.
17515class qualified_type_def::priv
17516{
17517 friend class qualified_type_def;
17518
17519 qualified_type_def::CV cv_quals_;
17520 // Before the type is canonicalized, this is used as a temporary
17521 // internal name.
17522 interned_string temporary_internal_name_;
17523 // Once the type is canonicalized, this is used as the internal
17524 // name.
17525 interned_string internal_name_;
17526 weak_ptr<type_base> underlying_type_;
17527
17528 priv()
17529 : cv_quals_(CV_NONE)
17530 {}
17531
17532 priv(qualified_type_def::CV quals,
17533 type_base_sptr t)
17534 : cv_quals_(quals),
17535 underlying_type_(t)
17536 {}
17537
17538 priv(qualified_type_def::CV quals)
17539 : cv_quals_(quals)
17540 {}
17541};// end class qualified_type_def::priv
17542
17543/// Build the name of the current instance of qualified type.
17544///
17545/// @param fully_qualified if true, build a fully qualified name.
17546///
17547/// @param internal set to true if the call is intended for an
17548/// internal use (for technical use inside the library itself), false
17549/// otherwise. If you don't know what this is for, then set it to
17550/// false.
17551///
17552/// @return a copy of the newly-built name.
17553string
17554qualified_type_def::build_name(bool fully_qualified, bool internal) const
17555{
17556 type_base_sptr t = get_underlying_type();
17557 if (!t)
17558 // The qualified type might temporarily have no underlying type,
17559 // especially during the construction of the type, while the
17560 // underlying type is not yet constructed. In that case, let's do
17561 // like if the underlying type is the 'void' type.
17563
17565 fully_qualified,
17566 internal);
17567}
17568
17569/// This function is automatically invoked whenever an instance of
17570/// this type is canonicalized.
17571///
17572/// It's an overload of the virtual type_base::on_canonical_type_set.
17573///
17574/// We put here what is thus meant to be executed only at the point of
17575/// type canonicalization.
17576void
17579
17580/// Constructor of the qualified_type_def
17581///
17582/// @param type the underlying type
17583///
17584/// @param quals a bitfield representing the const/volatile qualifiers
17585///
17586/// @param locus the location of the qualified type definition
17587qualified_type_def::qualified_type_def(type_base_sptr type,
17588 CV quals,
17589 const location& locus)
17590 : type_or_decl_base(type->get_environment(),
17591 QUALIFIED_TYPE
17592 | ABSTRACT_TYPE_BASE
17593 | ABSTRACT_DECL_BASE),
17594 type_base(type->get_environment(), type->get_size_in_bits(),
17595 type->get_alignment_in_bits()),
17596 decl_base(type->get_environment(), "", locus, "",
17597 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
17598 priv_(new priv(quals, type))
17599{
17601 interned_string name = type->get_environment().intern(build_name(false));
17602 set_name(name);
17603}
17604
17605/// Constructor of the qualified_type_def
17606///
17607/// @param env the environment of the type.
17608///
17609/// @param quals a bitfield representing the const/volatile qualifiers
17610///
17611/// @param locus the location of the qualified type definition
17612qualified_type_def::qualified_type_def(const environment& env,
17613 CV quals,
17614 const location& locus)
17615 : type_or_decl_base(env,
17616 QUALIFIED_TYPE
17617 | ABSTRACT_TYPE_BASE
17618 | ABSTRACT_DECL_BASE),
17619 type_base(env, /*size_in_bits=*/0,
17620 /*alignment_in_bits=*/0),
17621 decl_base(env, "", locus, ""),
17622 priv_(new priv(quals))
17623{
17625 // We don't yet have an underlying type. So for naming purpose,
17626 // let's temporarily pretend the underlying type is 'void'.
17627 interned_string name = env.intern("void");
17628 set_name(name);
17629}
17630
17631/// Return the hash value of the current IR node.
17632///
17633/// Note that upon the first invocation, this member functions
17634/// computes the hash value and returns it. Subsequent invocations
17635/// just return the hash value that was previously calculated.
17636///
17637/// @return the hash value of the current IR node.
17638hash_t
17640{
17642 return h;
17643}
17644
17645/// Get the size of the qualified type def.
17646///
17647/// This is an overload for type_base::get_size_in_bits().
17648///
17649/// @return the size of the qualified type.
17650size_t
17652{
17653 size_t s = 0;
17654 if (type_base_sptr ut = get_underlying_type())
17655 {
17656 // We do have the underlying type properly set, so let's make
17657 // the size of the qualified type match the size of its
17658 // underlying type.
17659 s = ut->get_size_in_bits();
17660 if (s != type_base::get_size_in_bits())
17661 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
17662 }
17664}
17665
17666/// Compares two instances of @ref qualified_type_def.
17667///
17668/// If the two intances are different, set a bitfield to give some
17669/// insight about the kind of differences there are.
17670///
17671/// @param l the first artifact of the comparison.
17672///
17673/// @param r the second artifact of the comparison.
17674///
17675/// @param k a pointer to a bitfield that gives information about the
17676/// kind of changes there are between @p l and @p r. This one is set
17677/// iff @p k is non-null and the function returns false.
17678///
17679/// Please note that setting k to a non-null value does have a
17680/// negative performance impact because even if @p l and @p r are not
17681/// equal, the function keeps up the comparison in order to determine
17682/// the different kinds of ways in which they are different.
17683///
17684/// @return true if @p l equals @p r, false otherwise.
17685bool
17687{
17688 bool result = true;
17689 if (l.get_cv_quals() != r.get_cv_quals())
17690 {
17691 result = false;
17692 if (k)
17694 else
17696 }
17697
17699 {
17700 result = false;
17701 if (k)
17702 {
17704 r.get_underlying_type().get()))
17705 // Underlying type changes in which the structure of the
17706 // type changed are considered local changes to the
17707 // qualified type.
17709 else
17710 *k |= SUBTYPE_CHANGE_KIND;
17711 }
17712 else
17713 // okay strictly speaking this is not necessary, but I am
17714 // putting it here to maintenance; that is, so that adding
17715 // subsequent clauses needed to compare two qualified types
17716 // later still works.
17718 }
17719
17720 ABG_RETURN(result);
17721}
17722
17723/// Equality operator for qualified types.
17724///
17725/// Note that this function does not check for equality of the scopes.
17726///
17727///@param o the other qualified type to compare against.
17728///
17729/// @return true iff both qualified types are equal.
17730bool
17732{
17733 const qualified_type_def* other =
17734 dynamic_cast<const qualified_type_def*>(&o);
17735 if (!other)
17736 return false;
17737 return try_canonical_compare(this, other);
17738}
17739
17740/// Equality operator for qualified types.
17741///
17742/// Note that this function does not check for equality of the scopes.
17743/// Also, this re-uses the equality operator above that takes a
17744/// decl_base.
17745///
17746///@param o the other qualified type to compare against.
17747///
17748/// @return true iff both qualified types are equal.
17749bool
17751{
17752 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17753 if (!other)
17754 return false;
17755 return *this == *other;
17756}
17757
17758/// Equality operator for qualified types.
17759///
17760/// Note that this function does not check for equality of the scopes.
17761/// Also, this re-uses the equality operator above that takes a
17762/// decl_base.
17763///
17764///@param o the other qualified type to compare against.
17765///
17766/// @return true iff both qualified types are equal.
17767bool
17769{
17770 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17771 if (!other)
17772 return false;
17773 return *this == *other;
17774}
17775
17776/// Implementation for the virtual qualified name builder for @ref
17777/// qualified_type_def.
17778///
17779/// @param qualified_name the output parameter to hold the resulting
17780/// qualified name.
17781///
17782/// @param internal set to true if the call is intended for an
17783/// internal use (for technical use inside the library itself), false
17784/// otherwise. If you don't know what this is for, then set it to
17785/// false.
17786void
17788 bool internal) const
17789{qualified_name = get_qualified_name(internal);}
17790
17791/// Implementation of the virtual qualified name builder/getter.
17792///
17793/// @param internal set to true if the call is intended for an
17794/// internal use (for technical use inside the library itself), false
17795/// otherwise. If you don't know what this is for, then set it to
17796/// false.
17797///
17798/// @return the resulting qualified name.
17799const interned_string&
17801{
17802 const environment& env = get_environment();
17803
17804
17805 if (!get_canonical_type())
17806 {
17807 // The type hasn't been canonicalized yet. We want to return a
17808 // temporary name that is not cached because the structure of
17809 // this type (and so its name) can change until its
17810 // canonicalized.
17811 if (internal)
17812 {
17813 // We are asked to return a temporary *internal* name.
17814 // Lets compute it and return a reference to where it's
17815 // stored.
17816 if (priv_->temporary_internal_name_.empty())
17817 priv_->temporary_internal_name_ =
17818 env.intern(build_name(true, /*internal=*/true));
17819 return priv_->temporary_internal_name_;
17820 }
17821 else
17822 {
17823 // We are asked to return a temporary non-internal name.
17825 (env.intern(build_name(true, /*internal=*/false)));
17827 }
17828 }
17829 else
17830 {
17831 // The type has already been canonicalized. We want to return
17832 // the definitive name and cache it.
17833 if (internal)
17834 {
17835 if (priv_->internal_name_.empty())
17836 priv_->internal_name_ =
17837 env.intern(build_name(/*qualified=*/true,
17838 /*internal=*/true));
17839 return priv_->internal_name_;
17840 }
17841 else
17842 {
17843 if (peek_qualified_name().empty())
17845 (env.intern(build_name(/*qualified=*/true,
17846 /*internal=*/false)));
17847 return peek_qualified_name();
17848 }
17849 }
17850}
17851
17852/// This implements the ir_traversable_base::traverse pure virtual
17853/// function.
17854///
17855/// @param v the visitor used on the current instance.
17856///
17857/// @return true if the entire IR node tree got traversed, false
17858/// otherwise.
17859bool
17861{
17862 if (v.type_node_has_been_visited(this))
17863 return true;
17864
17865 if (visiting())
17866 return true;
17867
17868 if (v.visit_begin(this))
17869 {
17870 visiting(true);
17871 if (type_base_sptr t = get_underlying_type())
17872 t->traverse(v);
17873 visiting(false);
17874 }
17875 bool result = v.visit_end(this);
17877 return result;
17878}
17879
17880qualified_type_def::~qualified_type_def()
17881{
17882}
17883
17884/// Getter of the const/volatile qualifier bit field
17887{return priv_->cv_quals_;}
17888
17889/// Setter of the const/value qualifiers bit field
17890void
17892{priv_->cv_quals_ = cv_quals;}
17893
17894/// Compute and return the string prefix or suffix representing the
17895/// qualifiers hold by the current instance of @ref
17896/// qualified_type_def.
17897///
17898/// @return the newly-built cv string.
17899string
17902
17903/// Getter of the underlying type
17904type_base_sptr
17906{return priv_->underlying_type_.lock();}
17907
17908/// Setter of the underlying type.
17909///
17910/// @param t the new underlying type.
17911void
17913{
17914 ABG_ASSERT(t);
17915 priv_->underlying_type_ = t;
17916 // Now we need to update other properties that depend on the new underlying type.
17917 set_size_in_bits(t->get_size_in_bits());
17918 set_alignment_in_bits(t->get_alignment_in_bits());
17920 set_name(name);
17921 if (scope_decl* s = get_scope())
17922 {
17923 // Now that the name has been updated, we need to update the
17924 // lookup maps accordingly.
17925 scope_decl::declarations::iterator i;
17926 if (s->find_iterator_for_member(this, i))
17928 else
17930 }
17931}
17932
17933/// Non-member equality operator for @ref qualified_type_def
17934///
17935/// @param l the left-hand side of the equality operator
17936///
17937/// @param r the right-hand side of the equality operator
17938///
17939/// @return true iff @p l and @p r equals.
17940bool
17941operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17942{
17943 if (l.get() == r.get())
17944 return true;
17945 if (!!l != !!r)
17946 return false;
17947
17948 return *l == *r;
17949}
17950
17951/// Non-member inequality operator for @ref qualified_type_def
17952///
17953/// @param l the left-hand side of the equality operator
17954///
17955/// @param r the right-hand side of the equality operator
17956///
17957/// @return true iff @p l and @p r equals.
17958bool
17959operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17960{return ! operator==(l, r);}
17961
17962/// Overloaded bitwise OR operator for cv qualifiers.
17965{
17966 return static_cast<qualified_type_def::CV>
17967 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
17968}
17969
17970/// Overloaded bitwise |= operator for cv qualifiers.
17973{
17974 l = l | r;
17975 return l;
17976}
17977
17978/// Overloaded bitwise &= operator for cv qualifiers.
17981{
17982 l = l & r;
17983 return l;
17984}
17985
17986/// Overloaded bitwise AND operator for CV qualifiers.
17989{
17990 return static_cast<qualified_type_def::CV>
17991 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
17992}
17993
17994/// Overloaded bitwise inverting operator for CV qualifiers.
17997{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
17998
17999/// Streaming operator for qualified_type_decl::CV
18000///
18001/// @param o the output stream to serialize the cv qualifier to.
18002///
18003/// @param cv the cv qualifier to serialize.
18004///
18005/// @return the output stream used.
18006std::ostream&
18007operator<<(std::ostream& o, qualified_type_def::CV cv)
18008{
18009 string str;
18010
18011 switch (cv)
18012 {
18013 case qualified_type_def::CV_NONE:
18014 str = "none";
18015 break;
18016 case qualified_type_def::CV_CONST:
18017 str = "const";
18018 break;
18019 case qualified_type_def::CV_VOLATILE:
18020 str = "volatile";
18021 break;
18022 case qualified_type_def::CV_RESTRICT:
18023 str = "restrict";
18024 break;
18025 }
18026
18027 o << str;
18028 return o;
18029}
18030
18031// </qualified_type_def>
18032
18033//<pointer_type_def definitions>
18034
18035/// Private data structure of the @ref pointer_type_def.
18036struct pointer_type_def::priv
18037{
18038 type_base_wptr pointed_to_type_;
18039 type_base* naked_pointed_to_type_;
18040 interned_string internal_qualified_name_;
18041 interned_string temp_internal_qualified_name_;
18042
18043 priv(const type_base_sptr& t)
18044 : pointed_to_type_(type_or_void(t, t->get_environment())),
18045 naked_pointed_to_type_(t.get())
18046 {}
18047
18048 priv()
18049 : naked_pointed_to_type_()
18050 {}
18051}; //end struct pointer_type_def
18052
18053/// This function is automatically invoked whenever an instance of
18054/// this type is canonicalized.
18055///
18056/// It's an overload of the virtual type_base::on_canonical_type_set.
18057///
18058/// We put here what is thus meant to be executed only at the point of
18059/// type canonicalization.
18060void
18063
18064
18065///Constructor of @ref pointer_type_def.
18066///
18067/// @param pointed_to the pointed-to type.
18068///
18069/// @param size_in_bits the size of the type, in bits.
18070///
18071/// @param align_in_bits the alignment of the type, in bits.
18072///
18073/// @param locus the source location where the type was defined.
18074pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
18075 size_t size_in_bits,
18076 size_t align_in_bits,
18077 const location& locus)
18078 : type_or_decl_base(pointed_to->get_environment(),
18079 POINTER_TYPE
18080 | ABSTRACT_TYPE_BASE
18081 | ABSTRACT_DECL_BASE),
18082 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18083 decl_base(pointed_to->get_environment(), "", locus, ""),
18084 priv_(new priv(pointed_to))
18085{
18087 try
18088 {
18089 ABG_ASSERT(pointed_to);
18090 const environment& env = pointed_to->get_environment();
18091 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18092 string name = (pto ? pto->get_name() : string("void")) + "*";
18093 set_name(env.intern(name));
18094 if (pto)
18095 set_visibility(pto->get_visibility());
18096 }
18097 catch (...)
18098 {}
18099}
18100
18101///Constructor of @ref pointer_type_def.
18102///
18103/// @param env the environment of the type.
18104///
18105/// @param size_in_bits the size of the type, in bits.
18106///
18107/// @param align_in_bits the alignment of the type, in bits.
18108///
18109/// @param locus the source location where the type was defined.
18110pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
18111 size_t alignment_in_bits,
18112 const location& locus)
18113 : type_or_decl_base(env,
18114 POINTER_TYPE
18115 | ABSTRACT_TYPE_BASE
18116 | ABSTRACT_DECL_BASE),
18117 type_base(env, size_in_bits, alignment_in_bits),
18118 decl_base(env, "", locus, ""),
18119 priv_(new priv())
18120{
18122 string name = string("void") + "*";
18123 set_name(env.intern(name));
18124}
18125
18126/// Return the hash value of the current IR node.
18127///
18128/// Note that upon the first invocation, this member functions
18129/// computes the hash value and returns it. Subsequent invocations
18130/// just return the hash value that was previously calculated.
18131///
18132/// @return the hash value of the current IR node.
18133hash_t
18135{
18137 return h;
18138}
18139
18140/// Set the pointed-to type of the pointer.
18141///
18142/// @param t the new pointed-to type.
18143void
18145{
18146 ABG_ASSERT(t);
18147 priv_->pointed_to_type_ = t;
18148 priv_->naked_pointed_to_type_ = t.get();
18149
18150 try
18151 {
18152 const environment& env = t->get_environment();
18153 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
18154 string name = (pto ? pto->get_name() : string("void")) + "*";
18155 set_name(env.intern(name));
18156 if (pto)
18157 set_visibility(pto->get_visibility());
18158 }
18159 catch (...)
18160 {}
18161}
18162
18163/// Compares two instances of @ref pointer_type_def.
18164///
18165/// If the two intances are different, set a bitfield to give some
18166/// insight about the kind of differences there are.
18167///
18168/// @param l the first artifact of the comparison.
18169///
18170/// @param r the second artifact of the comparison.
18171///
18172/// @param k a pointer to a bitfield that gives information about the
18173/// kind of changes there are between @p l and @p r. This one is set
18174/// iff @p k is non-null and the function returns false.
18175///
18176/// Please note that setting k to a non-null value does have a
18177/// negative performance impact because even if @p l and @p r are not
18178/// equal, the function keeps up the comparison in order to determine
18179/// the different kinds of ways in which they are different.
18180///
18181/// @return true if @p l equals @p r, false otherwise.
18182bool
18184{
18185 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18186 bool result = p1 == p2;
18187 if (!result)
18188 if (k)
18189 {
18190 if (!types_have_similar_structure(&l, &r))
18191 // pointed-to type changes in which the structure of the
18192 // type changed are considered local changes to the pointer
18193 // type.
18195 *k |= SUBTYPE_CHANGE_KIND;
18196 }
18197
18198 ABG_RETURN(result);
18199}
18200
18201/// Return true iff both instances of pointer_type_def are equal.
18202///
18203/// Note that this function does not check for the scopes of the this
18204/// types.
18205bool
18207{
18208 const pointer_type_def* other = is_pointer_type(&o);
18209 if (!other)
18210 return false;
18211 return try_canonical_compare(this, other);
18212}
18213
18214/// Return true iff both instances of pointer_type_def are equal.
18215///
18216/// Note that this function does not check for the scopes of the
18217/// types.
18218///
18219/// @param other the other type to compare against.
18220///
18221/// @return true iff @p other equals the current instance.
18222bool
18224{
18225 const decl_base* o = is_decl(&other);
18226 if (!o)
18227 return false;
18228 return *this == *o;
18229}
18230
18231/// Return true iff both instances of pointer_type_def are equal.
18232///
18233/// Note that this function does not check for the scopes of the
18234/// types.
18235///
18236/// @param other the other type to compare against.
18237///
18238/// @return true iff @p other equals the current instance.
18239bool
18241{
18242 const decl_base& o = other;
18243 return *this == o;
18244}
18245
18246/// Getter of the pointed-to type.
18247///
18248/// @return the pointed-to type.
18249const type_base_sptr
18251{return priv_->pointed_to_type_.lock();}
18252
18253/// Getter of a naked pointer to the pointed-to type.
18254///
18255/// @return a naked pointed to the pointed-to type.
18256type_base*
18258{return priv_->naked_pointed_to_type_;}
18259
18260/// Build and return the qualified name of the current instance of
18261/// @ref pointer_type_def.
18262///
18263/// @param qn output parameter. The resulting qualified name.
18264///
18265/// @param internal set to true if the call is intended for an
18266/// internal use (for technical use inside the library itself), false
18267/// otherwise. If you don't know what this is for, then set it to
18268/// false.
18269void
18271{qn = get_qualified_name(internal);}
18272
18273/// Build, cache and return the qualified name of the current instance
18274/// of @ref pointer_type_def. Subsequent invocations of this function
18275/// return the cached value.
18276///
18277/// Note that this function should work even if the underlying type is
18278/// momentarily empty.
18279///
18280/// @param internal set to true if the call is intended for an
18281/// internal use (for technical use inside the library itself), false
18282/// otherwise. If you don't know what this is for, then set it to
18283/// false.
18284///
18285/// @return the resulting qualified name.
18286const interned_string&
18288{
18289 type_base* pointed_to_type = get_naked_pointed_to_type();
18290 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18291
18292 if (internal)
18293 {
18294 if (get_canonical_type())
18295 {
18296 if (priv_->internal_qualified_name_.empty())
18297 if (pointed_to_type)
18298 priv_->internal_qualified_name_ =
18299 pointer_declaration_name(this,
18300 /*variable_name=*/"",
18301 /*qualified_name=*/
18302 is_typedef(pointed_to_type)
18303 ? false
18304 : true,
18305 /*internal=*/true);
18306 return priv_->internal_qualified_name_;
18307 }
18308 else
18309 {
18310 // As the type hasn't yet been canonicalized, its structure
18311 // (and so its name) can change. So let's invalidate the
18312 // cache where we store its name at each invocation of this
18313 // function.
18314 if (pointed_to_type)
18315 if (priv_->temp_internal_qualified_name_.empty())
18316 priv_->temp_internal_qualified_name_ =
18317 pointer_declaration_name(this,
18318 /*variable_name=*/"",
18319 /*qualified_name=*/
18320 is_typedef(pointed_to_type)
18321 ? false
18322 : true,
18323 /*internal=*/true);
18324 return priv_->temp_internal_qualified_name_;
18325 }
18326 }
18327 else
18328 {
18330 {
18333 (pointer_declaration_name(this,
18334 /*variable_name=*/"",
18335 /*qualified_name=*/true,
18336 /*internal=*/false));
18338 }
18339 else
18340 {
18341 // As the type hasn't yet been canonicalized, its structure
18342 // (and so its name) can change. So let's invalidate the
18343 // cache where we store its name at each invocation of this
18344 // function.
18345 if (pointed_to_type)
18347 (pointer_declaration_name(this,
18348 /*variable_name=*/"",
18349 /*qualified_name=*/true,
18350 /*internal=*/false));
18352 }
18353 }
18354}
18355
18356/// This implements the ir_traversable_base::traverse pure virtual
18357/// function.
18358///
18359/// @param v the visitor used on the current instance.
18360///
18361/// @return true if the entire IR node tree got traversed, false
18362/// otherwise.
18363bool
18365{
18366 if (v.type_node_has_been_visited(this))
18367 return true;
18368
18369 if (visiting())
18370 return true;
18371
18372 if (v.visit_begin(this))
18373 {
18374 visiting(true);
18375 if (type_base_sptr t = get_pointed_to_type())
18376 t->traverse(v);
18377 visiting(false);
18378 }
18379
18380 bool result = v.visit_end(this);
18382 return result;
18383}
18384
18385pointer_type_def::~pointer_type_def()
18386{}
18387
18388/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
18389/// equality; that is, make it compare the pointed to objects too.
18390///
18391/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18392/// of the equality.
18393///
18394/// @param r the shared_ptr of @ref pointer_type_def on
18395/// right-hand-side of the equality.
18396///
18397/// @return true if the @ref pointer_type_def pointed to by the
18398/// shared_ptrs are equal, false otherwise.
18399bool
18401{
18402 if (l.get() == r.get())
18403 return true;
18404 if (!!l != !!r)
18405 return false;
18406
18407 return *l == *r;
18408}
18409
18410/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
18411/// equality; that is, make it compare the pointed to objects too.
18412///
18413/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
18414/// of the equality.
18415///
18416/// @param r the shared_ptr of @ref pointer_type_def on
18417/// right-hand-side of the equality.
18418///
18419/// @return true iff the @ref pointer_type_def pointed to by the
18420/// shared_ptrs are different.
18421bool
18423{return !operator==(l, r);}
18424
18425// </pointer_type_def definitions>
18426
18427// <reference_type_def definitions>
18428
18429/// Private data structure of the @ref reference_type_def type.
18430struct reference_type_def::priv
18431{
18432
18433 type_base_wptr pointed_to_type_;
18434 bool is_lvalue_;
18435 interned_string internal_qualified_name_;
18436 interned_string temp_internal_qualified_name_;
18437
18438 priv(const type_base_sptr& t, bool is_lvalue)
18439 : pointed_to_type_(type_or_void(t, t->get_environment())),
18440 is_lvalue_(is_lvalue)
18441 {}
18442
18443 priv(bool is_lvalue)
18444 : is_lvalue_(is_lvalue)
18445 {}
18446
18447 priv() = delete;
18448};
18449
18450/// This function is automatically invoked whenever an instance of
18451/// this type is canonicalized.
18452///
18453/// It's an overload of the virtual type_base::on_canonical_type_set.
18454///
18455/// We put here what is thus meant to be executed only at the point of
18456/// type canonicalization.
18457void
18460
18461/// Constructor of the reference_type_def type.
18462///
18463/// @param pointed_to the pointed to type.
18464///
18465/// @param lvalue wether the reference is an lvalue reference. If
18466/// false, the reference is an rvalue one.
18467///
18468/// @param size_in_bits the size of the type, in bits.
18469///
18470/// @param align_in_bits the alignment of the type, in bits.
18471///
18472/// @param locus the source location of the type.
18473reference_type_def::reference_type_def(const type_base_sptr pointed_to,
18474 bool lvalue,
18475 size_t size_in_bits,
18476 size_t align_in_bits,
18477 const location& locus)
18478 : type_or_decl_base(pointed_to->get_environment(),
18479 REFERENCE_TYPE
18480 | ABSTRACT_TYPE_BASE
18481 | ABSTRACT_DECL_BASE),
18482 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18483 decl_base(pointed_to->get_environment(), "", locus, ""),
18484 priv_(new priv(pointed_to, lvalue))
18485{
18487
18488 try
18489 {
18490 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18491 string name;
18492 if (pto)
18493 {
18494 set_visibility(pto->get_visibility());
18495 name = string(pto->get_name()) + "&";
18496 }
18497 else
18498 name = string(get_type_name(is_function_type(pointed_to),
18499 /*qualified_name=*/true)) + "&";
18500
18501 if (!is_lvalue())
18502 name += "&";
18503 const environment& env = pointed_to->get_environment();
18504 set_name(env.intern(name));
18505 }
18506 catch (...)
18507 {}
18508}
18509
18510/// Constructor of the reference_type_def type.
18511///
18512/// This one creates a type that has no pointed-to type, temporarily.
18513/// This is useful for cases where the underlying type is not yet
18514/// available. It can be set later using
18515/// reference_type_def::set_pointed_to_type().
18516///
18517/// @param env the environment of the type.
18518///
18519/// @param lvalue wether the reference is an lvalue reference. If
18520/// false, the reference is an rvalue one.
18521///
18522/// @param size_in_bits the size of the type, in bits.
18523///
18524/// @param align_in_bits the alignment of the type, in bits.
18525///
18526/// @param locus the source location of the type.
18527reference_type_def::reference_type_def(const environment& env, bool lvalue,
18528 size_t size_in_bits,
18529 size_t alignment_in_bits,
18530 const location& locus)
18531 : type_or_decl_base(env,
18532 REFERENCE_TYPE
18533 | ABSTRACT_TYPE_BASE
18534 | ABSTRACT_DECL_BASE),
18535 type_base(env, size_in_bits, alignment_in_bits),
18536 decl_base(env, "", locus, ""),
18537 priv_(new priv(lvalue))
18538{
18540 string name = "void&";
18541 if (!is_lvalue())
18542 name += "&";
18543
18544 set_name(env.intern(name));
18545 priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
18546}
18547
18548/// Return the hash value of the current IR node.
18549///
18550/// Note that upon the first invocation, this member functions
18551/// computes the hash value and returns it. Subsequent invocations
18552/// just return the hash value that was previously calculated.
18553///
18554/// @return the hash value of the current IR node.
18555hash_t
18557{
18559 return h;
18560}
18561
18562/// Setter of the pointed_to type of the current reference type.
18563///
18564/// @param pointed_to the new pointed to type.
18565void
18566reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
18567{
18568 ABG_ASSERT(pointed_to_type);
18569 priv_->pointed_to_type_ = pointed_to_type;
18570
18571 decl_base_sptr pto;
18572 try
18573 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
18574 catch (...)
18575 {}
18576
18577 if (pto)
18578 {
18579 set_visibility(pto->get_visibility());
18580 string name = string(pto->get_name()) + "&";
18581 if (!is_lvalue())
18582 name += "&";
18583 const environment& env = pto->get_environment();
18584 set_name(env.intern(name));
18585 }
18586}
18587
18588/// Compares two instances of @ref reference_type_def.
18589///
18590/// If the two intances are different, set a bitfield to give some
18591/// insight about the kind of differences there are.
18592///
18593/// @param l the first artifact of the comparison.
18594///
18595/// @param r the second artifact of the comparison.
18596///
18597/// @param k a pointer to a bitfield that gives information about the
18598/// kind of changes there are between @p l and @p r. This one is set
18599/// iff @p k is non-null and the function returns false.
18600///
18601/// Please note that setting k to a non-null value does have a
18602/// negative performance impact because even if @p l and @p r are not
18603/// equal, the function keeps up the comparison in order to determine
18604/// the different kinds of ways in which they are different.
18605///
18606/// @return true if @p l equals @p r, false otherwise.
18607bool
18609{
18610 if (l.is_lvalue() != r.is_lvalue())
18611 {
18612 if (k)
18615 }
18616 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18617 bool result = p1 == p2;
18618 if (!result)
18619 if (k)
18620 {
18621 if (!types_have_similar_structure(&l, &r))
18623 *k |= SUBTYPE_CHANGE_KIND;
18624 }
18625 ABG_RETURN(result);
18626}
18627
18628/// Equality operator of the @ref reference_type_def type.
18629///
18630/// @param o the other instance of @ref reference_type_def to compare
18631/// against.
18632///
18633/// @return true iff the two instances are equal.
18634bool
18636{
18637 const reference_type_def* other =
18638 dynamic_cast<const reference_type_def*>(&o);
18639 if (!other)
18640 return false;
18641 return try_canonical_compare(this, other);
18642}
18643
18644/// Equality operator of the @ref reference_type_def type.
18645///
18646/// @param o the other instance of @ref reference_type_def to compare
18647/// against.
18648///
18649/// @return true iff the two instances are equal.
18650bool
18652{
18653 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18654 if (!other)
18655 return false;
18656 return *this == *other;
18657}
18658
18659/// Equality operator of the @ref reference_type_def type.
18660///
18661/// @param o the other instance of @ref reference_type_def to compare
18662/// against.
18663///
18664/// @return true iff the two instances are equal.
18665bool
18667{
18668 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18669 if (!other)
18670 return false;
18671 return *this == *other;
18672}
18673
18674type_base_sptr
18675reference_type_def::get_pointed_to_type() const
18676{return priv_->pointed_to_type_.lock();}
18677
18678bool
18679reference_type_def::is_lvalue() const
18680{return priv_->is_lvalue_;}
18681
18682/// Build and return the qualified name of the current instance of the
18683/// @ref reference_type_def.
18684///
18685/// @param qn output parameter. Is set to the newly-built qualified
18686/// name of the current instance of @ref reference_type_def.
18687///
18688/// @param internal set to true if the call is intended for an
18689/// internal use (for technical use inside the library itself), false
18690/// otherwise. If you don't know what this is for, then set it to
18691/// false.
18692void
18694{qn = get_qualified_name(internal);}
18695
18696/// Build, cache and return the qualified name of the current instance
18697/// of the @ref reference_type_def. Subsequent invocations of this
18698/// function return the cached value.
18699///
18700/// @param internal set to true if the call is intended for an
18701/// internal use (for technical use inside the library itself), false
18702/// otherwise. If you don't know what this is for, then set it to
18703/// false.
18704///
18705/// @return the newly-built qualified name of the current instance of
18706/// @ref reference_type_def.
18707const interned_string&
18709{
18710 type_base_sptr pointed_to_type = get_pointed_to_type();
18711 pointed_to_type = look_through_decl_only_type(pointed_to_type);
18712
18713 if (internal)
18714 {
18715 if (get_canonical_type())
18716 {
18717 if (priv_->internal_qualified_name_.empty())
18718 if (pointed_to_type)
18719 priv_->internal_qualified_name_ =
18720 get_name_of_reference_to_type(*pointed_to_type,
18721 is_lvalue(),
18722 /*qualified_name=*/
18723 is_typedef(pointed_to_type)
18724 ? false
18725 : true,
18726 /*internal=*/true);
18727 return priv_->internal_qualified_name_;
18728 }
18729 else
18730 {
18731 // As the type hasn't yet been canonicalized, its structure
18732 // (and so its name) can change. So let's invalidate the
18733 // cache where we store its name at each invocation of this
18734 // function.
18735 if (pointed_to_type)
18736 if (priv_->temp_internal_qualified_name_.empty())
18737 priv_->temp_internal_qualified_name_ =
18738 get_name_of_reference_to_type(*pointed_to_type,
18739 is_lvalue(),
18740 /*qualified_name=*/
18741 is_typedef(pointed_to_type)
18742 ? false
18743 : true,
18744 /*internal=*/true);
18745 return priv_->temp_internal_qualified_name_;
18746 }
18747 }
18748 else
18749 {
18751 {
18753 (get_name_of_reference_to_type(*pointed_to_type,
18754 is_lvalue(),
18755 /*qualified_name=*/true,
18756 /*internal=*/false));
18758 }
18759 else
18760 {
18761 // As the type hasn't yet been canonicalized, its structure
18762 // (and so its name) can change. So let's invalidate the
18763 // cache where we store its name at each invocation of this
18764 // function.
18765 if (pointed_to_type)
18767 (get_name_of_reference_to_type(*pointed_to_type,
18768 is_lvalue(),
18769 /*qualified_name=*/true,
18770 /*internal=*/false));
18772 }
18773 }
18774}
18775
18776/// Get the pretty representation of the current instance of @ref
18777/// reference_type_def.
18778///
18779/// @param internal set to true if the call is intended to get a
18780/// representation of the decl (or type) for the purpose of canonical
18781/// type comparison. This is mainly used in the function
18782/// type_base::get_canonical_type_for().
18783///
18784/// In other words if the argument for this parameter is true then the
18785/// call is meant for internal use (for technical use inside the
18786/// library itself), false otherwise. If you don't know what this is
18787/// for, then set it to false.
18788///
18789/// @param qualified_name if true, names emitted in the pretty
18790/// representation are fully qualified.
18791///
18792/// @return the pretty representatin of the @ref reference_type_def.
18793string
18795 bool qualified_name) const
18796{
18797 string result =
18799 (get_pointed_to_type()),
18800 is_lvalue(),
18801 qualified_name,
18802 internal);
18803
18804 return result;
18805}
18806
18807/// This implements the ir_traversable_base::traverse pure virtual
18808/// function.
18809///
18810/// @param v the visitor used on the current instance.
18811///
18812/// @return true if the entire IR node tree got traversed, false
18813/// otherwise.
18814bool
18816{
18817 if (v.type_node_has_been_visited(this))
18818 return true;
18819
18820 if (visiting())
18821 return true;
18822
18823 if (v.visit_begin(this))
18824 {
18825 visiting(true);
18826 if (type_base_sptr t = get_pointed_to_type())
18827 t->traverse(v);
18828 visiting(false);
18829 }
18830
18831 bool result = v.visit_end(this);
18833 return result;
18834}
18835
18836reference_type_def::~reference_type_def()
18837{}
18838
18839/// Turn equality of shared_ptr of @ref reference_type_def into a deep
18840/// equality; that is, make it compare the pointed to objects too.
18841///
18842/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18843/// of the equality.
18844///
18845/// @param r the shared_ptr of @ref reference_type_def on
18846/// right-hand-side of the equality.
18847///
18848/// @return true if the @ref reference_type_def pointed to by the
18849/// shared_ptrs are equal, false otherwise.
18850bool
18852{
18853 if (l.get() == r.get())
18854 return true;
18855 if (!!l != !!r)
18856 return false;
18857
18858 return *l == *r;
18859}
18860
18861/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
18862/// equality; that is, make it compare the pointed to objects too.
18863///
18864/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18865/// of the equality.
18866///
18867/// @param r the shared_ptr of @ref reference_type_def on
18868/// right-hand-side of the equality.
18869///
18870/// @return true iff the @ref reference_type_def pointed to by the
18871/// shared_ptrs are different.
18872bool
18875
18876// </reference_type_def definitions>
18877
18878// <ptr_to_mbr_type definitions>
18879
18880/// The private data type of @ref ptr_to_mbr_type.
18881struct ptr_to_mbr_type::priv
18882{
18883 // The type of the data member this pointer-to-member-type
18884 // designates.
18885 type_base_sptr dm_type_;
18886 // The class (or typedef to potentially qualified class) containing
18887 // the data member this pointer-to-member-type designates.
18888 type_base_sptr containing_type_;
18889 interned_string internal_qualified_name_;
18890 interned_string temp_internal_qualified_name_;
18891
18892 priv()
18893 {}
18894
18895 priv(const type_base_sptr& dm_type, const type_base_sptr& containing_type)
18896 : dm_type_(dm_type),
18897 containing_type_(containing_type)
18898 {}
18899};// end struct ptr_to_mbr_type::priv
18900
18901/// A constructor for a @ref ptr_to_mbr_type type.
18902///
18903/// @param env the environment to construct the @ref ptr_to_mbr_type in.
18904///
18905/// @param member_type the member type of the of the @ref
18906/// ptr_to_mbr_type to construct.
18907///
18908/// @param containing_type the containing type of the @ref
18909/// ptr_to_mbr_type to construct.
18910///
18911/// @param size_in_bits the size (in bits) of the resulting type.
18912///
18913/// @param alignment_in_bits the alignment (in bits) of the resulting
18914/// type.
18915///
18916/// @param locus the source location of the definition of the
18917/// resulting type.
18918ptr_to_mbr_type::ptr_to_mbr_type(const environment& env,
18919 const type_base_sptr& member_type,
18920 const type_base_sptr& containing_type,
18921 size_t size_in_bits,
18922 size_t alignment_in_bits,
18923 const location& locus)
18924 : type_or_decl_base(env,
18925 POINTER_TO_MEMBER_TYPE
18926 | ABSTRACT_TYPE_BASE
18927 | ABSTRACT_DECL_BASE),
18928 type_base(env, size_in_bits, alignment_in_bits),
18929 decl_base(env, "", locus, ""),
18930 priv_(new priv(member_type, containing_type))
18931{
18933 ABG_ASSERT(member_type);
18934 ABG_ASSERT(containing_type);
18935 set_is_anonymous(false);
18936}
18937
18938/// Getter of the name of the current ptr-to-mbr-type.
18939///
18940/// This just returns the qualified name.
18941///
18942/// @return the (qualified) name of the the type.
18943const interned_string&
18945{
18946 return get_qualified_name(/*internal=*/false);
18947}
18948
18949/// Return the hash value of the current IR node.
18950///
18951/// Note that upon the first invocation, this member functions
18952/// computes the hash value and returns it. Subsequent invocations
18953/// just return the hash value that was previously calculated.
18954///
18955/// @return the hash value of the current IR node.
18956hash_t
18958{
18960 return h;
18961}
18962
18963/// Getter of the member type of the current @ref ptr_to_mbr_type.
18964///
18965/// @return the type of the member referred to by the current
18966/// @ptr_to_mbr_type.
18967const type_base_sptr&
18969{return priv_->dm_type_;}
18970
18971/// Getter of the type containing the member pointed-to by the current
18972/// @ref ptr_to_mbr_type.
18973///
18974/// @return the type containing the member pointed-to by the current
18975/// @ref ptr_to_mbr_type.
18976const type_base_sptr&
18978{return priv_->containing_type_;}
18979
18980/// Equality operator for the current @ref ptr_to_mbr_type.
18981///
18982///@param o the other instance of @ref ptr_to_mbr_type to compare the
18983///current instance to.
18984///
18985/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18986bool
18988{
18989 const ptr_to_mbr_type* other =
18990 dynamic_cast<const ptr_to_mbr_type*>(&o);
18991 if (!other)
18992 return false;
18993 return try_canonical_compare(this, other);
18994}
18995
18996/// Equality operator for the current @ref ptr_to_mbr_type.
18997///
18998///@param o the other instance of @ref ptr_to_mbr_type to compare the
18999///current instance to.
19000///
19001/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
19002bool
19004{
19005 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19006 if (!other)
19007 return false;
19008 return *this == *other;
19009}
19010
19011/// Equality operator for the current @ref ptr_to_mbr_type.
19012///
19013///@param o the other instance of @ref ptr_to_mbr_type to compare the
19014///current instance to.
19015///
19016/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
19017bool
19019{
19020 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19021 if (!other)
19022 return false;
19023 return *this == *other;
19024}
19025
19026/// Get the qualified name for the current @ref ptr_to_mbr_type.
19027///
19028/// @param qualified_name out parameter. This is set to the name of
19029/// the current @ref ptr_to_mbr_type.
19030///
19031/// @param internal if this is true, then the qualified name is for
19032/// the purpose of type canoicalization.
19033void
19035 bool internal) const
19036{qualified_name = get_qualified_name(internal);}
19037
19038/// Get the qualified name for the current @ref ptr_to_mbr_type.
19039///
19040/// @param internal if this is true, then the qualified name is for
19041/// the purpose of type canoicalization.
19042///
19043/// @return the qualified name for the current @ref ptr_to_mbr_type.
19044const interned_string&
19046{
19047 type_base_sptr member_type = get_member_type();
19048 type_base_sptr containing_type = get_containing_type();
19049
19050 if (internal)
19051 {
19052 if (get_canonical_type())
19053 {
19054 if (priv_->internal_qualified_name_.empty())
19055 priv_->internal_qualified_name_ =
19056 ptr_to_mbr_declaration_name(this, "",
19057 /*qualified=*/true,
19058 internal);
19059 return priv_->internal_qualified_name_;
19060 }
19061 else
19062 {
19063 priv_->temp_internal_qualified_name_ =
19064 ptr_to_mbr_declaration_name(this, "", /*qualified=*/true, internal);
19065 return priv_->temp_internal_qualified_name_;
19066 }
19067 }
19068 else
19069 {
19071 (ptr_to_mbr_declaration_name(this, "", /*qualified=*/true,
19072 /*internal=*/false));
19074 }
19075}
19076
19077/// This implements the ir_traversable_base::traverse pure virtual
19078/// function for @ref ptr_to_mbr_type.
19079///
19080/// @param v the visitor used on the current instance.
19081///
19082/// @return true if the entire IR node tree got traversed, false
19083/// otherwise.
19084bool
19086{
19087 if (v.type_node_has_been_visited(this))
19088 return true;
19089
19090 if (visiting())
19091 return true;
19092
19093 if (v.visit_begin(this))
19094 {
19095 visiting(true);
19096 if (type_base_sptr t = get_member_type())
19097 t->traverse(v);
19098
19099 if (type_base_sptr t = get_containing_type())
19100 t->traverse(v);
19101 visiting(false);
19102 }
19103
19104 bool result = v.visit_end(this);
19106 return result;
19107}
19108
19109/// Desctructor for @ref ptr_to_mbr_type.
19112
19113
19114/// Compares two instances of @ref ptr_to_mbr_type.
19115///
19116/// If the two intances are different, set a bitfield to give some
19117/// insight about the kind of differences there are.
19118///
19119/// @param l the first artifact of the comparison.
19120///
19121/// @param r the second artifact of the comparison.
19122///
19123/// @param k a pointer to a bitfield that gives information about the
19124/// kind of changes there are between @p l and @p r. This one is set
19125/// iff @p k is non-null and the function returns false.
19126///
19127/// Please note that setting k to a non-null value does have a
19128/// negative performance impact because even if @p l and @p r are not
19129/// equal, the function keeps up the comparison in order to determine
19130/// the different kinds of ways in which they are different.
19131///
19132/// @return true if @p l equals @p r, false otherwise.
19133bool
19135{
19136 bool result = true;
19137
19138 if (!(l.decl_base::operator==(r)))
19139 {
19140 result = false;
19141 if (k)
19143 else
19144 result = false;
19145 }
19146
19147 if (l.get_member_type() != r.get_member_type())
19148 {
19149 if (k)
19150 {
19151 if (!types_have_similar_structure(&l, &r))
19153 *k |= SUBTYPE_CHANGE_KIND;
19154 }
19155 result = false;
19156 }
19157
19159 {
19160 if (k)
19161 {
19162 if (!types_have_similar_structure(&l, &r))
19164 *k |= SUBTYPE_CHANGE_KIND;
19165 }
19166 result = false;
19167 }
19168
19169 ABG_RETURN(result);
19170}
19171
19172// </ptr_to_mbr_type definitions>
19173
19174// <array_type_def definitions>
19175
19176// <array_type_def::subrange_type>
19177array_type_def::subrange_type::~subrange_type() = default;
19178
19179// <array_type_def::subrante_type::bound_value>
19180
19181/// Default constructor of the @ref
19182/// array_type_def::subrange_type::bound_value class.
19183///
19184/// Constructs an unsigned bound_value of value zero.
19186 : s_(UNSIGNED_SIGNEDNESS)
19187{
19188 v_.unsigned_ = 0;
19189}
19190
19191/// Initialize an unsigned bound_value with a given value.
19192///
19193/// @param v the initial bound value.
19195 : s_(UNSIGNED_SIGNEDNESS)
19196{
19197 v_.unsigned_ = v;
19198}
19199
19200/// Initialize a signed bound_value with a given value.
19201///
19202/// @param v the initial bound value.
19204 : s_(SIGNED_SIGNEDNESS)
19205{
19206 v_.signed_ = v;
19207}
19208
19209/// Getter of the signedness (unsigned VS signed) of the bound value.
19210///
19211/// @return the signedness of the bound value.
19212enum array_type_def::subrange_type::bound_value::signedness
19215
19216/// Setter of the signedness (unsigned VS signed) of the bound value.
19217///
19218/// @param s the new signedness of the bound value.
19219void
19222
19223/// Getter of the bound value as a signed value.
19224///
19225/// @return the bound value as signed.
19226int64_t
19230
19231/// Getter of the bound value as an unsigned value.
19232///
19233/// @return the bound value as unsigned.
19234uint64_t
19237
19238/// Setter of the bound value as unsigned.
19239///
19240/// @param v the new unsigned value.
19241void
19243{
19244 s_ = UNSIGNED_SIGNEDNESS;
19245 v_.unsigned_ = v;
19246}
19247
19248/// Setter of the bound value as signed.
19249///
19250/// @param v the new signed value.
19251void
19253{
19254 s_ = SIGNED_SIGNEDNESS;
19255 v_.signed_ = v;
19256}
19257
19258/// Equality operator of the bound value.
19259///
19260/// @param v the other bound value to compare with.
19261///
19262/// @return true iff the current bound value equals @p v.
19263bool
19265{
19266 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
19267}
19268
19269// </array_type_def::subrante_type::bound_value>
19270
19271struct array_type_def::subrange_type::priv
19272{
19273 bound_value lower_bound_;
19274 bound_value upper_bound_;
19275 type_base_wptr underlying_type_;
19277 bool infinite_;
19278
19279 priv(bound_value ub,
19280 translation_unit::language l = translation_unit::LANG_C11)
19281 : upper_bound_(ub), language_(l), infinite_(false)
19282 {}
19283
19284 priv(bound_value lb, bound_value ub,
19285 translation_unit::language l = translation_unit::LANG_C11)
19286 : lower_bound_(lb), upper_bound_(ub),
19287 language_(l), infinite_(false)
19288 {}
19289
19290 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
19291 translation_unit::language l = translation_unit::LANG_C11)
19292 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
19293 language_(l), infinite_(false)
19294 {}
19295};
19296
19297/// Constructor of an array_type_def::subrange_type type.
19298///
19299/// @param env the environment this type was created from.
19300///
19301/// @param name the name of the subrange type.
19302///
19303/// @param lower_bound the lower bound of the array. This is
19304/// generally zero (at least for C and C++).
19305///
19306/// @param upper_bound the upper bound of the array.
19307///
19308/// @param underlying_type the underlying type of the subrange type.
19309///
19310/// @param loc the source location where the type is defined.
19311array_type_def::subrange_type::subrange_type(const environment& env,
19312 const string& name,
19313 bound_value lower_bound,
19314 bound_value upper_bound,
19315 const type_base_sptr& utype,
19316 const location& loc,
19318 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19319 type_base(env,
19320 utype
19321 ? utype->get_size_in_bits()
19322 : 0,
19323 0),
19324 decl_base(env, name, loc, ""),
19325 priv_(new priv(lower_bound, upper_bound, utype, l))
19326{
19328}
19329
19330/// Constructor of the array_type_def::subrange_type type.
19331///
19332/// @param env the environment this type is being created in.
19333///
19334/// @param name the name of the subrange type.
19335///
19336/// @param lower_bound the lower bound of the array. This is
19337/// generally zero (at least for C and C++).
19338///
19339/// @param upper_bound the upper bound of the array.
19340///
19341/// @param loc the source location where the type is defined.
19342///
19343/// @param l the language that generated this subrange.
19344array_type_def::subrange_type::subrange_type(const environment& env,
19345 const string& name,
19346 bound_value lower_bound,
19347 bound_value upper_bound,
19348 const location& loc,
19350 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19351 type_base(env, /*size-in-bits=*/0, /*alignment=*/0),
19352 decl_base(env, name, loc, ""),
19353 priv_(new priv(lower_bound, upper_bound, l))
19354{
19356}
19357
19358/// Constructor of the array_type_def::subrange_type type.
19359///
19360/// @param env the environment this type is being created from.
19361///
19362/// @param name of the name of type.
19363///
19364/// @param upper_bound the upper bound of the array. The lower bound
19365/// is considered to be zero.
19366///
19367/// @param loc the source location of the type.
19368///
19369/// @param the language that generated this type.
19370array_type_def::subrange_type::subrange_type(const environment& env,
19371 const string& name,
19372 bound_value upper_bound,
19373 const location& loc,
19375 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19376 type_base(env, upper_bound.get_unsigned_value(), 0),
19377 decl_base(env, name, loc, ""),
19378 priv_(new priv(upper_bound, l))
19379{
19381}
19382
19383/// Return the hash value of the current IR node.
19384///
19385/// Note that upon the first invocation, this member functions
19386/// computes the hash value and returns it. Subsequent invocations
19387/// just return the hash value that was previously calculated.
19388///
19389/// @return the hash value of the current IR node.
19390hash_t
19392{
19394 return h;
19395}
19396
19397/// Getter of the underlying type of the subrange, that is, the type
19398/// that defines the range.
19399///
19400/// @return the underlying type.
19401type_base_sptr
19403{return priv_->underlying_type_.lock();}
19404
19405/// Setter of the underlying type of the subrange, that is, the type
19406/// that defines the range.
19407///
19408/// @param u the new underlying type.
19409void
19411{
19412 ABG_ASSERT(priv_->underlying_type_.expired());
19413 priv_->underlying_type_ = u;
19414 if (u)
19415 set_size_in_bits(u->get_size_in_bits());
19416}
19417
19418/// Getter of the upper bound of the subrange type.
19419///
19420/// @return the upper bound of the subrange type.
19421int64_t
19423{return priv_->upper_bound_.get_signed_value();}
19424
19425/// Getter of the lower bound of the subrange type.
19426///
19427/// @return the lower bound of the subrange type.
19428int64_t
19430{return priv_->lower_bound_.get_signed_value();}
19431
19432/// Setter of the upper bound of the subrange type.
19433///
19434/// @param ub the new value of the upper bound.
19435void
19437{priv_->upper_bound_ = ub;}
19438
19439/// Setter of the lower bound.
19440///
19441/// @param lb the new value of the lower bound.
19442void
19444{priv_->lower_bound_ = lb;}
19445
19446/// Getter of the length of the subrange type.
19447///
19448/// Note that a length of zero means the array has an infinite (or
19449/// rather a non-known) size.
19450///
19451/// @return the length of the subrange type.
19452uint64_t
19454{
19455 if (is_non_finite())
19456 return 0;
19457
19458 // A subrange can have an upper bound that is lower than its lower
19459 // bound. This is possible in Ada for instance. In that case, the
19460 // length of the subrange is considered to be zero.
19461 if (get_upper_bound() >= get_lower_bound())
19462 return get_upper_bound() - get_lower_bound() + 1;
19463 return 0;
19464}
19465
19466/// Test if the length of the subrange type is infinite.
19467///
19468/// @return true iff the length of the subrange type is infinite.
19469bool
19471{return priv_->infinite_;}
19472
19473/// Set the infinite-ness status of the subrange type.
19474///
19475/// @param f true iff the length of the subrange type should be set to
19476/// being infinite.
19477void
19479{priv_->infinite_ = f;}
19480
19481/// Getter of the language that generated this type.
19482///
19483/// @return the language of this type.
19486{return priv_->language_;}
19487
19488/// Return a string representation of the sub range.
19489///
19490/// @return the string representation of the sub range.
19491string
19493{
19494 std::ostringstream o;
19495
19497 {
19498 type_base_sptr underlying_type = get_underlying_type();
19499 if (underlying_type)
19500 o << ir::get_pretty_representation(underlying_type, false) << " ";
19501 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
19502 }
19503 else if (is_non_finite())
19504 o << "[]";
19505 else
19506 o << "[" << get_length() << "]";
19507
19508 return o.str();
19509}
19510
19511/// Return a string representation of a vector of subranges
19512///
19513/// @return the string representation of a vector of sub ranges.
19514string
19516{
19517 if (v.empty())
19518 return "[]";
19519
19520 string r;
19521 for (vector<subrange_sptr>::const_iterator i = v.begin();
19522 i != v.end();
19523 ++i)
19524 r += (*i)->as_string();
19525
19526 return r;
19527}
19528
19529/// Compares two isntances of @ref array_type_def::subrange_type.
19530///
19531/// If the two intances are different, set a bitfield to give some
19532/// insight about the kind of differences there are.
19533///
19534/// @param l the first artifact of the comparison.
19535///
19536/// @param r the second artifact of the comparison.
19537///
19538/// @param k a pointer to a bitfield that gives information about the
19539/// kind of changes there are between @p l and @p r. This one is set
19540/// iff @p k is non-null and the function returns false.
19541///
19542/// Please note that setting k to a non-null value does have a
19543/// negative performance impact because even if @p l and @p r are not
19544/// equal, the function keeps up the comparison in order to determine
19545/// the different kinds of ways in which they are different.
19546///
19547/// @return true if @p l equals @p r, false otherwise.
19548bool
19551 change_kind* k)
19552{
19553 bool result = true;
19554
19555 if (l.get_lower_bound() != r.get_lower_bound()
19556 || l.get_upper_bound() != r.get_upper_bound()
19557 || l.get_name() != r.get_name())
19558 {
19559 result = false;
19560 if (k)
19562 else
19563 ABG_RETURN(result);
19564 }
19565
19566 if (l.get_underlying_type()
19567 && r.get_underlying_type()
19568 && (*l.get_underlying_type() != *r.get_underlying_type()))
19569 {
19570 result = false;
19571 if (k)
19572 *k |= SUBTYPE_CHANGE_KIND;
19573 else
19574 ABG_RETURN(result);
19575 }
19576
19577 ABG_RETURN(result);
19578}
19579
19580/// Equality operator.
19581///
19582/// @param o the other subrange to test against.
19583///
19584/// @return true iff @p o equals the current instance of
19585/// array_type_def::subrange_type.
19586bool
19588{
19589 const subrange_type* other =
19590 dynamic_cast<const subrange_type*>(&o);
19591 if (!other)
19592 return false;
19593 return try_canonical_compare(this, other);
19594}
19595
19596/// Equality operator.
19597///
19598/// @param o the other subrange to test against.
19599///
19600/// @return true iff @p o equals the current instance of
19601/// array_type_def::subrange_type.
19602bool
19604{
19605 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19606 if (!other)
19607 return false;
19608 return *this == *other;
19609}
19610
19611/// Equality operator.
19612///
19613/// @param o the other subrange to test against.
19614///
19615/// @return true iff @p o equals the current instance of
19616/// array_type_def::subrange_type.
19617bool
19619{
19620 const type_base &t = o;
19621 return operator==(t);
19622}
19623
19624/// Equality operator.
19625///
19626/// @param o the other subrange to test against.
19627///
19628/// @return true iff @p o equals the current instance of
19629/// array_type_def::subrange_type.
19630bool
19633
19634/// Equality operator.
19635///
19636/// @param o the other subrange to test against.
19637///
19638/// @return true iff @p o equals the current instance of
19639/// array_type_def::subrange_type.
19640bool
19643
19644/// Inequality operator.
19645///
19646/// @param o the other subrange to test against.
19647///
19648/// @return true iff @p o is different from the current instance of
19649/// array_type_def::subrange_type.
19650bool
19653
19654/// Build a pretty representation for an
19655/// array_type_def::subrange_type.
19656///
19657/// @param internal set to true if the call is intended to get a
19658/// representation of the decl (or type) for the purpose of canonical
19659/// type comparison. This is mainly used in the function
19660/// type_base::get_canonical_type_for().
19661///
19662/// In other words if the argument for this parameter is true then the
19663/// call is meant for internal use (for technical use inside the
19664/// library itself), false otherwise. If you don't know what this is
19665/// for, then set it to false.
19666///
19667/// @return a copy of the pretty representation of the current
19668/// instance of typedef_decl.
19669string
19671{
19672 string name = get_name();
19673 string repr;
19674
19675 if (name.empty())
19676 repr += "<anonymous range>";
19677 else
19678 repr += "<range " + get_name() + ">";
19679 repr += as_string();
19680
19681 return repr;
19682}
19683
19684/// This implements the ir_traversable_base::traverse pure virtual
19685/// function.
19686///
19687/// @param v the visitor used on the current instance.
19688///
19689/// @return true if the entire IR node tree got traversed, false
19690/// otherwise.
19691bool
19693{
19694 if (v.type_node_has_been_visited(this))
19695 return true;
19696
19697 if (v.visit_begin(this))
19698 {
19699 visiting(true);
19700 if (type_base_sptr u = get_underlying_type())
19701 u->traverse(v);
19702 visiting(false);
19703 }
19704
19705 bool result = v.visit_end(this);
19707 return result;
19708}
19709
19710// </array_type_def::subrange_type>
19711
19712struct array_type_def::priv
19713{
19714 type_base_wptr element_type_;
19715 subranges_type subranges_;
19716 interned_string temp_internal_qualified_name_;
19717 interned_string internal_qualified_name_;
19718
19719 priv(type_base_sptr t)
19720 : element_type_(t)
19721 {}
19722
19723 priv(type_base_sptr t, subranges_type subs)
19724 : element_type_(t), subranges_(subs)
19725 {}
19726
19727 priv()
19728 {}
19729};
19730
19731/// Constructor for the type array_type_def
19732///
19733/// Note how the constructor expects a vector of subrange
19734/// objects. Parsing of the array information always entails
19735/// parsing the subrange info as well, thus the class subrange_type
19736/// is defined inside class array_type_def and also parsed
19737/// simultaneously.
19738///
19739/// @param e_type the type of the elements contained in the array
19740///
19741/// @param subs a vector of the array's subranges(dimensions)
19742///
19743/// @param locus the source location of the array type definition.
19744array_type_def::array_type_def(const type_base_sptr e_type,
19745 const std::vector<subrange_sptr>& subs,
19746 const location& locus)
19748 ARRAY_TYPE
19749 | ABSTRACT_TYPE_BASE
19750 | ABSTRACT_DECL_BASE),
19751 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
19752 decl_base(e_type->get_environment(), locus),
19753 priv_(new priv(e_type))
19754{
19756 append_subranges(subs);
19757}
19758
19759/// Constructor for the type array_type_def
19760///
19761/// This constructor builds a temporary array that has no element type
19762/// associated. Later when the element type is available, it be set
19763/// with the array_type_def::set_element_type() member function.
19764///
19765/// Note how the constructor expects a vector of subrange
19766/// objects. Parsing of the array information always entails
19767/// parsing the subrange info as well, thus the class subrange_type
19768/// is defined inside class array_type_def and also parsed
19769/// simultaneously.
19770///
19771/// @param env the environment of the array type.
19772///
19773/// @param subs a vector of the array's subranges(dimensions)
19774///
19775/// @param locus the source location of the array type definition.
19776array_type_def::array_type_def(const environment& env,
19777 const std::vector<subrange_sptr>& subs,
19778 const location& locus)
19779 : type_or_decl_base(env,
19780 ARRAY_TYPE
19781 | ABSTRACT_TYPE_BASE
19782 | ABSTRACT_DECL_BASE),
19783 type_base(env, 0, 0),
19784 decl_base(env, locus),
19785 priv_(new priv)
19786{
19788 append_subranges(subs);
19789}
19790
19791/// Return the hash value of the current IR node.
19792///
19793/// Note that upon the first invocation, this member functions
19794/// computes the hash value and returns it. Subsequent invocations
19795/// just return the hash value that was previously calculated.
19796///
19797/// @return the hash value of the current IR node.
19798hash_t
19800{
19802 return h;
19803}
19804
19805/// Update the size of the array.
19806///
19807/// This function computes the size of the array and sets it using
19808/// type_base::set_size_in_bits().
19809void
19810array_type_def::update_size()
19811{
19812 type_base_sptr e = priv_->element_type_.lock();
19813 if (e)
19814 {
19815 size_t s = e->get_size_in_bits();
19816 if (s)
19817 {
19818 for (const auto &sub : get_subranges())
19819 s *= sub->get_length();
19821 }
19822 set_alignment_in_bits(e->get_alignment_in_bits());
19823 }
19824}
19825
19826string
19827array_type_def::get_subrange_representation() const
19828{
19830 return r;
19831}
19832
19833/// Get the pretty representation of the current instance of @ref
19834/// array_type_def.
19835///
19836/// @param internal set to true if the call is intended to get a
19837/// representation of the decl (or type) for the purpose of canonical
19838/// type comparison. This is mainly used in the function
19839/// type_base::get_canonical_type_for().
19840///
19841/// In other words if the argument for this parameter is true then the
19842/// call is meant for internal use (for technical use inside the
19843/// library itself), false otherwise. If you don't know what this is
19844/// for, then set it to false.
19845/// @param internal set to true if the call is intended for an
19846/// internal use (for technical use inside the library itself), false
19847/// otherwise. If you don't know what this is for, then set it to
19848/// false.
19849///
19850/// @return the pretty representation of the ABI artifact.
19851string
19853 bool qualified_name) const
19854{
19855 return array_declaration_name(this, /*variable_name=*/"",
19856 qualified_name, internal);
19857}
19858
19859/// Compares two instances of @ref array_type_def.
19860///
19861/// If the two intances are different, set a bitfield to give some
19862/// insight about the kind of differences there are.
19863///
19864/// @param l the first artifact of the comparison.
19865///
19866/// @param r the second artifact of the comparison.
19867///
19868/// @param k a pointer to a bitfield that gives information about the
19869/// kind of changes there are between @p l and @p r. This one is set
19870/// iff @p k is non-null and the function returns false.
19871///
19872/// Please note that setting k to a non-null value does have a
19873/// negative performance impact because even if @p l and @p r are not
19874/// equal, the function keeps up the comparison in order to determine
19875/// the different kinds of ways in which they are different.
19876///
19877/// @return true if @p l equals @p r, false otherwise.
19878bool
19880{
19881 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
19882 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
19883
19884 bool result = true;
19885 if (this_subs.size() != other_subs.size())
19886 {
19887 result = false;
19888 if (k)
19890 else
19892 }
19893
19894 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19895 for (i = this_subs.begin(), j = other_subs.begin();
19896 i != this_subs.end() && j != other_subs.end();
19897 ++i, ++j)
19898 if (**i != **j)
19899 {
19900 result = false;
19901 if (k)
19902 {
19904 break;
19905 }
19906 else
19908 }
19909
19910 // Compare the element types modulo the typedefs they might have
19911 if (l.get_element_type() != r.get_element_type())
19912 {
19913 result = false;
19914 if (k)
19915 *k |= SUBTYPE_CHANGE_KIND;
19916 else
19918 }
19919
19920 ABG_RETURN(result);
19921}
19922
19923/// Test if two array types are equals modulo CV qualifiers.
19924///
19925/// @param l the first array of the comparison.
19926///
19927/// @param r the second array of the comparison.
19928///
19929/// @return true iff @p l equals @p r or, if they are different, the
19930/// difference between the too is just a matter of CV qualifiers.
19931bool
19933{
19934 if (l == r)
19935 return true;
19936
19937 if (!l || !r)
19939
19942
19943 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
19944 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
19945
19946 if (this_subs.size() != other_subs.size())
19948
19949 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19950 for (i = this_subs.begin(), j = other_subs.begin();
19951 i != this_subs.end() && j != other_subs.end();
19952 ++i, ++j)
19953 if (**i != **j)
19955
19956 type_base *first_element_type =
19958 type_base *second_element_type =
19960
19961 if (*first_element_type != *second_element_type)
19963
19964 return true;
19965}
19966
19967/// Test if two array types are equals modulo CV qualifiers.
19968///
19969/// @param l the first array of the comparison.
19970///
19971/// @param r the second array of the comparison.
19972///
19973/// @return true iff @p l equals @p r or, if they are different, the
19974/// difference between the too is just a matter of CV qualifiers.
19975bool
19977 const array_type_def_sptr& r)
19978{return equals_modulo_cv_qualifier(l.get(), r.get());}
19979
19980/// Test if two pointer types are equals modulo CV qualifiers.
19981///
19982/// @param l the first pointer of the comparison.
19983///
19984/// @param r the second pointer of the comparison.
19985///
19986/// @return true iff @p l equals @p r or, if they are different, the
19987/// difference between the too is just a matter of CV qualifiers.
19988bool
19990{
19991 if (l == r)
19992 return true;
19993
19994 if (!l || !r)
19996
19997 type_base_sptr l_ptt = l->get_pointed_to_type(),
19998 r_ptt = r->get_pointed_to_type();
19999
20000 do
20001 {
20002 l_ptt = peel_qualified_or_typedef_type(l_ptt);
20003 r_ptt = peel_qualified_or_typedef_type(r_ptt);
20004
20005 l_ptt = is_pointer_type(l_ptt)
20007 : l_ptt;
20008
20009 r_ptt = is_pointer_type(r_ptt)
20011 : r_ptt;
20012 } while (is_pointer_type(l_ptt) && is_pointer_type(r_ptt));
20013
20014 l_ptt = peel_qualified_or_typedef_type(l_ptt);
20015 r_ptt = peel_qualified_or_typedef_type(r_ptt);
20016
20017 return *l_ptt == *r_ptt;
20018}
20019
20020/// Test if two pointer types are equals modulo CV qualifiers.
20021///
20022/// @param l the first pointer of the comparison.
20023///
20024/// @param r the second pointer of the comparison.
20025///
20026/// @return true iff @p l equals @p r or, if they are different, the
20027/// difference between the too is just a matter of CV qualifiers.
20028bool
20032
20033/// Get the language of the array.
20034///
20035/// @return the language of the array.
20038{
20039 const std::vector<subrange_sptr>& subranges =
20040 get_subranges();
20041
20042 if (subranges.empty())
20043 return translation_unit::LANG_C11;
20044 return subranges.front()->get_language();
20045}
20046
20047bool
20049{
20050 const array_type_def* other =
20051 dynamic_cast<const array_type_def*>(&o);
20052 if (!other)
20053 return false;
20054 return try_canonical_compare(this, other);
20055}
20056
20057bool
20059{
20060 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20061 if (!other)
20062 return false;
20063 return *this == *other;
20064}
20065
20066/// Getter of the type of an array element.
20067///
20068/// @return the type of an array element.
20069const type_base_sptr
20071{return priv_->element_type_.lock();}
20072
20073/// Setter of the type of array element.
20074///
20075/// Beware that after using this function, one might want to
20076/// re-compute the canonical type of the array, if one has already
20077/// been computed.
20078///
20079/// The intended use of this method is to permit in-place adjustment
20080/// of the element type's qualifiers. In particular, the size of the
20081/// element type should not be changed.
20082///
20083/// @param element_type the new element type to set.
20084void
20085array_type_def::set_element_type(const type_base_sptr& element_type)
20086{
20087 priv_->element_type_ = element_type;
20088 update_size();
20090}
20091
20092/// Append subranges from the vector @param subs to the current
20093/// vector of subranges.
20094void
20095array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
20096{
20097
20098 for (const auto &sub : subs)
20099 priv_->subranges_.push_back(sub);
20100
20101 update_size();
20103}
20104
20105/// @return true if one of the sub-ranges of the array is infinite, or
20106/// if the array has no sub-range at all, also meaning that the size
20107/// of the array is infinite.
20108bool
20110{
20111 if (priv_->subranges_.empty())
20112 return true;
20113
20114 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
20115 priv_->subranges_.begin();
20116 i != priv_->subranges_.end();
20117 ++i)
20118 if ((*i)->is_non_finite())
20119 return true;
20120
20121 return false;
20122}
20123
20124int
20125array_type_def::get_dimension_count() const
20126{return priv_->subranges_.size();}
20127
20128/// Build and return the qualified name of the current instance of the
20129/// @ref array_type_def.
20130///
20131/// @param qn output parameter. Is set to the newly-built qualified
20132/// name of the current instance of @ref array_type_def.
20133///
20134/// @param internal set to true if the call is intended for an
20135/// internal use (for technical use inside the library itself), false
20136/// otherwise. If you don't know what this is for, then set it to
20137/// false.
20138void
20140{qn = get_qualified_name(internal);}
20141
20142/// Compute the qualified name of the array.
20143///
20144/// @param internal set to true if the call is intended for an
20145/// internal use (for technical use inside the library itself), false
20146/// otherwise. If you don't know what this is for, then set it to
20147/// false.
20148///
20149/// @return the resulting qualified name.
20150const interned_string&
20152{
20153 if (internal)
20154 {
20155 if (get_canonical_type())
20156 {
20157 if (priv_->internal_qualified_name_.empty())
20158 priv_->internal_qualified_name_ =
20159 array_declaration_name(this, /*variable_name=*/"",
20160 /*qualified=*/false,
20161 /*internal=*/true);
20162 return priv_->internal_qualified_name_;
20163 }
20164 else
20165 {
20166 priv_->temp_internal_qualified_name_ =
20167 array_declaration_name(this, /*variable_name=*/"",
20168 /*qualified*/false, /*internal*/true);
20169 return priv_->temp_internal_qualified_name_;
20170 }
20171 }
20172 else
20173 {
20174 if (get_canonical_type())
20175 {
20176 if (decl_base::peek_qualified_name().empty())
20177 set_qualified_name(array_declaration_name(this,
20178 /*variable_name=*/"",
20179 /*qualified=*/false,
20180 /*internal=*/false));
20182 }
20183 else
20184 {
20186 (array_declaration_name(this, /*variable_name=*/"",
20187 /*qualified=*/false,
20188 /*internal=*/false));
20190 }
20191 }
20192}
20193
20194/// This implements the ir_traversable_base::traverse pure virtual
20195/// function.
20196///
20197/// @param v the visitor used on the current instance.
20198///
20199/// @return true if the entire IR node tree got traversed, false
20200/// otherwise.
20201bool
20203{
20204 if (v.type_node_has_been_visited(this))
20205 return true;
20206
20207 if (visiting())
20208 return true;
20209
20210 if (v.visit_begin(this))
20211 {
20212 visiting(true);
20213 if (type_base_sptr t = get_element_type())
20214 t->traverse(v);
20215 visiting(false);
20216 }
20217
20218 bool result = v.visit_end(this);
20220 return result;
20221}
20222
20223const location&
20224array_type_def::get_location() const
20225{return decl_base::get_location();}
20226
20227/// Get the array's subranges
20228const std::vector<array_type_def::subrange_sptr>&
20230{return priv_->subranges_;}
20231
20232array_type_def::~array_type_def()
20233{}
20234
20235// </array_type_def definitions>
20236
20237// <enum_type_decl definitions>
20238
20239class enum_type_decl::priv
20240{
20241 type_base_sptr underlying_type_;
20242 enumerators enumerators_;
20243 mutable enumerators sorted_enumerators_;
20244
20245 friend class enum_type_decl;
20246
20247 priv();
20248
20249public:
20250 priv(type_base_sptr underlying_type,
20252 : underlying_type_(underlying_type),
20253 enumerators_(enumerators)
20254 {}
20255}; // end class enum_type_decl::priv
20256
20257/// Constructor.
20258///
20259/// @param name the name of the type declaration.
20260///
20261/// @param locus the source location where the type was defined.
20262///
20263/// @param underlying_type the underlying type of the enum.
20264///
20265/// @param enums the enumerators of this enum type.
20266///
20267/// @param linkage_name the linkage name of the enum.
20268///
20269/// @param vis the visibility of the enum type.
20270enum_type_decl::enum_type_decl(const string& name,
20271 const location& locus,
20272 type_base_sptr underlying_type,
20273 enumerators& enums,
20274 const string& linkage_name,
20275 visibility vis)
20276 : type_or_decl_base(underlying_type->get_environment(),
20277 ENUM_TYPE
20278 | ABSTRACT_TYPE_BASE
20279 | ABSTRACT_DECL_BASE),
20280 type_base(underlying_type->get_environment(),
20281 underlying_type->get_size_in_bits(),
20282 underlying_type->get_alignment_in_bits()),
20283 decl_base(underlying_type->get_environment(),
20284 name, locus, linkage_name, vis),
20285 priv_(new priv(underlying_type, enums))
20286{
20288 for (enumerators::iterator e = get_enumerators().begin();
20289 e != get_enumerators().end();
20290 ++e)
20291 e->set_enum_type(this);
20292}
20293
20294/// Return the hash value of the current IR node.
20295///
20296/// Note that upon the first invocation, this member functions
20297/// computes the hash value and returns it. Subsequent invocations
20298/// just return the hash value that was previously calculated.
20299///
20300/// @return the hash value of the current IR node.
20301hash_t
20303{
20305 return h;
20306}
20307
20308/// Return the underlying type of the enum.
20309type_base_sptr
20311{return priv_->underlying_type_;}
20312
20313/// @return the list of enumerators of the enum.
20316{return priv_->enumerators_;}
20317
20318/// @return the list of enumerators of the enum.
20321{return priv_->enumerators_;}
20322
20323/// Get the lexicographically sorted vector of enumerators.
20324///
20325/// @return the lexicographically sorted vector of enumerators.
20328{
20329 if (priv_->sorted_enumerators_.empty())
20330 {
20331 for (auto e = get_enumerators().rbegin();
20332 e != get_enumerators().rend();
20333 ++e)
20334 priv_->sorted_enumerators_.push_back(*e);
20335
20336 std::sort(priv_->sorted_enumerators_.begin(),
20337 priv_->sorted_enumerators_.end(),
20338 [](const enum_type_decl::enumerator& l,
20340 {
20341 if (l.get_name() == r.get_name())
20342 return l.get_value() < r.get_value();
20343 return (l.get_name() < r.get_name());
20344 });
20345 }
20346
20347 return priv_->sorted_enumerators_;
20348}
20349
20350/// Find an enumerator by its value.
20351///
20352/// @param value the enumerator value to look for.
20353///
20354/// @param result output parameter. This is set to the enumerator
20355/// which value is @p value, if found. This is set iff the function
20356/// returns true.
20357///
20358/// @return true iff an enumerator with value @p value was found and
20359/// returned by argument via @p result.
20360bool
20362 enum_type_decl:: enumerator& result)
20363{
20364 for (auto& e : get_enumerators())
20365 if (e.get_value() == value)
20366 {
20367 result = e;
20368 return true;
20369 }
20370
20371 return false;
20372}
20373
20374/// Find an enumerator by its name
20375///
20376/// @param name the enumerator name to look for.
20377///
20378/// @param result output parameter. This is set to the enumerator
20379/// which name is @p name, if found. This is set iff the function
20380/// returns true.
20381///
20382/// @return true iff an enumerator with name @p name was found and
20383/// returned by argument via @p result.
20384bool
20387{
20388 for (auto& e : get_enumerators())
20389 if (e.get_name() == name)
20390 {
20391 result = e;
20392 return true;
20393 }
20394
20395 return false;
20396}
20397
20398/// Get the pretty representation of the current instance of @ref
20399/// enum_type_decl.
20400///
20401/// @param internal set to true if the call is intended to get a
20402/// representation of the decl (or type) for the purpose of canonical
20403/// type comparison. This is mainly used in the function
20404/// type_base::get_canonical_type_for().
20405///
20406/// In other words if the argument for this parameter is true then the
20407/// call is meant for internal use (for technical use inside the
20408/// library itself), false otherwise. If you don't know what this is
20409/// for, then set it to false.
20410///
20411/// @param qualified_name if true, names emitted in the pretty
20412/// representation are fully qualified.
20413///
20414/// @return the pretty representation of the enum type.
20415string
20417 bool qualified_name) const
20418{
20419 string r = "enum ";
20420
20421 if (internal && get_is_anonymous())
20422 r += get_type_name(this, qualified_name, /*internal=*/true);
20423 else if (get_is_anonymous())
20424 r += get_enum_flat_representation(*this, "",
20425 /*one_line=*/true,
20426 qualified_name);
20427 else
20429 qualified_name);
20430 return r;
20431}
20432
20433/// This implements the ir_traversable_base::traverse pure virtual
20434/// function.
20435///
20436/// @param v the visitor used on the current instance.
20437///
20438/// @return true if the entire IR node tree got traversed, false
20439/// otherwise.
20440bool
20442{
20443 if (v.type_node_has_been_visited(this))
20444 return true;
20445
20446 if (visiting())
20447 return true;
20448
20449 if (v.visit_begin(this))
20450 {
20451 visiting(true);
20452 if (type_base_sptr t = get_underlying_type())
20453 t->traverse(v);
20454 visiting(false);
20455 }
20456
20457 bool result = v.visit_end(this);
20459 return result;
20460}
20461
20462/// Destructor for the enum type declaration.
20465
20466/// Test if two enums differ, but not by a name change.
20467///
20468/// @param l the first enum to consider.
20469///
20470/// @param r the second enum to consider.
20471///
20472/// @return true iff @p l differs from @p r by anything but a name
20473/// change.
20474bool
20476 const enum_type_decl& r,
20477 change_kind* k)
20478{
20479 bool result = false;
20481 {
20482 result = true;
20483 if (k)
20484 *k |= SUBTYPE_CHANGE_KIND;
20485 else
20486 return true;
20487 }
20488
20489 enum_type_decl::enumerators::const_iterator i, j;
20490 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
20491 i != l.get_enumerators().end() && j != r.get_enumerators().end();
20492 ++i, ++j)
20493 if (*i != *j)
20494 {
20495 result = true;
20496 if (k)
20497 {
20499 break;
20500 }
20501 else
20502 return true;
20503 }
20504
20505 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
20506 {
20507 result = true;
20508 if (k)
20510 else
20511 return true;
20512 }
20513
20514 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
20517 string n_l = l.get_name();
20518 string n_r = r.get_name();
20519 local_r.set_qualified_name(qn_l);
20520 local_r.set_name(n_l);
20521
20522 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
20523 {
20524 result = true;
20525 if (k)
20526 {
20527 if (!l.decl_base::operator==(r))
20529 if (!l.type_base::operator==(r))
20531 }
20532 else
20533 {
20534 local_r.set_name(n_r);
20535 local_r.set_qualified_name(qn_r);
20536 return true;
20537 }
20538 }
20539 local_r.set_qualified_name(qn_r);
20540 local_r.set_name(n_r);
20541
20542 return result;
20543}
20544
20545/// Test if a given enumerator is found present in an enum.
20546///
20547/// This is a subroutine of the equals function for enums.
20548///
20549/// @param enr the enumerator to consider.
20550///
20551/// @param enom the enum to consider.
20552///
20553/// @return true iff the enumerator @p enr is present in the enum @p
20554/// enom.
20555bool
20557 const enum_type_decl &enom)
20558{
20559 for (const auto &e : enom.get_enumerators())
20560 if (e == enr)
20561 return true;
20562 return false;
20563}
20564
20565/// Check if two enumerators values are equal.
20566///
20567/// This function doesn't check if the names of the enumerators are
20568/// equal or not.
20569///
20570/// @param enr the first enumerator to consider.
20571///
20572/// @param enl the second enumerator to consider.
20573///
20574/// @return true iff @p enr has the same value as @p enl.
20575static bool
20576enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
20577 const enum_type_decl::enumerator &enl)
20578{return enr.get_value() == enl.get_value();}
20579
20580/// Detect if a given enumerator value is present in an enum.
20581///
20582/// This function looks inside the enumerators of a given enum and
20583/// detect if the enum contains at least one enumerator or a given
20584/// value. The function also detects if the enumerator value we are
20585/// looking at is present in the enum with a different name. An
20586/// enumerator with the same value but with a different name is named
20587/// a "redundant enumerator". The function returns the set of
20588/// enumerators that are redundant with the value we are looking at.
20589///
20590/// @param enr the enumerator to consider.
20591///
20592/// @param enom the enum to consider.
20593///
20594/// @param redundant_enrs if the function returns true, then this
20595/// vector is filled with enumerators that are redundant with the
20596/// value of @p enr.
20597///
20598/// @return true iff the function detects that @p enom contains
20599/// enumerators with the same value as @p enr.
20600static bool
20601is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
20602 const enum_type_decl &enom,
20603 vector<enum_type_decl::enumerator>& redundant_enrs)
20604{
20605 bool found = false;
20606 for (const auto &e : enom.get_enumerators())
20607 if (enumerators_values_are_equal(e, enr))
20608 {
20609 found = true;
20610 if (e != enr)
20611 redundant_enrs.push_back(e);
20612 }
20613
20614 return found;
20615}
20616
20617/// Check if an enumerator value is redundant in a given enum.
20618///
20619/// Given an enumerator value, this function detects if an enum
20620/// contains at least one enumerator with the the same value but with
20621/// a different name.
20622///
20623/// @param enr the enumerator to consider.
20624///
20625/// @param enom the enum to consider.
20626///
20627/// @return true iff @p enr is a redundant enumerator in enom.
20628static bool
20629is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
20630 const enum_type_decl &enom)
20631{
20632 vector<enum_type_decl::enumerator> redundant_enrs;
20633 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
20634 {
20635 if (!redundant_enrs.empty())
20636 return true;
20637 }
20638 return false;
20639}
20640
20641/// Compares two instances of @ref enum_type_decl.
20642///
20643/// If the two intances are different, set a bitfield to give some
20644/// insight about the kind of differences there are.
20645///
20646/// @param l the first artifact of the comparison.
20647///
20648/// @param r the second artifact of the comparison.
20649///
20650/// @param k a pointer to a bitfield that gives information about the
20651/// kind of changes there are between @p l and @p r. This one is set
20652/// iff @p k is non-null and the function returns false.
20653///
20654/// Please note that setting k to a non-null value does have a
20655/// negative performance impact because even if @p l and @p r are not
20656/// equal, the function keeps up the comparison in order to determine
20657/// the different kinds of ways in which they are different.
20658///
20659/// @return true if @p l equals @p r, false otherwise.
20660bool
20662{
20663 bool result = true;
20664
20665 //
20666 // Look through decl-only-enum.
20667 //
20668
20669 const enum_type_decl *def1 =
20672 : &l;
20673
20674 const enum_type_decl *def2 =
20677 : &r;
20678
20679 if (!!def1 != !!def2)
20680 {
20681 // One enum is decl-only while the other is not.
20682 // So the two enums are different.
20683 result = false;
20684 if (k)
20685 *k |= SUBTYPE_CHANGE_KIND;
20686 else
20688 }
20689
20690 //
20691 // At this point, both enums have the same state of decl-only-ness.
20692 // So we can compare oranges to oranges.
20693 //
20694
20695 if (!def1)
20696 def1 = &l;
20697 if (!def2)
20698 def2 = &r;
20699
20700 if (def1->get_underlying_type() != def2->get_underlying_type())
20701 {
20702 result = false;
20703 if (k)
20704 *k |= SUBTYPE_CHANGE_KIND;
20705 else
20707 }
20708
20709 if (!(def1->decl_base::operator==(*def2)
20710 && def1->type_base::operator==(*def2)))
20711 {
20712 result = false;
20713 if (k)
20714 {
20715 if (!def1->decl_base::operator==(*def2))
20717 if (!def1->type_base::operator==(*def2))
20719 }
20720 else
20722 }
20723
20724 // Now compare the enumerators.
20725
20726 // First in a naive (but potentially fast) way in case both enums
20727 // are equal in a naive manner.
20728
20729 if (def1->get_enumerators().size() == def2->get_enumerators().size())
20730 {
20731 bool equals = true;
20732 for (auto e1 = def1->get_enumerators().begin(),
20733 e2 = def2->get_enumerators().begin();
20734 (e1 != def1->get_enumerators().end()
20735 && e2 != def2->get_enumerators().end());
20736 ++e1, ++e2)
20737 {
20738 if (*e1 != *e2)
20739 {
20740 equals = false;
20741 break;
20742 }
20743 }
20744 if (equals)
20745 ABG_RETURN(result);
20746 }
20747
20748 // If the two enums where not naively equals, let's try a more
20749 // clever (and slow) way.
20750
20751 // Note that the order of declaration
20752 // of enumerators should not matter in the comparison.
20753 //
20754 // Also if an enumerator value is redundant, that shouldn't impact
20755 // the comparison.
20756 //
20757 // In that case, note that the two enums below are considered equal:
20758 //
20759 // enum foo
20760 // {
20761 // e0 = 0;
20762 // e1 = 1;
20763 // e2 = 2;
20764 // };
20765 //
20766 // enum foo
20767 // {
20768 // e0 = 0;
20769 // e1 = 1;
20770 // e2 = 2;
20771 // e_added = 1; // <-- this value is redundant with the value
20772 // // of the enumerator e1.
20773 // };
20774 //
20775 // Note however that in the case below, the enums are different.
20776 //
20777 // enum foo
20778 // {
20779 // e0 = 0;
20780 // e1 = 1;
20781 // };
20782 //
20783 // enum foo
20784 // {
20785 // e0 = 0;
20786 // e2 = 1; // <-- this enum value is present in the first version
20787 // // of foo, but is not redundant with any enumerator
20788 // // in the second version of of enum foo.
20789 // };
20790 //
20791 // These two enums are considered equal.
20792
20793 for(const auto &e : def1->get_enumerators())
20794 if (!is_enumerator_present_in_enum(e, *def2)
20795 && (!is_enumerator_value_redundant(e, *def2)
20796 || !is_enumerator_value_redundant(e, *def1)))
20797 {
20798 result = false;
20799 if (k)
20800 {
20802 break;
20803 }
20804 else
20806 }
20807
20808 for(const auto &e : def2->get_enumerators())
20809 if (!is_enumerator_present_in_enum(e, *def1)
20810 && (!is_enumerator_value_redundant(e, *def1)
20811 || !is_enumerator_value_redundant(e, *def2)))
20812 {
20813 result = false;
20814 if (k)
20815 {
20817 break;
20818 }
20819 else
20821 }
20822
20823 ABG_RETURN(result);
20824}
20825
20826/// Equality operator.
20827///
20828/// @param o the other enum to test against.
20829///
20830/// @return true iff @p o equals the current instance of enum type
20831/// decl.
20832bool
20834{
20835 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
20836 if (!op)
20837 return false;
20838 return try_canonical_compare(this, op);
20839}
20840
20841/// Equality operator.
20842///
20843/// @param o the other enum to test against.
20844///
20845/// @return true iff @p o is equals the current instance of enum type
20846/// decl.
20847bool
20849{
20850 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20851 if (!other)
20852 return false;
20853 return *this == *other;
20854}
20855
20856/// Equality operator for @ref enum_type_decl_sptr.
20857///
20858/// @param l the first operand to compare.
20859///
20860/// @param r the second operand to compare.
20861///
20862/// @return true iff @p l equals @p r.
20863bool
20865{
20866 if (!!l != !!r)
20867 return false;
20868 if (l.get() == r.get())
20869 return true;
20870 decl_base_sptr o = r;
20871 return *l == *o;
20872}
20873
20874/// Inequality operator for @ref enum_type_decl_sptr.
20875///
20876/// @param l the first operand to compare.
20877///
20878/// @param r the second operand to compare.
20879///
20880/// @return true iff @p l equals @p r.
20881bool
20883{return !operator==(l, r);}
20884
20885/// The type of the private data of an @ref
20886/// enum_type_decl::enumerator.
20887class enum_type_decl::enumerator::priv
20888{
20889 string name_;
20890 int64_t value_;
20891 string qualified_name_;
20892 enum_type_decl* enum_type_;
20893
20894 friend class enum_type_decl::enumerator;
20895
20896public:
20897
20898 priv()
20899 : enum_type_()
20900 {}
20901
20902 priv(const string& name,
20903 int64_t value,
20904 enum_type_decl* e = 0)
20905 : name_(name),
20906 value_(value),
20907 enum_type_(e)
20908 {}
20909}; // end class enum_type_def::enumerator::priv
20910
20911/// Default constructor of the @ref enum_type_decl::enumerator type.
20913 : priv_(new priv)
20914{}
20915
20916enum_type_decl::enumerator::~enumerator() = default;
20917
20918/// Constructor of the @ref enum_type_decl::enumerator type.
20919///
20920/// @param env the environment we are operating from.
20921///
20922/// @param name the name of the enumerator.
20923///
20924/// @param value the value of the enumerator.
20926 int64_t value)
20927 : priv_(new priv(name, value))
20928{}
20929
20930/// Copy constructor of the @ref enum_type_decl::enumerator type.
20931///
20932/// @param other enumerator to copy.
20934 : priv_(new priv(other.get_name(),
20935 other.get_value(),
20936 other.get_enum_type()))
20937{}
20938
20939/// Assignment operator of the @ref enum_type_decl::enumerator type.
20940///
20941/// @param o
20944{
20945 priv_->name_ = o.get_name();
20946 priv_->value_ = o.get_value();
20947 priv_->enum_type_ = o.get_enum_type();
20948 return *this;
20949}
20950
20951/// Equality operator
20952///
20953/// @param other the enumerator to compare to the current
20954/// instance of enum_type_decl::enumerator.
20955///
20956/// @return true if @p other equals the current instance of
20957/// enum_type_decl::enumerator.
20958bool
20960{
20961 bool names_equal = true;
20962 names_equal = (get_name() == other.get_name());
20963 return names_equal && (get_value() == other.get_value());
20964}
20965
20966/// Inequality operator.
20967///
20968/// @param other the other instance to compare against.
20969///
20970/// @return true iff @p other is different from the current instance.
20971bool
20973{return !operator==(other);}
20974
20975/// Getter for the name of the current instance of
20976/// enum_type_decl::enumerator.
20977///
20978/// @return a reference to the name of the current instance of
20979/// enum_type_decl::enumerator.
20980const string&
20982{return priv_->name_;}
20983
20984/// Getter for the qualified name of the current instance of
20985/// enum_type_decl::enumerator. The first invocation of the method
20986/// builds the qualified name, caches it and return a reference to the
20987/// cached qualified name. Subsequent invocations just return the
20988/// cached value.
20989///
20990/// @param internal set to true if the call is intended for an
20991/// internal use (for technical use inside the library itself), false
20992/// otherwise. If you don't know what this is for, then set it to
20993/// false.
20994///
20995/// @return the qualified name of the current instance of
20996/// enum_type_decl::enumerator.
20997const string&
20999{
21000 if (priv_->qualified_name_.empty())
21001 {
21002 priv_->qualified_name_ =
21003 get_enum_type()->get_qualified_name(internal)
21004 + "::"
21005 + get_name();
21006 }
21007 return priv_->qualified_name_;
21008}
21009
21010/// Setter for the name of @ref enum_type_decl::enumerator.
21011///
21012/// @param n the new name.
21013void
21015{priv_->name_ = n;}
21016
21017/// Getter for the value of @ref enum_type_decl::enumerator.
21018///
21019/// @return the value of the current instance of
21020/// enum_type_decl::enumerator.
21021int64_t
21023{return priv_->value_;}
21024
21025/// Setter for the value of @ref enum_type_decl::enumerator.
21026///
21027/// @param v the new value of the enum_type_decl::enumerator.
21028void
21030{priv_->value_= v;}
21031
21032/// Getter for the enum type that this enumerator is for.
21033///
21034/// @return the enum type that this enumerator is for.
21037{return priv_->enum_type_;}
21038
21039/// Setter for the enum type that this enumerator is for.
21040///
21041/// @param e the new enum type.
21042void
21045// </enum_type_decl definitions>
21046
21047// <typedef_decl definitions>
21048
21049/// Private data structure of the @ref typedef_decl.
21050struct typedef_decl::priv
21051{
21052 type_base_wptr underlying_type_;
21053
21054 priv(const type_base_sptr& t)
21055 : underlying_type_(t)
21056 {}
21057}; // end struct typedef_decl::priv
21058
21059/// Constructor of the typedef_decl type.
21060///
21061/// @param name the name of the typedef.
21062///
21063/// @param underlying_type the underlying type of the typedef.
21064///
21065/// @param locus the source location of the typedef declaration.
21066///
21067/// @param linkage_name the mangled name of the typedef.
21068///
21069/// @param vis the visibility of the typedef type.
21070typedef_decl::typedef_decl(const string& name,
21071 const type_base_sptr underlying_type,
21072 const location& locus,
21073 const string& linkage_name,
21074 visibility vis)
21075 : type_or_decl_base(underlying_type->get_environment(),
21076 TYPEDEF_TYPE
21077 | ABSTRACT_TYPE_BASE
21078 | ABSTRACT_DECL_BASE),
21079 type_base(underlying_type->get_environment(),
21080 underlying_type->get_size_in_bits(),
21081 underlying_type->get_alignment_in_bits()),
21082 decl_base(underlying_type->get_environment(),
21083 name, locus, linkage_name, vis),
21084 priv_(new priv(underlying_type))
21085{
21087}
21088
21089/// Constructor of the typedef_decl type.
21090///
21091/// @param name the name of the typedef.
21092///
21093/// @param env the environment of the current typedef.
21094///
21095/// @param locus the source location of the typedef declaration.
21096///
21097/// @param mangled_name the mangled name of the typedef.
21098///
21099/// @param vis the visibility of the typedef type.
21100typedef_decl::typedef_decl(const string& name,
21101 const environment& env,
21102 const location& locus,
21103 const string& mangled_name,
21104 visibility vis)
21105 : type_or_decl_base(env,
21106 TYPEDEF_TYPE
21107 | ABSTRACT_TYPE_BASE
21108 | ABSTRACT_DECL_BASE),
21109 type_base(env, /*size_in_bits=*/0,
21110 /*alignment_in_bits=*/0),
21111 decl_base(env, name, locus, mangled_name, vis),
21112 priv_(new priv(nullptr))
21113{
21115}
21116
21117/// Return the hash value of the current IR node.
21118///
21119/// Note that upon the first invocation, this member functions
21120/// computes the hash value and returns it. Subsequent invocations
21121/// just return the hash value that was previously calculated.
21122///
21123/// @return the hash value of the current IR node.
21124hash_t
21126{
21128 return h;
21129}
21130
21131/// Return the size of the typedef.
21132///
21133/// This function looks at the size of the underlying type and ensures
21134/// that it's the same as the size of the typedef.
21135///
21136/// @return the size of the typedef.
21137size_t
21139{
21140 if (!get_underlying_type())
21141 return 0;
21142 size_t s = get_underlying_type()->get_size_in_bits();
21143 if (s != type_base::get_size_in_bits())
21144 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
21146}
21147
21148/// Return the alignment of the typedef.
21149///
21150/// This function looks at the alignment of the underlying type and
21151/// ensures that it's the same as the alignment of the typedef.
21152///
21153/// @return the size of the typedef.
21154size_t
21156{
21157 if (!get_underlying_type())
21158 return 0;
21159 size_t s = get_underlying_type()->get_alignment_in_bits();
21161 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
21163}
21164
21165/// Compares two instances of @ref typedef_decl.
21166///
21167/// If the two intances are different, set a bitfield to give some
21168/// insight about the kind of differences there are.
21169///
21170/// @param l the first artifact of the comparison.
21171///
21172/// @param r the second artifact of the comparison.
21173///
21174/// @param k a pointer to a bitfield that gives information about the
21175/// kind of changes there are between @p l and @p r. This one is set
21176/// iff @p k is non-null and the function returns false.
21177///
21178/// Please note that setting k to a non-null value does have a
21179/// negative performance impact because even if @p l and @p r are not
21180/// equal, the function keeps up the comparison in order to determine
21181/// the different kinds of ways in which they are different.
21182///
21183/// @return true if @p l equals @p r, false otherwise.
21184bool
21186{
21187 bool result = true;
21188
21189 // No need to go further if the types have different names or
21190 // different size / alignment.
21191 if (!(l.decl_base::operator==(r)))
21192 {
21193 result = false;
21194 if (k)
21196 else
21198 }
21199
21201 {
21202 // Changes to the underlying type of a typedef are considered
21203 // local, a bit like for pointers.
21204 result = false;
21205 if (k)
21207 else
21209 }
21210
21211 ABG_RETURN(result);
21212}
21213
21214/// Equality operator
21215///
21216/// @param o the other typedef_decl to test against.
21217bool
21219{
21220 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
21221 if (!other)
21222 return false;
21223 return try_canonical_compare(this, other);
21224}
21225
21226/// Equality operator
21227///
21228/// @param o the other typedef_decl to test against.
21229///
21230/// @return true if the current instance of @ref typedef_decl equals
21231/// @p o.
21232bool
21234{
21235 const decl_base* other = dynamic_cast<const decl_base*>(&o);
21236 if (!other)
21237 return false;
21238 return *this == *other;
21239}
21240
21241/// Build a pretty representation for a typedef_decl.
21242///
21243/// @param internal set to true if the call is intended to get a
21244/// representation of the decl (or type) for the purpose of canonical
21245/// type comparison. This is mainly used in the function
21246/// type_base::get_canonical_type_for().
21247///
21248/// In other words if the argument for this parameter is true then the
21249/// call is meant for internal use (for technical use inside the
21250/// library itself), false otherwise. If you don't know what this is
21251/// for, then set it to false.
21252
21253/// @param qualified_name if true, names emitted in the pretty
21254/// representation are fully qualified.
21255///
21256/// @return a copy of the pretty representation of the current
21257/// instance of typedef_decl.
21258string
21260 bool qualified_name) const
21261{
21262
21263 string result = "typedef ";
21264 if (qualified_name)
21265 result += get_qualified_name(internal);
21266 else
21267 result += get_name();
21268
21269 return result;
21270}
21271
21272/// Getter of the underlying type of the typedef.
21273///
21274/// @return the underlying_type.
21275type_base_sptr
21277{return priv_->underlying_type_.lock();}
21278
21279/// Setter ofthe underlying type of the typedef.
21280///
21281/// @param t the new underlying type of the typedef.
21282void
21284{
21285 priv_->underlying_type_ = t;
21286 set_size_in_bits(t->get_size_in_bits());
21287 set_alignment_in_bits(t->get_alignment_in_bits());
21288}
21289
21290/// Implementation of the virtual "get_qualified_name" method.
21291///
21292/// @param qualified_name the resuling qualified name of the typedef type.
21293///
21294/// @param internal if true, then it means the qualified name is for
21295/// "internal" purposes, meaning mainly for type canonicalization
21296/// purposes.
21297void
21299 bool internal) const
21300{qualified_name = get_qualified_name(internal);}
21301
21302/// Implementation of the virtual "get_qualified_name" method.
21303///
21304/// @param internal if true, then it means the qualified name is for
21305/// "internal" purposes, meaning mainly for type canonicalization
21306/// purposes.
21307///
21308/// @return the qualified name.
21309const interned_string&
21311{
21312 // Note that the qualified name has been already set by
21313 // qualified_name_setter::do_update, which is invoked by
21314 // update_qualified_name. The latter is itself invoked whenever the
21315 // typedef is added to its scope, in scope_decl::add_member_decl.
21316 if (internal)
21317 return decl_base::priv_->internal_qualified_name_;
21318 else
21319 return decl_base::priv_->qualified_name_;
21320}
21321
21322/// This implements the ir_traversable_base::traverse pure virtual
21323/// function.
21324///
21325/// @param v the visitor used on the current instance.
21326///
21327/// @return true if the entire IR node tree got traversed, false
21328/// otherwise.
21329bool
21331{
21332 if (v.type_node_has_been_visited(this))
21333 return true;
21334
21335 if (visiting())
21336 return true;
21337
21338 if (v.visit_begin(this))
21339 {
21340 visiting(true);
21341 if (type_base_sptr t = get_underlying_type())
21342 t->traverse(v);
21343 visiting(false);
21344 }
21345
21346 bool result = v.visit_end(this);
21348 return result;
21349}
21350
21351typedef_decl::~typedef_decl()
21352{}
21353// </typedef_decl definitions>
21354
21355// <var_decl definitions>
21356
21357struct var_decl::priv
21358{
21359 type_base_wptr type_;
21360 type_base* naked_type_;
21361 decl_base::binding binding_;
21362 elf_symbol_sptr symbol_;
21363 interned_string id_;
21364
21365 priv()
21366 : naked_type_(),
21367 binding_(decl_base::BINDING_GLOBAL)
21368 {}
21369
21370 priv(type_base_sptr t,
21372 : type_(t),
21373 naked_type_(t.get()),
21374 binding_(b)
21375 {}
21376
21377 /// Setter of the type of the variable.
21378 ///
21379 /// @param t the new variable type.
21380 void
21381 set_type(type_base_sptr t)
21382 {
21383 type_ = t;
21384 naked_type_ = t.get();
21385 }
21386}; // end struct var_decl::priv
21387
21388/// Constructor of the @ref var_decl type.
21389///
21390/// @param name the name of the variable declaration
21391///
21392/// @param type the type of the variable declaration
21393///
21394/// @param locus the source location where the variable was defined.
21395///
21396/// @param linkage_name the linkage name of the variable.
21397///
21398/// @param vis the visibility of of the variable.
21399///
21400/// @param bind the binding kind of the variable.
21401var_decl::var_decl(const string& name,
21402 type_base_sptr type,
21403 const location& locus,
21404 const string& linkage_name,
21405 visibility vis,
21406 binding bind)
21407 : type_or_decl_base(type->get_environment(),
21408 VAR_DECL | ABSTRACT_DECL_BASE),
21409 decl_base(type->get_environment(), name, locus, linkage_name, vis),
21410 priv_(new priv(type, bind))
21411{
21413}
21414
21415/// Getter of the type of the variable.
21416///
21417/// @return the type of the variable.
21418const type_base_sptr
21420{return priv_->type_.lock();}
21421
21422/// Setter of the type of the variable.
21423///
21424/// @param the new type of the variable.
21425void
21426var_decl::set_type(type_base_sptr& t)
21427{priv_->set_type(t);}
21428
21429/// Getter of the type of the variable.
21430///
21431/// This getter returns a bare pointer, as opposed to a smart pointer.
21432/// It's to be used on performance sensitive code paths identified by
21433/// careful profiling.
21434///
21435/// @return the type of the variable, as a bare pointer.
21436const type_base*
21438{return priv_->naked_type_;}
21439
21440/// Getter of the binding of the variable.
21441///
21442/// @return the biding of the variable.
21445{return priv_->binding_;}
21446
21447/// Setter of the binding of the variable.
21448///
21449/// @param b the new binding value.
21450void
21452{priv_->binding_ = b;}
21453
21454/// Sets the underlying ELF symbol for the current variable.
21455///
21456/// And underlyin$g ELF symbol for the current variable might exist
21457/// only if the corpus that this variable originates from was
21458/// constructed from an ELF binary file.
21459///
21460/// Note that comparing two variables that have underlying ELF symbols
21461/// involves comparing their underlying elf symbols. The decl name
21462/// for the variable thus becomes irrelevant in the comparison.
21463///
21464/// @param sym the new ELF symbol for this variable decl.
21465void
21467{
21468 priv_->symbol_ = sym;
21469 // The variable id cache that depends on the symbol must be
21470 // invalidated because the symbol changed.
21471 priv_->id_ = get_environment().intern("");
21472}
21473
21474/// Gets the the underlying ELF symbol for the current variable,
21475/// that was set using var_decl::set_symbol(). Please read the
21476/// documentation for that member function for more information about
21477/// "underlying ELF symbols".
21478///
21479/// @return sym the underlying ELF symbol for this variable decl, if
21480/// one exists.
21481const elf_symbol_sptr&
21483{return priv_->symbol_;}
21484
21485/// Create a new var_decl that is a clone of the current one.
21486///
21487/// @return the cloned var_decl.
21490{
21492 get_type(),
21493 get_location(),
21496 get_binding()));
21497
21498 v->set_symbol(get_symbol());
21499
21500 if (is_member_decl(*this))
21501 {
21505 get_member_is_static(*this),
21506 get_data_member_offset(*this));
21507 }
21508 else
21510
21511 return v;
21512}
21513/// Setter of the scope of the current var_decl.
21514///
21515/// Note that the decl won't hold a reference on the scope. It's
21516/// rather the scope that holds a reference on its members.
21517///
21518/// @param scope the new scope.
21519void
21520var_decl::set_scope(scope_decl* scope)
21521{
21522 if (!get_context_rel())
21523 set_context_rel(new dm_context_rel(scope));
21524 else
21525 get_context_rel()->set_scope(scope);
21526}
21527
21528/// Compares two instances of @ref var_decl without taking their type
21529/// into account.
21530///
21531/// If the two intances are different modulo their type, set a
21532/// bitfield to give some insight about the kind of differences there
21533/// are.
21534///
21535/// @param l the first artifact of the comparison.
21536///
21537/// @param r the second artifact of the comparison.
21538///
21539/// @param k a pointer to a bitfield that gives information about the
21540/// kind of changes there are between @p l and @p r. This one is set
21541/// iff @p k is non-null and the function returns false.
21542///
21543/// Please note that setting k to a non-null value does have a
21544/// negative performance impact because even if @p l and @p r are not
21545/// equal, the function keeps up the comparison in order to determine
21546/// the different kinds of ways in which they are different.
21547///
21548/// @return true if @p l equals @p r, false otherwise.
21549bool
21551{
21552 bool result = true;
21553
21554 // If there are underlying elf symbols for these variables,
21555 // compare them. And then compare the other parts.
21556 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
21557 if (!!s0 != !!s1)
21558 {
21559 result = false;
21560 if (k)
21562 else
21564 }
21565 else if (s0 && !textually_equals(*s0, *s1, k))
21566 {
21567 result = false;
21568 if (!k)
21570 }
21571 bool symbols_are_equal = (s0 && s1 && result);
21572
21573 if (symbols_are_equal)
21574 {
21575 // The variables have underlying elf symbols that are equal, so
21576 // now, let's compare the decl_base part of the variables w/o
21577 // considering their decl names.
21578 const environment& env = l.get_environment();
21579 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
21580 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
21581 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
21582 bool decl_bases_different = !l.decl_base::operator==(r);
21583 const_cast<var_decl&>(l).set_qualified_name(n1);
21584 const_cast<var_decl&>(r).set_qualified_name(n2);
21585
21586 if (decl_bases_different)
21587 {
21588 result = false;
21589 if (k)
21591 else
21593 }
21594 }
21595 else
21596 if (!l.decl_base::operator==(r))
21597 {
21598 result = false;
21599 if (k)
21601 else
21603 }
21604
21605 const dm_context_rel* c0 =
21606 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
21607 const dm_context_rel* c1 =
21608 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
21609 ABG_ASSERT(c0 && c1);
21610
21611 if (*c0 != *c1)
21612 {
21613 result = false;
21614 if (k)
21616 else
21618 }
21619
21620 ABG_RETURN(result);
21621}
21622
21623/// Compares two instances of @ref var_decl.
21624///
21625/// If the two intances are different, set a bitfield to give some
21626/// insight about the kind of differences there are.
21627///
21628/// @param l the first artifact of the comparison.
21629///
21630/// @param r the second artifact of the comparison.
21631///
21632/// @param k a pointer to a bitfield that gives information about the
21633/// kind of changes there are between @p l and @p r. This one is set
21634/// iff @p k is non-null and the function returns false.
21635///
21636/// Please note that setting k to a non-null value does have a
21637/// negative performance impact because even if @p l and @p r are not
21638/// equal, the function keeps up the comparison in order to determine
21639/// the different kinds of ways in which they are different.
21640///
21641/// @return true if @p l equals @p r, false otherwise.
21642bool
21643equals(const var_decl& l, const var_decl& r, change_kind* k)
21644{
21645 bool result = true;
21646
21647 // First test types of variables. This should be fast because in
21648 // the general case, most types should be canonicalized.
21649 if (*l.get_naked_type() != *r.get_naked_type())
21650 {
21651 result = false;
21652 if (k)
21653 {
21655 r.get_naked_type()))
21656 *k |= (LOCAL_TYPE_CHANGE_KIND);
21657 else
21658 *k |= SUBTYPE_CHANGE_KIND;
21659 }
21660 else
21662 }
21663
21664 result &= var_equals_modulo_types(l, r, k);
21665
21666 ABG_RETURN(result);
21667}
21668
21669/// Comparison operator of @ref var_decl.
21670///
21671/// @param o the instance of @ref var_decl to compare against.
21672///
21673/// @return true iff the current instance of @ref var_decl equals @p o.
21674bool
21676{
21677 const var_decl* other = dynamic_cast<const var_decl*>(&o);
21678 if (!other)
21679 return false;
21680
21681 return equals(*this, *other, 0);
21682}
21683
21684/// Return an ID that tries to uniquely identify the variable inside a
21685/// program or a library.
21686///
21687/// So if the variable has an underlying elf symbol, the ID is the
21688/// concatenation of the symbol name and its version. Otherwise, the
21689/// ID is the linkage name if its non-null. Otherwise, it's the
21690/// pretty representation of the variable.
21691///
21692/// @return the ID.
21695{
21696 if (priv_->id_.empty())
21697 {
21698 string repr = get_name();
21699 string sym_str;
21700 if (elf_symbol_sptr s = get_symbol())
21701 sym_str = s->get_id_string();
21702 else if (!get_linkage_name().empty())
21703 sym_str = get_linkage_name();
21704
21705 const environment& env = get_type()->get_environment();
21706 priv_->id_ = env.intern(repr);
21707 if (!sym_str.empty())
21708 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
21709 }
21710 return priv_->id_;
21711}
21712
21713/// Get the qualified name of a given variable or data member.
21714///
21715///
21716/// Note that if the current instance of @ref var_decl is an anonymous
21717/// data member, then the qualified name is actually the flat
21718/// representation (the definition) of the type of the anonymous data
21719/// member. We chose the flat representation because otherwise, the
21720/// name of an *anonymous* data member is empty, by construction, e.g:
21721///
21722/// struct foo {
21723/// int a;
21724/// union {
21725/// char b;
21726/// char c;
21727/// }; // <---- this data member is anonymous.
21728/// int d;
21729/// }
21730///
21731/// The string returned for the anonymous member here is going to be:
21732///
21733/// "union {char b; char c}"
21734///
21735/// @param internal if true then this is for a purpose to the library,
21736/// otherwise, it's for being displayed to users.
21737///
21738/// @return the resulting qualified name.
21739const interned_string&
21741{
21742 if (is_anonymous_data_member(this)
21743 && decl_base::get_qualified_name().empty())
21744 {
21745 // Display the anonymous data member in a way that makes sense.
21746 string r = get_pretty_representation(internal);
21748 }
21749
21750 return decl_base::get_qualified_name(internal);
21751}
21752
21753/// Build and return the pretty representation of this variable.
21754///
21755/// @param internal set to true if the call is intended to get a
21756/// representation of the decl (or type) for the purpose of canonical
21757/// type comparison. This is mainly used in the function
21758/// type_base::get_canonical_type_for().
21759///
21760/// In other words if the argument for this parameter is true then the
21761/// call is meant for internal use (for technical use inside the
21762/// library itself), false otherwise. If you don't know what this is
21763/// for, then set it to false.
21764///
21765/// @param qualified_name if true, names emitted in the pretty
21766/// representation are fully qualified.
21767///
21768/// @return a copy of the pretty representation of this variable.
21769string
21770var_decl::get_pretty_representation(bool internal, bool qualified_name) const
21771{
21772 string result;
21773
21774 if (is_member_decl(this) && get_member_is_static(this))
21775 result = "static ";
21776
21777 // Detect if the current instance of var_decl is a member of
21778 // an anonymous class or union.
21779 bool member_of_anonymous_class = false;
21780 if (class_or_union* scope = is_at_class_scope(this))
21781 if (scope->get_is_anonymous())
21782 member_of_anonymous_class = true;
21783
21784 type_base_sptr type = get_type();
21785 if (is_array_type(type, /*look_through_qualifiers=*/true)
21786 || is_pointer_type(type, /*look_through_qualifiers=*/true)
21787 || is_reference_type(type, /*look_through_qualifiers=*/true)
21788 || is_ptr_to_mbr_type(type, /*look_through_qualifiers=*/true))
21789 {
21790 string name;
21791 if (member_of_anonymous_class || !qualified_name)
21792 name = get_name();
21793 else
21794 name = get_qualified_name(internal);
21795
21796 if (qualified_type_def_sptr q = is_qualified_type(type))
21797 {
21798 string quals_repr =
21799 get_string_representation_of_cv_quals(q->get_cv_quals());
21800 if (!quals_repr.empty())
21801 name = quals_repr + " " + name;
21802 type = peel_qualified_type(type);
21803 }
21804
21805 name = string(" ") + name;
21806 if (array_type_def_sptr t = is_array_type(type))
21807 result += array_declaration_name(t, name, qualified_name, internal);
21808 else if (pointer_type_def_sptr t = is_pointer_type(type))
21809 result += pointer_declaration_name(t, name, qualified_name, internal);
21810 else if (reference_type_def_sptr t = is_reference_type(type))
21811 result += pointer_declaration_name(t, name, qualified_name, internal);
21812 else if (ptr_to_mbr_type_sptr t = is_ptr_to_mbr_type(type))
21813 result += ptr_to_mbr_declaration_name(t, name,
21814 qualified_name,
21815 internal);
21816 }
21817 else
21818 {
21819 if (/*The current var_decl is to be used as an anonymous data
21820 member. */
21821 get_name().empty())
21822 {
21823 // Display the anonymous data member in a way that
21824 // makes sense.
21825 result +=
21828 "", /*one_line=*/true, internal);
21829 }
21830 else if (data_member_has_anonymous_type(this))
21831 {
21834 "", /*one_line=*/true, internal);
21835 result += " ";
21836 if (!internal
21837 && (member_of_anonymous_class || !qualified_name))
21838 // It doesn't make sense to name the member of an
21839 // anonymous class or union like:
21840 // "__anonymous__::data_member_name". So let's just use
21841 // its non-qualified name.
21842 result += get_name();
21843 else
21844 result += get_qualified_name(internal);
21845 }
21846 else
21847 {
21848 result +=
21850 + " ";
21851
21852 if (!internal
21853 && (member_of_anonymous_class || !qualified_name))
21854 // It doesn't make sense to name the member of an
21855 // anonymous class or union like:
21856 // "__anonymous__::data_member_name". So let's just use
21857 // its non-qualified name.
21858 result += get_name();
21859 else
21860 result += get_qualified_name(internal);
21861 }
21862 }
21863 return result;
21864}
21865
21866/// Get a name that is valid even for an anonymous data member.
21867///
21868/// If the current @ref var_decl is an anonymous data member, then
21869/// return its pretty representation. As of now, that pretty
21870/// representation is actually its flat representation as returned by
21871/// get_class_or_union_flat_representation().
21872///
21873/// Otherwise, just return the name of the current @ref var_decl.
21874///
21875/// @param qualified if true, return the qualified name. This doesn't
21876/// have an effet if the current @ref var_decl represents an anonymous
21877/// data member.
21878string
21880{
21881 string name;
21882 if (is_anonymous_data_member(this))
21883 // This function is used in the comparison engine to determine
21884 // which anonymous data member was deleted. So it's not involved
21885 // in type comparison or canonicalization. We don't want to use
21886 // the 'internal' version of the pretty presentation.
21887 name = get_pretty_representation(/*internal=*/false, qualified);
21888 else
21889 name = get_name();
21890
21891 return name;
21892}
21893
21894/// This implements the ir_traversable_base::traverse pure virtual
21895/// function.
21896///
21897/// @param v the visitor used on the current instance.
21898///
21899/// @return true if the entire IR node tree got traversed, false
21900/// otherwise.
21901bool
21903{
21904 if (visiting())
21905 return true;
21906
21907 if (v.visit_begin(this))
21908 {
21909 visiting(true);
21910 if (type_base_sptr t = get_type())
21911 t->traverse(v);
21912 visiting(false);
21913 }
21914 return v.visit_end(this);
21915}
21916
21917var_decl::~var_decl()
21918{}
21919
21920// </var_decl definitions>
21921
21922/// This function is automatically invoked whenever an instance of
21923/// this type is canonicalized.
21924///
21925/// It's an overload of the virtual type_base::on_canonical_type_set.
21926///
21927/// We put here what is thus meant to be executed only at the point of
21928/// type canonicalization.
21929void
21931{
21932 priv_->cached_name_.clear();
21933 priv_->internal_cached_name_.clear();
21934}
21935
21936/// The most straightforward constructor for the function_type class.
21937///
21938/// @param return_type the return type of the function type.
21939///
21940/// @param parms the list of parameters of the function type.
21941/// Stricto sensu, we just need a list of types; we are using a list
21942/// of parameters (where each parameter also carries the name of the
21943/// parameter and its source location) to try and provide better
21944/// diagnostics whenever it makes sense. If it appears that this
21945/// wasts too many resources, we can fall back to taking just a
21946/// vector of types here.
21947///
21948/// @param size_in_bits the size of this type, in bits.
21949///
21950/// @param alignment_in_bits the alignment of this type, in bits.
21951///
21952/// @param size_in_bits the size of this type.
21953function_type::function_type(type_base_sptr return_type,
21954 const parameters& parms,
21955 size_t size_in_bits,
21956 size_t alignment_in_bits)
21957 : type_or_decl_base(return_type->get_environment(),
21958 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21959 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21960 priv_(new priv(parms, return_type))
21961{
21963
21964 for (parameters::size_type i = 0, j = 1;
21965 i < priv_->parms_.size();
21966 ++i, ++j)
21967 {
21968 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21969 // If the first parameter is artificial, then it certainly
21970 // means that this is a member function, and the first
21971 // parameter is the implicit this pointer. In that case, set
21972 // the index of that implicit parameter to zero. Otherwise,
21973 // the index of the first parameter starts at one.
21974 j = 0;
21975 priv_->parms_[i]->set_index(j);
21976 }
21977}
21978
21979/// A constructor for a function_type that takes no parameters.
21980///
21981/// @param return_type the return type of this function_type.
21982///
21983/// @param size_in_bits the size of this type, in bits.
21984///
21985/// @param alignment_in_bits the alignment of this type, in bits.
21986function_type::function_type(type_base_sptr return_type,
21987 size_t size_in_bits, size_t alignment_in_bits)
21988 : type_or_decl_base(return_type->get_environment(),
21989 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21990 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21991 priv_(new priv(return_type))
21992{
21994}
21995
21996/// A constructor for a function_type that takes no parameter and
21997/// that has no return_type yet. These missing parts can (and must)
21998/// be added later.
21999///
22000/// @param env the environment we are operating from.
22001///
22002/// @param size_in_bits the size of this type, in bits.
22003///
22004/// @param alignment_in_bits the alignment of this type, in bits.
22005function_type::function_type(const environment& env,
22006 size_t size_in_bits,
22007 size_t alignment_in_bits)
22008 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
22009 type_base(env, size_in_bits, alignment_in_bits),
22010 priv_(new priv)
22011{
22013}
22014
22015/// Return the hash value of the current IR node.
22016///
22017/// Note that upon the first invocation, this member functions
22018/// computes the hash value and returns it. Subsequent invocations
22019/// just return the hash value that was previously calculated.
22020///
22021/// @return the hash value of the current IR node.
22022hash_t
22024{
22026 return h;
22027}
22028
22029/// Getter for the return type of the current instance of @ref
22030/// function_type.
22031///
22032/// @return the return type.
22033type_base_sptr
22035{return priv_->return_type_.lock();}
22036
22037/// Setter of the return type of the current instance of @ref
22038/// function_type.
22039///
22040/// @param t the new return type to set.
22041void
22043{priv_->return_type_ = t;}
22044
22045/// Getter for the set of parameters of the current intance of @ref
22046/// function_type.
22047///
22048/// @return the parameters of the current instance of @ref
22049/// function_type.
22052{return priv_->parms_;}
22053
22054/// Get the Ith parameter of the vector of parameters of the current
22055/// instance of @ref function_type.
22056///
22057/// Note that the first parameter is at index 0. That parameter is
22058/// the first parameter that comes after the possible implicit "this"
22059/// parameter, when the current instance @ref function_type is for a
22060/// member function. Otherwise, if the current instance of @ref
22061/// function_type is for a non-member function, the parameter at index
22062/// 0 is the first parameter of the function.
22063///
22064///
22065/// @param i the index of the parameter to return. If i is greater
22066/// than the index of the last parameter, then this function returns
22067/// an empty parameter (smart) pointer.
22068///
22069/// @return the @p i th parameter that is not implicit.
22072{
22073 parameter_sptr result;
22074 if (dynamic_cast<const method_type*>(this))
22075 {
22076 if (i + 1 < get_parameters().size())
22077 result = get_parameters()[i + 1];
22078 }
22079 else
22080 {
22081 if (i < get_parameters().size())
22082 result = get_parameters()[i];
22083 }
22084 return result;
22085}
22086
22087/// Setter for the parameters of the current instance of @ref
22088/// function_type.
22089///
22090/// @param p the new vector of parameters to set.
22091void
22093{
22094 priv_->parms_ = p;
22095 for (parameters::size_type i = 0, j = 1;
22096 i < priv_->parms_.size();
22097 ++i, ++j)
22098 {
22099 if (i == 0 && priv_->parms_[i]->get_is_artificial())
22100 // If the first parameter is artificial, then it certainly
22101 // means that this is a member function, and the first
22102 // parameter is the implicit this pointer. In that case, set
22103 // the index of that implicit parameter to zero. Otherwise,
22104 // the index of the first parameter starts at one.
22105 j = 0;
22106 priv_->parms_[i]->set_index(j);
22107 }
22108}
22109
22110/// Append a new parameter to the vector of parameters of the current
22111/// instance of @ref function_type.
22112///
22113/// @param parm the parameter to append.
22114void
22116{
22117 parm->set_index(priv_->parms_.size());
22118 priv_->parms_.push_back(parm);
22119}
22120
22121/// Test if the current instance of @ref function_type is for a
22122/// variadic function.
22123///
22124/// A variadic function is a function that takes a variable number of
22125/// arguments.
22126///
22127/// @return true iff the current instance of @ref function_type is for
22128/// a variadic function.
22129bool
22131{
22132 return (!priv_->parms_.empty()
22133 && priv_->parms_.back()->get_variadic_marker());
22134}
22135
22136/// Compare two function types.
22137///
22138/// In case these function types are actually method types, this
22139/// function avoids comparing two parameters (of the function types)
22140/// if the types of the parameters are actually the types of the
22141/// classes of the method types. This prevents infinite recursion
22142/// during the comparison of two classes that are structurally
22143/// identical.
22144///
22145/// This is a subroutine of the equality operator of function_type.
22146///
22147/// @param lhs the first function type to consider
22148///
22149/// @param rhs the second function type to consider
22150///
22151/// @param k a pointer to a bitfield set by the function to give
22152/// information about the kind of changes carried by @p lhs and @p
22153/// rhs. It is set iff @p k is non-null and the function returns
22154/// false.
22155///
22156/// Please note that setting k to a non-null value does have a
22157/// negative performance impact because even if @p l and @p r are not
22158/// equal, the function keeps up the comparison in order to determine
22159/// the different kinds of ways in which they are different.
22160///
22161///@return true if lhs == rhs, false otherwise.
22162bool
22164{
22165#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
22166
22168
22169 {
22170 // First of all, let's see if these two function types haven't
22171 // already been compared. If so, and if the result of the
22172 // comparison has been cached, let's just re-use it, rather than
22173 // comparing them all over again.
22174 bool cached_result = false;
22175 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
22176 cached_result))
22177 ABG_RETURN(cached_result);
22178 }
22179
22181
22182 bool result = true;
22183
22184 if (!l.type_base::operator==(r))
22185 {
22186 result = false;
22187 if (k)
22189 else
22190 RETURN(result);
22191 }
22192
22193 class_or_union* l_class = 0, *r_class = 0;
22194 if (const method_type* m = dynamic_cast<const method_type*>(&l))
22195 l_class = m->get_class_type().get();
22196
22197 if (const method_type* m = dynamic_cast<const method_type*>(&r))
22198 r_class = m->get_class_type().get();
22199
22200 // Compare the names of the class of the method
22201
22202 if (!!l_class != !!r_class)
22203 {
22204 result = false;
22205 if (k)
22207 else
22208 RETURN(result);
22209 }
22210 else if (l_class
22211 && (l_class->get_qualified_name()
22212 != r_class->get_qualified_name()))
22213 {
22214 result = false;
22215 if (k)
22217 else
22218 RETURN(result);
22219 }
22220
22221 // Then compare the return type; Beware if it's t's a class type
22222 // that is the same as the method class name; we can recurse for
22223 // ever in that case.
22224
22225 decl_base* l_return_type_decl =
22227 decl_base* r_return_type_decl =
22229 bool compare_result_types = true;
22230 string l_rt_name = l_return_type_decl
22231 ? l_return_type_decl->get_qualified_name()
22232 : string();
22233 string r_rt_name = r_return_type_decl
22234 ? r_return_type_decl->get_qualified_name()
22235 : string();
22236
22237 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
22238 ||
22239 (r_class && (r_class->get_qualified_name() == r_rt_name)))
22240 compare_result_types = false;
22241
22242 if (compare_result_types)
22243 {
22244 // Let's not consider typedefs when comparing return types to
22245 // avoid spurious changes.
22246 //
22247 // TODO: We should also do this for parameter types, or rather,
22248 // we should teach the equality operators in the IR, at some
22249 // point, to peel typedefs off.
22250 if (l.get_return_type() != r.get_return_type())
22251 {
22252 result = false;
22253 if (k)
22254 {
22256 r.get_return_type()))
22258 else
22259 *k |= SUBTYPE_CHANGE_KIND;
22260 }
22261 else
22262 RETURN(result);
22263 }
22264 }
22265 else
22266 if (l_rt_name != r_rt_name)
22267 {
22268 result = false;
22269 if (k)
22270 *k |= SUBTYPE_CHANGE_KIND;
22271 else
22272 RETURN(result);
22273 }
22274
22275 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
22276 for (i = l.get_first_parm(), j = r.get_first_parm();
22277 i != l.get_parameters().end() && j != r.get_parameters().end();
22278 ++i, ++j)
22279 {
22280 if (**i != **j)
22281 {
22282 result = false;
22283 if (k)
22284 {
22285 if (!types_have_similar_structure((*i)->get_type(),
22286 (*j)->get_type()))
22288 else
22289 *k |= SUBTYPE_CHANGE_KIND;
22290 }
22291 else
22292 RETURN(result);
22293 }
22294 }
22295
22296 if ((i != l.get_parameters().end()
22297 || j != r.get_parameters().end()))
22298 {
22299 result = false;
22300 if (k)
22302 else
22303 RETURN(result);
22304 }
22305
22306 RETURN(result);
22307#undef RETURN
22308}
22309
22310/// Get the first parameter of the function.
22311///
22312/// If the function is a non-static member function, the parameter
22313/// returned is the first one following the implicit 'this' parameter.
22314///
22315/// @return the first non implicit parameter of the function.
22316function_type::parameters::const_iterator
22318{
22319 if (get_parameters().empty())
22320 return get_parameters().end();
22321
22322 bool is_method = dynamic_cast<const method_type*>(this);
22323
22324 parameters::const_iterator i = get_parameters().begin();
22325
22326 if (is_method && (*i)->get_is_artificial())
22327 ++i;
22328
22329 return i;
22330}
22331
22332/// Get the first parameter of the function.
22333///
22334/// Note that if the function is a non-static member function, the
22335/// parameter returned is the implicit 'this' parameter.
22336///
22337/// @return the first parameter of the function.
22338function_type::parameters::const_iterator
22340{return get_parameters().begin();}
22341
22342/// Get the name of the current @ref function_type.
22343///
22344/// The name is retrieved from a cache. If the cache is empty, this
22345/// function computes the name of the type, stores it in the cache and
22346/// returns it. Subsequent invocation of the function are going to
22347/// just hit the cache.
22348///
22349/// Note that if the type is *NOT* canonicalized then function type
22350/// name is never cached.
22351///
22352/// @param internal if true then it means the function type name is
22353/// going to be used for purposes that are internal to libabigail
22354/// itself. If you don't know what this is then you probably should
22355/// set this parameter to 'false'.
22356///
22357/// @return the name of the function type.
22358const interned_string&
22360{
22361 if (internal)
22362 {
22364 {
22365 if (priv_->internal_cached_name_.empty())
22366 priv_->internal_cached_name_ =
22367 get_function_type_name(this, /*internal=*/true);
22368 return priv_->internal_cached_name_;
22369 }
22370 else
22371 {
22372 priv_->temp_internal_cached_name_ =
22373 get_function_type_name(this, /*internal=*/true);
22374 return priv_->temp_internal_cached_name_;
22375 }
22376 }
22377 else
22378 {
22380 {
22381 if (priv_->cached_name_.empty())
22382 priv_->cached_name_ =
22383 get_function_type_name(this, /*internal=*/false);
22384 return priv_->cached_name_;
22385 }
22386 else
22387 {
22388 priv_->cached_name_ =
22389 get_function_type_name(this, /*internal=*/false);
22390 return priv_->cached_name_;
22391 }
22392 }
22393}
22394
22395/// Equality operator for function_type.
22396///
22397/// @param o the other function_type to compare against.
22398///
22399/// @return true iff the two function_type are equal.
22400bool
22402{
22403 const function_type* o = dynamic_cast<const function_type*>(&other);
22404 if (!o)
22405 return false;
22406 return try_canonical_compare(this, o);
22407}
22408
22409/// Return a copy of the pretty representation of the current @ref
22410/// function_type.
22411///
22412/// @param internal set to true if the call is intended to get a
22413/// representation of the decl (or type) for the purpose of canonical
22414/// type comparison. This is mainly used in the function
22415/// type_base::get_canonical_type_for().
22416///
22417/// In other words if the argument for this parameter is true then the
22418/// call is meant for internal use (for technical use inside the
22419/// library itself), false otherwise. If you don't know what this is
22420/// for, then set it to false.
22421///
22422/// @return a copy of the pretty representation of the current @ref
22423/// function_type.
22424string
22426 bool /*qualified_name*/) const
22427{return ir::get_pretty_representation(this, internal);}
22428
22429/// Traverses an instance of @ref function_type, visiting all the
22430/// sub-types and decls that it might contain.
22431///
22432/// @param v the visitor that is used to visit every IR sub-node of
22433/// the current node.
22434///
22435/// @return true if either
22436/// - all the children nodes of the current IR node were traversed
22437/// and the calling code should keep going with the traversing.
22438/// - or the current IR node is already being traversed.
22439/// Otherwise, returning false means that the calling code should not
22440/// keep traversing the tree.
22441bool
22443{
22444 // TODO: should we allow the walker to avoid visiting function type
22445 // twice? I think that if we do, then ir_node_visitor needs an
22446 // option to specifically disallow this feature for function types.
22447
22448 if (visiting())
22449 return true;
22450
22451 if (v.visit_begin(this))
22452 {
22453 visiting(true);
22454 bool keep_going = true;
22455
22456 if (type_base_sptr t = get_return_type())
22457 {
22458 if (!t->traverse(v))
22459 keep_going = false;
22460 }
22461
22462 if (keep_going)
22463 for (parameters::const_iterator i = get_parameters().begin();
22464 i != get_parameters().end();
22465 ++i)
22466 if (type_base_sptr parm_type = (*i)->get_type())
22467 if (!parm_type->traverse(v))
22468 break;
22469
22470 visiting(false);
22471 }
22472 return v.visit_end(this);
22473}
22474
22475function_type::~function_type()
22476{}
22477// </function_type>
22478
22479// <method_type>
22480
22481struct method_type::priv
22482{
22483 class_or_union_wptr class_type_;
22484 bool is_const;
22485
22486 priv()
22487 : is_const()
22488 {}
22489}; // end struct method_type::priv
22490
22491/// Constructor for instances of method_type.
22492///
22493/// Instances of method_decl must be of type method_type.
22494///
22495/// @param return_type the type of the return value of the method.
22496///
22497/// @param class_type the base type of the method type. That is, the
22498/// type of the class the method belongs to.
22499///
22500/// @param p the vector of the parameters of the method.
22501///
22502/// @param is_const whether this method type is for a const method.
22503/// Note that const-ness is a property of the method *type* and of the
22504/// relationship between a method *declaration* and its scope.
22505///
22506/// @param size_in_bits the size of an instance of method_type,
22507/// expressed in bits.
22508///
22509/// @param alignment_in_bits the alignment of an instance of
22510/// method_type, expressed in bits.
22511method_type::method_type (type_base_sptr return_type,
22512 class_or_union_sptr class_type,
22513 const std::vector<function_decl::parameter_sptr>& p,
22514 bool is_const,
22515 size_t size_in_bits,
22516 size_t alignment_in_bits)
22517 : type_or_decl_base(class_type->get_environment(),
22518 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22519 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22520 function_type(return_type, p, size_in_bits, alignment_in_bits),
22521 priv_(new priv)
22522{
22524 set_class_type(class_type);
22525 set_is_const(is_const);
22526}
22527
22528/// Constructor of instances of method_type.
22529///
22530///Instances of method_decl must be of type method_type.
22531///
22532/// @param return_type the type of the return value of the method.
22533///
22534/// @param class_type the type of the class the method belongs to.
22535/// The actual (dynamic) type of class_type must be a pointer
22536/// class_type. We are setting it to pointer to type_base here to
22537/// help client code that is compiled without rtti and thus cannot
22538/// perform dynamic casts.
22539///
22540/// @param p the vector of the parameters of the method type.
22541///
22542/// @param is_const whether this method type is for a const method.
22543/// Note that const-ness is a property of the method *type* and of the
22544/// relationship between a method *declaration* and its scope.
22545///
22546/// @param size_in_bits the size of an instance of method_type,
22547/// expressed in bits.
22548///
22549/// @param alignment_in_bits the alignment of an instance of
22550/// method_type, expressed in bits.
22551method_type::method_type(type_base_sptr return_type,
22552 type_base_sptr class_type,
22553 const std::vector<function_decl::parameter_sptr>& p,
22554 bool is_const,
22555 size_t size_in_bits,
22556 size_t alignment_in_bits)
22557 : type_or_decl_base(class_type->get_environment(),
22558 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22559 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22560 function_type(return_type, p, size_in_bits, alignment_in_bits),
22561 priv_(new priv)
22562{
22564 set_class_type(is_class_type(class_type));
22565 set_is_const(is_const);
22566}
22567
22568/// Constructor of the qualified_type_def
22569///
22570/// @param env the environment we are operating from.
22571///
22572/// @param size_in_bits the size of the type, expressed in bits.
22573///
22574/// @param alignment_in_bits the alignment of the type, expressed in bits
22575method_type::method_type(const environment& env,
22576 size_t size_in_bits,
22577 size_t alignment_in_bits)
22578 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22579 type_base(env, size_in_bits, alignment_in_bits),
22580 function_type(env, size_in_bits, alignment_in_bits),
22581 priv_(new priv)
22582{
22584}
22585
22586/// Constructor of instances of method_type.
22587///
22588/// When constructed with this constructor, and instane of method_type
22589/// must set a return type using method_type::set_return_type
22590///
22591/// @param class_typ the base type of the method type. That is, the
22592/// type of the class (or union) the method belongs to.
22593///
22594/// @param size_in_bits the size of an instance of method_type,
22595/// expressed in bits.
22596///
22597/// @param alignment_in_bits the alignment of an instance of
22598/// method_type, expressed in bits.
22599method_type::method_type(class_or_union_sptr class_type,
22600 bool is_const,
22601 size_t size_in_bits,
22602 size_t alignment_in_bits)
22603 : type_or_decl_base(class_type->get_environment(),
22604 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22605 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
22606 function_type(class_type->get_environment(),
22607 size_in_bits,
22608 alignment_in_bits),
22609 priv_(new priv)
22610{
22612 set_class_type(class_type);
22613 set_is_const(is_const);
22614}
22615
22616/// Return the hash value of the current IR node.
22617///
22618/// Note that upon the first invocation, this member functions
22619/// computes the hash value and returns it. Subsequent invocations
22620/// just return the hash value that was previously calculated.
22621///
22622/// @return the hash value of the current IR node.
22623hash_t
22625{
22627 return h;
22628}
22629
22630/// Get the class type this method belongs to.
22631///
22632/// @return the class type.
22633class_or_union_sptr
22635{return class_or_union_sptr(priv_->class_type_);}
22636
22637/// Sets the class type of the current instance of method_type.
22638///
22639/// The class type is the type of the class the method belongs to.
22640///
22641/// @param t the new class type to set.
22642void
22643method_type::set_class_type(const class_or_union_sptr& t)
22644{
22645 if (!t)
22646 return;
22647
22648 priv_->class_type_ = t;
22649}
22650
22651/// Return a copy of the pretty representation of the current @ref
22652/// method_type.
22653///
22654/// @param internal set to true if the call is intended to get a
22655/// representation of the decl (or type) for the purpose of canonical
22656/// type comparison. This is mainly used in the function
22657/// type_base::get_canonical_type_for().
22658///
22659/// In other words if the argument for this parameter is true then the
22660/// call is meant for internal use (for technical use inside the
22661/// library itself), false otherwise. If you don't know what this is
22662/// for, then set it to false.
22663///
22664/// @return a copy of the pretty representation of the current @ref
22665/// method_type.
22666string
22668 bool /*qualified_name*/) const
22669{return ir::get_pretty_representation(*this, internal);}
22670
22671/// Setter of the "is-const" property of @ref method_type.
22672///
22673/// @param the new value of the "is-const" property.
22674void
22676{priv_->is_const = f;}
22677
22678/// Getter of the "is-const" property of @ref method_type.
22679///
22680/// @return true iff the "is-const" property was set.
22681bool
22683{return priv_->is_const;}
22684
22685/// Test if the current method type is for a static method or not.
22686///
22687/// @return true iff the current method_type denotes a the type of a
22688/// static method.
22689bool
22691{
22692 // Let's see if the first parameter is artificial and is a pointer
22693 // to an instance of the same class type as the current class.
22695 if (!get_parameters().empty())
22696 first_parm = get_parameters()[0];
22697 if (!first_parm)
22698 return true;
22699 if (!first_parm->get_is_artificial())
22700 return true;
22701
22702 type_base_sptr this_ptr_type = first_parm->get_type();
22703 // Sometimes, the type of the "this" pointer is "const class_type*
22704 // const". Meaning that the "this pointer" itself is const
22705 // qualified. So let's get the underlying non-qualified pointer.
22706 this_ptr_type = peel_qualified_type(this_ptr_type);
22707 if (!is_pointer_type(this_ptr_type))
22708 return true;
22709
22710 type_base_sptr candidate_class_type =
22711 is_pointer_type(this_ptr_type)->get_pointed_to_type();
22712 candidate_class_type = peel_qualified_type(candidate_class_type);
22713 if (is_class_type(candidate_class_type)
22714 && get_type_name(candidate_class_type) == get_type_name(get_class_type()))
22715 // At this point, we are sure we are looking at a *non-static*
22716 // method.
22717 return false;
22718
22719 return true;
22720}
22721
22722/// The destructor of method_type
22725
22726// </method_type>
22727
22728// <function_decl definitions>
22729
22730struct function_decl::priv
22731{
22732 bool declared_inline_;
22733 decl_base::binding binding_;
22734 function_type_wptr type_;
22735 function_type* naked_type_;
22736 elf_symbol_sptr symbol_;
22737 interned_string id_;
22738
22739 priv()
22740 : declared_inline_(false),
22741 binding_(decl_base::BINDING_GLOBAL),
22742 naked_type_()
22743 {}
22744
22745 priv(function_type_sptr t,
22746 bool declared_inline,
22748 : declared_inline_(declared_inline),
22749 binding_(binding),
22750 type_(t),
22751 naked_type_(t.get())
22752 {}
22753
22754 priv(function_type_sptr t,
22755 bool declared_inline,
22758 : declared_inline_(declared_inline),
22759 binding_(binding),
22760 type_(t),
22761 naked_type_(t.get()),
22762 symbol_(s)
22763 {}
22764}; // end sruct function_decl::priv
22765
22766/// Constructor of the @ref function_decl.
22767///
22768/// @param name the name of the function.
22769///
22770/// @param function_type the type of the function.
22771///
22772/// @param declared_inline wether the function is declared inline.
22773///
22774/// @param locus the source location of the function.
22775///
22776/// @param mangled_name the linkage name of the function.
22777///
22778/// @param vis the visibility of the function.
22779///
22780/// @param bind the binding of the function.
22783 bool declared_inline,
22784 const location& locus,
22785 const string& mangled_name,
22786 visibility vis,
22787 binding bind)
22788 : type_or_decl_base(function_type->get_environment(),
22789 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22790 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
22791 priv_(new priv(function_type, declared_inline, bind))
22792{
22794}
22795
22796/// Constructor of the function_decl type.
22797///
22798/// This flavour of constructor is for when the pointer to the
22799/// instance of function_type that the client code has is presented as
22800/// a pointer to type_base. In that case, this constructor saves the
22801/// client code from doing a dynamic_cast to get the function_type
22802/// pointer.
22803///
22804/// @param name the name of the function declaration.
22805///
22806/// @param fn_type the type of the function declaration. The dynamic
22807/// type of this parameter should be 'pointer to function_type'
22808///
22809/// @param declared_inline whether this function was declared inline
22810///
22811/// @param locus the source location of the function declaration.
22812///
22813/// @param linkage_name the mangled name of the function declaration.
22814///
22815/// @param vis the visibility of the function declaration.
22816///
22817/// @param bind the kind of the binding of the function
22818/// declaration.
22820 type_base_sptr fn_type,
22821 bool declared_inline,
22822 const location& locus,
22823 const string& linkage_name,
22824 visibility vis,
22825 binding bind)
22826 : type_or_decl_base(fn_type->get_environment(),
22827 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22828 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
22829 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
22830 declared_inline,
22831 bind))
22832{
22834}
22835
22836/// Get the pretty representation of the current instance of @ref function_decl.
22837///
22838/// @param internal set to true if the call is intended to get a
22839/// representation of the decl (or type) for the purpose of canonical
22840/// type comparison. This is mainly used in the function
22841/// type_base::get_canonical_type_for().
22842///
22843/// In other words if the argument for this parameter is true then the
22844/// call is meant for internal use (for technical use inside the
22845/// library itself), false otherwise. If you don't know what this is
22846/// for, then set it to false.
22847///
22848/// @return the pretty representation for a function.
22849string
22851 bool qualified_name) const
22852{
22853 const method_decl* mem_fn =
22854 dynamic_cast<const method_decl*>(this);
22855
22856 string fn_prefix = mem_fn ? "method ": "function ";
22857 string result;
22858
22859 if (mem_fn
22860 && is_member_function(mem_fn)
22862 fn_prefix += "virtual ";
22863
22864 decl_base_sptr return_type;
22865 if ((mem_fn
22866 && is_member_function(mem_fn)
22867 && (get_member_function_is_dtor(*mem_fn)
22868 || get_member_function_is_ctor(*mem_fn))))
22869 /*cdtors do not have return types. */;
22870 else
22871 return_type = mem_fn
22872 ? get_type_declaration(mem_fn->get_type()->get_return_type())
22874
22875 result = get_pretty_representation_of_declarator(internal);
22876 if (return_type)
22877 {
22878 if (is_npaf_type(is_type(return_type))
22879 || !(is_pointer_to_function_type(is_type(return_type))
22880 || is_pointer_to_array_type(is_type(return_type))))
22881 result = get_type_name(is_type(return_type).get(), qualified_name,
22882 internal) + " " + result;
22883 else if (pointer_type_def_sptr p =
22885 result = add_outer_pointer_to_fn_type_expr(p, result,
22886 /*qualified=*/true,
22887 internal);
22888 else if(pointer_type_def_sptr p =
22889 is_pointer_to_array_type(is_type(return_type)))
22890 result = add_outer_pointer_to_array_type_expr(p, result,
22891 qualified_name,
22892 internal);
22893 else
22895 }
22896
22897 return fn_prefix + result;
22898}
22899
22900/// Compute and return the pretty representation for the part of the
22901/// function declaration that starts at the declarator. That is, the
22902/// return type and the other specifiers of the beginning of the
22903/// function's declaration ar omitted.
22904///
22905/// @param internal set to true if the call is intended to get a
22906/// representation of the decl (or type) for the purpose of canonical
22907/// type comparison. This is mainly used in the function
22908/// type_base::get_canonical_type_for().
22909///
22910/// In other words if the argument for this parameter is true then the
22911/// call is meant for internal use (for technical use inside the
22912/// library itself), false otherwise. If you don't know what this is
22913/// for, then set it to false.
22914///
22915/// @return the pretty representation for the part of the function
22916/// declaration that starts at the declarator.
22917string
22919{
22920 const method_decl* mem_fn =
22921 dynamic_cast<const method_decl*>(this);
22922
22923 string result;
22924
22925 if (mem_fn)
22926 {
22927 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
22928 + "::" + mem_fn->get_name();
22929 }
22930 else
22931 result += get_qualified_name();
22932
22933 std::ostringstream fn_parms;
22934 stream_pretty_representation_of_fn_parms(*get_type(),
22935 fn_parms,
22936 /*qualified=*/true,
22937 internal);
22938 result += fn_parms.str();
22939
22940 if (mem_fn
22941 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
22942 || is_method_type(mem_fn->get_type())->get_is_const()))
22943 result += " const";
22944
22945 return result;
22946}
22947
22948/// Getter for the first non-implicit parameter of a function decl.
22949///
22950/// If the function is a non-static member function, the parameter
22951/// returned is the first one following the implicit 'this' parameter.
22952///
22953/// @return the first non implicit parm.
22954function_decl::parameters::const_iterator
22956{
22957 if (get_parameters().empty())
22958 return get_parameters().end();
22959
22960 bool is_method = dynamic_cast<const method_decl*>(this);
22961
22962 parameters::const_iterator i = get_parameters().begin();
22963 if (is_method)
22964 ++i;
22965
22966 return i;
22967}
22968
22969/// Return the type of the current instance of @ref function_decl.
22970///
22971/// It's either a function_type or method_type.
22972/// @return the type of the current instance of @ref function_decl.
22973const shared_ptr<function_type>
22975{return priv_->type_.lock();}
22976
22977/// Fast getter of the type of the current instance of @ref function_decl.
22978///
22979/// Note that this function returns the underlying pointer managed by
22980/// the smart pointer returned by function_decl::get_type(). It's
22981/// faster than function_decl::get_type(). This getter is to be used
22982/// in code paths that are proven to be performance hot spots;
22983/// especially (for instance) when comparing function types. Those
22984/// are compared extremely frequently when libabigail is used to
22985/// handle huge binaries with a lot of functions.
22986///
22987/// @return the type of the current instance of @ref function_decl.
22988const function_type*
22990{return priv_->naked_type_;}
22991
22992void
22993function_decl::set_type(const function_type_sptr& fn_type)
22994{
22995 priv_->type_ = fn_type;
22996 priv_->naked_type_ = fn_type.get();
22997}
22998
22999/// This sets the underlying ELF symbol for the current function decl.
23000///
23001/// And underlyin$g ELF symbol for the current function decl might
23002/// exist only if the corpus that this function decl originates from
23003/// was constructed from an ELF binary file.
23004///
23005/// Note that comparing two function decls that have underlying ELF
23006/// symbols involves comparing their underlying elf symbols. The decl
23007/// name for the function thus becomes irrelevant in the comparison.
23008///
23009/// @param sym the new ELF symbol for this function decl.
23010void
23012{
23013 priv_->symbol_ = sym;
23014 // The function id cache that depends on the symbol must be
23015 // invalidated because the symbol changed.
23016 priv_->id_ = get_environment().intern("");
23017}
23018
23019/// Gets the the underlying ELF symbol for the current variable,
23020/// that was set using function_decl::set_symbol(). Please read the
23021/// documentation for that member function for more information about
23022/// "underlying ELF symbols".
23023///
23024/// @return sym the underlying ELF symbol for this function decl, if
23025/// one exists.
23026const elf_symbol_sptr&
23028{return priv_->symbol_;}
23029
23030/// Test if the function was declared inline.
23031///
23032/// @return true iff the function was declared inline.
23033bool
23035{return priv_->declared_inline_;}
23036
23037/// Set the property of the function being declared inline.
23038///
23039/// @param value true iff the function was declared inline.
23040void
23042{priv_->declared_inline_ = value;}
23043
23045function_decl::get_binding() const
23046{return priv_->binding_;}
23047
23048/// @return the return type of the current instance of function_decl.
23049const shared_ptr<type_base>
23051{return get_type()->get_return_type();}
23052
23053/// @return the parameters of the function.
23054const std::vector<shared_ptr<function_decl::parameter> >&
23056{return get_type()->get_parameters();}
23057
23058/// Append a parameter to the type of this function.
23059///
23060/// @param parm the parameter to append.
23061void
23062function_decl::append_parameter(shared_ptr<parameter> parm)
23063{get_type()->append_parameter(parm);}
23064
23065/// Append a vector of parameters to the type of this function.
23066///
23067/// @param parms the vector of parameters to append.
23068void
23069function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
23070{
23071 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
23072 i != parms.end();
23073 ++i)
23074 get_type()->append_parameter(*i);
23075}
23076
23077/// Create a new instance of function_decl that is a clone of the
23078/// current one.
23079///
23080/// @return the new clone.
23083{
23085 if (is_member_function(*this))
23086 {
23087 method_decl_sptr
23088 m(new method_decl(get_name(),
23089 get_type(),
23091 get_location(),
23094 get_binding()));
23096 ABG_ASSERT(scope);
23100 get_member_is_static(*this),
23104 f = m;
23105 }
23106 else
23107 {
23108 f.reset(new function_decl(get_name(),
23109 get_type(),
23111 get_location(),
23114 get_binding()));
23116 }
23117 f->set_symbol(get_symbol());
23118
23119 return f;
23120}
23121
23122/// Compares two instances of @ref function_decl.
23123///
23124/// If the two intances are different, set a bitfield to give some
23125/// insight about the kind of differences there are.
23126///
23127/// @param l the first artifact of the comparison.
23128///
23129/// @param r the second artifact of the comparison.
23130///
23131/// @param k a pointer to a bitfield that gives information about the
23132/// kind of changes there are between @p l and @p r. This one is set
23133/// iff @p k is non-null and the function returns false.
23134///
23135/// Please note that setting k to a non-null value does have a
23136/// negative performance impact because even if @p l and @p r are not
23137/// equal, the function keeps up the comparison in order to determine
23138/// the different kinds of ways in which they are different.
23139///
23140/// @return true if @p l equals @p r, false otherwise.
23141bool
23143{
23144 bool result = true;
23145
23146 // Compare function types
23147 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
23148 if (t0 == t1 || *t0 == *t1)
23149 ; // the types are equal, let's move on to compare the other
23150 // properties of the functions.
23151 else
23152 {
23153 result = false;
23154 if (k)
23155 {
23156 if (!types_have_similar_structure(t0, t1))
23158 else
23159 *k |= SUBTYPE_CHANGE_KIND;
23160 }
23161 else
23163 }
23164
23165 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
23166 if (!!s0 != !!s1)
23167 {
23168 result = false;
23169 if (k)
23171 else
23173 }
23174 else if (s0 && s0 != s1)
23175 {
23176 if (!elf_symbols_alias(s0, s1))
23177 {
23178 result = false;
23179 if (k)
23181 else
23183 }
23184 }
23185 bool symbols_are_equal = (s0 && s1 && result);
23186
23187 if (symbols_are_equal)
23188 {
23189 // The functions have underlying elf symbols that are equal,
23190 // so now, let's compare the decl_base part of the functions
23191 // w/o considering their decl names.
23192 interned_string n1 = l.get_name(), n2 = r.get_name();
23194 const_cast<function_decl&>(l).set_name("");
23195 const_cast<function_decl&>(l).set_linkage_name("");
23196 const_cast<function_decl&>(r).set_name("");
23197 const_cast<function_decl&>(r).set_linkage_name("");
23198
23199 bool decl_bases_different = !l.decl_base::operator==(r);
23200
23201 const_cast<function_decl&>(l).set_name(n1);
23202 const_cast<function_decl&>(l).set_linkage_name(ln1);
23203 const_cast<function_decl&>(r).set_name(n2);
23204 const_cast<function_decl&>(r).set_linkage_name(ln2);
23205
23206 if (decl_bases_different)
23207 {
23208 result = false;
23209 if (k)
23211 else
23213 }
23214 }
23215 else
23216 if (!l.decl_base::operator==(r))
23217 {
23218 result = false;
23219 if (k)
23221 else
23223 }
23224
23225 // Compare the remaining properties. Note that we don't take into
23226 // account the fact that the function was declared inline or not as
23227 // that doesn't have any impact on the final ABI.
23228 if (l.get_binding() != r.get_binding())
23229 {
23230 result = false;
23231 if (k)
23233 else
23235 }
23236
23238 {
23239 result = false;
23240 if (k)
23242 else
23244 }
23245
23247 {
23260 {
23261 result = false;
23262 if (k)
23264 else
23266 }
23267 }
23268
23269 ABG_RETURN(result);
23270}
23271
23272/// Comparison operator for @ref function_decl.
23273///
23274/// @param other the other instance of @ref function_decl to compare
23275/// against.
23276///
23277/// @return true iff the current instance of @ref function_decl equals
23278/// @p other.
23279bool
23281{
23282 const function_decl* o = dynamic_cast<const function_decl*>(&other);
23283 if (!o)
23284 return false;
23285 return equals(*this, *o, 0);
23286}
23287
23288/// Return true iff the function takes a variable number of
23289/// parameters.
23290///
23291/// @return true if the function taks a variable number
23292/// of parameters.
23293bool
23295{
23296 return (!get_parameters().empty()
23297 && get_parameters().back()->get_variadic_marker());
23298}
23299
23300/// Return an ID that tries to uniquely identify the function inside a
23301/// program or a library.
23302///
23303/// So if the function has an underlying elf symbol, the ID is the
23304/// concatenation of the symbol name and its version. Otherwise, the
23305/// ID is the linkage name if its non-null. Otherwise, it's the
23306/// pretty representation of the function.
23307///
23308/// @return the ID.
23311{
23312 if (priv_->id_.empty())
23313 {
23314 const environment& env = get_type()->get_environment();
23315 if (elf_symbol_sptr s = get_symbol())
23316 {
23317 string virtual_member_suffix;
23318 if (is_member_function(this))
23319 {
23320 method_decl* m = is_method_decl(this);
23321 ABG_ASSERT(m);
23323 {
23325 (m->get_type()->get_class_type(),
23326 /*look_through_decl_only=*/true))
23327 virtual_member_suffix += "/o";
23328 }
23329 }
23330 if (s->has_aliases())
23331 // The symbol has several aliases, so let's use a scheme
23332 // that allows all aliased functions to have different
23333 // IDs.
23334 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
23335 else
23336 // Let's use the full symbol name with its version as ID.
23337 priv_->id_ = env.intern(s->get_id_string());
23338
23339 if (!virtual_member_suffix.empty())
23340 priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
23341 }
23342 else if (!get_linkage_name().empty())
23343 priv_->id_= env.intern(get_linkage_name());
23344 else
23345 priv_->id_ = env.intern(get_pretty_representation());
23346 }
23347 return priv_->id_;
23348}
23349
23350/// Test if two function declarations are aliases.
23351///
23352/// Two functions declarations are aliases if their symbols are
23353/// aliases, in the ELF sense.
23354///
23355/// @param f1 the first function to consider.
23356///
23357/// @param f2 the second function to consider.
23358///
23359/// @return true iff @p f1 is an alias of @p f2
23360bool
23362{
23363 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
23364
23365 if (!s1 || !s2)
23366 return false;
23367
23368 return elf_symbols_alias(s1, s2);
23369}
23370
23371/// This implements the ir_traversable_base::traverse pure virtual
23372/// function.
23373///
23374/// @param v the visitor used on the current instance.
23375///
23376/// @return true if the entire IR node tree got traversed, false
23377/// otherwise.
23378bool
23380{
23381 if (visiting())
23382 return true;
23383
23384 if (v.visit_begin(this))
23385 {
23386 visiting(true);
23387 if (type_base_sptr t = get_type())
23388 t->traverse(v);
23389 visiting(false);
23390 }
23391 return v.visit_end(this);
23392}
23393
23394/// Destructor of the @ref function_decl type.
23396{delete priv_;}
23397
23398/// A deep comparison operator for a shared pointer to @ref function_decl
23399///
23400/// This function compares to shared pointers to @ref function_decl by
23401/// looking at the pointed-to instances of @ref function_dec
23402/// comparing them too. If the two pointed-to objects are equal then
23403/// this function returns true.
23404///
23405/// @param l the left-hand side argument of the equality operator.
23406///
23407/// @param r the right-hand side argument of the equality operator.
23408///
23409/// @return true iff @p l equals @p r.
23410bool
23412{
23413 if (l.get() == r.get())
23414 return true;
23415 if (!!l != !!r)
23416 return false;
23417
23418 return *l == *r;
23419}
23420
23421/// A deep inequality operator for smart pointers to functions.
23422///
23423/// @param l the left-hand side argument of the inequality operator.
23424///
23425/// @pram r the right-hand side argument of the inequality operator.
23426///
23427/// @return true iff @p is not equal to @p r.
23428bool
23430{return !operator==(l, r);}
23431
23432// <function_decl definitions>
23433
23434// <function_decl::parameter definitions>
23435
23436struct function_decl::parameter::priv
23437{
23438 type_base_wptr type_;
23439 unsigned index_;
23440 bool variadic_marker_;
23441
23442 priv()
23443 : index_(),
23444 variadic_marker_()
23445 {}
23446
23447 priv(type_base_sptr type,
23448 unsigned index,
23449 bool variadic_marker)
23450 : type_(type),
23451 index_(index),
23452 variadic_marker_(variadic_marker)
23453 {}
23454};// end struct function_decl::parameter::priv
23455
23456function_decl::parameter::parameter(const type_base_sptr type,
23457 unsigned index,
23458 const string& name,
23459 const location& loc,
23460 bool is_variadic)
23461 : type_or_decl_base(type->get_environment(),
23462 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23463 decl_base(type->get_environment(), name, loc),
23464 priv_(new priv(type, index, is_variadic))
23465{
23466 runtime_type_instance(this);
23467}
23468
23469function_decl::parameter::parameter(const type_base_sptr type,
23470 unsigned index,
23471 const string& name,
23472 const location& loc,
23473 bool is_variadic,
23474 bool is_artificial)
23475 : type_or_decl_base(type->get_environment(),
23476 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23477 decl_base(type->get_environment(), name, loc),
23478 priv_(new priv(type, index, is_variadic))
23479{
23480 runtime_type_instance(this);
23481 set_is_artificial(is_artificial);
23482}
23483
23484function_decl::parameter::parameter(const type_base_sptr type,
23485 const string& name,
23486 const location& loc,
23487 bool is_variadic,
23488 bool is_artificial)
23489 : type_or_decl_base(type->get_environment(),
23490 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23491 decl_base(type->get_environment(), name, loc),
23492 priv_(new priv(type, 0, is_variadic))
23493{
23494 runtime_type_instance(this);
23495 set_is_artificial(is_artificial);
23496}
23497
23498function_decl::parameter::parameter(const type_base_sptr type,
23499 unsigned index,
23500 bool variad)
23501 : type_or_decl_base(type->get_environment(),
23502 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23503 decl_base(type->get_environment(), "", location()),
23504 priv_(new priv(type, index, variad))
23505{
23506 runtime_type_instance(this);
23507}
23508
23509function_decl::parameter::~parameter() = default;
23510
23511const type_base_sptr
23512function_decl::parameter::get_type()const
23513{return priv_->type_.lock();}
23514
23515/// @return a copy of the type name of the parameter.
23516interned_string
23518{
23519 const environment& env = get_environment();
23520
23521 type_base_sptr t = get_type();
23522 string str;
23523 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
23524 str = "...";
23525 else
23526 {
23527 ABG_ASSERT(t);
23529 }
23530 return env.intern(str);
23531}
23532
23533/// @return a copy of the pretty representation of the type of the
23534/// parameter.
23535const string
23537{
23538 type_base_sptr t = get_type();
23539 string str;
23540 if (get_variadic_marker()
23541 || get_environment().is_variadic_parameter_type(t))
23542 str = "...";
23543 else
23544 {
23545 ABG_ASSERT(t);
23547 }
23548 return str;
23549}
23550
23551/// Get a name uniquely identifying the parameter in the function.
23552///
23553///@return the unique parm name id.
23556{
23557 const environment& env = get_environment();
23558
23559
23560 std::ostringstream o;
23561 o << "parameter-" << get_index();
23562
23563 return env.intern(o.str());
23564}
23565
23566unsigned
23567function_decl::parameter::get_index() const
23568{return priv_->index_;}
23569
23570void
23571function_decl::parameter::set_index(unsigned i)
23572{priv_->index_ = i;}
23573
23574
23575bool
23576function_decl::parameter::get_variadic_marker() const
23577{return priv_->variadic_marker_;}
23578
23579/// Compares two instances of @ref function_decl::parameter.
23580///
23581/// If the two intances are different, set a bitfield to give some
23582/// insight about the kind of differences there are.
23583///
23584/// @param l the first artifact of the comparison.
23585///
23586/// @param r the second artifact of the comparison.
23587///
23588/// @param k a pointer to a bitfield that gives information about the
23589/// kind of changes there are between @p l and @p r. This one is set
23590/// iff @p k is non-null and the function returns false.
23591///
23592/// Please note that setting k to a non-null value does have a
23593/// negative performance impact because even if @p l and @p r are not
23594/// equal, the function keeps up the comparison in order to determine
23595/// the different kinds of ways in which they are different.
23596///
23597/// @return true if @p l equals @p r, false otherwise.
23598bool
23600 const function_decl::parameter& r,
23601 change_kind* k)
23602{
23603 bool result = true;
23604
23605 if ((l.get_variadic_marker() != r.get_variadic_marker())
23606 || (l.get_index() != r.get_index())
23607 || (!!l.get_type() != !!r.get_type()))
23608 {
23609 result = false;
23610 if (k)
23611 {
23612 if (l.get_index() != r.get_index())
23614 if (l.get_variadic_marker() != r.get_variadic_marker()
23615 || !!l.get_type() != !!r.get_type())
23617 }
23618 else
23620 }
23621
23622 type_base_sptr l_type = l.get_type();
23623 type_base_sptr r_type = r.get_type();
23624
23625 if (l_type != r_type)
23626 {
23627 result = false;
23628 if (k)
23629 {
23630 if (!types_have_similar_structure(l_type, r_type))
23632 else
23633 *k |= SUBTYPE_CHANGE_KIND;
23634 }
23635 else
23637 }
23638
23639 ABG_RETURN(result);
23640}
23641
23642bool
23643function_decl::parameter::operator==(const parameter& o) const
23644{return equals(*this, o, 0);}
23645
23646bool
23647function_decl::parameter::operator==(const decl_base& o) const
23648{
23649 const function_decl::parameter* p =
23650 dynamic_cast<const function_decl::parameter*>(&o);
23651 if (!p)
23652 return false;
23653 return function_decl::parameter::operator==(*p);
23654}
23655
23656/// Non-member equality operator for @ref function_decl::parameter.
23657///
23658/// @param l the left-hand side of the equality operator
23659///
23660/// @param r the right-hand side of the equality operator
23661///
23662/// @return true iff @p l and @p r equals.
23663bool
23666{
23667 if (!!l != !!r)
23668 return false;
23669 if (!l)
23670 return true;
23671 return *l == *r;
23672}
23673
23674/// Non-member inequality operator for @ref function_decl::parameter.
23675///
23676/// @param l the left-hand side of the equality operator
23677///
23678/// @param r the right-hand side of the equality operator
23679///
23680/// @return true iff @p l and @p r different.
23681bool
23685
23686/// Traverse the diff sub-tree under the current instance
23687/// function_decl.
23688///
23689/// @param v the visitor to invoke on each diff node of the sub-tree.
23690///
23691/// @return true if the traversing has to keep going on, false
23692/// otherwise.
23693bool
23695{
23696 if (visiting())
23697 return true;
23698
23699 if (v.visit_begin(this))
23700 {
23701 visiting(true);
23702 if (type_base_sptr t = get_type())
23703 t->traverse(v);
23704 visiting(false);
23705 }
23706 return v.visit_end(this);
23707}
23708
23709/// Compute the qualified name of the parameter.
23710///
23711/// @param internal set to true if the call is intended for an
23712/// internal use (for technical use inside the library itself), false
23713/// otherwise. If you don't know what this is for, then set it to
23714/// false.
23715///
23716/// @param qn the resulting qualified name.
23717void
23719 bool /*internal*/) const
23720{qualified_name = get_name();}
23721
23722/// Compute and return a copy of the pretty representation of the
23723/// current function parameter.
23724///
23725/// @param internal set to true if the call is intended to get a
23726/// representation of the decl (or type) for the purpose of canonical
23727/// type comparison. This is mainly used in the function
23728/// type_base::get_canonical_type_for().
23729///
23730/// In other words if the argument for this parameter is true then the
23731/// call is meant for internal use (for technical use inside the
23732/// library itself), false otherwise. If you don't know what this is
23733/// for, then set it to false.
23734///
23735/// @return a copy of the textual representation of the current
23736/// function parameter.
23737string
23739 bool qualified_name) const
23740{
23741 const environment& env = get_environment();
23742
23743 string type_repr;
23744 type_base_sptr t = get_type();
23745 if (!t)
23746 type_repr = "void";
23747 else if (env.is_variadic_parameter_type(t))
23748 type_repr = "...";
23749 else
23750 type_repr = ir::get_type_name(t, qualified_name, internal);
23751
23752 string result = type_repr;
23753 string parm_name = get_name_id();
23754
23755 if (!parm_name.empty())
23756 result += " " + parm_name;
23757
23758 return result;
23759}
23760
23761// </function_decl::parameter definitions>
23762
23763// <class_or_union definitions>
23764
23765/// A Constructor for instances of @ref class_or_union
23766///
23767/// @param env the environment we are operating from.
23768///
23769/// @param name the identifier of the class.
23770///
23771/// @param size_in_bits the size of an instance of @ref
23772/// class_or_union, expressed in bits
23773///
23774/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23775/// expressed in bits.
23776///
23777/// @param locus the source location of declaration point this class.
23778///
23779/// @param vis the visibility of instances of @ref class_or_union.
23780///
23781/// @param mem_types the vector of member types of this instance of
23782/// @ref class_or_union.
23783///
23784/// @param data_members the vector of data members of this instance of
23785/// @ref class_or_union.
23786///
23787/// @param member_fns the vector of member functions of this instance
23788/// of @ref class_or_union.
23789class_or_union::class_or_union(const environment& env, const string& name,
23790 size_t size_in_bits, size_t align_in_bits,
23791 const location& locus, visibility vis,
23792 member_types& mem_types,
23794 member_functions& member_fns)
23795 : type_or_decl_base(env,
23796 ABSTRACT_TYPE_BASE
23797 | ABSTRACT_DECL_BASE
23798 | ABSTRACT_SCOPE_TYPE_DECL
23799 | ABSTRACT_SCOPE_DECL),
23800 decl_base(env, name, locus, name, vis),
23801 type_base(env, size_in_bits, align_in_bits),
23802 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23803 priv_(new priv(data_members, member_fns))
23804{
23805 for (member_types::iterator i = mem_types.begin();
23806 i != mem_types.end();
23807 ++i)
23810
23811 for (data_members::iterator i = data_members.begin();
23812 i != data_members.end();
23813 ++i)
23814 if (!has_scope(*i))
23815 add_decl_to_scope(*i, this);
23816
23817 for (member_functions::iterator i = member_fns.begin();
23818 i != member_fns.end();
23819 ++i)
23820 if (!has_scope(static_pointer_cast<decl_base>(*i)))
23821 add_decl_to_scope(*i, this);
23822}
23823
23824/// A constructor for instances of @ref class_or_union.
23825///
23826/// @param env the environment we are operating from.
23827///
23828/// @param name the name of the class.
23829///
23830/// @param size_in_bits the size of an instance of @ref
23831/// class_or_union, expressed in bits
23832///
23833/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23834/// expressed in bits.
23835///
23836/// @param locus the source location of declaration point this class.
23837///
23838/// @param vis the visibility of instances of @ref class_or_union.
23839class_or_union::class_or_union(const environment& env, const string& name,
23840 size_t size_in_bits, size_t align_in_bits,
23841 const location& locus, visibility vis)
23842 : type_or_decl_base(env,
23843 ABSTRACT_TYPE_BASE
23844 | ABSTRACT_DECL_BASE
23845 | ABSTRACT_SCOPE_TYPE_DECL
23846 | ABSTRACT_SCOPE_DECL),
23847 decl_base(env, name, locus, name, vis),
23848 type_base(env, size_in_bits, align_in_bits),
23849 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23850 priv_(new priv)
23851{}
23852
23853/// Constructor of the @ref class_or_union type.
23854///
23855/// @param env the @ref environment we are operating from.
23856///
23857/// @param name the name of the @ref class_or_union.
23858///
23859/// @param is_declaration_only a boolean saying whether the instance
23860/// represents a declaration only, or not.
23861class_or_union::class_or_union(const environment& env, const string& name,
23862 bool is_declaration_only)
23863 : type_or_decl_base(env,
23864 ABSTRACT_TYPE_BASE
23865 | ABSTRACT_DECL_BASE
23866 | ABSTRACT_SCOPE_TYPE_DECL
23867 | ABSTRACT_SCOPE_DECL),
23868 decl_base(env, name, location(), name),
23869 type_base(env, 0, 0),
23870 scope_type_decl(env, name, 0, 0, location()),
23871 priv_(new priv)
23872{
23873 set_is_declaration_only(is_declaration_only);
23874}
23875
23876/// Return the hash value of the current IR node.
23877///
23878/// Note that upon the first invocation, this member functions
23879/// computes the hash value and returns it. Subsequent invocations
23880/// just return the hash value that was previously calculated.
23881///
23882/// @return the hash value of the current IR node.
23883hash_t
23885{
23886 class_or_union::hash do_hash;
23887 hash_t h = do_hash(this);
23888 return h;
23889}
23890
23891/// This implements the ir_traversable_base::traverse pure virtual
23892/// function.
23893///
23894/// @param v the visitor used on the member nodes of the translation
23895/// unit during the traversal.
23896///
23897/// @return true if the entire IR node tree got traversed, false
23898/// otherwise.
23899bool
23901{
23902 if (v.type_node_has_been_visited(this))
23903 return true;
23904
23905 if (visiting())
23906 return true;
23907
23908 if (v.visit_begin(this))
23909 {
23910 visiting(true);
23911 bool stop = false;
23912
23913 if (!stop)
23914 for (data_members::const_iterator i = get_data_members().begin();
23915 i != get_data_members().end();
23916 ++i)
23917 if (!(*i)->traverse(v))
23918 {
23919 stop = true;
23920 break;
23921 }
23922
23923 if (!stop)
23924 for (member_functions::const_iterator i= get_member_functions().begin();
23925 i != get_member_functions().end();
23926 ++i)
23927 if (!(*i)->traverse(v))
23928 {
23929 stop = true;
23930 break;
23931 }
23932
23933 if (!stop)
23934 for (member_types::const_iterator i = get_member_types().begin();
23935 i != get_member_types().end();
23936 ++i)
23937 if (!(*i)->traverse(v))
23938 {
23939 stop = true;
23940 break;
23941 }
23942
23943 if (!stop)
23944 for (member_function_templates::const_iterator i =
23946 i != get_member_function_templates().end();
23947 ++i)
23948 if (!(*i)->traverse(v))
23949 {
23950 stop = true;
23951 break;
23952 }
23953
23954 if (!stop)
23955 for (member_class_templates::const_iterator i =
23957 i != get_member_class_templates().end();
23958 ++i)
23959 if (!(*i)->traverse(v))
23960 {
23961 stop = true;
23962 break;
23963 }
23964 visiting(false);
23965 }
23966
23967 bool result = v.visit_end(this);
23969 return result;
23970}
23971
23972/// Destrcutor of the @ref class_or_union type.
23974{delete priv_;}
23975
23976/// Add a member declaration to the current instance of class_or_union.
23977/// The member declaration can be either a member type, data member,
23978/// member function, or member template.
23979///
23980/// @param d the member declaration to add.
23981decl_base_sptr
23982class_or_union::add_member_decl(const decl_base_sptr& d)
23983{return insert_member_decl(d);}
23984
23985/// Remove a given decl from the current @ref class_or_union scope.
23986///
23987/// Note that only type declarations are supported by this method for
23988/// now. Support for the other kinds of declaration is left as an
23989/// exercise for the interested reader of the code.
23990///
23991/// @param decl the declaration to remove from this @ref
23992/// class_or_union scope.
23993void
23995{
23996 type_base_sptr t = is_type(decl);
23997
23998 // For now we want to support just removing types from classes. For
23999 // other kinds of IR node, we need more work.
24000 ABG_ASSERT(t);
24001
24003}
24004
24005/// Fixup the members of the type of an anonymous data member.
24006///
24007/// Walk all data members of (the type of) a given anonymous data
24008/// member and set a particular property of the relationship between
24009/// each data member and its containing type.
24010///
24011/// That property records the fact that the data member belongs to the
24012/// anonymous data member we consider.
24013///
24014/// In the future, if there are other properties of this relationship
24015/// to set in this manner, they ought to be added here.
24016///
24017/// @param anon_dm the anonymous data member to consider.
24018void
24020{
24021 class_or_union * anon_dm_type =
24023 if (!anon_dm_type)
24024 return;
24025
24026 for (class_or_union::data_members::const_iterator it =
24027 anon_dm_type->get_non_static_data_members().begin();
24028 it != anon_dm_type->get_non_static_data_members().end();
24029 ++it)
24030 {
24031 dm_context_rel *rel =
24032 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
24033 ABG_ASSERT(rel);
24034 rel->set_anonymous_data_member(anon_dm.get());
24035 }
24036}
24037
24038/// Getter of the alignment of the @ref class_or_union type.
24039///
24040/// If this @ref class_or_union is a declaration of a definition that
24041/// is elsewhere, then the size of the definition is returned.
24042///
24043/// @return the alignment of the @ref class_or_union type.
24044size_t
24053
24054/// Setter of the alignment of the class type.
24055///
24056/// If this class is a declaration of a definition that is elsewhere,
24057/// then the new alignment is set to the definition.
24058///
24059/// @param s the new alignment.
24060void
24069
24070/// Setter of the size of the @ref class_or_union type.
24071///
24072/// If this @ref class_or_union is a declaration of a definition that
24073/// is elsewhere, then the new size is set to the definition.
24074///
24075/// @param s the new size.
24076void
24085
24086/// Getter of the size of the @ref class_or_union type.
24087///
24088/// If this @ref class_or_union is a declaration of a definition that
24089/// is elsewhere, then the size of the definition is returned.
24090///
24091/// @return the size of the @ref class_or_union type.
24092size_t
24101
24102/// Get the number of anonymous member classes contained in this
24103/// class.
24104///
24105/// @return the number of anonymous member classes contained in this
24106/// class.
24107size_t
24109{
24110 int result = 0;
24111 for (member_types::const_iterator it = get_member_types().begin();
24112 it != get_member_types().end();
24113 ++it)
24114 if (class_decl_sptr t = is_class_type(*it))
24115 if (t->get_is_anonymous())
24116 ++result;
24117
24118 return result;
24119}
24120
24121/// Get the number of anonymous member unions contained in this class.
24122///
24123/// @return the number of anonymous member unions contained in this
24124/// class.
24125size_t
24127{
24128 int result = 0;
24129 for (member_types::const_iterator it = get_member_types().begin();
24130 it != get_member_types().end();
24131 ++it)
24132 if (union_decl_sptr t = is_union_type(*it))
24133 if (t->get_is_anonymous())
24134 ++result;
24135
24136 return result;
24137}
24138
24139/// Get the number of anonymous member enums contained in this class.
24140///
24141/// @return the number of anonymous member enums contained in this
24142/// class.
24143size_t
24145{
24146 int result = 0;
24147 for (member_types::const_iterator it = get_member_types().begin();
24148 it != get_member_types().end();
24149 ++it)
24150 if (enum_type_decl_sptr t = is_enum_type(*it))
24151 if (t->get_is_anonymous())
24152 ++result;
24153
24154 return result;
24155}
24156
24157/// Add a data member to the current instance of class_or_union.
24158///
24159/// @param v a var_decl to add as a data member. A proper
24160/// class_or_union::data_member is created from @p v and added to the
24161/// class_or_union. This var_decl should not have been already added
24162/// to a scope.
24163///
24164/// @param access the access specifier for the data member.
24165///
24166/// @param is_laid_out whether the data member was laid out. That is,
24167/// if its offset has been computed. In the pattern of a class
24168/// template for instance, this would be set to false.
24169///
24170/// @param is_static whether the data memer is static.
24171///
24172/// @param offset_in_bits if @p is_laid_out is true, this is the
24173/// offset of the data member, expressed (oh, surprise) in bits.
24174void
24176 bool is_laid_out, bool is_static,
24177 size_t offset_in_bits)
24178{
24179 ABG_ASSERT(!has_scope(v));
24180
24181 priv_->data_members_.push_back(v);
24183 set_data_member_is_laid_out(v, is_laid_out);
24184 set_data_member_offset(v, offset_in_bits);
24185 set_member_access_specifier(v, access);
24186 set_member_is_static(v, is_static);
24187
24188 // Add the variable to the set of static or non-static data members,
24189 // if it's not already in there.
24190 bool is_already_in = false;
24191 if (is_static)
24192 {
24193 for (const auto& s_dm: priv_->static_data_members_)
24194 {
24195 if (s_dm == v)
24196 {
24197 is_already_in = true;
24198 break;
24199 }
24200 }
24201 if (!is_already_in)
24202 priv_->static_data_members_.push_back(v);
24203 }
24204 else
24205 {
24206 // If this is a non-static variable, add it to the set of
24207 // non-static variables, if it's not already in there.
24208 for (data_members::const_iterator i =
24209 priv_->non_static_data_members_.begin();
24210 i != priv_->non_static_data_members_.end();
24211 ++i)
24212 if (*i == v)
24213 {
24214 is_already_in = true;
24215 break;
24216 }
24217 if (!is_already_in)
24218 priv_->non_static_data_members_.push_back(v);
24219 }
24220
24221 // If v is an anonymous data member, then fixup its data members.
24222 // For now, the only thing the fixup does is to make the data
24223 // members of the anonymous data member be aware of their containing
24224 // anonymous data member. That is helpful to compute the absolute
24225 // bit offset of each of the members of the anonymous data member.
24227}
24228
24229/// Get the data members of this @ref class_or_union.
24230///
24231/// @return a vector of the data members of this @ref class_or_union.
24234{return priv_->data_members_;}
24235
24236/// Find a data member of a given name in the current @ref class_or_union.
24237///
24238/// @param name the name of the data member to find in the current
24239/// @ref class_or_union.
24240///
24241/// @return a pointer to the @ref var_decl that represents the data
24242/// member to find inside the current @ref class_or_union.
24243const var_decl_sptr
24244class_or_union::find_data_member(const string& name) const
24245{
24246 for (data_members::const_iterator i = get_data_members().begin();
24247 i != get_data_members().end();
24248 ++i)
24249 if ((*i)->get_name() == name)
24250 return *i;
24251
24252 // We haven't found a data member with the name 'name'. Let's look
24253 // closer again, this time in our anonymous data members.
24254 for (data_members::const_iterator i = get_data_members().begin();
24255 i != get_data_members().end();
24256 ++i)
24258 {
24259 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
24260 ABG_ASSERT(type);
24261 if (var_decl_sptr data_member = type->find_data_member(name))
24262 return data_member;
24263 }
24264
24265 return var_decl_sptr();
24266}
24267
24268/// Find an anonymous data member in the class.
24269///
24270/// @param v the anonymous data member to find.
24271///
24272/// @return the anonymous data member found, or nil if none was found.
24273const var_decl_sptr
24275{
24276 if (!v->get_name().empty())
24277 return var_decl_sptr();
24278
24279 for (data_members::const_iterator it = get_non_static_data_members().begin();
24280 it != get_non_static_data_members().end();
24281 ++it)
24282 {
24283 if (is_anonymous_data_member(*it))
24284 if ((*it)->get_pretty_representation(/*internal=*/false, true)
24285 == v->get_pretty_representation(/*internal=*/false, true))
24286 return *it;
24287 }
24288
24289 return var_decl_sptr();
24290}
24291
24292/// Find a given data member.
24293///
24294/// This function takes a @ref var_decl as an argument. If it has a
24295/// non-empty name, then it tries to find a data member which has the
24296/// same name as the argument.
24297///
24298/// If it has an empty name, then the @ref var_decl is considered as
24299/// an anonymous data member. In that case, this function tries to
24300/// find an anonymous data member which type equals that of the @ref
24301/// var_decl argument.
24302///
24303/// @param v this carries either the name of the data member we need
24304/// to look for, or the type of the anonymous data member we are
24305/// looking for.
24306const var_decl_sptr
24308{
24309 if (!v)
24310 return var_decl_sptr();
24311
24312 if (v->get_name().empty())
24314
24315 return find_data_member(v->get_name());
24316}
24317
24318
24319/// Get the non-static data members of this @ref class_or_union.
24320///
24321/// @return a vector of the non-static data members of this @ref
24322/// class_or_union.
24325{return priv_->non_static_data_members_;}
24326
24327/// Get the static data memebers of this @ref class_or_union.
24328///
24329/// @return a vector of the static data members of this @ref
24330/// class_or_union.
24333{return priv_->static_data_members_;}
24334
24335/// Add a member function.
24336///
24337/// @param f the new member function to add.
24338///
24339/// @param a the access specifier to use for the new member function.
24340///
24341/// @param is_static whether the new member function is static.
24342///
24343/// @param is_ctor whether the new member function is a constructor.
24344///
24345/// @param is_dtor whether the new member function is a destructor.
24346///
24347/// @param is_const whether the new member function is const.
24348void
24351 bool is_static, bool is_ctor,
24352 bool is_dtor, bool is_const)
24353{
24354 ABG_ASSERT(!has_scope(f));
24355
24357
24358 set_member_function_is_ctor(f, is_ctor);
24359 set_member_function_is_dtor(f, is_dtor);
24361 set_member_is_static(f, is_static);
24362 set_member_function_is_const(f, is_const);
24363
24364 priv_->member_functions_.push_back(f);
24365
24366 // Update the map of linkage name -> member functions. It's useful,
24367 // so that class_or_union::find_member_function() can function.
24368 if (!f->get_linkage_name().empty())
24369 priv_->mem_fns_map_[f->get_linkage_name()] = f;
24370}
24371
24372/// Get the member functions of this @ref class_or_union.
24373///
24374/// @return a vector of the member functions of this @ref
24375/// class_or_union.
24378{return priv_->member_functions_;}
24379
24380/// Find a method, using its linkage name as a key.
24381///
24382/// @param linkage_name the linkage name of the method to find.
24383///
24384/// @return the method found, or nil if none was found.
24385const method_decl*
24386class_or_union::find_member_function(const string& linkage_name) const
24387{
24388 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
24389}
24390
24391/// Find a method, using its linkage name as a key.
24392///
24393/// @param linkage_name the linkage name of the method to find.
24394///
24395/// @return the method found, or nil if none was found.
24397class_or_union::find_member_function(const string& linkage_name)
24398{
24399 string_mem_fn_sptr_map_type::const_iterator i =
24400 priv_->mem_fns_map_.find(linkage_name);
24401 if (i == priv_->mem_fns_map_.end())
24402 return 0;
24403 return i->second.get();
24404}
24405
24406/// Find a method, using its linkage name as a key.
24407///
24408/// @param linkage_name the linkage name of the method to find.
24409///
24410/// @return the method found, or nil if none was found.
24411method_decl_sptr
24413{
24414 string_mem_fn_sptr_map_type::const_iterator i =
24415 priv_->mem_fns_map_.find(linkage_name);
24416 if (i == priv_->mem_fns_map_.end())
24417 return 0;
24418 return i->second;
24419}
24420
24421/// Find a method (member function) using its signature (pretty
24422/// representation) as a key.
24423///
24424/// @param s the signature of the method.
24425///
24426/// @return the method found, or nil if none was found.
24427const method_decl*
24429{
24430 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
24431}
24432
24433/// Find a method (member function) using its signature (pretty
24434/// representation) as a key.
24435///
24436/// @param s the signature of the method.
24437///
24438/// @return the method found, or nil if none was found.
24441{
24442 string_mem_fn_ptr_map_type::const_iterator i =
24443 priv_->signature_2_mem_fn_map_.find(s);
24444 if (i == priv_->signature_2_mem_fn_map_.end())
24445 return 0;
24446 return i->second;
24447}
24448
24449/// Get the member function templates of this class.
24450///
24451/// @return a vector of the member function templates of this class.
24452const member_function_templates&
24454{return priv_->member_function_templates_;}
24455
24456/// Get the member class templates of this class.
24457///
24458/// @return a vector of the member class templates of this class.
24459const member_class_templates&
24461{return priv_->member_class_templates_;}
24462
24463/// Append a member function template to the @ref class_or_union.
24464///
24465/// @param m the member function template to append.
24466void
24467class_or_union::add_member_function_template(member_function_template_sptr m)
24468{
24469 decl_base* c = m->as_function_tdecl()->get_scope();
24470 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24471 /// error message or something like a structured error.
24472 priv_->member_function_templates_.push_back(m);
24473 if (!c)
24474 scope_decl::add_member_decl(m->as_function_tdecl());
24475}
24476
24477/// Append a member class template to the @ref class_or_union.
24478///
24479/// @param m the member function template to append.
24480void
24482{
24483 decl_base* c = m->as_class_tdecl()->get_scope();
24484 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
24485 /// error message or something like a structured error.
24486 m->set_scope(this);
24487 priv_->member_class_templates_.push_back(m);
24488 if (!c)
24489 scope_decl::add_member_decl(m->as_class_tdecl());
24490}
24491
24492///@return true iff the current instance has no member.
24493bool
24495{
24496 return (get_member_types().empty()
24497 && priv_->data_members_.empty()
24498 && priv_->member_functions_.empty()
24499 && priv_->member_function_templates_.empty()
24500 && priv_->member_class_templates_.empty());
24501}
24502
24503/// Insert a data member to this @ref class_or_union type.
24504///
24505/// @param d the data member to insert.
24506///
24507/// @return the decl @p that got inserted.
24508decl_base_sptr
24510{
24511 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
24512 {
24513 add_data_member(v, public_access,
24514 /*is_laid_out=*/false,
24515 /*is_static=*/true,
24516 /*offset_in_bits=*/0);
24517 d = v;
24518 }
24519 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24520 add_member_function(f, public_access,
24521 /*is_static=*/false,
24522 /*is_ctor=*/false,
24523 /*is_dtor=*/false,
24524 /*is_const=*/false);
24525 else if (member_function_template_sptr f =
24526 dynamic_pointer_cast<member_function_template>(d))
24528 else if (member_class_template_sptr c =
24529 dynamic_pointer_cast<member_class_template>(d))
24531 else
24533
24534 return d;
24535}
24536
24537/// Equality operator.
24538///
24539/// @param other the other @ref class_or_union to compare against.
24540///
24541/// @return true iff @p other equals the current @ref class_or_union.
24542bool
24544{
24545 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
24546 if (!op)
24547 return false;
24548
24549 // If this is a decl-only type (and thus with no canonical type),
24550 // use the canonical type of the definition, if any.
24551 const class_or_union *l = 0;
24553 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
24554 if (l == 0)
24555 l = this;
24556
24557 // Likewise for the other class.
24558 const class_or_union *r = 0;
24559 if (op->get_is_declaration_only())
24560 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
24561 if (r == 0)
24562 r = op;
24563
24564 return try_canonical_compare(l, r);
24565}
24566
24567/// Equality operator.
24568///
24569/// @param other the other @ref class_or_union to compare against.
24570///
24571/// @return true iff @p other equals the current @ref class_or_union.
24572bool
24574{
24575 const decl_base* o = dynamic_cast<const decl_base*>(&other);
24576 if (!o)
24577 return false;
24578 return *this == *o;
24579}
24580
24581/// Equality operator.
24582///
24583/// @param other the other @ref class_or_union to compare against.
24584///
24585/// @return true iff @p other equals the current @ref class_or_union.
24586bool
24588{
24589 const decl_base& o = other;
24591}
24592
24593/// Compares two instances of @ref class_or_union.
24594///
24595/// If the two intances are different, set a bitfield to give some
24596/// insight about the kind of differences there are.
24597///
24598/// @param l the first artifact of the comparison.
24599///
24600/// @param r the second artifact of the comparison.
24601///
24602/// @param k a pointer to a bitfield that gives information about the
24603/// kind of changes there are between @p l and @p r. This one is set
24604/// iff it's non-null and if the function returns false.
24605///
24606/// Please note that setting k to a non-null value does have a
24607/// negative performance impact because even if @p l and @p r are not
24608/// equal, the function keeps up the comparison in order to determine
24609/// the different kinds of ways in which they are different.
24610///
24611/// @return true if @p l equals @p r, false otherwise.
24612bool
24614{
24615 // if one of the classes is declaration-only, look through it to
24616 // get its definition.
24617 bool l_is_decl_only = l.get_is_declaration_only();
24618 bool r_is_decl_only = r.get_is_declaration_only();
24619 if (l_is_decl_only || r_is_decl_only)
24620 {
24621 const class_or_union* def1 = l_is_decl_only
24623 : &l;
24624
24625 const class_or_union* def2 = r_is_decl_only
24627 : &r;
24628
24629 if (!def1 || !def2)
24630 {
24631 if (!l.get_is_anonymous()
24632 && !r.get_is_anonymous()
24633 && l_is_decl_only && r_is_decl_only
24635 // The two decl-only classes differ from their size. A
24636 // true decl-only class should not have a size property to
24637 // begin with. This comes from a DWARF oddity and can
24638 // results in a false positive, so let's not consider that
24639 // change.
24640 return true;
24641
24645 {
24646 const interned_string& q1 = l.get_scoped_name();
24647 const interned_string& q2 = r.get_scoped_name();
24648 if (q1 == q2)
24649 // Not using RETURN(true) here, because that causes
24650 // performance issues. We don't need to do
24651 // l.priv_->unmark_as_being_compared({l,r}) here because
24652 // we haven't marked l or r as being compared yet, and
24653 // doing so has a peformance cost that shows up on
24654 // performance profiles for *big* libraries.
24655 return true;
24656 else
24657 {
24658 if (k)
24660 // Not using RETURN(true) here, because that causes
24661 // performance issues. We don't need to do
24662 // l.priv_->unmark_as_being_compared({l,r}) here because
24663 // we haven't marked l or r as being compared yet, and
24664 // doing so has a peformance cost that shows up on
24665 // performance profiles for *big* libraries.
24667 }
24668 }
24669 else // A decl-only class is considered different from a
24670 // class definition of the same name.
24671 {
24672 if (!!def1 != !!def2)
24673 {
24674 if (k)
24677 }
24678
24679 // both definitions are empty
24680 if (!(l.decl_base::operator==(r)
24681 && l.type_base::operator==(r)))
24682 {
24683 if (k)
24686 }
24687
24688 return true;
24689 }
24690 }
24691
24692 bool val = *def1 == *def2;
24693 if (!val)
24694 if (k)
24696 ABG_RETURN(val);
24697 }
24698
24699 // No need to go further if the classes have different names or
24700 // different size / alignment.
24701 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
24702 {
24703 if (k)
24706 }
24707
24708 if (types_defined_same_linux_kernel_corpus_public(l, r))
24709 return true;
24710
24711 //TODO: Maybe remove this (cycle detection and canonical type
24712 //propagation handling) from here and have it only in the equal
24713 //overload for class_decl and union_decl because this one ( the
24714 //equal overload for class_or_union) is just a sub-routine of these
24715 //two above.
24716#define RETURN(value) \
24717 return return_comparison_result(l, r, value);
24718
24720
24722
24723 bool result = true;
24724
24725 //compare data_members
24726 {
24727 if (l.get_non_static_data_members().size()
24728 != r.get_non_static_data_members().size())
24729 {
24730 result = false;
24731 if (k)
24733 else
24734 RETURN(result);
24735 }
24736
24737 for (class_or_union::data_members::const_iterator
24738 d0 = l.get_non_static_data_members().begin(),
24739 d1 = r.get_non_static_data_members().begin();
24740 (d0 != l.get_non_static_data_members().end()
24741 && d1 != r.get_non_static_data_members().end());
24742 ++d0, ++d1)
24743 if (**d0 != **d1)
24744 {
24745 result = false;
24746 if (k)
24747 {
24748 // Report any representation change as being local.
24749 if (!types_have_similar_structure((*d0)->get_type(),
24750 (*d1)->get_type())
24751 || (*d0)->get_type() == (*d1)->get_type())
24753 else
24754 *k |= SUBTYPE_CHANGE_KIND;
24755 }
24756 else
24757 RETURN(result);
24758 }
24759 }
24760
24761 // Do not compare member functions. DWARF does not necessarily
24762 // all the member functions, be they virtual or not, in all
24763 // translation units. So we cannot have a clear view of them, per
24764 // class
24765
24766 // compare member function templates
24767 {
24768 if (l.get_member_function_templates().size()
24769 != r.get_member_function_templates().size())
24770 {
24771 result = false;
24772 if (k)
24774 else
24775 RETURN(result);
24776 }
24777
24778 for (member_function_templates::const_iterator
24779 fn_tmpl_it0 = l.get_member_function_templates().begin(),
24780 fn_tmpl_it1 = r.get_member_function_templates().begin();
24781 fn_tmpl_it0 != l.get_member_function_templates().end()
24782 && fn_tmpl_it1 != r.get_member_function_templates().end();
24783 ++fn_tmpl_it0, ++fn_tmpl_it1)
24784 if (**fn_tmpl_it0 != **fn_tmpl_it1)
24785 {
24786 result = false;
24787 if (k)
24788 {
24790 break;
24791 }
24792 else
24793 RETURN(result);
24794 }
24795 }
24796
24797 // compare member class templates
24798 {
24799 if (l.get_member_class_templates().size()
24800 != r.get_member_class_templates().size())
24801 {
24802 result = false;
24803 if (k)
24805 else
24806 RETURN(result);
24807 }
24808
24809 for (member_class_templates::const_iterator
24810 cl_tmpl_it0 = l.get_member_class_templates().begin(),
24811 cl_tmpl_it1 = r.get_member_class_templates().begin();
24812 cl_tmpl_it0 != l.get_member_class_templates().end()
24813 && cl_tmpl_it1 != r.get_member_class_templates().end();
24814 ++cl_tmpl_it0, ++cl_tmpl_it1)
24815 if (**cl_tmpl_it0 != **cl_tmpl_it1)
24816 {
24817 result = false;
24818 if (k)
24819 {
24821 break;
24822 }
24823 else
24824 RETURN(result);
24825 }
24826 }
24827
24828 RETURN(result);
24829#undef RETURN
24830}
24831
24832
24833/// Copy a method of a @ref class_or_union into a new @ref
24834/// class_or_union.
24835///
24836/// @param t the @ref class_or_union into which the method is to be copied.
24837///
24838/// @param method the method to copy into @p t.
24839///
24840/// @return the resulting newly copied method.
24841method_decl_sptr
24842copy_member_function(class_or_union_sptr t,
24843 const method_decl_sptr& method)
24844{return copy_member_function(t, method.get());}
24845
24846
24847/// Copy a method of a @ref class_or_union into a new @ref
24848/// class_or_union.
24849///
24850/// @param t the @ref class_or_union into which the method is to be copied.
24851///
24852/// @param method the method to copy into @p t.
24853///
24854/// @return the resulting newly copied method.
24855method_decl_sptr
24856copy_member_function(class_or_union_sptr t, const method_decl* method)
24857{
24858 ABG_ASSERT(t);
24859 ABG_ASSERT(method);
24860
24861 method_type_sptr old_type = method->get_type();
24862 ABG_ASSERT(old_type);
24863 method_type_sptr new_type(new method_type(old_type->get_return_type(),
24864 t,
24865 old_type->get_parameters(),
24866 old_type->get_is_const(),
24867 old_type->get_size_in_bits(),
24868 old_type->get_alignment_in_bits()));
24869 t->get_translation_unit()->bind_function_type_life_time(new_type);
24870
24871 method_decl_sptr
24872 new_method(new method_decl(method->get_name(),
24873 new_type,
24874 method->is_declared_inline(),
24875 method->get_location(),
24876 method->get_linkage_name(),
24877 method->get_visibility(),
24878 method->get_binding()));
24879 new_method->set_symbol(method->get_symbol());
24880
24881 if (class_decl_sptr class_type = is_class_type(t))
24882 class_type->add_member_function(new_method,
24886 get_member_is_static(*method),
24890 else
24891 t->add_member_function(new_method,
24893 get_member_is_static(*method),
24897 return new_method;
24898}
24899
24900/// Copy a data member of a @ref class_or_union into a new @ref
24901/// class_or_union.
24902///
24903/// @param t the @ref class_or_union into which the data member is to
24904/// be copied.
24905///
24906/// @param variable the data member to copy into @p t.
24907///
24908/// @return the resulting newly copied method.
24910copy_member_variable(class_or_union_sptr t, const var_decl* variable)
24911{
24912 ABG_ASSERT(variable);
24913 ABG_ASSERT(is_data_member(variable));
24914 ABG_ASSERT(t);
24915 ABG_ASSERT(!t->find_data_member(variable->get_name()));
24916
24917 type_base_sptr old_type = variable->get_type();
24918
24919 var_decl_sptr new_variable(new var_decl(variable->get_name(),
24920 old_type,
24921 variable->get_location(),
24922 variable->get_linkage_name(),
24923 variable->get_visibility(),
24924 variable->get_binding()));
24925
24926 size_t offset_in_bits = 0;
24927 if (get_data_member_is_laid_out(*variable))
24928 offset_in_bits = get_data_member_offset(*variable);
24929
24930 t->add_data_member(new_variable,
24931 get_member_access_specifier(*variable),
24932 get_data_member_is_laid_out(*variable),
24933 get_member_is_static(*variable),
24934 offset_in_bits);
24935
24936 return new_variable;
24937}
24938
24939/// Copy a data member of a @ref class_or_union into a new @ref
24940/// class_or_union.
24941///
24942/// @param t the @ref class_or_union into which the data member is to
24943/// be copied.
24944///
24945/// @param variable the data member to copy into @p t.
24946///
24947/// @return the resulting newly copied method.
24949copy_member_variable(class_or_union_sptr t, const var_decl_sptr& variable)
24950{return copy_member_variable(t, variable.get());}
24951
24952/// Copy a data member of a @ref class_or_union into a new @ref
24953/// class_or_union.
24954///
24955/// @param t the @ref class_or_union into which the data member is to
24956/// be copied.
24957///
24958/// @param variable the data member to copy into @p t.
24959///
24960/// @return the resulting newly copied method.
24963{return copy_member_variable(static_pointer_cast<class_or_union>(t), variable);}
24964// </class_or_union definitions>
24965
24966// <class_decl definitions>
24967
24968static void
24969sort_virtual_member_functions(class_decl::member_functions& mem_fns);
24970
24971/// The private data for the class_decl type.
24972struct class_decl::priv
24973{
24974 base_specs bases_;
24975 unordered_map<string, base_spec_sptr> bases_map_;
24976 member_functions virtual_mem_fns_;
24977 virtual_mem_fn_map_type virtual_mem_fns_map_;
24978 bool is_struct_;
24979
24980 priv()
24981 : is_struct_(false)
24982 {}
24983
24984 priv(bool is_struct, class_decl::base_specs& bases)
24985 : bases_(bases),
24986 is_struct_(is_struct)
24987 {
24988 }
24989
24990 priv(bool is_struct)
24991 : is_struct_(is_struct)
24992 {}
24993};// end struct class_decl::priv
24994
24995/// A Constructor for instances of \ref class_decl
24996///
24997/// @param env the environment we are operating from.
24998///
24999/// @param name the identifier of the class.
25000///
25001/// @param size_in_bits the size of an instance of class_decl, expressed
25002/// in bits
25003///
25004/// @param align_in_bits the alignment of an instance of class_decl,
25005/// expressed in bits.
25006///
25007/// @param locus the source location of declaration point this class.
25008///
25009/// @param vis the visibility of instances of class_decl.
25010///
25011/// @param bases the vector of base classes for this instance of class_decl.
25012///
25013/// @param mbrs the vector of member types of this instance of
25014/// class_decl.
25015///
25016/// @param data_mbrs the vector of data members of this instance of
25017/// class_decl.
25018///
25019/// @param mbr_fns the vector of member functions of this instance of
25020/// class_decl.
25021class_decl::class_decl(const environment& env, const string& name,
25022 size_t size_in_bits, size_t align_in_bits,
25023 bool is_struct, const location& locus,
25024 visibility vis, base_specs& bases,
25025 member_types& mbr_types,
25026 data_members& data_mbrs,
25027 member_functions& mbr_fns)
25028 : type_or_decl_base(env,
25029 CLASS_TYPE
25030 | ABSTRACT_TYPE_BASE
25031 | ABSTRACT_DECL_BASE
25032 | ABSTRACT_SCOPE_TYPE_DECL
25033 | ABSTRACT_SCOPE_DECL),
25034 decl_base(env, name, locus, name, vis),
25035 type_base(env, size_in_bits, align_in_bits),
25036 class_or_union(env, name, size_in_bits, align_in_bits,
25037 locus, vis, mbr_types, data_mbrs, mbr_fns),
25038 priv_(new priv(is_struct, bases))
25039{
25041}
25042
25043/// A Constructor for instances of @ref class_decl
25044///
25045/// @param env the environment we are operating from.
25046///
25047/// @param name the identifier of the class.
25048///
25049/// @param size_in_bits the size of an instance of class_decl, expressed
25050/// in bits
25051///
25052/// @param align_in_bits the alignment of an instance of class_decl,
25053/// expressed in bits.
25054///
25055/// @param locus the source location of declaration point this class.
25056///
25057/// @param vis the visibility of instances of class_decl.
25058///
25059/// @param bases the vector of base classes for this instance of class_decl.
25060///
25061/// @param mbrs the vector of member types of this instance of
25062/// class_decl.
25063///
25064/// @param data_mbrs the vector of data members of this instance of
25065/// class_decl.
25066///
25067/// @param mbr_fns the vector of member functions of this instance of
25068/// class_decl.
25069///
25070/// @param is_anonymous whether the newly created instance is
25071/// anonymous.
25072class_decl::class_decl(const environment& env, const string& name,
25073 size_t size_in_bits, size_t align_in_bits,
25074 bool is_struct, const location& locus,
25075 visibility vis, base_specs& bases,
25076 member_types& mbr_types, data_members& data_mbrs,
25077 member_functions& mbr_fns, bool is_anonymous)
25078 : type_or_decl_base(env,
25079 CLASS_TYPE
25080 | ABSTRACT_TYPE_BASE
25081 | ABSTRACT_DECL_BASE
25082 | ABSTRACT_SCOPE_TYPE_DECL
25083 | ABSTRACT_SCOPE_DECL),
25084 decl_base(env, name, locus,
25085 // If the class is anonymous then by default it won't
25086 // have a linkage name. Also, the anonymous class does
25087 // have an internal-only unique name that is generally
25088 // not taken into account when comparing classes; such a
25089 // unique internal-only name, when used as a linkage
25090 // name might introduce spurious comparison false
25091 // negatives.
25092 /*linkage_name=*/is_anonymous ? string() : name,
25093 vis),
25094 type_base(env, size_in_bits, align_in_bits),
25095 class_or_union(env, name, size_in_bits, align_in_bits,
25096 locus, vis, mbr_types, data_mbrs, mbr_fns),
25097 priv_(new priv(is_struct, bases))
25098{
25100 set_is_anonymous(is_anonymous);
25101}
25102
25103/// A constructor for instances of class_decl.
25104///
25105/// @param env the environment we are operating from.
25106///
25107/// @param name the name of the class.
25108///
25109/// @param size_in_bits the size of an instance of class_decl, expressed
25110/// in bits
25111///
25112/// @param align_in_bits the alignment of an instance of class_decl,
25113/// expressed in bits.
25114///
25115/// @param locus the source location of declaration point this class.
25116///
25117/// @param vis the visibility of instances of class_decl.
25118class_decl::class_decl(const environment& env, const string& name,
25119 size_t size_in_bits, size_t align_in_bits,
25120 bool is_struct, const location& locus,
25121 visibility vis)
25122 : type_or_decl_base(env,
25123 CLASS_TYPE
25124 | ABSTRACT_TYPE_BASE
25125 | ABSTRACT_DECL_BASE
25126 | ABSTRACT_SCOPE_TYPE_DECL
25127 | ABSTRACT_SCOPE_DECL),
25128 decl_base(env, name, locus, name, vis),
25129 type_base(env, size_in_bits, align_in_bits),
25130 class_or_union(env, name, size_in_bits, align_in_bits,
25131 locus, vis),
25132 priv_(new priv(is_struct))
25133{
25135}
25136
25137/// A constructor for instances of @ref class_decl.
25138///
25139/// @param env the environment we are operating from.
25140///
25141/// @param name the name of the class.
25142///
25143/// @param size_in_bits the size of an instance of class_decl, expressed
25144/// in bits
25145///
25146/// @param align_in_bits the alignment of an instance of class_decl,
25147/// expressed in bits.
25148///
25149/// @param locus the source location of declaration point this class.
25150///
25151/// @param vis the visibility of instances of class_decl.
25152///
25153/// @param is_anonymous whether the newly created instance is
25154/// anonymous.
25155class_decl:: class_decl(const environment& env, const string& name,
25156 size_t size_in_bits, size_t align_in_bits,
25157 bool is_struct, const location& locus,
25158 visibility vis, bool is_anonymous)
25159 : type_or_decl_base(env,
25160 CLASS_TYPE
25161 | ABSTRACT_TYPE_BASE
25162 | ABSTRACT_DECL_BASE
25163 | ABSTRACT_SCOPE_TYPE_DECL
25164 | ABSTRACT_SCOPE_DECL),
25165 decl_base(env, name, locus,
25166 // If the class is anonymous then by default it won't
25167 // have a linkage name. Also, the anonymous class does
25168 // have an internal-only unique name that is generally
25169 // not taken into account when comparing classes; such a
25170 // unique internal-only name, when used as a linkage
25171 // name might introduce spurious comparison false
25172 // negatives.
25173 /*linkage_name=*/ is_anonymous ? string() : name,
25174 vis),
25175 type_base(env, size_in_bits, align_in_bits),
25176 class_or_union(env, name, size_in_bits, align_in_bits,
25177 locus, vis),
25178 priv_(new priv(is_struct))
25179{
25181 set_is_anonymous(is_anonymous);
25182}
25183
25184/// A constuctor for instances of class_decl that represent a
25185/// declaration without definition.
25186///
25187/// @param env the environment we are operating from.
25188///
25189/// @param name the name of the class.
25190///
25191/// @param is_declaration_only a boolean saying whether the instance
25192/// represents a declaration only, or not.
25193class_decl::class_decl(const environment& env, const string& name,
25194 bool is_struct, bool is_declaration_only)
25195 : type_or_decl_base(env,
25196 CLASS_TYPE
25197 | ABSTRACT_TYPE_BASE
25198 | ABSTRACT_DECL_BASE
25199 | ABSTRACT_SCOPE_TYPE_DECL
25200 | ABSTRACT_SCOPE_DECL),
25201 decl_base(env, name, location(), name),
25202 type_base(env, 0, 0),
25203 class_or_union(env, name, is_declaration_only),
25204 priv_(new priv(is_struct))
25205{
25207}
25208
25209/// This method is invoked automatically right after the current
25210/// instance of @ref class_decl has been canonicalized.
25211///
25212/// Currently, the only thing it does is to sort the virtual member
25213/// functions vector.
25214void
25216{
25218
25219 for (class_decl::virtual_mem_fn_map_type::iterator i =
25220 priv_->virtual_mem_fns_map_.begin();
25221 i != priv_->virtual_mem_fns_map_.end();
25222 ++i)
25223 sort_virtual_member_functions(i->second);
25224}
25225
25226/// Set the "is-struct" flag of the class.
25227///
25228/// @param f the new value of the flag.
25229void
25231{priv_->is_struct_ = f;}
25232
25233/// Test if the class is a struct.
25234///
25235/// @return true iff the class is a struct.
25236bool
25238{return priv_->is_struct_;}
25239
25240/// Add a base specifier to this class.
25241///
25242/// @param b the new base specifier.
25243void
25245{
25246 priv_->bases_.push_back(b);
25247 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
25248}
25249
25250/// Get the base specifiers for this class.
25251///
25252/// @return a vector of the base specifiers.
25255{return priv_->bases_;}
25256
25257/// Find a base class of a given qualified name for the current class.
25258///
25259/// @param qualified_name the qualified name of the base class to look for.
25260///
25261/// @return a pointer to the @ref class_decl that represents the base
25262/// class of name @p qualified_name, if found.
25264class_decl::find_base_class(const string& qualified_name) const
25265{
25266 unordered_map<string, base_spec_sptr>::iterator i =
25267 priv_->bases_map_.find(qualified_name);
25268
25269 if (i != priv_->bases_map_.end())
25270 return i->second->get_base_class();
25271
25272 return class_decl_sptr();
25273}
25274
25275/// Get the virtual member functions of this class.
25276///
25277/// @param return a vector of the virtual member functions of this
25278/// class.
25281{return priv_->virtual_mem_fns_;}
25282
25283/// Get the map that associates a virtual table offset to the virtual
25284/// member functions with that virtual table offset.
25285///
25286/// Usually, there should be a 1:1 mapping between a given vtable
25287/// offset and virtual member functions of that vtable offset. But
25288/// because of some implementation details, there can be several C++
25289/// destructor functions that are *generated* by compilers, for a
25290/// given destructor that is defined in the source code. If the
25291/// destructor is virtual then those generated functions have some
25292/// DWARF attributes in common with the constructor that the user
25293/// actually defined in its source code. Among those attributes are
25294/// the vtable offset of the destructor.
25295///
25296/// @return the map that associates a virtual table offset to the
25297/// virtual member functions with that virtual table offset.
25300{return priv_->virtual_mem_fns_map_;}
25301
25302/// Sort the virtual member functions by their virtual index.
25303void
25305{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
25306
25307/// Getter of the pretty representation of the current instance of
25308/// @ref class_decl.
25309///
25310/// @param internal set to true if the call is intended to get a
25311/// representation of the decl (or type) for the purpose of canonical
25312/// type comparison. This is mainly used in the function
25313/// type_base::get_canonical_type_for().
25314///
25315/// In other words if the argument for this parameter is true then the
25316/// call is meant for internal use (for technical use inside the
25317/// library itself), false otherwise. If you don't know what this is
25318/// for, then set it to false.
25319///
25320/// @param qualified_name if true, names emitted in the pretty
25321/// representation are fully qualified.
25322///
25323/// @return the pretty representaion for a class_decl.
25324string
25326 bool qualified_name) const
25327{
25328 string cl = "class ";
25329 if (!internal && is_struct())
25330 cl = "struct ";
25331
25332 // When computing the pretty representation for internal purposes,
25333 // if an anonymous class is named by a typedef, then consider that
25334 // it has a name, which is the typedef name.
25335 if (get_is_anonymous())
25336 {
25337 if (internal && !get_name().empty())
25338 return cl + get_type_name(this, qualified_name, /*internal=*/true);
25340 /*one_line=*/true,
25341 internal);
25342
25343 }
25344
25345 string result = cl;
25346 if (qualified_name)
25347 result += get_qualified_name(internal);
25348 else
25349 result += get_name();
25350
25351 return result;
25352}
25353
25354decl_base_sptr
25355class_decl::insert_member_decl(decl_base_sptr d)
25356{
25357 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
25358 add_member_function(f, public_access,
25359 /*is_virtual=*/false,
25360 /*vtable_offset=*/0,
25361 /*is_static=*/false,
25362 /*is_ctor=*/false,
25363 /*is_dtor=*/false,
25364 /*is_const=*/false);
25365 else
25367
25368 return d;
25369}
25370
25371/// The private data structure of class_decl::base_spec.
25372struct class_decl::base_spec::priv
25373{
25374 class_decl_wptr base_class_;
25375 long offset_in_bits_;
25376 bool is_virtual_;
25377
25378 priv(const class_decl_sptr& cl,
25379 long offset_in_bits,
25380 bool is_virtual)
25381 : base_class_(cl),
25382 offset_in_bits_(offset_in_bits),
25383 is_virtual_(is_virtual)
25384 {}
25385};
25386
25387/// Constructor for base_spec instances.
25388///
25389/// @param base the base class to consider
25390///
25391/// @param a the access specifier of the base class.
25392///
25393/// @param offset_in_bits if positive or null, represents the offset
25394/// of the base in the layout of its containing type.. If negative,
25395/// means that the current base is not laid out in its containing type.
25396///
25397/// @param is_virtual if true, means that the current base class is
25398/// virtual in it's containing type.
25399class_decl::base_spec::base_spec(const class_decl_sptr& base,
25401 long offset_in_bits,
25402 bool is_virtual)
25403 : type_or_decl_base(base->get_environment(),
25404 ABSTRACT_DECL_BASE),
25405 decl_base(base->get_environment(), base->get_name(), base->get_location(),
25406 base->get_linkage_name(), base->get_visibility()),
25407 member_base(a),
25408 priv_(new priv(base, offset_in_bits, is_virtual))
25409{
25411 set_qualified_name(base->get_qualified_name());
25412}
25413
25414/// Return the hash value of the current IR node.
25415///
25416/// Note that upon the first invocation, this member functions
25417/// computes the hash value and returns it. Subsequent invocations
25418/// just return the hash value that was previously calculated.
25419///
25420/// @return the hash value of the current IR node.
25421hash_t
25423{
25425 return h;
25426}
25427
25428/// Get the base class referred to by the current base class
25429/// specifier.
25430///
25431/// @return the base class.
25434{return priv_->base_class_.lock();}
25435
25436/// Getter of the "is-virtual" proprerty of the base class specifier.
25437///
25438/// @return true iff this specifies a virtual base class.
25439bool
25441{return priv_->is_virtual_;}
25442
25443/// Getter of the offset of the base.
25444///
25445/// @return the offset of the base.
25446long
25448{return priv_->offset_in_bits_;}
25449
25450/// Traverses an instance of @ref class_decl::base_spec, visiting all
25451/// the sub-types and decls that it might contain.
25452///
25453/// @param v the visitor that is used to visit every IR sub-node of
25454/// the current node.
25455///
25456/// @return true if either
25457/// - all the children nodes of the current IR node were traversed
25458/// and the calling code should keep going with the traversing.
25459/// - or the current IR node is already being traversed.
25460/// Otherwise, returning false means that the calling code should not
25461/// keep traversing the tree.
25462bool
25464{
25465 if (visiting())
25466 return true;
25467
25468 if (v.visit_begin(this))
25469 {
25470 visiting(true);
25471 get_base_class()->traverse(v);
25472 visiting(false);
25473 }
25474
25475 return v.visit_end(this);
25476}
25477
25478/// Constructor for base_spec instances.
25479///
25480/// Note that this constructor is for clients that don't support RTTI
25481/// and that have a base class of type_base, but of dynamic type
25482/// class_decl.
25483///
25484/// @param base the base class to consider. Must be a pointer to an
25485/// instance of class_decl
25486///
25487/// @param a the access specifier of the base class.
25488///
25489/// @param offset_in_bits if positive or null, represents the offset
25490/// of the base in the layout of its containing type.. If negative,
25491/// means that the current base is not laid out in its containing type.
25492///
25493/// @param is_virtual if true, means that the current base class is
25494/// virtual in it's containing type.
25495class_decl::base_spec::base_spec(const type_base_sptr& base,
25497 long offset_in_bits,
25498 bool is_virtual)
25500 ABSTRACT_DECL_BASE),
25505 member_base(a),
25506 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
25507 offset_in_bits,
25508 is_virtual))
25509{
25511}
25512
25513class_decl::base_spec::~base_spec() = default;
25514
25515/// Compares two instances of @ref class_decl::base_spec.
25516///
25517/// If the two intances are different, set a bitfield to give some
25518/// insight about the kind of differences there are.
25519///
25520/// @param l the first artifact of the comparison.
25521///
25522/// @param r the second artifact of the comparison.
25523///
25524/// @param k a pointer to a bitfield that gives information about the
25525/// kind of changes there are between @p l and @p r. This one is set
25526/// iff @p k is non-null and the function returns false.
25527///
25528/// Please note that setting k to a non-null value does have a
25529/// negative performance impact because even if @p l and @p r are not
25530/// equal, the function keeps up the comparison in order to determine
25531/// the different kinds of ways in which they are different.
25532///
25533/// @return true if @p l equals @p r, false otherwise.
25534bool
25536 const class_decl::base_spec& r,
25537 change_kind* k)
25538{
25539 if (!l.member_base::operator==(r))
25540 {
25541 if (k)
25544 }
25545
25547}
25548
25549/// Comparison operator for @ref class_decl::base_spec.
25550///
25551/// @param other the instance of @ref class_decl::base_spec to compare
25552/// against.
25553///
25554/// @return true if the current instance of @ref class_decl::base_spec
25555/// equals @p other.
25556bool
25558{
25559 const class_decl::base_spec* o =
25560 dynamic_cast<const class_decl::base_spec*>(&other);
25561
25562 if (!o)
25563 return false;
25564
25565 return equals(*this, *o, 0);
25566}
25567
25568/// Comparison operator for @ref class_decl::base_spec.
25569///
25570/// @param other the instance of @ref class_decl::base_spec to compare
25571/// against.
25572///
25573/// @return true if the current instance of @ref class_decl::base_spec
25574/// equals @p other.
25575bool
25577{
25578 const class_decl::base_spec* o =
25579 dynamic_cast<const class_decl::base_spec*>(&other);
25580 if (!o)
25581 return false;
25582
25583 return operator==(static_cast<const decl_base&>(*o));
25584}
25585
25586mem_fn_context_rel::~mem_fn_context_rel()
25587{
25588}
25589
25590/// A constructor for instances of method_decl.
25591///
25592/// @param name the name of the method.
25593///
25594/// @param type the type of the method.
25595///
25596/// @param declared_inline whether the method was
25597/// declared inline or not.
25598///
25599/// @param locus the source location of the method.
25600///
25601/// @param linkage_name the mangled name of the method.
25602///
25603/// @param vis the visibility of the method.
25604///
25605/// @param bind the binding of the method.
25606method_decl::method_decl(const string& name,
25607 method_type_sptr type,
25608 bool declared_inline,
25609 const location& locus,
25610 const string& linkage_name,
25611 visibility vis,
25612 binding bind)
25614 METHOD_DECL
25615 | ABSTRACT_DECL_BASE
25616 |FUNCTION_DECL),
25617 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25618 function_decl(name, static_pointer_cast<function_type>(type),
25619 declared_inline, locus, linkage_name, vis, bind)
25620{
25622 set_context_rel(new mem_fn_context_rel(0));
25623 set_member_function_is_const(*this, type->get_is_const());
25624}
25625
25626/// A constructor for instances of method_decl.
25627///
25628/// @param name the name of the method.
25629///
25630/// @param type the type of the method. Must be an instance of
25631/// method_type.
25632///
25633/// @param declared_inline whether the method was
25634/// declared inline or not.
25635///
25636/// @param locus the source location of the method.
25637///
25638/// @param linkage_name the mangled name of the method.
25639///
25640/// @param vis the visibility of the method.
25641///
25642/// @param bind the binding of the method.
25643method_decl::method_decl(const string& name,
25644 function_type_sptr type,
25645 bool declared_inline,
25646 const location& locus,
25647 const string& linkage_name,
25648 visibility vis,
25649 binding bind)
25650 : type_or_decl_base(type->get_environment(),
25651 METHOD_DECL
25652 | ABSTRACT_DECL_BASE
25653 | FUNCTION_DECL),
25654 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25655 function_decl(name, static_pointer_cast<function_type>
25656 (dynamic_pointer_cast<method_type>(type)),
25657 declared_inline, locus, linkage_name, vis, bind)
25658{
25660 set_context_rel(new mem_fn_context_rel(0));
25661}
25662
25663/// A constructor for instances of method_decl.
25664///
25665/// @param name the name of the method.
25666///
25667/// @param type the type of the method. Must be an instance of
25668/// method_type.
25669///
25670/// @param declared_inline whether the method was
25671/// declared inline or not.
25672///
25673/// @param locus the source location of the method.
25674///
25675/// @param linkage_name the mangled name of the method.
25676///
25677/// @param vis the visibility of the method.
25678///
25679/// @param bind the binding of the method.
25680method_decl::method_decl(const string& name,
25681 type_base_sptr type,
25682 bool declared_inline,
25683 const location& locus,
25684 const string& linkage_name,
25685 visibility vis,
25686 binding bind)
25687 : type_or_decl_base(type->get_environment(),
25688 METHOD_DECL
25689 | ABSTRACT_DECL_BASE
25690 | FUNCTION_DECL),
25691 decl_base(type->get_environment(), name, locus, linkage_name, vis),
25692 function_decl(name, static_pointer_cast<function_type>
25693 (dynamic_pointer_cast<method_type>(type)),
25694 declared_inline, locus, linkage_name, vis, bind)
25695{
25697 set_context_rel(new mem_fn_context_rel(0));
25698}
25699
25700/// Set the linkage name of the method.
25701///
25702/// @param l the new linkage name of the method.
25703void
25705{
25706 string old_lname = get_linkage_name();
25708 // Update the linkage_name -> member function map of the containing
25709 // class declaration.
25710 if (!l.empty())
25711 {
25713 class_or_union_sptr cl = t->get_class_type();
25714 method_decl_sptr m(this, sptr_utils::noop_deleter());
25715 cl->priv_->mem_fns_map_[l] = m;
25716 if (!old_lname.empty() && l != old_lname)
25717 {
25718 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
25719 {
25720 ABG_ASSERT(m.get() == this);
25721 cl->priv_->mem_fns_map_.erase(old_lname);
25722 }
25723 }
25724 }
25725}
25726
25727method_decl::~method_decl()
25728{}
25729
25730const method_type_sptr
25732{
25733 method_type_sptr result;
25735 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
25736 return result;
25737}
25738
25739/// Set the containing class of a method_decl.
25740///
25741/// @param scope the new containing class_decl.
25742void
25743method_decl::set_scope(scope_decl* scope)
25744{
25745 if (!get_context_rel())
25746 set_context_rel(new mem_fn_context_rel(scope));
25747 else
25748 get_context_rel()->set_scope(scope);
25749}
25750
25751/// Equality operator for @ref method_decl_sptr.
25752///
25753/// This is a deep equality operator, as it compares the @ref
25754/// method_decl that is pointed-to by the smart pointer.
25755///
25756/// @param l the left-hand side argument of the equality operator.
25757///
25758/// @param r the righ-hand side argument of the equality operator.
25759///
25760/// @return true iff @p l equals @p r.
25761bool
25762operator==(const method_decl_sptr& l, const method_decl_sptr& r)
25763{
25764 if (l.get() == r.get())
25765 return true;
25766 if (!!l != !!r)
25767 return false;
25768
25769 return *l == *r;
25770}
25771
25772/// Inequality operator for @ref method_decl_sptr.
25773///
25774/// This is a deep equality operator, as it compares the @ref
25775/// method_decl that is pointed-to by the smart pointer.
25776///
25777/// @param l the left-hand side argument of the equality operator.
25778///
25779/// @param r the righ-hand side argument of the equality operator.
25780///
25781/// @return true iff @p l differs from @p r.
25782bool
25783operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
25784{return !operator==(l, r);}
25785
25786/// Test if a function_decl is actually a method_decl.
25787///
25788///@param d the @ref function_decl to consider.
25789///
25790/// @return the method_decl sub-object of @p d if inherits
25791/// a method_decl type.
25794{
25795 return dynamic_cast<method_decl*>
25796 (const_cast<type_or_decl_base*>(d));
25797}
25798
25799/// Test if a function_decl is actually a method_decl.
25800///
25801///@param d the @ref function_decl to consider.
25802///
25803/// @return the method_decl sub-object of @p d if inherits
25804/// a method_decl type.
25808
25809/// Test if a function_decl is actually a method_decl.
25810///
25811///@param d the @ref function_decl to consider.
25812///
25813/// @return the method_decl sub-object of @p d if inherits
25814/// a method_decl type.
25815method_decl_sptr
25817{return dynamic_pointer_cast<method_decl>(d);}
25818
25819/// A "less than" functor to sort a vector of instances of
25820/// method_decl that are virtual.
25821struct virtual_member_function_less_than
25822{
25823 /// The less than operator. First, it sorts the methods by their
25824 /// vtable index. If they have the same vtable index, it sorts them
25825 /// by the name of their ELF symbol. If they don't have elf
25826 /// symbols, it sorts them by considering their pretty
25827 /// representation.
25828 ///
25829 /// Note that this method expects virtual methods.
25830 ///
25831 /// @param f the first method to consider.
25832 ///
25833 /// @param s the second method to consider.
25834 ///
25835 /// @return true if method @p is less than method @s.
25836 bool
25837 operator()(const method_decl& f,
25838 const method_decl& s)
25839 {
25842
25843 ssize_t f_offset = get_member_function_vtable_offset(f);
25844 ssize_t s_offset = get_member_function_vtable_offset(s);
25845 if (f_offset != s_offset) return f_offset < s_offset;
25846
25847 string fn, sn;
25848 // Try the linkage names (important for destructors).
25849 fn = f.get_linkage_name();
25850 sn = s.get_linkage_name();
25851 if (fn != sn) return fn < sn;
25852
25853 // If the functions have symbols, then compare their symbol-id
25854 // string.
25855 elf_symbol_sptr f_sym = f.get_symbol();
25856 elf_symbol_sptr s_sym = s.get_symbol();
25857 if ((!f_sym) != (!s_sym)) return !f_sym;
25858 if (f_sym && s_sym)
25859 {
25860 fn = f_sym->get_id_string();
25861 sn = s_sym->get_id_string();
25862 if (fn != sn) return fn < sn;
25863 }
25864
25865 // None of the functions have symbols or linkage names that
25866 // distinguish them, so compare their pretty representation.
25869 if (fn != sn) return fn < sn;
25870
25871 /// If it's just the file paths that are different then sort them
25872 /// too.
25873 string fn_filepath, sn_filepath;
25874 unsigned line = 0, column = 0;
25875 location fn_loc = f.get_location(), sn_loc = s.get_location();
25876 if (fn_loc)
25877 fn_loc.expand(fn_filepath, line, column);
25878 if (sn_loc)
25879 sn_loc.expand(sn_filepath, line, column);
25880 return fn_filepath < sn_filepath;
25881 }
25882
25883 /// The less than operator. First, it sorts the methods by their
25884 /// vtable index. If they have the same vtable index, it sorts them
25885 /// by the name of their ELF symbol. If they don't have elf
25886 /// symbols, it sorts them by considering their pretty
25887 /// representation.
25888 ///
25889 /// Note that this method expects to take virtual methods.
25890 ///
25891 /// @param f the first method to consider.
25892 ///
25893 /// @param s the second method to consider.
25894 bool
25895 operator()(const method_decl_sptr f,
25896 const method_decl_sptr s)
25897 {return operator()(*f, *s);}
25898}; // end struct virtual_member_function_less_than
25899
25900/// Sort a vector of instances of virtual member functions.
25901///
25902/// @param mem_fns the vector of member functions to sort.
25903static void
25904sort_virtual_member_functions(class_decl::member_functions& mem_fns)
25905{
25906 virtual_member_function_less_than lt;
25907 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25908}
25909
25910/// Add a member function to the current instance of @ref class_or_union.
25911///
25912/// @param f a method_decl to add to the current class. This function
25913/// should not have been already added to a scope.
25914///
25915/// @param access the access specifier for the member function to add.
25916///
25917/// @param is_virtual if this is true then it means the function @p f
25918/// is a virtual function. That also means that the current instance
25919/// of @ref class_or_union is actually an instance of @ref class_decl.
25920///
25921/// @param vtable_offset the offset of the member function in the
25922/// virtual table. This parameter is taken into account only if @p
25923/// is_virtual is true.
25924///
25925/// @param is_static whether the member function is static.
25926///
25927/// @param is_ctor whether the member function is a constructor.
25928///
25929/// @param is_dtor whether the member function is a destructor.
25930///
25931/// @param is_const whether the member function is const.
25932void
25935 bool is_virtual,
25936 size_t vtable_offset,
25937 bool is_static, bool is_ctor,
25938 bool is_dtor, bool is_const)
25939{
25940 add_member_function(f, a, is_static, is_ctor,
25941 is_dtor, is_const);
25942
25943 if (class_decl* klass = is_class_type(this))
25944 {
25945 if (is_virtual)
25946 {
25947 set_member_function_virtuality(f, is_virtual, vtable_offset);
25948 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
25949 }
25950 }
25951}
25952
25953/// When a virtual member function has seen its virtualness set by
25954/// set_member_function_is_virtual(), this function ensures that the
25955/// member function is added to the specific vectors and maps of
25956/// virtual member function of its class.
25957///
25958/// @param method the method to fixup.
25959void
25960fixup_virtual_member_function(method_decl_sptr method)
25961{
25962 if (!method || !get_member_function_is_virtual(method))
25963 return;
25964
25965 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
25966
25967 class_decl::member_functions::const_iterator m;
25968 for (m = klass->priv_->virtual_mem_fns_.begin();
25969 m != klass->priv_->virtual_mem_fns_.end();
25970 ++m)
25971 if (m->get() == method.get()
25972 || (*m)->get_linkage_name() == method->get_linkage_name())
25973 break;
25974 if (m == klass->priv_->virtual_mem_fns_.end())
25975 klass->priv_->virtual_mem_fns_.push_back(method);
25976
25977 // Build or udpate the map that associates a vtable offset to the
25978 // number of virtual member functions that "point" to it.
25979 ssize_t voffset = get_member_function_vtable_offset(method);
25980 if (voffset == -1)
25981 return;
25982
25983 class_decl::virtual_mem_fn_map_type::iterator i =
25984 klass->priv_->virtual_mem_fns_map_.find(voffset);
25985 if (i == klass->priv_->virtual_mem_fns_map_.end())
25986 {
25987 class_decl::member_functions virtual_mem_fns_at_voffset;
25988 virtual_mem_fns_at_voffset.push_back(method);
25989 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
25990 }
25991 else
25992 {
25993 for (m = i->second.begin() ; m != i->second.end(); ++m)
25994 if (m->get() == method.get()
25995 || (*m)->get_linkage_name() == method->get_linkage_name())
25996 break;
25997 if (m == i->second.end())
25998 i->second.push_back(method);
25999 }
26000}
26001
26002/// Return true iff the class has no entity in its scope.
26003bool
26005{return priv_->bases_.empty() && has_no_member();}
26006
26007/// Test if the current instance of @ref class_decl has virtual member
26008/// functions.
26009///
26010/// @return true iff the current instance of @ref class_decl has
26011/// virtual member functions.
26012bool
26015
26016/// Test if the current instance of @ref class_decl has at least one
26017/// virtual base.
26018///
26019/// @return true iff the current instance of @ref class_decl has a
26020/// virtual member function.
26021bool
26023{
26024 for (base_specs::const_iterator b = get_base_specifiers().begin();
26025 b != get_base_specifiers().end();
26026 ++b)
26027 if ((*b)->get_is_virtual()
26028 || (*b)->get_base_class()->has_virtual_bases())
26029 return true;
26030
26031 return false;
26032}
26033
26034/// Test if the current instance has a vtable.
26035///
26036/// This is only valid for a C++ program.
26037///
26038/// Basically this function checks if the class has either virtual
26039/// functions, or virtual bases.
26040bool
26042{
26044 || has_virtual_bases())
26045 return true;
26046 return false;
26047}
26048
26049/// Get the highest vtable offset of all the virtual methods of the
26050/// class.
26051///
26052/// @return the highest vtable offset of all the virtual methods of
26053/// the class.
26054ssize_t
26056{
26057 ssize_t offset = -1;
26058 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
26059 get_virtual_mem_fns_map().begin();
26060 e != get_virtual_mem_fns_map().end();
26061 ++e)
26062 if (e->first > offset)
26063 offset = e->first;
26064
26065 return offset;
26066}
26067
26068/// Return the hash value of the current IR node.
26069///
26070/// Note that upon the first invocation, this member functions
26071/// computes the hash value and returns it. Subsequent invocations
26072/// just return the hash value that was previously calculated.
26073///
26074/// @return the hash value of the current IR node.
26075hash_t
26077{
26079 return h;
26080}
26081
26082/// Test if two methods are equal without taking their symbol or
26083/// linkage name into account.
26084///
26085/// @param f the first method.
26086///
26087/// @param s the second method.
26088///
26089/// @return true iff @p f equals @p s without taking their linkage
26090/// name or symbol into account.
26091static bool
26092methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
26093 const method_decl_sptr& s)
26094{
26095 method_decl_sptr first = f, second = s;
26096 elf_symbol_sptr saved_first_elf_symbol =
26097 first->get_symbol();
26098 elf_symbol_sptr saved_second_elf_symbol =
26099 second->get_symbol();
26100 interned_string saved_first_linkage_name =
26101 first->get_linkage_name();
26102 interned_string saved_second_linkage_name =
26103 second->get_linkage_name();
26104
26105 first->set_symbol(elf_symbol_sptr());
26106 first->set_linkage_name("");
26107 second->set_symbol(elf_symbol_sptr());
26108 second->set_linkage_name("");
26109
26110 bool equal = *first == *second;
26111
26112 first->set_symbol(saved_first_elf_symbol);
26113 first->set_linkage_name(saved_first_linkage_name);
26114 second->set_symbol(saved_second_elf_symbol);
26115 second->set_linkage_name(saved_second_linkage_name);
26116
26117 return equal;
26118}
26119
26120/// Test if a given method is equivalent to at least of other method
26121/// that is in a vector of methods.
26122///
26123/// Note that "equivalent" here means being equal without taking the
26124/// linkage name or the symbol of the methods into account.
26125///
26126/// This is a sub-routine of the 'equals' function that compares @ref
26127/// class_decl.
26128///
26129/// @param method the method to compare.
26130///
26131/// @param fns the vector of functions to compare @p method against.
26132///
26133/// @return true iff @p is equivalent to at least one method in @p
26134/// fns.
26135static bool
26136method_matches_at_least_one_in_vector(const method_decl_sptr& method,
26138{
26139 for (class_decl::member_functions::const_iterator i = fns.begin();
26140 i != fns.end();
26141 ++i)
26142 // Note that the comparison must be done in this order: method ==
26143 // *i This is to keep the consistency of the comparison. It's
26144 // important especially when doing type canonicalization. The
26145 // already canonicalize type is the left operand, and the type
26146 // being canonicalized is the right operand. This comes from the
26147 // code in type_base::get_canonical_type_for().
26148 if (methods_equal_modulo_elf_symbol(method, *i))
26149 return true;
26150
26151 return false;
26152}
26153
26154/// Compares two instances of @ref class_decl.
26155///
26156/// If the two intances are different, set a bitfield to give some
26157/// insight about the kind of differences there are.
26158///
26159/// @param l the first artifact of the comparison.
26160///
26161/// @param r the second artifact of the comparison.
26162///
26163/// @param k a pointer to a bitfield that gives information about the
26164/// kind of changes there are between @p l and @p r. This one is set
26165/// iff @p k is non-null and the function returns false.
26166///
26167/// Please note that setting k to a non-null value does have a
26168/// negative performance impact because even if @p l and @p r are not
26169/// equal, the function keeps up the comparison in order to determine
26170/// the different kinds of ways in which they are different.
26171///
26172/// @return true if @p l equals @p r, false otherwise.
26173bool
26175{
26176 {
26177 // First of all, let's see if these two types haven't already been
26178 // compared. If so, and if the result of the comparison has been
26179 // cached, let's just re-use it, rather than comparing them all
26180 // over again.
26181 bool result = false;
26182 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
26183 ABG_RETURN(result);
26184 }
26185
26186 // if one of the classes is declaration-only then we take a fast
26187 // path here.
26189 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
26190 static_cast<const class_or_union&>(r),
26191 k));
26192
26193 bool result = true;
26194 if (!equals(static_cast<const class_or_union&>(l),
26195 static_cast<const class_or_union&>(r),
26196 k))
26197 {
26198 result = false;
26199 if (!k)
26200 ABG_RETURN(result);
26201 }
26202
26204
26206
26207#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
26208
26209 // Compare bases.
26210 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
26211 {
26212 result = false;
26213 if (k)
26215 else
26216 RETURN(result);
26217 }
26218
26219 for (class_decl::base_specs::const_iterator
26220 b0 = l.get_base_specifiers().begin(),
26221 b1 = r.get_base_specifiers().begin();
26222 (b0 != l.get_base_specifiers().end()
26223 && b1 != r.get_base_specifiers().end());
26224 ++b0, ++b1)
26225 if (*b0 != *b1)
26226 {
26227 result = false;
26228 if (k)
26229 {
26230 if (!types_have_similar_structure((*b0)->get_base_class().get(),
26231 (*b1)->get_base_class().get()))
26233 else
26234 *k |= SUBTYPE_CHANGE_KIND;
26235 break;
26236 }
26237 RETURN(result);
26238 }
26239
26240 // Compare virtual member functions
26241
26242 // We look at the map that associates a given vtable offset to a
26243 // vector of virtual member functions that point to that offset.
26244 //
26245 // This is because there are cases where several functions can
26246 // point to the same virtual table offset.
26247 //
26248 // This is usually the case for virtual destructors. Even though
26249 // there can be only one virtual destructor declared in source
26250 // code, there are actually potentially up to three generated
26251 // functions for that destructor. Some of these generated
26252 // functions can be clones of other functions that are among those
26253 // generated ones. In any cases, they all have the same
26254 // properties, including the vtable offset property.
26255
26256 // So, there should be the same number of different vtable
26257 // offsets, the size of two maps must be equals.
26258 if (l.get_virtual_mem_fns_map().size()
26259 != r.get_virtual_mem_fns_map().size())
26260 {
26261 result = false;
26262 if (k)
26264 else
26265 RETURN(result);
26266 }
26267
26268 // Then, each virtual member function of a given vtable offset in
26269 // the first class type, must match an equivalent virtual member
26270 // function of a the same vtable offset in the second class type.
26271 //
26272 // By "match", I mean that the two virtual member function should
26273 // be equal if we don't take into account their symbol name or
26274 // their linkage name. This is because two destructor functions
26275 // clones (for instance) might have different linkage name, but
26276 // are still equivalent if their other properties are the same.
26277 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
26278 l.get_virtual_mem_fns_map().begin();
26279 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
26280 ++first_v_fn_entry)
26281 {
26282 unsigned voffset = first_v_fn_entry->first;
26283 const class_decl::member_functions& first_vfns =
26284 first_v_fn_entry->second;
26285
26286 const class_decl::virtual_mem_fn_map_type::const_iterator
26287 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
26288
26289 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
26290 {
26291 result = false;
26292 if (k)
26294 RETURN(result);
26295 }
26296
26297 const class_decl::member_functions& second_vfns =
26298 second_v_fn_entry->second;
26299
26300 bool matches = false;
26301 for (class_decl::member_functions::const_iterator i =
26302 first_vfns.begin();
26303 i != first_vfns.end();
26304 ++i)
26305 if (method_matches_at_least_one_in_vector(*i, second_vfns))
26306 {
26307 matches = true;
26308 break;
26309 }
26310
26311 if (!matches)
26312 {
26313 result = false;
26314 if (k)
26315 *k |= SUBTYPE_CHANGE_KIND;
26316 else
26317 RETURN(result);
26318 }
26319 }
26320
26321 RETURN(result);
26322#undef RETURN
26323}
26324
26325/// Copy a method of a class into a new class.
26326///
26327/// @param klass the class into which the method is to be copied.
26328///
26329/// @param method the method to copy into @p klass.
26330///
26331/// @return the resulting newly copied method.
26332method_decl_sptr
26333copy_member_function(class_decl_sptr clazz, const method_decl_sptr& f)
26334{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26335
26336/// Copy a method of a class into a new class.
26337///
26338/// @param klass the class into which the method is to be copied.
26339///
26340/// @param method the method to copy into @p klass.
26341///
26342/// @return the resulting newly copied method.
26343method_decl_sptr
26345{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
26346
26347/// Comparison operator for @ref class_decl.
26348///
26349/// @param other the instance of @ref class_decl to compare against.
26350///
26351/// @return true iff the current instance of @ref class_decl equals @p
26352/// other.
26353bool
26355{
26356 const class_decl* op = is_class_type(&other);
26357 if (!op)
26358 {
26359 if (class_or_union* cou = is_class_or_union_type(&other))
26360 return class_or_union::operator==(*cou);
26361 return false;
26362 }
26363
26364 // If this is a decl-only type (and thus with no canonical type),
26365 // use the canonical type of the definition, if any.
26366 const class_decl *l = 0;
26368 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
26369 if (l == 0)
26370 l = this;
26371
26372 ABG_ASSERT(l);
26373
26374 // Likewise for the other type.
26375 const class_decl *r = 0;
26376 if (op->get_is_declaration_only())
26377 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
26378 if (r == 0)
26379 r = op;
26380
26381 ABG_ASSERT(r);
26382
26383 return try_canonical_compare(l, r);
26384}
26385
26386/// Equality operator for class_decl.
26387///
26388/// Re-uses the equality operator that takes a decl_base.
26389///
26390/// @param other the other class_decl to compare against.
26391///
26392/// @return true iff the current instance equals the other one.
26393bool
26395{
26396 const decl_base* o = is_decl(&other);
26397 if (!o)
26398 return false;
26399 return *this == *o;
26400}
26401
26402/// Equality operator for class_decl.
26403///
26404/// Re-uses the equality operator that takes a decl_base.
26405///
26406/// @param other the other class_decl to compare against.
26407///
26408/// @return true iff the current instance equals the other one.
26409bool
26411{
26412 const decl_base& o = other;
26413 return *this == o;
26414}
26415
26416/// Comparison operator for @ref class_decl.
26417///
26418/// @param other the instance of @ref class_decl to compare against.
26419///
26420/// @return true iff the current instance of @ref class_decl equals @p
26421/// other.
26422bool
26424{
26425 const decl_base& o = other;
26426 return *this == o;
26427}
26428
26429/// Turn equality of shared_ptr of class_decl into a deep equality;
26430/// that is, make it compare the pointed to objects too.
26431///
26432/// @param l the shared_ptr of class_decl on left-hand-side of the
26433/// equality.
26434///
26435/// @param r the shared_ptr of class_decl on right-hand-side of the
26436/// equality.
26437///
26438/// @return true if the class_decl pointed to by the shared_ptrs are
26439/// equal, false otherwise.
26440bool
26442{
26443 if (l.get() == r.get())
26444 return true;
26445 if (!!l != !!r)
26446 return false;
26447
26448 return *l == *r;
26449}
26450
26451/// Turn inequality of shared_ptr of class_decl into a deep equality;
26452/// that is, make it compare the pointed to objects too.
26453///
26454/// @param l the shared_ptr of class_decl on left-hand-side of the
26455/// equality.
26456///
26457/// @param r the shared_ptr of class_decl on right-hand-side of the
26458/// equality.
26459///
26460/// @return true if the class_decl pointed to by the shared_ptrs are
26461/// different, false otherwise.
26462bool
26464{return !operator==(l, r);}
26465
26466/// Turn equality of shared_ptr of class_or_union into a deep
26467/// equality; that is, make it compare the pointed to objects too.
26468///
26469/// @param l the left-hand-side operand of the operator
26470///
26471/// @param r the right-hand-side operand of the operator.
26472///
26473/// @return true iff @p l equals @p r.
26474bool
26475operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
26476{
26477 if (l.get() == r.get())
26478 return true;
26479 if (!!l != !!r)
26480 return false;
26481
26482 return *l == *r;
26483}
26484
26485/// Turn inequality of shared_ptr of class_or_union into a deep
26486/// equality; that is, make it compare the pointed to objects too.
26487///
26488/// @param l the left-hand-side operand of the operator
26489///
26490/// @param r the right-hand-side operand of the operator.
26491///
26492/// @return true iff @p l is different from @p r.
26493bool
26494operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
26495{return !operator==(l, r);}
26496
26497/// This implements the ir_traversable_base::traverse pure virtual
26498/// function.
26499///
26500/// @param v the visitor used on the current instance and on its
26501/// members.
26502///
26503/// @return true if the entire IR node tree got traversed, false
26504/// otherwise.
26505bool
26507{
26508 if (v.type_node_has_been_visited(this))
26509 return true;
26510
26511 if (visiting())
26512 return true;
26513
26514 if (v.visit_begin(this))
26515 {
26516 visiting(true);
26517 bool stop = false;
26518
26519 for (base_specs::const_iterator i = get_base_specifiers().begin();
26520 i != get_base_specifiers().end();
26521 ++i)
26522 {
26523 if (!(*i)->traverse(v))
26524 {
26525 stop = true;
26526 break;
26527 }
26528 }
26529
26530 if (!stop)
26531 for (data_members::const_iterator i = get_data_members().begin();
26532 i != get_data_members().end();
26533 ++i)
26534 if (!(*i)->traverse(v))
26535 {
26536 stop = true;
26537 break;
26538 }
26539
26540 if (!stop)
26541 for (member_functions::const_iterator i= get_member_functions().begin();
26542 i != get_member_functions().end();
26543 ++i)
26544 if (!(*i)->traverse(v))
26545 {
26546 stop = true;
26547 break;
26548 }
26549
26550 if (!stop)
26551 for (member_types::const_iterator i = get_member_types().begin();
26552 i != get_member_types().end();
26553 ++i)
26554 if (!(*i)->traverse(v))
26555 {
26556 stop = true;
26557 break;
26558 }
26559
26560 if (!stop)
26561 for (member_function_templates::const_iterator i =
26563 i != get_member_function_templates().end();
26564 ++i)
26565 if (!(*i)->traverse(v))
26566 {
26567 stop = true;
26568 break;
26569 }
26570
26571 if (!stop)
26572 for (member_class_templates::const_iterator i =
26574 i != get_member_class_templates().end();
26575 ++i)
26576 if (!(*i)->traverse(v))
26577 {
26578 stop = true;
26579 break;
26580 }
26581 visiting(false);
26582 }
26583
26584 bool result = v.visit_end(this);
26586 return result;
26587}
26588
26589/// Destructor of the @ref class_decl type.
26591{delete priv_;}
26592
26593context_rel::~context_rel()
26594{}
26595
26596bool
26597member_base::operator==(const member_base& o) const
26598{
26600 && get_is_static() == o.get_is_static());
26601}
26602
26603/// Equality operator for smart pointers to @ref
26604/// class_decl::base_specs.
26605///
26606/// This compares the pointed-to objects.
26607///
26608/// @param l the first instance to consider.
26609///
26610/// @param r the second instance to consider.
26611///
26612/// @return true iff @p l equals @p r.
26613bool
26616{
26617 if (l.get() == r.get())
26618 return true;
26619 if (!!l != !!r)
26620 return false;
26621
26622 return *l == static_cast<const decl_base&>(*r);
26623}
26624
26625/// Inequality operator for smart pointers to @ref
26626/// class_decl::base_specs.
26627///
26628/// This compares the pointed-to objects.
26629///
26630/// @param l the first instance to consider.
26631///
26632/// @param r the second instance to consider.
26633///
26634/// @return true iff @p l is different from @p r.
26635bool
26638{return !operator==(l, r);}
26639
26640/// Test if an ABI artifact is a class base specifier.
26641///
26642/// @param tod the ABI artifact to consider.
26643///
26644/// @return a pointer to the @ref class_decl::base_spec sub-object of
26645/// @p tod iff it's a class base specifier.
26648{
26649 return dynamic_cast<class_decl::base_spec*>
26650 (const_cast<type_or_decl_base*>(tod));
26651}
26652
26653/// Test if an ABI artifact is a class base specifier.
26654///
26655/// @param tod the ABI artifact to consider.
26656///
26657/// @return a pointer to the @ref class_decl::base_spec sub-object of
26658/// @p tod iff it's a class base specifier.
26661{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
26662
26663bool
26664member_function_template::operator==(const member_base& other) const
26665{
26666 try
26667 {
26668 const member_function_template& o =
26669 dynamic_cast<const member_function_template&>(other);
26670
26671 if (!(is_constructor() == o.is_constructor()
26672 && is_const() == o.is_const()
26673 && member_base::operator==(o)))
26674 return false;
26675
26676 if (function_tdecl_sptr ftdecl = as_function_tdecl())
26677 {
26678 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
26679 if (other_ftdecl)
26680 return ftdecl->function_tdecl::operator==(*other_ftdecl);
26681 }
26682 }
26683 catch(...)
26684 {}
26685 return false;
26686}
26687
26688/// Equality operator for smart pointers to @ref
26689/// member_function_template. This is compares the
26690/// pointed-to instances.
26691///
26692/// @param l the first instance to consider.
26693///
26694/// @param r the second instance to consider.
26695///
26696/// @return true iff @p l equals @p r.
26697bool
26698operator==(const member_function_template_sptr& l,
26699 const member_function_template_sptr& r)
26700{
26701 if (l.get() == r.get())
26702 return true;
26703 if (!!l != !!r)
26704 return false;
26705
26706 return *l == *r;
26707}
26708
26709/// Inequality operator for smart pointers to @ref
26710/// member_function_template. This is compares the pointed-to
26711/// instances.
26712///
26713/// @param l the first instance to consider.
26714///
26715/// @param r the second instance to consider.
26716///
26717/// @return true iff @p l equals @p r.
26718bool
26719operator!=(const member_function_template_sptr& l,
26720 const member_function_template_sptr& r)
26721{return !operator==(l, r);}
26722
26723/// This implements the ir_traversable_base::traverse pure virtual
26724/// function.
26725///
26726/// @param v the visitor used on the current instance and on its
26727/// underlying function template.
26728///
26729/// @return true if the entire IR node tree got traversed, false
26730/// otherwise.
26731bool
26733{
26734 if (visiting())
26735 return true;
26736
26737 if (v.visit_begin(this))
26738 {
26739 visiting(true);
26740 if (function_tdecl_sptr f = as_function_tdecl())
26741 f->traverse(v);
26742 visiting(false);
26743 }
26744 return v.visit_end(this);
26745}
26746
26747/// Equality operator of the the @ref member_class_template class.
26748///
26749/// @param other the other @ref member_class_template to compare against.
26750///
26751/// @return true iff the current instance equals @p other.
26752bool
26754{
26755 try
26756 {
26757 const member_class_template& o =
26758 dynamic_cast<const member_class_template&>(other);
26759
26760 if (!member_base::operator==(o))
26761 return false;
26762
26763 return as_class_tdecl()->class_tdecl::operator==(o);
26764 }
26765 catch(...)
26766 {return false;}
26767}
26768
26769/// Equality operator of the the @ref member_class_template class.
26770///
26771/// @param other the other @ref member_class_template to compare against.
26772///
26773/// @return true iff the current instance equals @p other.
26774bool
26776{
26777 if (!decl_base::operator==(other))
26778 return false;
26779 return as_class_tdecl()->class_tdecl::operator==(other);
26780}
26781
26782/// Comparison operator for the @ref member_class_template
26783/// type.
26784///
26785/// @param other the other instance of @ref
26786/// member_class_template to compare against.
26787///
26788/// @return true iff the two instances are equal.
26789bool
26791{
26792 const decl_base* o = dynamic_cast<const decl_base*>(&other);
26793 return *this == *o;
26794}
26795
26796/// Comparison operator for the @ref member_class_template
26797/// type.
26798///
26799/// @param l the first argument of the operator.
26800///
26801/// @param r the second argument of the operator.
26802///
26803/// @return true iff the two instances are equal.
26804bool
26805operator==(const member_class_template_sptr& l,
26806 const member_class_template_sptr& r)
26807{
26808 if (l.get() == r.get())
26809 return true;
26810 if (!!l != !!r)
26811 return false;
26812
26813 return *l == *r;
26814}
26815
26816/// Inequality operator for the @ref member_class_template
26817/// type.
26818///
26819/// @param l the first argument of the operator.
26820///
26821/// @param r the second argument of the operator.
26822///
26823/// @return true iff the two instances are equal.
26824bool
26825operator!=(const member_class_template_sptr& l,
26826 const member_class_template_sptr& r)
26827{return !operator==(l, r);}
26828
26829/// This implements the ir_traversable_base::traverse pure virtual
26830/// function.
26831///
26832/// @param v the visitor used on the current instance and on the class
26833/// pattern of the template.
26834///
26835/// @return true if the entire IR node tree got traversed, false
26836/// otherwise.
26837bool
26839{
26840 if (visiting())
26841 return true;
26842
26843 if (v.visit_begin(this))
26844 {
26845 visiting(true);
26846 if (class_tdecl_sptr t = as_class_tdecl())
26847 t->traverse(v);
26848 visiting(false);
26849 }
26850 return v.visit_end(this);
26851}
26852
26853/// Streaming operator for class_decl::access_specifier.
26854///
26855/// @param o the output stream to serialize the access specifier to.
26856///
26857/// @param a the access specifier to serialize.
26858///
26859/// @return the output stream.
26860std::ostream&
26861operator<<(std::ostream& o, access_specifier a)
26862{
26863 string r;
26864
26865 switch (a)
26866 {
26867 case no_access:
26868 r = "none";
26869 break;
26870 case private_access:
26871 r = "private";
26872 break;
26873 case protected_access:
26874 r = "protected";
26875 break;
26876 case public_access:
26877 r= "public";
26878 break;
26879 };
26880 o << r;
26881 return o;
26882}
26883
26884/// Sets the static-ness property of a class member.
26885///
26886/// @param d the class member to set the static-ness property for.
26887/// Note that this must be a class member otherwise the function
26888/// aborts the current process.
26889///
26890/// @param s this must be true if the member is to be static, false
26891/// otherwise.
26892void
26894{
26896
26898 ABG_ASSERT(c);
26899
26900 c->set_is_static(s);
26901
26902 scope_decl* scope = d.get_scope();
26903
26904 if (class_or_union* cl = is_class_or_union_type(scope))
26905 {
26906 if (var_decl* v = is_var_decl(&d))
26907 {
26908 // First, find v in the set of data members.
26909 var_decl_sptr var;
26910 for (const auto& dm : cl->get_data_members())
26911 if (dm->get_name() == v->get_name())
26912 {
26913 var = dm;
26914 break;
26915 }
26916 if (!var)
26917 return;
26918
26919 if (s)
26920 {
26921 // remove from the non-static data members
26922 for (class_decl::data_members::iterator i =
26923 cl->priv_->non_static_data_members_.begin();
26924 i != cl->priv_->non_static_data_members_.end();
26925 ++i)
26926 {
26927 if ((*i)->get_name() == v->get_name())
26928 {
26929 cl->priv_->non_static_data_members_.erase(i);
26930 break;
26931 }
26932 }
26933
26934 // If it's not in the static data members, then add it
26935 // there.
26936 bool already_in_static_dms = false;
26937 for (const auto& s_dm : cl->priv_->static_data_members_)
26938 if (s_dm->get_name() == v->get_name())
26939 {
26940 already_in_static_dms = true;
26941 break;
26942 }
26943 if (!already_in_static_dms)
26944 cl->priv_->static_data_members_.push_back(var);
26945 }
26946 else // is non-static
26947 {
26948 // Remove from the static data members.
26949 for (class_or_union::data_members::iterator i =
26950 cl->priv_->static_data_members_.begin();
26951 i != cl->priv_->static_data_members_.end();
26952 ++i)
26953 if ((*i)->get_name() == v->get_name())
26954 {
26955 cl->priv_->static_data_members_.erase(i);
26956 break;
26957 }
26958
26959 // If it's not already in the non-static data members
26960 // then add it there.
26961 bool is_already_in_non_static_data_members = false;
26962 for (const auto& ns_dm : cl->priv_->non_static_data_members_)
26963 if (ns_dm->get_name() == v->get_name())
26964 {
26965 is_already_in_non_static_data_members = true;
26966 break;
26967 }
26968 if (!is_already_in_non_static_data_members)
26969 cl->priv_->non_static_data_members_.push_back(var);
26970 }
26971 }
26972 }
26973}
26974
26975/// Sets the static-ness property of a class member.
26976///
26977/// @param d the class member to set the static-ness property for.
26978/// Note that this must be a class member otherwise the function
26979/// aborts the current process.
26980///
26981/// @param s this must be true if the member is to be static, false
26982/// otherwise.
26983void
26984set_member_is_static(const decl_base_sptr& d, bool s)
26985{set_member_is_static(*d, s);}
26986
26987// </class_decl>
26988
26989// <union_decl>
26990
26991/// Constructor for the @ref union_decl type.
26992///
26993/// @param env the @ref environment we are operating from.
26994///
26995/// @param name the name of the union type.
26996///
26997/// @param size_in_bits the size of the union, in bits.
26998///
26999/// @param locus the location of the type.
27000///
27001/// @param vis the visibility of instances of @ref union_decl.
27002///
27003/// @param mbr_types the member types of the union.
27004///
27005/// @param data_mbrs the data members of the union.
27006///
27007/// @param member_fns the member functions of the union.
27008union_decl::union_decl(const environment& env, const string& name,
27009 size_t size_in_bits, const location& locus,
27010 visibility vis, member_types& mbr_types,
27011 data_members& data_mbrs, member_functions& member_fns)
27012 : type_or_decl_base(env,
27013 UNION_TYPE
27014 | ABSTRACT_TYPE_BASE
27015 | ABSTRACT_DECL_BASE),
27016 decl_base(env, name, locus, name, vis),
27017 type_base(env, size_in_bits, 0),
27018 class_or_union(env, name, size_in_bits, 0,
27019 locus, vis, mbr_types, data_mbrs, member_fns)
27020{
27022}
27023
27024/// Constructor for the @ref union_decl type.
27025///
27026/// @param env the @ref environment we are operating from.
27027///
27028/// @param name the name of the union type.
27029///
27030/// @param size_in_bits the size of the union, in bits.
27031///
27032/// @param locus the location of the type.
27033///
27034/// @param vis the visibility of instances of @ref union_decl.
27035///
27036/// @param mbr_types the member types of the union.
27037///
27038/// @param data_mbrs the data members of the union.
27039///
27040/// @param member_fns the member functions of the union.
27041///
27042/// @param is_anonymous whether the newly created instance is
27043/// anonymous.
27044union_decl::union_decl(const environment& env, const string& name,
27045 size_t size_in_bits, const location& locus,
27046 visibility vis, member_types& mbr_types,
27047 data_members& data_mbrs, member_functions& member_fns,
27048 bool is_anonymous)
27049 : type_or_decl_base(env,
27050 UNION_TYPE
27051 | ABSTRACT_TYPE_BASE
27052 | ABSTRACT_DECL_BASE),
27053 decl_base(env, name, locus,
27054 // If the class is anonymous then by default it won't
27055 // have a linkage name. Also, the anonymous class does
27056 // have an internal-only unique name that is generally
27057 // not taken into account when comparing classes; such a
27058 // unique internal-only name, when used as a linkage
27059 // name might introduce spurious comparison false
27060 // negatives.
27061 /*linkage_name=*/is_anonymous ? string() : name,
27062 vis),
27063 type_base(env, size_in_bits, 0),
27064 class_or_union(env, name, size_in_bits, 0,
27065 locus, vis, mbr_types, data_mbrs, member_fns)
27066{
27068 set_is_anonymous(is_anonymous);
27069}
27070
27071/// Constructor for the @ref union_decl type.
27072///
27073/// @param env the @ref environment we are operating from.
27074///
27075/// @param name the name of the union type.
27076///
27077/// @param size_in_bits the size of the union, in bits.
27078///
27079/// @param locus the location of the type.
27080///
27081/// @param vis the visibility of instances of @ref union_decl.
27082union_decl::union_decl(const environment& env, const string& name,
27083 size_t size_in_bits, const location& locus,
27084 visibility vis)
27085 : type_or_decl_base(env,
27086 UNION_TYPE
27087 | ABSTRACT_TYPE_BASE
27088 | ABSTRACT_DECL_BASE
27089 | ABSTRACT_SCOPE_TYPE_DECL
27090 | ABSTRACT_SCOPE_DECL),
27091 decl_base(env, name, locus, name, vis),
27092 type_base(env, size_in_bits, 0),
27093 class_or_union(env, name, size_in_bits,
27094 0, locus, vis)
27095{
27097}
27098
27099/// Constructor for the @ref union_decl type.
27100///
27101/// @param env the @ref environment we are operating from.
27102///
27103/// @param name the name of the union type.
27104///
27105/// @param size_in_bits the size of the union, in bits.
27106///
27107/// @param locus the location of the type.
27108///
27109/// @param vis the visibility of instances of @ref union_decl.
27110///
27111/// @param is_anonymous whether the newly created instance is
27112/// anonymous.
27113union_decl::union_decl(const environment& env, const string& name,
27114 size_t size_in_bits, const location& locus,
27115 visibility vis, bool is_anonymous)
27116 : type_or_decl_base(env,
27117 UNION_TYPE
27118 | ABSTRACT_TYPE_BASE
27119 | ABSTRACT_DECL_BASE
27120 | ABSTRACT_SCOPE_TYPE_DECL
27121 | ABSTRACT_SCOPE_DECL),
27122 decl_base(env, name, locus,
27123 // If the class is anonymous then by default it won't
27124 // have a linkage name. Also, the anonymous class does
27125 // have an internal-only unique name that is generally
27126 // not taken into account when comparing classes; such a
27127 // unique internal-only name, when used as a linkage
27128 // name might introduce spurious comparison false
27129 // negatives.
27130 /*linkage_name=*/is_anonymous ? string() : name,
27131 vis),
27132 type_base(env, size_in_bits, 0),
27133 class_or_union(env, name, size_in_bits,
27134 0, locus, vis)
27135{
27137 set_is_anonymous(is_anonymous);
27138}
27139
27140/// Constructor for the @ref union_decl type.
27141///
27142/// @param env the @ref environment we are operating from.
27143///
27144/// @param name the name of the union type.
27145///
27146/// @param is_declaration_only a boolean saying whether the instance
27147/// represents a declaration only, or not.
27148union_decl::union_decl(const environment& env,
27149 const string& name,
27150 bool is_declaration_only)
27151 : type_or_decl_base(env,
27152 UNION_TYPE
27153 | ABSTRACT_TYPE_BASE
27154 | ABSTRACT_DECL_BASE
27155 | ABSTRACT_SCOPE_TYPE_DECL
27156 | ABSTRACT_SCOPE_DECL),
27157 decl_base(env, name, location(), name),
27158 type_base(env, 0, 0),
27159 class_or_union(env, name, is_declaration_only)
27160{
27162}
27163
27164/// Return the hash value of the current IR node.
27165///
27166/// Note that upon the first invocation, this member functions
27167/// computes the hash value and returns it. Subsequent invocations
27168/// just return the hash value that was previously calculated.
27169///
27170/// @return the hash value of the current IR node.
27171hash_t
27173{
27175 return h;
27176}
27177
27178/// Getter of the pretty representation of the current instance of
27179/// @ref union_decl.
27180///
27181/// @param internal set to true if the call is intended to get a
27182/// representation of the decl (or type) for the purpose of canonical
27183/// type comparison. This is mainly used in the function
27184/// type_base::get_canonical_type_for().
27185///
27186/// In other words if the argument for this parameter is true then the
27187/// call is meant for internal use (for technical use inside the
27188/// library itself), false otherwise. If you don't know what this is
27189/// for, then set it to false.
27190///
27191/// @param qualified_name if true, names emitted in the pretty
27192/// representation are fully qualified.
27193///
27194/// @return the pretty representaion for a union_decl.
27195string
27197 bool qualified_name) const
27198{
27199 string repr;
27200 if (get_is_anonymous())
27201 {
27202 if (internal && !get_name().empty())
27203 repr = string("union ") +
27204 get_type_name(this, qualified_name, /*internal=*/true);
27205 else
27207 /*one_line=*/true,
27208 internal);
27209 }
27210 else
27211 {
27212 repr = "union ";
27213 if (qualified_name)
27214 repr += get_qualified_name(internal);
27215 else
27216 repr += get_name();
27217 }
27218
27219 return repr;
27220}
27221
27222/// Comparison operator for @ref union_decl.
27223///
27224/// @param other the instance of @ref union_decl to compare against.
27225///
27226/// @return true iff the current instance of @ref union_decl equals @p
27227/// other.
27228bool
27230{
27231 const union_decl* op = dynamic_cast<const union_decl*>(&other);
27232 if (!op)
27233 return false;
27234 return try_canonical_compare(this, op);
27235}
27236
27237/// Equality operator for union_decl.
27238///
27239/// Re-uses the equality operator that takes a decl_base.
27240///
27241/// @param other the other union_decl to compare against.
27242///
27243/// @return true iff the current instance equals the other one.
27244bool
27246{
27247 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27248 if (!o)
27249 return false;
27250 return *this == *o;
27251}
27252
27253/// Equality operator for union_decl.
27254///
27255/// Re-uses the equality operator that takes a decl_base.
27256///
27257/// @param other the other union_decl to compare against.
27258///
27259/// @return true iff the current instance equals the other one.
27260bool
27262{
27263 const decl_base *o = dynamic_cast<const decl_base*>(&other);
27264 return *this == *o;
27265}
27266
27267/// Comparison operator for @ref union_decl.
27268///
27269/// @param other the instance of @ref union_decl to compare against.
27270///
27271/// @return true iff the current instance of @ref union_decl equals @p
27272/// other.
27273bool
27275{
27276 const decl_base& o = other;
27277 return *this == o;
27278}
27279
27280/// This implements the ir_traversable_base::traverse pure virtual
27281/// function.
27282///
27283/// @param v the visitor used on the current instance and on its
27284/// members.
27285///
27286/// @return true if the entire IR node tree got traversed, false
27287/// otherwise.
27288bool
27290{
27291 if (v.type_node_has_been_visited(this))
27292 return true;
27293
27294 if (visiting())
27295 return true;
27296
27297 if (v.visit_begin(this))
27298 {
27299 visiting(true);
27300 bool stop = false;
27301
27302 if (!stop)
27303 for (data_members::const_iterator i = get_data_members().begin();
27304 i != get_data_members().end();
27305 ++i)
27306 if (!(*i)->traverse(v))
27307 {
27308 stop = true;
27309 break;
27310 }
27311
27312 if (!stop)
27313 for (member_functions::const_iterator i= get_member_functions().begin();
27314 i != get_member_functions().end();
27315 ++i)
27316 if (!(*i)->traverse(v))
27317 {
27318 stop = true;
27319 break;
27320 }
27321
27322 if (!stop)
27323 for (member_types::const_iterator i = get_member_types().begin();
27324 i != get_member_types().end();
27325 ++i)
27326 if (!(*i)->traverse(v))
27327 {
27328 stop = true;
27329 break;
27330 }
27331
27332 if (!stop)
27333 for (member_function_templates::const_iterator i =
27335 i != get_member_function_templates().end();
27336 ++i)
27337 if (!(*i)->traverse(v))
27338 {
27339 stop = true;
27340 break;
27341 }
27342
27343 if (!stop)
27344 for (member_class_templates::const_iterator i =
27346 i != get_member_class_templates().end();
27347 ++i)
27348 if (!(*i)->traverse(v))
27349 {
27350 stop = true;
27351 break;
27352 }
27353 visiting(false);
27354 }
27355
27356 bool result = v.visit_end(this);
27358 return result;
27359}
27360
27361/// Destructor of the @ref union_decl type.
27364
27365/// Compares two instances of @ref union_decl.
27366///
27367/// If the two intances are different, set a bitfield to give some
27368/// insight about the kind of differences there are.
27369///
27370/// @param l the first artifact of the comparison.
27371///
27372/// @param r the second artifact of the comparison.
27373///
27374/// @param k a pointer to a bitfield that gives information about the
27375/// kind of changes there are between @p l and @p r. This one is set
27376/// iff @p k is non-null and the function returns false.
27377///
27378/// Please note that setting k to a non-null value does have a
27379/// negative performance impact because even if @p l and @p r are not
27380/// equal, the function keeps up the comparison in order to determine
27381/// the different kinds of ways in which they are different.
27382///
27383/// @return true if @p l equals @p r, false otherwise.
27384bool
27386{
27387
27389
27390 {
27391 // First of all, let's see if these two types haven't already been
27392 // compared. If so, and if the result of the comparison has been
27393 // cached, let's just re-use it, rather than comparing them all
27394 // over again.
27395 bool result = false;
27396 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
27397 ABG_RETURN(result);
27398 }
27399
27400 bool result = equals(static_cast<const class_or_union&>(l),
27401 static_cast<const class_or_union&>(r),
27402 k);
27403
27405}
27406
27407/// Copy a method of a @ref union_decl into a new @ref
27408/// union_decl.
27409///
27410/// @param t the @ref union_decl into which the method is to be copied.
27411///
27412/// @param method the method to copy into @p t.
27413///
27414/// @return the resulting newly copied method.
27415method_decl_sptr
27416copy_member_function(union_decl_sptr union_type,
27417 const method_decl_sptr& f)
27418{return copy_member_function(union_type, f.get());}
27419
27420/// Copy a method of a @ref union_decl into a new @ref
27421/// union_decl.
27422///
27423/// @param t the @ref union_decl into which the method is to be copied.
27424///
27425/// @param method the method to copy into @p t.
27426///
27427/// @return the resulting newly copied method.
27428method_decl_sptr
27429copy_member_function(union_decl_sptr union_type,
27430 const method_decl* f)
27431{
27432 const class_or_union_sptr t = union_type;
27433 return copy_member_function(t, f);
27434}
27435
27436/// Turn equality of shared_ptr of union_decl into a deep equality;
27437/// that is, make it compare the pointed to objects too.
27438///
27439/// @param l the left-hand-side operand of the operator
27440///
27441/// @param r the right-hand-side operand of the operator.
27442///
27443/// @return true iff @p l equals @p r.
27444bool
27445operator==(const union_decl_sptr& l, const union_decl_sptr& r)
27446{
27447 if (l.get() == r.get())
27448 return true;
27449 if (!!l != !!r)
27450 return false;
27451
27452 return *l == *r;
27453}
27454
27455/// Turn inequality of shared_ptr of union_decl into a deep equality;
27456/// that is, make it compare the pointed to objects too.
27457///
27458/// @param l the left-hand-side operand of the operator
27459///
27460/// @param r the right-hand-side operand of the operator.
27461///
27462/// @return true iff @p l is different from @p r.
27463bool
27464operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
27465{return !operator==(l, r);}
27466// </union_decl>
27467
27468// <template_decl stuff>
27469
27470/// Data type of the private data of the @template_decl type.
27471class template_decl::priv
27472{
27473 friend class template_decl;
27474
27475 std::list<template_parameter_sptr> parms_;
27476public:
27477
27478 priv()
27479 {}
27480}; // end class template_decl::priv
27481
27482/// Add a new template parameter to the current instance of @ref
27483/// template_decl.
27484///
27485/// @param p the new template parameter to add.
27486void
27488{priv_->parms_.push_back(p);}
27489
27490/// Get the list of template parameters of the current instance of
27491/// @ref template_decl.
27492///
27493/// @return the list of template parameters.
27494const std::list<template_parameter_sptr>&
27496{return priv_->parms_;}
27497
27498/// Constructor.
27499///
27500/// @param env the environment we are operating from.
27501///
27502/// @param name the name of the template decl.
27503///
27504/// @param locus the source location where the template declaration is
27505/// defined.
27506///
27507/// @param vis the visibility of the template declaration.
27508template_decl::template_decl(const environment& env,
27509 const string& name,
27510 const location& locus,
27511 visibility vis)
27512 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
27513 decl_base(env, name, locus, /*mangled_name=*/"", vis),
27514 priv_(new priv)
27515{
27517}
27518
27519/// Destructor.
27522
27523/// Equality operator.
27524///
27525/// @param o the other instance to compare against.
27526///
27527/// @return true iff @p equals the current instance.
27528bool
27530{
27531 const template_decl* other = dynamic_cast<const template_decl*>(&o);
27532 if (!other)
27533 return false;
27534 return *this == *other;
27535}
27536
27537/// Equality operator.
27538///
27539/// @param o the other instance to compare against.
27540///
27541/// @return true iff @p equals the current instance.
27542bool
27544{
27545 try
27546 {
27547 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
27548 for (t0 = get_template_parameters().begin(),
27549 t1 = o.get_template_parameters().begin();
27550 (t0 != get_template_parameters().end()
27551 && t1 != o.get_template_parameters().end());
27552 ++t0, ++t1)
27553 {
27554 if (**t0 != **t1)
27555 return false;
27556 }
27557
27558 if (t0 != get_template_parameters().end()
27559 || t1 != o.get_template_parameters().end())
27560 return false;
27561
27562 return true;
27563 }
27564 catch(...)
27565 {return false;}
27566}
27567
27568// </template_decl stuff>
27569
27570//<template_parameter>
27571
27572/// The type of the private data of the @ref template_parameter type.
27573class template_parameter::priv
27574{
27575 friend class template_parameter;
27576
27577 unsigned index_;
27578 template_decl_wptr template_decl_;
27579 mutable bool hashing_started_;
27580 mutable bool comparison_started_;
27581
27582 priv();
27583
27584public:
27585
27586 priv(unsigned index, template_decl_sptr enclosing_template_decl)
27587 : index_(index),
27588 template_decl_(enclosing_template_decl),
27589 hashing_started_(),
27590 comparison_started_()
27591 {}
27592}; // end class template_parameter::priv
27593
27594template_parameter::template_parameter(unsigned index,
27595 template_decl_sptr enclosing_template)
27596 : priv_(new priv(index, enclosing_template))
27597 {}
27598
27599unsigned
27600template_parameter::get_index() const
27601{return priv_->index_;}
27602
27604template_parameter::get_enclosing_template_decl() const
27605{return priv_->template_decl_.lock();}
27606
27607
27608bool
27609template_parameter::operator==(const template_parameter& o) const
27610{
27611 if (get_index() != o.get_index())
27612 return false;
27613
27614 if (priv_->comparison_started_)
27615 return true;
27616
27617 bool result = false;
27618
27619 // Avoid inifite loops due to the fact that comparison the enclosing
27620 // template decl might lead to comparing this very same template
27621 // parameter with another one ...
27622 priv_->comparison_started_ = true;
27623
27624 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
27625 ;
27626 else if (get_enclosing_template_decl()
27627 && (*get_enclosing_template_decl()
27628 != *o.get_enclosing_template_decl()))
27629 ;
27630 else
27631 result = true;
27632
27633 priv_->comparison_started_ = false;
27634
27635 return result;
27636}
27637
27638/// Inequality operator.
27639///
27640/// @param other the other instance to compare against.
27641///
27642/// @return true iff the other instance is different from the current
27643/// one.
27644bool
27646{return !operator==(other);}
27647
27648/// Destructor.
27651
27652/// The type of the private data of the @ref type_tparameter type.
27653class type_tparameter::priv
27654{
27655 friend class type_tparameter;
27656}; // end class type_tparameter::priv
27657
27658/// Constructor of the @ref type_tparameter type.
27659///
27660/// @param index the index the type template parameter.
27661///
27662/// @param enclosing_tdecl the enclosing template declaration.
27663///
27664/// @param name the name of the template parameter.
27665///
27666/// @param locus the location of the declaration of this type template
27667/// parameter.
27668type_tparameter::type_tparameter(unsigned index,
27669 template_decl_sptr enclosing_tdecl,
27670 const string& name,
27671 const location& locus)
27672 : type_or_decl_base(enclosing_tdecl->get_environment(),
27673 ABSTRACT_DECL_BASE
27674 | ABSTRACT_TYPE_BASE
27675 | BASIC_TYPE),
27676 decl_base(enclosing_tdecl->get_environment(), name, locus),
27677 type_base(enclosing_tdecl->get_environment(), 0, 0),
27678 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
27679 template_parameter(index, enclosing_tdecl),
27680 priv_(new priv)
27681{
27683}
27684
27685/// Equality operator.
27686///
27687/// @param other the other template type parameter to compare against.
27688///
27689/// @return true iff @p other equals the current instance.
27690bool
27692{
27693 if (!type_decl::operator==(other))
27694 return false;
27695
27696 try
27697 {
27698 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27699 return template_parameter::operator==(o);
27700 }
27701 catch (...)
27702 {return false;}
27703}
27704
27705/// Equality operator.
27706///
27707/// @param other the other template type parameter to compare against.
27708///
27709/// @return true iff @p other equals the current instance.
27710bool
27712{
27713 if (!type_decl::operator==(other))
27714 return false;
27715
27716 try
27717 {
27718 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27719 return template_parameter::operator==(o);
27720 }
27721 catch (...)
27722 {return false;}
27723}
27724
27725/// Equality operator.
27726///
27727/// @param other the other template type parameter to compare against.
27728///
27729/// @return true iff @p other equals the current instance.
27730bool
27732{
27733 if (!decl_base::operator==(other))
27734 return false;
27735
27736 try
27737 {
27738 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
27739 return template_parameter::operator==(o);
27740 }
27741 catch (...)
27742 {return false;}
27743}
27744
27745/// Equality operator.
27746///
27747/// @param other the other template type parameter to compare against.
27748///
27749/// @return true iff @p other equals the current instance.
27750bool
27752{
27753 try
27754 {
27755 const type_base& o = dynamic_cast<const type_base&>(other);
27756 return *this == o;
27757 }
27758 catch(...)
27759 {return false;}
27760}
27761
27762/// Equality operator.
27763///
27764/// @param other the other template type parameter to compare against.
27765///
27766/// @return true iff @p other equals the current instance.
27767bool
27769{return *this == static_cast<const type_base&>(other);}
27770
27771type_tparameter::~type_tparameter()
27772{}
27773
27774/// The type of the private data of the @ref non_type_tparameter type.
27775class non_type_tparameter::priv
27776{
27777 friend class non_type_tparameter;
27778
27779 type_base_wptr type_;
27780
27781 priv();
27782
27783public:
27784
27785 priv(type_base_sptr type)
27786 : type_(type)
27787 {}
27788}; // end class non_type_tparameter::priv
27789
27790/// The constructor for the @ref non_type_tparameter type.
27791///
27792/// @param index the index of the template parameter.
27793///
27794/// @param enclosing_tdecl the enclosing template declaration that
27795/// holds this parameter parameter.
27796///
27797/// @param name the name of the template parameter.
27798///
27799/// @param type the type of the template parameter.
27800///
27801/// @param locus the location of the declaration of this template
27802/// parameter.
27803non_type_tparameter::non_type_tparameter(unsigned index,
27804 template_decl_sptr enclosing_tdecl,
27805 const string& name,
27806 type_base_sptr type,
27807 const location& locus)
27808 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
27809 decl_base(type->get_environment(), name, locus, ""),
27810 template_parameter(index, enclosing_tdecl),
27811 priv_(new priv(type))
27812{
27814}
27815
27816/// Getter for the type of the template parameter.
27817///
27818/// @return the type of the template parameter.
27819const type_base_sptr
27821{return priv_->type_.lock();}
27822
27823
27824bool
27826{
27827 if (!decl_base::operator==(other))
27828 return false;
27829
27830 try
27831 {
27832 const non_type_tparameter& o =
27833 dynamic_cast<const non_type_tparameter&>(other);
27834 return (template_parameter::operator==(o)
27835 && get_type() == o.get_type());
27836 }
27837 catch(...)
27838 {return false;}
27839}
27840
27841bool
27843{
27844 try
27845 {
27846 const decl_base& o = dynamic_cast<const decl_base&>(other);
27847 return *this == o;
27848 }
27849 catch(...)
27850 {return false;}
27851}
27852
27853non_type_tparameter::~non_type_tparameter()
27854{}
27855
27856// <template_tparameter stuff>
27857
27858/// Type of the private data of the @ref template_tparameter type.
27859class template_tparameter::priv
27860{
27861}; //end class template_tparameter::priv
27862
27863/// Constructor for the @ref template_tparameter.
27864///
27865/// @param index the index of the template parameter.
27866///
27867/// @param enclosing_tdecl the enclosing template declaration.
27868///
27869/// @param name the name of the template parameter.
27870///
27871/// @param locus the location of the declaration of the template
27872/// parameter.
27873template_tparameter::template_tparameter(unsigned index,
27874 template_decl_sptr enclosing_tdecl,
27875 const string& name,
27876 const location& locus)
27877 : type_or_decl_base(enclosing_tdecl->get_environment(),
27878 ABSTRACT_DECL_BASE
27879 | ABSTRACT_TYPE_BASE
27880 | BASIC_TYPE),
27881 decl_base(enclosing_tdecl->get_environment(), name, locus),
27882 type_base(enclosing_tdecl->get_environment(), 0, 0),
27883 type_decl(enclosing_tdecl->get_environment(), name,
27884 0, 0, locus, name, VISIBILITY_DEFAULT),
27885 type_tparameter(index, enclosing_tdecl, name, locus),
27886 template_decl(enclosing_tdecl->get_environment(), name, locus),
27887 priv_(new priv)
27888{
27890}
27891
27892/// Equality operator.
27893///
27894/// @param other the other template parameter to compare against.
27895///
27896/// @return true iff @p other equals the current instance.
27897bool
27899{
27900 try
27901 {
27902 const template_tparameter& o =
27903 dynamic_cast<const template_tparameter&>(other);
27904 return (type_tparameter::operator==(o)
27906 }
27907 catch(...)
27908 {return false;}
27909}
27910
27911/// Equality operator.
27912///
27913/// @param other the other template parameter to compare against.
27914///
27915/// @return true iff @p other equals the current instance.
27916bool
27918{
27919 try
27920 {
27921 const template_tparameter& o =
27922 dynamic_cast<const template_tparameter&>(other);
27923 return (type_tparameter::operator==(o)
27925 }
27926 catch(...)
27927 {return false;}
27928}
27929
27930bool
27932{
27933 try
27934 {
27935 const template_tparameter& other =
27936 dynamic_cast<const template_tparameter&>(o);
27937 return *this == static_cast<const type_base&>(other);
27938 }
27939 catch(...)
27940 {return false;}
27941}
27942
27943bool
27945{
27946 try
27947 {
27948 const template_tparameter& other =
27949 dynamic_cast<const template_tparameter&>(o);
27950 return type_base::operator==(other);
27951 }
27952 catch(...)
27953 {return false;}
27954}
27955
27956template_tparameter::~template_tparameter()
27957{}
27958
27959// </template_tparameter stuff>
27960
27961// <type_composition stuff>
27962
27963/// The type of the private data of the @ref type_composition type.
27964class type_composition::priv
27965{
27966 friend class type_composition;
27967
27968 type_base_wptr type_;
27969
27970 // Forbid this.
27971 priv();
27972
27973public:
27974
27975 priv(type_base_wptr type)
27976 : type_(type)
27977 {}
27978}; //end class type_composition::priv
27979
27980/// Constructor for the @ref type_composition type.
27981///
27982/// @param index the index of the template type composition.
27983///
27984/// @param tdecl the enclosing template parameter that owns the
27985/// composition.
27986///
27987/// @param t the resulting type.
27988type_composition::type_composition(unsigned index,
27989 template_decl_sptr tdecl,
27990 type_base_sptr t)
27991 : type_or_decl_base(tdecl->get_environment(),
27992 ABSTRACT_DECL_BASE),
27993 decl_base(tdecl->get_environment(), "", location()),
27994 template_parameter(index, tdecl),
27995 priv_(new priv(t))
27996{
27998}
27999
28000/// Getter for the resulting composed type.
28001///
28002/// @return the composed type.
28003const type_base_sptr
28005{return priv_->type_.lock();}
28006
28007/// Setter for the resulting composed type.
28008///
28009/// @param t the composed type.
28010void
28012{priv_->type_ = t;}
28013
28014type_composition::~type_composition()
28015{}
28016
28017// </type_composition stuff>
28018
28019//</template_parameter stuff>
28020
28021// <function_template>
28022
28023class function_tdecl::priv
28024{
28025 friend class function_tdecl;
28026
28027 function_decl_sptr pattern_;
28028 binding binding_;
28029
28030 priv();
28031
28032public:
28033
28034 priv(function_decl_sptr pattern, binding bind)
28035 : pattern_(pattern), binding_(bind)
28036 {}
28037
28038 priv(binding bind)
28039 : binding_(bind)
28040 {}
28041}; // end class function_tdecl::priv
28042
28043/// Constructor for a function template declaration.
28044///
28045/// @param env the environment we are operating from.
28046///
28047/// @param locus the location of the declaration.
28048///
28049/// @param vis the visibility of the declaration. This is the
28050/// visibility the functions instantiated from this template are going
28051/// to have.
28052///
28053/// @param bind the binding of the declaration. This is the binding
28054/// the functions instantiated from this template are going to have.
28055function_tdecl::function_tdecl(const environment& env,
28056 const location& locus,
28057 visibility vis,
28058 binding bind)
28059 : type_or_decl_base(env,
28060 ABSTRACT_DECL_BASE
28061 | TEMPLATE_DECL
28062 | ABSTRACT_SCOPE_DECL),
28063 decl_base(env, "", locus, "", vis),
28064 template_decl(env, "", locus, vis),
28065 scope_decl(env, "", locus),
28066 priv_(new priv(bind))
28067{
28069}
28070
28071/// Constructor for a function template declaration.
28072///
28073/// @param pattern the pattern of the template.
28074///
28075/// @param locus the location of the declaration.
28076///
28077/// @param vis the visibility of the declaration. This is the
28078/// visibility the functions instantiated from this template are going
28079/// to have.
28080///
28081/// @param bind the binding of the declaration. This is the binding
28082/// the functions instantiated from this template are going to have.
28083function_tdecl::function_tdecl(function_decl_sptr pattern,
28084 const location& locus,
28085 visibility vis,
28086 binding bind)
28087 : type_or_decl_base(pattern->get_environment(),
28088 ABSTRACT_DECL_BASE
28089 | TEMPLATE_DECL
28090 | ABSTRACT_SCOPE_DECL),
28091 decl_base(pattern->get_environment(), pattern->get_name(), locus,
28092 pattern->get_name(), vis),
28093 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
28094 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
28095 priv_(new priv(pattern, bind))
28096{
28098}
28099
28100/// Set a new pattern to the function template.
28101///
28102/// @param p the new pattern.
28103void
28105{
28106 priv_->pattern_ = p;
28107 add_decl_to_scope(p, this);
28108 set_name(p->get_name());
28109}
28110
28111/// Get the pattern of the function template.
28112///
28113/// @return the pattern.
28116{return priv_->pattern_;}
28117
28118/// Get the binding of the function template.
28119///
28120/// @return the binding
28123{return priv_->binding_;}
28124
28125/// Comparison operator for the @ref function_tdecl type.
28126///
28127/// @param other the other instance of @ref function_tdecl to compare against.
28128///
28129/// @return true iff the two instance are equal.
28130bool
28132{
28133 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
28134 if (o)
28135 return *this == *o;
28136 return false;
28137}
28138
28139/// Comparison operator for the @ref function_tdecl type.
28140///
28141/// @param other the other instance of @ref function_tdecl to compare against.
28142///
28143/// @return true iff the two instance are equal.
28144bool
28146{
28147 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
28148 if (o)
28149 return *this == *o;
28150 return false;
28151}
28152
28153/// Comparison operator for the @ref function_tdecl type.
28154///
28155/// @param o the other instance of @ref function_tdecl to compare against.
28156///
28157/// @return true iff the two instance are equal.
28158bool
28160{
28161 if (!(get_binding() == o.get_binding()
28162 && template_decl::operator==(o)
28163 && scope_decl::operator==(o)
28164 && !!get_pattern() == !!o.get_pattern()))
28165 return false;
28166
28167 if (get_pattern())
28168 return (*get_pattern() == *o.get_pattern());
28169
28170 return true;
28171}
28172
28173/// This implements the ir_traversable_base::traverse pure virtual
28174/// function.
28175///
28176/// @param v the visitor used on the current instance and on the
28177/// function pattern of the template.
28178///
28179/// @return true if the entire IR node tree got traversed, false
28180/// otherwise.
28181bool
28183{
28184 if (visiting())
28185 return true;
28186
28187 if (!v.visit_begin(this))
28188 {
28189 visiting(true);
28190 if (get_pattern())
28191 get_pattern()->traverse(v);
28192 visiting(false);
28193 }
28194 return v.visit_end(this);
28195}
28196
28197function_tdecl::~function_tdecl()
28198{}
28199
28200// </function_template>
28201
28202// <class template>
28203
28204/// Type of the private data of the the @ref class_tdecl type.
28205class class_tdecl::priv
28206{
28207 friend class class_tdecl;
28208 class_decl_sptr pattern_;
28209
28210public:
28211
28212 priv()
28213 {}
28214
28215 priv(class_decl_sptr pattern)
28216 : pattern_(pattern)
28217 {}
28218}; // end class class_tdecl::priv
28219
28220/// Constructor for the @ref class_tdecl type.
28221///
28222/// @param env the environment we are operating from.
28223///
28224/// @param locus the location of the declaration of the class_tdecl
28225/// type.
28226///
28227/// @param vis the visibility of the instance of class instantiated
28228/// from this template.
28229class_tdecl::class_tdecl(const environment& env,
28230 const location& locus,
28231 visibility vis)
28232 : type_or_decl_base(env,
28233 ABSTRACT_DECL_BASE
28234 | TEMPLATE_DECL
28235 | ABSTRACT_SCOPE_DECL),
28236 decl_base(env, "", locus, "", vis),
28237 template_decl(env, "", locus, vis),
28238 scope_decl(env, "", locus),
28239 priv_(new priv)
28240{
28242}
28243
28244/// Constructor for the @ref class_tdecl type.
28245///
28246/// @param pattern The details of the class template. This must NOT be a
28247/// null pointer. If you really this to be null, please use the
28248/// constructor above instead.
28249///
28250/// @param locus the source location of the declaration of the type.
28251///
28252/// @param vis the visibility of the instances of class instantiated
28253/// from this template.
28254class_tdecl::class_tdecl(class_decl_sptr pattern,
28255 const location& locus,
28256 visibility vis)
28257 : type_or_decl_base(pattern->get_environment(),
28258 ABSTRACT_DECL_BASE
28259 | TEMPLATE_DECL
28260 | ABSTRACT_SCOPE_DECL),
28261 decl_base(pattern->get_environment(), pattern->get_name(),
28262 locus, pattern->get_name(), vis),
28263 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
28264 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
28265 priv_(new priv(pattern))
28266{
28268}
28269
28270/// Setter of the pattern of the template.
28271///
28272/// @param p the new template.
28273void
28275{
28276 priv_->pattern_ = p;
28277 add_decl_to_scope(p, this);
28278 set_name(p->get_name());
28279}
28280
28281/// Getter of the pattern of the template.
28282///
28283/// @return p the new template.
28286{return priv_->pattern_;}
28287
28288bool
28290{
28291 try
28292 {
28293 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28294
28295 if (!(template_decl::operator==(o)
28296 && scope_decl::operator==(o)
28297 && !!get_pattern() == !!o.get_pattern()))
28298 return false;
28299
28300 if (!get_pattern() || !o.get_pattern())
28301 return true;
28302
28303 return get_pattern()->decl_base::operator==(*o.get_pattern());
28304 }
28305 catch(...) {}
28306 return false;
28307}
28308
28309bool
28311{
28312 try
28313 {
28314 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
28315 return *this == static_cast<const decl_base&>(o);
28316 }
28317 catch(...)
28318 {return false;}
28319}
28320
28321bool
28323{return *this == static_cast<const decl_base&>(o);}
28324
28325/// This implements the ir_traversable_base::traverse pure virtual
28326/// function.
28327///
28328/// @param v the visitor used on the current instance and on the class
28329/// pattern of the template.
28330///
28331/// @return true if the entire IR node tree got traversed, false
28332/// otherwise.
28333bool
28335{
28336 if (visiting())
28337 return true;
28338
28339 if (v.visit_begin(this))
28340 {
28341 visiting(true);
28342 if (class_decl_sptr pattern = get_pattern())
28343 pattern->traverse(v);
28344 visiting(false);
28345 }
28346 return v.visit_end(this);
28347}
28348
28349class_tdecl::~class_tdecl()
28350{}
28351
28352/// This visitor checks if a given type as non-canonicalized sub
28353/// types.
28354class non_canonicalized_subtype_detector : public ir::ir_node_visitor
28355{
28356 type_base* type_;
28357 type_base* has_non_canonical_type_;
28358
28359private:
28360 non_canonicalized_subtype_detector();
28361
28362public:
28363 non_canonicalized_subtype_detector(type_base* type)
28364 : type_(type),
28365 has_non_canonical_type_()
28366 {}
28367
28368 /// Return true if the visitor detected that there is a
28369 /// non-canonicalized sub-type.
28370 ///
28371 /// @return true if the visitor detected that there is a
28372 /// non-canonicalized sub-type.
28373 type_base*
28374 has_non_canonical_type() const
28375 {return has_non_canonical_type_;}
28376
28377 /// The intent of this visitor handler is to avoid looking into
28378 /// sub-types of member functions of the type we are traversing.
28379 bool
28380 visit_begin(function_decl* f)
28381 {
28382 // Do not look at sub-types of non-virtual member functions.
28383 if (is_member_function(f)
28385 return false;
28386 return true;
28387 }
28388
28389 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
28390 /// the 'has_non_canonical_type' flag. And in any case, when
28391 /// visiting a sub-type, do not visit its children nodes. So this
28392 /// function only goes to the level below the level of the top-most
28393 /// type.
28394 ///
28395 /// @return true if we are at the same level as the top-most type,
28396 /// otherwise return false.
28397 bool
28398 visit_begin(type_base* t)
28399 {
28400 if (t != type_)
28401 {
28402 if (!t->get_canonical_type())
28403 // We are looking a sub-type of 'type_' which has no
28404 // canonical type. So tada! we found one! Get out right
28405 // now with the trophy.
28406 has_non_canonical_type_ = t;
28407
28408 return false;
28409 }
28410 return true;
28411 }
28412
28413 /// When we are done visiting a sub-type, if it's been flagged as
28414 /// been non-canonicalized, then stop the traversing.
28415 ///
28416 /// Otherwise, keep going.
28417 ///
28418 /// @return false iff the sub-type that has been visited is
28419 /// non-canonicalized.
28420 bool
28421 visit_end(type_base* )
28422 {
28423 if (has_non_canonical_type_)
28424 return false;
28425 return true;
28426 }
28427}; //end class non_canonicalized_subtype_detector
28428
28429/// Test if a type has sub-types that are non-canonicalized.
28430///
28431/// @param t the type which sub-types to consider.
28432///
28433/// @return true if a type has sub-types that are non-canonicalized.
28434type_base*
28436{
28437 if (!t)
28438 return 0;
28439
28440 non_canonicalized_subtype_detector v(t.get());
28441 t->traverse(v);
28442 return v.has_non_canonical_type();
28443}
28444
28445/// Tests if the change of a given type effectively comes from just
28446/// its sub-types. That is, if the type has changed but its type name
28447/// hasn't changed, then the change of the type mostly likely is a
28448/// sub-type change.
28449///
28450/// @param t_v1 the first version of the type.
28451///
28452/// @param t_v2 the second version of the type.
28453///
28454/// @return true iff the type changed and the change is about its
28455/// sub-types.
28456bool
28457type_has_sub_type_changes(const type_base_sptr t_v1,
28458 const type_base_sptr t_v2)
28459{
28460 type_base_sptr t1 = strip_typedef(t_v1);
28461 type_base_sptr t2 = strip_typedef(t_v2);
28462
28463 string repr1 = get_pretty_representation(t1, /*internal=*/false),
28464 repr2 = get_pretty_representation(t2, /*internal=*/false);
28465 return (t1 != t2 && repr1 == repr2);
28466}
28467
28468/// Make sure that the life time of a given (smart pointer to a) type
28469/// is the same as the life time of the libabigail library.
28470///
28471/// @param t the type to consider.
28472void
28473keep_type_alive(type_base_sptr t)
28474{
28475 const environment& env = t->get_environment();
28476 env.priv_->extra_live_types_.push_back(t);
28477}
28478
28479/// Hash an ABI artifact that is either a type or a decl.
28480///
28481/// This function intends to provides the fastest possible hashing for
28482/// types and decls, while being completely correct.
28483///
28484/// Note that if the artifact is a type and if it has a canonical
28485/// type, the hash value is going to be the pointer value of the
28486/// canonical type. Otherwise, this function computes a hash value
28487/// for the type by recursively walking the type members. This last
28488/// code path is possibly *very* slow and should only be used when
28489/// only handful of types are going to be hashed.
28490///
28491/// If the artifact is a decl, then a combination of the hash of its
28492/// type and the hash of the other properties of the decl is computed.
28493///
28494/// @param tod the type or decl to hash.
28495///
28496/// @return the resulting hash value.
28497size_t
28499{
28500 hash_t result = 0;
28501
28502 if (tod == 0)
28503 ;
28504 else if (const type_base* t = is_type(tod))
28505 result = hash_type(t);
28506 else if (const decl_base* d = is_decl(tod))
28507 {
28508 if (const scope_decl* s = is_scope_decl(d))
28509 {
28510 if (const global_scope* g = is_global_scope(s))
28511 result = reinterpret_cast<size_t>(g);
28512 else
28513 result = reinterpret_cast<size_t>(s);
28514 }
28515 else if (var_decl* v = is_var_decl(d))
28516 {
28517 ABG_ASSERT(v->get_type());
28518 hash_t h = hash_type_or_decl(v->get_type());
28519 string repr = v->get_pretty_representation(/*internal=*/true);
28520 std::hash<string> hash_string;
28521 h = hashing::combine_hashes(h, hash_string(repr));
28522 result = h;
28523 }
28524 else if (function_decl* f = is_function_decl(d))
28525 {
28526 ABG_ASSERT(f->get_type());
28527 hash_t h = hash_type_or_decl(f->get_type());
28528 string repr = f->get_pretty_representation(/*internal=*/true);
28529 std::hash<string> hash_string;
28530 h = hashing::combine_hashes(h, hash_string(repr));
28531 result = h;
28532 }
28534 {
28535 type_base_sptr parm_type = p->get_type();
28536 ABG_ASSERT(parm_type);
28537 std::hash<bool> hash_bool;
28538 std::hash<unsigned> hash_unsigned;
28539 hash_t h = hash_type_or_decl(parm_type);
28540 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
28541 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
28542 result = h;
28543 }
28544 else if (class_decl::base_spec *bs = is_class_base_spec(d))
28545 {
28546 member_base::hash hash_member;
28547 std::hash<size_t> hash_size;
28548 std::hash<bool> hash_bool;
28549 type_base_sptr type = bs->get_base_class();
28550 hash_t h = hash_type_or_decl(type);
28551 h = hashing::combine_hashes(h, hash_member(*bs));
28552 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
28553 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
28554 result = h;
28555 }
28556 else
28557 // This is a *really* *SLOW* path. If it shows up in a
28558 // performance profile, I bet it'd be a good idea to try to
28559 // avoid it altogether.
28560 // TODO: recode this function or get rid of it altogethe.
28561 abort();
28562 }
28563 else
28564 // We should never get here.
28565 abort();
28566 return *result;
28567}
28568
28569/// Hash an ABI artifact that is a type.
28570///
28571/// This function intends to provides the fastest possible hashing for
28572/// types while being completely correct.
28573///
28574/// Note that if the type artifact has a canonical type, the hash
28575/// value is going to be the pointer value of the canonical type.
28576/// Otherwise, this function computes a hash value for the type by
28577/// recursively walking the type members. This last code path is
28578/// possibly *very* slow and should only be used when only handful of
28579/// types are going to be hashed.
28580///
28581/// @param t the type or decl to hash.
28582///
28583/// @return the resulting hash value.
28584size_t
28586{return hash_as_canonical_type_or_constant(t);}
28587
28588/// Hash an ABI artifact that is either a type of a decl.
28589///
28590/// @param tod the ABI artifact to hash.
28591///
28592/// @return the hash value of the ABI artifact.
28593size_t
28595{return hash_type_or_decl(tod.get());}
28596
28597/// Get the hash value associated to an IR node.
28598///
28599/// Unlike type_or_decl_base::hash_value(), if the IR has no
28600/// associated hash value, an empty hash value is returned.
28601///
28602/// @param artefact the IR node to consider.
28603///
28604/// @return the hash value stored on the IR node or an empty hash if
28605/// no hash value is stored in the @p artefact.
28606hash_t
28608{
28609 const type_or_decl_base* artefactp = &artefact;
28610 if (decl_base *d = is_decl(artefactp))
28611 {
28613 if (d->type_or_decl_base::priv_->get_hashing_state()
28615 return d->type_or_decl_base::priv_->hash_value_;
28616 }
28617 else if (artefact.priv_->get_hashing_state() == hashing::HASHING_FINISHED_STATE)
28618 return artefact.priv_->hash_value_;
28619
28620 return hash_t();
28621}
28622
28623/// Test if a given type is allowed to be non canonicalized
28624///
28625/// This is a subroutine of hash_as_canonical_type_or_constant.
28626///
28627/// For now, the only types allowed to be non canonicalized in the
28628/// system are (typedefs & pointers to) decl-only class/union, the
28629/// void type and variadic parameter types.
28630///
28631/// @return true iff @p t is a one of the only types allowed to be
28632/// non-canonicalized in the system.
28633bool
28635{
28636 if (!t)
28637 return true;
28638
28639 return (// The IR nodes for the types below are unique across the
28640 // entire ABI corpus. Thus, no need to canonicalize them.
28641 // Maybe we could say otherwise and canonicalize them once
28642 // for all so that they can be removed from here.
28644
28645 // An IR node for the types below can be equal to several
28646 // other types (i.e, a decl-only type t equals a fully
28647 // defined type of the same name in ODR-supported
28648 // languages). Hence, they can't be given a canonical type.
28649 //
28650 // TODO: Maybe add a mode that would detect ODR violations
28651 // that would make a decl-only type co-exists with several
28652 // different definitions of the type in the ABI corpus.
28655 /*look_through_decl_only=*/true)
28657
28658}
28659
28660/// Test if a type is unique in the entire environment.
28661///
28662/// Examples of unique types are void, void* and variadic parameter
28663/// types.
28664///
28665/// @param t the type to test for.
28666///
28667/// @return true iff the type @p t is unique in the entire
28668/// environment.
28669bool
28670is_unique_type(const type_base_sptr& t)
28671{return is_unique_type(t.get());}
28672
28673/// Test if a type is unique in the entire environment.
28674///
28675/// Examples of unique types are void, void* and variadic parameter
28676/// types.
28677///
28678/// @param t the type to test for.
28679///
28680/// @return true iff the type @p t is unique in the entire
28681/// environment.
28682bool
28684{
28685 if (!t)
28686 return false;
28687
28688 const environment& env = t->get_environment();
28689 return (env.is_void_type(t)
28690 || env.is_void_pointer_type(t)
28691 || env.is_variadic_parameter_type(t));
28692}
28693
28694/// For a given type, return its exemplar type.
28695///
28696/// For a given type, its exemplar type is either its canonical type
28697/// or the canonical type of the definition type of a given
28698/// declaration-only type. If the neither of those two types exist,
28699/// then the exemplar type is the given type itself.
28700///
28701/// @param type the input to consider.
28702///
28703/// @return the exemplar type.
28704type_base*
28706{
28707 if (decl_base * decl = is_decl(type))
28708 {
28709 // Make sure we get the real definition of a decl-only type.
28710 decl = look_through_decl_only(decl);
28711 type = is_type(decl);
28712 ABG_ASSERT(type);
28713 }
28714 type_base *exemplar = type->get_naked_canonical_type();
28715 if (!exemplar)
28716 {
28717 // The type has no canonical type. Let's be sure that it's one
28718 // of those rare types that are allowed to be non canonicalized
28719 // in the system.
28720 exemplar = const_cast<type_base*>(type);
28722 }
28723 return exemplar;
28724}
28725
28726/// Test if a given type is allowed to be non canonicalized
28727///
28728/// This is a subroutine of hash_as_canonical_type_or_constant.
28729///
28730/// For now, the only types allowed to be non canonicalized in the
28731/// system are decl-only class/union and the void type.
28732///
28733/// @return true iff @p t is a one of the only types allowed to be
28734/// non-canonicalized in the system.
28735bool
28736is_non_canonicalized_type(const type_base_sptr& t)
28737{return is_non_canonicalized_type(t.get());}
28738
28739/// Hash a type by either returning the pointer value of its canonical
28740/// type or by returning a constant if the type doesn't have a
28741/// canonical type.
28742///
28743/// This is a subroutine of hash_type.
28744///
28745/// @param t the type to consider.
28746///
28747/// @return the hash value.
28748static size_t
28749hash_as_canonical_type_or_constant(const type_base *t)
28750{
28751 type_base *canonical_type = 0;
28752
28753 if (t)
28754 canonical_type = t->get_naked_canonical_type();
28755
28756 if (!canonical_type)
28757 {
28758 // If the type doesn't have a canonical type, maybe it's because
28759 // it's a declaration-only type? If that's the case, let's try
28760 // to get the canonical type of the definition of this
28761 // declaration.
28762 decl_base *decl = is_decl(t);
28763 if (decl
28764 && decl->get_is_declaration_only()
28766 {
28767 type_base *definition =
28769 ABG_ASSERT(definition);
28770 canonical_type = definition->get_naked_canonical_type();
28771 }
28772 }
28773
28774 if (canonical_type)
28775 return reinterpret_cast<size_t>(canonical_type);
28776
28777 // If we reached this point, it means we are seeing a
28778 // non-canonicalized type. It must be a decl-only class or a void
28779 // type, otherwise it means that for some weird reason, the type
28780 // hasn't been canonicalized. It should be!
28782
28783 return 0xDEADBABE;
28784}
28785
28786/// Test if the pretty representation of a given @ref function_decl is
28787/// lexicographically less then the pretty representation of another
28788/// @ref function_decl.
28789///
28790/// @param f the first @ref function_decl to consider for comparison.
28791///
28792/// @param s the second @ref function_decl to consider for comparison.
28793///
28794/// @return true iff the pretty representation of @p f is
28795/// lexicographically less than the pretty representation of @p s.
28796bool
28798{
28801
28802 if (fr != sr)
28803 return fr < sr;
28804
28805 fr = f.get_pretty_representation(/*internal=*/true),
28806 sr = s.get_pretty_representation(/*internal=*/true);
28807
28808 if (fr != sr)
28809 return fr < sr;
28810
28811 if (f.get_symbol())
28812 fr = f.get_symbol()->get_id_string();
28813 else if (!f.get_linkage_name().empty())
28814 fr = f.get_linkage_name();
28815
28816 if (s.get_symbol())
28817 sr = s.get_symbol()->get_id_string();
28818 else if (!s.get_linkage_name().empty())
28819 sr = s.get_linkage_name();
28820
28821 return fr < sr;
28822}
28823
28824/// Test if two types have similar structures, even though they are
28825/// (or can be) different.
28826///
28827/// const and volatile qualifiers are completely ignored.
28828///
28829/// typedef are resolved to their definitions; their names are ignored.
28830///
28831/// Two indirect types (pointers or references) have similar structure
28832/// if their underlying types are of the same kind and have the same
28833/// name. In the indirect types case, the size of the underlying type
28834/// does not matter.
28835///
28836/// Two direct types (i.e, non indirect) have a similar structure if
28837/// they have the same kind, name and size. Two class types have
28838/// similar structure if they have the same name, size, and if the
28839/// types of their data members have similar types.
28840///
28841/// @param first the first type to consider.
28842///
28843/// @param second the second type to consider.
28844///
28845/// @param indirect_type whether to do an indirect comparison
28846///
28847/// @return true iff @p first and @p second have similar structures.
28848bool
28849types_have_similar_structure(const type_base_sptr& first,
28850 const type_base_sptr& second,
28851 bool indirect_type)
28852{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
28853
28854/// Test if two types have similar structures, even though they are
28855/// (or can be) different.
28856///
28857/// const and volatile qualifiers are completely ignored.
28858///
28859/// typedef are resolved to their definitions; their names are ignored.
28860///
28861/// Two indirect types (pointers, references or arrays) have similar
28862/// structure if their underlying types are of the same kind and have
28863/// the same name. In the indirect types case, the size of the
28864/// underlying type does not matter.
28865///
28866/// Two direct types (i.e, non indirect) have a similar structure if
28867/// they have the same kind, name and size. Two class types have
28868/// similar structure if they have the same name, size, and if the
28869/// types of their data members have similar types.
28870///
28871/// @param first the first type to consider.
28872///
28873/// @param second the second type to consider.
28874///
28875/// @param indirect_type if true, then consider @p first and @p
28876/// second as being underlying types of indirect types. Meaning that
28877/// their size does not matter.
28878///
28879/// @return true iff @p first and @p second have similar structures.
28880bool
28882 const type_base* second,
28883 bool indirect_type)
28884{
28885 if (!!first != !!second)
28886 return false;
28887
28888 if (!first)
28889 return false;
28890
28891 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
28892 first = peel_qualified_or_typedef_type(first);
28893 second = peel_qualified_or_typedef_type(second);
28894
28895 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
28896 // various ty2 below cannot be null.
28897 if (typeid(*first) != typeid(*second))
28898 return false;
28899
28900 // Peel off matching pointers.
28901 if (const pointer_type_def* ty1 = is_pointer_type(first))
28902 {
28903 const pointer_type_def* ty2 = is_pointer_type(second);
28904 return types_have_similar_structure(ty1->get_pointed_to_type(),
28905 ty2->get_pointed_to_type(),
28906 /*indirect_type=*/true);
28907 }
28908
28909 // Peel off matching references.
28910 if (const reference_type_def* ty1 = is_reference_type(first))
28911 {
28912 const reference_type_def* ty2 = is_reference_type(second);
28913 if (ty1->is_lvalue() != ty2->is_lvalue())
28914 return false;
28915 return types_have_similar_structure(ty1->get_pointed_to_type(),
28916 ty2->get_pointed_to_type(),
28917 /*indirect_type=*/true);
28918 }
28919
28920 // Peel off matching pointer-to-member types.
28921 if (const ptr_to_mbr_type* ty1 = is_ptr_to_mbr_type(first))
28922 {
28923 const ptr_to_mbr_type* ty2 = is_ptr_to_mbr_type(second);
28924 return (types_have_similar_structure(ty1->get_member_type(),
28925 ty2->get_member_type(),
28926 /*indirect_type=*/true)
28927 && types_have_similar_structure(ty1->get_containing_type(),
28928 ty2->get_containing_type(),
28929 /*indirect_type=*/true));
28930 }
28931
28932 if (const type_decl* ty1 = is_type_decl(first))
28933 {
28934 const type_decl* ty2 = is_type_decl(second);
28935 if (!indirect_type)
28936 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28937 return false;
28938
28939 return ty1->get_name() == ty2->get_name();
28940 }
28941
28942 if (const enum_type_decl* ty1 = is_enum_type(first))
28943 {
28944 const enum_type_decl* ty2 = is_enum_type(second);
28945 if (!indirect_type)
28946 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28947 return false;
28948
28949 return (get_name(ty1->get_underlying_type())
28950 == get_name(ty2->get_underlying_type()));
28951 }
28952
28953 if (const class_decl* ty1 = is_class_type(first))
28954 {
28955 const class_decl* ty2 = is_class_type(second);
28956 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28957 && ty1->get_name() != ty2->get_name())
28958 return false;
28959
28960 if (!indirect_type)
28961 {
28962 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
28963 || (ty1->get_non_static_data_members().size()
28964 != ty2->get_non_static_data_members().size()))
28965 return false;
28966
28967 for (class_or_union::data_members::const_iterator
28968 i = ty1->get_non_static_data_members().begin(),
28969 j = ty2->get_non_static_data_members().begin();
28970 (i != ty1->get_non_static_data_members().end()
28971 && j != ty2->get_non_static_data_members().end());
28972 ++i, ++j)
28973 {
28974 var_decl_sptr dm1 = *i;
28975 var_decl_sptr dm2 = *j;
28976 if (!types_have_similar_structure(dm1->get_type().get(),
28977 dm2->get_type().get(),
28978 indirect_type))
28979 return false;
28980 }
28981 }
28982
28983 return true;
28984 }
28985
28986 if (const union_decl* ty1 = is_union_type(first))
28987 {
28988 const union_decl* ty2 = is_union_type(second);
28989 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28990 && ty1->get_name() != ty2->get_name())
28991 return false;
28992
28993 if (!indirect_type)
28994 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
28995
28996 return true;
28997 }
28998
28999 if (const array_type_def* ty1 = is_array_type(first))
29000 {
29001 const array_type_def* ty2 = is_array_type(second);
29002 if (!indirect_type)
29003 {
29004 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
29005 || ty1->get_dimension_count() != ty2->get_dimension_count())
29006 return false;
29007
29008 // Handle int[5][2] vs int[2][5] ...
29009 //
29010 // 6.2.5/20 of
29011 // https://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
29012 // says:
29013 //
29014 // "Array types are characterized by their element
29015 // type and by the number of elements in the array"
29016 //
29017 // and 6.5.2.1/3 says:
29018 //
29019 // "arrays are stored in row-major order (last subscript
29020 // varies fastest)."
29021 //
29022 // So, let's ensure that all dimensions (sub-ranges) have
29023 // the same length.
29024
29025 for (auto r1 = ty1->get_subranges().begin(),
29026 r2 = ty1->get_subranges().begin();
29027 (r1 != ty1->get_subranges().end()
29028 && r2 != ty2->get_subranges().end());
29029 ++r1, ++r2)
29030 if ((*r1)->get_length() != (*r2)->get_length())
29031 return false;
29032 }
29033
29034 // ... then compare the elements of the arrays.
29035 if (!types_have_similar_structure(ty1->get_element_type(),
29036 ty2->get_element_type(),
29037 /*indirect_type=*/true))
29038 return false;
29039
29040 return true;
29041 }
29042
29043 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
29044 {
29046 if (ty1->get_upper_bound() != ty2->get_upper_bound()
29047 || ty1->get_lower_bound() != ty2->get_lower_bound()
29048 || ty1->get_language() != ty2->get_language()
29049 || !types_have_similar_structure(ty1->get_underlying_type(),
29050 ty2->get_underlying_type(),
29051 indirect_type))
29052 return false;
29053
29054 return true;
29055 }
29056
29057 if (const function_type* ty1 = is_function_type(first))
29058 {
29059 const function_type* ty2 = is_function_type(second);
29060 if (!types_have_similar_structure(ty1->get_return_type(),
29061 ty2->get_return_type(),
29062 indirect_type))
29063 return false;
29064
29065 if (ty1->get_parameters().size() != ty2->get_parameters().size())
29066 return false;
29067
29068 for (function_type::parameters::const_iterator
29069 i = ty1->get_parameters().begin(),
29070 j = ty2->get_parameters().begin();
29071 (i != ty1->get_parameters().end()
29072 && j != ty2->get_parameters().end());
29073 ++i, ++j)
29074 if (!types_have_similar_structure((*i)->get_type(),
29075 (*j)->get_type(),
29076 indirect_type))
29077 return false;
29078
29079 return true;
29080 }
29081
29082 // All kinds of type should have been handled at this point.
29084
29085 return false;
29086}
29087
29088/// Look for a data member of a given class, struct or union type and
29089/// return it.
29090///
29091/// The data member is designated by its name.
29092///
29093/// @param type the class, struct or union type to consider.
29094///
29095/// @param dm_name the name of the data member to lookup.
29096///
29097/// @return the data member iff it was found in @type or NULL if no
29098/// data member with that name was found.
29099const var_decl*
29101 const char* dm_name)
29102
29103{
29105 if (!cou)
29106 return 0;
29107
29108 return cou->find_data_member(dm_name).get();
29109}
29110
29111/// Look for a data member of a given class, struct or union type and
29112/// return it.
29113///
29114/// The data member is designated by its name.
29115///
29116/// @param type the class, struct or union type to consider.
29117///
29118/// @param dm the data member to lookup.
29119///
29120/// @return the data member iff it was found in @type or NULL if no
29121/// data member with that name was found.
29122const var_decl_sptr
29123lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
29124{
29125 class_or_union_sptr cou = is_class_or_union_type(type);
29126 if (!cou)
29127 return var_decl_sptr();
29128
29129 return cou->find_data_member(dm);
29130}
29131
29132/// Get the function parameter designated by its index.
29133///
29134/// Note that the first function parameter has index 0.
29135///
29136/// @param fun the function to consider.
29137///
29138/// @param parm_index the index of the function parameter to get.
29139///
29140/// @return the function parameter designated by its index, of NULL if
29141/// no function parameter with that index was found.
29144 unsigned parm_index)
29145{
29147 if (!fn)
29148 return 0;
29149
29150 const function_decl::parameters &parms = fn->get_type()->get_parameters();
29151 if (parms.size() <= parm_index)
29152 return 0;
29153
29154 return parms[parm_index].get();
29155}
29156
29157/// Build the internal name of the underlying type of an enum.
29158///
29159/// @param base_name the (unqualified) name of the enum the underlying
29160/// type is destined to.
29161///
29162/// @param is_anonymous true if the underlying type of the enum is to
29163/// be anonymous.
29164string
29166 bool is_anonymous,
29167 uint64_t size)
29168{
29169 std::ostringstream o;
29170
29171 if (is_anonymous)
29172 o << "unnamed-enum";
29173 else
29174 o << "enum-" << base_name;
29175
29176 o << "-underlying-type-" << size;
29177
29178 return o.str();
29179}
29180
29181/// Find the first data member of a class or union which name matches
29182/// a regular expression.
29183///
29184/// @param t the class or union to consider.
29185///
29186/// @param r the regular expression to consider.
29187///
29188/// @return the data member matched by @p r or nil if none was found.
29191 const regex::regex_t_sptr& r)
29192{
29193 for (auto data_member : t.get_data_members())
29194 {
29195 if (regex::match(r, data_member->get_name()))
29196 return data_member;
29197 }
29198
29199 return var_decl_sptr();
29200}
29201
29202/// Find the last data member of a class or union which name matches
29203/// a regular expression.
29204///
29205/// @param t the class or union to consider.
29206///
29207/// @param r the regular expression to consider.
29208///
29209/// @return the data member matched by @p r or nil if none was found.
29212 const regex::regex_t_sptr& regex)
29213{
29214 auto d = t.get_data_members().rbegin();
29215 auto e = t.get_data_members().rend();
29216 for (; d != e; ++d)
29217 {
29218 if (regex::match(regex, (*d)->get_name()))
29219 return *d;
29220 }
29221
29222 return var_decl_sptr();
29223}
29224
29225/// Emit the pretty representation of the parameters of a function
29226/// type.
29227///
29228/// @param fn_type the function type to consider.
29229///
29230/// @param o the output stream to emit the pretty representation to.
29231///
29232/// @param qualified if true, emit fully qualified names.
29233///
29234/// @param internal if true, then the result is to be used for the
29235/// purpose of type canonicalization.
29236static void
29237stream_pretty_representation_of_fn_parms(const function_type& fn_type,
29238 ostream& o, bool qualified,
29239 bool internal)
29240{
29241 o << "(";
29242 if (fn_type.get_parameters().empty())
29243 o << "void";
29244 else
29245 {
29246 type_base_sptr type;
29247 auto end = fn_type.get_parameters().end();
29248 auto first_parm = fn_type.get_first_non_implicit_parm();
29250 const environment& env = fn_type.get_environment();
29251 for (auto i = fn_type.get_first_non_implicit_parm(); i != end; ++i)
29252 {
29253 if (i != first_parm)
29254 o << ", ";
29255 parm = *i;
29256 type = parm->get_type();
29257 // If the type is a decl-only class, union or enum that has a
29258 // definition, use the definition instead. That definition
29259 // is what is going to be serialized out in ABIXML anyway,
29260 // so use that for consistency.
29261 if (decl_base_sptr def = look_through_decl_only(is_decl(type)))
29262 type = is_type(def);
29263 if (env.is_variadic_parameter_type(type))
29264 o << "...";
29265 else
29266 o << get_type_name(type, qualified, internal);
29267 }
29268 }
29269 o << ")";
29270}
29271
29272/// When constructing the name of a pointer to function type, add the
29273/// return type to the left of the existing type identifier, and the
29274/// parameters declarator to the right.
29275///
29276/// This function considers the name of the type as an expression.
29277///
29278/// The resulting type expr is going to be made of three parts:
29279/// left_expr inner_expr right_expr.
29280///
29281/// Suppose we want to build the type expression representing:
29282///
29283/// "an array of pointer to function taking a char parameter and
29284/// returning an int".
29285///
29286/// It's going to look like:
29287///
29288/// int(*a[])(char);
29289///
29290/// Suppose the caller of this function started to emit the inner
29291/// "a[]" part of the expression already. It thus calls this
29292/// function with that input "a[]" part. We consider that "a[]" as
29293/// the "type identifier".
29294///
29295/// So the inner_expr is going to be "(*a[])".
29296///
29297/// The left_expr part is "int". The right_expr part is "(char)".
29298///
29299/// In other words, this function adds the left_expr and right_expr to
29300/// the inner_expr. left_expr and right_expr are called "outer
29301/// pointer to function type expression".
29302///
29303/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29304/// array_declaration_name()
29305///
29306/// @param p the pointer to function type to consider.
29307///
29308/// @param input the type-id to use as the inner expression of the
29309/// overall pointer-to-function type expression
29310///
29311/// @param qualified if true then use qualified names in the resulting
29312/// type name.
29313///
29314/// @param internal if true then the resulting type name is going to
29315/// be used for type canonicalization purposes.
29316///
29317/// @return the name of the pointer to function type.
29318static string
29319add_outer_pointer_to_fn_type_expr(const type_base* p,
29320 const string& input,
29321 bool qualified, bool internal)
29322{
29323 if (!p)
29324 return "";
29325
29326 function_type_sptr pointed_to_fn;
29327 string star_or_ref;
29328
29329 if (const pointer_type_def* ptr = is_pointer_type(p))
29330 {
29331 pointed_to_fn = is_function_type(ptr->get_pointed_to_type());
29332 star_or_ref= "*";
29333 }
29334 else if (const reference_type_def* ref = is_reference_type(p))
29335 {
29336 star_or_ref = "&";
29337 pointed_to_fn = is_function_type(ref->get_pointed_to_type());
29338 }
29339
29340 if (!pointed_to_fn)
29341 return "";
29342
29343 if (pointed_to_fn->priv_->is_pretty_printing())
29344 // We have just detected a cycle while walking the sub-tree of
29345 // this function type for the purpose of printing its
29346 // representation. We need to get out of here pronto or else
29347 // we'll be spinning endlessly.
29348 return "";
29349
29350 // Let's mark thie function type to signify that we started walking
29351 // its subtree. This is to detect potential cycles and avoid
29352 // looping endlessly.
29353 pointed_to_fn->priv_->set_is_pretty_printing();
29354
29355 std::ostringstream left, right, inner;
29356
29357 inner << "(" << star_or_ref << input << ")";
29358
29359 type_base_sptr type;
29360 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
29361 qualified, internal);
29362
29363 type_base_sptr return_type = pointed_to_fn->get_return_type();
29364 string result;
29365
29366 if (is_npaf_type(return_type)
29367 || !(is_pointer_to_function_type(return_type)
29368 || is_pointer_to_array_type(return_type)))
29369 {
29370 if (return_type)
29371 left << get_type_name(return_type, qualified, internal);
29372 result = left.str() + " " + inner.str() + right.str();
29373 }
29374 else if (pointer_type_def_sptr p = is_pointer_to_function_type(return_type))
29375 {
29376 string inner_string = inner.str() + right.str();
29377 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
29378 qualified, internal);
29379 }
29380 else if (pointer_type_def_sptr p = is_pointer_to_array_type(return_type))
29381 {
29382 string inner_string = inner.str() + right.str();
29383 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29384 qualified, internal);
29385 }
29386 else
29388
29389 // Lets unmark this function type to signify that we are done
29390 // walking its subtree. This was to detect potential cycles and
29391 // avoid looping endlessly.
29392 pointed_to_fn->priv_->unset_is_pretty_printing();
29393 return result;
29394}
29395
29396/// When constructing the name of a pointer to function type, add the
29397/// return type to the left of the existing type identifier, and the
29398/// parameters declarator to the right.
29399///
29400/// This function considers the name of the type as an expression.
29401///
29402/// The resulting type expr is going to be made of three parts:
29403/// left_expr inner_expr right_expr.
29404///
29405/// Suppose we want to build the type expression representing:
29406///
29407/// "an array of pointer to function taking a char parameter and
29408/// returning an int".
29409///
29410/// It's going to look like:
29411///
29412/// int(*a[])(char);
29413///
29414/// Suppose the caller of this function started to emit the inner
29415/// "a[]" part of the expression already. It thus calls this
29416/// function with that input "a[]" part. We consider that "a[]" as
29417/// the "type identifier".
29418///
29419/// So the inner_expr is going to be "(*a[])".
29420///
29421/// The left_expr part is "int". The right_expr part is "(char)".
29422///
29423/// In other words, this function adds the left_expr and right_expr to
29424/// the inner_expr. left_expr and right_expr are called "outer
29425/// pointer to function type expression".
29426///
29427/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29428/// array_declaration_name()
29429///
29430/// @param p the pointer to function type to consider.
29431///
29432/// @param input the type-id to use as the inner expression of the
29433/// overall pointer-to-function type expression
29434///
29435/// @param qualified if true then use qualified names in the resulting
29436/// type name.
29437///
29438/// @param internal if true then the resulting type name is going to
29439/// be used for type canonicalization purposes.
29440///
29441/// @return the name of the pointer to function type.
29442static string
29443add_outer_pointer_to_fn_type_expr(const type_base_sptr& p,
29444 const string& input,
29445 bool qualified, bool internal)
29446{return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
29447
29448/// When constructing the name of a pointer to array type, add the
29449/// array element type type to the left of the existing type
29450/// identifier, and the array declarator part to the right.
29451///
29452/// This function considers the name of the type as an expression.
29453///
29454/// The resulting type expr is going to be made of three parts:
29455/// left_expr inner_expr right_expr.
29456///
29457/// Suppose we want to build the type expression representing:
29458///
29459/// "a pointer to an array of int".
29460///
29461/// It's going to look like:
29462///
29463/// int(*foo)[];
29464///
29465/// Suppose the caller of this function started to emit the inner
29466/// "foo" part of the expression already. It thus calls this function
29467/// with that input "foo" part. We consider that "foo" as the "type
29468/// identifier".
29469///
29470/// So we are passed an input string that is "foo" and it's going to
29471/// be turned into the inner_expr part, which is going to be "(*foo)".
29472///
29473/// The left_expr part is "int". The right_expr part is "[]".
29474///
29475/// In other words, this function adds the left_expr and right_expr to
29476/// the inner_expr. left_expr and right_expr are called "outer
29477/// pointer to array type expression".
29478///
29479/// The model of this function was taken from the article "Reading C
29480/// type declaration", from Steve Friedl at
29481/// http://unixwiz.net/techtips/reading-cdecl.html.
29482///
29483/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29484/// array_declaration_name()
29485///
29486/// @param p the pointer to array type to consider.
29487///
29488/// @param input the type-id to start from as the inner part of the
29489/// final type name.
29490///
29491/// @param qualified if true then use qualified names in the resulting
29492/// type name.
29493///
29494/// @param internal if true then the resulting type name is going to
29495/// be used for type canonicalization purposes.
29496///
29497/// @return the name of the pointer to array type.
29498static string
29499add_outer_pointer_to_array_type_expr(const type_base* p,
29500 const string& input, bool qualified,
29501 bool internal)
29502{
29503 if (!p)
29504 return "";
29505
29506 string star_or_ref;
29507 type_base_sptr pointed_to_type;
29508
29509 if (const pointer_type_def *ptr = is_pointer_type(p))
29510 {
29511 pointed_to_type = ptr->get_pointed_to_type();
29512 star_or_ref = "*";
29513 }
29514 else if (const reference_type_def *ref = is_reference_type(p))
29515 {
29516 pointed_to_type = ref->get_pointed_to_type();
29517 star_or_ref = "&";
29518 }
29519
29520 array_type_def_sptr array = is_array_type(pointed_to_type);
29521 if (!array)
29522 return "";
29523
29524 std::ostringstream left, right, inner;
29525 inner << "(" << star_or_ref << input << ")";
29526 right << array->get_subrange_representation();
29527 string result;
29528
29529 type_base_sptr array_element_type = array->get_element_type();
29530
29531 if (is_npaf_type(array_element_type)
29532 || !(is_pointer_to_function_type(array_element_type)
29533 || is_pointer_to_array_type(array_element_type)))
29534 {
29535 left << get_type_name(array_element_type, qualified, internal);
29536 result = left.str() + inner.str() + right.str();
29537 }
29538 else if (pointer_type_def_sptr p =
29539 is_pointer_to_function_type(array_element_type))
29540 {
29541 string r = inner.str() + right.str();
29542 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
29543 }
29544 else if (pointer_type_def_sptr p =
29545 is_pointer_to_array_type(array_element_type))
29546 {
29547 string inner_string = inner.str() + right.str();
29548 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29549 qualified, internal);
29550 }
29551 else
29553
29554 return result;
29555}
29556
29557/// When constructing the name of a pointer to array type, add the
29558/// array element type type to the left of the existing type
29559/// identifier, and the array declarator part to the right.
29560///
29561/// This function considers the name of the type as an expression.
29562///
29563/// The resulting type expr is going to be made of three parts:
29564/// left_expr inner_expr right_expr.
29565///
29566/// Suppose we want to build the type expression representing:
29567///
29568/// "a pointer to an array of int".
29569///
29570/// It's going to look like:
29571///
29572/// int(*foo)[];
29573///
29574/// Suppose the caller of this function started to emit the inner
29575/// "foo" part of the expression already. It thus calls this function
29576/// with that input "foo" part. We consider that "foo" as the "type
29577/// identifier".
29578///
29579/// So we are passed an input string that is "foo" and it's going to
29580/// be turned into the inner_expr part, which is going to be "(*foo)".
29581///
29582/// The left_expr part is "int". The right_expr part is "[]".
29583///
29584/// In other words, this function adds the left_expr and right_expr to
29585/// the inner_expr. left_expr and right_expr are called "outer
29586/// pointer to array type expression".
29587///
29588/// The model of this function was taken from the article "Reading C
29589/// type declaration", from Steve Friedl at
29590/// http://unixwiz.net/techtips/reading-cdecl.html.
29591///
29592/// This is a sub-routine of @ref pointer_declaration_name() and @ref
29593/// array_declaration_name()
29594///
29595/// @param p the pointer to array type to consider.
29596///
29597/// @param input the type-id to start from as the inner part of the
29598/// final type name.
29599///
29600/// @param qualified if true then use qualified names in the resulting
29601/// type name.
29602///
29603/// @param internal if true then the resulting type name is going to
29604/// be used for type canonicalization purposes.
29605///
29606/// @return the name of the pointer to array type.
29607static string
29608add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
29609 const string& input, bool qualified,
29610 bool internal)
29611{return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
29612 input, qualified, internal);}
29613
29614/// When constructing the name of a pointer to mebmer type, add the
29615/// return type to the left of the existing type identifier, and the
29616/// parameters declarator to the right.
29617///
29618/// This function considers the name of the type as an expression.
29619///
29620/// The resulting type expr is going to be made of three parts:
29621/// left_expr inner_expr right_expr.
29622///
29623/// Suppose we want to build the type expression representing:
29624///
29625/// "an array of pointer to member function (of a containing struct
29626/// X) taking a char parameter and returning an int".
29627///
29628/// It's going to look like:
29629///
29630/// int (X::* a[])(char);
29631///
29632/// Suppose the caller of this function started to emit the inner
29633/// "a[]" part of the expression already. It thus calls this
29634/// function with that input "a[]" part. We consider that "a[]" as
29635/// the "type identifier".
29636///
29637/// So the inner_expr is going to be "(X::* a[])".
29638///
29639/// The left_expr part is "int". The right_expr part is "(char)".
29640///
29641/// In other words, this function adds the left_expr and right_expr to
29642/// the inner_expr. left_expr and right_expr are called "outer
29643/// pointer to member type expression".
29644///
29645/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29646///
29647/// @param p the pointer to member type to consider.
29648///
29649/// @param input the type-id to use as the inner expression of the
29650/// overall pointer-to-member type expression
29651///
29652/// @param qualified if true then use qualified names in the resulting
29653/// type name.
29654///
29655/// @param internal if true then the resulting type name is going to
29656/// be used for type canonicalization purposes.
29657///
29658/// @return the name of the pointer to member type.
29659static string
29660add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
29661 const string& input, bool qualified,
29662 bool internal)
29663{
29664 if (!p)
29665 return "";
29666
29667 std::ostringstream left, right, inner;
29668 type_base_sptr void_type = p->get_environment().get_void_type();
29669 string containing_type_name = get_type_name(p->get_containing_type(),
29670 qualified, internal);
29671 type_base_sptr mbr_type = p->get_member_type();
29672 string result;
29673 if (function_type_sptr fn_type = is_function_type(mbr_type))
29674 {
29675 inner << "(" << containing_type_name << "::*" << input << ")";
29676 stream_pretty_representation_of_fn_parms(*fn_type, right,
29677 qualified, internal);
29678 type_base_sptr return_type = fn_type->get_return_type();
29679 if (!return_type)
29680 return_type = void_type;
29681 if (is_npaf_type(return_type)
29682 || !(is_pointer_to_function_type(return_type)
29683 || is_pointer_to_array_type(return_type)
29684 || is_pointer_to_ptr_to_mbr_type(return_type)
29685 || is_ptr_to_mbr_type(return_type)))
29686 {
29687 left << get_type_name(return_type, qualified, internal) << " ";;
29688 result = left.str() + inner.str() + right.str();
29689 }
29690 else if (pointer_type_def_sptr p = is_pointer_type(return_type))
29691 {
29692 string inner_str = inner.str() + right.str();
29693 result = pointer_declaration_name(p, inner_str, qualified, internal);
29694 }
29695 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(return_type))
29696 {
29697 string inner_str = inner.str() + right.str();
29698 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
29699 qualified, internal);
29700 }
29701 else
29703 }
29704 else if (ptr_to_mbr_type_sptr ptr_mbr_type = is_ptr_to_mbr_type(mbr_type))
29705 {
29706 inner << "(" << containing_type_name << "::*" << input << ")";
29707 stream_pretty_representation_of_fn_parms(*fn_type, right,
29708 qualified, internal);
29709 string inner_str = inner.str() + right.str();
29710 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
29711 qualified, internal);
29712 }
29713 else
29714 {
29715 left << get_type_name(p->get_member_type(), qualified, internal) << " ";
29716 inner << containing_type_name << "::*" << input;
29717 result = left.str()+ inner.str();
29718 }
29719
29720 return result;
29721}
29722
29723/// Test if two decls have different names.
29724///
29725/// Note that this function takes into account decls whose names are
29726/// relevant from an ABI standpoint. For instance, function parameter
29727/// names are not relevant in that context.
29728///
29729/// @param d1 the first declaration to consider.
29730///
29731/// @param d2 the second declaration to consider.
29732///
29733/// @return true if d1 and d2 have different names.
29734bool
29736{
29737 string d1_name, d2_name;
29738
29739 const decl_base *d1 = dynamic_cast<const decl_base*>(a1);
29740 if (d1 == 0)
29741 return false;
29742
29743 const decl_base *d2 = dynamic_cast<const decl_base*>(a2);
29744 if (d2 == 0)
29745 return false;
29746
29748 // Name changes for fn parms are irrelevant.
29749 return false;
29750
29751 d1_name = d1->get_qualified_name();
29752 d2_name = d2->get_qualified_name();
29753
29754 return d1_name != d2_name;
29755}
29756
29757/// Test if two decls have different names.
29758///
29759/// @param d1 the first declaration to consider.
29760///
29761/// @param d2 the second declaration to consider.
29762///
29763/// @return true if d1 and d2 have different names.
29764bool
29766 const type_or_decl_base_sptr& d2)
29767{return decl_name_changed(d1.get(), d2.get());}
29768
29769/// Test if a diff node carries a change whereby two integral types
29770/// have different names in a harmless way.
29771///
29772/// Basically, if the integral type name change is accompanied by a
29773/// size change then the change is considered harmful. If there are
29774/// modifiers change, the change is considered harmful.
29775bool
29777 const type_base_sptr& s)
29778{
29779 if (is_decl(f)
29780 && is_decl(s)
29781 && ((is_integral_type(f) && is_integral_type(s))
29782 || (is_decl(f)->get_name().empty()
29783 && is_type_decl(f)
29784 && is_integral_type(s))
29785 || (is_decl(s)->get_name().empty()
29786 && is_type_decl(s)
29787 && is_integral_type(f)))
29789 && (f->get_size_in_bits() == s->get_size_in_bits())
29790 && (f->get_alignment_in_bits() == s->get_alignment_in_bits()))
29791 return true;
29792
29793 return false;
29794}
29795
29796/// Test if a diff node carries a change whereby two integral types
29797/// have different names in a harmless way.
29798///
29799/// Basically, if the integral type name change is accompanied by a
29800/// size change then the change is considered harmful. If there are
29801/// modifiers change, the change is considered harmful.
29802bool
29804 const decl_base_sptr& s)
29806
29807
29808/// When constructing the name of a pointer to mebmer type, add the
29809/// return type to the left of the existing type identifier, and the
29810/// parameters declarator to the right.
29811///
29812/// This function considers the name of the type as an expression.
29813///
29814/// The resulting type expr is going to be made of three parts:
29815/// left_expr inner_expr right_expr.
29816///
29817/// Suppose we want to build the type expression representing:
29818///
29819/// "an array of pointer to member function (of a containing struct
29820/// X) taking a char parameter and returning an int".
29821///
29822/// It's going to look like:
29823///
29824/// int (X::* a[])(char);
29825///
29826/// Suppose the caller of this function started to emit the inner
29827/// "a[]" part of the expression already. It thus calls this
29828/// function with that input "a[]" part. We consider that "a[]" as
29829/// the "type identifier".
29830///
29831/// So the inner_expr is going to be "(X::* a[])".
29832///
29833/// The left_expr part is "int". The right_expr part is "(char)".
29834///
29835/// In other words, this function adds the left_expr and right_expr to
29836/// the inner_expr. left_expr and right_expr are called "outer
29837/// pointer to member type expression".
29838///
29839/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
29840///
29841/// @param p the pointer to member type to consider.
29842///
29843/// @param input the type-id to use as the inner expression of the
29844/// overall pointer-to-member type expression
29845///
29846/// @param qualified if true then use qualified names in the resulting
29847/// type name.
29848///
29849/// @param internal if true then the resulting type name is going to
29850/// be used for type canonicalization purposes.
29851///
29852/// @return the name of the pointer to member type.
29853static string
29854add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
29855 const string& input, bool qualified,
29856 bool internal)
29857{return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
29858
29859/// This adds the outer parts of a pointer to a pointer-to-member
29860/// expression.
29861///
29862/// Please read the comments of @ref add_outer_ptr_to_mbr_type_expr to
29863/// learn more about this function, which is similar.
29864///
29865/// This is a sub-routine of @ref pointer_declaration_name().
29866///
29867/// @param a pointer (or reference) to a pointer-to-member type.
29868///
29869/// @param input the inner type-id to add the outer parts to.
29870///
29871/// @param qualified if true then use qualified names in the resulting
29872/// type name.
29873///
29874/// @param internal if true then the resulting type name is going to
29875/// be used for type canonicalization purposes.
29876static string
29877add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
29878 const string& input, bool qualified,
29879 bool internal)
29880{
29881 if (!p)
29882 return "";
29883
29884 string star_or_ref;
29885 type_base_sptr pointed_to_type;
29886
29887 if (const pointer_type_def* ptr = is_pointer_type(p))
29888 {
29889 pointed_to_type = ptr->get_pointed_to_type();
29890 star_or_ref = "*";
29891 }
29892 else if (const reference_type_def* ref = is_reference_type(p))
29893 {
29894 pointed_to_type= ref->get_pointed_to_type();
29895 star_or_ref = "&";
29896 }
29897
29898 if (!pointed_to_type)
29899 return "";
29900
29901 ptr_to_mbr_type_sptr pointed_to_ptr_to_mbr =
29902 is_ptr_to_mbr_type(pointed_to_type);
29903 if (!pointed_to_ptr_to_mbr)
29904 return "";
29905
29906 std::ostringstream inner;
29907 inner << star_or_ref << input;
29908 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
29909 inner.str(),
29910 qualified, internal);
29911 return result;
29912}
29913
29914/// Emit the name of a pointer declaration.
29915///
29916/// @param the pointer to consider.
29917///
29918/// @param idname the name of the variable that has @p as a type or
29919/// the id of the type. If it's empty then the resulting name is
29920/// going to be the abstract name of the type.
29921///
29922/// @param qualified if true then the type name is going to be
29923/// fully qualified.
29924///
29925/// @param internal if true then the type name is going to be used for
29926/// type canonicalization purposes.
29927static interned_string
29928pointer_declaration_name(const type_base* ptr,
29929 const string& idname,
29930 bool qualified, bool internal)
29931{
29932 if (!ptr)
29933 return interned_string();
29934
29935 type_base_sptr pointed_to_type;
29936 string star_or_ref;
29937 if (const pointer_type_def* p = is_pointer_type(ptr))
29938 {
29939 pointed_to_type = p->get_pointed_to_type();
29940 star_or_ref = "*";
29941 }
29942 else if (const reference_type_def* p = is_reference_type(ptr))
29943 {
29944 pointed_to_type = p->get_pointed_to_type();
29945 star_or_ref = "&";
29946 }
29947
29948 if (!pointed_to_type)
29949 return interned_string();
29950
29951 string result;
29952 if (is_npaf_type(pointed_to_type)
29953 || !(is_function_type(pointed_to_type)
29954 || is_array_type(pointed_to_type)
29955 || is_ptr_to_mbr_type(pointed_to_type)))
29956 {
29957 result = get_type_name(pointed_to_type,
29958 qualified,
29959 internal)
29960 + star_or_ref;
29961
29962 if (!idname.empty())
29963 result += idname;
29964 }
29965 else
29966 {
29967 // derived type
29968 if (is_function_type(pointed_to_type))
29969 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
29970 qualified, internal);
29971 else if (is_array_type(pointed_to_type))
29972 result = add_outer_pointer_to_array_type_expr(ptr, idname,
29973 qualified, internal);
29974 else if (is_ptr_to_mbr_type(pointed_to_type))
29975 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
29976 qualified, internal);
29977 else
29979 }
29980 return ptr->get_environment().intern(result);
29981}
29982
29983
29984/// Emit the name of a pointer declaration.
29985///
29986/// @param the pointer to consider.
29987///
29988/// @param the name of the variable that has @p as a type. If it's
29989/// empty then the resulting name is going to be the abstract name of
29990/// the type.
29991///
29992/// @param qualified if true then the type name is going to be
29993/// fully qualified.
29994///
29995/// @param internal if true then the type name is going to be used for
29996/// type canonicalization purposes.
29997static interned_string
29998pointer_declaration_name(const type_base_sptr& ptr,
29999 const string& variable_name,
30000 bool qualified, bool internal)
30001{return pointer_declaration_name(ptr.get(), variable_name,
30002 qualified, internal);}
30003
30004/// Emit the name of a array declaration.
30005///
30006/// @param the array to consider.
30007///
30008/// @param the name of the variable that has @p as a type. If it's
30009/// empty then the resulting name is going to be the abstract name of
30010/// the type.
30011///
30012/// @param qualified if true then the type name is going to be
30013/// fully qualified.
30014///
30015/// @param internal if true then the type name is going to be used for
30016/// type canonicalization purposes.
30017static interned_string
30018array_declaration_name(const array_type_def* array,
30019 const string& variable_name,
30020 bool qualified, bool internal)
30021{
30022 if (!array)
30023 return interned_string();
30024
30025 type_base_sptr e_type = array->get_element_type();
30026 string e_type_repr =
30027 (e_type
30028 ? get_type_name(e_type, qualified, internal)
30029 : string("void"));
30030
30031 string result;
30032 if (is_ada_language(array->get_language()))
30033 {
30034 std::ostringstream o;
30035 if (!variable_name.empty())
30036 o << variable_name << " is ";
30037 o << "array ("
30038 << array->get_subrange_representation()
30039 << ") of " << e_type_repr;
30040 result = o.str();
30041 }
30042 else
30043 {
30044 if (is_npaf_type(e_type)
30045 || !(is_pointer_to_function_type(e_type)
30046 || is_pointer_to_array_type(e_type)
30048 || is_ptr_to_mbr_type(e_type)))
30049 {
30050 result = e_type_repr;
30051 if (!variable_name.empty())
30052 result += variable_name;
30053 result += array->get_subrange_representation();
30054 }
30055 else if (pointer_type_def_sptr p = is_pointer_type(e_type))
30056 {
30057 string s = variable_name + array->get_subrange_representation();
30058 result = pointer_declaration_name(p, s, qualified, internal);
30059 }
30060 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(e_type))
30061 {
30062 string s = variable_name + array->get_subrange_representation();
30063 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
30064 }
30065 else
30067 }
30068 return array->get_environment().intern(result);
30069}
30070
30071/// Emit the name of a array declaration.
30072///
30073/// @param the array to consider.
30074///
30075/// @param the name of the variable that has @p as a type. If it's
30076/// empty then the resulting name is going to be the abstract name of
30077/// the type.
30078///
30079/// @param qualified if true then the type name is going to be
30080/// fully qualified.
30081///
30082/// @param internal if true then the type name is going to be used for
30083/// type canonicalization purposes.
30084static interned_string
30085array_declaration_name(const array_type_def_sptr& array,
30086 const string& variable_name,
30087 bool qualified, bool internal)
30088{return array_declaration_name(array.get(), variable_name,
30089 qualified, internal);}
30090
30091/// Emit the name of a pointer-to-member declaration.
30092///
30093/// @param ptr the pointer-to-member to consider.
30094///
30095/// @param variable_name the name of the variable that has @p as a
30096/// type. If it's empty then the resulting name is going to be the
30097/// abstract name of the type.
30098///
30099/// @param qualified if true then the type name is going to be
30100/// fully qualified.
30101///
30102/// @param internal if true then the type name is going to be used for
30103/// type canonicalization purposes.
30104static interned_string
30105ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
30106 const string& variable_name,
30107 bool qualified, bool internal)
30108{
30109 if (!ptr)
30110 return interned_string();
30111
30112 string input = variable_name;
30113 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
30114 qualified, internal);
30115 return ptr->get_environment().intern(result);
30116}
30117
30118/// Emit the name of a pointer-to-member declaration.
30119///
30120/// @param ptr the pointer-to-member to consider.
30121///
30122/// @param variable_name the name of the variable that has @p as a
30123/// type. If it's empty then the resulting name is going to be the
30124/// abstract name of the type.
30125///
30126/// @param qualified if true then the type name is going to be
30127/// fully qualified.
30128///
30129/// @param internal if true then the type name is going to be used for
30130/// type canonicalization purposes.
30131static interned_string
30132ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
30133 const string& variable_name,
30134 bool qualified, bool internal)
30135{
30136 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
30137 qualified, internal);
30138}
30139
30140/// Sort types right before hashing and canonicalizing them.
30141///
30142/// @param types the vector of types to sort.
30143void
30144sort_types_for_hash_computing_and_c14n(vector<type_base_sptr>& types)
30145{
30146 sort_types_for_hash_computing_and_c14n(types.begin(), types.end());
30147}
30148
30149bool
30152
30153// <ir_node_visitor stuff>
30154
30155/// The private data structure of the ir_node_visitor type.
30156struct ir_node_visitor::priv
30157{
30158 pointer_set visited_ir_nodes;
30159 bool allow_visiting_already_visited_type_node;
30160
30161 priv()
30162 : allow_visiting_already_visited_type_node(true)
30163 {}
30164}; // end struct ir_node_visitory::priv
30165
30166/// Default Constructor of the ir_node_visitor type.
30168 : priv_(new priv)
30169{}
30170
30171ir_node_visitor::~ir_node_visitor() = default;
30172
30173/// Set if the walker using this visitor is allowed to re-visit a type
30174/// node that was previously visited or not.
30175///
30176/// @param f if true, then the walker using this visitor is allowed to
30177/// re-visit a type node that was previously visited.
30178void
30180{priv_->allow_visiting_already_visited_type_node = f;}
30181
30182/// Get if the walker using this visitor is allowed to re-visit a type
30183/// node that was previously visited or not.
30184///
30185/// @return true iff the walker using this visitor is allowed to
30186/// re-visit a type node that was previously visited.
30187bool
30189{return priv_->allow_visiting_already_visited_type_node;}
30190
30191/// Mark a given type node as having been visited.
30192///
30193/// Note that for this function to work, the type node must have been
30194/// canonicalized. Otherwise the process is aborted.
30195///
30196/// @param p the type to mark as having been visited.
30197void
30199{
30201 return;
30202
30203 if (p == 0 || type_node_has_been_visited(p))
30204 return;
30205
30206 type_base* canonical_type = p->get_naked_canonical_type();
30208 {
30209 ABG_ASSERT(!canonical_type);
30210 canonical_type = p;
30211 }
30212 ABG_ASSERT(canonical_type);
30213
30214 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
30215 priv_->visited_ir_nodes.insert(canonical_ptr_value);
30216}
30217
30218/// Un-mark all visited type nodes.
30219///
30220/// That is, no type node is going to be considered as having been
30221/// visited anymore.
30222///
30223/// In other words, after invoking this funciton,
30224/// ir_node_visitor::type_node_has_been_visited() is going to return
30225/// false on all type nodes.
30226void
30228{priv_->visited_ir_nodes.clear();}
30229
30230/// Test if a given type node has been marked as visited.
30231///
30232/// @param p the type node to consider.
30233///
30234/// @return true iff the type node @p p has been marked as visited by
30235/// the function ir_node_visitor::mark_type_node_as_visited.
30236bool
30238{
30240 return false;
30241
30242 if (p == 0)
30243 return false;
30244
30245 type_base *canonical_type = p->get_naked_canonical_type();
30247 {
30248 ABG_ASSERT(!canonical_type);
30249 canonical_type = p;
30250 }
30251 ABG_ASSERT(canonical_type);
30252
30253 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
30254 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
30255 if (it == priv_->visited_ir_nodes.end())
30256 return false;
30257
30258 return true;
30259}
30260
30261bool
30262ir_node_visitor::visit_begin(decl_base*)
30263{return true;}
30264
30265bool
30266ir_node_visitor::visit_end(decl_base*)
30267{return true;}
30268
30269bool
30270ir_node_visitor::visit_begin(scope_decl*)
30271{return true;}
30272
30273bool
30274ir_node_visitor::visit_end(scope_decl*)
30275{return true;}
30276
30277bool
30278ir_node_visitor::visit_begin(type_base*)
30279{return true;}
30280
30281bool
30282ir_node_visitor::visit_end(type_base*)
30283{return true;}
30284
30285bool
30286ir_node_visitor::visit_begin(scope_type_decl* t)
30287{return visit_begin(static_cast<type_base*>(t));}
30288
30289bool
30290ir_node_visitor::visit_end(scope_type_decl* t)
30291{return visit_end(static_cast<type_base*>(t));}
30292
30293bool
30294ir_node_visitor::visit_begin(type_decl* t)
30295{return visit_begin(static_cast<type_base*>(t));}
30296
30297bool
30298ir_node_visitor::visit_end(type_decl* t)
30299{return visit_end(static_cast<type_base*>(t));}
30300
30301bool
30302ir_node_visitor::visit_begin(namespace_decl* d)
30303{return visit_begin(static_cast<decl_base*>(d));}
30304
30305bool
30306ir_node_visitor::visit_end(namespace_decl* d)
30307{return visit_end(static_cast<decl_base*>(d));}
30308
30309bool
30310ir_node_visitor::visit_begin(qualified_type_def* t)
30311{return visit_begin(static_cast<type_base*>(t));}
30312
30313bool
30314ir_node_visitor::visit_end(qualified_type_def* t)
30315{return visit_end(static_cast<type_base*>(t));}
30316
30317bool
30318ir_node_visitor::visit_begin(pointer_type_def* t)
30319{return visit_begin(static_cast<type_base*>(t));}
30320
30321bool
30322ir_node_visitor::visit_end(pointer_type_def* t)
30323{return visit_end(static_cast<type_base*>(t));}
30324
30325bool
30326ir_node_visitor::visit_begin(reference_type_def* t)
30327{return visit_begin(static_cast<type_base*>(t));}
30328
30329bool
30330ir_node_visitor::visit_end(reference_type_def* t)
30331{return visit_end(static_cast<type_base*>(t));}
30332
30333bool
30334ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
30335{return visit_begin(static_cast<type_base*>(t));}
30336
30337bool
30338ir_node_visitor::visit_end(ptr_to_mbr_type* t)
30339{return visit_end(static_cast<type_base*>(t));}
30340
30341bool
30342ir_node_visitor::visit_begin(array_type_def* t)
30343{return visit_begin(static_cast<type_base*>(t));}
30344
30345bool
30346ir_node_visitor::visit_end(array_type_def* t)
30347{return visit_end(static_cast<type_base*>(t));}
30348
30349bool
30350ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
30351{return visit_begin(static_cast<type_base*>(t));}
30352
30353bool
30354ir_node_visitor::visit_end(array_type_def::subrange_type* t)
30355{return visit_end(static_cast<type_base*>(t));}
30356
30357bool
30358ir_node_visitor::visit_begin(enum_type_decl* t)
30359{return visit_begin(static_cast<type_base*>(t));}
30360
30361bool
30362ir_node_visitor::visit_end(enum_type_decl* t)
30363{return visit_end(static_cast<type_base*>(t));}
30364
30365bool
30366ir_node_visitor::visit_begin(typedef_decl* t)
30367{return visit_begin(static_cast<type_base*>(t));}
30368
30369bool
30370ir_node_visitor::visit_end(typedef_decl* t)
30371{return visit_end(static_cast<type_base*>(t));}
30372
30373bool
30374ir_node_visitor::visit_begin(function_type* t)
30375{return visit_begin(static_cast<type_base*>(t));}
30376
30377bool
30378ir_node_visitor::visit_end(function_type* t)
30379{return visit_end(static_cast<type_base*>(t));}
30380
30381bool
30382ir_node_visitor::visit_begin(var_decl* d)
30383{return visit_begin(static_cast<decl_base*>(d));}
30384
30385bool
30386ir_node_visitor::visit_end(var_decl* d)
30387{return visit_end(static_cast<decl_base*>(d));}
30388
30389bool
30390ir_node_visitor::visit_begin(function_decl* d)
30391{return visit_begin(static_cast<decl_base*>(d));}
30392
30393bool
30394ir_node_visitor::visit_end(function_decl* d)
30395{return visit_end(static_cast<decl_base*>(d));}
30396
30397bool
30398ir_node_visitor::visit_begin(function_decl::parameter* d)
30399{return visit_begin(static_cast<decl_base*>(d));}
30400
30401bool
30402ir_node_visitor::visit_end(function_decl::parameter* d)
30403{return visit_end(static_cast<decl_base*>(d));}
30404
30405bool
30406ir_node_visitor::visit_begin(function_tdecl* d)
30407{return visit_begin(static_cast<decl_base*>(d));}
30408
30409bool
30410ir_node_visitor::visit_end(function_tdecl* d)
30411{return visit_end(static_cast<decl_base*>(d));}
30412
30413bool
30414ir_node_visitor::visit_begin(class_tdecl* d)
30415{return visit_begin(static_cast<decl_base*>(d));}
30416
30417bool
30418ir_node_visitor::visit_end(class_tdecl* d)
30419{return visit_end(static_cast<decl_base*>(d));}
30420
30421bool
30422ir_node_visitor::visit_begin(class_or_union* t)
30423{return visit_begin(static_cast<type_base*>(t));}
30424
30425bool
30426ir_node_visitor::visit_end(class_or_union* t)
30427{return visit_end(static_cast<type_base*>(t));}
30428
30429bool
30430ir_node_visitor::visit_begin(class_decl* t)
30431{return visit_begin(static_cast<type_base*>(t));}
30432
30433bool
30434ir_node_visitor::visit_end(class_decl* t)
30435{return visit_end(static_cast<type_base*>(t));}
30436
30437bool
30438ir_node_visitor::visit_begin(union_decl* t)
30439{return visit_begin(static_cast<type_base*>(t));}
30440
30441bool
30442ir_node_visitor::visit_end(union_decl* t)
30443{return visit_end(static_cast<type_base*>(t));}
30444
30445bool
30446ir_node_visitor::visit_begin(class_decl::base_spec* d)
30447{return visit_begin(static_cast<decl_base*>(d));}
30448
30449bool
30450ir_node_visitor::visit_end(class_decl::base_spec* d)
30451{return visit_end(static_cast<decl_base*>(d));}
30452
30453bool
30454ir_node_visitor::visit_begin(member_function_template* d)
30455{return visit_begin(static_cast<decl_base*>(d));}
30456
30457bool
30458ir_node_visitor::visit_end(member_function_template* d)
30459{return visit_end(static_cast<decl_base*>(d));}
30460
30461bool
30462ir_node_visitor::visit_begin(member_class_template* d)
30463{return visit_begin(static_cast<decl_base*>(d));}
30464
30465bool
30466ir_node_visitor::visit_end(member_class_template* d)
30467{return visit_end(static_cast<decl_base*>(d));}
30468
30469// </ir_node_visitor stuff>
30470
30471// <debugging facilities>
30472
30473/// Generate a different string at each invocation.
30474///
30475/// @return the resulting string.
30476static string
30477get_next_string()
30478{
30479 static __thread size_t counter;
30480 ++counter;
30481 std::ostringstream o;
30482 o << counter;
30483 return o.str();
30484}
30485
30486/// A hashing functor for a @ref function_decl
30487struct function_decl_hash
30488{
30489 size_t operator()(const function_decl* f) const
30490 {return reinterpret_cast<size_t>(f);}
30491
30492 size_t operator()(const function_decl_sptr& f) const
30493 {return operator()(f.get());}
30494};
30495
30496/// Convenience typedef for a hash map of pointer to function_decl and
30497/// string.
30498typedef unordered_map<const function_decl*, string,
30499 function_decl_hash,
30501
30502/// Return a string associated to a given function. Two functions
30503/// that compare equal would yield the same string, as far as this
30504/// routine is concerned. And two functions that are different would
30505/// yield different strings.
30506///
30507/// This is used to debug core diffing issues on functions. The
30508/// sequence of strings can be given to the 'testdiff2' program that
30509/// is in the tests/ directory of the source tree, to reproduce core
30510/// diffing issues on string and thus ease the debugging.
30511///
30512/// @param fn the function to generate a string for.
30513///
30514/// @param m the function_decl* <-> string map to be used by this
30515/// function to generate strings associated to a function.
30516///
30517/// @return the resulting string.
30518static const string&
30519fn_to_str(const function_decl* fn,
30521{
30522 fns_to_str_map_type::const_iterator i = m.find(fn);
30523 if (i != m.end())
30524 return i->second;
30525 string s = get_next_string();
30526 return m[fn]= s;
30527}
30528
30529/// Generate a sequence of string that matches a given sequence of
30530/// function. In the resulting sequence, each function is "uniquely
30531/// representated" by a string. For instance, if the same function "foo"
30532/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
30533/// we don't care about the actual string) would appear at index 1 and 3.
30534///
30535/// @param begin the beginning of the sequence of functions to consider.
30536///
30537/// @param end the end of the sequence of functions. This points to
30538/// one-passed-the-end of the actual sequence.
30539///
30540/// @param m the function_decl* <-> string map to be used by this
30541/// function to generate strings associated to a function.
30542///
30543/// @param o the output stream where to emit the generated list of
30544/// strings to.
30545static void
30546fns_to_str(vector<function_decl*>::const_iterator begin,
30547 vector<function_decl*>::const_iterator end,
30549 std::ostream& o)
30550{
30551 vector<function_decl*>::const_iterator i;
30552 for (i = begin; i != end; ++i)
30553 o << "'" << fn_to_str(*i, m) << "' ";
30554}
30555
30556/// For each sequence of functions given in argument, generate a
30557/// sequence of string that matches a given sequence of function. In
30558/// the resulting sequence, each function is "uniquely representated"
30559/// by a string. For instance, if the same function "foo" appears at
30560/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30561/// care about the actual string) would appear at index 1 and 3.
30562///
30563/// @param a_begin the beginning of the sequence of functions to consider.
30564///
30565/// @param a_end the end of the sequence of functions. This points to
30566/// one-passed-the-end of the actual sequence.
30567///
30568/// @param b_begin the beginning of the second sequence of functions
30569/// to consider.
30570///
30571/// @param b_end the end of the second sequence of functions.
30572///
30573/// @param m the function_decl* <-> string map to be used by this
30574/// function to generate strings associated to a function.
30575///
30576/// @param o the output stream where to emit the generated list of
30577/// strings to.
30578static void
30579fns_to_str(vector<function_decl*>::const_iterator a_begin,
30580 vector<function_decl*>::const_iterator a_end,
30581 vector<function_decl*>::const_iterator b_begin,
30582 vector<function_decl*>::const_iterator b_end,
30584 std::ostream& o)
30585{
30586 fns_to_str(a_begin, a_end, m, o);
30587 o << "->|<- ";
30588 fns_to_str(b_begin, b_end, m, o);
30589 o << "\n";
30590}
30591
30592/// For each sequence of functions given in argument, generate a
30593/// sequence of string that matches a given sequence of function. In
30594/// the resulting sequence, each function is "uniquely representated"
30595/// by a string. For instance, if the same function "foo" appears at
30596/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
30597/// care about the actual string) would appear at index 1 and 3.
30598///
30599/// @param a_begin the beginning of the sequence of functions to consider.
30600///
30601/// @param a_end the end of the sequence of functions. This points to
30602/// one-passed-the-end of the actual sequence.
30603///
30604/// @param b_begin the beginning of the second sequence of functions
30605/// to consider.
30606///
30607/// @param b_end the end of the second sequence of functions.
30608///
30609/// @param o the output stream where to emit the generated list of
30610/// strings to.
30611void
30612fns_to_str(vector<function_decl*>::const_iterator a_begin,
30613 vector<function_decl*>::const_iterator a_end,
30614 vector<function_decl*>::const_iterator b_begin,
30615 vector<function_decl*>::const_iterator b_end,
30616 std::ostream& o)
30617{
30619 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
30620}
30621
30622// </debugging facilities>
30623
30624// </class template>
30625
30626}// end namespace ir
30627}//end namespace abigail
30628
30629namespace
30630{
30631
30632/// Update the qualified parent name, qualified name and scoped name
30633/// of a tree decl node.
30634///
30635/// @return true if the tree walking should continue, false otherwise.
30636///
30637/// @param d the tree node to take in account.
30638bool
30639qualified_name_setter::do_update(abigail::ir::decl_base* d)
30640{
30641 std::string parent_qualified_name;
30642 abigail::ir::scope_decl* parent = d->get_scope();
30643 if (parent)
30644 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
30645 else
30646 d->priv_->qualified_parent_name_ = abigail::interned_string();
30647
30648 const abigail::ir::environment& env = d->get_environment();
30649
30650 if (!d->priv_->qualified_parent_name_.empty())
30651 {
30652 if (d->get_name().empty())
30653 d->priv_->qualified_name_ = abigail::interned_string();
30654 else
30655 {
30656 d->priv_->qualified_name_ =
30657 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
30658 d->priv_->internal_qualified_name_ = env.intern(d->get_name());
30659 }
30660 }
30661 // Make sure the internal qualified name (used for type
30662 // canonicalization puroses) is always the qualified name. For
30663 // integral/real types however, only the non qualified type is used.
30664 if (!is_integral_type(d))
30665 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
30666
30667 if (d->priv_->scoped_name_.empty())
30668 {
30669 if (parent
30670 && !parent->get_is_anonymous()
30671 && !parent->get_name().empty())
30672 d->priv_->scoped_name_ =
30673 env.intern(parent->get_name() + "::" + d->get_name());
30674 else
30675 d->priv_->scoped_name_ =
30676 env.intern(d->get_name());
30677 }
30678
30679 if (!is_scope_decl(d))
30680 return false;
30681
30682 return true;
30683}
30684
30685/// This is called when we start visiting a decl node, during the
30686/// udpate of the qualified name of a given sub-tree.
30687///
30688/// @param d the decl node we are visiting.
30689///
30690/// @return true iff the traversal should keep going.
30691bool
30692qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
30693{return do_update(d);}
30694
30695/// This is called when we start visiting a type node, during the
30696/// udpate of the qualified name of a given sub-tree.
30697///
30698/// @param d the decl node we are visiting.
30699///
30700/// @return true iff the traversal should keep going.
30701bool
30702qualified_name_setter::visit_begin(abigail::ir::type_base* t)
30703{
30705 return do_update(d);
30706 return false;
30707}
30708}// end anonymous namespace.
This header declares filters for the diff trees resulting from comparing ABI Corpora.
The private data and functions of the abigail::ir::corpus type.
#define ABG_RETURN_FALSE
A macro used to return the "false" boolean from DIE comparison routines.
#define ABG_RETURN(value)
A macro used to return from DIE comparison routines.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
Definition abg-fwd.h:1743
Declaration of types pertaining to the interned string pool used throughout Libabigail,...
This contains the private implementation of the suppression engine of libabigail.
#define CACHE_COMPARISON_RESULT_AND_RETURN(value)
Cache the result of a comparison between too artifacts (l & r) and return immediately.
Definition abg-ir.cc:1145
#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r)
This macro is to be used while comparing composite types that might recursively refer to themselves....
Definition abg-ir.cc:1031
Types of the main internal representation of libabigail.
Wrappers around regex types and functions.
#define ABG_ASSERT_NOT_REACHED
A macro that expands to aborting the program when executed.
This type abstracts the configuration information of the library.
Definition abg-config.h:18
bool has_string(const char *s) const
Test if the interned string pool already contains a string with a given value.
Definition abg-ir.cc:96
const char * get_string(const char *s) const
Get a pointer to the interned string which has a given value.
Definition abg-ir.cc:106
interned_string create_string(const std::string &)
Create an interned string with a given value.
Definition abg-ir.cc:123
interned_string_pool()
Default constructor.
Definition abg-ir.cc:83
~interned_string_pool()
Destructor.
Definition abg-ir.cc:132
The abstraction of an interned string.
bool empty() const
Test if the current instance of interned_string is empty.
This class is to hold the value of the bound of a subrange. The value can be either signed or unsigne...
Definition abg-ir.h:2589
void set_signed(int64_t v)
Setter of the bound value as signed.
Definition abg-ir.cc:19252
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition abg-ir.cc:19220
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition abg-ir.cc:19213
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition abg-ir.cc:19227
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition abg-ir.cc:19264
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition abg-ir.cc:19235
bound_value()
Default constructor of the array_type_def::subrange_type::bound_value class.
Definition abg-ir.cc:19185
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition abg-ir.cc:19242
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++.
Definition abg-ir.h:2574
void set_lower_bound(int64_t lb)
Setter of the lower bound.
Definition abg-ir.cc:19443
bool is_non_finite() const
Test if the length of the subrange type is infinite.
Definition abg-ir.cc:19470
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition abg-ir.cc:19436
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:19410
string as_string() const
Return a string representation of the sub range.
Definition abg-ir.cc:19492
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:19391
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:19692
bool operator!=(const decl_base &o) const
Equality operator.
Definition abg-ir.cc:19631
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition abg-ir.cc:19422
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:19402
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:19587
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition abg-ir.cc:19429
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:19670
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition abg-ir.cc:19515
uint64_t get_length() const
Getter of the length of the subrange type.
Definition abg-ir.cc:19453
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition abg-ir.cc:19485
The abstraction of an array type.
Definition abg-ir.h:2548
virtual bool is_non_finite() const
Definition abg-ir.cc:20109
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:20139
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:19799
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition abg-ir.cc:20070
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition abg-ir.cc:20085
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition abg-ir.h:2566
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:20202
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition abg-ir.cc:20229
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:20048
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
Definition abg-ir.h:2569
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of array_type_def.
Definition abg-ir.cc:19852
translation_unit::language get_language() const
Get the language of the array.
Definition abg-ir.cc:20037
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition abg-ir.cc:20095
Abstraction of a base specifier in a class declaration.
Definition abg-ir.h:4364
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
Definition abg-ir.cc:25433
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition abg-ir.cc:25440
long get_offset_in_bits() const
Getter of the offset of the base.
Definition abg-ir.cc:25447
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:25422
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:25463
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Definition abg-ir.cc:25557
Abstracts a class declaration.
Definition abg-ir.h:4174
void is_struct(bool f)
Set the "is-struct" flag of the class.
Definition abg-ir.cc:25230
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition abg-ir.cc:26013
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:25299
bool is_struct() const
Test if the class is a struct.
Definition abg-ir.cc:25237
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:26076
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition abg-ir.cc:25254
virtual ~class_decl()
Destructor of the class_decl type.
Definition abg-ir.cc:26590
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:25215
bool has_vtable() const
Test if the current instance has a vtable.
Definition abg-ir.cc:26041
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition abg-ir.cc:26055
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition abg-ir.cc:26022
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26506
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition abg-ir.h:4192
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
Definition abg-ir.cc:25244
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition abg-ir.cc:25280
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition abg-ir.cc:25304
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition abg-ir.cc:26174
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition abg-ir.cc:26354
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:25264
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition abg-ir.cc:26004
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition abg-ir.h:4193
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Getter of the pretty representation of the current instance of class_decl.
Definition abg-ir.cc:25325
The base type of class_decl and union_decl.
Definition abg-ir.h:3977
virtual size_t get_num_anonymous_member_classes() const
Get the number of anonymous member classes contained in this class.
Definition abg-ir.cc:24108
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:24349
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:24274
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition abg-ir.cc:24377
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
Definition abg-ir.cc:23994
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition abg-ir.cc:24453
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition abg-ir.cc:24093
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition abg-ir.cc:24126
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
Definition abg-ir.cc:24467
unordered_map< ssize_t, member_functions > virtual_mem_fn_map_type
Convenience typedef.
Definition abg-ir.h:4009
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition abg-ir.h:4008
const data_members & get_data_members() const
Get the data members of this class_or_union.
Definition abg-ir.cc:24233
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:23884
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:24175
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:24428
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:24412
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition abg-ir.cc:24077
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
Definition abg-ir.cc:24509
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:23982
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:23900
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition abg-ir.cc:24481
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
Definition abg-ir.cc:24324
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:24386
const data_members & get_static_data_members() const
Get the static data memebers of this class_or_union.
Definition abg-ir.cc:24332
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:24019
vector< var_decl_sptr > data_members
Convenience typedef.
Definition abg-ir.h:4007
virtual ~class_or_union()
Destrcutor of the class_or_union type.
Definition abg-ir.cc:23973
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:24543
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition abg-ir.cc:26893
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition abg-ir.cc:24045
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition abg-ir.cc:24460
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition abg-ir.cc:24061
vector< type_base_sptr > member_types
Convenience typedef.
Definition abg-ir.h:4006
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
Definition abg-ir.cc:24144
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:24244
Abstract a class template.
Definition abg-ir.h:3797
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition abg-ir.cc:28285
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
Definition abg-ir.cc:28274
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:28334
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:28289
The abstraction of the relationship between an entity and its containing scope (its context)....
Definition abg-ir.h:1285
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition abg-corpus.h:25
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr<exported_decls_builder>.
Definition abg-corpus.h:45
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
origin get_origin() const
Getter for the origin of the corpus.
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
type_maps & get_type_per_loc_map()
Get the maps that associate a location string to a certain kind of type.
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
const environment & get_environment() const
Getter of the enviroment of the corpus.
The base type of all declarations.
Definition abg-ir.h:1585
void set_definition_of_declaration(const decl_base_sptr &)
Set the definition of this declaration-only decl_base.
Definition abg-ir.cc:16330
void set_is_declaration_only(bool f)
Set a flag saying if the enum_type_decl is a declaration-only enum_type_decl.
Definition abg-ir.cc:5005
virtual bool operator!=(const decl_base &) const
Inequality operator.
Definition abg-ir.cc:5220
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current decl.
Definition abg-ir.cc:4894
scope_decl * get_scope() const
Return the type containing the current decl, if any.
Definition abg-ir.cc:4792
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
Definition abg-ir.cc:4523
void set_is_in_public_symbol_table(bool)
Set the flag saying if this decl is from a symbol that is in a public symbols table,...
Definition abg-ir.cc:4585
friend bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
Definition abg-ir.cc:5575
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
Definition abg-ir.cc:4953
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
Definition abg-ir.cc:4767
const decl_base * get_naked_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
Definition abg-ir.cc:4989
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition abg-ir.cc:4823
void clear_qualified_name()
Clear the qualified name of this decl.
Definition abg-ir.cc:4516
virtual void set_name(const string &n)
Setter for the name of the decl.
Definition abg-ir.cc:4655
const location & get_location() const
Get the location of a given declaration.
Definition abg-ir.cc:4605
binding
ELF binding.
Definition abg-ir.h:1636
typedef_decl_sptr get_naming_typedef() const
Getter for the naming typedef of the current decl.
Definition abg-ir.cc:4715
virtual const interned_string & get_name() const
Getter for the name of the current decl.
Definition abg-ir.cc:4811
virtual void set_scope(scope_decl *)
Setter of the scope of the current decl.
Definition abg-ir.cc:5247
const interned_string & peek_qualified_name() const
Getter for the qualified name.
Definition abg-ir.cc:4507
const context_rel * get_context_rel() const
Getter for the context relationship.
Definition abg-ir.cc:4557
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Definition abg-ir.cc:4668
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scpe)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition abg-ir.cc:8450
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
Definition abg-ir.cc:4945
const decl_base_sptr get_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
Definition abg-ir.cc:4973
friend void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition abg-ir.cc:5544
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
Definition abg-ir.cc:4733
void set_location(const location &l)
Set the location for a given declaration.
Definition abg-ir.cc:4643
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
Definition abg-ir.cc:4678
void set_visibility(visibility v)
Setter for the visibility of the decl.
Definition abg-ir.cc:4784
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
Definition abg-ir.cc:4550
visibility get_visibility() const
Getter for the visibility of the decl.
Definition abg-ir.cc:4777
visibility
ELF visibility.
Definition abg-ir.h:1626
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Definition abg-ir.cc:4996
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:5236
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition abg-ir.cc:4961
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition abg-ir.cc:4760
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition abg-ir.cc:5515
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition abg-ir.cc:6641
virtual ~decl_base()
Destructor of the decl_base type.
Definition abg-ir.cc:5224
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:5209
const interned_string & get_qualified_parent_name() const
Return a copy of the qualified name of the parent of the current decl.
Definition abg-ir.cc:4804
bool get_is_anonymous_or_has_anonymous_parent() const
Definition abg-ir.cc:4701
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
Definition abg-ir.cc:4690
bool get_is_in_public_symbol_table() const
Test if the decl is defined in a ELF symbol table as a public symbol.
Definition abg-ir.cc:4577
friend bool equals(const decl_base &, const decl_base &, change_kind *)
Compares two instances of decl_base.
Definition abg-ir.cc:5138
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
Definition abg-ir.cc:4536
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representatin of the current declaration.
Definition abg-ir.cc:4846
The abstraction for a data member context relationship. This relates a data member to its parent clas...
Definition abg-ir.h:3003
const var_decl * get_anonymous_data_member() const
Return a non-nil value if this data member context relationship has an anonymous data member....
Definition abg-ir.cc:3344
void set_anonymous_data_member(var_decl *)
Set the containing anonymous data member of this data member context relationship....
Definition abg-ir.cc:3354
The abstraction of the version of an ELF symbol.
Definition abg-ir.h:1232
version & operator=(const version &o)
Assign a version to the current one.
Definition abg-ir.cc:3257
bool operator==(const version &o) const
Compares the current version against another one.
Definition abg-ir.cc:3239
bool is_default() const
Getter for the 'is_default' property of the version.
Definition abg-ir.cc:3219
const string & str() const
Getter for the version name.
Definition abg-ir.cc:3205
bool operator!=(const version &o) const
Inequality operator.
Definition abg-ir.cc:3248
Abstraction of an elf symbol.
Definition abg-ir.h:961
const abg_compat::optional< std::string > & get_namespace() const
Getter of the 'namespace' property.
Definition abg-ir.cc:2342
elf_symbol_sptr get_alias_which_equals(const elf_symbol &other) const
In the list of aliases of a given elf symbol, get the alias that equals this current symbol.
Definition abg-ir.cc:2665
elf_symbol_sptr get_next_common_instance() const
Get the next common instance of the current common symbol.
Definition abg-ir.cc:2560
type get_type() const
Getter for the type of the current instance of elf_symbol.
Definition abg-ir.cc:2176
const elf_symbol_sptr get_main_symbol() const
Get the main symbol of an alias chain.
Definition abg-ir.cc:2397
void set_is_in_ksymtab(bool is_in_ksymtab)
Setter of the 'is-in-ksymtab' property.
Definition abg-ir.cc:2321
bool has_aliases() const
Check if the current elf_symbol has an alias.
Definition abg-ir.cc:2426
void set_name(const string &n)
Setter for the name of the current intance of elf_symbol.
Definition abg-ir.cc:2166
bool is_suppressed() const
Getter for the 'is-suppressed' property.
Definition abg-ir.cc:2358
binding
The binding of a symbol.
Definition abg-ir.h:978
int get_number_of_aliases() const
Get the number of aliases to this elf symbol.
Definition abg-ir.cc:2433
string get_aliases_id_string(const string_elf_symbols_map_type &symtab, bool include_symbol_itself=true) const
Return a comma separated list of the id of the current symbol as well as the id string of its aliases...
Definition abg-ir.cc:2686
void set_binding(binding b)
Setter for the binding of the current instance of elf_symbol.
Definition abg-ir.cc:2211
void add_common_instance(const elf_symbol_sptr &)
Add a common instance to the current common elf symbol.
Definition abg-ir.cc:2571
void add_alias(const elf_symbol_sptr &)
Add an alias to the current elf symbol.
Definition abg-ir.cc:2450
void set_is_suppressed(bool is_suppressed)
Setter for the 'is-suppressed' property.
Definition abg-ir.cc:2367
bool is_variable() const
Test if the current instance of elf_symbol is a variable symbol or not.
Definition abg-ir.cc:2299
elf_symbol_sptr update_main_symbol(const std::string &)
Update the main symbol for a group of aliased symbols.
Definition abg-ir.cc:2496
void set_size(size_t)
Setter of the size of the symbol.
Definition abg-ir.cc:2197
const string & get_name() const
Getter for the name of the elf_symbol.
Definition abg-ir.cc:2159
binding get_binding() const
Getter for the binding of the current instance of elf_symbol.
Definition abg-ir.cc:2204
static bool get_name_and_version_from_id(const string &id, string &name, string &ver)
Given the ID of a symbol, get the name and the version of said symbol.
Definition abg-ir.cc:2752
bool is_function() const
Test if the current instance of elf_symbol is a function symbol or not.
Definition abg-ir.cc:2290
type
The type of a symbol.
Definition abg-ir.h:965
void set_version(const version &v)
Setter for the version of the current instance of elf_symbol.
Definition abg-ir.cc:2225
const abg_compat::optional< uint32_t > & get_crc() const
Getter of the 'crc' property.
Definition abg-ir.cc:2328
void set_visibility(visibility v)
Setter of the visibility of the current instance of elf_symbol.
Definition abg-ir.cc:2236
bool does_alias(const elf_symbol &) const
Test if the current symbol aliases another one.
Definition abg-ir.cc:2811
bool is_main_symbol() const
Tests whether this symbol is the main symbol.
Definition abg-ir.cc:2411
void set_crc(const abg_compat::optional< uint32_t > &crc)
Setter of the 'crc' property.
Definition abg-ir.cc:2335
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
Definition abg-ir.cc:2063
visibility
The visibility of the symbol.
Definition abg-ir.h:987
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition abg-ir.cc:2218
bool is_common_symbol() const
Return true if the symbol is a common one.
Definition abg-ir.cc:2529
void set_index(size_t)
Setter for the index.
Definition abg-ir.cc:2152
visibility get_visibility() const
Getter of the visibility of the current instance of elf_symbol.
Definition abg-ir.cc:2244
bool has_other_common_instances() const
Return true if this common common symbol has other common instances.
Definition abg-ir.cc:2545
size_t get_index() const
Getter for the index.
Definition abg-ir.cc:2145
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
Definition abg-ir.cc:2616
elf_symbol_sptr get_alias_from_name(const string &name) const
From the aliases of the current symbol, lookup one with a given name.
Definition abg-ir.cc:2643
const environment & get_environment() const
Getter of the environment used by the current instance of elf_symbol.
Definition abg-ir.cc:2138
void set_type(type t)
Setter for the type of the current instance of elf_symbol.
Definition abg-ir.cc:2183
bool is_public() const
Test if the current instance of elf_symbol is public or not.
Definition abg-ir.cc:2274
bool is_in_ksymtab() const
Getter of the 'is-in-ksymtab' property.
Definition abg-ir.cc:2313
size_t get_size() const
Getter of the size of the symbol.
Definition abg-ir.cc:2190
bool is_defined() const
Test if the current instance of elf_symbol is defined or not.
Definition abg-ir.cc:2252
void set_namespace(const abg_compat::optional< std::string > &ns)
Setter of the 'namespace' property.
Definition abg-ir.cc:2349
elf_symbol_sptr get_next_alias() const
Get the next alias of the current symbol.
Definition abg-ir.cc:2418
bool operator==(const elf_symbol &) const
Test if two main symbols are textually equal, or, if they have aliases that are textually equal.
Definition abg-ir.cc:2797
The abstraction of an enumerator.
Definition abg-ir.h:2881
enumerator()
Default constructor of the enum_type_decl::enumerator type.
Definition abg-ir.cc:20912
bool operator!=(const enumerator &other) const
Inequality operator.
Definition abg-ir.cc:20972
void set_name(const string &n)
Setter for the name of enum_type_decl::enumerator.
Definition abg-ir.cc:21014
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition abg-ir.cc:21036
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition abg-ir.cc:20981
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition abg-ir.cc:21043
void set_value(int64_t v)
Setter for the value of enum_type_decl::enumerator.
Definition abg-ir.cc:21029
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:20998
int64_t get_value() const
Getter for the value of enum_type_decl::enumerator.
Definition abg-ir.cc:21022
bool operator==(const enumerator &other) const
Equality operator.
Definition abg-ir.cc:20959
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::enumerator type.
Definition abg-ir.cc:20943
Abstracts a declaration for an enum type.
Definition abg-ir.h:2785
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition abg-ir.h:2801
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:20302
virtual ~enum_type_decl()
Destructor for the enum type declaration.
Definition abg-ir.cc:20463
const enumerators & get_enumerators() const
Definition abg-ir.cc:20315
bool find_enumerator_by_value(int64_t value, enum_type_decl::enumerator &result)
Find an enumerator by its value.
Definition abg-ir.cc:20361
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
Definition abg-ir.cc:20327
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:20441
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition abg-ir.cc:20310
bool find_enumerator_by_name(const string &name, enum_type_decl::enumerator &result)
Find an enumerator by its name.
Definition abg-ir.cc:20385
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:20833
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:20416
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition abg-ir.h:148
bool decl_only_class_equals_definition() const
Getter of the "decl-only-class-equals-definition" flag.
Definition abg-ir.cc:3591
bool is_void_pointer_type(const type_base_sptr &) const
Test if a given type is the same as the void pointer type of the environment.
Definition abg-ir.cc:3658
std::unordered_map< string, std::vector< type_base_sptr > > canonical_types_map_type
A convenience typedef for a map of canonical types. The key is the pretty representation string of a ...
Definition abg-ir.h:158
bool user_set_analyze_exported_interfaces_only() const
Getter for a property that says if the user actually did set the analyze_exported_interfaces_only() p...
Definition abg-ir.cc:3738
const vector< type_base_sptr > * get_canonical_types(const char *name) const
Get the vector of canonical types which have a given "string representation".
Definition abg-ir.cc:3875
const type_base_sptr & get_void_type() const
Get the unique type_decl that represents a "void" type for the current environment....
Definition abg-ir.cc:3468
bool is_variadic_parameter_type(const type_base *) const
Test if a type is a variadic parameter type as defined in the current environment.
Definition abg-ir.cc:3690
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
Definition abg-ir.cc:3519
const type_base_sptr & get_void_pointer_type() const
Getter of the "pointer-to-void" IR node that is shared across the ABI corpus. This node must be the o...
Definition abg-ir.cc:3487
const config & get_config() const
Getter of the general configuration object.
Definition abg-ir.cc:3728
environment()
Default constructor of the environment type.
Definition abg-ir.cc:3369
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition abg-ir.cc:3531
type_base * get_canonical_type(const char *name, unsigned index)
Get a given canonical type which has a given "string representation".
Definition abg-ir.cc:3898
const type_base_sptr & get_variadic_parameter_type() const
Get a type_decl instance that represents a the type of a variadic function parameter....
Definition abg-ir.cc:3506
bool is_void_type(const type_base_sptr &) const
Test if a given type is a void type as defined in the current environment.
Definition abg-ir.cc:3627
virtual ~environment()
Destructor for the environment type.
Definition abg-ir.cc:3374
bool canonicalization_started() const
Getter of a flag saying if the canonicalization process has started or not.
Definition abg-ir.cc:3558
interned_string intern(const string &) const
Do intern a string.
Definition abg-ir.cc:3721
bool analyze_exported_interfaces_only() const
Getter for the property that controls if we are to restrict the analysis to the types that are only r...
Definition abg-ir.cc:3764
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Definition abg-ir.cc:3382
Abstraction of a function parameter.
Definition abg-ir.h:3335
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
Definition abg-ir.cc:23718
interned_string get_type_name() const
Definition abg-ir.cc:23517
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition abg-ir.cc:23555
const string get_type_pretty_representation() const
Definition abg-ir.cc:23536
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition abg-ir.cc:23694
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:23738
Abstraction for a function declaration.
Definition abg-ir.h:3165
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition abg-ir.h:3187
string get_pretty_representation_of_declarator(bool internal=false) const
Compute and return the pretty representation for the part of the function declaration that starts at ...
Definition abg-ir.cc:22918
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition abg-ir.cc:22989
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:23379
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition abg-ir.cc:23069
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition abg-ir.cc:23294
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition abg-ir.cc:22955
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition abg-ir.cc:22974
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:22781
const type_base_sptr get_return_type() const
Definition abg-ir.cc:23050
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition abg-ir.cc:23082
const std::vector< parameter_sptr > & get_parameters() const
Definition abg-ir.cc:23055
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition abg-ir.cc:23062
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition abg-ir.cc:23011
virtual ~function_decl()
Destructor of the function_decl type.
Definition abg-ir.cc:23395
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:23027
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition abg-ir.cc:23280
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition abg-ir.h:3190
bool is_declared_inline() const
Test if the function was declared inline.
Definition abg-ir.cc:23034
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:22850
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:23310
Abstract a function template declaration.
Definition abg-ir.h:3752
binding get_binding() const
Get the binding of the function template.
Definition abg-ir.cc:28122
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
Definition abg-ir.cc:28104
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition abg-ir.cc:28115
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:28182
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition abg-ir.cc:28131
Abstraction of a function type.
Definition abg-ir.h:3420
shared_ptr< function_decl::parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition abg-ir.h:3430
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:22023
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:22442
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition abg-ir.cc:22130
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition abg-ir.cc:22339
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:21930
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition abg-ir.cc:22401
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:22115
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition abg-ir.cc:22092
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition abg-ir.cc:22359
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:22071
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition abg-ir.cc:22034
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition abg-ir.cc:22042
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition abg-ir.cc:22317
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition abg-ir.cc:22051
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition abg-ir.h:3432
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Return a copy of the pretty representation of the current function_type.
Definition abg-ir.cc:22425
This abstracts the global scope of a given translation unit.
Definition abg-ir.h:1982
The base class for the visitor type hierarchy used for traversing a translation unit.
Definition abg-ir.h:4811
bool allow_visiting_already_visited_type_node() const
Get if the walker using this visitor is allowed to re-visit a type node that was previously visited o...
Definition abg-ir.cc:30188
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition abg-ir.cc:30237
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition abg-ir.cc:30227
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition abg-ir.cc:30167
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition abg-ir.cc:30198
The entry point to manage locations.
Definition abg-ir.h:449
location create_new_location(const std::string &fle, size_t lne, size_t col)
Insert the triplet representing a source locus into our internal vector of location triplet....
Definition abg-ir.cc:507
void expand_location(const location &location, std::string &path, unsigned &line, unsigned &column) const
Given an instance of location type, return the triplet {path,line,column} that represents the source ...
Definition abg-ir.cc:530
The source location of a token.
Definition abg-ir.h:307
bool get_is_artificial() const
Test if the location is artificial.
Definition abg-ir.h:348
unsigned get_value() const
Get the value of the location.
Definition abg-ir.h:395
string expand(void) const
Expand the location into a string.
Definition abg-ir.cc:472
void expand(std::string &path, unsigned &line, unsigned &column) const
Expand the current location into a tripplet file path, line and column number.
Definition abg-ir.cc:452
Abstraction of a member function context relationship. This relates a member function to its parent c...
Definition abg-ir.h:4497
bool is_constructor() const
Getter for the 'is-constructor' property.
Definition abg-ir.h:4575
bool is_const() const
Getter for the 'is-const' property.
Definition abg-ir.h:4610
size_t vtable_offset() const
Getter for the vtable offset property.
Definition abg-ir.h:4555
bool is_destructor() const
Getter for the 'is-destructor' property.
Definition abg-ir.h:4592
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition abg-ir.h:3839
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition abg-ir.h:3859
bool get_is_static() const
Definition abg-ir.h:3871
Abstracts a member class template template.
Definition abg-ir.h:4702
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
Definition abg-ir.cc:26753
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26838
Abstract a member function template.
Definition abg-ir.h:4647
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:26732
Abstraction of the declaration of a method.
Definition abg-ir.h:3887
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
Definition abg-ir.cc:6538
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
Definition abg-ir.cc:25704
const method_type_sptr get_type() const
Definition abg-ir.cc:25731
Abstracts the type of a class member function.
Definition abg-ir.h:3506
void set_class_type(const class_or_union_sptr &t)
Sets the class type of the current instance of method_type.
Definition abg-ir.cc:22643
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:22624
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition abg-ir.cc:22675
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
Definition abg-ir.cc:22690
virtual ~method_type()
The destructor of method_type.
Definition abg-ir.cc:22723
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:22667
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition abg-ir.cc:22634
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition abg-ir.cc:22682
The abstraction of a namespace declaration.
Definition abg-ir.h:2207
bool is_empty_or_has_empty_sub_namespaces() const
Test if the current namespace_decl is empty or contains empty namespaces itself.
Definition abg-ir.cc:17451
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17482
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition abg-ir.cc:17385
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition abg-ir.cc:17437
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:17423
Abstracts non type template parameters.
Definition abg-ir.h:3662
const type_base_sptr get_type() const
Getter for the type of the template parameter.
Definition abg-ir.cc:27820
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition abg-ir.cc:27825
The abstraction of a pointer type.
Definition abg-ir.h:2350
void set_pointed_to_type(const type_base_sptr &)
Set the pointed-to type of the pointer.
Definition abg-ir.cc:18144
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:18270
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18134
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:18061
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:18364
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition abg-ir.cc:18206
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition abg-ir.cc:18250
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition abg-ir.cc:18257
The abstraction of a pointer-to-member type.
Definition abg-ir.h:2485
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Get the qualified name for the current ptr_to_mbr_type.
Definition abg-ir.cc:19034
virtual const interned_string & get_name() const
Getter of the name of the current ptr-to-mbr-type.
Definition abg-ir.cc:18944
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18957
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:18977
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
Definition abg-ir.cc:19018
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:19085
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
Definition abg-ir.cc:18968
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
Definition abg-ir.cc:19110
The abstraction of a qualified type.
Definition abg-ir.h:2236
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation for the virtual qualified name builder for qualified_type_def.
Definition abg-ir.cc:17787
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition abg-ir.cc:17912
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition abg-ir.cc:17651
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:17639
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:17900
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition abg-ir.h:2255
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:17577
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition abg-ir.cc:17891
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17860
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition abg-ir.cc:17886
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition abg-ir.cc:17905
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition abg-ir.cc:17731
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition abg-ir.cc:17554
The internal representation of an integral type.
Definition abg-ir-priv.h:49
void set_modifiers(modifiers_type)
Setter of the modifiers bitmap of the real_type.
Definition abg-ir.cc:16827
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
Definition abg-ir.cc:16850
base_type get_base_type() const
Getter of the base type of the real_type.
Definition abg-ir.cc:16813
bool operator==(const real_type &) const
Equality operator for the real_type.
Definition abg-ir.cc:16837
real_type()
Default constructor of the real_type.
Definition abg-ir.cc:16783
modifiers_type
The modifiers of the base types above. Several modifiers can be combined for a given base type....
Definition abg-ir-priv.h:89
@ LONG_LONG_MODIFIER
The "long long" modifier.
@ LONG_MODIFIER
The "long" modifier.
Definition abg-ir-priv.h:98
@ SIGNED_MODIFIER
The "signed" modifier.
Definition abg-ir-priv.h:92
@ UNSIGNED_MODIFIER
The "unsigned" modier.
Definition abg-ir-priv.h:94
@ SHORT_MODIFIER
The "short" modifier.
Definition abg-ir-priv.h:96
base_type
The possible base types of integral types. We might have forgotten many of these, so do not hesitate ...
Definition abg-ir-priv.h:57
@ WCHAR_T_BASE_TYPE
The "wchar_t" base type.
Definition abg-ir-priv.h:73
@ CHAR32_T_BASE_TYPE
The "char32_t" base type.
Definition abg-ir-priv.h:71
@ FLOAT_BASE_TYPE
The "float" base type.
Definition abg-ir-priv.h:67
@ BOOL_BASE_TYPE
The "bool" base type in C++ or "_Bool" in C11.
Definition abg-ir-priv.h:63
@ CHAR_BASE_TYPE
The "char" base type.
Definition abg-ir-priv.h:61
@ CHAR16_T_BASE_TYPE
The "char16_t base type.
Definition abg-ir-priv.h:69
@ INT_BASE_TYPE
The "int" base type.
Definition abg-ir-priv.h:59
@ ARRAY_SIZE_BASE_TYPE
The aray size type used by Clang.
Definition abg-ir-priv.h:79
@ DOUBLE_BASE_TYPE
The "double" base type.
Definition abg-ir-priv.h:65
modifiers_type get_modifiers() const
Getter of the modifiers bitmap of the real_type.
Definition abg-ir.cc:16820
Abstracts a reference type.
Definition abg-ir.h:2416
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Build and return the qualified name of the current instance of the reference_type_def.
Definition abg-ir.cc:18693
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:18556
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition abg-ir.cc:18458
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:18815
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:18566
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition abg-ir.cc:18635
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:18794
A declaration that introduces a scope.
Definition abg-ir.h:1853
virtual size_t get_num_anonymous_member_classes() const
Getter for the number of anonymous classes contained in this scope.
Definition abg-ir.cc:7921
void remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
Definition abg-ir.cc:8130
void insert_member_type(type_base_sptr t, declarations::iterator before)
Insert a member type.
Definition abg-ir.cc:8088
void add_member_type(type_base_sptr t)
Add a member type to the current instance of class_or_union.
Definition abg-ir.cc:8105
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
Definition abg-ir.cc:7939
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
Definition abg-ir.cc:7974
std::vector< scope_decl_sptr > scopes
Convenience typedef for a vector of scope_decl_sptr.
Definition abg-ir.h:1864
bool is_empty() const
Test if the current scope is empty.
Definition abg-ir.cc:7988
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:8420
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
Definition abg-ir.cc:8063
decl_base_sptr insert_member_decl(decl_base_sptr member, declarations::iterator before)
Insert a member decl to this scope, right before an element pointed to by a given iterator....
Definition abg-ir.cc:8198
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
Definition abg-ir.h:1860
const type_base_sptrs_type & get_sorted_canonical_types() const
Return a vector of sorted canonical types of the current scope.
Definition abg-ir.cc:7857
bool find_iterator_for_member(const decl_base *, declarations::iterator &)
Find a member of the current scope and return an iterator on it.
Definition abg-ir.cc:8372
virtual void remove_member_decl(decl_base_sptr member)
Remove a declaration from the current scope.
Definition abg-ir.cc:8223
virtual decl_base_sptr add_member_decl(const decl_base_sptr &member)
Add a member decl to this scope. Note that user code should not use this, but rather use add_decl_to_...
Definition abg-ir.cc:8034
type_base_sptr find_member_type(const string &name) const
Find a member type of a given name, inside the current scope_decl.
Definition abg-ir.cc:8074
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition abg-ir.cc:7881
const canonical_type_sptr_set_type & get_canonical_types() const
@eturn the set of canonical types of the the current scope.
Definition abg-ir.cc:7845
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
Definition abg-ir.cc:8149
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition abg-ir.cc:8450
virtual bool operator==(const decl_base &) const
Return true iff both scopes have the same names and have the same member decls.
Definition abg-ir.cc:8326
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
Definition abg-ir.cc:7899
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
Definition abg-ir.cc:7957
A type that introduces a scope.
Definition abg-ir.h:2184
virtual bool traverse(ir_node_visitor &)
Traverses an instance of scope_type_decl, visiting all the sub-types and decls that it might contain.
Definition abg-ir.cc:17344
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition abg-ir.cc:17306
The base class of templates.
Definition abg-ir.h:3567
const std::list< template_parameter_sptr > & get_template_parameters() const
Get the list of template parameters of the current instance of template_decl.
Definition abg-ir.cc:27495
virtual ~template_decl()
Destructor.
Definition abg-ir.cc:27520
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:27487
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition abg-ir.cc:27529
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition abg-ir.h:3599
virtual ~template_parameter()
Destructor.
Definition abg-ir.cc:27649
bool operator!=(const template_parameter &) const
Inequality operator.
Definition abg-ir.cc:27645
Abstracts a template template parameter.
Definition abg-ir.h:3695
virtual bool operator==(const type_base &) const
Equality operator.
Definition abg-ir.cc:27898
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
Definition abg-ir.h:695
void set_address_size(char)
Setter of the address size in this translation unit.
Definition abg-ir.cc:1426
const std::string & get_absolute_path() const
Get the concatenation of the build directory and the relative path of the translation unit.
Definition abg-ir.cc:1341
void set_is_constructed(bool)
Setter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
Definition abg-ir.cc:1458
bool operator==(const translation_unit &) const
Compare the current translation unit against another one.
Definition abg-ir.cc:1468
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
Definition abg-ir.cc:1384
char get_address_size() const
Getter of the address size in this translation unit.
Definition abg-ir.cc:1419
const std::string & get_compilation_dir_path() const
Get the path of the directory that was 'current' when the translation unit was compiled.
Definition abg-ir.cc:1322
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
Definition abg-ir.cc:1368
void set_language(language l)
Setter of the language of the source code of the translation unit.
Definition abg-ir.cc:1285
void bind_function_type_life_time(function_type_sptr) const
Ensure that the life time of a function type is bound to the life time of the current translation uni...
Definition abg-ir.cc:1494
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
Definition abg-ir.cc:1221
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
Definition abg-ir.cc:1408
bool is_constructed() const
Getter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
Definition abg-ir.cc:1442
const std::string & get_path() const
Get the path of the current translation unit.
Definition abg-ir.cc:1298
void set_compilation_dir_path(const std::string &)
Set the path of the directory that was 'current' when the translation unit was compiled.
Definition abg-ir.cc:1333
location_manager & get_loc_mgr()
Getter of the location manager for the current translation unit.
Definition abg-ir.cc:1392
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
Definition abg-ir.cc:1309
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse virtual function.
Definition abg-ir.cc:1528
language
The language of the translation unit.
Definition abg-ir.h:708
bool operator!=(const translation_unit &) const
Inequality operator.
Definition abg-ir.cc:1483
const vector< function_type_sptr > & get_live_fn_types() const
Get the vector of function types that are used in the current translation unit.
Definition abg-ir.cc:1264
const environment & get_environment() const
Getter of the environment of the current translation_unit.
Definition abg-ir.cc:1271
const type_maps & get_types() const
Getter of the types of the current translation_unit.
Definition abg-ir.cc:1248
language get_language() const
Getter of the language of the source code of the translation unit.
Definition abg-ir.cc:1278
bool visiting() const
This should returns false before and after the node has been visiting. During the visiting of the nod...
An abstraction helper for type declarations.
Definition abg-ir.h:2003
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
Definition abg-ir.cc:16413
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition abg-ir.cc:16389
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition abg-ir.cc:16492
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:16359
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:16518
virtual void on_canonical_type_set()
This method is invoked automatically right after the current instance of class_decl has been canonica...
Definition abg-ir.cc:16084
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition abg-ir.cc:16485
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition abg-ir.cc:16478
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition abg-ir.cc:16468
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition abg-ir.cc:16506
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition abg-ir.cc:16499
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition abg-ir.cc:16373
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition abg-ir.h:3730
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition abg-ir.cc:28004
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition abg-ir.cc:28011
A basic type declaration that introduces no scope.
Definition abg-ir.h:2118
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation for the virtual qualified name builder for type_decl.
Definition abg-ir.cc:17138
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:16978
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:17217
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition abg-ir.cc:17076
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition abg-ir.cc:17032
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:17197
This is a type that aggregates maps of all the kinds of types that are supported by libabigail.
Definition abg-ir.h:602
istring_type_base_wptrs_map_type & typedef_types()
Getter for the map that associates the name of a typedef to the vector of instances of typedef_decl_s...
Definition abg-ir.cc:651
istring_type_base_wptrs_map_type & function_types()
Getter for the map that associates the name of a function type to the vector of instances of function...
Definition abg-ir.cc:754
istring_type_base_wptrs_map_type & reference_types()
Getter for the map that associates the name of a reference type to the vector of instances of referen...
Definition abg-ir.cc:705
const istring_type_base_wptrs_map_type & class_types() const
Getter for the map that associates the name of a class type to the vector of instances of class_decl_...
Definition abg-ir.cc:609
istring_type_base_wptrs_map_type & union_types()
Getter for the map that associates the name of a union type to the vector of instances of union_decl_...
Definition abg-ir.cc:623
istring_type_base_wptrs_map_type & array_types()
Getter for the map that associates the name of an array type to the vector of instances of array_type...
Definition abg-ir.cc:719
istring_type_base_wptrs_map_type & enum_types()
Getter for the map that associates the name of an enum type to the vector of instances of enum_type_d...
Definition abg-ir.cc:637
bool empty() const
Test if the type_maps is empty.
Definition abg-ir.cc:577
istring_type_base_wptrs_map_type & qualified_types()
Getter for the map that associates the name of a qualified type to the vector of instances of qualifi...
Definition abg-ir.cc:664
istring_type_base_wptrs_map_type & ptr_to_mbr_types()
Getter for the map that associates the name of a pointer-to-member type to the vector of instances of...
Definition abg-ir.cc:684
const vector< type_base_wptr > & get_types_sorted_by_name() const
Getter of all types types sorted by their pretty representation.
Definition abg-ir.cc:1157
istring_type_base_wptrs_map_type & pointer_types()
Getter for the map that associates the name of a pointer type to the vector of instances of pointer_t...
Definition abg-ir.cc:677
const istring_type_base_wptrs_map_type & basic_types() const
Getter for the map that associates the name of a basic type to the vector instances of type_decl_sptr...
Definition abg-ir.cc:595
const istring_type_base_wptrs_map_type & subrange_types() const
Getter for the map that associates the name of a subrange type to the vector of instances of array_ty...
Definition abg-ir.cc:740
The base class of both types and declarations.
Definition abg-ir.h:1406
void set_translation_unit(translation_unit *)
Set the translation_unit this ABI artifact belongs to.
Definition abg-ir.cc:4278
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
Definition abg-ir.cc:4091
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
Definition abg-ir.cc:4080
location & get_artificial_location() const
Getter of the artificial location of the artifact.
Definition abg-ir.cc:4238
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
Definition abg-ir.cc:4245
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Definition abg-ir.cc:4270
friend hash_t set_or_get_cached_hash_value(const T &type_or_decl)
Set the hash value of an IR node and return it.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:4191
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
Definition abg-ir.cc:4114
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition abg-ir.cc:4103
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
Definition abg-ir.cc:4303
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
Definition abg-ir.cc:4134
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition abg-ir.cc:11174
friend hash_t peek_hash_value(const type_or_decl_base &)
Get the hash value associated to an IR node.
Definition abg-ir.cc:28607
const void * type_or_decl_base_pointer() const
Getter of the pointer to either the type_base sub-object of the current instance if it's a type,...
Definition abg-ir.cc:4169
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10747
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
Definition abg-ir.cc:4220
type_or_decl_kind
This is a bitmap type which instance is meant to contain the runtime type of a given ABI artifact....
Definition abg-ir.h:1418
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition abg-ir.cc:4202
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
Definition abg-ir.cc:10820
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Definition abg-ir.cc:4295
Abstracts a type template parameter.
Definition abg-ir.h:3628
virtual bool operator==(const type_base &) const
Equality operator.
Definition abg-ir.cc:27691
The abstraction of a typedef declaration.
Definition abg-ir.h:2935
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation of the virtual "get_qualified_name" method.
Definition abg-ir.cc:21298
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition abg-ir.cc:21283
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition abg-ir.cc:21138
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:21125
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:21330
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition abg-ir.cc:21276
virtual bool operator==(const decl_base &) const
Equality operator.
Definition abg-ir.cc:21218
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition abg-ir.cc:21155
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:21259
Abstracts a union type declaration.
Definition abg-ir.h:4422
virtual hash_t hash_value() const
Return the hash value of the current IR node.
Definition abg-ir.cc:27172
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:27289
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition abg-ir.cc:27229
virtual ~union_decl()
Destructor of the union_decl type.
Definition abg-ir.cc:27362
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:27196
Abstracts a variable declaration.
Definition abg-ir.h:3068
binding get_binding() const
Getter of the binding of the variable.
Definition abg-ir.cc:21444
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition abg-ir.cc:21426
void set_binding(binding b)
Setter of the binding of the variable.
Definition abg-ir.cc:21451
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
Definition abg-ir.cc:6199
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
Definition abg-ir.cc:21489
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:21740
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition abg-ir.cc:21437
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition abg-ir.cc:6344
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition abg-ir.cc:21419
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition abg-ir.cc:21902
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:21879
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition abg-ir.cc:21466
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:21482
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition abg-ir.cc:21675
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:21770
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:21694
A type used to time various part of the libabigail system.
bool stop()
Stop the timer.
bool start()
Start the timer.
bool is_decl_only_class_with_size_change(const class_or_union &first, const class_or_union &second)
Test if two classes that are decl-only (have the decl-only flag and carry no data members) but are di...
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
ostream & operator<<(ostream &o, diff_category c)
Serialize an instance of diff_category to an output stream.
hash_t combine_hashes(hash_t val1, hash_t val2)
Combine two hash values to produce a third hash value.
Definition abg-hash.cc:172
@ HASHING_FINISHED_STATE
Hashing of given IR node started and is now done. If an ABI artifact is in this state,...
Definition abg-hash.h:61
real_type::modifiers_type operator~(real_type::modifiers_type l)
Bitwise one's complement operator for real_type::modifiers_type.
Definition abg-ir.cc:16575
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
Definition abg-fwd.h:235
bool enum_has_non_name_change(const enum_type_decl &l, const enum_type_decl &r, change_kind *k)
Test if two enums differ, but not by a name change.
Definition abg-ir.cc:20475
const type_base_sptr lookup_type_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a type in a scope.
Definition abg-ir.cc:12958
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition abg-ir.cc:28634
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Definition abg-ir.cc:6454
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
Definition abg-ir.cc:7264
hash_t peek_hash_value(const type_or_decl_base &artefact)
Get the hash value associated to an IR node.
Definition abg-ir.cc:28607
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
Definition abg-ir.cc:12445
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:28585
void fqn_to_components(const string &fqn, list< string > &comps)
Decompose a fully qualified name into the list of its components.
Definition abg-ir.cc:12309
var_decl_sptr get_last_data_member(const class_or_union &klass)
Get the last data member of a class type.
Definition abg-ir.cc:5781
bool is_anonymous_or_typedef_named(const decl_base &d)
Test if a given decl is anonymous or has a naming typedef.
Definition abg-ir.cc:6154
bool is_template_parm_composition_type(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter composition type.
Definition abg-ir.cc:12096
type_base_sptr canonicalize(type_base_sptr t, bool do_log, bool show_stats)
Compute the canonical type of a given type.
Definition abg-ir.cc:16251
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
Definition abg-ir.cc:5575
pointer_type_def_sptr is_pointer_to_npaf_type(const type_base_sptr &t)
Test if we are looking at a pointer to a neither-a-pointer-to-an-array-nor-a-function type.
Definition abg-ir.cc:11554
bool debug_equals(const type_or_decl_base *l, const type_or_decl_base *r)
Test if two ABI artifacts are equal.
Definition abg-ir.cc:10142
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition abg-fwd.h:269
access_specifier
Access specifier for class members.
Definition abg-ir.h:917
size_t get_canonical_type_index(const type_base &t)
Getter of the canonical type index of a given type.
Definition abg-ir.cc:345
const type_base_wptrs_type * lookup_enum_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the enum type*s* that have a given qualified name.
Definition abg-ir.cc:14026
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition abg-ir.cc:23361
pointer_type_def_sptr is_pointer_to_array_type(const type_base_sptr &t)
Test if a type is a pointer to array type.
Definition abg-ir.cc:11536
bool type_is_suitable_for_hash_computing(const type_base &)
Test if we should attempt to compute a hash value for a given type.
Definition abg-ir.cc:15825
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
Definition abg-fwd.h:289
bool maybe_update_types_lookup_map< function_type >(const function_type_sptr &type, istring_type_base_wptrs_map_type &types_map, bool)
This is the specialization for type function_type of the function template:
Definition abg-ir.cc:14698
weak_ptr< function_type > function_type_wptr
Convenience typedef for a weak pointer on a function_type.
Definition abg-fwd.h:216
type_base_sptr lookup_class_or_typedef_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, union or typedef type which has a given qualified name.
Definition abg-ir.cc:14188
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition abg-ir.cc:6578
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
Definition abg-fwd.h:142
scope_decl * get_type_scope(type_base *t)
Get the scope of a given type.
Definition abg-ir.cc:8800
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:25960
void pop_composite_type_comparison_operands(const type_base &left, const type_base &right)
Pop a pair of operands from the stack of operands to the current type comparison.
Definition abg-ir.cc:332
bool equals_modulo_cv_qualifier(const array_type_def *l, const array_type_def *r)
Test if two array types are equals modulo CV qualifiers.
Definition abg-ir.cc:19932
const scope_decl * is_scope_decl(const decl_base *d)
Test if a declaration is a scope_decl.
Definition abg-ir.cc:5445
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
Definition abg-ir.cc:7615
const type_base * is_void_pointer_type(const type_base *t)
Test if a type is a pointer to void type.
Definition abg-ir.cc:11787
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition abg-ir.cc:10807
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition abg-ir.cc:5872
bool is_template_parameter(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter.
Definition abg-ir.cc:10681
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
Definition abg-ir.cc:1540
weak_ptr< type_base > type_base_wptr
Convenience typedef for a weak pointer on a type_base.
Definition abg-fwd.h:128
type_base_sptr peel_reference_type(const type_base_sptr &type)
Return the leaf pointed-to type node of a reference_type_def node.
Definition abg-ir.cc:7173
class_decl::base_spec * is_class_base_spec(const type_or_decl_base *tod)
Test if an ABI artifact is a class base specifier.
Definition abg-ir.cc:26647
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
Definition abg-ir.cc:5399
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
Definition abg-ir.cc:12215
T * maybe_get_canonical_type(T *t)
Get the canonical type of a given type T* as a T*.
Definition abg-ir.cc:894
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition abg-ir.h:926
type_base_sptr lookup_type_from_translation_unit(const string &type_name, const string &tu_path, const corpus &corp)
Lookup a type from a given translation unit present in a give corpus.
Definition abg-ir.cc:13585
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
Definition abg-ir.cc:28705
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:16768
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
Definition abg-ir.cc:8475
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
Definition abg-ir.cc:10207
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
Definition abg-ir.cc:7548
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
Definition abg-ir.h:1361
@ LOCAL_TYPE_CHANGE_KIND
This means that a given IR artifact has a local type change.
Definition abg-ir.h:1365
@ SUBTYPE_CHANGE_KIND
This means that a given IR artifact has changes in some of its sub-types, with respect to the other a...
Definition abg-ir.h:1381
@ LOCAL_NON_TYPE_CHANGE_KIND
This means that a given IR artifact has a local non-type change. That is a change that is carried by ...
Definition abg-ir.h:1370
var_decl_sptr find_last_data_member_matching_regexp(const class_or_union &t, const regex::regex_t_sptr &regex)
Find the last data member of a class or union which name matches a regular expression.
Definition abg-ir.cc:29211
const ptr_to_mbr_type * is_ptr_to_mbr_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type.
Definition abg-ir.cc:11711
const var_decl_sptr get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
Get the first non-anonymous data member of a given anonymous data member.
Definition abg-ir.cc:5718
class_decl_sptr lookup_class_type_through_scopes(const list< string > &fqn, const translation_unit &tu)
Lookup a class type from a translation unit by walking its scopes in sequence and by looking into the...
Definition abg-ir.cc:13320
string get_enum_flat_representation(const enum_type_decl &enum_type, const string &indent, bool one_line, bool qualified_names)
Get the flat representation of an instance of enum_type_decl type.
Definition abg-ir.cc:9684
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
Definition abg-ir.cc:5479
bool operator==(const translation_unit_sptr &l, const translation_unit_sptr &r)
A deep comparison operator for pointers to translation units.
Definition abg-ir.cc:1849
weak_ptr< class_decl > class_decl_wptr
Convenience typedef for a weak pointer on a class_decl.
Definition abg-fwd.h:202
string components_to_type_name(const list< string > &comps)
Turn a set of qualified name components (that name a type) into a qualified name string.
Definition abg-ir.cc:12335
void unmark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being not compared anymore.
Definition abg-ir.cc:1085
vector< type_base_sptr > type_base_sptrs_type
Helper typedef for a vector of shared pointer to a type_base.
Definition abg-ir.h:127
void debug_comp_stack(const environment &env)
Emit a trace of the two comparison operands stack on the standard error stream.
Definition abg-ir.cc:10192
bool collect_non_anonymous_data_members(const class_or_union *cou, string_decl_base_sptr_map &dms)
Collect all the non-anonymous data members of a class or union type.
Definition abg-ir.cc:5815
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition abg-ir.cc:11165
type_base_sptr synthesize_type_from_translation_unit(const type_base_sptr &type, translation_unit &tu)
In a translation unit, lookup a given type or synthesize it if it's a qualified type.
Definition abg-ir.cc:15271
void set_member_function_virtuality(function_decl &fn, bool is_virtual, ssize_t voffset)
Set the virtual-ness of a member fcuntion.
Definition abg-ir.cc:6715
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition abg-fwd.h:244
function_type_sptr lookup_or_synthesize_fn_type(const function_type_sptr &fn_t, const corpus &corpus)
Look into an ABI corpus for a function type.
Definition abg-ir.cc:13610
bool is_declaration_only_class_or_union_type(const type_base *t, bool look_through_decl_only)
Test wheter a type is a declaration-only class.
Definition abg-ir.cc:11349
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
Definition abg-ir.cc:9286
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
Definition abg-ir.cc:10858
type_base_sptr lookup_class_typedef_or_enum_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, typedef or enum type which has a given qualified name.
Definition abg-ir.cc:14213
type_base_sptr peel_const_qualified_type(const qualified_type_def_sptr &q)
If a qualified type is const, then return its underlying type.
Definition abg-ir.cc:7333
const class_or_union_sptr data_member_has_anonymous_type(const var_decl &d)
Test if a data member has annonymous type or not.
Definition abg-ir.cc:6058
type_decl * is_integral_type(const type_or_decl_base *t)
Test if a type is an integral type.
Definition abg-ir.cc:10967
bool anonymous_data_member_exists_in_class(const var_decl &anon_dm, const class_or_union &clazz)
Test if a given anonymous data member exists in a class or union.
Definition abg-ir.cc:6114
class_decl_sptr lookup_class_type_per_location(const interned_string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
Definition abg-ir.cc:13889
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition abg-ir.cc:6482
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
Definition abg-ir.cc:7222
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
Definition abg-ir.cc:12776
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:28849
corpus_group_sptr is_corpus_group(const corpus_sptr &corpus)
Test if a corpus is a corpus_group.
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
Definition abg-fwd.h:314
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
Definition abg-ir.cc:11396
var_decl_sptr get_data_member(class_or_union *clazz, const char *member_name)
Get a given data member, referred to by its name, of a class type.
Definition abg-ir.cc:10024
type_base * look_through_decl_only_type(type_base *t)
If a type is is decl-only, then get its definition. Otherwise, just return the initial type.
Definition abg-ir.cc:12027
const var_decl_sptr get_next_data_member(const class_or_union *klass, const var_decl_sptr &data_member)
In the context of a given class or union, this function returns the data member that is located after...
Definition abg-ir.cc:5742
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition abg-fwd.h:193
type_base_sptr peel_typedef_pointer_or_reference_type(const type_base_sptr type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def,...
Definition abg-ir.cc:7409
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
Definition abg-ir.cc:6538
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
Definition abg-ir.cc:6915
bool is_comparison_cycle_detected(T &l, T &r)
Detect if a recursive comparison cycle is detected while structurally comparing two types (a....
Definition abg-ir.cc:989
bool string_to_elf_symbol_type(const string &s, elf_symbol::type &t)
Convert a string representing a symbol type into an elf_symbol::type.
Definition abg-ir.cc:3064
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
Definition abg-ir.cc:12078
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
Definition abg-ir.cc:10909
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10787
decl_base_sptr look_through_decl_only(const decl_base &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
Definition abg-ir.cc:11967
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
Definition abg-ir.cc:11858
string get_name(const type_or_decl_base *tod, bool qualified)
Build and return a copy of the name of an ABI artifact that is either a type or a decl.
Definition abg-ir.cc:8686
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition abg-ir.cc:5544
const class_decl * is_compatible_with_class_type(const type_base *t)
Test if a type is a class. This function looks through typedefs.
Definition abg-ir.cc:11118
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition abg-ir.cc:11011
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
Definition abg-ir.h:105
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
Definition abg-ir.cc:6316
enum_type_decl_sptr lookup_enum_type_per_location(const interned_string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
Definition abg-ir.cc:14056
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
Definition abg-ir.cc:9833
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition abg-fwd.h:210
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
Definition abg-fwd.h:167
function_type_sptr synthesize_function_type_from_translation_unit(const function_type &fn_type, translation_unit &tu)
In a translation unit, lookup the sub-types that make up a given function type and if the sub-types a...
Definition abg-ir.cc:15354
std::ostream & operator<<(std::ostream &o, elf_symbol::type t)
Serialize an instance of symbol_type and stream it to a given output stream.
Definition abg-ir.cc:2936
type_base_sptr peel_pointer_type(const type_base_sptr &type)
Return the leaf pointed-to type node of a pointer_type_def node.
Definition abg-ir.cc:7117
bool var_equals_modulo_types(const var_decl &l, const var_decl &r, change_kind *k)
Compares two instances of var_decl without taking their type into account.
Definition abg-ir.cc:21550
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
Definition abg-ir.cc:12485
type_base_sptr lookup_type_through_translation_units(const string &qn, const corpus &abi_corpus)
Lookup a type definition in all the translation units of a given ABI corpus.
Definition abg-ir.cc:13560
qualified_type_def_sptr is_array_of_qualified_element(const array_type_def_sptr &array)
Tests if the element of a given array is a qualified type.
Definition abg-ir.cc:12156
void sort_types(const canonical_type_sptr_set_type &types, vector< type_base_sptr > &result)
Sort types in a hopefully stable manner.
Definition abg-ir.cc:3448
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
Definition abg-ir.cc:11614
type_base * peel_pointer_or_reference_type(const type_base *type, bool peel_qual_type)
Return the leaf underlying or pointed-to type node of a, pointer_type_def, reference_type_def or qual...
Definition abg-ir.cc:7511
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
Definition abg-ir.cc:11651
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
bool elf_symbol_is_function(elf_symbol::type t)
Test if the type of an ELF symbol denotes a function symbol.
Definition abg-ir.cc:3145
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
Definition abg-ir.cc:1808
bool lookup_decl_only_class_types(const interned_string &qualified_name, const corpus &corp, type_base_wptrs_type &result)
Look into a given corpus to find the class type*s* that have a given qualified name and that are decl...
Definition abg-ir.cc:13813
bool member_function_has_vtable_offset(const function_decl &f)
Test if a virtual member function has a vtable offset set.
Definition abg-ir.cc:6567
decl_base_sptr insert_decl_into_scope(decl_base_sptr decl, scope_decl::declarations::iterator before, scope_decl *scope)
Inserts a declaration into a given scope, before a given IR child node of the scope.
Definition abg-ir.cc:8494
unordered_map< interned_string, bool, hash_interned_string > interned_string_bool_map_type
Convenience typedef for a map of interned_string -> bool.
Definition abg-ir.cc:3365
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
Definition abg-ir.cc:11100
unordered_map< interned_string, type_base_wptrs_type, hash_interned_string > istring_type_base_wptrs_map_type
A convenience typedef for a map which key is an interned_string and which value is a vector of type_b...
Definition abg-fwd.h:148
bool function_decl_is_less_than(const function_decl &f, const function_decl &s)
Test if the pretty representation of a given function_decl is lexicographically less then the pretty ...
Definition abg-ir.cc:28797
bool elf_symbols_alias(const elf_symbol &s1, const elf_symbol &s2)
Test if two symbols alias.
Definition abg-ir.cc:2867
var_decl_sptr find_data_member_from_anonymous_data_member(const var_decl_sptr &anon_dm, const string &name)
Find a data member inside an anonymous data member.
Definition abg-ir.cc:10650
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
Definition abg-ir.cc:8543
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition abg-fwd.h:256
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
Definition abg-fwd.h:239
const location & get_natural_or_artificial_location(const decl_base *decl)
Get the non-artificial (natural) location of a decl.
Definition abg-ir.cc:10052
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:28498
method_decl_sptr copy_member_function(class_or_union_sptr t, const method_decl_sptr &method)
Copy a method of a class_or_union into a new class_or_union.
Definition abg-ir.cc:24842
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
bool is_template_decl(const decl_base_sptr &decl)
Tests whether a decl is a template.
Definition abg-ir.cc:12238
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
Definition abg-fwd.h:264
bool string_to_elf_symbol_binding(const string &s, elf_symbol::binding &b)
Convert a string representing a an elf symbol binding into an elf_symbol::binding.
Definition abg-ir.cc:3097
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
Definition abg-fwd.h:120
pointer_type_def_sptr lookup_pointer_type(const interned_string &type_name, const translation_unit &tu)
Lookup a pointer type from a translation unit.
Definition abg-ir.cc:12714
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition abg-fwd.h:136
bool is_data_member_of_anonymous_class_or_union(const var_decl &d)
Test if a var_decl is a data member belonging to an anonymous type.
Definition abg-ir.cc:5990
bool integral_type_has_harmless_name_change(const type_base_sptr &f, const type_base_sptr &s)
Test if a diff node carries a change whereby two integral types have different names in a harmless wa...
Definition abg-ir.cc:29776
const type_base * is_void_pointer_type_equivalent(const type_base *type)
Test if a type is equivalent to a pointer to void type.
Definition abg-ir.cc:11750
unordered_map< const function_decl *, string, function_decl_hash, function_decl::ptr_equal > fns_to_str_map_type
Convenience typedef for a hash map of pointer to function_decl and string.
Definition abg-ir.cc:30500
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition abg-ir.cc:12244
bool try_canonical_compare(const T *l, const T *r)
Compare two types by comparing their canonical types if present.
Definition abg-ir.cc:914
const decl_base_sptr lookup_var_decl_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a var_decl in a scope.
Definition abg-ir.cc:12975
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:28435
unordered_map< string, decl_base_sptr > string_decl_base_sptr_map
Convenience typedef for a map which key is a string and which value is a decl_base_sptr.
Definition abg-fwd.h:157
qualified_type_def_sptr lookup_qualified_type(const interned_string &type_name, const translation_unit &tu)
Lookup a qualified type from a translation unit.
Definition abg-ir.cc:12668
void push_composite_type_comparison_operands(const type_base &left, const type_base &right)
Push a pair of operands on the stack of operands of the current type comparison, during type canonica...
Definition abg-ir.cc:311
const type_base_sptr lookup_type(const interned_string &fqn, const translation_unit &tu)
Lookup a type in a translation unit.
Definition abg-ir.cc:12891
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
Definition abg-ir.cc:1824
function_decl::parameter * is_function_parameter(const type_or_decl_base *tod)
Test whether a declaration is a function_decl.
Definition abg-ir.cc:10724
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
Definition abg-ir.cc:5138
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition abg-ir.cc:6344
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
Definition abg-ir.cc:12522
bool string_to_elf_symbol_visibility(const string &s, elf_symbol::visibility &v)
Convert a string representing a an elf symbol visibility into an elf_symbol::visibility.
Definition abg-ir.cc:3122
const enum_type_decl * is_compatible_with_enum_type(const type_base *t)
Test if a type is an enum. This function looks through typedefs.
Definition abg-ir.cc:11051
weak_ptr< elf_symbol > elf_symbol_wptr
A convenience typedef for a weak pointer to elf_symbol.
Definition abg-ir.h:929
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition abg-ir.cc:6510
interned_string get_name_of_reference_to_type(const type_base &pointed_to_type, bool lvalue_reference, bool qualified, bool internal)
Get the name of the reference to a given type.
Definition abg-ir.cc:9041
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
Definition abg-fwd.h:226
void maybe_update_types_lookup_map(const type_decl_sptr &basic_type)
Update the map that associates the fully qualified name of a basic type with the type itself.
Definition abg-ir.cc:14728
bool is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr, const enum_type_decl &enom)
Test if a given enumerator is found present in an enum.
Definition abg-ir.cc:20556
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
Definition abg-ir.cc:7301
translation_unit::language string_to_translation_unit_language(const string &l)
Parse a string representing a language into a translation_unit::language enumerator into a string.
Definition abg-ir.cc:1670
type_base_sptr lookup_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a type from a corpus, by its location.
Definition abg-ir.cc:14518
bool get_next_data_member_offset(const class_or_union *klass, const var_decl_sptr &dm, uint64_t &offset)
Get the offset of the non-static data member that comes after a given one.
Definition abg-ir.cc:6229
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
Definition abg-ir.cc:6273
shared_ptr< ir_traversable_base > ir_traversable_base_sptr
Convenience typedef for a shared pointer to ir_traversable_base.
Definition abg-fwd.h:109
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
Definition abg-ir.cc:6368
const function_decl::parameter * get_function_parameter(const decl_base *fun, unsigned parm_index)
Get the function parameter designated by its index.
Definition abg-ir.cc:29143
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition abg-ir.cc:12059
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
Definition abg-ir.cc:1792
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition abg-ir.cc:10747
void keep_type_alive(type_base_sptr t)
Make sure that the life time of a given (smart pointer to a) type is the same as the life time of the...
Definition abg-ir.cc:28473
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:25793
array_type_def_sptr lookup_array_type(const interned_string &type_name, const translation_unit &tu)
Lookup an array type from a translation unit.
Definition abg-ir.cc:12820
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition abg-ir.cc:5464
string get_class_or_union_flat_representation(const class_or_union &cou, const string &indent, bool one_line, bool internal, bool qualified_names)
Get the flat representation of an instance of class_or_union type.
Definition abg-ir.cc:9508
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition abg-ir.cc:8450
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
Definition abg-ir.cc:29165
bool is_npaf_type(const type_base_sptr &t)
Test if a type is a neither a pointer, an array nor a function type.
Definition abg-ir.cc:10894
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition abg-ir.cc:5515
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition abg-fwd.h:175
void set_data_member_offset(var_decl_sptr m, uint64_t o)
Set the offset of a data member into its containing class.
Definition abg-ir.cc:6167
type_base_sptr strip_typedef(const type_base_sptr type)
Recursively returns the the underlying type of a typedef. The return type should not be a typedef of ...
Definition abg-ir.cc:6780
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition abg-ir.cc:6184
unordered_set< uintptr_t > pointer_set
A convenience typedef for an unordered set of pointer values.
Definition abg-ir.h:99
void sort_types_for_hash_computing_and_c14n(IteratorType begin, IteratorType end)
Sort types before hashing (and then canonicalizing) them.
class_or_union * is_at_class_scope(const decl_base_sptr decl)
Tests whether a given decl is at class scope.
Definition abg-ir.cc:10607
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition abg-ir.cc:6641
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
Definition abg-ir.cc:11479
string get_class_or_enum_flat_representation(const type_base &coe, const string &indent, bool one_line, bool internal, bool qualified_name)
Get the flat representation of an instance of enum_type_decl type.
Definition abg-ir.cc:9805
class_or_union * anonymous_data_member_to_class_or_union(const var_decl *d)
Get the class_or_union type of a given anonymous data member.
Definition abg-ir.cc:6030
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
Definition abg-ir.cc:8766
pointer_type_def_sptr is_pointer_to_function_type(const type_base_sptr &t)
Test if a type is a pointer to function type.
Definition abg-ir.cc:11519
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
Definition abg-ir.cc:10503
weak_ptr< decl_base > decl_base_wptr
Convenience typedef for a weak pointer to a decl_base.
Definition abg-fwd.h:181
var_decl_sptr has_fake_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with one element.
Definition abg-ir.cc:11276
interned_string get_function_type_name(const function_type_sptr &fn_type, bool internal)
Get the name of a given function type and return a copy of it.
Definition abg-ir.cc:9118
bool is_function_template_pattern(const shared_ptr< decl_base > decl)
Test whether a decl is the pattern of a function template.
Definition abg-ir.cc:12110
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
Definition abg-ir.cc:11918
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition abg-ir.cc:11445
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition abg-ir.cc:10071
enum_type_decl_sptr lookup_enum_type(const interned_string &type_name, const translation_unit &tu)
Lookup an enum type from a translation unit.
Definition abg-ir.cc:12590
type_base_sptr peel_typedef_type(const type_base_sptr &type)
Return the leaf underlying type node of a typedef_decl node.
Definition abg-ir.cc:7063
const type_base_wptrs_type * lookup_union_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the union type*s* that have a given qualified name.
Definition abg-ir.cc:13844
var_decl_sptr copy_member_variable(class_or_union_sptr t, const var_decl *variable)
Copy a data member of a class_or_union into a new class_or_union.
Definition abg-ir.cc:24910
interned_string get_name_of_qualified_type(const type_base_sptr &underlying_type, qualified_type_def::CV quals, bool qualified, bool internal)
Get the name of a qualified type, given the underlying type and its qualifiers.
Definition abg-ir.cc:9071
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
Definition abg-fwd.h:306
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
Definition abg-ir.cc:12194
function_type_sptr lookup_function_type(const interned_string &type_name, const translation_unit &tu)
Lookup a function type from a translation unit.
Definition abg-ir.cc:12840
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
Definition abg-ir.cc:10552
string get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
Get the string representation of a CV qualifier bitmap.
Definition abg-ir.cc:8656
void set_data_member_is_laid_out(var_decl_sptr m, bool l)
Set a flag saying if a data member is laid out.
Definition abg-ir.cc:6330
pointer_type_def_sptr is_pointer_to_ptr_to_mbr_type(const type_base_sptr &t)
Test if we are looking at a pointer to pointer to member type.
Definition abg-ir.cc:11571
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition abg-ir.cc:5613
var_decl_sptr find_first_data_member_matching_regexp(const class_or_union &t, const regex::regex_t_sptr &r)
Find the first data member of a class or union which name matches a regular expression.
Definition abg-ir.cc:29190
const type_base_wptrs_type * lookup_class_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the class type*s* that have a given qualified name.
Definition abg-ir.cc:13793
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition abg-ir.cc:10229
var_decl_sptr has_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with non-finite data member.
Definition abg-ir.cc:11206
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition abg-ir.cc:26893
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
Definition abg-ir.cc:12123
interned_string get_method_type_name(const method_type_sptr fn_type, bool internal)
Get the name of a given method type and return a copy of it.
Definition abg-ir.cc:9208
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:29100
interned_string get_function_id_or_pretty_representation(const function_decl *fn)
Get the ID of a function, or, if the ID can designate several different functions,...
Definition abg-ir.cc:9180
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition abg-fwd.h:161
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
Definition abg-ir.cc:7590
type_decl_sptr lookup_basic_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a type_decl type from a given corpus, by its location.
Definition abg-ir.cc:13681
bool compare_using_locations(const decl_base *f, const decl_base *s)
Compare decls using their locations.
Definition abg-ir.cc:3413
bool classes_have_same_layout(const type_base_sptr &f, const type_base_sptr &s)
Test if two classes have the same layout.
Definition abg-ir.cc:10262
const type_base_sptr lookup_type_through_scopes(const type_base_sptr type, const translation_unit &tu)
Lookup a type from a translation unit by walking the scopes of the translation unit in sequence and l...
Definition abg-ir.cc:13252
type_or_decl_base * debug(const type_or_decl_base *artifact)
Emit a textual representation of an artifact to std error stream for debugging purposes.
Definition abg-ir.cc:10091
unordered_set< type_base_sptr, canonical_type_hash > canonical_type_sptr_set_type
Helper typedef for an unordered set of type_base_sptr which uses pointer value to tell its members ap...
Definition abg-ir.h:121
bool return_comparison_result(T &l, T &r, bool value)
Return the result of the comparison of two (sub) types.
Definition abg-ir.cc:1127
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
Definition abg-fwd.h:284
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
Definition abg-ir.cc:1833
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
Definition abg-ir.cc:15428
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition abg-ir.cc:28670
bool types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
Test if two types are equal modulo a typedef or CV qualifiers.
Definition abg-ir.cc:10397
void mark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being compared.
Definition abg-ir.cc:1050
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
Definition abg-ir.cc:8835
const scope_decl * get_top_most_scope_under(const decl_base *decl, const scope_decl *scope)
Return the a scope S containing a given declaration and that is right under a given scope P.
Definition abg-ir.cc:8587
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
Definition abg-ir.cc:7668
bool operator!=(const translation_unit_sptr &l, const translation_unit_sptr &r)
A deep inequality operator for pointers to translation units.
Definition abg-ir.cc:1868
interned_string get_name_of_pointer_to_type(const type_base &pointed_to_type, bool qualified, bool internal)
Get the name of the pointer to a given type.
Definition abg-ir.cc:9019
bool decl_name_changed(const type_or_decl_base *a1, const type_or_decl_base *a2)
Test if two decls have different names.
Definition abg-ir.cc:29735
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
Definition abg-ir.cc:10672
typedef_decl_sptr lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a typedef_decl from a corpus, by its location.
Definition abg-ir.cc:14151
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition abg-ir.cc:10695
bool elf_symbol_is_variable(elf_symbol::type t)
Test if the type of an ELF symbol denotes a function symbol.
Definition abg-ir.cc:3155
bool type_has_sub_type_changes(const type_base_sptr t_v1, const type_base_sptr t_v2)
Tests if the change of a given type effectively comes from just its sub-types. That is,...
Definition abg-ir.cc:28457
bool maybe_update_types_lookup_map< class_decl >(const class_decl_sptr &class_type, istring_type_base_wptrs_map_type &map, bool use_type_name_as_key)
This is the specialization for type class_decl of the function template:
Definition abg-ir.cc:14636
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
Definition abg-ir.cc:11888
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
Definition abg-ir.cc:11838
typedef_decl_sptr lookup_typedef_type(const interned_string &type_name, const translation_unit &tu)
Lookup a typedef type from a translation unit.
Definition abg-ir.cc:12628
bool is_typedef_ptr_or_ref_to_decl_only_class_or_union_type(const type_base *t)
Test if a type is a typedef, pointer or reference to a decl-only class/union.
Definition abg-ir.cc:11591
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol.
Definition abg-ir.h:947
union_decl_sptr lookup_union_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
Definition abg-ir.cc:12555
bool class_or_union_types_of_same_kind(const class_or_union *first, const class_or_union *second)
Test if two class or union types are of the same kind.
Definition abg-ir.cc:11417
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
Definition abg-ir.cc:8732
bool is_ptr_ref_or_qual_type(const type_base *t)
Helper to detect if a type is either a reference, a pointer, or a qualified type.
Definition abg-ir.cc:3396
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
Definition abg-ir.cc:11948
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
Definition abg-fwd.h:294
type_base * peel_qualified_or_typedef_type(const type_base *type)
Return the leaf underlying type of a qualified or typedef type.
Definition abg-ir.cc:7358
type_base_sptr type_or_void(const type_base_sptr t, const environment &env)
Return either the type given in parameter if it's non-null, or the void type.
Definition abg-ir.cc:15458
bool is_at_global_scope(const decl_base &decl)
Tests whether a given declaration is at global scope.
Definition abg-ir.cc:10580
type_decl * is_real_type(const type_or_decl_base *t)
Test if a type is a real type.
Definition abg-ir.cc:10927
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition abg-ir.cc:5417
bool maybe_compare_as_member_decls(const decl_base &l, const decl_base &r, change_kind *k)
Compare the properties that belong to the "is-a-member-relation" of a decl.
Definition abg-ir.cc:5069
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition abg-ir.cc:6395
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
Definition abg-ir.cc:6425
bool is_declaration_only_class_type(const type_base_sptr &t, bool look_through_decl_only)
Test wheter a type is a declaration-only class.
Definition abg-ir.cc:11385
bool match(const regex_t_sptr &r, const std::string &str)
See if a string matches a regex.
Definition abg-regex.cc:127
std::shared_ptr< regex_t > regex_t_sptr
A convenience typedef for a shared pointer of regex_t.
Definition abg-fwd.h:87
const char * get_anonymous_subrange_internal_name_prefix()
Getter of the prefix for the name of anonymous range.
const char * get_anonymous_enum_internal_name_prefix()
Getter of the prefix for the name of anonymous enums.
const char * get_anonymous_struct_internal_name_prefix()
Getter of the prefix for the name of anonymous structs.
const char * get_anonymous_union_internal_name_prefix()
Getter of the prefix for the name of anonymous unions.
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
Definition abg-ir.cc:151
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
Definition abg-ir.cc:185
unordered_map< string, string * > pool_map_type
Convenience typedef for a map of string -> string*.
Definition abg-ir.cc:73
A functor to hash instances of interned_string.
size_t operator()(const type_base_sptr &l) const
Hash a type by returning the pointer value of its canonical type.
Definition abg-ir.cc:7783
Hasher for the class_or_union type.
Definition abg-hash.h:250
bool is_printing_flat_representation() const
Getter of the 'is_printing_flat_representation_' boolean.
void unset_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to false.
void set_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to true.
A functor to sort decls somewhat topologically. That is, types are sorted in a way that makes the one...
The private data of the environment type.
Equality functor for instances of function_decl.
Definition abg-ir.h:4772
The hashing functor for function_type.
Definition abg-hash.h:217
The type of the private data of the function_type type.
virtual bool traverse(ir_node_visitor &v)
Traverse a given IR node and its children, calling an visitor on each node.
Definition abg-ir.cc:30150
The hashing functor for member_base.
Definition abg-hash.h:243
Private type to hold private members of translation_unit.
Hash functor for instances of type_base.
Definition abg-hash.h:111
Definition of the private data of type_base.
The private data of type_or_decl_base.
A predicate for deep equality of instances of shared_ptr<type_base>
Definition abg-ir.h:2096
A functor to sort types somewhat topologically. That is, types are sorted in a way that makes the one...
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.