libabigail
abg-ir.cc
Go to the documentation of this file.
1// C++ -*-
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// -*- Mode: C++ -*-
4
5// Copyright (C) 2013-2024 Red Hat, Inc.
6//
7//Author: Dodji Seketeli
8
9/// @file
10///
11/// Definitions for the Internal Representation artifacts of libabigail.
12
13#include <cxxabi.h>
14#include <cstdint>
15#include <functional>
16#include <iterator>
17#include <memory>
18#include <sstream>
19#include <typeinfo>
20#include <unordered_map>
21#include <utility>
22#include <vector>
23
24#include "abg-internal.h"
25// <headers defining libabigail's API go under here>
26ABG_BEGIN_EXPORT_DECLARATIONS
27
28#include "abg-interned-str.h"
29#include "abg-ir.h"
30#include "abg-corpus.h"
31#include "abg-regex.h"
32
33ABG_END_EXPORT_DECLARATIONS
34// </headers defining libabigail's API>
35
36#include "abg-corpus-priv.h"
37#include "abg-tools-utils.h"
38#include "abg-comp-filter.h"
39#include "abg-ir-priv.h"
40
41namespace
42{
43/// This internal type is a tree walking that is used to set the
44/// qualified name of a tree of decls and types. It used by the
45/// function update_qualified_name().
46class qualified_name_setter : public abigail::ir::ir_node_visitor
47{
48
49public:
50 bool
51 do_update(abigail::ir::decl_base* d);
52
53 bool
54 visit_begin(abigail::ir::decl_base* d);
55
56 bool
57 visit_begin(abigail::ir::type_base* d);
58}; // end class qualified_name_setter
59
60}// end anon namespace
61
62namespace abigail
63{
64
65// Inject.
66using std::string;
67using std::list;
68using std::vector;
69using std::unordered_map;
70using std::dynamic_pointer_cast;
71using std::static_pointer_cast;
72
73/// Convenience typedef for a map of string -> string*.
74typedef unordered_map<string, string*> pool_map_type;
75
76/// The type of the private data structure of type @ref
77/// intered_string_pool.
78struct interned_string_pool::priv
79{
80 pool_map_type map;
81}; //end struc struct interned_string_pool::priv
82
83/// Default constructor.
85 : priv_(new priv)
86{
87 priv_->map[""] = 0;
88}
89
90/// Test if the interned string pool already contains a string with a
91/// given value.
92///
93/// @param s the string to test for.
94///
95/// @return true if the pool contains a string with the value @p s.
96bool
98{return priv_->map.find(s) != priv_->map.end();}
99
100/// Get a pointer to the interned string which has a given value.
101///
102/// @param s the value of the interned string to look for.
103///
104/// @return a pointer to the raw string of characters which has the
105/// value of @p s. Or null if no string with value @p s was interned.
106const char*
108{
109 unordered_map<string, string*>::const_iterator i =
110 priv_->map.find(s);
111 if (i == priv_->map.end())
112 return 0;
113 if (i->second)
114 return i->second->c_str();
115 return "";
116}
117
118/// Create an interned string with a given value.
119///
120/// @param str_value the value of the interned string to create.
121///
122/// @return the new created instance of @ref interned_string created.
124interned_string_pool::create_string(const std::string& str_value)
125{
126 string*& result = priv_->map[str_value];
127 if (!result && !str_value.empty())
128 result = new string(str_value);
129 return interned_string(result);
130}
131
132/// Destructor.
134{
135 for (pool_map_type::iterator i = priv_->map.begin();
136 i != priv_->map.end();
137 ++i)
138 if (i->second)
139 delete i->second;
140}
141
142/// Equality operator.
143///
144/// @param l the instance of std::string on the left-hand-side of the
145/// equality operator.
146///
147/// @param r the instance of @ref interned_string on the
148/// right-hand-side of the equality operator.
149///
150/// @return true iff the two string are equal.
151bool
152operator==(const std::string& l, const interned_string& r)
153{return r.operator==(l);}
154
155bool
156operator!=(const std::string& l, const interned_string& r)
157{return !(l == r);}
158
159/// Streaming operator.
160///
161/// Streams an instance of @ref interned_string to an output stream.
162///
163/// @param o the destination output stream.
164///
165/// @param s the instance of @ref interned_string to stream out.
166///
167/// @return the output stream this function just streamed to.
168std::ostream&
169operator<<(std::ostream& o, const interned_string& s)
170{
171 o << static_cast<std::string>(s);
172 return o;
173}
174
175/// Concatenation operator.
176///
177/// Concatenate two instances of @ref interned_string, builds an
178/// instance of std::string with the resulting string and return it.
179///
180/// @param s1 the first string to consider.
181///
182/// @param s2 the second string to consider.
183///
184/// @return the resuting concatenated string.
185std::string
186operator+(const interned_string& s1,const std::string& s2)
187{return static_cast<std::string>(s1) + s2;}
188
189/// Concatenation operator.
190///
191/// Concatenate two instances of @ref interned_string, builds an
192/// instance of std::string with the resulting string and return it.
193///
194/// @param s1 the first string to consider.
195///
196/// @param s2 the second string to consider.
197///
198/// @return the resuting concatenated string.
199std::string
200operator+(const std::string& s1, const interned_string& s2)
201{return s1 + static_cast<std::string>(s2);}
202
203namespace ir
204{
205
206static size_t
207hash_as_canonical_type_or_constant(const type_base *t);
208
209static bool
210has_generic_anonymous_internal_type_name(const decl_base *d);
211
212static interned_string
213get_generic_anonymous_internal_type_name(const decl_base *d);
214
215static string
216get_internal_integral_type_name(const type_base*);
217
218static void
219update_qualified_name(decl_base * d);
220
221static void
222update_qualified_name(decl_base_sptr d);
223
224static interned_string
225pointer_declaration_name(const type_base* ptr,
226 const string& variable_name,
227 bool qualified, bool internal);
228
229static interned_string
230pointer_declaration_name(const type_base_sptr& ptr,
231 const string& variable_name,
232 bool qualified, bool internal);
233
234static interned_string
235ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
236 const string& variable_name,
237 bool qualified, bool internal);
238
239static interned_string
240ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
241 const string& variable_name,
242 bool qualified, bool internal);
243
244static interned_string
245array_declaration_name(const array_type_def* array,
246 const string& variable_name,
247 bool qualified, bool internal);
248
249static interned_string
250array_declaration_name(const array_type_def_sptr& array,
251 const string& variable_name,
252 bool qualified, bool internal);
253
254static void
255stream_pretty_representation_of_fn_parms(const function_type& fn_type,
256 ostream& o, bool qualified,
257 bool internal);
258static string
259add_outer_pointer_to_fn_type_expr(const type_base* pointer_to_fn,
260 const string& input, bool qualified,
261 bool internal);
262
263static string
264add_outer_pointer_to_fn_type_expr(const type_base_sptr& pointer_to_fn,
265 const string& input, bool qualified,
266 bool internal);
267
268static string
269add_outer_pointer_to_array_type_expr(const type_base* pointer_to_ar,
270 const string& input, bool qualified,
271 bool internal);
272
273static string
274add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
275 const string& input, bool qualified,
276 bool internal);
277
278static string
279add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
280 const string& input, bool qualified,
281 bool internal);
282
283static string
284add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
285 const string& input, bool qualified,
286 bool internal);
287
288static string
289add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
290 const string& input,
291 bool qualified, bool internal);
292
293void
294push_composite_type_comparison_operands(const type_base& left,
295 const type_base& right);
296
297void
298pop_composite_type_comparison_operands(const type_base& left,
299 const type_base& right);
300
301bool
302mark_dependant_types_compared_until(const type_base &r);
303
304/// Push a pair of operands on the stack of operands of the current
305/// type comparison, during type canonicalization.
306///
307/// For more information on this, please look at the description of
308/// the environment::priv::right_type_comp_operands_ data member.
309///
310/// @param left the left-hand-side comparison operand to push.
311///
312/// @param right the right-hand-side comparison operand to push.
313void
315 const type_base& right)
316{
317 const environment& env = left.get_environment();
318 env.priv_->push_composite_type_comparison_operands(&left, &right);
319}
320
321/// Pop a pair of operands from the stack of operands to the current
322/// type comparison.
323///
324/// For more information on this, please look at the description of
325/// the environment::privright_type_comp_operands_ data member.
326///
327/// @param left the left-hand-side comparison operand we expect to
328/// pop from the top of the stack. If this doesn't match the
329/// operand found on the top of the stack, the function aborts.
330///
331/// @param right the right-hand-side comparison operand we expect to
332/// pop from the bottom of the stack. If this doesn't match the
333/// operand found on the top of the stack, the function aborts.
334void
336 const type_base& right)
337{
338 const environment& env = left.get_environment();
339 env.priv_->pop_composite_type_comparison_operands(&left, &right);
340}
341
342/// In the stack of the current types being compared (as part of type
343/// canonicalization), mark all the types that comes after a certain
344/// one as NOT being eligible to the canonical type propagation
345/// optimization.
346///
347/// For a starter, please read about the @ref
348/// OnTheFlyCanonicalization, aka, "canonical type propagation
349/// optimization".
350///
351/// To implement that optimization, we need, among other things to
352/// maintain stack of the types (and their sub-types) being
353/// currently compared as part of type canonicalization.
354///
355/// Note that we only consider the type that is the right-hand-side
356/// operand of the comparison because it's that one that is being
357/// canonicalized and thus, that is not yet canonicalized.
358///
359/// The reason why a type is deemed NON-eligible to the canonical
360/// type propagation optimization is that it "depends" on
361/// recursively present type. Let me explain.
362///
363/// Suppose we have a type T that has sub-types named ST0 and ST1.
364/// Suppose ST1 itself has a sub-type that is T itself. In this
365/// case, we say that T is a recursive type, because it has T
366/// (itself) as one of its sub-types:
367///
368/// T
369/// +-- ST0
370/// |
371/// +-- ST1
372/// +
373/// |
374/// +-- T
375///
376/// ST1 is said to "depend" on T because it has T as a sub-type.
377/// But because T is recursive, then ST1 is said to depend on a
378/// recursive type. Notice however that ST0 does not depend on any
379/// recursive type.
380///
381/// When we are at the point of comparing the sub-type T of ST1
382/// against its counterpart, the stack of the right-hand-side
383/// operands of the type canonicalization is going to look like
384/// this:
385///
386/// | T | ST1 |
387///
388/// We don't add the type T to the stack as we detect that T was
389/// already in there (recursive cycle).
390///
391/// So, this function will basically mark ST1 as being NON-eligible
392/// to being the target of canonical type propagation, by marking ST1
393/// as being dependant on T.
394///
395/// @param right the right-hand-side operand of the type comparison.
396///
397/// @return true iff the operation was successful.
398bool
400{
401 const environment& env = r.get_environment();
403 return env.priv_->mark_dependant_types_compared_until(&r);
404 return false;
405}
406
407/// @brief the location of a token represented in its simplest form.
408/// Instances of this type are to be stored in a sorted vector, so the
409/// type must have proper relational operators.
410class expanded_location
411{
412 string path_;
413 unsigned line_;
414 unsigned column_;
415
416 expanded_location();
417
418public:
419
420 friend class location_manager;
421
422 expanded_location(const string& path, unsigned line, unsigned column)
423 : path_(path), line_(line), column_(column)
424 {}
425
426 bool
427 operator==(const expanded_location& l) const
428 {
429 return (path_ == l.path_
430 && line_ == l.line_
431 && column_ && l.column_);
432 }
433
434 bool
435 operator<(const expanded_location& l) const
436 {
437 if (path_ < l.path_)
438 return true;
439 else if (path_ > l.path_)
440 return false;
441
442 if (line_ < l.line_)
443 return true;
444 else if (line_ > l.line_)
445 return false;
446
447 return column_ < l.column_;
448 }
449};
450
451/// Expand the location into a tripplet path, line and column number.
452///
453/// @param path the output parameter where this function sets the
454/// expanded path.
455///
456/// @param line the output parameter where this function sets the
457/// expanded line.
458///
459/// @param column the ouptut parameter where this function sets the
460/// expanded column.
461void
462location::expand(std::string& path, unsigned& line, unsigned& column) const
463{
464 if (!get_location_manager())
465 {
466 // We don't have a location manager maybe because this location
467 // was just freshly instanciated. We still want to be able to
468 // expand to default values.
469 path = "";
470 line = 0;
471 column = 0;
472 return;
473 }
474 get_location_manager()->expand_location(*this, path, line, column);
475}
476
477
478/// Expand the location into a string.
479///
480/// @return the string representing the location.
481string
483{
484 string path, result;
485 unsigned line = 0, column = 0;
486 expand(path, line, column);
487
488 std::ostringstream o;
489 o << path << ":" << line << ":" << column;
490 return o.str();
491}
492
493struct location_manager::priv
494{
495 /// This sorted vector contains the expanded locations of the tokens
496 /// coming from a given ABI Corpus. The index of a given expanded
497 /// location in the table gives us an integer that is used to build
498 /// instance of location types.
499 std::vector<expanded_location> locs;
500};
501
502location_manager::location_manager()
503 : priv_(new location_manager::priv)
504{}
505
506location_manager::~location_manager() = default;
507
508/// Insert the triplet representing a source locus into our internal
509/// vector of location triplet. Return an instance of location type,
510/// built from an integral type that represents the index of the
511/// source locus triplet into our source locus table.
512///
513/// @param file_path the file path of the source locus
514/// @param line the line number of the source location
515/// @param col the column number of the source location
516location
517location_manager::create_new_location(const std::string& file_path,
518 size_t line,
519 size_t col)
520{
521 expanded_location l(file_path, line, col);
522
523 // Just append the new expanded location to the end of the vector
524 // and return its index. Note that indexes start at 1.
525 priv_->locs.push_back(l);
526 return location(priv_->locs.size(), this);
527}
528
529/// Given an instance of location type, return the triplet
530/// {path,line,column} that represents the source locus. Note that
531/// the location must have been previously created from the function
532/// location_manager::create_new_location, otherwise this function yields
533/// unexpected results, including possibly a crash.
534///
535/// @param location the instance of location type to expand
536/// @param path the resulting path of the source locus
537/// @param line the resulting line of the source locus
538/// @param column the resulting colum of the source locus
539void
541 std::string& path,
542 unsigned& line,
543 unsigned& column) const
544{
545 if (location.value_ == 0)
546 return;
547 expanded_location &l = priv_->locs[location.value_ - 1];
548 path = l.path_;
549 line = l.line_;
550 column = l.column_;
551}
552
553typedef unordered_map<function_type_sptr,
554 bool,
556 type_shared_ptr_equal> fn_type_ptr_map;
557
558// <type_maps stuff>
559
560struct type_maps::priv
561{
562 mutable istring_type_base_wptrs_map_type basic_types_;
563 mutable istring_type_base_wptrs_map_type class_types_;
564 mutable istring_type_base_wptrs_map_type union_types_;
565 mutable istring_type_base_wptrs_map_type enum_types_;
566 mutable istring_type_base_wptrs_map_type typedef_types_;
567 mutable istring_type_base_wptrs_map_type qualified_types_;
568 mutable istring_type_base_wptrs_map_type pointer_types_;
569 mutable istring_type_base_wptrs_map_type ptr_to_mbr_types_;
570 mutable istring_type_base_wptrs_map_type reference_types_;
571 mutable istring_type_base_wptrs_map_type array_types_;
572 mutable istring_type_base_wptrs_map_type subrange_types_;
573 mutable istring_type_base_wptrs_map_type function_types_;
574 mutable vector<type_base_wptr> sorted_types_;
575}; // end struct type_maps::priv
576
577type_maps::type_maps()
578 : priv_(new priv)
579{}
580
581type_maps::~type_maps() = default;
582
583/// Test if the type_maps is empty.
584///
585/// @return true iff the type_maps is empty.
586bool
588{
589 return (basic_types().empty()
590 && class_types().empty()
591 && union_types().empty()
592 && enum_types().empty()
593 && typedef_types().empty()
595 && pointer_types().empty()
597 && array_types().empty()
598 && subrange_types().empty()
599 && function_types().empty());
600}
601
602/// Getter for the map that associates the name of a basic type to the
603/// vector instances of type_decl_sptr that represents that type.
606{return priv_->basic_types_;}
607
608/// Getter for the map that associates the name of a basic type to the
609/// vector of instances of @ref type_decl_sptr that represents that
610/// type.
613{return priv_->basic_types_;}
614
615/// Getter for the map that associates the name of a class type to the
616/// vector of instances of @ref class_decl_sptr that represents that
617/// type.
620{return priv_->class_types_;}
621
622/// Getter for the map that associates the name of a class type to the
623/// vector of instances of @ref class_decl_sptr that represents that
624/// type.
627{return priv_->class_types_;}
628
629/// Getter for the map that associates the name of a union type to the
630/// vector of instances of @ref union_decl_sptr that represents that
631/// type.
634{return priv_->union_types_;}
635
636/// Getter for the map that associates the name of a union type to the
637/// vector of instances of @ref union_decl_sptr that represents that
638/// type.
641{return priv_->union_types_;}
642
643/// Getter for the map that associates the name of an enum type to the
644/// vector of instances of @ref enum_type_decl_sptr that represents
645/// that type.
648{return priv_->enum_types_;}
649
650/// Getter for the map that associates the name of an enum type to the
651/// vector of instances of @ref enum_type_decl_sptr that represents
652/// that type.
655{return priv_->enum_types_;}
656
657/// Getter for the map that associates the name of a typedef to the
658/// vector of instances of @ref typedef_decl_sptr that represents tha
659/// type.
662{return priv_->typedef_types_;}
663
664/// Getter for the map that associates the name of a typedef to the
665/// vector of instances of @ref typedef_decl_sptr that represents tha
666/// type.
669{return priv_->typedef_types_;}
670
671/// Getter for the map that associates the name of a qualified type to
672/// the vector of instances of @ref qualified_type_def_sptr.
675{return priv_->qualified_types_;}
676
677/// Getter for the map that associates the name of a qualified type to
678/// the vector of instances of @ref qualified_type_def_sptr.
681{return priv_->qualified_types_;}
682
683/// Getter for the map that associates the name of a pointer type to
684/// the vector of instances of @ref pointer_type_def_sptr that
685/// represents that type.
688{return priv_->pointer_types_;}
689
690/// Getter for the map that associates the name of a pointer-to-member
691/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
692/// represents that type.
695{return priv_->ptr_to_mbr_types_;}
696
697/// Getter for the map that associates the name of a pointer-to-member
698/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
699/// represents that type.
702{return priv_->ptr_to_mbr_types_;}
703
704/// Getter for the map that associates the name of a pointer type to
705/// the vector of instances of @ref pointer_type_def_sptr that
706/// represents that type.
709{return priv_->pointer_types_;}
710
711/// Getter for the map that associates the name of a reference type to
712/// the vector of instances of @ref reference_type_def_sptr that
713/// represents that type.
716{return priv_->reference_types_;}
717
718/// Getter for the map that associates the name of a reference type to
719/// the vector of instances of @ref reference_type_def_sptr that
720/// represents that type.
723{return priv_->reference_types_;}
724
725/// Getter for the map that associates the name of an array type to
726/// the vector of instances of @ref array_type_def_sptr that
727/// represents that type.
730{return priv_->array_types_;}
731
732/// Getter for the map that associates the name of an array type to
733/// the vector of instances of @ref array_type_def_sptr that
734/// represents that type.
737{return priv_->array_types_;}
738
739/// Getter for the map that associates the name of a subrange type to
740/// the vector of instances of @ref array_type_def::subrange_sptr that
741/// represents that type.
744{return priv_->subrange_types_;}
745
746/// Getter for the map that associates the name of a subrange type to
747/// the vector of instances of @ref array_type_def::subrange_sptr that
748/// represents that type.
751{return priv_->subrange_types_;}
752
753/// Getter for the map that associates the name of a function type to
754/// the vector of instances of @ref function_type_sptr that represents
755/// that type.
758{return priv_->function_types_;}
759
760/// Getter for the map that associates the name of a function type to
761/// the vector of instances of @ref function_type_sptr that represents
762/// that type.
765{return priv_->function_types_;}
766
767/// A comparison functor to compare/sort types based on their pretty
768/// representations.
769struct type_name_comp
770{
771 /// Comparison operator for two instances of @ref type_base.
772 ///
773 /// This compares the two types by lexicographically comparing their
774 /// pretty representation.
775 ///
776 /// @param l the left-most type to compare.
777 ///
778 /// @param r the right-most type to compare.
779 ///
780 /// @return true iff @p l < @p r.
781 bool
782 operator()(type_base *l, type_base *r) const
783 {
784 if (l == 0 && r == 0)
785 return false;
786
787 string l_repr = get_pretty_representation(l);
788 string r_repr = get_pretty_representation(r);
789 return l_repr < r_repr;
790 }
791
792 /// Comparison operator for two instances of @ref type_base.
793 ///
794 /// This compares the two types by lexicographically comparing their
795 /// pretty representation.
796 ///
797 /// @param l the left-most type to compare.
798 ///
799 /// @param r the right-most type to compare.
800 ///
801 /// @return true iff @p l < @p r.
802 bool
803 operator()(const type_base_sptr &l, const type_base_sptr &r) const
804 {return operator()(l.get(), r.get());}
805
806 /// Comparison operator for two instances of @ref type_base.
807 ///
808 /// This compares the two types by lexicographically comparing their
809 /// pretty representation.
810 ///
811 /// @param l the left-most type to compare.
812 ///
813 /// @param r the right-most type to compare.
814 ///
815 /// @return true iff @p l < @p r.
816 bool
817 operator()(const type_base_wptr &l, const type_base_wptr &r) const
818 {return operator()(type_base_sptr(l), type_base_sptr(r));}
819}; // end struct type_name_comp
820
821#ifdef WITH_DEBUG_SELF_COMPARISON
822
823/// This is a function called when the ABG_RETURN* macros defined
824/// below return false.
825///
826/// The purpose of this function is to ease debugging. To know where
827/// the equality functions first compare non-equal, we can just set a
828/// breakpoint on this notify_equality_failed function and run the
829/// equality functions. Because all the equality functions use the
830/// ABG_RETURN* macros to return their values, this function is always
831/// called when any of those equality function return false.
832///
833/// @param l the first operand of the equality.
834///
835/// @param r the second operand of the equality.
836static void
837notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
838 const type_or_decl_base &r __attribute__((unused)))
839{}
840
841/// This is a function called when the ABG_RETURN* macros defined
842/// below return false.
843///
844/// The purpose of this function is to ease debugging. To know where
845/// the equality functions first compare non-equal, we can just set a
846/// breakpoint on this notify_equality_failed function and run the
847/// equality functions. Because all the equality functions use the
848/// ABG_RETURN* macros to return their values, this function is always
849/// called when any of those equality function return false.
850///
851/// @param l the first operand of the equality.
852///
853/// @param r the second operand of the equality.
854static void
855notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
856 const type_or_decl_base *r __attribute__((unused)))
857{}
858
859#define ABG_RETURN_EQUAL(l, r) \
860 do \
861 { \
862 if (l != r) \
863 notify_equality_failed(l, r); \
864 return (l == r); \
865 } \
866 while(false)
867
868
869#define ABG_RETURN_FALSE \
870 do \
871 { \
872 notify_equality_failed(l, r); \
873 return false; \
874 } while(false)
875
876#define ABG_RETURN(value) \
877 do \
878 { \
879 if (value == false) \
880 notify_equality_failed(l, r); \
881 return value; \
882 } while (false)
883
884#else // WITH_DEBUG_SELF_COMPARISON
885
886#define ABG_RETURN_FALSE return false
887#define ABG_RETURN(value) return (value)
888#define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
889#endif
890
891/// Compare two types by comparing their canonical types if present.
892///
893/// If the canonical types are not present (because the types have not
894/// yet been canonicalized, for instance) then the types are compared
895/// structurally.
896///
897/// @param l the first type to take into account in the comparison.
898///
899/// @param r the second type to take into account in the comparison.
900template<typename T>
901bool
902try_canonical_compare(const T *l, const T *r)
903{
904#if WITH_DEBUG_TYPE_CANONICALIZATION
905 // We are debugging the canonicalization of a type down the stack.
906 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
907 // type being canonicalized. We are at a point where we can compare
908 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
909 // have canonical types) or structural comparison.
910 //
911 // Because we are debugging the process of type canonicalization, we
912 // want to compare 'l' and 'r' canonically *AND* structurally. Both
913 // kinds of comparison should yield the same result, otherwise type
914 // canonicalization just failed for the subtype 'r' of the type
915 // being canonicalized.
916 //
917 // In concrete terms, this function is going to be called twice with
918 // the same pair {'l', 'r'} to compare: The first time with
919 // environment::priv_->use_canonical_type_comparison_ set to true,
920 // instructing us to compare them canonically, and the second time
921 // with that boolean set to false, instructing us to compare them
922 // structurally.
923 const environment&env = l->get_environment();
924 if (env.priv_->use_canonical_type_comparison_)
925 {
926 if (const type_base *lc = l->get_naked_canonical_type())
927 if (const type_base *rc = r->get_naked_canonical_type())
928 ABG_RETURN_EQUAL(lc, rc);
929 }
930 return equals(*l, *r, 0);
931#else
932 if (const type_base *lc = l->get_naked_canonical_type())
933 if (const type_base *rc = r->get_naked_canonical_type())
934 ABG_RETURN_EQUAL(lc, rc);
935 return equals(*l, *r, 0);
936#endif
937
938
939}
940
941/// Detect if a recursive comparison cycle is detected while
942/// structurally comparing two types (a.k.a member-wise comparison).
943///
944/// @param l the left-hand-side operand of the current comparison.
945///
946/// @param r the right-hand-side operand of the current comparison.
947///
948/// @return true iff a comparison cycle is detected.
949template<typename T>
950bool
952{
953 bool result = l.priv_->comparison_started(l, r);
954 return result ;
955}
956
957/// Detect if a recursive comparison cycle is detected while
958/// structurally comparing two @ref class_decl types.
959///
960/// @param l the left-hand-side operand of the current comparison.
961///
962/// @param r the right-hand-side operand of the current comparison.
963///
964/// @return true iff a comparison cycle is detected.
965template<>
966bool
968{
969 return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
970 static_cast<const class_or_union&>(r));
971}
972
973/// This macro is to be used while comparing composite types that
974/// might recursively refer to themselves. Comparing two such types
975/// might get us into a cyle.
976///
977/// Practically, if we detect that we are already into comparing 'l'
978/// and 'r'; then, this is a cycle.
979//
980/// To break the cycle, we assume the result of the comparison is true
981/// for now. Comparing the other sub-types of l & r will tell us later
982/// if l & r are actually different or not.
983///
984/// In the mean time, returning true from this macro should not be
985/// used to propagate the canonical type of 'l' onto 'r' as we don't
986/// know yet if l equals r. All the types that depend on l and r
987/// can't (and that are in the comparison stack currently) can't have
988/// their canonical type propagated either. So this macro disallows
989/// canonical type propagation for those types that depend on a
990/// recursively defined sub-type for now.
991///
992/// @param l the left-hand-side operand of the comparison.
993#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
994 do \
995 { \
996 if (is_comparison_cycle_detected(l, r)) \
997 { \
998 mark_dependant_types_compared_until(r); \
999 return true; \
1000 } \
1001 } \
1002 while(false)
1003
1004
1005/// Mark a pair of types as being compared.
1006///
1007/// This is helpful to later detect recursive cycles in the comparison
1008/// stack.
1009///
1010/// @param l the left-hand-side operand of the comparison.
1011///
1012/// @parm r the right-hand-side operand of the comparison.
1013template<typename T>
1014void
1016{
1017 l.priv_->mark_as_being_compared(l, r);
1019}
1020
1021/// Mark a pair of @ref class_decl types as being compared.
1022///
1023/// This is helpful to later detect recursive cycles in the comparison
1024/// stack.
1025///
1026/// @param l the left-hand-side operand of the comparison.
1027///
1028/// @parm r the right-hand-side operand of the comparison.
1029template<>
1030void
1032{
1033 return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
1034 static_cast<const class_or_union&>(r));
1035}
1036
1037/// Mark a pair of types as being not compared anymore.
1038///
1039/// This is helpful to later detect recursive cycles in the comparison
1040/// stack.
1041///
1042/// Note that the types must have been passed to
1043/// mark_types_as_being_compared prior to calling this function.
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_->unmark_as_being_compared(l, r);
1054}
1055
1056/// Mark a pair of @ref class_decl types as being not compared
1057/// anymore.
1058///
1059/// This is helpful to later detect recursive cycles in the comparison
1060/// stack.
1061///
1062/// Note that the types must have been passed to
1063/// mark_types_as_being_compared prior to calling this function.
1064///
1065/// @param l the left-hand-side operand of the comparison.
1066///
1067/// @parm r the right-hand-side operand of the comparison.
1068template<>
1069void
1071{
1072 return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
1073 static_cast<const class_or_union&>(r));
1074}
1075
1076/// Return the result of the comparison of two (sub) types.
1077///
1078/// The function does the necessary book keeping before returning the
1079/// result of the comparison of two (sub) types.
1080///
1081/// The book-keeping done is in the following
1082/// areas:
1083///
1084/// * Management of the Canonical Type Propagation optimization
1085/// * type comparison cycle detection
1086///
1087/// @param l the left-hand-side operand of the type comparison
1088///
1089/// @param r the right-hand-side operand of the type comparison
1090///
1091/// @param propagate_canonical_type if true, it means the function
1092/// performs the @ref OnTheFlyCanonicalization, aka, "canonical type
1093/// propagation optimization".
1094///
1095/// @param value the result of the comparison of @p l and @p r.
1096///
1097/// @return the value @p value.
1098template<typename T>
1099bool
1100return_comparison_result(T& l, T& r, bool value,
1101 bool propagate_canonical_type = true)
1102{
1103 if (propagate_canonical_type && (value == true))
1104 maybe_propagate_canonical_type(l, r);
1105
1107
1108 const environment& env = l.get_environment();
1110 // We are instructed to perform the "canonical type propagation"
1111 // optimization, making 'r' to possibly get the canonical type of
1112 // 'l' if it has one. This mostly means that we are currently
1113 // canonicalizing the type that contain the subtype provided in
1114 // the 'r' argument.
1115 {
1116 if (value == true
1117 && (is_type(&r)->priv_->depends_on_recursive_type()
1118 || env.priv_->is_recursive_type(&r))
1119 && is_type(&r)->priv_->canonical_type_propagated()
1120 && !is_type(&r)->priv_->propagated_canonical_type_confirmed()
1121 && !env.priv_->right_type_comp_operands_.empty())
1122 {
1123 // Track the object 'r' for which the propagated canonical
1124 // type might be re-initialized if the current comparison
1125 // eventually fails.
1126 env.priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
1127 }
1128 else if (value == true
1129 && env.priv_->right_type_comp_operands_.empty()
1130 && is_type(&r)->priv_->canonical_type_propagated()
1131 && !is_type(&r)->priv_->propagated_canonical_type_confirmed())
1132 {
1133 // The type provided in the 'r' argument is the type that is
1134 // being canonicalized; 'r' is not a mere subtype being
1135 // compared, it's the whole type being canonicalized. And
1136 // its canonicalization has just succeeded.
1137 //
1138 // Let's confirm the canonical type resulting from the
1139 // "canonical type propagation" optimization.
1140 env.priv_->confirm_ct_propagation(&r);
1141 }
1142 else if (value == true
1143 && is_type(&r)->priv_->canonical_type_propagated()
1144 && !is_type(&r)->priv_->propagated_canonical_type_confirmed())
1145 // In any other case, we are not sure if propagated types
1146 // should be confirmed yet. So let's mark them as such.
1147 env.priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
1148 else if (value == false)
1149 {
1150 // The comparison of the current sub-type failed. So all
1151 // the with non-confirmed propagated types (those in
1152 // env.prix_->types_with_non_confirmed_propagated_ct_)
1153 // should see their tentatively propagated canonical type
1154 // cancelled.
1155 env.priv_->cancel_all_non_confirmed_propagated_canonical_types();
1156 }
1157 }
1158
1159 // If we reached this point with value == true and the stack of
1160 // types being compared is empty, then it means that the type pair
1161 // that was at the bottom of the stack is now fully compared.
1162 //
1163 // It follows that all types that were target of canonical type
1164 // propagation can now see their tentative canonical type be
1165 // confirmed for real.
1166 if (value == true
1167 && env.priv_->right_type_comp_operands_.empty()
1168 && !env.priv_->types_with_non_confirmed_propagated_ct_.empty())
1169 // So the comparison is completely done and there are some
1170 // types for which their propagated canonical type is sitll
1171 // considered not confirmed. As the comparison did yield true, we
1172 // shall now confirm the propagation for all those types.
1173 env.priv_->confirm_ct_propagation();
1174
1175#ifdef WITH_DEBUG_SELF_COMPARISON
1176 if (value == false && env.priv_->right_type_comp_operands_.empty())
1177 {
1178 for (const auto i : env.priv_->types_with_non_confirmed_propagated_ct_)
1179 {
1180 type_base *t = reinterpret_cast<type_base*>(i);
1181 env.priv_->check_abixml_canonical_type_propagation_during_self_comp(t);
1182 }
1183 }
1184#endif
1185
1186 ABG_RETURN(value);
1187}
1188
1189#define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1190 do \
1191 { \
1192 bool res = return_comparison_result(l, r, value); \
1193 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1194 return res; \
1195 } while (false)
1196
1197/// Cache the result of a comparison between too artifacts (l & r) and
1198/// return immediately.
1199///
1200/// @param value the value to cache.
1201#define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1202 do \
1203 { \
1204 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1205 return value; \
1206 } while (false)
1207
1208/// Getter of all types types sorted by their pretty representation.
1209///
1210/// @return a sorted vector of all types sorted by their pretty
1211/// representation.
1212const vector<type_base_wptr>&
1214{
1215 if (priv_->sorted_types_.empty())
1216 {
1217 istring_type_base_wptrs_map_type::const_iterator i;
1218 vector<type_base_wptr>::const_iterator j;
1219
1220 for (i = basic_types().begin(); i != basic_types().end(); ++i)
1221 for (j = i->second.begin(); j != i->second.end(); ++j)
1222 priv_->sorted_types_.push_back(*j);
1223
1224 for (i = class_types().begin(); i != class_types().end(); ++i)
1225 for (j = i->second.begin(); j != i->second.end(); ++j)
1226 priv_->sorted_types_.push_back(*j);
1227
1228 for (i = union_types().begin(); i != union_types().end(); ++i)
1229 for (j = i->second.begin(); j != i->second.end(); ++j)
1230 priv_->sorted_types_.push_back(*j);
1231
1232 for (i = enum_types().begin(); i != enum_types().end(); ++i)
1233 for (j = i->second.begin(); j != i->second.end(); ++j)
1234 priv_->sorted_types_.push_back(*j);
1235
1236 for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
1237 for (j = i->second.begin(); j != i->second.end(); ++j)
1238 priv_->sorted_types_.push_back(*j);
1239
1240 type_name_comp comp;
1241 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1242 }
1243
1244 return priv_->sorted_types_;
1245}
1246
1247// </type_maps stuff>
1248
1249// <translation_unit stuff>
1250
1251/// Constructor of translation_unit.
1252///
1253/// @param env the environment of this translation unit. Please note
1254/// that the life time of the environment must be greater than the
1255/// life time of the translation unit because the translation uses
1256/// resources that are allocated in the environment.
1257///
1258/// @param path the location of the translation unit.
1259///
1260/// @param address_size the size of addresses in the translation unit,
1261/// in bits.
1262translation_unit::translation_unit(const environment& env,
1263 const std::string& path,
1264 char address_size)
1265 : priv_(new priv(env))
1266{
1267 priv_->path_ = path;
1268 priv_->address_size_ = address_size;
1269}
1270
1271/// Getter of the the global scope of the translation unit.
1272///
1273/// @return the global scope of the current translation unit. If
1274/// there is not global scope allocated yet, this function creates one
1275/// and returns it.
1276const scope_decl_sptr&
1278{
1279 return const_cast<translation_unit*>(this)->get_global_scope();
1280}
1281
1282/// Getter of the the global scope of the translation unit.
1283///
1284/// @return the global scope of the current translation unit. If
1285/// there is not global scope allocated yet, this function creates one
1286/// and returns it.
1289{
1290 if (!priv_->global_scope_)
1291 {
1292 priv_->global_scope_.reset
1293 (new global_scope(const_cast<translation_unit*>(this)));
1294 priv_->global_scope_->set_translation_unit
1295 (const_cast<translation_unit*>(this));
1296 }
1297 return priv_->global_scope_;
1298}
1299
1300/// Getter of the types of the current @ref translation_unit.
1301///
1302/// @return the maps of the types of the translation unit.
1303const type_maps&
1305{return priv_->types_;}
1306
1307/// Getter of the types of the current @ref translation_unit.
1308///
1309/// @return the maps of the types of the translation unit.
1310type_maps&
1312{return priv_->types_;}
1313
1314/// Get the vector of function types that are used in the current
1315/// translation unit.
1316///
1317/// @return the vector of function types that are used in the current
1318/// translation unit.
1319const vector<function_type_sptr>&
1321{return priv_->live_fn_types_;}
1322
1323/// Getter of the environment of the current @ref translation_unit.
1324///
1325/// @return the translation unit of the current translation unit.
1326const environment&
1328{return priv_->env_;}
1329
1330/// Getter of the language of the source code of the translation unit.
1331///
1332/// @return the language of the source code.
1335{return priv_->language_;}
1336
1337/// Setter of the language of the source code of the translation unit.
1338///
1339/// @param l the new language.
1340void
1342{priv_->language_ = l;}
1343
1344
1345/// Get the path of the current translation unit.
1346///
1347/// This path is relative to the build directory of the translation
1348/// unit as returned by translation_unit::get_compilation_dir_path.
1349///
1350/// @return the relative path of the compilation unit associated to
1351/// the current instance of translation_unit.
1352//
1353const std::string&
1355{return priv_->path_;}
1356
1357/// Set the path associated to the current instance of
1358/// translation_unit.
1359///
1360/// This path is relative to the build directory of the translation
1361/// unit as returned by translation_unit::get_compilation_dir_path.
1362///
1363/// @param a_path the new relative path to set.
1364void
1365translation_unit::set_path(const string& a_path)
1366{priv_->path_ = a_path;}
1367
1368
1369/// Get the path of the directory that was 'current' when the
1370/// translation unit was compiled.
1371///
1372/// Note that the path returned by translation_unit::get_path is
1373/// relative to the path returned by this function.
1374///
1375/// @return the compilation directory for the current translation
1376/// unit.
1377const std::string&
1379{return priv_->comp_dir_path_;}
1380
1381/// Set the path of the directory that was 'current' when the
1382/// translation unit was compiled.
1383///
1384/// Note that the path returned by translation_unit::get_path is
1385/// relative to the path returned by this function.
1386///
1387/// @param the compilation directory for the current translation unit.
1388void
1390{priv_->comp_dir_path_ = d;}
1391
1392/// Get the concatenation of the build directory and the relative path
1393/// of the translation unit.
1394///
1395/// @return the absolute path of the translation unit.
1396const std::string&
1398{
1399 if (priv_->abs_path_.empty())
1400 {
1401 string path;
1402 if (!priv_->path_.empty())
1403 {
1404 if (!priv_->comp_dir_path_.empty())
1405 {
1406 path = priv_->comp_dir_path_;
1407 path += "/";
1408 }
1409 path += priv_->path_;
1410 }
1411 priv_->abs_path_ = path;
1412 }
1413
1414 return priv_->abs_path_;
1415}
1416
1417/// Set the corpus this translation unit is a member of.
1418///
1419/// Note that adding a translation unit to a @ref corpus automatically
1420/// triggers a call to this member function.
1421///
1422/// @param corpus the corpus.
1423void
1425{priv_->corp = c;}
1426
1427/// Get the corpus this translation unit is a member of.
1428///
1429/// @return the parent corpus, or nil if this doesn't belong to any
1430/// corpus yet.
1431corpus*
1433{return priv_->corp;}
1434
1435/// Get the corpus this translation unit is a member of.
1436///
1437/// @return the parent corpus, or nil if this doesn't belong to any
1438/// corpus yet.
1439const corpus*
1441{return const_cast<translation_unit*>(this)->get_corpus();}
1442
1443/// Getter of the location manager for the current translation unit.
1444///
1445/// @return a reference to the location manager for the current
1446/// translation unit.
1449{return priv_->loc_mgr_;}
1450
1451/// const Getter of the location manager.
1452///
1453/// @return a const reference to the location manager for the current
1454/// translation unit.
1455const location_manager&
1457{return priv_->loc_mgr_;}
1458
1459/// Tests whether if the current translation unit contains ABI
1460/// artifacts or not.
1461///
1462/// @return true iff the current translation unit is empty.
1463bool
1465{
1466 if (!priv_->global_scope_)
1467 return true;
1468 return get_global_scope()->is_empty();
1469}
1470
1471/// Getter of the address size in this translation unit.
1472///
1473/// @return the address size, in bits.
1474char
1476{return priv_->address_size_;}
1477
1478/// Setter of the address size in this translation unit.
1479///
1480/// @param a the new address size in bits.
1481void
1483{priv_->address_size_= a;}
1484
1485/// Getter of the 'is_constructed" flag. It says if the translation
1486/// unit is fully constructed or not.
1487///
1488/// This flag is important for cases when comparison might depend on
1489/// if the translation unit is fully built or not. For instance, when
1490/// reading types from DWARF, the virtual methods of a class are not
1491/// necessarily fully constructed until we have reached the end of the
1492/// translation unit. In that case, before we've reached the end of
1493/// the translation unit, we might not take virtual functions into
1494/// account when comparing classes.
1495///
1496/// @return true if the translation unit is constructed.
1497bool
1499{return priv_->is_constructed_;}
1500
1501/// Setter of the 'is_constructed" flag. It says if the translation
1502/// unit is fully constructed or not.
1503///
1504/// This flag is important for cases when comparison might depend on
1505/// if the translation unit is fully built or not. For instance, when
1506/// reading types from DWARF, the virtual methods of a class are not
1507/// necessarily fully constructed until we have reached the end of the
1508/// translation unit. In that case, before we've reached the end of
1509/// the translation unit, we might not take virtual functions into
1510/// account when comparing classes.
1511///
1512/// @param f true if the translation unit is constructed.
1513void
1515{priv_->is_constructed_ = f;}
1516
1517/// Compare the current translation unit against another one.
1518///
1519/// @param other the other tu to compare against.
1520///
1521/// @return true if the two translation units are equal, false
1522/// otherwise.
1523bool
1525{
1526 if (get_address_size() != other.get_address_size())
1527 return false;
1528
1529 return *get_global_scope() == *other.get_global_scope();
1530}
1531
1532/// Inequality operator.
1533///
1534/// @param o the instance of @ref translation_unit to compare the
1535/// current instance against.
1536///
1537/// @return true iff the current instance is different from @p o.
1538bool
1540{return ! operator==(o);}
1541
1542/// Ensure that the life time of a function type is bound to the life
1543/// time of the current translation unit.
1544///
1545/// @param ftype the function time which life time to bind to the life
1546/// time of the current instance of @ref translation_unit. That is,
1547/// it's onlyh when the translation unit is destroyed that the
1548/// function type can be destroyed to.
1549void
1551{
1552 const environment& env = get_environment();
1553
1554 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1555
1556 interned_string repr = get_type_name(ftype);
1557 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1558 push_back(ftype);
1559
1560 // The function type must be out of the same environment as its
1561 // translation unit.
1562 {
1563 const environment& e = ftype->get_environment();
1564 ABG_ASSERT(&env == &e);
1565 }
1566
1567 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1568 ABG_ASSERT(existing_tu == this);
1569 else
1570 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1571
1573}
1574
1575/// This implements the ir_traversable_base::traverse virtual
1576/// function.
1577///
1578/// @param v the visitor used on the member nodes of the translation
1579/// unit during the traversal.
1580///
1581/// @return true if the entire type IR tree got traversed, false
1582/// otherwise.
1583bool
1585{return get_global_scope()->traverse(v);}
1586
1587translation_unit::~translation_unit()
1588{}
1589
1590/// Converts a translation_unit::language enumerator into a string.
1591///
1592/// @param l the language enumerator to translate.
1593///
1594/// @return the resulting string.
1595string
1597{
1598 switch (l)
1599 {
1600 case translation_unit::LANG_UNKNOWN:
1601 return "LANG_UNKNOWN";
1602 case translation_unit::LANG_Cobol74:
1603 return "LANG_Cobol74";
1604 case translation_unit::LANG_Cobol85:
1605 return "LANG_Cobol85";
1606 case translation_unit::LANG_C89:
1607 return "LANG_C89";
1608 case translation_unit::LANG_C99:
1609 return "LANG_C99";
1610 case translation_unit::LANG_C11:
1611 return "LANG_C11";
1612 case translation_unit::LANG_C:
1613 return "LANG_C";
1614 case translation_unit::LANG_C_plus_plus_11:
1615 return "LANG_C_plus_plus_11";
1616 case translation_unit::LANG_C_plus_plus_14:
1617 return "LANG_C_plus_plus_14";
1618 case translation_unit::LANG_C_plus_plus:
1619 return "LANG_C_plus_plus";
1620 case translation_unit::LANG_ObjC:
1621 return "LANG_ObjC";
1622 case translation_unit::LANG_ObjC_plus_plus:
1623 return "LANG_ObjC_plus_plus";
1624 case translation_unit::LANG_Fortran77:
1625 return "LANG_Fortran77";
1626 case translation_unit::LANG_Fortran90:
1627 return "LANG_Fortran90";
1628 case translation_unit::LANG_Fortran95:
1629 return "LANG_Fortran95";
1630 case translation_unit::LANG_Ada83:
1631 return "LANG_Ada83";
1632 case translation_unit::LANG_Ada95:
1633 return "LANG_Ada95";
1634 case translation_unit::LANG_Pascal83:
1635 return "LANG_Pascal83";
1636 case translation_unit::LANG_Modula2:
1637 return "LANG_Modula2";
1638 case translation_unit::LANG_Java:
1639 return "LANG_Java";
1640 case translation_unit::LANG_PLI:
1641 return "LANG_PLI";
1642 case translation_unit::LANG_UPC:
1643 return "LANG_UPC";
1644 case translation_unit::LANG_D:
1645 return "LANG_D";
1646 case translation_unit::LANG_Python:
1647 return "LANG_Python";
1648 case translation_unit::LANG_Go:
1649 return "LANG_Go";
1650 case translation_unit::LANG_Mips_Assembler:
1651 return "LANG_Mips_Assembler";
1652 default:
1653 return "LANG_UNKNOWN";
1654 }
1655
1656 return "LANG_UNKNOWN";
1657}
1658
1659/// Parse a string representing a language into a
1660/// translation_unit::language enumerator into a string.
1661///
1662/// @param l the string representing the language.
1663///
1664/// @return the resulting translation_unit::language enumerator.
1667{
1668 if (l == "LANG_Cobol74")
1669 return translation_unit::LANG_Cobol74;
1670 else if (l == "LANG_Cobol85")
1671 return translation_unit::LANG_Cobol85;
1672 else if (l == "LANG_C89")
1673 return translation_unit::LANG_C89;
1674 else if (l == "LANG_C99")
1675 return translation_unit::LANG_C99;
1676 else if (l == "LANG_C11")
1677 return translation_unit::LANG_C11;
1678 else if (l == "LANG_C")
1679 return translation_unit::LANG_C;
1680 else if (l == "LANG_C_plus_plus_11")
1681 return translation_unit::LANG_C_plus_plus_11;
1682 else if (l == "LANG_C_plus_plus_14")
1683 return translation_unit::LANG_C_plus_plus_14;
1684 else if (l == "LANG_C_plus_plus")
1685 return translation_unit::LANG_C_plus_plus;
1686 else if (l == "LANG_ObjC")
1687 return translation_unit::LANG_ObjC;
1688 else if (l == "LANG_ObjC_plus_plus")
1689 return translation_unit::LANG_ObjC_plus_plus;
1690 else if (l == "LANG_Fortran77")
1691 return translation_unit::LANG_Fortran77;
1692 else if (l == "LANG_Fortran90")
1693 return translation_unit::LANG_Fortran90;
1694 else if (l == "LANG_Fortran95")
1695 return translation_unit::LANG_Fortran95;
1696 else if (l == "LANG_Ada83")
1697 return translation_unit::LANG_Ada83;
1698 else if (l == "LANG_Ada95")
1699 return translation_unit::LANG_Ada95;
1700 else if (l == "LANG_Pascal83")
1701 return translation_unit::LANG_Pascal83;
1702 else if (l == "LANG_Modula2")
1703 return translation_unit::LANG_Modula2;
1704 else if (l == "LANG_Java")
1705 return translation_unit::LANG_Java;
1706 else if (l == "LANG_PLI")
1707 return translation_unit::LANG_PLI;
1708 else if (l == "LANG_UPC")
1709 return translation_unit::LANG_UPC;
1710 else if (l == "LANG_D")
1711 return translation_unit::LANG_D;
1712 else if (l == "LANG_Python")
1713 return translation_unit::LANG_Python;
1714 else if (l == "LANG_Go")
1715 return translation_unit::LANG_Go;
1716 else if (l == "LANG_Mips_Assembler")
1717 return translation_unit::LANG_Mips_Assembler;
1718
1719 return translation_unit::LANG_UNKNOWN;
1720}
1721
1722/// Test if a language enumerator designates the C language.
1723///
1724/// @param l the language enumerator to consider.
1725///
1726/// @return true iff @p l designates the C language.
1727bool
1729{
1730 return (l == translation_unit::LANG_C89
1731 || l == translation_unit::LANG_C99
1732 || l == translation_unit::LANG_C11
1733 || l == translation_unit::LANG_C);
1734}
1735
1736/// Test if a language enumerator designates the C++ language.
1737///
1738/// @param l the language enumerator to consider.
1739///
1740/// @return true iff @p l designates the C++ language.
1741bool
1743{
1744 return (l == translation_unit::LANG_C_plus_plus_03
1745 || l == translation_unit::LANG_C_plus_plus_11
1746 || l == translation_unit::LANG_C_plus_plus_14
1747 || l == translation_unit::LANG_C_plus_plus);
1748}
1749
1750/// Test if a language enumerator designates the Java language.
1751///
1752/// @param l the language enumerator to consider.
1753///
1754/// @return true iff @p l designates the Java language.
1755bool
1757{return l == translation_unit::LANG_Java;}
1758
1759/// Test if a language enumerator designates the Ada language.
1760///
1761/// @param l the language enumerator to consider.
1762///
1763/// @return true iff @p l designates the Ada language.
1764bool
1766{
1767 return (l == translation_unit::LANG_Ada83
1768 || l == translation_unit::LANG_Ada95);
1769}
1770
1771/// A deep comparison operator for pointers to translation units.
1772///
1773/// @param l the first translation unit to consider for the comparison.
1774///
1775/// @param r the second translation unit to consider for the comparison.
1776///
1777/// @return true if the two translation units are equal, false otherwise.
1778bool
1780{
1781 if (l.get() == r.get())
1782 return true;
1783
1784 if (!!l != !!r)
1785 return false;
1786
1787 return *l == *r;
1788}
1789
1790/// A deep inequality operator for pointers to translation units.
1791///
1792/// @param l the first translation unit to consider for the comparison.
1793///
1794/// @param r the second translation unit to consider for the comparison.
1795///
1796/// @return true iff the two translation units are different.
1797bool
1799{return !operator==(l, r);}
1800
1801// </translation_unit stuff>
1802
1803// <elf_symbol stuff>
1804struct elf_symbol::priv
1805{
1806 const environment& env_;
1807 size_t index_;
1808 size_t size_;
1809 string name_;
1810 elf_symbol::type type_;
1811 elf_symbol::binding binding_;
1812 elf_symbol::version version_;
1813 elf_symbol::visibility visibility_;
1814 bool is_defined_;
1815 // This flag below says if the symbol is a common elf symbol. In
1816 // relocatable files, a common symbol is a symbol defined in a
1817 // section of kind SHN_COMMON.
1818 //
1819 // Note that a symbol of kind STT_COMMON is also considered a common
1820 // symbol. Here is what the gABI says about STT_COMMON and
1821 // SHN_COMMON:
1822 //
1823 // Symbols with type STT_COMMON label uninitialized common
1824 // blocks. In relocatable objects, these symbols are not
1825 // allocated and must have the special section index SHN_COMMON
1826 // (see below). In shared objects and executables these symbols
1827 // must be allocated to some section in the defining object.
1828 //
1829 // In relocatable objects, symbols with type STT_COMMON are
1830 // treated just as other symbols with index SHN_COMMON. If the
1831 // link-editor allocates space for the SHN_COMMON symbol in an
1832 // output section of the object it is producing, it must
1833 // preserve the type of the output symbol as STT_COMMON.
1834 //
1835 // When the dynamic linker encounters a reference to a symbol
1836 // that resolves to a definition of type STT_COMMON, it may (but
1837 // is not required to) change its symbol resolution rules as
1838 // follows: instead of binding the reference to the first symbol
1839 // found with the given name, the dynamic linker searches for
1840 // the first symbol with that name with type other than
1841 // STT_COMMON. If no such symbol is found, it looks for the
1842 // STT_COMMON definition of that name that has the largest size.
1843 bool is_common_;
1844 bool is_in_ksymtab_;
1847 bool is_suppressed_;
1848 elf_symbol_wptr main_symbol_;
1849 elf_symbol_wptr next_alias_;
1850 elf_symbol_wptr next_common_instance_;
1851 string id_string_;
1852
1853 priv(const environment& e)
1854 : env_(e),
1855 index_(),
1856 size_(),
1857 type_(elf_symbol::NOTYPE_TYPE),
1858 binding_(elf_symbol::GLOBAL_BINDING),
1859 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1860 is_defined_(false),
1861 is_common_(false),
1862 is_in_ksymtab_(false),
1863 crc_(),
1864 namespace_(),
1865 is_suppressed_(false)
1866 {}
1867
1868 priv(const environment& e,
1869 size_t i,
1870 size_t s,
1871 const string& n,
1874 bool d,
1875 bool c,
1876 const elf_symbol::version& ve,
1878 bool is_in_ksymtab,
1881 bool is_suppressed)
1882 : env_(e),
1883 index_(i),
1884 size_(s),
1885 name_(n),
1886 type_(t),
1887 binding_(b),
1888 version_(ve),
1889 visibility_(vi),
1890 is_defined_(d),
1891 is_common_(c),
1892 is_in_ksymtab_(is_in_ksymtab),
1893 crc_(crc),
1894 namespace_(ns),
1895 is_suppressed_(is_suppressed)
1896 {
1897 if (!is_common_)
1898 is_common_ = type_ == COMMON_TYPE;
1899 }
1900}; // end struct elf_symbol::priv
1901
1902/// Constructor of the @ref elf_symbol type.
1903///
1904/// Note that this constructor is private, so client code cannot use
1905/// it to create instances of @ref elf_symbol. Rather, client code
1906/// should use the @ref elf_symbol::create() function to create
1907/// instances of @ref elf_symbol instead.
1908///
1909/// @param e the environment we are operating from.
1910///
1911/// @param i the index of the symbol in the (ELF) symbol table.
1912///
1913/// @param s the size of the symbol.
1914///
1915/// @param n the name of the symbol.
1916///
1917/// @param t the type of the symbol.
1918///
1919/// @param b the binding of the symbol.
1920///
1921/// @param d true if the symbol is defined, false otherwise.
1922///
1923/// @param c true if the symbol is a common symbol, false otherwise.
1924///
1925/// @param ve the version of the symbol.
1926///
1927/// @param vi the visibility of the symbol.
1928///
1929/// @param crc the CRC (modversions) value of Linux Kernel symbols
1930///
1931/// @param ns the namespace of Linux Kernel symbols, if any
1932elf_symbol::elf_symbol(const environment& e,
1933 size_t i,
1934 size_t s,
1935 const string& n,
1936 type t,
1937 binding b,
1938 bool d,
1939 bool c,
1940 const version& ve,
1941 visibility vi,
1942 bool is_in_ksymtab,
1945 bool is_suppressed)
1946 : priv_(new priv(e,
1947 i,
1948 s,
1949 n,
1950 t,
1951 b,
1952 d,
1953 c,
1954 ve,
1955 vi,
1956 is_in_ksymtab,
1957 crc,
1958 ns,
1959 is_suppressed))
1960{}
1961
1962/// Factory of instances of @ref elf_symbol.
1963///
1964/// This is the function to use to create instances of @ref elf_symbol.
1965///
1966/// @param e the environment we are operating from.
1967///
1968/// @param i the index of the symbol in the (ELF) symbol table.
1969///
1970/// @param s the size of the symbol.
1971///
1972/// @param n the name of the symbol.
1973///
1974/// @param t the type of the symbol.
1975///
1976/// @param b the binding of the symbol.
1977///
1978/// @param d true if the symbol is defined, false otherwise.
1979///
1980/// @param c true if the symbol is a common symbol.
1981///
1982/// @param ve the version of the symbol.
1983///
1984/// @param vi the visibility of the symbol.
1985///
1986/// @param crc the CRC (modversions) value of Linux Kernel symbols
1987///
1988/// @param ns the namespace of Linux Kernel symbols, if any
1989///
1990/// @return a (smart) pointer to a newly created instance of @ref
1991/// elf_symbol.
1994 size_t i,
1995 size_t s,
1996 const string& n,
1997 type t,
1998 binding b,
1999 bool d,
2000 bool c,
2001 const version& ve,
2002 visibility vi,
2003 bool is_in_ksymtab,
2006 bool is_suppressed)
2007{
2008 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
2009 is_in_ksymtab, crc, ns, is_suppressed));
2010 sym->priv_->main_symbol_ = sym;
2011 return sym;
2012}
2013
2014/// Test textual equality between two symbols.
2015///
2016/// Textual equality means that the aliases of the compared symbols
2017/// are not taken into account. Only the name, type, and version of
2018/// the symbols are compared.
2019///
2020/// @return true iff the two symbols are textually equal.
2021static bool
2022textually_equals(const elf_symbol&l,
2023 const elf_symbol&r)
2024{
2025 bool equals = (l.get_name() == r.get_name()
2026 && l.get_type() == r.get_type()
2027 && l.is_public() == r.is_public()
2028 && l.is_defined() == r.is_defined()
2030 && l.get_version() == r.get_version()
2031 && l.get_crc() == r.get_crc()
2032 && l.get_namespace() == r.get_namespace());
2033
2034 if (equals && l.is_variable())
2035 // These are variable symbols. Let's compare their symbol size.
2036 // The symbol size in this case is the size taken by the storage
2037 // of the variable. If that size changes, then it's an ABI
2038 // change.
2039 equals = l.get_size() == r.get_size();
2040
2041 return equals;
2042}
2043
2044/// Getter of the environment used by the current instance of @ref
2045/// elf_symbol.
2046///
2047/// @return the enviroment used by the current instance of @ref elf_symbol.
2048const environment&
2050{return priv_->env_;}
2051
2052/// Getter for the index
2053///
2054/// @return the index of the symbol.
2055size_t
2057{return priv_->index_;}
2058
2059/// Setter for the index.
2060///
2061/// @param s the new index.
2062void
2064{priv_->index_ = s;}
2065
2066/// Getter for the name of the @ref elf_symbol.
2067///
2068/// @return a reference to the name of the @ref symbol.
2069const string&
2071{return priv_->name_;}
2072
2073/// Setter for the name of the current intance of @ref elf_symbol.
2074///
2075/// @param n the new name.
2076void
2077elf_symbol::set_name(const string& n)
2078{
2079 priv_->name_ = n;
2080 priv_->id_string_.clear();
2081}
2082
2083/// Getter for the type of the current instance of @ref elf_symbol.
2084///
2085/// @return the type of the elf symbol.
2088{return priv_->type_;}
2089
2090/// Setter for the type of the current instance of @ref elf_symbol.
2091///
2092/// @param t the new symbol type.
2093void
2095{priv_->type_ = t;}
2096
2097/// Getter of the size of the symbol.
2098///
2099/// @return the size of the symbol, in bytes.
2100size_t
2102{return priv_->size_;}
2103
2104/// Setter of the size of the symbol.
2105///
2106/// @param size the new size of the symbol, in bytes.
2107void
2109{priv_->size_ = size;}
2110
2111/// Getter for the binding of the current instance of @ref elf_symbol.
2112///
2113/// @return the binding of the symbol.
2116{return priv_->binding_;}
2117
2118/// Setter for the binding of the current instance of @ref elf_symbol.
2119///
2120/// @param b the new binding.
2121void
2123{priv_->binding_ = b;}
2124
2125/// Getter for the version of the current instanc of @ref elf_symbol.
2126///
2127/// @return the version of the elf symbol.
2130{return priv_->version_;}
2131
2132/// Setter for the version of the current instance of @ref elf_symbol.
2133///
2134/// @param v the new version of the elf symbol.
2135void
2137{
2138 priv_->version_ = v;
2139 priv_->id_string_.clear();
2140}
2141
2142/// Setter of the visibility of the current instance of @ref
2143/// elf_symbol.
2144///
2145/// @param v the new visibility of the elf symbol.
2146void
2148{priv_->visibility_ = v;}
2149
2150/// Getter of the visibility of the current instance of @ref
2151/// elf_symbol.
2152///
2153/// @return the visibility of the elf symbol.
2156{return priv_->visibility_;}
2157
2158/// Test if the current instance of @ref elf_symbol is defined or not.
2159///
2160/// @return true if the current instance of @ref elf_symbol is
2161/// defined, false otherwise.
2162bool
2164{return priv_->is_defined_;}
2165
2166/// Sets a flag saying if the current instance of @ref elf_symbol is
2167/// defined
2168///
2169/// @param b the new value of the flag.
2170void
2172{priv_->is_defined_ = d;}
2173
2174/// Test if the current instance of @ref elf_symbol is public or not.
2175///
2176/// This tests if the symbol is defined, has default or protected
2177///visibility, and either:
2178/// - has global binding
2179/// - has weak binding
2180/// - or has a GNU_UNIQUE binding.
2181///
2182/// return true if the current instance of @ref elf_symbol is public,
2183/// false otherwise.
2184bool
2186{
2187 return (is_defined()
2188 && (get_binding() == GLOBAL_BINDING
2189 || get_binding() == WEAK_BINDING
2190 || get_binding() == GNU_UNIQUE_BINDING)
2191 && (get_visibility() == DEFAULT_VISIBILITY
2192 || get_visibility() == PROTECTED_VISIBILITY));
2193}
2194
2195/// Test if the current instance of @ref elf_symbol is a function
2196/// symbol or not.
2197///
2198/// @return true if the current instance of @ref elf_symbol is a
2199/// function symbol, false otherwise.
2200bool
2202{return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2203
2204/// Test if the current instance of @ref elf_symbol is a variable
2205/// symbol or not.
2206///
2207/// @return true if the current instance of @ref elf_symbol is a
2208/// variable symbol, false otherwise.
2209bool
2211{
2212 return (get_type() == OBJECT_TYPE
2213 || get_type() == TLS_TYPE
2214 // It appears that undefined variables have NOTYPE type.
2215 || (get_type() == NOTYPE_TYPE
2216 && !is_defined()));
2217}
2218
2219/// Getter of the 'is-in-ksymtab' property.
2220///
2221/// @return true iff the current symbol is in the Linux Kernel
2222/// specific 'ksymtab' symbol table.
2223bool
2225{return priv_->is_in_ksymtab_;}
2226
2227/// Setter of the 'is-in-ksymtab' property.
2228///
2229/// @param is_in_ksymtab this is true iff the current symbol is in the
2230/// Linux Kernel specific 'ksymtab' symbol table.
2231void
2233{priv_->is_in_ksymtab_ = is_in_ksymtab;}
2234
2235/// Getter of the 'crc' property.
2236///
2237/// @return the CRC (modversions) value for Linux Kernel symbols, if any
2240{return priv_->crc_;}
2241
2242/// Setter of the 'crc' property.
2243///
2244/// @param crc the new CRC (modversions) value for Linux Kernel symbols
2245void
2247{priv_->crc_ = crc;}
2248
2249/// Getter of the 'namespace' property.
2250///
2251/// @return the namespace for Linux Kernel symbols, if any
2254{return priv_->namespace_;}
2255
2256/// Setter of the 'namespace' property.
2257///
2258/// @param ns the new namespace for Linux Kernel symbols, if any
2259void
2261{priv_->namespace_ = ns;}
2262
2263/// Getter for the 'is-suppressed' property.
2264///
2265/// @return true iff the current symbol has been suppressed by a
2266/// suppression specification that was provided in the context that
2267/// led to the creation of the corpus this ELF symbol belongs to.
2268bool
2270{return priv_->is_suppressed_;}
2271
2272/// Setter for the 'is-suppressed' property.
2273///
2274/// @param true iff the current symbol has been suppressed by a
2275/// suppression specification that was provided in the context that
2276/// led to the creation of the corpus this ELF symbol belongs to.
2277void
2279{priv_->is_suppressed_ = is_suppressed;}
2280
2281/// @name Elf symbol aliases
2282///
2283/// An alias A for an elf symbol S is a symbol that is defined at the
2284/// same address as S. S is chained to A through the
2285/// elf_symbol::get_next_alias() method.
2286///
2287/// When there are several aliases to a symbol, the main symbol is the
2288/// the first symbol found in the symbol table for a given address.
2289///
2290/// The alias chain is circular. That means if S is the main symbol
2291/// and A is the alias, S is chained to A and A
2292/// is chained back to the main symbol S. The last alias in an alias
2293///chain is always chained to the main symbol.
2294///
2295/// Thus, when looping over the aliases of an elf_symbol A, detecting
2296/// an alias that is equal to the main symbol should logically be a
2297/// loop exit condition.
2298///
2299/// Accessing and adding aliases for instances of elf_symbol is done
2300/// through the member functions below.
2301
2302/// @{
2303
2304/// Get the main symbol of an alias chain.
2305///
2306///@return the main symbol.
2307const elf_symbol_sptr
2309{return priv_->main_symbol_.lock();}
2310
2311/// Get the main symbol of an alias chain.
2312///
2313///@return the main symbol.
2316{return priv_->main_symbol_.lock();}
2317
2318/// Tests whether this symbol is the main symbol.
2319///
2320/// @return true iff this symbol is the main symbol.
2321bool
2323{return get_main_symbol().get() == this;}
2324
2325/// Get the next alias of the current symbol.
2326///
2327///@return the alias, or NULL if there is no alias.
2330{return priv_->next_alias_.lock();}
2331
2332
2333/// Check if the current elf_symbol has an alias.
2334///
2335///@return true iff the current elf_symbol has an alias.
2336bool
2338{return bool(get_next_alias());}
2339
2340/// Get the number of aliases to this elf symbol
2341///
2342/// @return the number of aliases to this elf symbol.
2343int
2345{
2346 int result = 0;
2347
2349 a && a.get() != get_main_symbol().get();
2350 a = a->get_next_alias())
2351 ++result;
2352
2353 return result;
2354}
2355
2356/// Add an alias to the current elf symbol.
2357///
2358/// @param alias the new alias. Note that this elf_symbol should *NOT*
2359/// have aliases prior to the invocation of this function.
2360void
2362{
2363 if (!alias)
2364 return;
2365
2366 ABG_ASSERT(!alias->has_aliases());
2368
2369 if (has_aliases())
2370 {
2371 elf_symbol_sptr last_alias;
2373 a && !a->is_main_symbol();
2374 a = a->get_next_alias())
2375 {
2376 if (a->get_next_alias()->is_main_symbol())
2377 {
2378 ABG_ASSERT(last_alias == 0);
2379 last_alias = a;
2380 }
2381 }
2382 ABG_ASSERT(last_alias);
2383
2384 last_alias->priv_->next_alias_ = alias;
2385 }
2386 else
2387 priv_->next_alias_ = alias;
2388
2389 alias->priv_->next_alias_ = get_main_symbol();
2390 alias->priv_->main_symbol_ = get_main_symbol();
2391}
2392
2393/// Update the main symbol for a group of aliased symbols
2394///
2395/// If after the construction of the symbols (in order of discovery), the
2396/// actual main symbol can be identified (e.g. as the symbol that actually is
2397/// defined in the code), this method offers a way of updating the main symbol
2398/// through one of the aliased symbols.
2399///
2400/// For that, locate the new main symbol by name and update all references to
2401/// the main symbol among the group of aliased symbols.
2402///
2403/// @param name the name of the main symbol
2404///
2405/// @return the new main elf_symbol
2407elf_symbol::update_main_symbol(const std::string& name)
2408{
2410 if (!has_aliases() || get_name() == name)
2411 return get_main_symbol();
2412
2413 // find the new main symbol
2414 elf_symbol_sptr new_main;
2415 // we've already checked this; check the rest of the aliases
2416 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2417 a = a->get_next_alias())
2418 if (a->get_name() == name)
2419 {
2420 new_main = a;
2421 break;
2422 }
2423
2424 if (!new_main)
2425 return get_main_symbol();
2426
2427 // now update all main symbol references
2428 priv_->main_symbol_ = new_main;
2429 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2430 a = a->get_next_alias())
2431 a->priv_->main_symbol_ = new_main;
2432
2433 return new_main;
2434}
2435
2436/// Return true if the symbol is a common one.
2437///
2438/// @return true iff the symbol is common.
2439bool
2441{return priv_->is_common_;}
2442
2443/// Return true if this common common symbol has other common instances.
2444///
2445/// A common instance of a given common symbol is another common
2446/// symbol with the same name. Those exist in relocatable files. The
2447/// linker normally allocates all the instances into a common block in
2448/// the final output file.
2449///
2450/// Note that the current object must be a common symbol, otherwise,
2451/// this function aborts.
2452///
2453/// @return true iff the current common symbol has other common
2454/// instances.
2455bool
2457{
2459 return bool(get_next_common_instance());
2460}
2461
2462/// Get the next common instance of the current common symbol.
2463///
2464/// A common instance of a given common symbol is another common
2465/// symbol with the same name. Those exist in relocatable files. The
2466/// linker normally allocates all the instances into a common block in
2467/// the final output file.
2468///
2469/// @return the next common instance, or nil if there is not any.
2472{return priv_->next_common_instance_.lock();}
2473
2474/// Add a common instance to the current common elf symbol.
2475///
2476/// Note that this symbol must be the main symbol. Being the main
2477/// symbol means being the first common symbol to appear in the symbol
2478/// table.
2479///
2480/// @param common the other common instance to add.
2481void
2483{
2484 if (!common)
2485 return;
2486
2487 ABG_ASSERT(!common->has_other_common_instances());
2490
2492 {
2493 elf_symbol_sptr last_common_instance;
2495 c && (c.get() != get_main_symbol().get());
2496 c = c->get_next_common_instance())
2497 {
2498 if (c->get_next_common_instance().get() == get_main_symbol().get())
2499 {
2500 ABG_ASSERT(last_common_instance == 0);
2501 last_common_instance = c;
2502 }
2503 }
2504 ABG_ASSERT(last_common_instance);
2505
2506 last_common_instance->priv_->next_common_instance_ = common;
2507 }
2508 else
2509 priv_->next_common_instance_ = common;
2510
2511 common->priv_->next_common_instance_ = get_main_symbol();
2512 common->priv_->main_symbol_ = get_main_symbol();
2513}
2514
2515/// Get a string that is representative of a given elf_symbol.
2516///
2517/// If the symbol has a version, then the ID string is the
2518/// concatenation of the name of the symbol, the '@' character, and
2519/// the version of the symbol. If the version is the default version
2520/// of the symbol then the '@' character is replaced by a "@@" string.
2521///
2522/// Otherwise, if the symbol does not have any version, this function
2523/// returns the name of the symbol.
2524///
2525/// @return a the ID string.
2526const string&
2528{
2529 if (priv_->id_string_.empty())
2530 {
2531 string s = get_name ();
2532
2533 if (!get_version().is_empty())
2534 {
2535 if (get_version().is_default())
2536 s += "@@";
2537 else
2538 s += "@";
2539 s += get_version().str();
2540 }
2541 priv_->id_string_ = s;
2542 }
2543
2544 return priv_->id_string_;
2545}
2546
2547/// From the aliases of the current symbol, lookup one with a given name.
2548///
2549/// @param name the name of symbol alias we are looking for.
2550///
2551/// @return the symbol alias that has the name @p name, or nil if none
2552/// has been found.
2554elf_symbol::get_alias_from_name(const string& name) const
2555{
2556 if (name == get_name())
2557 return elf_symbol_sptr(priv_->main_symbol_);
2558
2560 a && a.get() != get_main_symbol().get();
2561 a = a->get_next_alias())
2562 if (a->get_name() == name)
2563 return a;
2564
2565 return elf_symbol_sptr();
2566}
2567
2568/// In the list of aliases of a given elf symbol, get the alias that
2569/// equals this current symbol.
2570///
2571/// @param other the elf symbol to get the potential aliases from.
2572///
2573/// @return the alias of @p other that texually equals the current
2574/// symbol, or nil if no alias textually equals the current symbol.
2577{
2578 for (elf_symbol_sptr a = other.get_next_alias();
2579 a && a.get() != a->get_main_symbol().get();
2580 a = a->get_next_alias())
2581 if (textually_equals(*this, *a))
2582 return a;
2583 return elf_symbol_sptr();
2584}
2585
2586/// Return a comma separated list of the id of the current symbol as
2587/// well as the id string of its aliases.
2588///
2589/// @param syms a map of all the symbols of the corpus the current
2590/// symbol belongs to.
2591///
2592/// @param include_symbol_itself if set to true, then the name of the
2593/// current symbol is included in the list of alias names that is emitted.
2594///
2595/// @return the string.
2596string
2598 bool include_symbol_itself) const
2599{
2600 string result;
2601
2602 if (include_symbol_itself)
2603 result = get_id_string();
2604
2605 vector<elf_symbol_sptr> aliases;
2606 compute_aliases_for_elf_symbol(*this, syms, aliases);
2607 if (!aliases.empty() && include_symbol_itself)
2608 result += ", ";
2609
2610 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2611 i != aliases.end();
2612 ++i)
2613 {
2614 if (i != aliases.begin())
2615 result += ", ";
2616 result += (*i)->get_id_string();
2617 }
2618 return result;
2619}
2620
2621/// Return a comma separated list of the id of the current symbol as
2622/// well as the id string of its aliases.
2623///
2624/// @param include_symbol_itself if set to true, then the name of the
2625/// current symbol is included in the list of alias names that is emitted.
2626///
2627/// @return the string.
2628string
2629elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2630{
2631 vector<elf_symbol_sptr> aliases;
2632 if (include_symbol_itself)
2633 aliases.push_back(get_main_symbol());
2634
2636 a && a.get() != get_main_symbol().get();
2637 a = a->get_next_alias())
2638 aliases.push_back(a);
2639
2640 string result;
2641 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2642 i != aliases.end();
2643 ++i)
2644 {
2645 if (i != aliases.begin())
2646 result += ", ";
2647 result += (*i)->get_id_string();
2648 }
2649
2650 return result;
2651}
2652
2653/// Given the ID of a symbol, get the name and the version of said
2654/// symbol.
2655///
2656/// @param id the symbol ID to consider.
2657///
2658/// @param name the symbol name extracted from the ID. This is set
2659/// only if the function returned true.
2660///
2661/// @param ver the symbol version extracted from the ID.
2662bool
2664 string& name,
2665 string& ver)
2666{
2667 name.clear(), ver.clear();
2668
2669 string::size_type i = id.find('@');
2670 if (i == string::npos)
2671 {
2672 name = id;
2673 return true;
2674 }
2675
2676 name = id.substr(0, i);
2677 ++i;
2678
2679 if (i >= id.size())
2680 return true;
2681
2682 string::size_type j = id.find('@', i);
2683 if (j == string::npos)
2684 j = i;
2685 else
2686 ++j;
2687
2688 if (j >= id.size())
2689 {
2690 ver = "";
2691 return true;
2692 }
2693
2694 ver = id.substr(j);
2695 return true;
2696}
2697
2698///@}
2699
2700/// Test if two main symbols are textually equal, or, if they have
2701/// aliases that are textually equal.
2702///
2703/// @param other the symbol to compare against.
2704///
2705/// @return true iff the current instance of elf symbol equals the @p
2706/// other.
2707bool
2709{
2710 bool are_equal = textually_equals(*this, other);
2711 if (!are_equal)
2712 are_equal = bool(get_alias_which_equals(other));
2713 return are_equal;
2714}
2715
2716/// Test if the current symbol aliases another one.
2717///
2718/// @param o the other symbol to test against.
2719///
2720/// @return true iff the current symbol aliases @p o.
2721bool
2723{
2724 if (*this == o)
2725 return true;
2726
2727 if (get_main_symbol() == o.get_main_symbol())
2728 return true;
2729
2731 a && !a->is_main_symbol();
2732 a = a->get_next_alias())
2733 {
2734 if (o == *a)
2735 return true;
2736 }
2737 return false;
2738}
2739
2740/// Equality operator for smart pointers to elf_symbol.
2741///
2742/// @param lhs the first elf symbol to consider.
2743///
2744/// @param rhs the second elf symbol to consider.
2745///
2746/// @return true iff @p lhs equals @p rhs.
2747bool
2749{
2750 if (!!lhs != !!rhs)
2751 return false;
2752
2753 if (!lhs)
2754 return true;
2755
2756 return *lhs == *rhs;
2757}
2758
2759/// Inequality operator for smart pointers to elf_symbol.
2760///
2761/// @param lhs the first elf symbol to consider.
2762///
2763/// @param rhs the second elf symbol to consider.
2764///
2765/// @return true iff @p lhs is different from @p rhs.
2766bool
2768{return !operator==(lhs, rhs);}
2769
2770/// Test if two symbols alias.
2771///
2772/// @param s1 the first symbol to consider.
2773///
2774/// @param s2 the second symbol to consider.
2775///
2776/// @return true if @p s1 aliases @p s2.
2777bool
2779{return s1.does_alias(s2) || s2.does_alias(s1);}
2780
2781void
2782compute_aliases_for_elf_symbol(const elf_symbol& sym,
2783 const string_elf_symbols_map_type& symtab,
2784 vector<elf_symbol_sptr>& aliases)
2785{
2786
2787 if (elf_symbol_sptr a = sym.get_next_alias())
2788 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2789 aliases.push_back(a);
2790 else
2791 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2792 i != symtab.end();
2793 ++i)
2794 for (elf_symbols::const_iterator j = i->second.begin();
2795 j != i->second.end();
2796 ++j)
2797 {
2798 if (**j == sym)
2799 for (elf_symbol_sptr s = (*j)->get_next_alias();
2800 s && !s->is_main_symbol();
2801 s = s->get_next_alias())
2802 aliases.push_back(s);
2803 else
2804 for (elf_symbol_sptr s = (*j)->get_next_alias();
2805 s && !s->is_main_symbol();
2806 s = s->get_next_alias())
2807 if (*s == sym)
2808 aliases.push_back(*j);
2809 }
2810}
2811
2812/// Test if two symbols alias.
2813///
2814/// @param s1 the first symbol to consider.
2815///
2816/// @param s2 the second symbol to consider.
2817///
2818/// @return true if @p s1 aliases @p s2.
2819bool
2821{
2822 if (!!s1 != !!s2)
2823 return false;
2824 if (s1 == s2)
2825 return true;
2826 return elf_symbols_alias(*s1, *s2);
2827}
2828
2829/// Test if two symbols alias.
2830///
2831/// @param s1 the first symbol to consider.
2832///
2833/// @param s2 the second symbol to consider.
2834///
2835/// @return true if @p s1 aliases @p s2.
2836bool
2838{return elf_symbols_alias(s1.get(), s2.get());}
2839
2840/// Serialize an instance of @ref symbol_type and stream it to a given
2841/// output stream.
2842///
2843/// @param o the output stream to serialize the symbole type to.
2844///
2845/// @param t the symbol type to serialize.
2846std::ostream&
2847operator<<(std::ostream& o, elf_symbol::type t)
2848{
2849 string repr;
2850
2851 switch (t)
2852 {
2853 case elf_symbol::NOTYPE_TYPE:
2854 repr = "unspecified symbol type";
2855 break;
2856 case elf_symbol::OBJECT_TYPE:
2857 repr = "variable symbol type";
2858 break;
2859 case elf_symbol::FUNC_TYPE:
2860 repr = "function symbol type";
2861 break;
2862 case elf_symbol::SECTION_TYPE:
2863 repr = "section symbol type";
2864 break;
2865 case elf_symbol::FILE_TYPE:
2866 repr = "file symbol type";
2867 break;
2868 case elf_symbol::COMMON_TYPE:
2869 repr = "common data object symbol type";
2870 break;
2871 case elf_symbol::TLS_TYPE:
2872 repr = "thread local data object symbol type";
2873 break;
2874 case elf_symbol::GNU_IFUNC_TYPE:
2875 repr = "indirect function symbol type";
2876 break;
2877 default:
2878 {
2879 std::ostringstream s;
2880 s << "unknown symbol type (" << (char)t << ')';
2881 repr = s.str();
2882 }
2883 break;
2884 }
2885
2886 o << repr;
2887 return o;
2888}
2889
2890/// Serialize an instance of @ref symbol_binding and stream it to a
2891/// given output stream.
2892///
2893/// @param o the output stream to serialize the symbole type to.
2894///
2895/// @param b the symbol binding to serialize.
2896std::ostream&
2897operator<<(std::ostream& o, elf_symbol::binding b)
2898{
2899 string repr;
2900
2901 switch (b)
2902 {
2903 case elf_symbol::LOCAL_BINDING:
2904 repr = "local binding";
2905 break;
2906 case elf_symbol::GLOBAL_BINDING:
2907 repr = "global binding";
2908 break;
2909 case elf_symbol::WEAK_BINDING:
2910 repr = "weak binding";
2911 break;
2912 case elf_symbol::GNU_UNIQUE_BINDING:
2913 repr = "GNU unique binding";
2914 break;
2915 default:
2916 {
2917 std::ostringstream s;
2918 s << "unknown binding (" << (unsigned char) b << ")";
2919 repr = s.str();
2920 }
2921 break;
2922 }
2923
2924 o << repr;
2925 return o;
2926}
2927
2928/// Serialize an instance of @ref elf_symbol::visibility and stream it
2929/// to a given output stream.
2930///
2931/// @param o the output stream to serialize the symbole type to.
2932///
2933/// @param v the symbol visibility to serialize.
2934std::ostream&
2935operator<<(std::ostream& o, elf_symbol::visibility v)
2936{
2937 string repr;
2938
2939 switch (v)
2940 {
2941 case elf_symbol::DEFAULT_VISIBILITY:
2942 repr = "default visibility";
2943 break;
2944 case elf_symbol::PROTECTED_VISIBILITY:
2945 repr = "protected visibility";
2946 break;
2947 case elf_symbol::HIDDEN_VISIBILITY:
2948 repr = "hidden visibility";
2949 break;
2950 case elf_symbol::INTERNAL_VISIBILITY:
2951 repr = "internal visibility";
2952 break;
2953 default:
2954 {
2955 std::ostringstream s;
2956 s << "unknown visibility (" << (unsigned char) v << ")";
2957 repr = s.str();
2958 }
2959 break;
2960 }
2961
2962 o << repr;
2963 return o;
2964}
2965
2966/// Convert a string representing a symbol type into an
2967/// elf_symbol::type.
2968///
2969///@param s the string to convert.
2970///
2971///@param t the resulting elf_symbol::type.
2972///
2973/// @return true iff the conversion completed successfully.
2974bool
2976{
2977 if (s == "no-type")
2978 t = elf_symbol::NOTYPE_TYPE;
2979 else if (s == "object-type")
2980 t = elf_symbol::OBJECT_TYPE;
2981 else if (s == "func-type")
2982 t = elf_symbol::FUNC_TYPE;
2983 else if (s == "section-type")
2984 t = elf_symbol::SECTION_TYPE;
2985 else if (s == "file-type")
2986 t = elf_symbol::FILE_TYPE;
2987 else if (s == "common-type")
2988 t = elf_symbol::COMMON_TYPE;
2989 else if (s == "tls-type")
2990 t = elf_symbol::TLS_TYPE;
2991 else if (s == "gnu-ifunc-type")
2992 t = elf_symbol::GNU_IFUNC_TYPE;
2993 else
2994 return false;
2995
2996 return true;
2997}
2998
2999/// Convert a string representing a an elf symbol binding into an
3000/// elf_symbol::binding.
3001///
3002/// @param s the string to convert.
3003///
3004/// @param b the resulting elf_symbol::binding.
3005///
3006/// @return true iff the conversion completed successfully.
3007bool
3009{
3010 if (s == "local-binding")
3011 b = elf_symbol::LOCAL_BINDING;
3012 else if (s == "global-binding")
3013 b = elf_symbol::GLOBAL_BINDING;
3014 else if (s == "weak-binding")
3015 b = elf_symbol::WEAK_BINDING;
3016 else if (s == "gnu-unique-binding")
3017 b = elf_symbol::GNU_UNIQUE_BINDING;
3018 else
3019 return false;
3020
3021 return true;
3022}
3023
3024/// Convert a string representing a an elf symbol visibility into an
3025/// elf_symbol::visibility.
3026///
3027/// @param s the string to convert.
3028///
3029/// @param b the resulting elf_symbol::visibility.
3030///
3031/// @return true iff the conversion completed successfully.
3032bool
3034{
3035 if (s == "default-visibility")
3036 v = elf_symbol::DEFAULT_VISIBILITY;
3037 else if (s == "protected-visibility")
3038 v = elf_symbol::PROTECTED_VISIBILITY;
3039 else if (s == "hidden-visibility")
3040 v = elf_symbol::HIDDEN_VISIBILITY;
3041 else if (s == "internal-visibility")
3042 v = elf_symbol::INTERNAL_VISIBILITY;
3043 else
3044 return false;
3045
3046 return true;
3047}
3048
3049/// Test if the type of an ELF symbol denotes a function symbol.
3050///
3051/// @param t the type of the ELF symbol.
3052///
3053/// @return true iff elf symbol type @p t denotes a function symbol
3054/// type.
3055bool
3057{return t == elf_symbol::FUNC_TYPE;}
3058
3059/// Test if the type of an ELF symbol denotes a function symbol.
3060///
3061/// @param t the type of the ELF symbol.
3062///
3063/// @return true iff elf symbol type @p t denotes a function symbol
3064/// type.
3065bool
3067{return t == elf_symbol::OBJECT_TYPE;}
3068
3069// <elf_symbol::version stuff>
3070
3071struct elf_symbol::version::priv
3072{
3073 string version_;
3074 bool is_default_;
3075
3076 priv()
3077 : is_default_(false)
3078 {}
3079
3080 priv(const string& v,
3081 bool d)
3082 : version_(v),
3083 is_default_(d)
3084 {}
3085}; // end struct elf_symbol::version::priv
3086
3087elf_symbol::version::version()
3088 : priv_(new priv)
3089{}
3090
3091/// @param v the name of the version.
3092///
3093/// @param is_default true if this is a default version.
3094elf_symbol::version::version(const string& v,
3095 bool is_default)
3096 : priv_(new priv(v, is_default))
3097{}
3098
3099elf_symbol::version::version(const elf_symbol::version& v)
3100 : priv_(new priv(v.str(), v.is_default()))
3101{
3102}
3103
3104elf_symbol::version::~version() = default;
3105
3106/// Cast the version_type into a string that is its name.
3107///
3108/// @return the name of the version.
3109elf_symbol::version::operator const string&() const
3110{return priv_->version_;}
3111
3112/// Getter for the version name.
3113///
3114/// @return the version name.
3115const string&
3117{return priv_->version_;}
3118
3119/// Setter for the version name.
3120///
3121/// @param s the version name.
3122void
3124{priv_->version_ = s;}
3125
3126/// Getter for the 'is_default' property of the version.
3127///
3128/// @return true iff this is a default version.
3129bool
3131{return priv_->is_default_;}
3132
3133/// Setter for the 'is_default' property of the version.
3134///
3135/// @param f true if this is the default version.
3136void
3138{priv_->is_default_ = f;}
3139
3140bool
3141elf_symbol::version::is_empty() const
3142{return str().empty();}
3143
3144/// Compares the current version against another one.
3145///
3146/// @param o the other version to compare the current one to.
3147///
3148/// @return true iff the current version equals @p o.
3149bool
3151{return str() == o.str();}
3152
3153/// Inequality operator.
3154///
3155/// @param o the version to compare against the current one.
3156///
3157/// @return true iff both versions are different.
3158bool
3160{return !operator==(o);}
3161
3162/// Assign a version to the current one.
3163///
3164/// @param o the other version to assign to this one.
3165///
3166/// @return a reference to the assigned version.
3169{
3170 str(o.str());
3171 is_default(o.is_default());
3172 return *this;
3173}
3174
3175// </elf_symbol::version stuff>
3176
3177// </elf_symbol stuff>
3178
3179// <class dm_context_rel stuff>
3180struct dm_context_rel::priv
3181{
3182 bool is_laid_out_;
3183 size_t offset_in_bits_;
3184 var_decl* anonymous_data_member_;
3185
3186 priv(bool is_static = false)
3187 : is_laid_out_(!is_static),
3188 offset_in_bits_(0),
3189 anonymous_data_member_()
3190 {}
3191
3192 priv(bool is_laid_out, size_t offset_in_bits)
3193 : is_laid_out_(is_laid_out),
3194 offset_in_bits_(offset_in_bits),
3195 anonymous_data_member_()
3196 {}
3197}; //end struct dm_context_rel::priv
3198
3199dm_context_rel::dm_context_rel()
3200 : context_rel(),
3201 priv_(new priv)
3202{}
3203
3204dm_context_rel::dm_context_rel(scope_decl* s,
3205 bool is_laid_out,
3206 size_t offset_in_bits,
3208 bool is_static)
3209 : context_rel(s, a, is_static),
3210 priv_(new priv(is_laid_out, offset_in_bits))
3211{}
3212
3213dm_context_rel::dm_context_rel(scope_decl* s)
3214 : context_rel(s),
3215 priv_(new priv())
3216{}
3217
3218bool
3219dm_context_rel::get_is_laid_out() const
3220{return priv_->is_laid_out_;}
3221
3222void
3223dm_context_rel::set_is_laid_out(bool f)
3224{priv_->is_laid_out_ = f;}
3225
3226size_t
3227dm_context_rel::get_offset_in_bits() const
3228{return priv_->offset_in_bits_;}
3229
3230void
3231dm_context_rel::set_offset_in_bits(size_t o)
3232{priv_->offset_in_bits_ = o;}
3233
3234bool
3235dm_context_rel::operator==(const dm_context_rel& o) const
3236{
3237 if (!context_rel::operator==(o))
3238 return false;
3239
3240 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3241 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3242}
3243
3244bool
3245dm_context_rel::operator!=(const dm_context_rel& o) const
3246{return !operator==(o);}
3247
3248/// Return a non-nil value if this data member context relationship
3249/// has an anonymous data member. That means, if the data member this
3250/// relation belongs to is part of an anonymous data member.
3251///
3252/// @return the containing anonymous data member of this data member
3253/// relationship. Nil if there is none.
3254const var_decl*
3256{return priv_->anonymous_data_member_;}
3257
3258/// Set the containing anonymous data member of this data member
3259/// context relationship. That means that the data member this
3260/// relation belongs to is part of an anonymous data member.
3261///
3262/// @param anon_dm the containing anonymous data member of this data
3263/// member relationship. Nil if there is none.
3264void
3266{priv_->anonymous_data_member_ = anon_dm;}
3267
3268dm_context_rel::~dm_context_rel()
3269{}
3270// </class dm_context_rel stuff>
3271
3272// <environment stuff>
3273
3274/// Convenience typedef for a map of interned_string -> bool.
3275typedef unordered_map<interned_string,
3277
3278
3279/// Default constructor of the @ref environment type.
3281 :priv_(new priv)
3282{}
3283
3284/// Destructor for the @ref environment type.
3286{}
3287
3288/// Getter the map of canonical types.
3289///
3290/// @return the map of canonical types. The key of the map is the
3291/// hash of the canonical type and its value if the canonical type.
3294{return priv_->canonical_types_;}
3295
3296/// Getter the map of canonical types.
3297///
3298/// @return the map of canonical types. The key of the map is the
3299/// hash of the canonical type and its value if the canonical type.
3302{return const_cast<environment*>(this)->get_canonical_types_map();}
3303
3304/// Helper to detect if a type is either a reference, a pointer, or a
3305/// qualified type.
3306bool
3308{
3309 if (is_pointer_type(t)
3310 || is_reference_type(t)
3311 || is_qualified_type(t))
3312 return true;
3313 return false;
3314}
3315
3316/// Compare decls using their locations.
3317///
3318/// @param f the first decl to compare.
3319///
3320/// @param s the second decl to compare.
3321///
3322/// @return true if @p f compares less than @p s.
3323bool
3325 const decl_base *s)
3326{
3327 // If a decl has artificial location, then use that one over the
3328 // natural one.
3331
3332 ABG_ASSERT(fl.get_value() && sl.get_value());
3333 if (fl.get_is_artificial() == sl.get_is_artificial())
3334 {
3335 // The locations of the two artfifacts have the same
3336 // artificial-ness so they can be compared.
3337 string p1, p2;
3338 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3339 fl.expand(p1, l1, c1);
3340 sl.expand(p2, l2, c2);
3341 if (p1 != p2)
3342 return p1 < p2;
3343 if (l1 != l2)
3344 return l1 < l2;
3345 if (c1 != c2)
3346 return c1 < c2;
3347 }
3348
3349 return (get_pretty_representation(f, /*internal=*/false)
3350 < get_pretty_representation(s, /*internal=*/false));
3351}
3352
3353/// Sort types in a hopefully stable manner.
3354///
3355/// @param types a set of types with canonical types to sort.
3356///
3357/// @param result the resulting sorted vector.
3358void
3360 vector<type_base_sptr>& result)
3361{
3362 for (auto t: types)
3363 result.push_back(t);
3364
3365 type_topo_comp comp;
3366 std::stable_sort(result.begin(), result.end(), comp);
3367}
3368
3369/// Get the unique @ref type_decl that represents a "void" type for
3370/// the current environment. This node must be the only one
3371/// representing a void type in the system.
3372///
3373/// Note that upon first use of this IR node (by the relevant
3374/// front-end, for instance) it must be added to a scope using e.g,
3375/// the @ref add_decl_to_scope() function.
3376///
3377/// @return the @ref type_decl that represents a "void" type.
3378const type_base_sptr&
3380{
3381 if (!priv_->void_type_)
3382 priv_->void_type_.reset(new type_decl(*this,
3383 intern("void"),
3384 0, 0, location()));
3385 return priv_->void_type_;
3386}
3387
3388/// Getter of the "pointer-to-void" IR node that is shared across the
3389/// ABI corpus. This node must be the only one representing a void
3390/// pointer type in the system.
3391///
3392/// Note that upon first use of this IR node (by the relevant
3393/// front-end, for instance) it must be added to a scope using e.g,
3394/// the @ref add_decl_to_scope() function.
3395///
3396/// @return the "pointer-to-void" IR node.
3397const type_base_sptr&
3399{
3400 if (!priv_->void_pointer_type_)
3401 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3402 0, 0, location()));
3403 return priv_->void_pointer_type_;
3404}
3405
3406/// Get a @ref type_decl instance that represents a the type of a
3407/// variadic function parameter. This node must be the only one
3408/// representing a variadic parameter type in the system.
3409///
3410/// Note that upon first use of this IR node (by the relevant
3411/// front-end, for instance) it must be added to a scope using e.g,
3412/// the @ref add_decl_to_scope() function.
3413///
3414/// @return the Get a @ref type_decl instance that represents a the
3415/// type of a variadic function parameter.
3416const type_base_sptr&
3418{
3419 if (!priv_->variadic_marker_type_)
3420 priv_->variadic_marker_type_.
3422 0, 0, location()));
3423 return priv_->variadic_marker_type_;
3424}
3425
3426/// Getter of the name of the variadic parameter type.
3427///
3428/// @return the name of the variadic parameter type.
3429string&
3431{
3432 static string variadic_parameter_type_name = "variadic parameter type";
3433 return variadic_parameter_type_name;
3434}
3435
3436/// Test if the canonicalization of types created out of the current
3437/// environment is done.
3438///
3439/// @return true iff the canonicalization of types created out of the current
3440/// environment is done.
3441bool
3443{return priv_->canonicalization_is_done_;}
3444
3445/// Set a flag saying if the canonicalization of types created out of
3446/// the current environment is done or not.
3447///
3448/// Note that this function must only be called by internal code of
3449/// the library that creates ABI artifacts (e.g, read an abi corpus
3450/// from elf or from our own xml format and creates representations of
3451/// types out of it) and thus needs to canonicalize types to speed-up
3452/// further type comparison.
3453///
3454/// @param f the new value of the flag.
3455void
3457{priv_->canonicalization_is_done_ = f;}
3458
3459/// Getter for the "on-the-fly-canonicalization" flag.
3460///
3461/// @return true iff @ref OnTheFlyCanonicalization
3462/// "on-the-fly-canonicalization" is to be performed during
3463/// comparison.
3464bool
3466{return priv_->do_on_the_fly_canonicalization_;}
3467
3468/// Setter for the "on-the-fly-canonicalization" flag.
3469///
3470/// @param f If this is true then @ref OnTheFlyCanonicalization
3471/// "on-the-fly-canonicalization" is to be performed during
3472/// comparison.
3473void
3475{priv_->do_on_the_fly_canonicalization_ = f;}
3476
3477/// Getter of the "decl-only-class-equals-definition" flag.
3478///
3479/// Usually, a declaration-only class named 'struct foo' compares
3480/// equal to any class definition named "struct foo'. This is at
3481/// least true for C++.
3482///
3483/// In C, though, because there can be multiple definitions of 'struct
3484/// foo' in the binary, a declaration-only "struct foo" might be
3485/// considered to *NOT* resolve to any of the struct foo defined. In
3486/// that case, the declaration-only "struct foo" is considered
3487/// different from the definitions.
3488///
3489/// This flag controls the behaviour of the comparison of an
3490/// unresolved decl-only class against a definition of the same name.
3491///
3492/// If set to false, the the declaration equals the definition. If
3493/// set to false, then the decalration is considered different from
3494/// the declaration.
3495///
3496/// @return the value of the "decl-only-class-equals-definition" flag.
3497bool
3499{return priv_->decl_only_class_equals_definition_;}
3500
3501/// Setter of the "decl-only-class-equals-definition" flag.
3502///
3503/// Usually, a declaration-only class named 'struct foo' compares
3504/// equal to any class definition named "struct foo'. This is at
3505/// least true for C++.
3506///
3507/// In C, though, because there can be multiple definitions of 'struct
3508/// foo' in the binary, a declaration-only "struct foo" might be
3509/// considered to *NOT* resolve to any of the struct foo defined. In
3510/// that case, the declaration-only "struct foo" is considered
3511/// different from the definitions.
3512///
3513/// This flag controls the behaviour of the comparison of an
3514/// unresolved decl-only class against a definition of the same name.
3515///
3516/// If set to false, the the declaration equals the definition. If
3517/// set to false, then the decalration is considered different from
3518/// the declaration.
3519///
3520/// @param the new value of the "decl-only-class-equals-definition"
3521/// flag.
3522void
3524{priv_->decl_only_class_equals_definition_ = f;}
3525
3526/// Test if a given type is a void type as defined in the current
3527/// environment.
3528///
3529/// @param t the type to consider.
3530///
3531/// @return true iff @p t is a void type as defined in the current
3532/// environment.
3533bool
3534environment::is_void_type(const type_base_sptr& t) const
3535{
3536 if (!t)
3537 return false;
3538 return is_void_type(t.get());
3539}
3540
3541/// Test if a given type is a void type as defined in the current
3542/// environment.
3543///
3544/// @param t the type to consider.
3545///
3546/// @return true iff @p t is a void type as defined in the current
3547/// environment.
3548bool
3550{
3551 if (!t)
3552 return false;
3553 return (t == get_void_type().get()
3554 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3555}
3556
3557/// Test if a given type is the same as the void pointer type of the
3558/// environment.
3559///
3560/// @param t the IR type to test.
3561///
3562/// @return true iff @p t is the void pointer returned by
3563/// environment::get_void_pointer_type().
3564bool
3565environment::is_void_pointer_type(const type_base_sptr& t) const
3566{
3567 if (!t)
3568 return false;
3569
3570 return t.get() == get_void_pointer_type().get();
3571}
3572
3573/// Test if a given type is the same as the void pointer type of the
3574/// environment.
3575///
3576/// @param t the IR type to test.
3577///
3578/// @return true iff @p t is the void pointer returned by
3579/// environment::get_void_pointer_type().
3580bool
3582{
3583 if (!t)
3584 return false;
3585
3586 return t == get_void_pointer_type().get();
3587}
3588
3589/// Test if a type is a variadic parameter type as defined in the
3590/// current environment.
3591///
3592/// @param t the type to consider.
3593///
3594/// @return true iff @p t is a variadic parameter type as defined in
3595/// the current environment.
3596bool
3598{
3599 if (!t)
3600 return false;
3601 return t == get_variadic_parameter_type().get();
3602}
3603
3604/// Test if a type is a variadic parameter type as defined in the
3605/// current environment.
3606///
3607/// @param t the type to consider.
3608///
3609/// @return true iff @p t is a variadic parameter type as defined in
3610/// the current environment.
3611bool
3612environment::is_variadic_parameter_type(const type_base_sptr& t) const
3613{return is_variadic_parameter_type(t.get());}
3614
3615/// Do intern a string.
3616///
3617/// If a value of this string already exists in the interned string
3618/// pool of the current environment, then this function returns a new
3619/// interned_string pointing to that already existing string.
3620/// Otherwise, a new string is created, stored in the interned string
3621/// pool and a new interned_string instance is created to point to
3622/// that new intrerned string, and it's return.
3623///
3624/// @param s the value of the string to intern.
3625///
3626/// @return the interned string.
3628environment::intern(const string& s) const
3629{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3630
3631/// Getter of the general configuration object.
3632///
3633/// @return the configuration object.
3634const config&
3636{return priv_->config_;}
3637
3638/// Getter for a property that says if the user actually did set the
3639/// analyze_exported_interfaces_only() property. If not, it means
3640/// the default behaviour prevails.
3641///
3642/// @return tru iff the user did set the
3643/// analyze_exported_interfaces_only() property.
3644bool
3646{return priv_->analyze_exported_interfaces_only_.has_value();}
3647
3648/// Setter for the property that controls if we are to restrict the
3649/// analysis to the types that are only reachable from the exported
3650/// interfaces only, or if the set of types should be more broad than
3651/// that. Typically, we'd restrict the analysis to types reachable
3652/// from exported interfaces only (stricto sensu, that would really be
3653/// only the types that are part of the ABI of well designed
3654/// libraries) for performance reasons.
3655///
3656/// @param f the value of the flag.
3657void
3659{priv_->analyze_exported_interfaces_only_ = f;}
3660
3661/// Getter for the property that controls if we are to restrict the
3662/// analysis to the types that are only reachable from the exported
3663/// interfaces only, or if the set of types should be more broad than
3664/// that. Typically, we'd restrict the analysis to types reachable
3665/// from exported interfaces only (stricto sensu, that would really be
3666/// only the types that are part of the ABI of well designed
3667/// libraries) for performance reasons.
3668///
3669/// @param f the value of the flag.
3670bool
3672{return priv_->analyze_exported_interfaces_only_.value_or(false);}
3673
3674#ifdef WITH_DEBUG_SELF_COMPARISON
3675/// Setter of the corpus of the input corpus of the self comparison
3676/// that takes place when doing "abidw --debug-abidiff <binary>".
3677///
3678/// The first invocation of this function sets the first corpus of the
3679/// self comparison. The second invocation of this very same function
3680/// sets the second corpus of the self comparison. That second corpus
3681/// is supposed to come from the abixml serialization of the first
3682/// corpus.
3683///
3684/// @param c the corpus of the input binary or the corpus of the
3685/// abixml serialization of the initial binary input.
3686void
3687environment::set_self_comparison_debug_input(const corpus_sptr& c)
3688{
3689 self_comparison_debug_is_on(true);
3690 if (priv_->first_self_comparison_corpus_.expired())
3691 priv_->first_self_comparison_corpus_ = c;
3692 else if (priv_->second_self_comparison_corpus_.expired()
3693 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3694 priv_->second_self_comparison_corpus_ = c;
3695}
3696
3697/// Getter for the corpora of the input binary and the intermediate
3698/// abixml of the self comparison that takes place when doing
3699/// 'abidw --debug-abidiff <binary>'.
3700///
3701/// @param first_corpus output parameter that is set to the corpus of
3702/// the input corpus.
3703///
3704/// @param second_corpus output parameter that is set to the corpus of
3705/// the second corpus.
3706void
3707environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3708 corpus_sptr& second_corpus)
3709{
3710 first_corpus = priv_->first_self_comparison_corpus_.lock();
3711 second_corpus = priv_->second_self_comparison_corpus_.lock();
3712}
3713
3714/// Turn on/off the self comparison debug mode.
3715///
3716/// @param f true iff the self comparison debug mode is turned on.
3717void
3718environment::self_comparison_debug_is_on(bool f)
3719{priv_->self_comparison_debug_on_ = f;}
3720
3721/// Test if we are in the process of the 'self-comparison
3722/// debugging' as triggered by 'abidw --debug-abidiff' command.
3723///
3724/// @return true if self comparison debug is on.
3725bool
3726environment::self_comparison_debug_is_on() const
3727{return priv_->self_comparison_debug_on_;}
3728#endif
3729
3730#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3731/// Set the "type canonicalization debugging" mode, triggered by using
3732/// the command: "abidw --debug-tc".
3733///
3734/// @param flag if true then the type canonicalization debugging mode
3735/// is enabled.
3736void
3737environment::debug_type_canonicalization_is_on(bool flag)
3738{priv_->debug_type_canonicalization_ = flag;}
3739
3740/// Getter of the "type canonicalization debugging" mode, triggered by
3741/// using the command: "abidw --debug-tc".
3742///
3743/// @return true iff the type canonicalization debugging mode is
3744/// enabled.
3745bool
3746environment::debug_type_canonicalization_is_on() const
3747{return priv_->debug_type_canonicalization_;}
3748
3749/// Setter of the "DIE canonicalization debugging" mode, triggered by
3750/// using the command: "abidw --debug-dc".
3751///
3752/// @param flag true iff the DIE canonicalization debugging mode is
3753/// enabled.
3754void
3755environment::debug_die_canonicalization_is_on(bool flag)
3756{priv_->debug_die_canonicalization_ = flag;}
3757
3758/// Getter of the "DIE canonicalization debugging" mode, triggered by
3759/// using the command: "abidw --debug-dc".
3760///
3761/// @return true iff the DIE canonicalization debugging mode is
3762/// enabled.
3763bool
3764environment::debug_die_canonicalization_is_on() const
3765{return priv_->debug_die_canonicalization_;}
3766#endif // WITH_DEBUG_TYPE_CANONICALIZATION
3767
3768/// Get the vector of canonical types which have a given "string
3769/// representation".
3770///
3771/// @param 'name', the textual representation of the type as returned
3772/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3773/// /*qualified=*/true)
3774///
3775/// This is useful to for debugging purposes as it's handy to use from
3776/// inside a debugger like GDB.
3777///
3778/// @return a pointer to the vector of canonical types having the
3779/// representation @p name, or nullptr if no type with that
3780/// representation exists.
3781vector<type_base_sptr>*
3783{
3784 auto ti = get_canonical_types_map().find(name);
3785 if (ti == get_canonical_types_map().end())
3786 return nullptr;
3787 return &ti->second;
3788}
3789
3790/// Get a given canonical type which has a given "string
3791/// representation".
3792///
3793/// @param 'name', the textual representation of the type as returned
3794/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3795/// /*qualified=*/true).
3796///
3797/// @param index, the index of the type in the vector of types that
3798/// all have the same textual representation @p 'name'. That vector
3799/// is returned by the function environment::get_canonical_types().
3800///
3801/// @return the canonical type which has the representation @p name,
3802/// and which is at index @p index in the vector of canonical types
3803/// having that same textual representation.
3804type_base*
3805environment::get_canonical_type(const char* name, unsigned index)
3806{
3807 vector<type_base_sptr> *types = get_canonical_types(name);
3808 if (!types ||index >= types->size())
3809 return nullptr;
3810 return (*types)[index].get();
3811}
3812
3813#ifdef WITH_DEBUG_SELF_COMPARISON
3814/// Get the set of abixml type-id and the pointer value of the
3815/// (canonical) type it's associated to.
3816///
3817/// This is useful for debugging purposes, especially in the context
3818/// of the use of the command:
3819/// 'abidw --debug-abidiff <binary>'.
3820///
3821/// @return the set of abixml type-id and the pointer value of the
3822/// (canonical) type it's associated to.
3823const unordered_map<string, uintptr_t>&
3824environment::get_type_id_canonical_type_map() const
3825{return priv_->get_type_id_canonical_type_map();}
3826
3827/// Get the set of abixml type-id and the pointer value of the
3828/// (canonical) type it's associated to.
3829///
3830/// This is useful for debugging purposes, especially in the context
3831/// of the use of the command:
3832/// 'abidw --debug-abidiff <binary>'.
3833///
3834/// @return the set of abixml type-id and the pointer value of the
3835/// (canonical) type it's associated to.
3836unordered_map<string, uintptr_t>&
3837environment::get_type_id_canonical_type_map()
3838{return priv_->get_type_id_canonical_type_map();}
3839
3840/// Getter of the map that associates the values of type pointers to
3841/// their type-id strings.
3842///
3843/// Note that this map is populated at abixml reading time, (by
3844/// build_type()) when a given XML element representing a type is
3845/// read into a corresponding abigail::ir::type_base.
3846///
3847/// This is used only for the purpose of debugging the
3848/// self-comparison process. That is, when invoking "abidw
3849/// --debug-abidiff".
3850///
3851/// @return the map that associates the values of type pointers to
3852/// their type-id strings.
3853const unordered_map<uintptr_t, string>&
3854environment::get_pointer_type_id_map() const
3855{return priv_->get_pointer_type_id_map();}
3856
3857/// Getter of the map that associates the values of type pointers to
3858/// their type-id strings.
3859///
3860/// Note that this map is populated at abixml reading time, (by
3861/// build_type()) when a given XML element representing a type is
3862/// read into a corresponding abigail::ir::type_base.
3863///
3864/// This is used only for the purpose of debugging the
3865/// self-comparison process. That is, when invoking "abidw
3866/// --debug-abidiff".
3867///
3868/// @return the map that associates the values of type pointers to
3869/// their type-id strings.
3870unordered_map<uintptr_t, string>&
3871environment::get_pointer_type_id_map()
3872{return priv_->get_pointer_type_id_map();}
3873
3874/// Getter of the type-id that corresponds to the value of a pointer
3875/// to abigail::ir::type_base that was created from the abixml reader.
3876///
3877/// That value is retrieved from the map returned from
3878/// environment::get_pointer_type_id_map().
3879///
3880/// That map is populated at abixml reading time, (by build_type())
3881/// when a given XML element representing a type is read into a
3882/// corresponding abigail::ir::type_base.
3883///
3884/// This is used only for the purpose of debugging the
3885/// self-comparison process. That is, when invoking "abidw
3886/// --debug-abidiff".
3887///
3888/// @return the type-id strings that corresponds
3889string
3890environment::get_type_id_from_pointer(uintptr_t ptr) const
3891{return priv_->get_type_id_from_pointer(ptr);}
3892
3893/// Getter of the type-id that corresponds to the value of an
3894/// abigail::ir::type_base that was created from the abixml reader.
3895///
3896/// That value is retrieved from the map returned from
3897/// environment::get_pointer_type_id_map().
3898///
3899/// That map is populated at abixml reading time, (by build_type())
3900/// when a given XML element representing a type is read into a
3901/// corresponding abigail::ir::type_base.
3902///
3903/// This is used only for the purpose of debugging the
3904/// self-comparison process. That is, when invoking "abidw
3905/// --debug-abidiff".
3906///
3907/// @return the type-id strings that corresponds
3908string
3909environment::get_type_id_from_type(const type_base *t) const
3910{return priv_->get_type_id_from_type(t);}
3911
3912/// Getter of the canonical type of the artifact designated by a
3913/// type-id.
3914///
3915/// That type-id was generated by the abixml writer at the emitting
3916/// time of the abixml file. The corresponding canonical type was
3917/// stored in the map returned by
3918/// environment::get_type_id_canonical_type_map().
3919///
3920/// This is useful for debugging purposes, especially in the context
3921/// of the use of the command:
3922/// 'abidw --debug-abidiff <binary>'.
3923///
3924/// @return the set of abixml type-id and the pointer value of the
3925/// (canonical) type it's associated to.
3926uintptr_t
3927environment::get_canonical_type_from_type_id(const char* type_id) const
3928{return priv_->get_canonical_type_from_type_id(type_id);}
3929#endif
3930
3931// </environment stuff>
3932
3933// <type_or_decl_base stuff>
3934
3935/// The private data of @ref type_or_decl_base.
3936struct type_or_decl_base::priv
3937{
3938 // This holds the kind of dynamic type of particular instance.
3939 // Yes, this is part of the implementation of a "poor man" runtime
3940 // type identification. We are doing this because profiling shows
3941 // that using dynamic_cast in some places is really to slow and is
3942 // constituting a hotspot. This poor man's implementation made
3943 // things be much faster.
3944 enum type_or_decl_kind kind_;
3945 // This holds the runtime type instance pointer of particular
3946 // instance. In other words, this is the "this pointer" of the
3947 // dynamic type of a particular instance.
3948 void* rtti_;
3949 // This holds a pointer to either the type_base sub-object (if the
3950 // current instance is a type) or the decl_base sub-object (if the
3951 // current instance is a decl). This is used by the is_decl() and
3952 // is_type() functions, which also show up during profiling as
3953 // hotspots, due to their use of dynamic_cast.
3954 void* type_or_decl_ptr_;
3955 bool hashing_started_;
3956 const environment& env_;
3957 translation_unit* translation_unit_;
3958 // The location of an artifact as seen from its input by the
3959 // artifact reader. This might be different from the source
3960 // location advertised by the original emitter of the artifact
3961 // emitter.
3962 location artificial_location_;
3963 // Flags if the current ABI artifact is artificial (i.e, *NOT*
3964 // generated from the initial source code, but rather either
3965 // artificially by the compiler or by libabigail itself).
3966 bool is_artificial_;
3967
3968 /// Constructor of the type_or_decl_base::priv private type.
3969 ///
3970 /// @param e the environment in which the ABI artifact was created.
3971 ///
3972 /// @param k the identifier of the runtime type of the current
3973 /// instance of ABI artifact.
3974 priv(const environment& e,
3975 enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL)
3976 : kind_(k),
3977 rtti_(),
3978 type_or_decl_ptr_(),
3979 hashing_started_(),
3980 env_(e),
3981 translation_unit_(),
3982 is_artificial_()
3983 {}
3984
3986 kind() const
3987 {return kind_;}
3988
3989 void
3990 kind (enum type_or_decl_kind k)
3991 {kind_ |= k;}
3992}; // end struct type_or_decl_base::priv
3993
3994/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
3995/// bitmap type.
3999{
4000 return static_cast<type_or_decl_base::type_or_decl_kind>
4001 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4002}
4003
4004/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4005/// bitmap type.
4009{
4010 l = l | r;
4011 return l;
4012}
4013
4014/// bitwise "AND" operator for the
4015/// type_or_decl_base::type_or_decl_kind bitmap type.
4019{
4020 return static_cast<type_or_decl_base::type_or_decl_kind>
4021 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4022}
4023
4024/// bitwise "A&=" operator for the
4025/// type_or_decl_base::type_or_decl_kind bitmap type.
4029{
4030 l = l & r;
4031 return l;
4032}
4033
4034/// Constructor of @ref type_or_decl_base.
4035///
4036/// @param the environment the current ABI artifact is constructed
4037/// from.
4038///
4039/// @param k the runtime identifier bitmap of the type being built.
4040type_or_decl_base::type_or_decl_base(const environment& e,
4041 enum type_or_decl_kind k)
4042 :priv_(new priv(e, k))
4043{}
4044
4045/// The destructor of the @ref type_or_decl_base type.
4047{}
4048
4049/// Getter of the flag that says if the artefact is artificial.
4050///
4051/// Being artificial means it was not explicitely mentionned in the
4052/// source code, but was rather artificially created by the compiler
4053/// or libabigail.
4054///
4055/// @return true iff the declaration is artificial.
4056bool
4058{return priv_->is_artificial_;}
4059
4060/// Setter of the flag that says if the artefact is artificial.
4061///
4062/// Being artificial means the artefact was not explicitely
4063/// mentionned in the source code, but was rather artificially created
4064/// by the compiler or by libabigail.
4065///
4066/// @param f the new value of the flag that says if the artefact is
4067/// artificial.
4068void
4070{priv_->is_artificial_ = f;}
4071
4072/// Getter for the "kind" property of @ref type_or_decl_base type.
4073///
4074/// This property holds the identifier bitmap of the runtime type of
4075/// an ABI artifact.
4076///
4077/// @return the runtime type identifier bitmap of the current ABI
4078/// artifact.
4081{return priv_->kind();}
4082
4083/// Setter for the "kind" property of @ref type_or_decl_base type.
4084///
4085/// This property holds the identifier bitmap of the runtime type of
4086/// an ABI artifact.
4087///
4088/// @param the runtime type identifier bitmap of the current ABI
4089/// artifact.
4090void
4092{priv_->kind(k);}
4093
4094/// Getter of the pointer to the runtime type sub-object of the
4095/// current instance.
4096///
4097/// @return the pointer to the runtime type sub-object of the current
4098/// instance.
4099const void*
4101{return priv_->rtti_;}
4102
4103/// Getter of the pointer to the runtime type sub-object of the
4104/// current instance.
4105///
4106/// @return the pointer to the runtime type sub-object of the current
4107/// instance.
4108void*
4110{return priv_->rtti_;}
4111
4112/// Setter of the pointer to the runtime type sub-object of the
4113/// current instance.
4114///
4115/// @param i the new pointer to the runtime type sub-object of the
4116/// current instance.
4117void
4119{
4120 priv_->rtti_ = i;
4121 if (type_base* t = dynamic_cast<type_base*>(this))
4122 priv_->type_or_decl_ptr_ = t;
4123 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4124 priv_->type_or_decl_ptr_ = d;
4125}
4126
4127/// Getter of the pointer to either the type_base sub-object of the
4128/// current instance if it's a type, or to the decl_base sub-object of
4129/// the current instance if it's a decl.
4130///
4131/// @return the pointer to either the type_base sub-object of the
4132/// current instance if it's a type, or to the decl_base sub-object of
4133/// the current instance if it's a decl.
4134const void*
4136{return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
4137
4138/// Getter of the pointer to either the type_base sub-object of the
4139/// current instance if it's a type, or to the decl_base sub-object of
4140/// the current instance if it's a decl.
4141///
4142/// @return the pointer to either the type_base sub-object of the
4143/// current instance if it's a type, or to the decl_base sub-object of
4144/// the current instance if it's a decl.
4145void*
4147{return priv_->type_or_decl_ptr_;}
4148
4149/// Getter for the 'hashing_started' property.
4150///
4151/// @return the 'hashing_started' property.
4152bool
4154{return priv_->hashing_started_;}
4155
4156/// Setter for the 'hashing_started' property.
4157///
4158/// @param b the value to set the 'hashing_property' to.
4159void
4161{priv_->hashing_started_ = b;}
4162
4163/// Getter of the environment of the current ABI artifact.
4164///
4165/// @return the environment of the artifact.
4166const environment&
4168{return priv_->env_;}
4169
4170/// Setter of the artificial location of the artificat.
4171///
4172/// The artificial location is a location that was artificially
4173/// generated by libabigail, not generated by the original emitter of
4174/// the ABI meta-data. For instance, when reading an XML element from
4175/// an abixml file, the artificial location is the source location of
4176/// the XML element within the file, not the value of the
4177/// 'location'property that might be carried by the element.
4178///
4179/// Artificial locations might be useful to ensure that abixml emitted
4180/// by the abixml writer are sorted the same way as the input abixml
4181/// read by the reader.
4182///
4183/// @param l the new artificial location.
4184void
4186{priv_->artificial_location_ = l;}
4187
4188/// Getter of the artificial location of the artifact.
4189///
4190/// The artificial location is a location that was artificially
4191/// generated by libabigail, not generated by the original emitter of
4192/// the ABI meta-data. For instance, when reading an XML element from
4193/// an abixml file, the artificial location is the source location of
4194/// the XML element within the file, not the value of the
4195/// 'location'property that might be carried by the element.
4196///
4197/// Artificial locations might be useful to ensure that the abixml
4198/// emitted by the abixml writer is sorted the same way as the input
4199/// abixml read by the reader.
4200///
4201/// @return the new artificial location.
4202location&
4204{return priv_->artificial_location_;}
4205
4206/// Test if the current ABI artifact carries an artificial location.
4207///
4208/// @return true iff the current ABI artifact carries an artificial location.
4209bool
4211{
4212 return (priv_->artificial_location_
4213 && priv_->artificial_location_.get_is_artificial());
4214}
4215
4216/// Get the @ref corpus this ABI artifact belongs to.
4217///
4218/// @return the corpus this ABI artifact belongs to, or nil if it
4219/// belongs to none for now.
4220corpus*
4222{
4224 if (!tu)
4225 return 0;
4226 return tu->get_corpus();
4227}
4228
4229
4230/// Get the @ref corpus this ABI artifact belongs to.
4231///
4232/// @return the corpus this ABI artifact belongs to, or nil if it
4233/// belongs to none for now.
4234const corpus*
4236{return const_cast<type_or_decl_base*>(this)->get_corpus();}
4237
4238/// Set the @ref translation_unit this ABI artifact belongs to.
4239///
4240/// Note that adding an ABI artifact to a containining on should
4241/// invoke this member function.
4242void
4244{priv_->translation_unit_ = tu;}
4245
4246
4247/// Get the @ref translation_unit this ABI artifact belongs to.
4248///
4249/// @return the translation unit this ABI artifact belongs to, or nil
4250/// if belongs to none for now.
4253{return priv_->translation_unit_;}
4254
4255/// Get the @ref translation_unit this ABI artifact belongs to.
4256///
4257/// @return the translation unit this ABI artifact belongs to, or nil
4258/// if belongs to none for now.
4259const translation_unit*
4261{return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
4262
4263/// Traverse the the ABI artifact.
4264///
4265/// @param v the visitor used to traverse the sub-tree nodes of the
4266/// artifact.
4267bool
4269{return true;}
4270
4271/// Non-member equality operator for the @type_or_decl_base type.
4272///
4273/// @param lr the left-hand operand of the equality.
4274///
4275/// @param rr the right-hand operatnr of the equality.
4276///
4277/// @return true iff @p lr equals @p rr.
4278bool
4280{
4281 const type_or_decl_base* l = &lr;
4282 const type_or_decl_base* r = &rr;
4283
4284 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4285 *dr = dynamic_cast<const decl_base*>(r);
4286
4287 if (!!dl != !!dr)
4288 return false;
4289
4290 if (dl && dr)
4291 return *dl == *dr;
4292
4293 const type_base* tl = dynamic_cast<const type_base*>(l),
4294 *tr = dynamic_cast<const type_base*>(r);
4295
4296 if (!!tl != !!tr)
4297 return false;
4298
4299 if (tl && tr)
4300 return *tl == *tr;
4301
4302 return false;
4303}
4304
4305/// Non-member equality operator for the @type_or_decl_base type.
4306///
4307/// @param l the left-hand operand of the equality.
4308///
4309/// @param r the right-hand operatnr of the equality.
4310///
4311/// @return true iff @p l equals @p r.
4312bool
4314{
4315 if (!! l != !!r)
4316 return false;
4317
4318 if (!l)
4319 return true;
4320
4321 return *r == *l;
4322}
4323
4324/// Non-member inequality operator for the @type_or_decl_base type.
4325///
4326/// @param l the left-hand operand of the equality.
4327///
4328/// @param r the right-hand operator of the equality.
4329///
4330/// @return true iff @p l is different from @p r.
4331bool
4333{return !operator==(l, r);}
4334
4335// </type_or_decl_base stuff>
4336
4337// <Decl definition>
4338
4339struct decl_base::priv
4340{
4341 bool in_pub_sym_tab_;
4342 bool is_anonymous_;
4343 location location_;
4344 context_rel *context_;
4345 interned_string name_;
4346 interned_string qualified_parent_name_;
4347 // This temporary qualified name is the cache used for the qualified
4348 // name before the type associated to this decl (if applicable) is
4349 // canonicalized. Once the type is canonicalized, the cached use is
4350 // the data member qualified_parent_name_ above.
4351 interned_string temporary_qualified_name_;
4352 // This is the fully qualified name of the decl. It contains the
4353 // name of the decl and the qualified name of its scope. So if in
4354 // the parent scopes of the decl, there is one anonymous struct,
4355 // somewhere in the name, there is going to by an
4356 // __anonymous_struct__ string, even if the anonymous struct is not
4357 // the direct containing scope of this decl.
4358 interned_string qualified_name_;
4359 interned_string temporary_internal_qualified_name_;
4360 interned_string internal_qualified_name_;
4361 // Unline qualified_name_, scoped_name_ contains the name of the
4362 // decl and the name of its scope; not the qualified name of the
4363 // scope.
4364 interned_string scoped_name_;
4365 interned_string linkage_name_;
4366 visibility visibility_;
4367 decl_base_sptr declaration_;
4368 decl_base_wptr definition_of_declaration_;
4369 decl_base* naked_definition_of_declaration_;
4370 bool is_declaration_only_;
4371 typedef_decl_sptr naming_typedef_;
4372
4373 priv()
4374 : in_pub_sym_tab_(false),
4375 is_anonymous_(true),
4376 context_(),
4377 visibility_(VISIBILITY_DEFAULT),
4378 naked_definition_of_declaration_(),
4379 is_declaration_only_(false)
4380 {}
4381
4382 priv(interned_string name, interned_string linkage_name, visibility vis)
4383 : in_pub_sym_tab_(false),
4384 context_(),
4385 name_(name),
4386 qualified_name_(name),
4387 linkage_name_(linkage_name),
4388 visibility_(vis),
4389 naked_definition_of_declaration_(),
4390 is_declaration_only_(false)
4391 {
4392 is_anonymous_ = name_.empty();
4393 }
4394
4395 ~priv()
4396 {
4397 delete context_;
4398 }
4399};// end struct decl_base::priv
4400
4401/// Constructor for the @ref decl_base type.
4402///
4403/// @param e the environment the current @ref decl_base is being
4404/// created in.
4405///
4406/// @param name the name of the declaration.
4407///
4408/// @param locus the location where to find the declaration in the
4409/// source code.
4410///
4411/// @param linkage_name the linkage name of the declaration.
4412///
4413/// @param vis the visibility of the declaration.
4414decl_base::decl_base(const environment& e,
4415 const string& name,
4416 const location& locus,
4417 const string& linkage_name,
4418 visibility vis)
4419 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4420 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4421{
4422 set_location(locus);
4423}
4424
4425/// Constructor.
4426///
4427/// @param e the environment this instance of @ref decl_base is
4428/// created in.
4429///
4430/// @param name the name of the declaration being constructed.
4431///
4432/// @param locus the source location of the declaration being constructed.
4433///
4434/// @param linkage_name the linkage name of the declaration being
4435/// constructed.
4436///
4437/// @param vis the visibility of the declaration being constructed.
4438decl_base::decl_base(const environment& e,
4439 const interned_string& name,
4440 const location& locus,
4441 const interned_string& linkage_name,
4442 visibility vis)
4443 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4444 priv_(new priv(name, linkage_name, vis))
4445{
4446 set_location(locus);
4447}
4448
4449/// Constructor for the @ref decl_base type.
4450///
4451///@param environment the environment this instance of @ref decl_base
4452/// is being constructed in.
4453///
4454/// @param l the location where to find the declaration in the source
4455/// code.
4456decl_base::decl_base(const environment& e, const location& l)
4457 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4458 priv_(new priv())
4459{
4460 set_location(l);
4461}
4462
4463/// Getter for the qualified name.
4464///
4465/// Unlike decl_base::get_qualified_name() this doesn't try to update
4466/// the qualified name.
4467///
4468/// @return the qualified name.
4469const interned_string&
4471{return priv_->qualified_name_;}
4472
4473/// Clear the qualified name of this decl.
4474///
4475/// This is useful to ensure that the cache for the qualified name of
4476/// the decl is refreshed right after type canonicalization, for
4477/// instance.
4478void
4480{priv_->qualified_name_.clear();}
4481
4482/// Setter for the qualified name.
4483///
4484/// @param n the new qualified name.
4485void
4487{priv_->qualified_name_ = n;}
4488
4489/// Getter of the temporary qualified name of the current declaration.
4490///
4491/// This temporary qualified name is used as a qualified name cache by
4492/// the type for which this is the declaration (when applicable)
4493/// before the type is canonicalized. Once the type is canonicalized,
4494/// it's the result of decl_base::peek_qualified_name() that becomes
4495/// the qualified name cached.
4496///
4497/// @return the temporary qualified name.
4498const interned_string&
4500{return priv_->temporary_qualified_name_;}
4501
4502/// Setter for the temporary qualified name of the current
4503/// declaration.
4504///
4505///@param n the new temporary qualified name.
4506///
4507/// This temporary qualified name is used as a qualified name cache by
4508/// the type for which this is the declaration (when applicable)
4509/// before the type is canonicalized. Once the type is canonicalized,
4510/// it's the result of decl_base::peek_qualified_name() that becomes
4511/// the qualified name cached.
4512void
4514{priv_->temporary_qualified_name_ = n;}
4515
4516///Getter for the context relationship.
4517///
4518///@return the context relationship for the current decl_base.
4519const context_rel*
4521{return priv_->context_;}
4522
4523///Getter for the context relationship.
4524///
4525///@return the context relationship for the current decl_base.
4528{return priv_->context_;}
4529
4530void
4531decl_base::set_context_rel(context_rel *c)
4532{priv_->context_ = c;}
4533
4534/// Get the hash of a decl. If the hash hasn't been computed yet,
4535/// compute it ans store its value; otherwise, just return the hash.
4536///
4537/// @return the hash of the decl.
4538size_t
4540{
4541 size_t result = 0;
4542
4543 if (const type_base* t = dynamic_cast<const type_base*>(this))
4544 {
4546 result = hash(t);
4547 }
4548 else
4549 // If we reach this point, it mean we are missing a virtual
4550 // overload for decl_base::get_hash. Add it!
4551 abort();
4552
4553 return result;
4554}
4555
4556/// Test if the decl is defined in a ELF symbol table as a public
4557/// symbol.
4558///
4559/// @return true iff the decl is defined in a ELF symbol table as a
4560/// public symbol.
4561bool
4563{return priv_->in_pub_sym_tab_;}
4564
4565/// Set the flag saying if this decl is from a symbol that is in
4566/// a public symbols table, defined as public (global or weak).
4567///
4568/// @param f the new flag value.
4569void
4571{priv_->in_pub_sym_tab_ = f;}
4572
4573/// Get the location of a given declaration.
4574///
4575/// The location is an abstraction for the tripplet {file path,
4576/// line, column} that defines where the declaration appeared in the
4577/// source code.
4578///
4579/// To get the value of the tripplet {file path, line, column} from
4580/// the @ref location, you need to use the
4581/// location_manager::expand_location() method.
4582///
4583/// The instance of @ref location_manager that you want is
4584/// accessible from the instance of @ref translation_unit that the
4585/// current instance of @ref decl_base belongs to, via a call to
4586/// translation_unit::get_loc_mgr().
4587///
4588/// @return the location of the current instance of @ref decl_base.
4589const location&
4591{return priv_->location_;}
4592
4593/// Set the location for a given declaration.
4594///
4595/// The location is an abstraction for the tripplet {file path,
4596/// line, column} that defines where the declaration appeared in the
4597/// source code.
4598///
4599/// To create a location from a tripplet {file path, line, column},
4600/// you need to use the method @ref
4601/// location_manager::create_new_location().
4602///
4603/// Note that there can be two kinds of location. An artificial
4604/// location and a non-artificial one. The non-artificial location is
4605/// the one emitted by the original emitter of the ABI artifact, for
4606/// instance, if the ABI artifact comes from debug info, then the
4607/// source location that is present in the debug info represent a
4608/// non-artificial location. When looking at an abixml file on the
4609/// other hand, the value of the 'location' attribute of an XML
4610/// element describing an artifact is the non-artificial location.
4611/// The artificial location is the location (line number from the
4612/// beginning of the file) of the XML element within the abixml file.
4613///
4614/// So, if the location that is being set is artificial, note that the
4615/// type_or_decl_base::has_artificial_location() method of this decl will
4616/// subsequently return true and that artificial location will have to
4617/// be retrieved using type_or_decl_base::get_artificial_location().
4618/// If the location is non-artificial however,
4619/// type_or_decl_base::has_artificial_location() will subsequently
4620/// return false and the non-artificial location will have to be
4621/// retrieved using decl_base::get_location().
4622///
4623/// The instance of @ref location_manager that you want is
4624/// accessible from the instance of @ref translation_unit that the
4625/// current instance of @ref decl_base belongs to, via a call to
4626/// translation_unit::get_loc_mgr().
4627void
4629{
4630 if (l.get_is_artificial())
4632 else
4633 priv_->location_ = l;
4634}
4635
4636/// Setter for the name of the decl.
4637///
4638/// @param n the new name to set.
4639void
4640decl_base::set_name(const string& n)
4641{
4642 priv_->name_ = get_environment().intern(n);
4643 priv_->is_anonymous_ = n.empty();
4644}
4645
4646/// Test if the current declaration is anonymous.
4647///
4648/// Being anonymous means that the declaration was created without a
4649/// name. This can usually happen for enum or struct types.
4650///
4651/// @return true iff the type is anonymous.
4652bool
4654{return priv_->is_anonymous_;}
4655
4656/// Set the "is_anonymous" flag of the current declaration.
4657///
4658/// Being anonymous means that the declaration was created without a
4659/// name. This can usually happen for enum or struct types.
4660///
4661/// @param f the new value of the flag.
4662void
4664{priv_->is_anonymous_ = f;}
4665
4666
4667/// Get the "has_anonymous_parent" flag of the current declaration.
4668///
4669/// Having an anoymous parent means having a anonymous parent scope
4670/// (containing type or namespace) which is either direct or indirect.
4671///
4672/// @return true iff the current decl has a direct or indirect scope
4673/// which is anonymous.
4674bool
4676{
4677 scope_decl *scope = get_scope();
4678 if (!scope)
4679 return false;
4680 return scope->get_is_anonymous();
4681}
4682
4683/// @return the logical "OR" of decl_base::get_is_anonymous() and
4684/// decl_base::get_has_anonymous_parent().
4685bool
4688
4689/// Getter for the naming typedef of the current decl.
4690///
4691/// Consider the C idiom:
4692///
4693/// typedef struct {int member;} foo_type;
4694///
4695/// In that idiom, foo_type is the naming typedef of the anonymous
4696/// struct that is declared.
4697///
4698/// @return the naming typedef, if any. Otherwise, returns nil.
4701{return priv_->naming_typedef_;}
4702
4703/// Set the naming typedef of the current instance of @ref decl_base.
4704///
4705/// Consider the C idiom:
4706///
4707/// typedef struct {int member;} foo_type;
4708///
4709/// In that idiom, foo_type is the naming typedef of the anonymous
4710/// struct that is declared.
4711///
4712/// After completion of this function, the decl will not be considered
4713/// anonymous anymore. It's name is going to be the name of the
4714/// naming typedef.
4715///
4716/// @param typedef_type the new naming typedef.
4717void
4719{
4720 // A naming typedef is usually for an anonymous type.
4722 // Whe the typedef-named decl is saved into abixml, it's
4723 // not anonymous anymore. Its name is the typedef name.
4724 // So when we read it back, we must still be able to
4725 // apply the naming typedef to the decl.
4726 || t->get_name() == get_name());
4727 // Only non canonicalized types can be edited this way.
4728 ABG_ASSERT(is_type(this)
4729 && is_type(this)->get_naked_canonical_type() == nullptr);
4730
4731 priv_->naming_typedef_ = t;
4732 set_name(t->get_name());
4733 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4734 set_qualified_name(get_environment().intern(qualified_name));
4735 set_is_anonymous(false);
4736 // Now that the qualified type of the decl has changed, let's update
4737 // the qualified names of the member types of this decls.
4738 update_qualified_name(this);
4739}
4740
4741/// Getter for the mangled name.
4742///
4743/// @return the new mangled name.
4744const interned_string&
4746{return priv_->linkage_name_;}
4747
4748/// Setter for the linkage name.
4749///
4750/// @param m the new linkage name.
4751void
4753{
4754 const environment& env = get_environment();
4755 priv_->linkage_name_ = env.intern(m);
4756}
4757
4758/// Getter for the visibility of the decl.
4759///
4760/// @return the new visibility.
4763{return priv_->visibility_;}
4764
4765/// Setter for the visibility of the decl.
4766///
4767/// @param v the new visibility.
4768void
4770{priv_->visibility_ = v;}
4771
4772/// Return the type containing the current decl, if any.
4773///
4774/// @return the type that contains the current decl, or NULL if there
4775/// is none.
4778{
4779 if (priv_->context_)
4780 return priv_->context_->get_scope();
4781 return 0;
4782}
4783
4784/// Return a copy of the qualified name of the parent of the current
4785/// decl.
4786///
4787/// @return the newly-built qualified name of the of the current decl.
4788const interned_string&
4790{return priv_->qualified_parent_name_;}
4791
4792/// Getter for the name of the current decl.
4793///
4794/// @return the name of the current decl.
4795const interned_string&
4797{return priv_->name_;}
4798
4799/// Compute the qualified name of the decl.
4800///
4801/// @param qn the resulting qualified name.
4802///
4803/// @param internal set to true if the call is intended for an
4804/// internal use (for technical use inside the library itself), false
4805/// otherwise. If you don't know what this is for, then set it to
4806/// false.
4807void
4809{qn = get_qualified_name(internal);}
4810
4811/// Get the pretty representatin of the current declaration.
4812///
4813///
4814/// @param internal set to true if the call is intended to get a
4815/// representation of the decl (or type) for the purpose of canonical
4816/// type comparison. This is mainly used in the function
4817/// type_base::get_canonical_type_for().
4818///
4819/// In other words if the argument for this parameter is true then the
4820/// call is meant for internal use (for technical use inside the
4821/// library itself), false otherwise. If you don't know what this is
4822/// for, then set it to false.
4823///
4824/// @param qualified_name if true, names emitted in the pretty
4825/// representation are fully qualified.
4826///
4827/// @return the default pretty representation for a decl. This is
4828/// basically the fully qualified name of the decl optionally prefixed
4829/// with a meaningful string to add context for the user.
4830string
4832 bool qualified_name) const
4833{
4834 if (internal
4835 && get_is_anonymous()
4836 && has_generic_anonymous_internal_type_name(this))
4837 {
4838 // We are looking at an anonymous enum, union or class and we
4839 // want an *internal* pretty representation for it. All
4840 // anonymous types of this kind in the same namespace must have
4841 // the same internal representation for type canonicalization to
4842 // work properly.
4843 //
4844 // OK, in practise, we are certainly looking at an enum because
4845 // classes and unions should have their own overloaded virtual
4846 // member function for this.
4847 string name = get_generic_anonymous_internal_type_name(this);
4848 if (qualified_name && !get_qualified_parent_name().empty())
4849 name = get_qualified_parent_name() + "::" + name;
4850 return name;
4851 }
4852
4853 if (qualified_name)
4854 return get_qualified_name(internal);
4855 return get_name();
4856}
4857
4858/// Return the qualified name of the decl.
4859///
4860/// This is the fully qualified name of the decl. It's made of the
4861/// concatenation of the name of the decl with the qualified name of
4862/// its scope.
4863///
4864/// Note that the value returned by this function is computed by @ref
4865/// update_qualified_name when the decl is added to its scope.
4866///
4867/// @param internal set to true if the call is intended for an
4868/// internal use (for technical use inside the library itself), false
4869/// otherwise. If you don't know what this is for, then set it to
4870/// false.
4871///
4872/// @return the resulting qualified name.
4873const interned_string&
4874decl_base::get_qualified_name(bool /*internal*/) const
4875{return priv_->qualified_name_;}
4876
4877/// Return the scoped name of the decl.
4878///
4879/// This is made of the concatenation of the name of the decl with the
4880/// name of its scope. It doesn't contain the qualified name of its
4881/// scope, unlike what is returned by decl_base::get_qualified_name.
4882///
4883/// Note that the value returned by this function is computed by @ref
4884/// update_qualified_name when the decl is added to its scope.
4885///
4886/// @return the scoped name of the decl.
4887const interned_string&
4889{return priv_->scoped_name_;}
4890
4891/// If this @ref decl_base is a definition, get its earlier
4892/// declaration.
4893///
4894/// @return the earlier declaration of the class, if any.
4895const decl_base_sptr
4897{return priv_->declaration_;}
4898
4899/// set the earlier declaration of this @ref decl_base definition.
4900///
4901/// @param d the earlier declaration to set. Note that it's set only
4902/// if it's a pure declaration.
4903void
4905{
4906 if (d && d->get_is_declaration_only())
4907 priv_->declaration_ = d;
4908}
4909
4910
4911/// If this @ref decl_base is declaration-only, get its definition, if
4912/// any.
4913///
4914/// @return the definition of this decl-only @ref decl_base.
4915const decl_base_sptr
4917{return priv_->definition_of_declaration_.lock();}
4918
4919/// If this @ref decl_base is declaration-only, get its definition,
4920/// if any.
4921///
4922/// Note that this function doesn't return a smart pointer, but rather
4923/// the underlying pointer managed by the smart pointer. So it's as
4924/// fast as possible. This getter is to be used in code paths that
4925/// are proven to be performance hot spots; especially, when comparing
4926/// sensitive types like enums, classes or unions. Those are compared
4927/// extremely frequently and thus, their access to the definition of
4928/// declaration must be fast.
4929///
4930/// @return the definition of the declaration.
4931const decl_base*
4933{return priv_->naked_definition_of_declaration_;}
4934
4935/// Test if a @ref decl_base is a declaration-only decl.
4936///
4937/// @return true iff the current @ref decl_base is declaration-only.
4938bool
4940{return priv_->is_declaration_only_;}
4941
4942/// Set a flag saying if the @ref enum_type_decl is a declaration-only
4943/// @ref enum_type_decl.
4944///
4945/// @param f true if the @ref enum_type_decl is a declaration-only
4946/// @ref enum_type_decl.
4947void
4949{
4950 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
4951
4952 priv_->is_declaration_only_ = f;
4953
4954 if (update_types_lookup_map)
4955 if (scope_decl* s = get_scope())
4956 {
4957 scope_decl::declarations::iterator i;
4958 if (s->find_iterator_for_member(this, i))
4960 else
4962 }
4963}
4964
4967{
4968 return static_cast<change_kind>(static_cast<unsigned>(l)
4969 | static_cast<unsigned>(r));
4970}
4971
4974{
4975 return static_cast<change_kind>(static_cast<unsigned>(l)
4976 & static_cast<unsigned>(r));
4977}
4978
4981{
4982 l = l | r;
4983 return l;
4984}
4985
4988{
4989 l = l & r;
4990 return l;
4991}
4992
4993/// Compare the properties that belong to the "is-a-member-relation"
4994/// of a decl.
4995///
4996/// For instance, access specifiers are part of the
4997/// "is-a-member-relation" of a decl.
4998///
4999/// This comparison however doesn't take decl names into account. So
5000/// typedefs for instance are decls that we want to compare with this
5001/// function.
5002///
5003/// This function is a sub-routine of the more general 'equals'
5004/// overload for instances of decl_base.
5005///
5006/// @param l the left-hand side operand of the comparison.
5007///
5008/// @param r the right-hand side operand of the comparison.
5009///
5010/// @return true iff @p l compare equals, as a member decl, to @p r.
5011bool
5013 const decl_base& r,
5014 change_kind* k)
5015{
5016 bool result = true;
5017 if (is_member_decl(l) && is_member_decl(r))
5018 {
5019 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
5020 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
5021
5022 access_specifier la = no_access, ra = no_access;
5023 bool member_types_or_functions =
5024 ((is_type(l) && is_type(r))
5025 || (is_function_decl(l) && is_function_decl(r)));
5026
5027 if (member_types_or_functions)
5028 {
5029 // Access specifiers on member types in DWARF is not
5030 // reliable; in the same DSO, the same struct can be either
5031 // a class or a struct, and the access specifiers of its
5032 // member types are not necessarily given, so they
5033 // effectively can be considered differently, again, in the
5034 // same DSO. So, here, let's avoid considering those!
5035 // during comparison.
5036 la = r1->get_access_specifier();
5037 ra = r2->get_access_specifier();
5038 r1->set_access_specifier(no_access);
5039 r2->set_access_specifier(no_access);
5040 }
5041
5042 bool rels_are_different = *r1 != *r2;
5043
5044 if (member_types_or_functions)
5045 {
5046 // restore the access specifiers.
5047 r1->set_access_specifier(la);
5048 r2->set_access_specifier(ra);
5049 }
5050
5051 if (rels_are_different)
5052 {
5053 result = false;
5054 if (k)
5056 }
5057 }
5058 ABG_RETURN(result);
5059}
5060
5061/// Get the name of a decl for the purpose of comparing two decl
5062/// names.
5063///
5064/// This is a sub-routine of the 'equal' overload for decl_base.
5065///
5066/// This function takes into account the fact that all anonymous names
5067/// shall have the same name for the purpose of comparison.
5068///
5069/// For decls that are part of an anonymous scope, only the
5070/// non-qualified name should be taken into account.
5071static interned_string
5072get_decl_name_for_comparison(const decl_base &d)
5073{
5074 if (has_generic_anonymous_internal_type_name(&d)
5075 && d.get_is_anonymous())
5076 {
5077 // The decl is anonymous. It should have the same name as the
5078 // other anymous types of the same kind.
5079 string r;
5080 r += get_generic_anonymous_internal_type_name(&d);
5081 return d.get_environment().intern(r);
5082 }
5083
5086 || is_typedef(&d))
5087 ? d.get_name()
5088 : d.get_qualified_name(/*internal=*/true);
5089 return n;
5090}
5091
5092/// Compares two instances of @ref decl_base.
5093///
5094/// If the two intances are different, set a bitfield to give some
5095/// insight about the kind of differences there are.
5096///
5097/// @param l the first artifact of the comparison.
5098///
5099/// @param r the second artifact of the comparison.
5100///
5101/// @param k a pointer to a bitfield that gives information about the
5102/// kind of changes there are between @p l and @p r. This one is set
5103/// iff it's non-null and if the function returns false.
5104///
5105/// Please note that setting k to a non-null value does have a
5106/// negative performance impact because even if @p l and @p r are not
5107/// equal, the function keeps up the comparison in order to determine
5108/// the different kinds of ways in which they are different.
5109///
5110/// @return true if @p l equals @p r, false otherwise.
5111bool
5112equals(const decl_base& l, const decl_base& r, change_kind* k)
5113{
5114 bool result = true;
5115 const interned_string &l_linkage_name = l.get_linkage_name();
5116 const interned_string &r_linkage_name = r.get_linkage_name();
5117 if (!l_linkage_name.empty() && !r_linkage_name.empty())
5118 {
5119 if (l_linkage_name != r_linkage_name)
5120 {
5121 // Linkage names are different. That usually means the two
5122 // decls are different, unless we are looking at two
5123 // function declarations which have two different symbols
5124 // that are aliases of each other.
5125 const function_decl *f1 = is_function_decl(&l),
5126 *f2 = is_function_decl(&r);
5127 if (f1 && f2 && function_decls_alias(*f1, *f2))
5128 ;// The two functions are aliases, so they are not
5129 // different.
5130 else
5131 {
5132 result = false;
5133 if (k)
5135 else
5137 }
5138 }
5139 }
5140
5141 // This is the qualified name of the decls that we want to compare.
5142 // We want to use the "internal" version of the qualified name as
5143 // that one is stable even for anonymous decls.
5144 interned_string ln = get_decl_name_for_comparison(l);
5145 interned_string rn = get_decl_name_for_comparison(r);
5146
5147 /// If both of the current decls have an anonymous scope then let's
5148 /// compare their name component by component by properly handling
5149 /// anonymous scopes. That's the slow path.
5150 ///
5151 /// Otherwise, let's just compare their name, the obvious way.
5152 /// That's the fast path because in that case the names are
5153 /// interned_string and comparing them is much faster.
5154 bool decls_are_same = (ln == rn);
5155 if (!decls_are_same
5156 && l.get_is_anonymous()
5158 && r.get_is_anonymous()
5160 // Both decls are anonymous and their scope are *NOT* anonymous.
5161 // So we consider the decls to have equivalent names (both
5162 // anonymous, remember). We are still in the fast path here.
5163 decls_are_same = true;
5164
5165 if (!decls_are_same
5168 // This is the slow path as we are comparing the decl qualified
5169 // names component by component, properly handling anonymous
5170 // scopes.
5171 decls_are_same = tools_utils::decl_names_equal(ln, rn);
5172
5173 if (!decls_are_same)
5174 {
5175 result = false;
5176 if (k)
5178 else
5180 }
5181
5182 result &= maybe_compare_as_member_decls(l, r, k);
5183
5184 ABG_RETURN(result);
5185}
5186
5187/// Return true iff the two decls have the same name.
5188///
5189/// This function doesn't test if the scopes of the the two decls are
5190/// equal.
5191///
5192/// Note that this virtual function is to be implemented by classes
5193/// that extend the \p decl_base class.
5194bool
5196{return equals(*this, other, 0);}
5197
5198/// Inequality operator.
5199///
5200/// @param other to other instance of @ref decl_base to compare the
5201/// current instance to.
5202///
5203/// @return true iff the current instance of @ref decl_base is
5204/// different from @p other.
5205bool
5207{return !operator==(other);}
5208
5209/// Destructor of the @ref decl_base type.
5211{delete priv_;}
5212
5213/// This implements the ir_traversable_base::traverse pure virtual
5214/// function.
5215///
5216/// @param v the visitor used on the member nodes of the translation
5217/// unit during the traversal.
5218///
5219/// @return true if the entire IR node tree got traversed, false
5220/// otherwise.
5221bool
5223{
5224 // Do nothing in the base class.
5225 return true;
5226}
5227
5228/// Setter of the scope of the current decl.
5229///
5230/// Note that the decl won't hold a reference on the scope. It's
5231/// rather the scope that holds a reference on its members.
5232void
5234{
5235 if (!priv_->context_)
5236 priv_->context_ = new context_rel(scope);
5237 else
5238 priv_->context_->set_scope(scope);
5239}
5240
5241// </decl_base definition>
5242
5243/// Streaming operator for the decl_base::visibility.
5244///
5245/// @param o the output stream to serialize the visibility to.
5246///
5247/// @param v the visibility to serialize.
5248///
5249/// @return the output stream.
5250std::ostream&
5251operator<<(std::ostream& o, decl_base::visibility v)
5252{
5253 string r;
5254 switch (v)
5255 {
5256 case decl_base::VISIBILITY_NONE:
5257 r = "none";
5258 break;
5259 case decl_base::VISIBILITY_DEFAULT:
5260 r = "default";
5261 break;
5262 case decl_base::VISIBILITY_PROTECTED:
5263 r = "protected";
5264 break;
5265 case decl_base::VISIBILITY_HIDDEN:
5266 r = "hidden";
5267 break;
5268 case decl_base::VISIBILITY_INTERNAL:
5269 r = "internal";
5270 break;
5271 }
5272 return o;
5273}
5274
5275/// Streaming operator for decl_base::binding.
5276///
5277/// @param o the output stream to serialize the visibility to.
5278///
5279/// @param b the binding to serialize.
5280///
5281/// @return the output stream.
5282std::ostream&
5283operator<<(std::ostream& o, decl_base::binding b)
5284{
5285 string r;
5286 switch (b)
5287 {
5288 case decl_base::BINDING_NONE:
5289 r = "none";
5290 break;
5291 case decl_base::BINDING_LOCAL:
5292 r = "local";
5293 break;
5294 case decl_base::BINDING_GLOBAL:
5295 r = "global";
5296 break;
5297 case decl_base::BINDING_WEAK:
5298 r = "weak";
5299 break;
5300 }
5301 o << r;
5302 return o;
5303}
5304
5305/// Turn equality of shared_ptr of decl_base into a deep equality;
5306/// that is, make it compare the pointed to objects, not just the
5307/// pointers.
5308///
5309/// @param l the shared_ptr of decl_base on left-hand-side of the
5310/// equality.
5311///
5312/// @param r the shared_ptr of decl_base on right-hand-side of the
5313/// equality.
5314///
5315/// @return true if the decl_base pointed to by the shared_ptrs are
5316/// equal, false otherwise.
5317bool
5318operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5319{
5320 if (l.get() == r.get())
5321 return true;
5322 if (!!l != !!r)
5323 return false;
5324
5325 return *l == *r;
5326}
5327
5328/// Inequality operator of shared_ptr of @ref decl_base.
5329///
5330/// This is a deep equality operator, that is, it compares the
5331/// pointed-to objects, rather than just the pointers.
5332///
5333/// @param l the left-hand-side operand.
5334///
5335/// @param r the right-hand-side operand.
5336///
5337/// @return true iff @p l is different from @p r.
5338bool
5339operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5340{return !operator==(l, r);}
5341
5342/// Turn equality of shared_ptr of type_base into a deep equality;
5343/// that is, make it compare the pointed to objects too.
5344///
5345/// @param l the shared_ptr of type_base on left-hand-side of the
5346/// equality.
5347///
5348/// @param r the shared_ptr of type_base on right-hand-side of the
5349/// equality.
5350///
5351/// @return true if the type_base pointed to by the shared_ptrs are
5352/// equal, false otherwise.
5353bool
5354operator==(const type_base_sptr& l, const type_base_sptr& r)
5355{
5356 if (l.get() == r.get())
5357 return true;
5358 if (!!l != !!r)
5359 return false;
5360
5361 return *l == *r;
5362}
5363
5364/// Turn inequality of shared_ptr of type_base into a deep equality;
5365/// that is, make it compare the pointed to objects..
5366///
5367/// @param l the shared_ptr of type_base on left-hand-side of the
5368/// equality.
5369///
5370/// @param r the shared_ptr of type_base on right-hand-side of the
5371/// equality.
5372///
5373/// @return true iff the type_base pointed to by the shared_ptrs are
5374/// different.
5375bool
5376operator!=(const type_base_sptr& l, const type_base_sptr& r)
5377{return !operator==(l, r);}
5378
5379/// Tests if a declaration has got a scope.
5380///
5381/// @param d the declaration to consider.
5382///
5383/// @return true if the declaration has got a scope, false otherwise.
5384bool
5386{return (d.get_scope());}
5387
5388/// Tests if a declaration has got a scope.
5389///
5390/// @param d the declaration to consider.
5391///
5392/// @return true if the declaration has got a scope, false otherwise.
5393bool
5394has_scope(const decl_base_sptr d)
5395{return has_scope(*d.get());}
5396
5397/// Tests if a declaration is a class member.
5398///
5399/// @param d the declaration to consider.
5400///
5401/// @return true if @p d is a class member, false otherwise.
5402bool
5403is_member_decl(const decl_base_sptr d)
5404{return is_at_class_scope(d) || is_method_decl(d);}
5405
5406/// Tests if a declaration is a class member.
5407///
5408/// @param d the declaration to consider.
5409///
5410/// @return true if @p d is a class member, false otherwise.
5411bool
5413{return is_at_class_scope(d) || is_method_decl(d);}
5414
5415/// Tests if a declaration is a class member.
5416///
5417/// @param d the declaration to consider.
5418///
5419/// @return true if @p d is a class member, false otherwise.
5420bool
5422{return is_at_class_scope(d) || is_method_decl(d);}
5423
5424/// Test if a declaration is a @ref scope_decl.
5425///
5426/// @param d the declaration to take in account.
5427///
5428/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5429/// if d is a @ref scope_decl.
5432{return dynamic_cast<scope_decl*>(d);}
5433
5434/// Test if a declaration is a @ref scope_decl.
5435///
5436/// @param d the declaration to take in account.
5437///
5438/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5439/// if d is a @ref scope_decl.
5441is_scope_decl(const decl_base_sptr& d)
5442{return dynamic_pointer_cast<scope_decl>(d);}
5443
5444/// Tests if a type is a class member.
5445///
5446/// @param t the type to consider.
5447///
5448/// @return true if @p t is a class member type, false otherwise.
5449bool
5450is_member_type(const type_base_sptr& t)
5451{
5452 decl_base_sptr d = get_type_declaration(t);
5453 return is_member_decl(d);
5454}
5455
5456/// Test if a type is user-defined.
5457///
5458/// A type is considered user-defined if it's a
5459/// struct/class/union/enum that is *NOT* artificial.
5460///
5461/// @param t the type to consider.
5462///
5463/// @return true iff the type @p t is user-defined.
5464bool
5466{
5467 if (t == 0)
5468 return false;
5469
5471 decl_base *d = is_decl(t);
5472
5474 && d && !d->get_is_artificial())
5475 return true;
5476
5477 return false;
5478}
5479
5480/// Test if a type is user-defined.
5481///
5482/// A type is considered user-defined if it's a
5483/// struct/class/union/enum.
5484///
5485///
5486/// @param t the type to consider.
5487///
5488/// @return true iff the type @p t is user-defined.
5489bool
5490is_user_defined_type(const type_base_sptr& t)
5491{return is_user_defined_type(t.get());}
5492
5493/// Gets the access specifier for a class member.
5494///
5495/// @param d the declaration of the class member to consider. Note
5496/// that this must be a class member otherwise the function aborts the
5497/// current process.
5498///
5499/// @return the access specifier for the class member @p d.
5502{
5504
5505 const context_rel* c = d.get_context_rel();
5506 ABG_ASSERT(c);
5507
5508 return c->get_access_specifier();
5509}
5510
5511/// Gets the access specifier for a class member.
5512///
5513/// @param d the declaration of the class member to consider. Note
5514/// that this must be a class member otherwise the function aborts the
5515/// current process.
5516///
5517/// @return the access specifier for the class member @p d.
5519get_member_access_specifier(const decl_base_sptr& d)
5520{return get_member_access_specifier(*d);}
5521
5522/// Sets the access specifier for a class member.
5523///
5524/// @param d the class member to set the access specifier for. Note
5525/// that this must be a class member otherwise the function aborts the
5526/// current process.
5527///
5528/// @param a the new access specifier to set the class member to.
5529void
5532{
5534
5536 ABG_ASSERT(c);
5537
5538 c->set_access_specifier(a);
5539}
5540
5541/// Sets the access specifier for a class member.
5542///
5543/// @param d the class member to set the access specifier for. Note
5544/// that this must be a class member otherwise the function aborts the
5545/// current process.
5546///
5547/// @param a the new access specifier to set the class member to.
5548void
5549set_member_access_specifier(const decl_base_sptr& d,
5552
5553/// Gets a flag saying if a class member is static or not.
5554///
5555/// @param d the declaration for the class member to consider. Note
5556/// that this must be a class member otherwise the function aborts the
5557/// current process.
5558///
5559/// @return true if the class member @p d is static, false otherwise.
5560bool
5562{
5564
5565 const context_rel* c = d.get_context_rel();
5566 ABG_ASSERT(c);
5567
5568 return c->get_is_static();
5569}
5570
5571/// Gets a flag saying if a class member is static or not.
5572///
5573/// @param d the declaration for the class member to consider. Note
5574/// that this must be a class member otherwise the function aborts the
5575/// current process.
5576///
5577/// @return true if the class member @p d is static, false otherwise.
5578bool
5580{return get_member_is_static(*d);}
5581
5582/// Gets a flag saying if a class member is static or not.
5583///
5584/// @param d the declaration for the class member to consider. Note
5585/// that this must be a class member otherwise the function aborts the
5586/// current process.
5587///
5588/// @return true if the class member @p d is static, false otherwise.
5589bool
5590get_member_is_static(const decl_base_sptr& d)
5591{return get_member_is_static(*d);}
5592
5593/// Test if a var_decl is a data member.
5594///
5595/// @param v the var_decl to consider.
5596///
5597/// @return true if @p v is data member, false otherwise.
5598bool
5600{return is_at_class_scope(v);}
5601
5602/// Test if a var_decl is a data member.
5603///
5604/// @param v the var_decl to consider.
5605///
5606/// @return true if @p v is data member, false otherwise.
5607bool
5609{return is_data_member(*v);}
5610
5611/// Test if a var_decl is a data member.
5612///
5613/// @param v the var_decl to consider.
5614///
5615/// @return true if @p v is data member, false otherwise.
5616bool
5618{return is_at_class_scope(d);}
5619
5620/// Test if a decl is a data member.
5621///
5622/// @param d the decl to consider.
5623///
5624/// @return a pointer to the data member iff @p d is a data member, or
5625/// a null pointer.
5627is_data_member(const decl_base_sptr& d)
5628{
5629 if (var_decl_sptr v = is_var_decl(d))
5630 {
5631 if (is_data_member(v))
5632 return v;
5633 }
5634 return var_decl_sptr();
5635}
5636
5637/// Test if a decl is a data member.
5638///
5639/// @param d the decl to consider.
5640///
5641/// @return a pointer to the data member iff @p d is a data member, or
5642/// a null pointer.
5645{
5646 if (var_decl_sptr v = is_var_decl(d))
5647 {
5648 if (is_data_member(v))
5649 return v;
5650 }
5651 return var_decl_sptr();
5652}
5653
5654/// Test if a decl is a data member.
5655///
5656/// @param d the decl to consider.
5657///
5658/// @return a pointer to the data member iff @p d is a data member, or
5659/// a null pointer.
5660var_decl*
5662{
5663 if (var_decl *v = is_var_decl(d))
5664 if (is_data_member(v))
5665 return v;
5666 return 0;
5667}
5668
5669/// Test if a decl is a data member.
5670///
5671/// @param d the decl to consider.
5672///
5673/// @return a pointer to the data member iff @p d is a data member, or
5674/// a null pointer.
5675var_decl*
5677{
5678 if (var_decl *v = is_var_decl(d))
5679 if (is_data_member(v))
5680 return v;
5681 return 0;
5682}
5683
5684/// Get the first non-anonymous data member of a given anonymous data
5685/// member.
5686///
5687/// E.g:
5688///
5689/// struct S
5690/// {
5691/// union // <-- for this anonymous data member, the function
5692/// // returns a.
5693/// {
5694/// int a;
5695/// charb;
5696/// };
5697/// };
5698///
5699/// @return anon_dm the anonymous data member to consider.
5700///
5701/// @return the first non-anonymous data member of @p anon_dm. If no
5702/// data member was found then this function returns @p anon_dm.
5703const var_decl_sptr
5705{
5706 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5707 return anon_dm;
5708
5709 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5710 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5711
5712 if (is_anonymous_data_member(first))
5714
5715 return first;
5716}
5717
5718/// In the context of a given class or union, this function returns
5719/// the data member that is located after a given data member.
5720///
5721/// @param klass the class or union to consider.
5722///
5723/// @param the data member to consider.
5724///
5725/// @return the data member that is located right after @p
5726/// data_member.
5727const var_decl_sptr
5729 const var_decl_sptr &data_member)
5730{
5731 if (!klass ||!data_member)
5732 return var_decl_sptr();
5733
5734 for (class_or_union::data_members::const_iterator it =
5735 klass->get_non_static_data_members().begin();
5736 it != klass->get_non_static_data_members().end();
5737 ++it)
5738 if (**it == *data_member)
5739 {
5740 ++it;
5741 if (it != klass->get_non_static_data_members().end())
5743 break;
5744 }
5745
5746 return var_decl_sptr();
5747}
5748
5749/// In the context of a given class or union, this function returns
5750/// the data member that is located after a given data member.
5751///
5752/// @param klass the class or union to consider.
5753///
5754/// @param the data member to consider.
5755///
5756/// @return the data member that is located right after @p
5757/// data_member.
5758const var_decl_sptr
5759get_next_data_member(const class_or_union_sptr& klass,
5760 const var_decl_sptr &data_member)
5761{return get_next_data_member(klass.get(), data_member);}
5762
5763/// Get the last data member of a class type.
5764///
5765/// @param klass the class type to consider.
5768{return klass.get_non_static_data_members().back();}
5769
5770/// Get the last data member of a class type.
5771///
5772/// @param klass the class type to consider.
5775{return get_last_data_member(*klass);}
5776
5777/// Get the last data member of a class type.
5778///
5779/// @param klass the class type to consider.
5781get_last_data_member(const class_or_union_sptr &klass)
5782{return get_last_data_member(klass.get());}
5783
5784/// Collect all the non-anonymous data members of a class or union type.
5785///
5786/// If the class contains any anonymous data member, this function
5787/// looks through it to collect the non-anonymous data members that it
5788/// contains. The function also also looks through the base classes
5789/// of the current type.
5790///
5791/// @param cou the class or union type to consider.
5792///
5793/// @param dms output parameter. This is populated by the function
5794/// with a map containing the non-anonymous data members that were
5795/// collected. The key of the map is the name of the data member.
5796/// This is set iff the function returns true.
5797///
5798/// @return true iff at least one non-anonymous data member was
5799/// collected.
5800bool
5803{
5804 if (!cou)
5805 return false;
5806
5807 bool result = false;
5808 class_decl* klass = is_class_type(cou);
5809 if (klass)
5810 // First look into base classes for data members.
5812 result |= collect_non_anonymous_data_members(base->get_base_class().get(), dms);
5813
5814 // Then look into our data members
5815 for (var_decl_sptr member : cou->get_non_static_data_members())
5816 {
5817 if (is_anonymous_data_member(member))
5818 {
5819 class_or_union_sptr cl = anonymous_data_member_to_class_or_union(member);
5820 ABG_ASSERT(cl);
5821 result |= collect_non_anonymous_data_members(cl.get(), dms);
5822 }
5823 else
5824 {
5825 dms[member->get_name()] = member;
5826 result = true;
5827 }
5828 }
5829 return true;
5830}
5831
5832/// Collect all the non-anonymous data members of a class or union type.
5833///
5834/// If the class contains any anonymous data member, this function
5835/// looks through it to collect the non-anonymous data members that it
5836/// contains. The function also also looks through the base classes
5837/// of the current type.
5838///
5839/// @param cou the class or union type to consider.
5840///
5841/// @param dms output parameter. This is populated by the function
5842/// with a map containing the non-anonymous data members that were
5843/// collected. The key of the map is the name of the data member.
5844/// This is set iff the function returns true.
5845///
5846/// @return true iff at least one non-anonymous data member was
5847/// collected.
5848bool
5850{return collect_non_anonymous_data_members(cou.get(), dms);}
5851
5852/// Test if a decl is an anonymous data member.
5853///
5854/// @param d the decl to consider.
5855///
5856/// @return true iff @p d is an anonymous data member.
5857bool
5859{return is_anonymous_data_member(&d);}
5860
5861/// Test if a decl is an anonymous data member.
5862///
5863/// @param d the decl to consider.
5864///
5865/// @return the var_decl representing the data member iff @p d is an
5866/// anonymous data member.
5867const var_decl*
5869{
5870 if (const var_decl* v = is_data_member(d))
5871 {
5873 return v;
5874 }
5875 return 0;
5876}
5877
5878/// Test if a decl is an anonymous data member.
5879///
5880/// @param d the decl to consider.
5881///
5882/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5883/// it's an anonymous data member. Otherwise returns a nil pointer.
5884const var_decl*
5886{
5887 if (const var_decl* v = is_data_member(d))
5888 {
5890 return v;
5891 }
5892 return 0;
5893}
5894
5895/// Test if a decl is an anonymous data member.
5896///
5897/// @param d the decl to consider.
5898///
5899/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5900/// it's an anonymous data member. Otherwise returns a nil pointer.
5903{
5904 if (var_decl_sptr v = is_data_member(d))
5905 {
5907 return v;
5908 }
5909 return var_decl_sptr();
5910}
5911
5912/// Test if a decl is an anonymous data member.
5913///
5914/// @param d the decl to consider.
5915///
5916/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5917/// it's an anonymous data member. Otherwise returns a nil pointer.
5919is_anonymous_data_member(const decl_base_sptr& d)
5920{
5921 if (var_decl_sptr v = is_data_member(d))
5922 return is_anonymous_data_member(v);
5923 return var_decl_sptr();
5924}
5925
5926/// Test if a @ref var_decl is an anonymous data member.
5927///
5928/// @param d the @ref var_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.
5934{
5935 if (is_anonymous_data_member(d.get()))
5936 return d;
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.
5946const var_decl*
5948{
5949 if (d && is_anonymous_data_member(*d))
5950 return d;
5951 return 0;
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 true iff @p d is an anonymous data member.
5959bool
5961{
5962 return (is_data_member(d)
5963 && d.get_is_anonymous()
5964 && d.get_name().empty()
5966}
5967
5968/// Test if a @ref var_decl is a data member belonging to an anonymous
5969/// type.
5970///
5971/// @param d the @ref var_decl to consider.
5972///
5973/// @return true iff @p d is a data member belonging to an anonymous
5974/// type.
5975bool
5977{
5978 if (is_data_member(d))
5979 {
5980 scope_decl* scope = d.get_scope();
5981 if (scope && scope->get_is_anonymous())
5982 return true;
5983 }
5984 return false;
5985}
5986
5987/// Test if a @ref var_decl is a data member belonging to an anonymous
5988/// type.
5989///
5990/// @param d the @ref var_decl to consider.
5991///
5992/// @return true iff @p d is a data member belonging to an anonymous
5993/// type.
5994bool
5997
5998/// Test if a @ref var_decl is a data member belonging to an anonymous
5999/// type.
6000///
6001/// @param d the @ref var_decl to consider.
6002///
6003/// @return true iff @p d is a data member belonging to an anonymous
6004/// type.
6005bool
6008
6009/// Get the @ref class_or_union type of a given anonymous data member.
6010///
6011/// @param d the anonymous data member to consider.
6012///
6013/// @return the @ref class_or_union type of the anonymous data member
6014/// @p d.
6017{
6018 if ((d = is_anonymous_data_member(d)))
6019 return is_class_or_union_type(d->get_type().get());
6020 return 0;
6021}
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.
6029class_or_union_sptr
6031{
6033 return is_class_or_union_type(d.get_type());
6034 return class_or_union_sptr();
6035}
6036
6037/// Test if a data member has annonymous type or not.
6038///
6039/// @param d the data member to consider.
6040///
6041/// @return the anonymous class or union type iff @p turns out to have
6042/// an anonymous type. Otherwise, returns nil.
6043const class_or_union_sptr
6045{
6046 if (is_data_member(d))
6047 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
6048 if (cou->get_is_anonymous())
6049 return cou;
6050
6051 return class_or_union_sptr();
6052}
6053
6054/// Test if a data member has annonymous type or not.
6055///
6056/// @param d the data member to consider.
6057///
6058/// @return the anonymous class or union type iff @p turns out to have
6059/// an anonymous type. Otherwise, returns nil.
6060const class_or_union_sptr
6062{
6063 if (d)
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{return data_member_has_anonymous_type(d.get());}
6077
6078/// Get the @ref class_or_union type of a given anonymous data member.
6079///
6080/// @param d the anonymous data member to consider.
6081///
6082/// @return the @ref class_or_union type of the anonymous data member
6083/// @p d.
6084class_or_union_sptr
6086{
6088 return is_class_or_union_type(v->get_type());
6089 return class_or_union_sptr();
6090}
6091
6092/// Test if a given anonymous data member exists in a class or union.
6093///
6094/// @param anon_dm the anonymous data member to consider.
6095///
6096/// @param clazz the class to consider.
6097///
6098/// @return true iff @p anon_dm exists in the @clazz.
6099bool
6101 const class_or_union& clazz)
6102{
6103 if (!anon_dm.get_is_anonymous()
6104 || !is_class_or_union_type(anon_dm.get_type()))
6105 return false;
6106
6107 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
6108 ABG_ASSERT(cl);
6109
6110 // Look for the presence of each data member of anon_dm in clazz.
6111 //
6112 // If one data member of anon_dm is not present in clazz, then the
6113 // data member anon_dm is considered to not exist in clazz.
6114 for (auto anon_dm_m : cl->get_non_static_data_members())
6115 {
6116 // If the data member anon_dm_m is not an anonymous data member,
6117 // it's easy to look for it.
6118 if (!is_anonymous_data_member(anon_dm_m))
6119 {
6120 if (!clazz.find_data_member(anon_dm_m->get_name()))
6121 return false;
6122 }
6123 // If anon_dm_m is itself an anonymous data member then recurse
6124 else
6125 {
6126 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
6127 return false;
6128 }
6129 }
6130
6131 return true;
6132}
6133
6134/// Test if a given decl is anonymous or has a naming typedef.
6135///
6136/// @param d the decl to consider.
6137///
6138/// @return true iff @p d is anonymous or has a naming typedef.
6139bool
6141{
6142 if (d.get_is_anonymous() || d.get_naming_typedef())
6143 return true;
6144 return false;
6145}
6146
6147/// Set the offset of a data member into its containing class.
6148///
6149/// @param m the data member to consider.
6150///
6151/// @param o the offset, in bits.
6152void
6154{
6156
6157 dm_context_rel* ctxt_rel =
6158 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6159 ABG_ASSERT(ctxt_rel);
6160
6161 ctxt_rel->set_offset_in_bits(o);
6162}
6163
6164/// Get the offset of a data member.
6165///
6166/// @param m the data member to consider.
6167///
6168/// @return the offset (in bits) of @p m in its containing class.
6169uint64_t
6171{
6173 const dm_context_rel* ctxt_rel =
6174 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6175 ABG_ASSERT(ctxt_rel);
6176 return ctxt_rel->get_offset_in_bits();
6177}
6178
6179/// Get the offset of a data member.
6180///
6181/// @param m the data member to consider.
6182///
6183/// @return the offset (in bits) of @p m in its containing class.
6184uint64_t
6186{return get_data_member_offset(*m);}
6187
6188/// Get the offset of a data member.
6189///
6190/// @param m the data member to consider.
6191///
6192/// @return the offset (in bits) of @p m in its containing class.
6193uint64_t
6194get_data_member_offset(const decl_base_sptr d)
6195{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6196
6197/// Get the offset of the non-static data member that comes after a
6198/// given one.
6199///
6200/// If there is no data member after after the one given to this
6201/// function (maybe because the given one is the last data member of
6202/// the class type) then the function return false.
6203///
6204/// @param klass the class to consider.
6205///
6206/// @param dm the data member before the one we want to retrieve.
6207///
6208/// @param offset out parameter. This parameter is set by the
6209/// function to the offset of the data member that comes right after
6210/// the data member @p dm, iff the function returns true.
6211///
6212/// @return true iff the data member coming right after @p dm was
6213/// found.
6214bool
6216 const var_decl_sptr& dm,
6217 uint64_t& offset)
6218{
6219 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6220 if (!next_dm)
6221 return false;
6222 offset = get_data_member_offset(next_dm);
6223 return true;
6224}
6225
6226/// Get the offset of the non-static data member that comes after a
6227/// given one.
6228///
6229/// If there is no data member after after the one given to this
6230/// function (maybe because the given one is the last data member of
6231/// the class type) then the function return false.
6232///
6233/// @param klass the class to consider.
6234///
6235/// @param dm the data member before the one we want to retrieve.
6236///
6237/// @param offset out parameter. This parameter is set by the
6238/// function to the offset of the data member that comes right after
6239/// the data member @p dm, iff the function returns true.
6240///
6241/// @return true iff the data member coming right after @p dm was
6242/// found.
6243bool
6244get_next_data_member_offset(const class_or_union_sptr& klass,
6245 const var_decl_sptr& dm,
6246 uint64_t& offset)
6247{return get_next_data_member_offset(klass.get(), dm, offset);}
6248
6249/// Get the absolute offset of a data member.
6250///
6251/// If the data member is part of an anonymous data member then this
6252/// returns the absolute offset -- relative to the beginning of the
6253/// containing class of the anonymous data member.
6254///
6255/// @param m the data member to consider.
6256///
6257/// @return the aboslute offset of the data member @p m.
6258uint64_t
6260{
6262 const dm_context_rel* ctxt_rel =
6263 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6264 ABG_ASSERT(ctxt_rel);
6265
6266 const var_decl *containing_anonymous_data_member =
6267 ctxt_rel->get_anonymous_data_member();
6268
6269 uint64_t containing_anonymous_data_member_offset = 0;
6270 if (containing_anonymous_data_member)
6271 containing_anonymous_data_member_offset =
6272 get_absolute_data_member_offset(*containing_anonymous_data_member);
6273
6274 return (ctxt_rel->get_offset_in_bits()
6275 +
6276 containing_anonymous_data_member_offset);
6277}
6278
6279/// Get the absolute offset of a data member.
6280///
6281/// If the data member is part of an anonymous data member then this
6282/// returns the absolute offset -- relative to the beginning of the
6283/// containing class of the anonymous data member.
6284///
6285/// @param m the data member to consider.
6286///
6287/// @return the aboslute offset of the data member @p m.
6288uint64_t
6290{
6291 if (!m)
6292 return 0;
6294}
6295
6296/// Get the size of a given variable.
6297///
6298/// @param v the variable to consider.
6299///
6300/// @return the size of variable @p v.
6301uint64_t
6303{
6304 type_base_sptr t = v->get_type();
6305 ABG_ASSERT(t);
6306
6307 return t->get_size_in_bits();
6308}
6309
6310/// Set a flag saying if a data member is laid out.
6311///
6312/// @param m the data member to consider.
6313///
6314/// @param l true if @p m is to be considered as laid out.
6315void
6317{
6319 dm_context_rel* ctxt_rel =
6320 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6321 ctxt_rel->set_is_laid_out(l);
6322}
6323
6324/// Test whether a data member is laid out.
6325///
6326/// @param m the data member to consider.
6327///
6328/// @return true if @p m is laid out, false otherwise.
6329bool
6331{
6333 const dm_context_rel* ctxt_rel =
6334 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6335
6336 return ctxt_rel->get_is_laid_out();
6337}
6338
6339/// Test whether a data member is laid out.
6340///
6341/// @param m the data member to consider.
6342///
6343/// @return true if @p m is laid out, false otherwise.
6344bool
6346{return get_data_member_is_laid_out(*m);}
6347
6348/// Test whether a function_decl is a member function.
6349///
6350/// @param f the function_decl to test.
6351///
6352/// @return true if @p f is a member function, false otherwise.
6353bool
6355{return is_member_decl(f);}
6356
6357/// Test whether a function_decl is a member function.
6358///
6359/// @param f the function_decl to test.
6360///
6361/// @return true if @p f is a member function, false otherwise.
6362bool
6364{return is_member_decl(*f);}
6365
6366/// Test whether a function_decl is a member function.
6367///
6368/// @param f the function_decl to test.
6369///
6370/// @return true if @p f is a member function, false otherwise.
6371bool
6373{return is_member_decl(*f);}
6374
6375/// Test whether a member function is a constructor.
6376///
6377/// @param f the member function to test.
6378///
6379/// @return true if @p f is a constructor, false otherwise.
6380bool
6382{
6384
6385 const method_decl* m = is_method_decl(&f);
6386 ABG_ASSERT(m);
6387
6388 const mem_fn_context_rel* ctxt =
6389 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6390
6391 return ctxt->is_constructor();
6392}
6393
6394/// Test whether a member function is a constructor.
6395///
6396/// @param f the member function to test.
6397///
6398/// @return true if @p f is a constructor, false otherwise.
6399bool
6401{return get_member_function_is_ctor(*f);}
6402
6403
6404/// Setter for the is_ctor property of the member function.
6405///
6406/// @param f the member function to set.
6407///
6408/// @param f the new boolean value of the is_ctor property. Is true
6409/// if @p f is a constructor, false otherwise.
6410void
6412{
6414
6415 method_decl* m = is_method_decl(&f);
6416 ABG_ASSERT(m);
6417
6418 mem_fn_context_rel* ctxt =
6419 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6420
6421 ctxt->is_constructor(c);
6422}
6423
6424/// Setter for the is_ctor property of the member function.
6425///
6426/// @param f the member function to set.
6427///
6428/// @param f the new boolean value of the is_ctor property. Is true
6429/// if @p f is a constructor, false otherwise.
6430void
6433
6434/// Test whether a member function is a destructor.
6435///
6436/// @param f the function to test.
6437///
6438/// @return true if @p f is a destructor, false otherwise.
6439bool
6441{
6443
6444 const method_decl* m = is_method_decl(&f);
6445 ABG_ASSERT(m);
6446
6447 const mem_fn_context_rel* ctxt =
6448 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6449
6450 return ctxt->is_destructor();
6451}
6452
6453/// Test whether a member function is a destructor.
6454///
6455/// @param f the function to test.
6456///
6457/// @return true if @p f is a destructor, false otherwise.
6458bool
6460{return get_member_function_is_dtor(*f);}
6461
6462/// Set the destructor-ness property of a member function.
6463///
6464/// @param f the function to set.
6465///
6466/// @param d true if @p f is a destructor, false otherwise.
6467void
6469{
6471
6472 method_decl* m = is_method_decl(&f);
6473 ABG_ASSERT(m);
6474
6475 mem_fn_context_rel* ctxt =
6476 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6477
6478 ctxt->is_destructor(d);
6479}
6480
6481/// Set the destructor-ness property of a member function.
6482///
6483/// @param f the function to set.
6484///
6485/// @param d true if @p f is a destructor, false otherwise.
6486void
6489
6490/// Test whether a member function is const.
6491///
6492/// @param f the function to test.
6493///
6494/// @return true if @p f is const, false otherwise.
6495bool
6497{
6499
6500 const method_decl* m = is_method_decl(&f);
6501 ABG_ASSERT(m);
6502
6503 const mem_fn_context_rel* ctxt =
6504 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6505
6506 return ctxt->is_const();
6507}
6508
6509/// Test whether a member function is const.
6510///
6511/// @param f the function to test.
6512///
6513/// @return true if @p f is const, false otherwise.
6514bool
6516{return get_member_function_is_const(*f);}
6517
6518/// set the const-ness property of a member function.
6519///
6520/// @param f the function to set.
6521///
6522/// @param is_const the new value of the const-ness property of @p f
6523void
6525{
6527
6528 method_decl* m = is_method_decl(&f);
6529 ABG_ASSERT(m);
6530
6531 mem_fn_context_rel* ctxt =
6532 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6533
6534 ctxt->is_const(is_const);
6535}
6536
6537/// set the const-ness property of a member function.
6538///
6539/// @param f the function to set.
6540///
6541/// @param is_const the new value of the const-ness property of @p f
6542void
6544{set_member_function_is_const(*f, is_const);}
6545
6546/// Test if a virtual member function has a vtable offset set.
6547///
6548/// @param f the virtual member function to consider.
6549///
6550/// @return true iff the virtual member function has its vtable offset
6551/// set, i.e, if the vtable offset of @p is different from -1.
6552bool
6554{return get_member_function_vtable_offset(f) != -1;}
6555
6556/// Get the vtable offset of a member function.
6557///
6558/// @param f the member function to consider.
6559///
6560/// @return the vtable offset of @p f. Note that a vtable offset of
6561/// value -1 means that the member function does *NOT* yet have a
6562/// vtable offset associated to it.
6563ssize_t
6565{
6567
6568 const method_decl* m =
6569 dynamic_cast<const method_decl*>(&f);
6570 ABG_ASSERT(m);
6571
6572 const mem_fn_context_rel* ctxt =
6573 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6574
6575 return ctxt->vtable_offset();
6576}
6577
6578/// Get the vtable offset of a member function.
6579///
6580/// @param f the member function to consider.
6581///
6582/// @return the vtable offset of @p f. Note that a vtable offset of
6583/// value -1 means that the member function does *NOT* yet have a
6584/// vtable offset associated to it.
6585ssize_t
6588
6589/// Set the vtable offset of a member function.
6590///
6591/// @param f the member function to consider.
6592///
6593/// @param s the new vtable offset. Please note that a vtable offset
6594/// of value -1 means that the virtual member function does not (yet)
6595/// have any vtable offset associated to it.
6596void
6598{
6600
6601 method_decl* m = is_method_decl(&f);
6602 ABG_ASSERT(m);
6603
6604 mem_fn_context_rel* ctxt =
6605 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6606
6607 ctxt->vtable_offset(s);
6608}
6609
6610/// Get the vtable offset of a member function.
6611///
6612/// @param f the member function to consider.
6613///
6614/// @param s the new vtable offset. Please note that a vtable offset
6615/// of value -1 means that the virtual member function does not (yet)
6616/// have any vtable offset associated to it.
6617void
6619{return set_member_function_vtable_offset(*f, s);}
6620
6621/// Test if a given member function is virtual.
6622///
6623/// @param mem_fn the member function to consider.
6624///
6625/// @return true iff a @p mem_fn is virtual.
6626bool
6628{
6630
6631 const method_decl* m =
6632 dynamic_cast<const method_decl*>(&f);
6633 ABG_ASSERT(m);
6634
6635 const mem_fn_context_rel* ctxt =
6636 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6637
6638 return ctxt->is_virtual();
6639}
6640
6641/// Test if a given member function is virtual.
6642///
6643/// @param mem_fn the member function to consider.
6644///
6645/// @return true iff a @p mem_fn is virtual.
6646bool
6648{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6649
6650/// Test if a given member function is virtual.
6651///
6652/// @param mem_fn the member function to consider.
6653///
6654/// @return true iff a @p mem_fn is virtual.
6655bool
6657{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6658
6659/// Set the virtual-ness of a member function.
6660///
6661/// @param f the member function to consider.
6662///
6663/// @param is_virtual set to true if the function is virtual.
6664void
6666{
6668
6669 method_decl* m = is_method_decl(&f);
6670 ABG_ASSERT(m);
6671
6672 mem_fn_context_rel* ctxt =
6673 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6674
6675 ctxt->is_virtual(is_virtual);
6676}
6677
6678/// Set the virtual-ness of a member function.
6679///
6680/// @param f the member function to consider.
6681///
6682/// @param is_virtual set to true if the function is virtual.
6683void
6685{
6686 if (fn)
6687 {
6688 set_member_function_is_virtual(*fn, is_virtual);
6690 (dynamic_pointer_cast<method_decl>(fn));
6691 }
6692}
6693
6694/// Recursively returns the the underlying type of a typedef. The
6695/// return type should not be a typedef of anything anymore.
6696///
6697///
6698/// Also recursively strip typedefs from the sub-types of the type
6699/// given in arguments.
6700///
6701/// Note that this function builds types in which typedefs are
6702/// stripped off. Usually, types are held by their scope, so their
6703/// life time is bound to the life time of their scope. But as this
6704/// function cannot really insert the built type into it's scope, it
6705/// must ensure that the newly built type stays live long enough.
6706///
6707/// So, if the newly built type has a canonical type, this function
6708/// returns the canonical type. Otherwise, this function ensure that
6709/// the newly built type has a life time that is the same as the life
6710/// time of the entire libabigail library.
6711///
6712/// @param type the type to strip the typedefs from.
6713///
6714/// @return the resulting type stripped from its typedefs, or just
6715/// return @p type if it has no typedef in any of its sub-types.
6716type_base_sptr
6717strip_typedef(const type_base_sptr type)
6718{
6719 if (!type)
6720 return type;
6721
6722 // If type is a class type then do not try to strip typedefs from it.
6723 // And if it has no canonical type (which can mean that it's a
6724 // declaration-only class), then, make sure its live for ever and
6725 // return it.
6726 if (class_decl_sptr cl = is_class_type(type))
6727 {
6728 if (!cl->get_canonical_type())
6729 keep_type_alive(type);
6730 return type;
6731 }
6732
6733 const environment& env = type->get_environment();
6734 type_base_sptr t = type;
6735
6736 if (const typedef_decl_sptr ty = is_typedef(t))
6737 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6738 else if (const reference_type_def_sptr ty = is_reference_type(t))
6739 {
6740 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6741 env));
6742 ABG_ASSERT(p);
6743 t.reset(new reference_type_def(p,
6744 ty->is_lvalue(),
6745 ty->get_size_in_bits(),
6746 ty->get_alignment_in_bits(),
6747 ty->get_location()));
6748 }
6749 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6750 {
6751 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6752 env));
6753 ABG_ASSERT(p);
6754 t.reset(new pointer_type_def(p,
6755 ty->get_size_in_bits(),
6756 ty->get_alignment_in_bits(),
6757 ty->get_location()));
6758 }
6759 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6760 {
6761 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6762 env));
6763 ABG_ASSERT(p);
6764 t.reset(new qualified_type_def(p,
6765 ty->get_cv_quals(),
6766 ty->get_location()));
6767 }
6768 else if (const array_type_def_sptr ty = is_array_type(t))
6769 {
6770 type_base_sptr p = strip_typedef(ty->get_element_type());
6771 ABG_ASSERT(p);
6772 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6773 }
6774 else if (const method_type_sptr ty = is_method_type(t))
6775 {
6777 for (function_decl::parameters::const_iterator i =
6778 ty->get_parameters().begin();
6779 i != ty->get_parameters().end();
6780 ++i)
6781 {
6783 type_base_sptr typ = strip_typedef(p->get_type());
6784 ABG_ASSERT(typ);
6786 (new function_decl::parameter(typ,
6787 p->get_index(),
6788 p->get_name(),
6789 p->get_location(),
6790 p->get_variadic_marker(),
6791 p->get_is_artificial()));
6792 parm.push_back(stripped);
6793 }
6794 type_base_sptr p = strip_typedef(ty->get_return_type());
6795 ABG_ASSERT(!!p == !!ty->get_return_type());
6796 t.reset(new method_type(p, ty->get_class_type(),
6797 parm, ty->get_is_const(),
6798 ty->get_size_in_bits(),
6799 ty->get_alignment_in_bits()));
6800 }
6801 else if (const function_type_sptr ty = is_function_type(t))
6802 {
6804 for (function_decl::parameters::const_iterator i =
6805 ty->get_parameters().begin();
6806 i != ty->get_parameters().end();
6807 ++i)
6808 {
6810 type_base_sptr typ = strip_typedef(p->get_type());
6811 ABG_ASSERT(typ);
6813 (new function_decl::parameter(typ,
6814 p->get_index(),
6815 p->get_name(),
6816 p->get_location(),
6817 p->get_variadic_marker(),
6818 p->get_is_artificial()));
6819 parm.push_back(stripped);
6820 }
6821 type_base_sptr p = strip_typedef(ty->get_return_type());
6822 ABG_ASSERT(!!p == !!ty->get_return_type());
6823 t.reset(new function_type(p, parm,
6824 ty->get_size_in_bits(),
6825 ty->get_alignment_in_bits()));
6826 }
6827
6828 if (!t->get_translation_unit())
6829 t->set_translation_unit(type->get_translation_unit());
6830
6831 if (!(type->get_canonical_type() && canonicalize(t)))
6832 keep_type_alive(t);
6833
6834 return t->get_canonical_type() ? t->get_canonical_type() : t;
6835}
6836
6837/// Strip qualification from a qualified type, when it makes sense.
6838///
6839/// DWARF constructs "const reference". This is redundant because a
6840/// reference is always const. It also constructs the useless "const
6841/// void" type. The issue is these redundant types then leak into the
6842/// IR and make for bad diagnostics.
6843///
6844/// This function thus strips the const qualifier from the type in
6845/// that case. It might contain code to strip other cases like this
6846/// in the future.
6847///
6848/// @param t the type to strip const qualification from.
6849///
6850/// @return the stripped type or just return @p t.
6851decl_base_sptr
6852strip_useless_const_qualification(const qualified_type_def_sptr t)
6853{
6854 if (!t)
6855 return t;
6856
6857 decl_base_sptr result = t;
6858 type_base_sptr u = t->get_underlying_type();
6859 const environment& env = t->get_environment();
6860
6861 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6862 && (is_reference_type(u)))
6863 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6864 && env.is_void_type(u))
6865 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6866 // Let's strip the const qualifier because a reference is always
6867 // 'const' and a const void doesn't make sense. They will just
6868 // lead to spurious changes later down the pipeline, that we'll
6869 // have to deal with by doing painful and error-prone editing of
6870 // the diff IR. Dropping that useless and inconsistent artefact
6871 // right here seems to be a good way to go.
6872 result = is_decl(u);
6873
6874 return result;
6875}
6876
6877/// Merge redundant qualifiers from a tree of qualified types.
6878///
6879/// Suppose a tree of qualified types leads to:
6880///
6881/// const virtual const restrict const int;
6882///
6883/// Suppose the IR tree of qualified types ressembles (with C meaning
6884/// const, V meaning virtual and R meaning restrict):
6885///
6886/// [C|V]-->[C|R] -->[C] --> [int].
6887///
6888/// This function walks the IR and remove the redundant CV qualifiers
6889/// so the IR becomes:
6890///
6891/// [C|V] --> [R] --> [] -->[int].
6892///
6893/// Note that the empty qualified type (noted []) represents a
6894/// qualified type with no qualifier. It's rare, but it can exist.
6895/// I've put it here just for the sake of example.
6896///
6897/// The resulting IR thus represents the (merged) type:
6898///
6899/// const virtual restrict int.
6900///
6901/// This function is a sub-routine of the overload @ref
6902/// strip_useless_const_qualification which doesn't return any value.
6903///
6904/// @param t the qualified type to consider.
6905///
6906/// @param redundant_quals the (redundant) qualifiers to be removed
6907/// from the qualifiers of the underlying types of @p t.
6908///
6909/// @return the underlying type of @p t which might have had its
6910/// redundant qualifiers removed.
6911static qualified_type_def_sptr
6912strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
6913 qualified_type_def::CV redundant_quals)
6914{
6915 if (!t)
6916 return t;
6917
6918 // We must NOT edit canonicalized types.
6919 ABG_ASSERT(!t->get_canonical_type());
6920
6921 qualified_type_def_sptr underlying_qualified_type =
6922 is_qualified_type(t->get_underlying_type());
6923
6924 // Let's build 'currated qualifiers' that are the qualifiers of the
6925 // current type from which redundant qualifiers are removed.
6926 qualified_type_def::CV currated_quals = t->get_cv_quals();
6927
6928 // Remove the redundant qualifiers from these currated qualifiers
6929 currated_quals &= ~redundant_quals;
6930 t->set_cv_quals(currated_quals);
6931
6932 // The redundant qualifiers, moving forward, is now the union of the
6933 // previous set of redundant qualifiers and the currated qualifiers.
6934 redundant_quals |= currated_quals;
6935
6936 qualified_type_def_sptr result = t;
6937 if (underlying_qualified_type)
6938 // Now remove the redundant qualifiers from the qualified types
6939 // potentially carried by the underlying type.
6940 result =
6941 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
6942 redundant_quals);
6943
6944 return result;
6945}
6946
6947/// Merge redundant qualifiers from a tree of qualified types.
6948///
6949/// Suppose a tree of qualified types leads to:
6950///
6951/// const virtual const restrict const int;
6952///
6953/// Suppose the IR tree of qualified types ressembles (with C meaning
6954/// const, V meaning virtual and R meaning restrict):
6955///
6956/// [C|V]-->[C|R] -->[C] --> [int].
6957///
6958/// This function walks the IR and remove the redundant CV qualifiers
6959/// so the IR becomes:
6960///
6961/// [C|V] --> [R] --> [] -->[int].
6962///
6963/// Note that the empty qualified type (noted []) represents a
6964/// qualified type with no qualifier. It's rare, but it can exist.
6965/// I've put it here just for the sake of example.
6966///
6967/// The resulting IR thus represents the (merged) type:
6968///
6969/// const virtual restrict int.
6970///
6971/// @param t the qualified type to consider. The IR below the
6972/// argument to this parameter will be edited to remove redundant
6973/// qualifiers where applicable.
6974void
6975strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
6976{
6977 if (!t)
6978 return;
6979
6980 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
6981 strip_redundant_quals_from_underyling_types(t, redundant_quals);
6982}
6983
6984/// Return the leaf underlying type node of a @ref typedef_decl node.
6985///
6986/// If the underlying type of a @ref typedef_decl node is itself a
6987/// @ref typedef_decl node, then recursively look at the underlying
6988/// type nodes to get the first one that is not a a @ref typedef_decl
6989/// node. This is what a leaf underlying type node means.
6990///
6991/// Otherwise, if the underlying type node of @ref typedef_decl is
6992/// *NOT* a @ref typedef_decl node, then just return the underlying
6993/// type node.
6994///
6995/// And if the type node considered is not a @ref typedef_decl node,
6996/// then just return it.
6997///
6998/// @return the leaf underlying type node of a @p type.
6999type_base_sptr
7000peel_typedef_type(const type_base_sptr& type)
7001{
7002 typedef_decl_sptr t = is_typedef(type);
7003 if (!t)
7004 return type;
7005
7006 if (is_typedef(t->get_underlying_type()))
7007 return peel_typedef_type(t->get_underlying_type());
7008 return t->get_underlying_type();
7009}
7010
7011/// Return the leaf underlying type node of a @ref typedef_decl node.
7012///
7013/// If the underlying type of a @ref typedef_decl node is itself a
7014/// @ref typedef_decl node, then recursively look at the underlying
7015/// type nodes to get the first one that is not a a @ref typedef_decl
7016/// node. This is what a leaf underlying type node means.
7017///
7018/// Otherwise, if the underlying type node of @ref typedef_decl is
7019/// *NOT* a @ref typedef_decl node, then just return the underlying
7020/// type node.
7021///
7022/// And if the type node considered is not a @ref typedef_decl node,
7023/// then just return it.
7024///
7025/// @return the leaf underlying type node of a @p type.
7026const type_base*
7028{
7029 const typedef_decl* t = is_typedef(type);
7030 if (!t)
7031 return type;
7032
7033 return peel_typedef_type(t->get_underlying_type()).get();
7034}
7035
7036/// Return the leaf pointed-to type node of a @ref pointer_type_def
7037/// node.
7038///
7039/// If the pointed-to type of a @ref pointer_type_def node is itself a
7040/// @ref pointer_type_def node, then recursively look at the
7041/// pointed-to type nodes to get the first one that is not a a @ref
7042/// pointer_type_def node. This is what a leaf pointed-to type node
7043/// means.
7044///
7045/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7046/// *NOT* a @ref pointer_type_def node, then just return the
7047/// pointed-to type node.
7048///
7049/// And if the type node considered is not a @ref pointer_type_def
7050/// node, then just return it.
7051///
7052/// @return the leaf pointed-to type node of a @p type.
7053type_base_sptr
7054peel_pointer_type(const type_base_sptr& type)
7055{
7057 if (!t)
7058 return type;
7059
7060 if (is_pointer_type(t->get_pointed_to_type()))
7061 return peel_pointer_type(t->get_pointed_to_type());
7062 return t->get_pointed_to_type();
7063}
7064
7065/// Return the leaf pointed-to type node of a @ref pointer_type_def
7066/// node.
7067///
7068/// If the pointed-to type of a @ref pointer_type_def node is itself a
7069/// @ref pointer_type_def node, then recursively look at the
7070/// pointed-to type nodes to get the first one that is not a a @ref
7071/// pointer_type_def node. This is what a leaf pointed-to type node
7072/// means.
7073///
7074/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7075/// *NOT* a @ref pointer_type_def node, then just return the
7076/// pointed-to type node.
7077///
7078/// And if the type node considered is not a @ref pointer_type_def
7079/// node, then just return it.
7080///
7081/// @return the leaf pointed-to type node of a @p type.
7082const type_base*
7084{
7085 const pointer_type_def* t = is_pointer_type(type);
7086 if (!t)
7087 return type;
7088
7089 return peel_pointer_type(t->get_pointed_to_type()).get();
7090}
7091
7092/// Return the leaf pointed-to type node of a @ref reference_type_def
7093/// node.
7094///
7095/// If the pointed-to type of a @ref reference_type_def node is itself
7096/// a @ref reference_type_def node, then recursively look at the
7097/// pointed-to type nodes to get the first one that is not a a @ref
7098/// reference_type_def node. This is what a leaf pointed-to type node
7099/// means.
7100///
7101/// Otherwise, if the pointed-to type node of @ref reference_type_def
7102/// is *NOT* a @ref reference_type_def node, then just return the
7103/// pointed-to type node.
7104///
7105/// And if the type node considered is not a @ref reference_type_def
7106/// node, then just return it.
7107///
7108/// @return the leaf pointed-to type node of a @p type.
7109type_base_sptr
7110peel_reference_type(const type_base_sptr& type)
7111{
7113 if (!t)
7114 return type;
7115
7116 if (is_reference_type(t->get_pointed_to_type()))
7117 return peel_reference_type(t->get_pointed_to_type());
7118 return t->get_pointed_to_type();
7119}
7120
7121/// Return the leaf pointed-to type node of a @ref reference_type_def
7122/// node.
7123///
7124/// If the pointed-to type of a @ref reference_type_def node is itself
7125/// a @ref reference_type_def node, then recursively look at the
7126/// pointed-to type nodes to get the first one that is not a a @ref
7127/// reference_type_def node. This is what a leaf pointed-to type node
7128/// means.
7129///
7130/// Otherwise, if the pointed-to type node of @ref reference_type_def
7131/// is *NOT* a @ref reference_type_def node, then just return the
7132/// pointed-to type node.
7133///
7134/// And if the type node considered is not a @ref reference_type_def
7135/// node, then just return it.
7136///
7137/// @return the leaf pointed-to type node of a @p type.
7138const type_base*
7140{
7141 const reference_type_def* t = is_reference_type(type);
7142 if (!t)
7143 return type;
7144
7145 return peel_reference_type(t->get_pointed_to_type()).get();
7146}
7147
7148/// Return the leaf element type of an array.
7149///
7150/// If the element type is itself an array, then recursively return
7151/// the element type of that array itself.
7152///
7153/// @param type the array type to consider. If this is not an array
7154/// type, this type is returned by the function.
7155///
7156/// @return the leaf element type of the array @p type, or, if it's
7157/// not an array type, then just return @p.
7158const type_base_sptr
7159peel_array_type(const type_base_sptr& type)
7160{
7161 const array_type_def_sptr t = is_array_type(type);
7162 if (!t)
7163 return type;
7164
7165 return peel_array_type(t->get_element_type());
7166}
7167
7168/// Return the leaf element type of an array.
7169///
7170/// If the element type is itself an array, then recursively return
7171/// the element type of that array itself.
7172///
7173/// @param type the array type to consider. If this is not an array
7174/// type, this type is returned by the function.
7175///
7176/// @return the leaf element type of the array @p type, or, if it's
7177/// not an array type, then just return @p.
7178const type_base*
7180{
7181 const array_type_def* t = is_array_type(type);
7182 if (!t)
7183 return type;
7184
7185 return peel_array_type(t->get_element_type()).get();
7186}
7187
7188/// Return the leaf underlying type of a qualified type.
7189///
7190/// If the underlying type is itself a qualified type, then
7191/// recursively return the first underlying type of that qualified
7192/// type to return the first underlying type that is not a qualified type.
7193///
7194/// If the underlying type is NOT a qualified type, then just return
7195/// that underlying type.
7196///
7197/// @param type the qualified type to consider.
7198///
7199/// @return the leaf underlying type.
7200const type_base*
7202{
7203 const qualified_type_def* t = is_qualified_type(type);
7204 if (!t)
7205 return type;
7206
7207 return peel_qualified_type(t->get_underlying_type().get());
7208}
7209
7210/// Return the leaf underlying type of a qualified type.
7211///
7212/// If the underlying type is itself a qualified type, then
7213/// recursively return the first underlying type of that qualified
7214/// type to return the first underlying type that is not a qualified type.
7215///
7216/// If the underlying type is NOT a qualified type, then just return
7217/// that underlying type.
7218///
7219/// @param type the qualified type to consider.
7220///
7221/// @return the leaf underlying type.
7222const type_base_sptr
7223peel_qualified_type(const type_base_sptr& type)
7224{
7225 const qualified_type_def_sptr t = is_qualified_type(type);
7226 if (!t)
7227 return type;
7228
7229 return peel_qualified_type(t->get_underlying_type());
7230}
7231
7232/// Test if a given qualified type is const.
7233///
7234/// @pram t the qualified type to consider.
7235///
7236/// @return true iff @p t is a const qualified type.
7237bool
7238is_const_qualified_type(const qualified_type_def_sptr& t)
7239{
7240 if (!t)
7241 return false;
7242
7243 if (t->get_cv_quals() == qualified_type_def::CV_CONST)
7244 return true;
7245
7246 return false;
7247}
7248
7249/// Test if a given type is const-qualified.
7250///
7251/// @pram t the type to consider.
7252///
7253/// @return true iff @p t is a const qualified type.
7254bool
7255is_const_qualified_type(const type_base_sptr& t)
7256{
7257 qualified_type_def_sptr q = is_qualified_type(t);
7258 if (!q)
7259 return false;
7260 return is_const_qualified_type(q);
7261}
7262
7263/// If a qualified type is const, then return its underlying type.
7264///
7265/// @param q the qualified type to consider.
7266///
7267/// @return the underlying type of @p q if it's a const-qualified
7268/// type, otherwise, return @p q itself.
7269type_base_sptr
7270peel_const_qualified_type(const qualified_type_def_sptr& q)
7271{
7272 if (!q)
7273 return q;
7274
7276 return q->get_underlying_type();
7277
7278 return q;
7279}
7280
7281/// Return the leaf underlying type of a qualified or typedef type.
7282///
7283/// If the underlying type is itself a qualified or typedef type, then
7284/// recursively return the first underlying type of that qualified or
7285/// typedef type to return the first underlying type that is not a
7286/// qualified or typedef type.
7287///
7288/// If the underlying type is NOT a qualified nor a typedef type, then
7289/// just return that underlying type.
7290///
7291/// @param type the qualified or typedef type to consider.
7292///
7293/// @return the leaf underlying type.
7294type_base*
7296{
7297 while (is_typedef(type) || is_qualified_type(type))
7298 {
7299 if (const typedef_decl* t = is_typedef(type))
7300 type = peel_typedef_type(t);
7301
7302 if (const qualified_type_def* t = is_qualified_type(type))
7303 type = peel_qualified_type(t);
7304 }
7305
7306 return const_cast<type_base*>(type);
7307}
7308
7309/// Return the leaf underlying type of a qualified or typedef type.
7310///
7311/// If the underlying type is itself a qualified or typedef type, then
7312/// recursively return the first underlying type of that qualified or
7313/// typedef type to return the first underlying type that is not a
7314/// qualified or typedef type.
7315///
7316/// If the underlying type is NOT a qualified nor a typedef type, then
7317/// just return that underlying type.
7318///
7319/// @param type the qualified or typedef type to consider.
7320///
7321/// @return the leaf underlying type.
7322type_base_sptr
7323peel_qualified_or_typedef_type(const type_base_sptr &t)
7324{
7325 type_base_sptr type = t;
7326 while (is_typedef(type) || is_qualified_type(type))
7327 {
7328 if (typedef_decl_sptr t = is_typedef(type))
7329 type = peel_typedef_type(t);
7330
7331 if (qualified_type_def_sptr t = is_qualified_type(type))
7332 type = peel_qualified_type(t);
7333 }
7334
7335 return type;
7336}
7337
7338/// Return the leaf underlying or pointed-to type node of a @ref
7339/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7340/// or @ref array_type_def node.
7341///
7342/// @param type the type to peel.
7343///
7344/// @return the leaf underlying or pointed-to type node of @p type.
7345type_base_sptr
7347{
7348 type_base_sptr typ = type;
7349 while (is_typedef(typ)
7350 || is_pointer_type(typ)
7351 || is_reference_type(typ)
7352 || is_array_type(typ))
7353 {
7354 if (typedef_decl_sptr t = is_typedef(typ))
7355 typ = peel_typedef_type(t);
7356
7358 typ = peel_pointer_type(t);
7359
7361 typ = peel_reference_type(t);
7362
7363 if (const array_type_def_sptr t = is_array_type(typ))
7364 typ = peel_array_type(t);
7365 }
7366
7367 return typ;
7368}
7369
7370/// Return the leaf underlying or pointed-to type node of a @ref
7371/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7372/// node.
7373///
7374/// @param type the type to peel.
7375///
7376/// @return the leaf underlying or pointed-to type node of @p type.
7377type_base*
7379{
7380 while (is_typedef(type)
7381 || is_pointer_type(type)
7382 || is_reference_type(type)
7383 || is_array_type(type))
7384 {
7385 if (const typedef_decl* t = is_typedef(type))
7386 type = peel_typedef_type(t);
7387
7388 if (const pointer_type_def* t = is_pointer_type(type))
7389 type = peel_pointer_type(t);
7390
7391 if (const reference_type_def* t = is_reference_type(type))
7392 type = peel_reference_type(t);
7393
7394 if (const array_type_def* t = is_array_type(type))
7395 type = peel_array_type(t);
7396 }
7397
7398 return const_cast<type_base*>(type);
7399}
7400
7401/// Return the leaf underlying or pointed-to type node of a @ref
7402/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7403/// 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*
7410 bool peel_qual_type)
7411{
7412 while (is_typedef(type)
7413 || is_pointer_type(type)
7414 || is_reference_type(type)
7415 || is_array_type(type)
7416 || (peel_qual_type && is_qualified_type(type)))
7417 {
7418 if (const typedef_decl* t = is_typedef(type))
7419 type = peel_typedef_type(t);
7420
7421 if (const pointer_type_def* t = is_pointer_type(type))
7422 type = peel_pointer_type(t);
7423
7424 if (const reference_type_def* t = is_reference_type(type))
7425 type = peel_reference_type(t);
7426
7427 if (const array_type_def* t = is_array_type(type))
7428 type = peel_array_type(t);
7429
7430 if (peel_qual_type)
7431 if (const qualified_type_def* t = is_qualified_type(type))
7432 type = peel_qualified_type(t);
7433 }
7434
7435 return const_cast<type_base*>(type);
7436}
7437
7438/// Return the leaf underlying or pointed-to type node of a, @ref
7439/// pointer_type_def, @ref reference_type_def or @ref
7440/// qualified_type_def type node.
7441///
7442/// @param type the type to peel.
7443///
7444/// @param peel_qualified_type if true, also peel qualified types.
7445///
7446/// @return the leaf underlying or pointed-to type node of @p type.
7447type_base*
7449 bool peel_qual_type)
7450{
7451 while (is_pointer_type(type)
7452 || is_reference_type(type)
7453 || is_array_type(type)
7454 || (peel_qual_type && is_qualified_type(type)))
7455 {
7456 if (const pointer_type_def* t = is_pointer_type(type))
7457 type = peel_pointer_type(t);
7458
7459 if (const reference_type_def* t = is_reference_type(type))
7460 type = peel_reference_type(t);
7461
7462 if (const array_type_def* t = is_array_type(type))
7463 type = peel_array_type(t);
7464
7465 if (peel_qual_type)
7466 if (const qualified_type_def* t = is_qualified_type(type))
7467 type = peel_qualified_type(t);
7468 }
7469
7470 return const_cast<type_base*>(type);
7471}
7472
7473/// Clone an array type.
7474///
7475/// Note that the element type of the new array is shared witht the
7476/// old one.
7477///
7478/// @param array the array type to clone.
7479///
7480/// @return a newly built array type. Note that it needs to be added
7481/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7482/// bound to the one of that scope. Otherwise, its lifetime is bound
7483/// to the lifetime of its containing shared pointer.
7486{
7487 vector<array_type_def::subrange_sptr> subranges;
7488
7489 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7490 array->get_subranges().begin();
7491 i != array->get_subranges().end();
7492 ++i)
7493 {
7495 (new array_type_def::subrange_type(array->get_environment(),
7496 (*i)->get_name(),
7497 (*i)->get_lower_bound(),
7498 (*i)->get_upper_bound(),
7499 (*i)->get_underlying_type(),
7500 (*i)->get_location(),
7501 (*i)->get_language()));
7502 subrange->is_non_finite((*i)->is_non_finite());
7503 if (scope_decl *scope = (*i)->get_scope())
7504 add_decl_to_scope(subrange, scope);
7505 subranges.push_back(subrange);
7506 }
7507
7508 array_type_def_sptr result
7509 (new array_type_def(array->get_element_type(),
7510 subranges, array->get_location()));
7511
7512 return result;
7513}
7514
7515/// Clone a typedef type.
7516///
7517/// Note that the underlying type of the newly constructed typedef is
7518/// shared with the old one.
7519///
7520/// @param t the typedef to clone.
7521///
7522/// @return the newly constructed typedef. Note that it needs to be
7523/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7524/// to be bound to the one of that scope. Otherwise, its lifetime is
7525/// bound to the lifetime of its containing shared pointer.
7528{
7529 if (!t)
7530 return t;
7531
7532 typedef_decl_sptr result
7533 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7534 t->get_location(), t->get_linkage_name(),
7535 t->get_visibility()));
7536 return result;
7537}
7538
7539/// Clone a qualifiend type.
7540///
7541/// Note that underlying type of the newly constructed qualified type
7542/// is shared with the old one.
7543///
7544/// @param t the qualified type to clone.
7545///
7546/// @return the newly constructed qualified type. Note that it needs
7547/// to be added to a scope (e.g, using add_decl_to_scope) for its
7548/// lifetime to be bound to the one of that scope. Otherwise, its
7549/// lifetime is bound to the lifetime of its containing shared
7550/// pointer.
7551qualified_type_def_sptr
7552clone_qualified_type(const qualified_type_def_sptr& t)
7553{
7554 if (!t)
7555 return t;
7556
7557 qualified_type_def_sptr result
7558 (new qualified_type_def(t->get_underlying_type(),
7559 t->get_cv_quals(), t->get_location()));
7560
7561 return result;
7562}
7563
7564/// Clone a typedef, an array or a qualified tree.
7565///
7566/// @param type the typedef, array or qualified tree to clone. any
7567/// order.
7568///
7569/// @return the cloned type, or NULL if @type was neither a typedef,
7570/// array nor a qualified type.
7571static type_base_sptr
7572clone_typedef_array_qualified_type(type_base_sptr type)
7573{
7574 if (!type)
7575 return type;
7576
7577 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7578 type_base_sptr result;
7579
7580 if (typedef_decl_sptr t = is_typedef(type))
7581 result = clone_typedef(is_typedef(t));
7582 else if (qualified_type_def_sptr t = is_qualified_type(type))
7583 result = clone_qualified_type(t);
7584 else if (array_type_def_sptr t = is_array_type(type))
7585 result = clone_array(t);
7586 else
7587 return type_base_sptr();
7588
7589 if (scope)
7590 add_decl_to_scope(is_decl(result), scope);
7591
7592 return result;
7593}
7594
7595/// Clone a type tree made of an array or a typedef of array.
7596///
7597/// Note that this can be a tree which root node is a typedef an which
7598/// sub-tree can be any arbitrary combination of typedef, qualified
7599/// type and arrays.
7600///
7601/// @param t the array or typedef of qualified array to consider.
7602///
7603/// @return a clone of @p t.
7604type_base_sptr
7605clone_array_tree(const type_base_sptr t)
7606{
7608
7609 scope_decl* scope = is_decl(t)->get_scope();
7610 type_base_sptr result = clone_typedef_array_qualified_type(t);
7611 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7612
7613 type_base_sptr subtree;
7614 if (typedef_decl_sptr type = is_typedef(result))
7615 {
7616 type_base_sptr s =
7617 clone_typedef_array_qualified_type(type->get_underlying_type());
7618 if (s)
7619 {
7620 subtree = s;
7621 type->set_underlying_type(subtree);
7622 }
7623 }
7624 else if (array_type_def_sptr type = is_array_type(result))
7625 {
7626 type_base_sptr s =
7627 clone_typedef_array_qualified_type(type->get_element_type());
7628 if (s)
7629 {
7630 subtree = s;
7631 type->set_element_type(subtree);
7632 }
7633 }
7634 add_decl_to_scope(is_decl(subtree), scope);
7635
7636 for (;;)
7637 {
7638 if (typedef_decl_sptr t = is_typedef(subtree))
7639 {
7640 type_base_sptr s =
7641 clone_typedef_array_qualified_type(t->get_underlying_type());
7642 if (s)
7643 {
7644 scope_decl* scope =
7645 is_decl(t->get_underlying_type())->get_scope();
7646 ABG_ASSERT(scope);
7647 add_decl_to_scope(is_decl(s), scope);
7648 t->set_underlying_type (s);
7649 subtree = s;
7650 }
7651 else
7652 break;
7653 }
7654 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7655 {
7656 type_base_sptr s =
7657 clone_typedef_array_qualified_type(t->get_underlying_type());
7658 if (s)
7659 {
7660 scope_decl* scope =
7661 is_decl(t->get_underlying_type())->get_scope();
7662 ABG_ASSERT(scope);
7663 add_decl_to_scope(is_decl(s), scope);
7664 t->set_underlying_type(s);
7665 subtree = s;
7666 }
7667 else
7668 break;
7669 }
7670 else if (array_type_def_sptr t = is_array_type(subtree))
7671 {
7672 type_base_sptr e = t->get_element_type();
7673 if (is_typedef(e) || is_qualified_type(e))
7674 {
7675 type_base_sptr s =
7676 clone_typedef_array_qualified_type(e);
7677 if (s)
7678 {
7679 scope_decl* scope = is_decl(e)->get_scope();
7680 ABG_ASSERT(scope);
7681 add_decl_to_scope(is_decl(s), scope);
7682 t->set_element_type(s);
7683 }
7684 else
7685 break;
7686 }
7687 break;
7688 }
7689 else
7690 break;
7691 }
7692 return result;
7693}
7694
7695/// Update the qualified name of a given sub-tree.
7696///
7697/// @param d the sub-tree for which to update the qualified name.
7698static void
7699update_qualified_name(decl_base * d)
7700{
7701 ::qualified_name_setter setter;
7702 d->traverse(setter);
7703}
7704
7705/// Update the qualified name of a given sub-tree.
7706///
7707/// @param d the sub-tree for which to update the qualified name.
7708static void
7709update_qualified_name(decl_base_sptr d)
7710{return update_qualified_name(d.get());}
7711
7712// <scope_decl stuff>
7713
7714/// Hash a type by returning the pointer value of its canonical type.
7715///
7716/// @param l the type to hash.
7717///
7718/// @return the the pointer value of the canonical type of @p l.
7719size_t
7720canonical_type_hash::operator()(const type_base_sptr& l) const
7721{return operator()(l.get());}
7722
7723/// Hash a (canonical) type by returning its pointer value
7724///
7725/// @param l the canonical type to hash.
7726///
7727/// @return the pointer value of the canonical type of @p l.
7728size_t
7730{return reinterpret_cast<size_t>(l);}
7731
7732struct scope_decl::priv
7733{
7734 declarations members_;
7735 declarations sorted_members_;
7736 type_base_sptrs_type member_types_;
7737 type_base_sptrs_type sorted_member_types_;
7738 scopes member_scopes_;
7739 canonical_type_sptr_set_type canonical_types_;
7740 type_base_sptrs_type sorted_canonical_types_;
7741}; // end struct scope_decl::priv
7742
7743/// Constructor of the @ref scope_decl type.
7744///
7745/// @param the environment to use for the new instance.
7746///
7747/// @param the name of the scope decl.
7748///
7749/// @param locus the source location where the scope_decl is defined.
7750///
7751/// @param vis the visibility of the declaration.
7752scope_decl::scope_decl(const environment& env,
7753 const string& name,
7754 const location& locus,
7755 visibility vis)
7756 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7757 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7758 priv_(new priv)
7759{}
7760
7761/// Constructor of the @ref scope_decl type.
7762///
7763/// @param the environment to use for the new instance.
7764///
7765/// @param l the source location where the scope_decl is defined.
7766///
7767/// @param vis the visibility of the declaration.
7768scope_decl::scope_decl(const environment& env, location& l)
7769 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7770 decl_base(env, "", l),
7771 priv_(new priv)
7772{}
7773
7774/// @eturn the set of canonical types of the the current scope.
7777{return priv_->canonical_types_;}
7778
7779/// @eturn the set of canonical types of the the current scope.
7782{return const_cast<scope_decl*>(this)->get_canonical_types();}
7783
7784/// Return a vector of sorted canonical types of the current scope.
7785///
7786/// The types are sorted "almost topologically". That means, they are
7787/// sorted using the lexicographic order of the string representing
7788/// the location their definition point. If a type doesn't have a
7789/// location, then its pretty representation is used.
7790///
7791/// @return a vector of sorted canonical types of the current scope.
7794{
7795 if (priv_->sorted_canonical_types_.empty())
7796 {
7797 for (canonical_type_sptr_set_type::const_iterator e =
7798 get_canonical_types().begin();
7799 e != get_canonical_types().end();
7800 ++e)
7801 priv_->sorted_canonical_types_.push_back(*e);
7802
7803 type_topo_comp comp;
7804 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7805 priv_->sorted_canonical_types_.end(),
7806 comp);
7807 }
7808 return priv_->sorted_canonical_types_;
7809}
7810
7811/// Getter for the member declarations carried by the current @ref
7812/// scope_decl.
7813///
7814/// @return the member declarations carried by the current @ref
7815/// scope_decl.
7818{return priv_->members_;}
7819
7820/// Getter for the member declarations carried by the current @ref
7821/// scope_decl.
7822///
7823/// @return the member declarations carried by the current @ref
7824/// scope_decl.
7827{return priv_->members_;}
7828
7829/// Getter for the sorted member declarations carried by the current
7830/// @ref scope_decl.
7831///
7832/// @return the sorted member declarations carried by the current @ref
7833/// scope_decl. The declarations are sorted topologically.
7836{
7837 decl_topo_comp comp;
7838 if (priv_->sorted_members_.empty())
7839 {
7840 for (declarations::const_iterator i = get_member_decls().begin();
7841 i != get_member_decls().end();
7842 ++i)
7843 priv_->sorted_members_.push_back(*i);
7844
7845 std::stable_sort(priv_->sorted_members_.begin(),
7846 priv_->sorted_members_.end(),
7847 comp);
7848 }
7849 return priv_->sorted_members_;
7850}
7851
7852/// Getter for the number of anonymous classes contained in this
7853/// scope.
7854///
7855/// @return the number of anonymous classes contained in this scope.
7856size_t
7858{
7859 int result = 0;
7860 for (declarations::const_iterator it = get_member_decls().begin();
7861 it != get_member_decls().end();
7862 ++it)
7863 if (class_decl_sptr t = is_class_type(*it))
7864 if (t->get_is_anonymous())
7865 ++result;
7866
7867 return result;
7868}
7869
7870/// Getter for the number of anonymous unions contained in this
7871/// scope.
7872///
7873/// @return the number of anonymous unions contained in this scope.
7874size_t
7876{
7877 int result = 0;
7878 for (declarations::const_iterator it = get_member_decls().begin();
7879 it != get_member_decls().end();
7880 ++it)
7881 if (union_decl_sptr t = is_union_type(*it))
7882 if (t->get_is_anonymous())
7883 ++result;
7884
7885 return result;
7886}
7887
7888/// Getter for the number of anonymous enums contained in this
7889/// scope.
7890///
7891/// @return the number of anonymous enums contained in this scope.
7892size_t
7894{
7895 int result = 0;
7896 for (declarations::const_iterator it = get_member_decls().begin();
7897 it != get_member_decls().end();
7898 ++it)
7899 if (enum_type_decl_sptr t = is_enum_type(*it))
7900 if (t->get_is_anonymous())
7901 ++result;
7902
7903 return result;
7904}
7905
7906/// Getter for the scopes carried by the current scope.
7907///
7908/// @return the scopes carried by the current scope.
7911{return priv_->member_scopes_;}
7912
7913/// Getter for the scopes carried by the current scope.
7914///
7915/// @return the scopes carried by the current scope.
7916const scope_decl::scopes&
7918{return priv_->member_scopes_;}
7919
7920/// Test if the current scope is empty.
7921///
7922/// @return true iff the current scope is empty.
7923bool
7925{
7926 return (get_member_decls().empty()
7927 && get_canonical_types().empty());
7928}
7929
7930/// Set the translation unit of a decl
7931///
7932/// It also perform some IR integrity checks.
7933///
7934/// This is a sub-routine of scope_decl::{insert,add}_member_decl.
7935///
7936/// @param decl the decl to set the translation unit for.
7937///
7938/// @param tu the translation unit to set.
7939static void
7940maybe_set_translation_unit(const decl_base_sptr& decl,
7941 translation_unit* tu)
7942{
7943 if (translation_unit* existing_tu = decl->get_translation_unit())
7944 // The decl already belongs to a translation unit.
7945 // Either:
7946 //
7947 // 1/ it's a unique type, in which case we should not add it to
7948 // any translation unique since unique types are "logically"
7949 // supposed to belong to no translation unit in particular, as
7950 // they are unique.
7951 //
7952 // 2/ or the decl was already added to this translation unit.
7953 ABG_ASSERT(tu == existing_tu || is_unique_type(is_type(decl)));
7954 else
7955 decl->set_translation_unit(tu);
7956}
7957
7958/// Add a member decl to this scope. Note that user code should not
7959/// use this, but rather use add_decl_to_scope.
7960///
7961/// Note that this function updates the qualified name of the member
7962/// decl that is added. It also sets the scope of the member. Thus,
7963/// it ABG_ASSERTs that member should not have its scope set, prior to
7964/// calling this function.
7965///
7966/// @param member the new member decl to add to this scope.
7967decl_base_sptr
7968scope_decl::add_member_decl(const decl_base_sptr& member)
7969{
7970 ABG_ASSERT(!has_scope(member));
7971
7972 member->set_scope(this);
7973 priv_->members_.push_back(member);
7974 if (is_type(member))
7975 priv_->member_types_.push_back(is_type(member));
7976
7977 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
7978 priv_->member_scopes_.push_back(m);
7979
7980 update_qualified_name(member);
7981
7983 maybe_set_translation_unit(member, tu);
7984
7986
7987 return member;
7988}
7989
7990/// Get the member types of this @ref scope_decl.
7991///
7992/// @return a vector of the member types of this ref class_or_union.
7995{return priv_->member_types_;}
7996
7997/// Find a member type of a given name, inside the current @ref
7998/// scope_decl.
7999///
8000/// @param name the name of the member type to look for.
8001///
8002/// @return a pointer to the @ref type_base that represents the member
8003/// type of name @p name, for the current scope.
8004type_base_sptr
8005scope_decl::find_member_type(const string& name) const
8006{
8007 for (auto t : get_member_types())
8008 if (get_type_name(t, /*qualified*/false) == name)
8009 return t;
8010 return type_base_sptr();
8011}
8012
8013/// Insert a member type.
8014///
8015/// @param t the type to insert in the @ref scope_decl type.
8016///
8017/// @param an iterator right before which @p t has to be inserted.
8018void
8020 declarations::iterator before)
8021{
8022 decl_base_sptr d = get_type_declaration(t);
8023 ABG_ASSERT(d);
8024 ABG_ASSERT(!has_scope(d));
8025
8026 priv_->member_types_.push_back(t);
8027 insert_member_decl(d, before);
8028}
8029
8030/// Add a member type to the current instance of class_or_union.
8031///
8032/// @param t the member type to add. It must not have been added to a
8033/// scope, otherwise this will violate an ABG_ASSERTion.
8034void
8037
8038/// Add a member type to the current instance of class_or_union.
8039///
8040/// @param t the type to be added as a member type to the current
8041/// instance of class_or_union. An instance of class_or_union::member_type
8042/// will be created out of @p t and and added to the the class.
8043///
8044/// @param a the access specifier for the member type to be created.
8045type_base_sptr
8047{
8048 decl_base_sptr d = get_type_declaration(t);
8049 ABG_ASSERT(d);
8051 add_member_type(t);
8053 return t;
8054}
8055
8056/// Remove a member type from the current @ref class_or_union scope.
8057///
8058/// @param t the type to remove.
8059void
8061{
8062 for (auto i = priv_->member_types_.begin();
8063 i != priv_->member_types_.end();
8064 ++i)
8065 {
8066 if (*((*i)) == *t)
8067 {
8068 priv_->member_types_.erase(i);
8069 return;
8070 }
8071 }
8072}
8073
8074/// Get the sorted member types of this @ref scope_decl
8075///
8076/// @return a vector of the sorted member types of this ref
8077/// class_or_union.
8080{
8081 if (priv_->sorted_member_types_.empty())
8082 {
8083 for (auto t : get_member_types())
8084 priv_->sorted_member_types_.push_back(t);
8085
8086 type_topo_comp comp;
8087 std::stable_sort(priv_->sorted_member_types_.begin(),
8088 priv_->sorted_member_types_.end(),
8089 comp);
8090 }
8091 return priv_->sorted_member_types_;
8092}
8093
8094/// Insert a member decl to this scope, right before an element
8095/// pointed to by a given iterator. Note that user code should not
8096/// use this, but rather use insert_decl_into_scope.
8097///
8098/// Note that this function updates the qualified name of the inserted
8099/// member.
8100///
8101/// @param member the new member decl to add to this scope.
8102///
8103/// @param before an interator pointing to the element before which
8104/// the new member should be inserted.
8105decl_base_sptr
8107 declarations::iterator before)
8108{
8109 ABG_ASSERT(!member->get_scope());
8110
8111 member->set_scope(this);
8112 priv_->members_.insert(before, member);
8113
8114 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8115 priv_-> member_scopes_.push_back(m);
8116
8117 update_qualified_name(member);
8118
8120 maybe_set_translation_unit(member, tu);
8121
8123
8124 return member;
8125}
8126
8127/// Remove a declaration from the current scope.
8128///
8129/// @param member the declaration to remove from the scope.
8130void
8132{
8133 for (declarations::iterator i = priv_->members_.begin();
8134 i != priv_->members_.end();
8135 ++i)
8136 {
8137 if (**i == *member)
8138 {
8139 priv_->members_.erase(i);
8140 // Do not access i after this point as it's invalided by the
8141 // erase call.
8142 break;
8143 }
8144 }
8145
8146 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8147 if (scope)
8148 {
8149 for (scopes::iterator i = priv_->member_scopes_.begin();
8150 i != priv_->member_scopes_.end();
8151 ++i)
8152 {
8153 if (**i == *member)
8154 {
8155 priv_->member_scopes_.erase(i);
8156 break;
8157 }
8158 }
8159 }
8160
8161 member->set_scope(nullptr);
8162 member->set_translation_unit(nullptr);
8163}
8164
8165/// Return the hash value for the current instance of scope_decl.
8166///
8167/// This method can trigger the computing of the hash value, if need be.
8168///
8169/// @return the hash value.
8170size_t
8172{
8173 scope_decl::hash hash_scope;
8174 return hash_scope(this);
8175}
8176
8177/// Compares two instances of @ref scope_decl.
8178///
8179/// If the two intances are different, set a bitfield to give some
8180/// insight about the kind of differences there are.
8181///
8182/// @param l the first artifact of the comparison.
8183///
8184/// @param r the second artifact of the comparison.
8185///
8186/// @param k a pointer to a bitfield that gives information about the
8187/// kind of changes there are between @p l and @p r. This one is set
8188/// iff @p k is non-null and the function returns false.
8189///
8190/// Please note that setting k to a non-null value does have a
8191/// negative performance impact because even if @p l and @p r are not
8192/// equal, the function keeps up the comparison in order to determine
8193/// the different kinds of ways in which they are different.
8194///
8195/// @return true if @p l equals @p r, false otherwise.
8196bool
8198{
8199 bool result = true;
8200
8201 if (!l.decl_base::operator==(r))
8202 {
8203 result = false;
8204 if (k)
8206 else
8208 }
8209
8210 scope_decl::declarations::const_iterator i, j;
8211 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8212 i != l.get_member_decls().end() && j != r.get_member_decls().end();
8213 ++i, ++j)
8214 {
8215 if (**i != **j)
8216 {
8217 result = false;
8218 if (k)
8219 {
8220 *k |= SUBTYPE_CHANGE_KIND;
8221 break;
8222 }
8223 else
8225 }
8226 }
8227
8228 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8229 {
8230 result = false;
8231 if (k)
8233 else
8235 }
8236
8237 ABG_RETURN(result);
8238}
8239
8240/// Return true iff both scopes have the same names and have the same
8241/// member decls.
8242///
8243/// This function doesn't check for equality of the scopes of its
8244/// arguments.
8245bool
8247{
8248 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8249 if (!other)
8250 return false;
8251
8252 return equals(*this, *other, 0);
8253}
8254
8255/// Equality operator for @ref scope_decl_sptr.
8256///
8257/// @param l the left hand side operand of the equality operator.
8258///
8259/// @pram r the right hand side operand of the equalify operator.
8260///
8261/// @return true iff @p l equals @p r.
8262bool
8264{
8265 if (!!l != !!r)
8266 return false;
8267 if (l.get() == r.get())
8268 return true;
8269 return *l == *r;
8270}
8271
8272/// Inequality operator for @ref scope_decl_sptr.
8273///
8274/// @param l the left hand side operand of the equality operator.
8275///
8276/// @pram r the right hand side operand of the equalify operator.
8277///
8278/// @return true iff @p l equals @p r.
8279bool
8281{return !operator==(l, r);}
8282
8283/// Find a member of the current scope and return an iterator on it.
8284///
8285/// @param decl the scope member to find.
8286///
8287/// @param i the iterator to set to the member @p decl. This is set
8288/// iff the function returns true.
8289///
8290/// @return true if the member decl was found, false otherwise.
8291bool
8293 declarations::iterator& i)
8294{
8295 if (!decl)
8296 return false;
8297
8298 if (get_member_decls().empty())
8299 {
8300 i = get_member_decls().end();
8301 return false;
8302 }
8303
8304 for (declarations::iterator it = get_member_decls().begin();
8305 it != get_member_decls().end();
8306 ++it)
8307 {
8308 if ((*it).get() == decl)
8309 {
8310 i = it;
8311 return true;
8312 }
8313 }
8314
8315 return false;
8316}
8317
8318/// Find a member of the current scope and return an iterator on it.
8319///
8320/// @param decl the scope member to find.
8321///
8322/// @param i the iterator to set to the member @p decl. This is set
8323/// iff the function returns true.
8324///
8325/// @return true if the member decl was found, false otherwise.
8326bool
8328 declarations::iterator& i)
8329{return find_iterator_for_member(decl.get(), i);}
8330
8331/// This implements the ir_traversable_base::traverse pure virtual
8332/// function.
8333///
8334/// @param v the visitor used on the current instance of scope_decl
8335/// and on its member nodes.
8336///
8337/// @return true if the traversal of the tree should continue, false
8338/// otherwise.
8339bool
8341{
8342 if (visiting())
8343 return true;
8344
8345 if (v.visit_begin(this))
8346 {
8347 visiting(true);
8348 for (scope_decl::declarations::const_iterator i =
8349 get_member_decls().begin();
8350 i != get_member_decls ().end();
8351 ++i)
8352 if (!(*i)->traverse(v))
8353 break;
8354 visiting(false);
8355 }
8356 return v.visit_end(this);
8357}
8358
8359scope_decl::~scope_decl()
8360{}
8361
8362/// Appends a declaration to a given scope, if the declaration
8363/// doesn't already belong to one and if the declaration is not for a
8364/// type that is supposed to be unique.
8365///
8366/// @param decl the declaration to add to the scope
8367///
8368/// @param scope the scope to append the declaration to
8369decl_base_sptr
8370add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8371{
8372 ABG_ASSERT(scope);
8373
8374 if (scope && decl && !decl->get_scope())
8375 decl = scope->add_member_decl(decl);
8376
8377 return decl;
8378}
8379
8380/// Appends a declaration to a given scope, if the declaration doesn't
8381/// already belong to a scope.
8382///
8383/// @param decl the declaration to add append to the scope
8384///
8385/// @param scope the scope to append the decl to
8386decl_base_sptr
8387add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8388{return add_decl_to_scope(decl, scope.get());}
8389
8390/// Remove a given decl from its scope
8391///
8392/// @param decl the decl to remove from its scope.
8393void
8394remove_decl_from_scope(decl_base_sptr decl)
8395{
8396 if (!decl)
8397 return;
8398
8399 scope_decl* scope = decl->get_scope();
8400 scope->remove_member_decl(decl);
8401}
8402
8403/// Inserts a declaration into a given scope, before a given IR child
8404/// node of the scope.
8405///
8406/// @param decl the declaration to insert into the scope.
8407///
8408/// @param before an iterator pointing to the child IR node before
8409/// which to insert the declaration.
8410///
8411/// @param scope the scope into which to insert the declaration.
8412decl_base_sptr
8413insert_decl_into_scope(decl_base_sptr decl,
8414 scope_decl::declarations::iterator before,
8415 scope_decl* scope)
8416{
8417 if (scope && decl && !decl->get_scope())
8418 {
8419 decl_base_sptr d = scope->insert_member_decl(decl, before);
8420 decl = d;
8421 }
8422 return decl;
8423}
8424
8425/// Inserts a declaration into a given scope, before a given IR child
8426/// node of the scope.
8427///
8428/// @param decl the declaration to insert into the scope.
8429///
8430/// @param before an iterator pointing to the child IR node before
8431/// which to insert the declaration.
8432///
8433/// @param scope the scope into which to insert the declaration.
8434decl_base_sptr
8435insert_decl_into_scope(decl_base_sptr decl,
8436 scope_decl::declarations::iterator before,
8437 scope_decl_sptr scope)
8438{return insert_decl_into_scope(decl, before, scope.get());}
8439
8440/// Constructor of the @ref global_scope type.
8441///
8442/// @param tu the translation unit the scope belongs to.
8443global_scope::global_scope(translation_unit *tu)
8444 : type_or_decl_base(tu->get_environment(),
8445 GLOBAL_SCOPE_DECL
8446 | ABSTRACT_DECL_BASE
8447 | ABSTRACT_SCOPE_DECL),
8448 decl_base(tu->get_environment(), "", location()),
8449 scope_decl(tu->get_environment(), "", location()),
8450 translation_unit_(tu)
8451{
8452 runtime_type_instance(this);
8453}
8454
8455/// return the global scope as seen by a given declaration.
8456///
8457/// @param decl the declaration to consider.
8458///
8459/// @return the global scope of the decl, or a null pointer if the
8460/// decl is not yet added to a translation_unit.
8461const global_scope*
8463{
8464 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8465 return s;
8466
8467 scope_decl* scope = decl.get_scope();
8468 while (scope && !dynamic_cast<global_scope*>(scope))
8469 scope = scope->get_scope();
8470
8471 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8472}
8473
8474/// return the global scope as seen by a given declaration.
8475///
8476/// @param decl the declaration to consider.
8477///
8478/// @return the global scope of the decl, or a null pointer if the
8479/// decl is not yet added to a translation_unit.
8480const global_scope*
8482{return get_global_scope(*decl);}
8483
8484/// Return the global scope as seen by a given declaration.
8485///
8486/// @param decl the declaration to consider.
8487///
8488/// @return the global scope of the decl, or a null pointer if the
8489/// decl is not yet added to a translation_unit.
8490const global_scope*
8491get_global_scope(const shared_ptr<decl_base> decl)
8492{return get_global_scope(decl.get());}
8493
8494/// Return the a scope S containing a given declaration and that is
8495/// right under a given scope P.
8496///
8497/// Note that @p scope must come before @p decl in topological
8498/// order.
8499///
8500/// @param decl the decl for which to find a scope.
8501///
8502/// @param scope the scope under which the resulting scope must be.
8503///
8504/// @return the resulting scope.
8505const scope_decl*
8507 const scope_decl* scope)
8508{
8509 if (!decl)
8510 return 0;
8511
8512 if (scope == 0)
8513 return get_global_scope(decl);
8514
8515 // Handle the case where decl is a scope itself.
8516 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8517 if (!s)
8518 s = decl->get_scope();
8519
8520 if (is_global_scope(s))
8521 return scope;
8522
8523 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8524 // same. The caller needs to be prepared to deal with this case.
8525 if (s == scope)
8526 return s;
8527
8528 while (s && !is_global_scope(s) && s->get_scope() != scope)
8529 s = s->get_scope();
8530
8531 if (!s || is_global_scope(s))
8532 // SCOPE must come before decl in topological order, but I don't
8533 // know how to ensure that ...
8534 return scope;
8535 ABG_ASSERT(s);
8536
8537 return s;
8538}
8539
8540/// Return the a scope S containing a given declaration and that is
8541/// right under a given scope P.
8542///
8543/// @param decl the decl for which to find a scope.
8544///
8545/// @param scope the scope under which the resulting scope must be.
8546///
8547/// @return the resulting scope.
8548const scope_decl*
8549get_top_most_scope_under(const decl_base_sptr decl,
8550 const scope_decl* scope)
8551{return get_top_most_scope_under(decl.get(), scope);}
8552
8553/// Return the a scope S containing a given declaration and that is
8554/// right under a given scope P.
8555///
8556/// @param decl the decl for which to find a scope.
8557///
8558/// @param scope the scope under which the resulting scope must be.
8559///
8560/// @return the resulting scope.
8561const scope_decl*
8562get_top_most_scope_under(const decl_base_sptr decl,
8563 const scope_decl_sptr scope)
8564{return get_top_most_scope_under(decl, scope.get());}
8565
8566// </scope_decl stuff>
8567
8568
8569/// Get the string representation of a CV qualifier bitmap.
8570///
8571/// @param cv_quals the bitmap of CV qualifiers to consider.
8572///
8573/// @return the string representation.
8574string
8576{
8577 string repr;
8578 if (cv_quals & qualified_type_def::CV_RESTRICT)
8579 repr = "restrict";
8580 if (cv_quals & qualified_type_def::CV_CONST)
8581 {
8582 if (!repr.empty())
8583 repr += ' ';
8584 repr += "const";
8585 }
8586 if (cv_quals & qualified_type_def::CV_VOLATILE)
8587 {
8588 if (!repr.empty())
8589 repr += ' ';
8590 repr += "volatile";
8591 }
8592 return repr;
8593}
8594
8595/// Build and return a copy of the name of an ABI artifact that is
8596/// either a type or a decl.
8597///
8598/// @param tod the ABI artifact to get the name for.
8599///
8600/// @param qualified if yes, return the qualified name of @p tod;
8601/// otherwise, return the non-qualified name;
8602///
8603/// @return the name of @p tod.
8604string
8605get_name(const type_or_decl_base *tod, bool qualified)
8606{
8607 string result;
8608
8609 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8610
8611 if (type_base* t = dynamic_cast<type_base*>(a))
8612 result = get_type_name(t, qualified);
8613 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8614 {
8615 if (qualified)
8616 result = d->get_qualified_name();
8617 else
8618 result = d->get_name();
8619 }
8620 else
8621 // We should never reach this point.
8622 abort();
8623
8624 return result;
8625}
8626
8627/// Build and return a copy of the name of an ABI artifact that is
8628/// either a type of a decl.
8629///
8630/// @param tod the ABI artifact to get the name for.
8631///
8632/// @param qualified if yes, return the qualified name of @p tod;
8633/// otherwise, return the non-qualified name;
8634///
8635/// @return the name of @p tod.
8636string
8637get_name(const type_or_decl_base_sptr& tod, bool qualified)
8638{return get_name(tod.get(), qualified);}
8639
8640/// Build and return a qualified name from a name and its scope.
8641///
8642/// The name is supposed to be for an entity that is part of the
8643/// scope.
8644///
8645/// @param the scope to consider.
8646///
8647/// @param name of the name to consider.
8648///
8649/// @return a copy of the string that represents the qualified name.
8650string
8651build_qualified_name(const scope_decl* scope, const string& name)
8652{
8653 if (name.empty())
8654 return "";
8655
8656 string qualified_name;
8657 if (scope)
8658 qualified_name = scope->get_qualified_name();
8659
8660 if (qualified_name.empty())
8661 qualified_name = name;
8662 else
8663 qualified_name = qualified_name + "::" + name;
8664
8665 return qualified_name;
8666}
8667
8668/// Build and return the qualified name of a type in its scope.
8669///
8670/// @param scope the scope of the type to consider.
8671///
8672/// @param type the type to consider.
8673string
8674build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8675{return build_qualified_name(scope, get_name((type)));}
8676
8677// </scope_decl stuff>
8678
8679/// Get the location of the declaration of a given type.
8680///
8681/// @param type the type to consider.
8682///
8683/// @return the location of the declaration of type @p type.
8685get_location(const type_base_sptr& type)
8686{
8687 if (decl_base_sptr decl = get_type_declaration(type))
8688 return get_location(decl);
8689 return location();
8690}
8691
8692/// Get the location of a given declaration.
8693///
8694/// @param decl the declaration to consider.
8695///
8696/// @return the location of the declaration @p decl.
8698get_location(const decl_base_sptr& decl)
8699{
8700 location loc = decl->get_location();
8701 if (!loc)
8702 {
8703 if (class_or_union_sptr c = is_class_or_union_type(decl))
8704 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8705 {
8706 c = is_class_or_union_type(c->get_definition_of_declaration());
8707 loc = c->get_location();
8708 }
8709 }
8710 return loc;
8711}
8712
8713/// Get the scope of a given type.
8714///
8715/// @param t the type to consider.
8716///
8717/// @return the scope of type @p t or 0 if the type has no scope yet.
8720{
8721 if (!t)
8722 return 0;
8723
8725 if (d)
8726 return d->get_scope();
8727 return 0;
8728}
8729
8730/// Get the scope of a given type.
8731///
8732/// @param t the type to consider.
8733///
8734/// @return the scope of type @p t or 0 if the type has no scope yet.
8736get_type_scope(const type_base_sptr& t)
8737{return get_type_scope(t.get());}
8738
8739/// Get the name of a given type and return a copy of it.
8740///
8741/// @param t the type to consider.
8742///
8743/// @param qualified if true then return the qualified name of the
8744/// type.
8745///
8746/// @param internal set to true if the call is intended for an
8747/// internal use (for technical use inside the library itself), false
8748/// otherwise. If you don't know what this is for, then set it to
8749/// false.
8750///
8751/// @return a copy of the type name if the type has a name, or the
8752/// empty string if it does not.
8754get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8755{return get_type_name(t.get(), qualified, internal);}
8756
8757/// Return true iff a decl is for a type type that has a generic
8758/// anonymous internal type name.
8759///
8760/// @param d the decl to considier.
8761///
8762/// @return true iff @p d is for a type type that has a generic
8763/// anonymous internal type name.
8764static bool
8765has_generic_anonymous_internal_type_name(const decl_base *d)
8766{
8767 return (is_class_or_union_type(d)
8768 || is_enum_type(d)
8769 || is_subrange_type(d));
8770}
8771
8772/// Return the generic internal name of an anonymous type.
8773///
8774/// For internal purposes, we want to define a generic name for all
8775/// anonymous types of a certain kind. For instance, all anonymous
8776/// structs will be have a generic name of "__anonymous_struct__", all
8777/// anonymous unions will have a generic name of
8778/// "__anonymous_union__", etc.
8779///
8780/// That generic name can be used as a hash to put all anonymous types
8781/// of a certain kind in the same hash table bucket, for instance.
8782static interned_string
8783get_generic_anonymous_internal_type_name(const decl_base *d)
8784{
8785 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8786
8787 const environment&env = d->get_environment();
8788
8789 interned_string result;
8790 if (is_class_type(d))
8791 result =
8793 else if (is_union_type(d))
8794 result =
8796 else if (is_enum_type(d))
8797 result =
8799 else if (is_subrange_type(d))
8800 result =
8802 else
8804
8805 return result;
8806}
8807
8808/// Get the internal name for a given integral type.
8809///
8810/// All integral types that have the modifiers 'short, long or long
8811/// long' have the same internal name. This is so that they can all
8812/// have the same canonical type if they are of the same size.
8813/// Otherwise, 'long int' and 'long long int' would have different
8814/// canonical types even though they are equivalent from an ABI point
8815/// of view.
8816///
8817/// @param t the integral type to consider
8818///
8819/// @return the internal name for @p t if it's an integral type, or
8820/// the empty string if @p t is not an integral type.
8821static string
8822get_internal_integral_type_name(const type_base* t)
8823{
8824 string name;
8825 type_decl *type = is_integral_type(t);
8826
8827 if (!type)
8828 return name;
8829
8830 integral_type int_type;
8831 if (parse_integral_type(type->get_name(), int_type))
8832 name = int_type.to_string(/*internal=*/true);
8833
8834 return name;
8835}
8836
8837/// Get the name of a given type and return a copy of it.
8838///
8839/// @param t the type to consider.
8840///
8841/// @param qualified if true then return the qualified name of the
8842/// type.
8843///
8844/// @param internal set to true if the call is intended for an
8845/// internal use (for technical use inside the library itself), false
8846/// otherwise. If you don't know what this is for, then set it to
8847/// false.
8848///
8849/// @return a copy of the type name if the type has a name, or the
8850/// empty string if it does not.
8851interned_string
8852get_type_name(const type_base* t, bool qualified, bool internal)
8853{
8854 const decl_base* d = dynamic_cast<const decl_base*>(t);
8855 if (!d)
8856 {
8857 const function_type* fn_type = is_function_type(t);
8858 ABG_ASSERT(fn_type);
8859 return fn_type->get_cached_name(internal);
8860 }
8861
8862 const environment&env = d->get_environment();
8863
8864 // All anonymous types of a given kind get to have the same internal
8865 // name for internal purpose. This to allow them to be compared
8866 // among themselves during type canonicalization.
8867 if (internal)
8868 {
8869 if (d->get_is_anonymous())
8870 {
8871 string r;
8872 r += get_generic_anonymous_internal_type_name(d);
8873 return t->get_environment().intern(r);
8874 }
8875
8876 if (is_typedef(t))
8877 return d->get_name();
8878
8879 if (qualified)
8880 return d->get_qualified_name(internal);
8881
8882 return env.intern(get_internal_integral_type_name(t));
8883 }
8884
8885 if (d->get_is_anonymous())
8886 {
8888 return env.intern
8890 /*one_line=*/true,
8891 internal, qualified));
8892 }
8893
8894 if (qualified)
8895 return d->get_qualified_name(internal);
8896 return d->get_name();
8897}
8898
8899/// Get the name of a given type and return a copy of it.
8900///
8901/// @param t the type to consider.
8902///
8903/// @param qualified if true then return the qualified name of the
8904/// type.
8905///
8906/// @param internal set to true if the call is intended for an
8907/// internal use (for technical use inside the library itself), false
8908/// otherwise. If you don't know what this is for, then set it to
8909/// false.
8910///
8911/// @return a copy of the type name if the type has a name, or the
8912/// empty string if it does not.
8914get_type_name(const type_base& t, bool qualified, bool internal)
8915{return get_type_name(&t, qualified, internal);}
8916
8917/// Get the name of the pointer to a given type.
8918///
8919/// @param pointed_to_type the pointed-to-type to consider.
8920///
8921/// @param qualified this is true if the resulting name should be of a
8922/// pointer to a *fully-qualified* pointed-to-type.
8923///
8924/// @param internal true if the name is for libabigail-internal
8925/// purposes.
8926///
8927/// @return the name (string representation) of the pointer.
8930 bool qualified, bool internal)
8931{
8932 const environment& env = pointed_to_type.get_environment();
8933 string tn = get_type_name(pointed_to_type, qualified, internal);
8934 tn = tn + "*";
8935
8936 return env.intern(tn);
8937}
8938
8939/// Get the name of the reference to a given type.
8940///
8941/// @param pointed_to_type the pointed-to-type to consider.
8942///
8943/// @param qualified this is true if the resulting name should be of a
8944/// reference to a *fully-qualified* pointed-to-type.
8945///
8946/// @param internal true if the name is for libabigail-internal
8947/// purposes.
8948///
8949/// @return the name (string representation) of the reference.
8952 bool lvalue_reference,
8953 bool qualified, bool internal)
8954{
8955 const environment& env = pointed_to_type.get_environment();
8956
8957 string name = get_type_name(pointed_to_type, qualified, internal);
8958 if (lvalue_reference)
8959 name = name + "&";
8960 else
8961 name = name + "&&";
8962
8963 return env.intern(name);
8964}
8965
8966/// Get the name of a qualified type, given the underlying type and
8967/// its qualifiers.
8968///
8969/// @param underlying_type the underlying type to consider.
8970///
8971/// @param quals the CV qualifiers of the name.
8972///
8973/// @param qualified true if we should consider the fully qualified
8974/// name of @p underlying_type.
8975///
8976/// @param internal true if the result is to be used for
8977/// libabigail-internal purposes.
8978///
8979/// @return the name (string representation) of the qualified type.
8981get_name_of_qualified_type(const type_base_sptr& underlying_type,
8983 bool qualified, bool internal)
8984{
8985 const environment& env = underlying_type->get_environment();
8986
8987 string quals_repr = get_string_representation_of_cv_quals(quals);
8988 string name = get_type_name(underlying_type, qualified, internal);
8989
8990 if (quals_repr.empty() && internal)
8991 // We are asked to return the internal name, that might be used
8992 // for type canonicalization. For that canonicalization, we need
8993 // to make a difference between a no-op qualified type which
8994 // underlying type is foo (the qualified type is named "none
8995 // foo"), and the name of foo, which is just "foo".
8996 //
8997 // Please remember that this has to be kept in sync with what is
8998 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
8999 // change this code here, please change that code there too.
9000 quals_repr = "";
9001
9002 if (!quals_repr.empty())
9003 {
9004 if (is_pointer_type(peel_qualified_type(underlying_type))
9005 || is_reference_type(peel_qualified_type(underlying_type)))
9006 {
9007 name += " ";
9008 name += quals_repr;
9009 }
9010 else
9011 name = quals_repr + " " + name;
9012 }
9013
9014 return env.intern(name);
9015}
9016
9017/// Get the name of a given function type and return a copy of it.
9018///
9019/// @param fn_type the function type to consider.
9020///
9021/// @param internal set to true if the call is intended for an
9022/// internal use (for technical use inside the library itself), false
9023/// otherwise. If you don't know what this is for, then set it to
9024/// false.
9025///
9026/// @return a copy of the function type name
9029 bool internal)
9030{return get_function_type_name(fn_type.get(), internal);}
9031
9032/// Get the name of a given function type and return a copy of it.
9033///
9034/// @param fn_type the function type to consider.
9035///
9036/// @param internal set to true if the call is intended for an
9037/// internal use (for technical use inside the library itself), false
9038/// otherwise. If you don't know what this is for, then set it to
9039/// false.
9040///
9041/// @return a copy of the function type name
9044 bool internal)
9045{
9046 ABG_ASSERT(fn_type);
9047
9048 if (const method_type* method = is_method_type(fn_type))
9049 return get_method_type_name(method, internal);
9050
9051 return get_function_type_name(*fn_type, internal);
9052}
9053
9054/// Get the name of a given function type and return a copy of it.
9055///
9056/// @param fn_type the function type to consider.
9057///
9058/// @param internal set to true if the call is intended for an
9059/// internal use (for technical use inside the library itself), false
9060/// otherwise. If you don't know what this is for, then set it to
9061/// false.
9062///
9063/// @return a copy of the function type name
9066 bool internal)
9067{
9068 std::ostringstream o;
9069 // When the function name is used for internal purposes (e.g, for
9070 // canonicalization), we want its representation to stay the same,
9071 // regardless of typedefs. So let's strip typedefs from the return
9072 // type.
9073 type_base_sptr return_type =
9074 internal
9076 : fn_type.get_return_type();
9077 const environment& env = fn_type.get_environment();
9078
9079 o << get_type_name(return_type, /*qualified=*/true, internal) << " ";
9080 stream_pretty_representation_of_fn_parms(fn_type, o,
9081 /*qualified=*/true,
9082 internal);
9083 return env.intern(o.str());
9084}
9085
9086/// Get the ID of a function, or, if the ID can designate several
9087/// different functions, get its pretty representation.
9088///
9089/// @param fn the function to consider
9090///
9091/// @return the function ID of pretty representation of @p fn.
9094{
9095 ABG_ASSERT(fn);
9096
9097 interned_string result = fn->get_environment().intern(fn->get_id());
9098
9099 if (const corpus *c = fn->get_corpus())
9100 {
9102 c->get_exported_decls_builder();
9103 if (b->fn_id_maps_to_several_fns(fn))
9104 result = fn->get_environment().intern(fn->get_pretty_representation());
9105 }
9106
9107 return result;
9108}
9109
9110/// Get the name of a given method type and return a copy of it.
9111///
9112/// @param fn_type the function type to consider.
9113///
9114/// @param internal set to true if the call is intended for an
9115/// internal use (for technical use inside the library itself), false
9116/// otherwise. If you don't know what this is for, then set it to
9117/// false.
9118///
9119/// @return a copy of the function type name
9122 bool internal)
9123{return get_method_type_name(fn_type.get(), internal);}
9124
9125/// Get the name of a given method type and return a copy of it.
9126///
9127/// @param fn_type the function type to consider.
9128///
9129/// @param internal set to true if the call is intended for an
9130/// internal use (for technical use inside the library itself), false
9131/// otherwise. If you don't know what this is for, then set it to
9132/// false.
9133///
9134/// @return a copy of the function type name
9137 bool internal)
9138{
9139 if (fn_type)
9140 return get_method_type_name(*fn_type, internal);
9141
9142 return interned_string();
9143}
9144
9145/// Get the name of a given method type and return a copy of it.
9146///
9147/// @param fn_type the function type to consider.
9148///
9149/// @param internal set to true if the call is intended for an
9150/// internal use (for technical use inside the library itself), false
9151/// otherwise. If you don't know what this is for, then set it to
9152/// false.
9153///
9154/// @return a copy of the function type name
9157 bool internal)
9158{
9159 std::ostringstream o;
9160 // When the function name is used for internal purposes (e.g, for
9161 // canonicalization), we want its representation to stay the same,
9162 // regardless of typedefs. So let's strip typedefs from the return
9163 // type.
9164 type_base_sptr return_type =
9165 internal
9167 : fn_type.get_return_type();
9168 const environment& env = fn_type.get_environment();
9169
9170 if (return_type)
9171 o << get_type_name(return_type, /*qualified=*/true, internal);
9172 else
9173 // There are still some abixml files out there in which "void"
9174 // can be expressed as an empty type.
9175 o << "void";
9176
9177 class_or_union_sptr class_type = fn_type.get_class_type();
9178 ABG_ASSERT(class_type);
9179
9180 o << " (" << class_type->get_qualified_name(internal) << "::*) ";
9181 stream_pretty_representation_of_fn_parms(fn_type, o,
9182 /*qualified=*/true,
9183 internal);
9184
9185 return env.intern(o.str());
9186}
9187
9188/// Build and return a copy of the pretty representation of an ABI
9189/// artifact that could be either a type of a decl.
9190///
9191/// param tod the ABI artifact to consider.
9192///
9193/// @param internal set to true if the call is intended for an
9194/// internal use (for technical use inside the library itself), false
9195/// otherwise. If you don't know what this is for, then set it to
9196/// false.
9197///
9198/// @return a copy of the pretty representation of an ABI artifact
9199/// that could be either a type of a decl.
9200string
9202{
9203 string result;
9204
9205 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9206 result = get_pretty_representation(t, internal);
9207 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9208 result = get_pretty_representation(d, internal);
9209 else
9210 // We should never reach this point
9211 abort();
9212
9213 return result;
9214}
9215
9216/// Build and return a copy of the pretty representation of an ABI
9217/// artifact that could be either a type of a decl.
9218///
9219/// param tod the ABI artifact to consider.
9220///
9221/// @param internal set to true if the call is intended for an
9222/// internal use (for technical use inside the library itself), false
9223/// otherwise. If you don't know what this is for, then set it to
9224/// false.
9225///
9226/// @return a copy of the pretty representation of an ABI artifact
9227/// that could be either a type of a decl.
9228string
9230{return get_pretty_representation(tod.get(), internal);}
9231
9232/// Get a copy of the pretty representation of a decl.
9233///
9234/// @param d the decl 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 the pretty representation of the decl.
9242string
9243get_pretty_representation(const decl_base* d, bool internal)
9244{
9245 if (!d)
9246 return "";
9247 return d->get_pretty_representation(internal);
9248}
9249
9250/// Get a copy of the pretty representation of a type.
9251///
9252/// @param d the type to consider.
9253///
9254/// @param internal set to true if the call is intended for an
9255/// internal use (for technical use inside the library itself), false
9256/// otherwise. If you don't know what this is for, then set it to
9257/// false.
9258///
9259/// @return the pretty representation of the type.
9260string
9261get_pretty_representation(const type_base* t, bool internal)
9262{
9263 if (!t)
9264 return "void";
9265 if (const function_type* fn_type = is_function_type(t))
9266 return get_pretty_representation(fn_type, internal);
9267
9268 const decl_base* d = get_type_declaration(t);
9269 ABG_ASSERT(d);
9270 return get_pretty_representation(d, internal);
9271}
9272
9273/// Get a copy of the pretty representation of a decl.
9274///
9275/// @param d the decl to consider.
9276///
9277/// @param internal set to true if the call is intended for an
9278/// internal use (for technical use inside the library itself), false
9279/// otherwise. If you don't know what this is for, then set it to
9280/// false.
9281///
9282/// @return the pretty representation of the decl.
9283string
9284get_pretty_representation(const decl_base_sptr& d, bool internal)
9285{return get_pretty_representation(d.get(), internal);}
9286
9287/// Get a copy of the pretty representation of a type.
9288///
9289/// @param d the type to consider.
9290///
9291/// @param internal set to true if the call is intended for an
9292/// internal use (for technical use inside the library itself), false
9293/// otherwise. If you don't know what this is for, then set it to
9294/// false.
9295///
9296/// @return the pretty representation of the type.
9297string
9298get_pretty_representation(const type_base_sptr& t, bool internal)
9299{return get_pretty_representation(t.get(), internal);}
9300
9301/// Get the pretty representation of a function type.
9302///
9303/// @param fn_type the function type to consider.
9304///
9305/// @param internal set to true if the call is intended for an
9306/// internal use (for technical use inside the library itself), false
9307/// otherwise. If you don't know what this is for, then set it to
9308/// false.
9309///
9310/// @return the string represenation of the function type.
9311string
9313 bool internal)
9314{return get_pretty_representation(fn_type.get(), internal);}
9315
9316/// Get the pretty representation of a function type.
9317///
9318/// @param fn_type the function type to consider.
9319///
9320/// @param internal set to true if the call is intended for an
9321/// internal use (for technical use inside the library itself), false
9322/// otherwise. If you don't know what this is for, then set it to
9323/// false.
9324///
9325/// @return the string represenation of the function type.
9326string
9327get_pretty_representation(const function_type* fn_type, bool internal)
9328{
9329 if (!fn_type)
9330 return "void";
9331
9332 if (const method_type* method = is_method_type(fn_type))
9333 return get_pretty_representation(method, internal);
9334
9335 return get_pretty_representation(*fn_type, internal);
9336}
9337
9338/// Get the pretty representation of a function type.
9339///
9340/// @param fn_type the function type to consider.
9341///
9342/// @param internal set to true if the call is intended for an
9343/// internal use (for technical use inside the library itself), false
9344/// otherwise. If you don't know what this is for, then set it to
9345/// false.
9346///
9347/// @return the string represenation of the function type.
9348string
9349get_pretty_representation(const function_type& fn_type, bool internal)
9350{
9351 std::ostringstream o;
9352 o << "function type " << get_function_type_name(fn_type, internal);
9353 return o.str();
9354}
9355
9356/// Get the pretty representation of a method type.
9357///
9358/// @param method the method type to consider.
9359///
9360/// @param internal set to true if the call is intended for an
9361/// internal use (for technical use inside the library itself), false
9362/// otherwise. If you don't know what this is for, then set it to
9363/// false.
9364///
9365/// @return the string represenation of the method type.
9366string
9367get_pretty_representation(const method_type& method, bool internal)
9368{
9369 std::ostringstream o;
9370 o << "method type " << get_method_type_name(method, internal);
9371 return o.str();
9372}
9373
9374/// Get the pretty representation of a method type.
9375///
9376/// @param method the method type to consider.
9377///
9378/// @param internal set to true if the call is intended for an
9379/// internal use (for technical use inside the library itself), false
9380/// otherwise. If you don't know what this is for, then set it to
9381/// false.
9382///
9383/// @return the string represenation of the method type.
9384string
9385get_pretty_representation(const method_type* method, bool internal)
9386{
9387 if (!method)
9388 return "void";
9389 return get_pretty_representation(*method, internal);
9390}
9391
9392/// Get the pretty representation of a method type.
9393///
9394/// @param method the method type to consider.
9395///
9396/// @param internal set to true if the call is intended for an
9397/// internal use (for technical use inside the library itself), false
9398/// otherwise. If you don't know what this is for, then set it to
9399/// false.
9400///
9401/// @return the string represenation of the method type.
9402string
9404{return get_pretty_representation(method.get(), internal);}
9405
9406/// Get the flat representation of an instance of @ref class_or_union
9407/// type.
9408///
9409/// The flat representation of a given @ref class_or_union type is the
9410/// actual definition of the type, for instance:
9411///
9412/// struct foo {int a; char b;}
9413///
9414///@param cou the instance of @ref class_or_union to consider.
9415///
9416///@param indent the identation spaces to use in the representation.
9417///
9418///@param one_line if true, then the flat representation stands on one
9419///line. Otherwise, it stands on multiple lines.
9420///
9421///@return the resulting flat representation.
9422string
9424 const string& indent,
9425 bool one_line,
9426 bool internal,
9427 bool qualified_names)
9428{
9429 string repr;
9430 string local_indent = " ";
9431
9432 if (class_decl* clazz = is_class_type(&cou))
9433 {
9434 repr = indent;
9435 if (!internal && clazz->is_struct())
9436 repr += "struct";
9437 else
9438 repr += "class";
9439 }
9440 else if (is_union_type(cou))
9441 repr = indent + "union";
9442 else
9443 return "";
9444
9445 repr += " ";
9446
9447 string name = cou.get_qualified_name();
9448
9449 if (!cou.get_is_anonymous())
9450 repr += name;
9451
9452 repr += "{";
9453
9454 if (!one_line)
9455 repr += "\n";
9456
9457 string real_indent;
9459 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9460 dm != dmems.end();
9461 ++dm)
9462 {
9463 if (dm != dmems.begin())
9464 {
9465 if (one_line)
9466 real_indent = " ";
9467 else
9468 real_indent = "\n" + indent + local_indent;
9469 }
9470
9472 repr +=
9475 real_indent, one_line, internal, qualified_names);
9476 else
9477 {
9478 if (one_line)
9479 {
9480 if (dm != dmems.begin())
9481 repr += real_indent;
9482 repr += (*dm)->get_pretty_representation(internal,
9483 qualified_names);
9484 }
9485 else
9486 repr +=
9487 real_indent+ (*dm)->get_pretty_representation(internal,
9488 qualified_names);
9489 }
9490 repr += ";";
9491 }
9492
9493 if (one_line)
9494 repr += "}";
9495 else
9496 repr += indent + "}";
9497
9498 return repr;
9499}
9500
9501/// Get the flat representation of an instance of @ref class_or_union
9502/// type.
9503///
9504/// The flat representation of a given @ref class_or_union type is the
9505/// actual definition of the type, for instance:
9506///
9507/// struct foo {int a; char b;}
9508///
9509///@param cou the instance of @ref class_or_union to consider.
9510///
9511///@param indent the identation spaces to use in the representation.
9512///
9513///@param one_line if true, then the flat representation stands on one
9514///line. Otherwise, it stands on multiple lines.
9515///
9516///@return the resulting flat representation.
9517string
9519 const string& indent,
9520 bool one_line,
9521 bool internal,
9522 bool qualified_names)
9523{
9524 if (cou)
9525 return get_class_or_union_flat_representation(*cou, indent, one_line,
9526 internal, qualified_names);
9527 return "";
9528}
9529
9530/// Get the flat representation of an instance of @ref class_or_union
9531/// type.
9532///
9533/// The flat representation of a given @ref class_or_union type is the
9534/// actual definition of the type, for instance:
9535///
9536/// struct foo {int a; char b;}
9537///
9538///@param cou the instance of @ref class_or_union to consider.
9539///
9540///@param indent the identation spaces to use in the representation.
9541///
9542///@param one_line if true, then the flat representation stands on one
9543///line. Otherwise, it stands on multiple lines.
9544///
9545///@return the resulting flat representation.
9546string
9547get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9548 const string& indent,
9549 bool one_line,
9550 bool internal,
9551 bool qualified_names)
9553 indent,
9554 one_line,
9555 internal,
9556 qualified_names);}
9557
9558/// Get the flat representation of an instance of @ref enum_type_decl
9559/// type.
9560///
9561/// The flat representation of a given @ref enum_type_decl type is the
9562/// actual definition of the type, for instance:
9563///
9564/// enum {E_0 =0, E_1 = 1}
9565///
9566///@param enum_type the enum type to consider.
9567///
9568///@param indent the identation spaces to use in the representation.
9569///
9570///@param one_line if true, then the flat representation stands on one
9571///line. Otherwise, it stands on multiple lines.
9572///
9573///@param qualified_names use qualified names when applicable.
9574///Typically, if this is true, the name of the enum is going to be
9575///qualified.
9576///
9577///@return the resulting flat representation.
9578string
9580 const string& indent, bool one_line,
9581 bool qualified_names)
9582{
9583 string repr;
9584 std::ostringstream o;
9585 string local_indent = " ";
9586
9587 repr = indent + "enum ";
9588
9589 if (!enum_type.get_is_anonymous())
9590 o << (qualified_names
9591 ? enum_type.get_qualified_name()
9592 : enum_type.get_name()) + " ";
9593
9594 o << "{";
9595
9596 if (!one_line)
9597 o << "\n";
9598
9599 for (const auto &enumerator : enum_type.get_sorted_enumerators())
9600 {
9601 if (!one_line)
9602 o << "\n" + indent;
9603
9604 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
9605 }
9606
9607 if (!one_line)
9608 o << "\n" + indent << "}";
9609 else
9610 o << "}";
9611
9612 repr =o.str();
9613
9614 return repr;
9615}
9616
9617/// Get the flat representation of an instance of @ref enum_type_decl
9618/// type.
9619///
9620/// The flat representation of a given @ref enum_type_decl type is the
9621/// actual definition of the type, for instance:
9622///
9623/// enum {E_0 =0, E_1 = 1}
9624///
9625///@param enum_type the enum type to consider.
9626///
9627///@param indent the identation spaces to use in the representation.
9628///
9629///@param one_line if true, then the flat representation stands on one
9630///line. Otherwise, it stands on multiple lines.
9631///
9632///@param qualified_names use qualified names when applicable.
9633///Typically, if this is true, the name of the enum is going to be
9634///qualified.
9635///
9636///@return the resulting flat representation.
9637string
9639 const string& indent, bool one_line,
9640 bool qualified_names)
9641{
9642 if (!enum_type)
9643 return "";
9644
9645 return get_enum_flat_representation(*enum_type, indent,
9646 one_line, qualified_names);
9647}
9648
9649/// Get the flat representation of an instance of @ref enum_type_decl
9650/// type.
9651///
9652/// The flat representation of a given @ref enum_type_decl type is the
9653/// actual definition of the type, for instance:
9654///
9655/// enum {E_0 =0, E_1 = 1}
9656///
9657///@param enum_type the enum type to consider.
9658///
9659///@param indent the identation spaces to use in the representation.
9660///
9661///@param one_line if true, then the flat representation stands on one
9662///line. Otherwise, it stands on multiple lines.
9663///
9664///@param qualified_names use qualified names when applicable.
9665///Typically, if this is true, the name of the enum is going to be
9666///qualified.
9667///
9668///@return the resulting flat representation.
9669string
9671 const string& indent, bool one_line,
9672 bool qualified_names)
9673{
9674 return get_enum_flat_representation(enum_type.get(),
9675 indent, one_line,
9676 qualified_names);
9677}
9678
9679/// Get the flat representation of an instance of @ref enum_type_decl
9680/// type.
9681///
9682/// The flat representation of a given @ref enum_type_decl type is the
9683/// actual definition of the type, for instance:
9684///
9685/// enum {E_0 =0, E_1 = 1}
9686///
9687///@param enum_type the enum type to consider.
9688///
9689///@param indent the identation spaces to use in the representation.
9690///
9691///@param one_line if true, then the flat representation stands on one
9692///line. Otherwise, it stands on multiple lines.
9693///
9694///@param qualified_names use qualified names when applicable.
9695///Typically, if this is true, the name of the enum is going to be
9696///qualified.
9697///
9698///@return the resulting flat representation.
9699string
9701 const string& indent,
9702 bool one_line,
9703 bool internal,
9704 bool qualified_name)
9705
9706{
9707 string repr;
9708 if (const class_or_union* cou = is_class_or_union_type(&coe))
9709 repr = get_class_or_union_flat_representation(cou, indent, one_line,
9710 internal, qualified_name);
9711 else if (const enum_type_decl* enom = is_enum_type(&coe))
9712 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9713
9714 return repr;
9715}
9716
9717/// Get the textual representation of a type for debugging purposes.
9718///
9719/// If the type is a class/union, this shows the data members, virtual
9720/// member functions, size, pointer value of its canonical type, etc.
9721/// Otherwise, this just shows the name of the artifact as returned by
9722/// type_or_decl_base:get_pretty_representation().
9723///
9724/// @param artifact the artifact to show a debugging representation of.
9725///
9726/// @return a debugging string representation of @p artifact.
9727string
9729{
9730 if (!artifact)
9731 return string("");
9732
9733 class_or_union * c = is_class_or_union_type(artifact);
9734 if (c)
9735 {
9736 class_decl *clazz = is_class_type(c);
9737 string name = c->get_qualified_name();
9738 std::ostringstream o;
9739 if (clazz)
9740 {
9741 if (clazz->is_struct())
9742 o << "struct ";
9743 else
9744 o << "class ";
9745 }
9746 else if (is_union_type(c))
9747 o << "union ";
9748 o << name;
9749
9750 if (clazz)
9751 {
9752 if (!clazz->get_base_specifiers().empty())
9753 o << " :" << std::endl;
9754 for (auto &b : clazz->get_base_specifiers())
9755 {
9756 o << " ";
9757 if (b->get_is_virtual())
9758 o << "virtual ";
9759 o << b->get_base_class()->get_qualified_name()
9760 << std::endl;
9761 }
9762 }
9763 o << std::endl
9764 << "{"
9765 << " // size in bits: " << c->get_size_in_bits() << "\n"
9766 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9767 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9768 << " // translation unit: " << c->get_translation_unit()->get_absolute_path() << std::endl
9769 << " // @: " << std::hex << is_type(c)
9770 << ", @canonical: " << c->get_canonical_type().get() << std::dec
9771 << "\n\n";
9772
9773 for (auto m : c->get_data_members())
9774 {
9775 type_base_sptr t = m->get_type();
9777
9778 o << " "
9779 << m->get_pretty_representation(/*internal=*/false,
9780 /*qualified=*/false)
9781 << ";";
9782
9783 if (t && t->get_canonical_type())
9784 o << " // uses canonical type '@"
9785 << std::hex << t->get_canonical_type().get() << std::dec;
9786
9787 o << "'" << std::endl;
9788 }
9789
9790 if (clazz && clazz->has_vtable())
9791 {
9792 o << " // virtual member functions\n\n";
9793 for (auto f : clazz->get_virtual_mem_fns())
9794 o << " " << f->get_pretty_representation(/*internal=*/false,
9795 /*qualified=*/false)
9796 << ";" << std::endl;
9797 }
9798
9799 o << "};" << std::endl;
9800
9801 return o.str();
9802 }
9803 else if (const enum_type_decl* e = is_enum_type(artifact))
9804 {
9805 string name = e->get_qualified_name();
9806 std::ostringstream o;
9807 o << "enum " << name
9808 << " : "
9809 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9810 true)
9811 << "\n"
9812 << "{\n"
9813 << " // size in bits: " << e->get_size_in_bits() << "\n"
9814 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9815 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9816 << " // translation unit: "
9817 << e->get_translation_unit()->get_absolute_path() << "\n"
9818 << " // @: " << std::hex << is_type(e)
9819 << ", @canonical: " << e->get_canonical_type().get() << std::dec
9820 << "\n\n";
9821
9822 for (const auto &enom : e->get_enumerators())
9823 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9824
9825 o << "};\n";
9826
9827 return o.str();
9828 }
9829 return artifact->get_pretty_representation(/*internal=*/true,
9830 /*qualified=*/true);
9831}
9832
9833/// Get a given data member, referred to by its name, of a class type.
9834///
9835/// @param clazz the class to consider.
9836///
9837/// @param member_name name of the data member to get.
9838///
9839/// @return the resulting data member or nullptr if none was found.
9841get_data_member(class_or_union *clazz, const char* member_name)
9842{
9843 if (!clazz)
9844 return var_decl_sptr();
9845 return clazz->find_data_member(member_name);
9846}
9847
9848/// Get a given data member, referred to by its name, of a class type.
9849///
9850/// @param clazz the class to consider.
9851///
9852/// @param member_name name of the data member to get.
9853///
9854/// @return the resulting data member or nullptr if none was found.
9856get_data_member(type_base *clazz, const char* member_name)
9857{return get_data_member(is_class_or_union_type(clazz), member_name);}
9858
9859/// Get the non-artificial (natural) location of a decl.
9860///
9861/// If the decl doesn't have a natural location then return its
9862/// artificial one.
9863///
9864/// @param decl the decl to consider.
9865///
9866/// @return the natural location @p decl if it has one; otherwise,
9867/// return its artificial one.
9868const location&
9870{
9871 ABG_ASSERT(decl);
9872
9873 if (decl->get_location())
9874 return decl->get_location();
9875 return decl->get_artificial_location();
9876}
9877
9878/// Get the artificial location of a decl.
9879///
9880/// If the decl doesn't have an artificial location then return its
9881/// natural one.
9882///
9883/// @param decl the decl to consider.
9884///
9885/// @return the artificial location @p decl if it has one; otherwise,
9886/// return its natural one.
9887const location&
9889{
9890 ABG_ASSERT(decl);
9891
9892 if (decl->has_artificial_location())
9893 return decl->get_artificial_location();
9894 return decl->get_location();
9895}
9896
9897/// Emit a textual representation of an artifact to std error stream
9898/// for debugging purposes.
9899///
9900/// This is useful to invoke from within a command line debugger like
9901/// GDB to help make sense of a given ABI artifact.
9902///
9903/// @param artifact the ABI artifact to emit the debugging
9904/// representation for.
9905///
9906/// @return the artifact @p artifact.
9908debug(const type_or_decl_base* artifact)
9909{
9910 std::cerr << get_debug_representation(artifact) << std::endl;
9911 return const_cast<type_or_decl_base*>(artifact);
9912}
9913
9914/// Emit a textual representation of an artifact to std error stream
9915/// for debugging purposes.
9916///
9917/// This is useful to invoke from within a command line debugger like
9918/// GDB to help make sense of a given ABI artifact.
9919///
9920/// @param artifact the ABI artifact to emit the debugging
9921/// representation for.
9922///
9923/// @return the artifact @p artifact.
9924type_base*
9925debug(const type_base* artifact)
9926{
9927 debug(static_cast<const type_or_decl_base*>(artifact));
9928 return const_cast<type_base*>(artifact);
9929}
9930
9931/// Emit a textual representation of an artifact to std error stream
9932/// for debugging purposes.
9933///
9934/// This is useful to invoke from within a command line debugger like
9935/// GDB to help make sense of a given ABI artifact.
9936///
9937/// @param artifact the ABI artifact to emit the debugging
9938/// representation for.
9939///
9940/// @return the artifact @p artifact.
9941decl_base*
9942debug(const decl_base* artifact)
9943{
9944 debug(static_cast<const type_or_decl_base*>(artifact));
9945 return const_cast<decl_base*>(artifact);
9946}
9947
9948/// Test if two ABI artifacts are equal.
9949///
9950/// This can be useful when used from the command line of a debugger
9951/// like GDB.
9952///
9953/// @param l the first ABI artifact to consider in the comparison.
9954///
9955/// @param r the second ABI artifact to consider in the comparison.
9956///
9957/// @return true iff @p l equals @p r.
9958bool
9960{
9961 if (!!l != !!r)
9962 return false;
9963 if (!l && !r)
9964 return true;
9965
9966 return (*l == *r);
9967}
9968
9969/// Emit a trace of a comparison operand stack.
9970///
9971/// @param vect the operand stack to emit the trace for.
9972///
9973/// @param o the output stream to emit the trace to.
9974static void
9975debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
9976{
9977 for (auto t : vect)
9978 {
9979 o << "|" << t->get_pretty_representation()
9980 << "@" << std::hex << t << std::dec;
9981 }
9982 if (!vect.empty())
9983 o << "|";
9984}
9985
9986/// Construct a trace of the two comparison operand stacks.
9987///
9988/// @param the environment in which the comparison operand stacks are.
9989///
9990/// @return a string representing the trace.
9991static string
9992print_comp_stack(const environment& env)
9993{
9994 std::ostringstream o;
9995 o << "left-operands: ";
9996 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
9997 o << "\n" << "right-operands: ";
9998 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
9999 o << "\n";
10000 return o.str();
10001}
10002
10003/// Emit a trace of the two comparison operands stack on the standard
10004/// error stream.
10005///
10006/// @param env the environment the comparison operands stack belong
10007/// to.
10008void
10010{
10011 std::cerr << print_comp_stack(env);
10012 std::cerr << std::endl;
10013}
10014
10015/// By looking at the language of the TU a given ABI artifact belongs
10016/// to, test if the ONE Definition Rule should apply.
10017///
10018/// To date, it applies to c++, java and ada.
10019///
10020/// @param artifact the ABI artifact to consider.
10021///
10022/// @return true iff the One Definition Rule should apply.
10023bool
10025{
10027 artifact.get_translation_unit()->get_language();
10028
10030 || is_java_language(l)
10031 || is_ada_language(l))
10032 return true;
10033
10034 return false;
10035}
10036
10037/// Get the declaration for a given type.
10038///
10039/// @param t the type to consider.
10040///
10041/// @return the declaration for the type to return.
10042const decl_base*
10044{return dynamic_cast<const decl_base*>(t);}
10045
10046/// Get the declaration for a given type.
10047///
10048/// @param t the type to consider.
10049///
10050/// @return the declaration for the type to return.
10051decl_base*
10053{return dynamic_cast<decl_base*>(t);}
10054
10055/// Get the declaration for a given type.
10056///
10057/// @param t the type to consider.
10058///
10059/// @return the declaration for the type to return.
10060decl_base_sptr
10061get_type_declaration(const type_base_sptr t)
10062{return dynamic_pointer_cast<decl_base>(t);}
10063
10064/// Test if two types are equal modulo a typedef.
10065///
10066/// Type A and B are compatible if
10067///
10068/// - A and B are equal
10069/// - or if one type is a typedef of the other one.
10070///
10071/// @param type1 the first type to consider.
10072///
10073/// @param type2 the second type to consider.
10074///
10075/// @return true iff @p type1 and @p type2 are compatible.
10076bool
10077types_are_compatible(const type_base_sptr type1,
10078 const type_base_sptr type2)
10079{
10080 if (!type1 || !type2)
10081 return false;
10082
10083 if (type1 == type2)
10084 return true;
10085
10086 // Normally we should strip typedefs entirely, but this is
10087 // potentially costly, especially on binaries with huge changesets
10088 // like the Linux Kernel. So we just get the leaf types for now.
10089 //
10090 // Maybe there should be an option by which users accepts to pay the
10091 // CPU usage toll in exchange for finer filtering?
10092
10093 // type_base_sptr t1 = strip_typedef(type1);
10094 // type_base_sptr t2 = strip_typedef(type2);
10095
10096 type_base_sptr t1 = peel_typedef_type(type1);
10097 type_base_sptr t2 = peel_typedef_type(type2);
10098
10099 return t1 == t2;
10100}
10101
10102/// Test if two types are equal modulo a typedef.
10103///
10104/// Type A and B are compatible if
10105///
10106/// - A and B are equal
10107/// - or if one type is a typedef of the other one.
10108///
10109/// @param type1 the declaration of the first type to consider.
10110///
10111/// @param type2 the declaration of the second type to consider.
10112///
10113/// @return true iff @p type1 and @p type2 are compatible.
10114bool
10115types_are_compatible(const decl_base_sptr d1,
10116 const decl_base_sptr d2)
10117{return types_are_compatible(is_type(d1), is_type(d2));}
10118
10119/// Return the translation unit a declaration belongs to.
10120///
10121/// @param decl the declaration to consider.
10122///
10123/// @return the resulting translation unit, or null if the decl is not
10124/// yet added to a translation unit.
10127{return const_cast<translation_unit*>(decl.get_translation_unit());}
10128
10129/// Return the translation unit a declaration belongs to.
10130///
10131/// @param decl the declaration to consider.
10132///
10133/// @return the resulting translation unit, or null if the decl is not
10134/// yet added to a translation unit.
10137{return decl ? get_translation_unit(*decl) : 0;}
10138
10139/// Return the translation unit a declaration belongs to.
10140///
10141/// @param decl the declaration to consider.
10142///
10143/// @return the resulting translation unit, or null if the decl is not
10144/// yet added to a translation unit.
10146get_translation_unit(const shared_ptr<decl_base> decl)
10147{return get_translation_unit(decl.get());}
10148
10149/// Tests whether if a given scope is the global scope.
10150///
10151/// @param scope the scope to consider.
10152///
10153/// @return true iff the current scope is the global one.
10154bool
10156{return !!dynamic_cast<const global_scope*>(&scope);}
10157
10158/// Tests whether if a given scope is the global scope.
10159///
10160/// @param scope the scope to consider.
10161///
10162/// @return the @ref global_scope* representing the scope @p scope or
10163/// 0 if @p scope is not a global scope.
10164const global_scope*
10166{return dynamic_cast<const global_scope*>(scope);}
10167
10168/// Tests whether if a given scope is the global scope.
10169///
10170/// @param scope the scope to consider.
10171///
10172/// @return true iff the current scope is the global one.
10173bool
10174is_global_scope(const shared_ptr<scope_decl>scope)
10175{return is_global_scope(scope.get());}
10176
10177/// Tests whether a given declaration is at global scope.
10178///
10179/// @param decl the decl to consider.
10180///
10181/// @return true iff decl is at global scope.
10182bool
10184{return (is_global_scope(decl.get_scope()));}
10185
10186/// Tests whether a given declaration is at global scope.
10187///
10188/// @param decl the decl to consider.
10189///
10190/// @return true iff decl is at global scope.
10191bool
10192is_at_global_scope(const decl_base_sptr decl)
10193{return (decl && is_global_scope(decl->get_scope()));}
10194
10195/// Tests whether a given declaration is at global scope.
10196///
10197/// @param decl the decl to consider.
10198///
10199/// @return true iff decl is at global scope.
10200bool
10202{return is_at_global_scope(*decl);}
10203
10204/// Tests whether a given decl is at class scope.
10205///
10206/// @param decl the decl to consider.
10207///
10208/// @return true iff decl is at class scope.
10210is_at_class_scope(const decl_base_sptr decl)
10211{return is_at_class_scope(decl.get());}
10212
10213/// Tests whether a given decl is at class scope.
10214///
10215/// @param decl the decl to consider.
10216///
10217/// @return true iff decl is at class scope.
10220{
10221 if (!decl)
10222 return 0;
10223
10224 return is_at_class_scope(*decl);
10225}
10226
10227/// Tests whether a given decl is at class scope.
10228///
10229/// @param decl the decl to consider.
10230///
10231/// @return true iff decl is at class scope.
10234{
10235 scope_decl* scope = decl.get_scope();
10236 if (class_or_union* cl = is_class_type(scope))
10237 return cl;
10238 if (class_or_union* cl = is_union_type(scope))
10239 return cl;
10240 return 0;
10241}
10242
10243/// Find a data member inside an anonymous data member.
10244///
10245/// An anonymous data member has a type which is a class or union.
10246/// This function looks for a data member inside the type of that
10247/// anonymous data member.
10248///
10249/// @param anon_dm the anonymous data member to consider.
10250///
10251/// @param name the name of the data member to look for.
10254 const string& name)
10255{
10256 const class_or_union* containing_class_or_union =
10258
10259 if (!containing_class_or_union)
10260 return var_decl_sptr();
10261
10262 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10263 return result;
10264}
10265
10266/// Tests whether a given decl is at template scope.
10267///
10268/// Note that only template parameters , types that are compositions,
10269/// and template patterns (function or class) can be at template scope.
10270///
10271/// @param decl the decl to consider.
10272///
10273/// @return true iff the decl is at template scope.
10274bool
10275is_at_template_scope(const shared_ptr<decl_base> decl)
10276{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10277
10278/// Tests whether a decl is a template parameter.
10279///
10280/// @param decl the decl to consider.
10281///
10282/// @return true iff decl is a template parameter.
10283bool
10284is_template_parameter(const shared_ptr<decl_base> decl)
10285{
10286 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10287 || dynamic_pointer_cast<non_type_tparameter>(decl)
10288 || dynamic_pointer_cast<template_tparameter>(decl)));
10289}
10290
10291/// Test whether a declaration is a @ref function_decl.
10292///
10293/// @param d the declaration to test for.
10294///
10295/// @return a shared pointer to @ref function_decl if @p d is a @ref
10296/// function_decl. Otherwise, a nil shared pointer.
10299{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10300
10301/// Test whether a declaration is a @ref function_decl.
10302///
10303/// @param d the declaration to test for.
10304///
10305/// @return true if @p d is a function_decl.
10306bool
10308{return is_function_decl(&d);}
10309
10310/// Test whether a declaration is a @ref function_decl.
10311///
10312/// @param d the declaration to test for.
10313///
10314/// @return a shared pointer to @ref function_decl if @p d is a @ref
10315/// function_decl. Otherwise, a nil shared pointer.
10318{return dynamic_pointer_cast<function_decl>(d);}
10319
10320/// Test whether a declaration is a @ref function_decl.
10321///
10322/// @param d the declaration to test for.
10323///
10324/// @return a pointer to @ref function_decl if @p d is a @ref
10325/// function_decl. Otherwise, a nil shared pointer.
10328{
10329 return dynamic_cast<function_decl::parameter*>
10330 (const_cast<type_or_decl_base*>(tod));
10331}
10332
10333/// Test whether an ABI artifact is a @ref function_decl.
10334///
10335/// @param tod the declaration to test for.
10336///
10337/// @return a pointer to @ref function_decl if @p d is a @ref
10338/// function_decl. Otherwise, a nil shared pointer.
10341{return dynamic_pointer_cast<function_decl::parameter>(tod);}
10342
10343/// Test if an ABI artifact is a declaration.
10344///
10345/// @param d the artifact to consider.
10346///
10347/// @param return the declaration sub-object of @p d if it's a
10348/// declaration, or NULL if it is not.
10349decl_base*
10351{
10352 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10353 {
10354 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10355 // The artifact is a decl-only (like a function or a
10356 // variable). That is, it's not a type that also has a
10357 // declaration. In this case, we are in the fast path and we
10358 // have a pointer to the decl sub-object handy. Just return
10359 // it ...
10360 return reinterpret_cast<decl_base*>
10361 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10362
10363 // ... Otherwise, we are in the slow path, which is that the
10364 // artifact is a type which has a declaration. In that case,
10365 // let's use the slow dynamic_cast because we don't have the
10366 // pointer to the decl sub-object handily present.
10367 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10368 }
10369 return 0;
10370}
10371
10372/// Test if an ABI artifact is a declaration.
10373///
10374/// @param d the artifact to consider.
10375///
10376/// @param return the declaration sub-object of @p d if it's a
10377/// declaration, or NULL if it is not.
10378decl_base_sptr
10380{return dynamic_pointer_cast<decl_base>(d);}
10381
10382/// Test if an ABI artifact is a declaration.
10383///
10384/// This is done using a slow path that uses dynamic_cast.
10385///
10386/// @param d the artifact to consider.
10387///
10388/// @param return the declaration sub-object of @p d if it's a
10389decl_base*
10391{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10392
10393/// Test if an ABI artifact is a declaration.
10394///
10395/// This is done using a slow path that uses dynamic_cast.
10396///
10397/// @param d the artifact to consider.
10398///
10399/// @param return the declaration sub-object of @p d if it's a
10400decl_base_sptr
10402{return dynamic_pointer_cast<decl_base>(t);}
10403
10404/// Test whether a declaration is a type.
10405///
10406/// @param d the IR artefact to test for.
10407///
10408/// @return true if the artifact is a type, false otherwise.
10409bool
10411{
10412 if (dynamic_cast<const type_base*>(&tod))
10413 return true;
10414 return false;
10415}
10416
10417/// Test whether a declaration is a type.
10418///
10419/// @param d the IR artefact to test for.
10420///
10421/// @return true if the artifact is a type, false otherwise.
10422type_base*
10424{
10425 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10426 return reinterpret_cast<type_base*>
10427 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10428
10429 return 0;
10430}
10431
10432/// Test whether a declaration is a type.
10433///
10434/// @param d the IR artefact to test for.
10435///
10436/// @return true if the artifact is a type, false otherwise.
10437type_base_sptr
10439{return dynamic_pointer_cast<type_base>(tod);}
10440
10441/// Test whether a declaration is a type.
10442///
10443/// @param d the declaration to test for.
10444///
10445/// @return true if the declaration is a type, false otherwise.
10446
10447/// Test if a given type is anonymous.
10448///
10449/// Note that this function considers that an anonymous class that is
10450/// named by a typedef is not anonymous anymore. This is the C idiom:
10451///
10452/// typedef struct {int member;} s_type;
10453///
10454/// The typedef s_type becomes the name of the originally anonymous
10455/// struct.
10456///
10457/// @param t the type to consider.
10458///
10459/// @return true iff @p t is anonymous.
10460bool
10462{
10463 const decl_base* d = get_type_declaration(t);
10464 if (d)
10465 if (d->get_is_anonymous())
10466 {
10468 {
10469 // An anonymous class that is named by a typedef is not
10470 // considered anonymous anymore.
10471 if (!cou->get_naming_typedef())
10472 return true;
10473 }
10474 else
10475 return true;
10476 }
10477 return false;
10478}
10479
10480/// Test if a given type is anonymous.
10481///
10482/// @param t the type to consider.
10483///
10484/// @return true iff @p t is anonymous.
10485bool
10486is_anonymous_type(const type_base_sptr& t)
10487{return is_anonymous_type(t.get());}
10488
10489/// Test if a type is a neither a pointer, an array nor a function
10490/// type.
10491///
10492/// @param t the type to consider.
10493///
10494/// @return true if the @p t is NOT a pointer, an array nor a
10495/// function.
10496bool
10497is_npaf_type(const type_base_sptr& t)
10498{
10499 if (!(is_pointer_type(t)
10500 || is_array_type(t)
10501 || is_function_type(t)
10502 || is_ptr_to_mbr_type(t)))
10503 return true;
10504 return false;
10505}
10506
10507/// Test whether a type is a type_decl (a builtin type).
10508///
10509/// @return the type_decl* for @t if it's type_decl, otherwise, return
10510/// nil.
10511const type_decl*
10513{return dynamic_cast<const type_decl*>(t);}
10514
10515/// Test whether a type is a type_decl (a builtin type).
10516///
10517/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10518/// return nil.
10521{return dynamic_pointer_cast<type_decl>(t);}
10522
10523/// Test if a type is an integral type.
10524///
10525/// @param t the type to test.
10526///
10527/// @return the integral type @p t can be converted to, or nil if @p
10528/// is not an integral type.
10529type_decl*
10531{
10532 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10533 if (!type)
10534 return nullptr;
10535
10536 integral_type int_type;
10537 if (!parse_integral_type(type->get_name(), int_type))
10538 return nullptr;
10539
10540 return type;
10541}
10542
10543/// Test if a type is an integral type.
10544///
10545/// @param t the type to test.
10546///
10547/// @return the integral type @p t can be converted to, or nil if @p
10548/// is not an integral type.
10551{
10552 const type_decl_sptr type = is_type_decl(t);
10553 if (!type)
10554 return type_decl_sptr();
10555
10556 integral_type int_type;
10557 if (!parse_integral_type(type->get_name(), int_type))
10558 return type_decl_sptr();
10559
10560 return type;
10561}
10562
10563/// Test whether a type is a typedef.
10564///
10565/// @param t the type to test for.
10566///
10567/// @return the typedef declaration of the @p t, or NULL if it's not a
10568/// typedef.
10571{return dynamic_pointer_cast<typedef_decl>(t);}
10572
10573/// Test whether a type is a typedef.
10574///
10575/// @param t the declaration of the type to test for.
10576///
10577/// @return the typedef declaration of the @p t, or NULL if it's not a
10578/// typedef.
10579const typedef_decl*
10581{return dynamic_cast<const typedef_decl*>(t);}
10582
10583/// Test whether a type is a typedef.
10584///
10585/// @param t the declaration of the type to test for.
10586///
10587/// @return the typedef declaration of the @p t, or NULL if it's not a
10588/// typedef.
10591{return dynamic_cast<typedef_decl*>(t);}
10592
10593/// Test whether a type is a typedef.
10594///
10595/// @param t the declaration of the type to test for.
10596///
10597/// @return the typedef declaration of the @p t, or NULL if it's not a
10598/// typedef.
10599const typedef_decl*
10601{return dynamic_cast<const typedef_decl*>(t);}
10602/// Test if a type is an enum. This function looks through typedefs.
10603///
10604/// @parm t the type to consider.
10605///
10606/// @return the enum_decl if @p t is an @ref enum_decl or null
10607/// otherwise.
10609is_compatible_with_enum_type(const type_base_sptr& t)
10610{
10611 if (!t)
10612 return enum_type_decl_sptr();
10613
10614 // Normally we should strip typedefs entirely, but this is
10615 // potentially costly, especially on binaries with huge changesets
10616 // like the Linux Kernel. So we just get the leaf types for now.
10617 //
10618 // Maybe there should be an option by which users accepts to pay the
10619 // CPU usage toll in exchange for finer filtering?
10620
10621 // type_base_sptr ty = strip_typedef(t);
10622 type_base_sptr ty = peel_typedef_type(t);;
10623 return is_enum_type(ty);
10624}
10625
10626/// Test if a type is an enum. This function looks through typedefs.
10627///
10628/// @parm t the type to consider.
10629///
10630/// @return the enum_decl if @p t is an @ref enum_decl or null
10631/// otherwise.
10633is_compatible_with_enum_type(const decl_base_sptr& t)
10635
10636/// Test if a decl is an enum_type_decl
10637///
10638/// @param d the decl to test for.
10639///
10640/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
10641const enum_type_decl*
10643{return dynamic_cast<const enum_type_decl*>(d);}
10644
10645/// Test if a decl is an enum_type_decl
10646///
10647/// @param d the decl to test for.
10648///
10649/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
10652{return dynamic_pointer_cast<enum_type_decl>(d);}
10653
10654/// Test if a type is a class. This function looks through typedefs.
10655///
10656/// @parm t the type to consider.
10657///
10658/// @return the class_decl if @p t is a class_decl or null otherwise.
10660is_compatible_with_class_type(const type_base_sptr& t)
10661{
10662 if (!t)
10663 return class_decl_sptr();
10664
10665 // Normally we should strip typedefs entirely, but this is
10666 // potentially costly, especially on binaries with huge changesets
10667 // like the Linux Kernel. So we just get the leaf types for now.
10668 //
10669 // Maybe there should be an option by which users accepts to pay the
10670 // CPU usage toll in exchange for finer filtering?
10671
10672 // type_base_sptr ty = strip_typedef(t);
10673 type_base_sptr ty = peel_typedef_type(t);
10674 return is_class_type(ty);
10675}
10676
10677/// Test if a type is a class. This function looks through typedefs.
10678///
10679/// @parm t the type to consider.
10680///
10681/// @return the class_decl if @p t is a class_decl or null otherwise.
10683is_compatible_with_class_type(const decl_base_sptr& t)
10685
10686/// Test whether a type is a class.
10687///
10688/// @parm t the type to consider.
10689///
10690/// @return true iff @p t is a class_decl.
10691bool
10693{return is_class_type(&t);}
10694
10695/// Test whether a type is a class.
10696///
10697/// @parm t the type to consider.
10698///
10699/// @return the class_decl if @p t is a class_decl or null otherwise.
10702{
10703 if (!t)
10704 return 0;
10705
10706 if (t->kind() & type_or_decl_base::CLASS_TYPE)
10707 return reinterpret_cast<class_decl*>
10708 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10709
10710 return 0;
10711}
10712
10713/// Test whether a type is a class.
10714///
10715/// @parm t the type to consider.
10716///
10717/// @return the class_decl if @p t is a class_decl or null otherwise.
10720{return dynamic_pointer_cast<class_decl>(d);}
10721
10722/// Test if the last data member of a class is an array with
10723/// non-finite data member.
10724///
10725/// The flexible data member idiom is a well known C idiom:
10726/// https://en.wikipedia.org/wiki/Flexible_array_member.
10727///
10728/// @param klass the class to consider.
10729///
10730/// @return the data member which type is a flexible array, if any, or
10731/// nil.
10734{
10735 var_decl_sptr nil;
10737 if (dms.empty())
10738 return nil;
10739
10740 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
10741 {// The type of the last data member is an array.
10742 if (array->is_non_finite())
10743 // The array has a non-finite size. We are thus looking at a
10744 // flexible array data member. Let's return it.
10745 return dms.back();
10746 }
10747
10748 return nil;
10749}
10750
10751/// Test if the last data member of a class is an array with
10752/// non-finite data member.
10753///
10754/// The flexible data member idiom is a well known C idiom:
10755/// https://en.wikipedia.org/wiki/Flexible_array_member.
10756///
10757/// @param klass the class to consider.
10758///
10759/// @return the data member which type is a flexible array, if any, or
10760/// nil.
10763{
10764 if (!klass)
10765 return var_decl_sptr();
10766
10767 return has_flexible_array_data_member(*klass);
10768}
10769
10770/// Test if the last data member of a class is an array with
10771/// non-finite data member.
10772///
10773/// The flexible data member idiom is a well known C idiom:
10774/// https://en.wikipedia.org/wiki/Flexible_array_member.
10775///
10776/// @param klass the class to consider.
10777///
10778/// @return the data member which type is a flexible array, if any, or
10779/// nil.
10782{return has_flexible_array_data_member(klass.get());}
10783
10784/// Test if the last data member of a class is an array with
10785/// one element.
10786///
10787/// An array with one element is a way to mimic the flexible data
10788/// member idiom that was later standardized in C99.
10789///
10790/// To learn more about the flexible data member idiom, please
10791/// consider reading :
10792/// https://en.wikipedia.org/wiki/Flexible_array_member.
10793///
10794/// The various ways of representing that idiom pre-standardization
10795/// are presented in this article:
10796/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10797///
10798/// @param klass the class to consider.
10799///
10800/// @return the data member which type is a fake flexible array, if
10801/// any, or nil.
10804{
10805 var_decl_sptr nil;
10807 if (dms.empty())
10808 return nil;
10809
10810 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
10811 {// The type of the last data member is an array.
10812 if (array->get_subranges().size() == 1
10813 && array->get_subranges()[0]->get_length() == 1)
10814 // The array has a size of one. We are thus looking at a
10815 // "fake" flexible array data member. Let's return it.
10816 return dms.back();
10817 }
10818
10819 return nil;
10820}
10821
10822/// Test if the last data member of a class is an array with
10823/// one element.
10824///
10825/// An array with one element is a way to mimic the flexible data
10826/// member idiom that was later standardized in C99.
10827///
10828/// To learn more about the flexible data member idiom, please
10829/// consider reading :
10830/// https://en.wikipedia.org/wiki/Flexible_array_member.
10831///
10832/// The various ways of representing that idiom pre-standardization
10833/// are presented in this article:
10834/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10835///
10836/// @param klass the class to consider.
10837///
10838/// @return the data member which type is a fake flexible array, if
10839/// any, or nil.
10843
10844/// Test if the last data member of a class is an array with
10845/// one element.
10846///
10847/// An array with one element is a way to mimic the flexible data
10848/// member idiom that was later standardized in C99.
10849///
10850/// To learn more about the flexible data member idiom, please
10851/// consider reading :
10852/// https://en.wikipedia.org/wiki/Flexible_array_member.
10853///
10854/// The various ways of representing that idiom pre-standardization
10855/// are presented in this article:
10856/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10857///
10858/// @param klass the class to consider.
10859///
10860/// @return the data member which type is a fake flexible array, if
10861/// any, or nil.
10864{return has_fake_flexible_array_data_member(klass.get());}
10865
10866/// Test wheter a type is a declaration-only class.
10867///
10868/// @param t the type to considier.
10869///
10870/// @param look_through_decl_only if true, then look through the
10871/// decl-only class to see if it actually has a class definition in
10872/// the same ABI corpus.
10873///
10874/// @return true iff @p t is a declaration-only class.
10875bool
10878{
10879 if (class_or_union *klass = is_class_or_union_type(t))
10880 {
10882 klass = look_through_decl_only_class(klass);
10883 return klass->get_is_declaration_only();
10884 }
10885 return false;
10886}
10887
10888/// Test wheter a type is a declaration-only class.
10889///
10890/// @param t the type to considier.
10891///
10892/// @param look_through_decl_only if true, then look through the
10893/// decl-only class to see if it actually has a class definition in
10894/// the same ABI corpus.
10895///
10896/// @return true iff @p t is a declaration-only class.
10897bool
10901
10902/// Test wheter a type is a declaration-only class.
10903///
10904/// @param t the type to considier.
10905///
10906/// @param look_through_decl_only if true, then look through the
10907/// decl-only class to see if it actually has a class definition in
10908/// the same ABI corpus.
10909///
10910/// @return true iff @p t is a declaration-only class.
10911bool
10912is_declaration_only_class_type(const type_base_sptr& t,
10915
10916/// Test if a type is a @ref class_or_union.
10917///
10918/// @param t the type to consider.
10919///
10920/// @return the @ref class_or_union is @p is a @ref class_or_union, or
10921/// nil otherwise.
10924{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
10925
10926/// Test if a type is a @ref class_or_union.
10927///
10928/// @param t the type to consider.
10929///
10930/// @return the @ref class_or_union is @p is a @ref class_or_union, or
10931/// nil otherwise.
10932shared_ptr<class_or_union>
10933is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
10934{return dynamic_pointer_cast<class_or_union>(t);}
10935
10936/// Test if two class or union types are of the same kind.
10937///
10938/// @param first the first type to consider.
10939///
10940/// @param second the second type to consider.
10941///
10942/// @return true iff @p first is of the same kind as @p second.
10943bool
10945 const class_or_union* second)
10946{
10947 if ((is_class_type(first) && is_class_type(second))
10948 || (is_union_type(first) && is_union_type(second)))
10949 return true;
10950
10951 return false;
10952}
10953
10954/// Test if two class or union types are of the same kind.
10955///
10956/// @param first the first type to consider.
10957///
10958/// @param second the second type to consider.
10959///
10960/// @return true iff @p first is of the same kind as @p second.
10961bool
10962class_or_union_types_of_same_kind(const class_or_union_sptr& first,
10963 const class_or_union_sptr& second)
10964{return class_or_union_types_of_same_kind(first.get(), second.get());}
10965
10966/// Test if a type is a @ref union_decl.
10967///
10968/// @param t the type to consider.
10969///
10970/// @return true iff @p t is a union_decl.
10971bool
10973{return is_union_type(&t);}
10974
10975/// Test if a type is a @ref union_decl.
10976///
10977/// @param t the type to consider.
10978///
10979/// @return the @ref union_decl is @p is a @ref union_decl, or nil
10980/// otherwise.
10983{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
10984
10985/// Test if a type is a @ref union_decl.
10986///
10987/// @param t the type to consider.
10988///
10989/// @return the @ref union_decl is @p is a @ref union_decl, or nil
10990/// otherwise.
10991union_decl_sptr
10992is_union_type(const shared_ptr<type_or_decl_base>& t)
10993{return dynamic_pointer_cast<union_decl>(t);}
10994
10995/// Test whether a type is a pointer_type_def.
10996///
10997/// @param t the type to test.
10998///
10999/// @param look_through_decl_only if this is true, then look through
11000/// qualified types to see if the underlying type is a
11001/// pointer_type_def.
11002///
11003/// @return the @ref pointer_type_def_sptr if @p t is a
11004/// pointer_type_def, null otherwise.
11005const pointer_type_def*
11007 bool look_through_qualifiers)
11008{
11009 if (!t)
11010 return 0;
11011
11012 const type_base* type = is_type(t);
11013 if (look_through_qualifiers)
11014 type = peel_qualified_type(is_type(t));
11015
11016 return dynamic_cast<pointer_type_def*>(const_cast<type_base*>(type));
11017}
11018
11019/// Test whether a type is a pointer_type_def.
11020///
11021/// @param t the type to test.
11022///
11023/// @param look_through_decl_only if this is true, then look through
11024/// qualified types to see if the underlying type is a
11025/// pointer_type_def.
11026///
11027/// @return the @ref pointer_type_def_sptr if @p t is a
11028/// pointer_type_def, null otherwise.
11031 bool look_through_qualifiers)
11032{
11033 type_base_sptr type = is_type(t);
11034 if (look_through_qualifiers)
11035 type = peel_qualified_type(type);
11036 return dynamic_pointer_cast<pointer_type_def>(type);
11037}
11038
11039/// Test if a type is a pointer to function type.
11040///
11041/// @param t the type to consider.
11042///
11043/// @return the @ref pointer_type_def_sptr iff @p t is a pointer to
11044/// function type.
11046is_pointer_to_function_type(const type_base_sptr& t)
11047{
11049 {
11050 if (is_function_type(p->get_pointed_to_type()))
11051 return p;
11052 }
11053 return pointer_type_def_sptr();
11054}
11055
11056/// Test if a type is a pointer to array type.
11057///
11058/// @param t the type to consider.
11059///
11060/// @return the pointer_type_def_sptr iff @p t is a pointer to array
11061/// type.
11063is_pointer_to_array_type(const type_base_sptr& t)
11064{
11066 {
11067 if (is_array_type(p->get_pointed_to_type()))
11068 return p;
11069 }
11070 return pointer_type_def_sptr();
11071}
11072
11073/// Test if we are looking at a pointer to a
11074/// neither-a-pointer-to-an-array-nor-a-function type.
11075///
11076/// @param t the type to consider.
11077///
11078/// @return the @ref pointer_type_def_sptr type iff @p t is a
11079/// neither-a-pointer-an-array-nor-a-function type.
11081is_pointer_to_npaf_type(const type_base_sptr& t)
11082{
11084 {
11085 if (is_npaf_type(p->get_pointed_to_type()))
11086 return p;
11087 }
11088 return pointer_type_def_sptr();
11089}
11090
11091/// Test if we are looking at a pointer to pointer to member type.
11092///
11093/// @param t the type to consider.
11094///
11095/// @return the @ref pointer_type_def_sptr type iff @p t is a pointer
11096/// to pointer to member type.
11098is_pointer_to_ptr_to_mbr_type(const type_base_sptr& t)
11099{
11101 {
11102 if (is_ptr_to_mbr_type(p->get_pointed_to_type()))
11103 return p;
11104 }
11105 return pointer_type_def_sptr();
11106}
11107
11108/// Test if a type is a typedef, pointer or reference to a decl-only
11109/// class/union.
11110///
11111/// This looks into qualified types too.
11112///
11113/// @param t the type to consider.
11114///
11115/// @return true iff @p t is a type is a typedef, pointer or reference
11116/// to a decl-only class/union.
11117bool
11119{
11120 const type_base * type =
11121 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11122
11124 /*look_through_decl_only=*/true))
11125 return true;
11126
11127 return false;
11128}
11129
11130/// Test if a type is a typedef of a class or union type, or a typedef
11131/// of a qualified class or union type.
11132///
11133/// Note that if the type is directly a class or union type, the
11134/// function returns true as well.
11135///
11136/// @param t the type to consider.
11137///
11138/// @return true iff @p t is a typedef of a class or union type, or a
11139/// typedef of a qualified class or union type.
11140bool
11142{
11143 if (!t)
11144 return false;
11145
11148 return true;
11149
11150return false;
11151}
11152
11153/// Test if a type is a typedef of a class or union type, or a typedef
11154/// of a qualified class or union type.
11155///
11156/// Note that if the type is directly a class or union type, the
11157/// function returns true as well.
11158///
11159/// @param t the type to consider.
11160///
11161/// @return true iff @p t is a typedef of a class or union type, or a
11162/// typedef of a qualified class or union type.
11163bool
11166
11167/// Test whether a type is a reference_type_def.
11168///
11169/// @param t the type to test.
11170///
11171/// @param look_through_decl_only if this is true, then look through
11172/// qualified types to see if the underlying type is a
11173/// reference_type_def.
11174///
11175/// @return the @ref reference_type_def_sptr if @p t is a
11176/// reference_type_def, null otherwise.
11179 bool look_through_qualifiers)
11180{
11181 const type_base* type = is_type(t);
11182 if (!type)
11183 return nullptr;
11184
11185 if (look_through_qualifiers)
11186 type = peel_qualified_type(type);
11187 return dynamic_cast<reference_type_def*>(const_cast<type_base*>(type));
11188}
11189
11190/// Test whether a type is a reference_type_def.
11191///
11192/// @param t the type to test.
11193///
11194/// @param look_through_decl_only if this is true, then look through
11195/// qualified types to see if the underlying type is a
11196/// reference_type_def.
11197///
11198/// @return the @ref reference_type_def_sptr if @p t is a
11199/// reference_type_def, null otherwise.
11200const reference_type_def*
11202 bool look_through_qualifiers)
11203{
11204 const type_base* type = is_type(t);
11205
11206 if (look_through_qualifiers)
11207 type = peel_qualified_type(type);
11208 return dynamic_cast<const reference_type_def*>(type);
11209}
11210
11211/// Test whether a type is a reference_type_def.
11212///
11213/// @param t the type to test.
11214///
11215/// @param look_through_decl_only if this is true, then look through
11216/// qualified types to see if the underlying type is a
11217/// reference_type_def.
11218///
11219/// @return the @ref reference_type_def_sptr if @p t is a
11220/// reference_type_def, null otherwise.
11223 bool look_through_qualifiers)
11224{
11225 type_base_sptr type = is_type(t);
11226 if (look_through_qualifiers)
11227 type = peel_qualified_type(type);
11228 return dynamic_pointer_cast<reference_type_def>(type);
11229}
11230
11231/// Test whether a type is a @ref ptr_to_mbr_type.
11232///
11233/// @param t the type to test.
11234///
11235/// @return the @ref ptr_to_mbr_type* if @p t is a @ref
11236/// ptr_to_mbr_type type, null otherwise.
11237const ptr_to_mbr_type*
11239 bool look_through_qualifiers)
11240{
11241 const type_base* type = is_type(t);
11242 if (look_through_qualifiers)
11243 type = peel_qualified_type(type);
11244 return dynamic_cast<const ptr_to_mbr_type*>(type);
11245}
11246
11247/// Test whether a type is a @ref ptr_to_mbr_type_sptr.
11248///
11249/// @param t the type to test.
11250///
11251/// @param look_through_decl_only if this is true, then look through
11252/// qualified types to see if the underlying type is a
11253/// ptr_to_mbr_type..
11254///
11255/// @return the @ref ptr_to_mbr_type_sptr if @p t is a @ref
11256/// ptr_to_mbr_type type, null otherwise.
11259 bool look_through_qualifiers)
11260{
11261 type_base_sptr type = is_type(t);
11262 if (look_through_qualifiers)
11263 type = peel_qualified_type(type);
11264 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
11265}
11266
11267/// Test if a type is equivalent to a pointer to void type.
11268///
11269/// Note that this looks trough typedefs or CV qualifiers to look for
11270/// the void pointer.
11271///
11272/// @param type the type to consider.
11273///
11274/// @return the actual void pointer if @p is eqivalent to a void
11275/// pointer or NULL if it's not.
11276const type_base*
11278{
11279 type = peel_qualified_or_typedef_type(type);
11280
11281 const pointer_type_def * t = is_pointer_type(type);
11282 if (!t)
11283 return 0;
11284
11285 // Look through typedefs in the pointed-to type as well.
11286 type_base * ty = t->get_pointed_to_type().get();
11288 if (ty && ty->get_environment().is_void_type(ty))
11289 return ty;
11290
11291 return 0;
11292}
11293
11294/// Test if a type is equivalent to a pointer to void type.
11295///
11296/// Note that this looks trough typedefs or CV qualifiers to look for
11297/// the void pointer.
11298///
11299/// @param type the type to consider.
11300///
11301/// @return the actual void pointer if @p is eqivalent to a void
11302/// pointer or NULL if it's not.
11303const type_base*
11305{return is_void_pointer_type_equivalent(&type);}
11306
11307/// Test if a type is a pointer to void type.
11308///
11309/// @param type the type to consider.
11310///
11311/// @return the actual void pointer if @p is a void pointer or NULL if
11312/// it's not.
11313const type_base*
11315{
11316 if (!t)
11317 return nullptr;
11318
11319 if (t->get_environment().get_void_pointer_type().get() == t)
11320 return t;
11321
11322 const pointer_type_def* ptr = is_pointer_type(t);
11323 if (!ptr)
11324 return nullptr;
11325
11327 return t;
11328
11329 return nullptr;
11330}
11331
11332/// Test if a type is a pointer to void type.
11333///
11334/// @param type the type to consider.
11335///
11336/// @return the actual void pointer if @p is a void pointer or NULL if
11337/// it's not.
11338const type_base_sptr
11339is_void_pointer_type(const type_base_sptr& t)
11340{
11341 type_base_sptr nil;
11342 if (!t)
11343 return nil;
11344
11345 if (t->get_environment().get_void_pointer_type().get() == t.get())
11346 return t;
11347
11348 const pointer_type_def* ptr = is_pointer_type(t.get());
11349 if (!ptr)
11350 return nil;
11351
11352 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11353 return t;
11354
11355 return nil;
11356}
11357
11358/// Test whether a type is a reference_type_def.
11359///
11360/// @param t the type to test.
11361///
11362/// @return the @ref reference_type_def_sptr if @p t is a
11363/// reference_type_def, null otherwise.
11366{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11367
11368/// Test whether a type is a qualified_type_def.
11369///
11370/// @param t the type to test.
11371///
11372/// @return the @ref qualified_type_def_sptr if @p t is a
11373/// qualified_type_def, null otherwise.
11374qualified_type_def_sptr
11376{return dynamic_pointer_cast<qualified_type_def>(t);}
11377
11378/// Test whether a type is a function_type.
11379///
11380/// @param t the type to test.
11381///
11382/// @return the @ref function_type_sptr if @p t is a
11383/// function_type, null otherwise.
11386{return dynamic_pointer_cast<function_type>(t);}
11387
11388/// Test whether a type is a function_type.
11389///
11390/// @param t the type to test.
11391///
11392/// @return the @ref function_type_sptr if @p t is a
11393/// function_type, null otherwise.
11396{return dynamic_cast<function_type*>(t);}
11397
11398/// Test whether a type is a function_type.
11399///
11400/// @param t the type to test.
11401///
11402/// @return the @ref function_type_sptr if @p t is a
11403/// function_type, null otherwise.
11404const function_type*
11406{return dynamic_cast<const function_type*>(t);}
11407
11408/// Test whether a type is a method_type.
11409///
11410/// @param t the type to test.
11411///
11412/// @return the @ref method_type_sptr if @p t is a
11413/// method_type, null otherwise.
11416{return dynamic_pointer_cast<method_type>(t);}
11417
11418/// Test whether a type is a method_type.
11419///
11420/// @param t the type to test.
11421///
11422/// @return the @ref method_type_sptr if @p t is a
11423/// method_type, null otherwise.
11424const method_type*
11426{return dynamic_cast<const method_type*>(t);}
11427
11428/// Test whether a type is a method_type.
11429///
11430/// @param t the type to test.
11431///
11432/// @return the @ref method_type_sptr if @p t is a
11433/// method_type, null otherwise.
11436{return dynamic_cast<method_type*>(t);}
11437
11438/// If a class (or union) is a decl-only class, get its definition.
11439/// Otherwise, just return the initial class.
11440///
11441/// @param the_class the class (or union) to consider.
11442///
11443/// @return either the definition of the class, or the class itself.
11447
11448/// If a class (or union) is a decl-only class, get its definition.
11449/// Otherwise, just return the initial class.
11450///
11451/// @param the_class the class (or union) to consider.
11452///
11453/// @return either the definition of the class, or the class itself.
11454class_or_union_sptr
11457
11458/// If a class (or union) is a decl-only class, get its definition.
11459/// Otherwise, just return the initial class.
11460///
11461/// @param klass the class (or union) to consider.
11462///
11463/// @return either the definition of the class, or the class itself.
11464class_or_union_sptr
11465look_through_decl_only_class(class_or_union_sptr klass)
11467
11468/// If an enum is a decl-only enum, get its definition.
11469/// Otherwise, just return the initial enum.
11470///
11471/// @param the_enum the enum to consider.
11472///
11473/// @return either the definition of the enum, or the enum itself.
11476{return is_enum_type(look_through_decl_only(the_enum));}
11477
11478/// If an enum is a decl-only enum, get its definition.
11479/// Otherwise, just return the initial enum.
11480///
11481/// @param enom the enum to consider.
11482///
11483/// @return either the definition of the enum, or the enum itself.
11486{return is_enum_type(look_through_decl_only(enom));}
11487
11488/// If a decl is decl-only get its definition. Otherwise, just return nil.
11489///
11490/// @param d the decl to consider.
11491///
11492/// @return either the definition of the decl, or nil.
11493decl_base_sptr
11495{
11496 decl_base_sptr decl;
11499
11500 if (!decl)
11501 return decl;
11502
11503 while (decl->get_is_declaration_only()
11504 && decl->get_definition_of_declaration())
11505 decl = decl->get_definition_of_declaration();
11506
11507 return decl;
11508}
11509
11510/// If a decl is decl-only enum, get its definition. Otherwise, just
11511/// return the initial decl.
11512///
11513/// @param d the decl to consider.
11514///
11515/// @return either the definition of the enum, or the decl itself.
11516decl_base*
11518{
11519 if (!d)
11520 return d;
11521
11522 decl_base* result = look_through_decl_only(*d).get();
11523 if (!result)
11524 result = d;
11525
11526 return result;
11527}
11528
11529/// If a decl is decl-only get its definition. Otherwise, just return nil.
11530///
11531/// @param d the decl to consider.
11532///
11533/// @return either the definition of the decl, or nil.
11534decl_base_sptr
11535look_through_decl_only(const decl_base_sptr& d)
11536{
11537 if (!d)
11538 return d;
11539
11540 decl_base_sptr result = look_through_decl_only(*d);
11541 if (!result)
11542 result = d;
11543
11544 return result;
11545}
11546
11547/// If a type is is decl-only, then get its definition. Otherwise,
11548/// just return the initial type.
11549///
11550/// @param d the decl to consider.
11551///
11552/// @return either the definition of the decl, or the initial type.
11553type_base*
11555{
11556 decl_base* d = is_decl(t);
11557 if (!d)
11558 return t;
11560 return is_type(d);
11561}
11562
11563/// If a type is is decl-only, then get its definition. Otherwise,
11564/// just return the initial type.
11565///
11566/// @param d the decl to consider.
11567///
11568/// @return either the definition of the decl, or the initial type.
11569type_base_sptr
11570look_through_decl_only(const type_base_sptr& t)
11571{
11572 decl_base_sptr d = is_decl(t);
11573 if (!d)
11574 return t;
11576 return is_type(d);
11577}
11578
11579/// Tests if a declaration is a variable declaration.
11580///
11581/// @param decl the decl to test.
11582///
11583/// @return the var_decl_sptr iff decl is a variable declaration; nil
11584/// otherwise.
11585var_decl*
11587{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
11588
11589/// Tests if a declaration is a variable declaration.
11590///
11591/// @param decl the decl to test.
11592///
11593/// @return the var_decl_sptr iff decl is a variable declaration; nil
11594/// otherwise.
11597{return dynamic_pointer_cast<var_decl>(decl);}
11598
11599/// Tests if a declaration is a namespace declaration.
11600///
11601/// @param d the decalration to consider.
11602///
11603/// @return the namespace declaration if @p d is a namespace.
11605is_namespace(const decl_base_sptr& d)
11606{return dynamic_pointer_cast<namespace_decl>(d);}
11607
11608/// Tests if a declaration is a namespace declaration.
11609///
11610/// @param d the decalration to consider.
11611///
11612/// @return the namespace declaration if @p d is a namespace.
11615{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
11616
11617/// Tests whether a decl is a template parameter composition type.
11618///
11619/// @param decl the declaration to consider.
11620///
11621/// @return true iff decl is a template parameter composition type.
11622bool
11623is_template_parm_composition_type(const shared_ptr<decl_base> decl)
11624{
11625 return (decl
11626 && is_at_template_scope(decl)
11627 && is_type(decl)
11628 && !is_template_parameter(decl));
11629}
11630
11631/// Test whether a decl is the pattern of a function template.
11632///
11633/// @param decl the decl to consider.
11634///
11635/// @return true iff decl is the pattern of a function template.
11636bool
11637is_function_template_pattern(const shared_ptr<decl_base> decl)
11638{
11639 return (decl
11640 && dynamic_pointer_cast<function_decl>(decl)
11641 && dynamic_cast<template_decl*>(decl->get_scope()));
11642}
11643
11644/// Test if a type is an array_type_def.
11645///
11646/// @param type the type to consider.
11647///
11648/// @return true iff @p type is an array_type_def.
11651 bool look_through_qualifiers)
11652{
11653 const type_base* t = is_type(type);
11654
11655 if (look_through_qualifiers)
11656 t = peel_qualified_type(t);
11657 return dynamic_cast<array_type_def*>(const_cast<type_base*>(t));
11658}
11659
11660/// Test if a type is an array_type_def.
11661///
11662/// @param type the type to consider.
11663///
11664/// @return true iff @p type is an array_type_def.
11667 bool look_through_qualifiers)
11668{
11669 type_base_sptr t = is_type(type);
11670
11671 if (look_through_qualifiers)
11672 t = peel_qualified_type(t);
11673 return dynamic_pointer_cast<array_type_def>(t);
11674}
11675
11676/// Tests if the element of a given array is a qualified type.
11677///
11678/// @param array the array type to consider.
11679///
11680/// @return the qualified element of the array iff it's a qualified
11681/// type. Otherwise, return a nil object.
11682qualified_type_def_sptr
11684{
11685 if (!array)
11686 return qualified_type_def_sptr();
11687
11688 return is_qualified_type(array->get_element_type());
11689}
11690
11691/// Test if an array type is an array to a qualified element type.
11692///
11693/// @param type the array type to consider.
11694///
11695/// @return true the array @p type iff it's an array to a qualified
11696/// element type.
11698is_array_of_qualified_element(const type_base_sptr& type)
11699{
11700 if (array_type_def_sptr array = is_array_type(type))
11702 return array;
11703
11704 return array_type_def_sptr();
11705}
11706
11707/// Test if a type is a typedef of an array.
11708///
11709/// Note that the function looks through qualified and typedefs types
11710/// of the underlying type of the current typedef. In other words, if
11711/// we are looking at a typedef of a CV-qualified array, or at a
11712/// typedef of a CV-qualified typedef of an array, this function will
11713/// still return TRUE.
11714///
11715/// @param t the type to consider.
11716///
11717/// @return true if t is a typedef which underlying type is an array.
11718/// That array might be either cv-qualified array or a typedef'ed
11719/// array, or a combination of both.
11721is_typedef_of_array(const type_base_sptr& t)
11722{
11723 array_type_def_sptr result;
11724
11725 if (typedef_decl_sptr typdef = is_typedef(t))
11726 {
11727 type_base_sptr u =
11728 peel_qualified_or_typedef_type(typdef->get_underlying_type());
11729 result = is_array_type(u);
11730 }
11731
11732 return result;
11733}
11734
11735/// Test if a type is an array_type_def::subrange_type.
11736///
11737/// @param type the type to consider.
11738///
11739/// @return the array_type_def::subrange_type which @p type is a type
11740/// of, or nil if it's not of that type.
11741array_type_def::subrange_type*
11743{
11744 return dynamic_cast<array_type_def::subrange_type*>
11745 (const_cast<type_or_decl_base*>(type));
11746}
11747
11748/// Test if a type is an array_type_def::subrange_type.
11749///
11750/// @param type the type to consider.
11751///
11752/// @return the array_type_def::subrange_type which @p type is a type
11753/// of, or nil if it's not of that type.
11756{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
11757
11758/// Tests whether a decl is a template.
11759///
11760/// @param decl the decl to consider.
11761///
11762/// @return true iff decl is a function template, class template, or
11763/// template template parameter.
11764bool
11765is_template_decl(const decl_base_sptr& decl)
11766{return decl && dynamic_pointer_cast<template_decl>(decl);}
11767
11768/// This enum describe the kind of entity to lookup, while using the
11769/// lookup API.
11771{
11772 LOOKUP_ENTITY_TYPE,
11773 LOOKUP_ENTITY_VAR,
11774};
11775
11776/// Find the first relevant delimiter (the "::" string) in a fully
11777/// qualified C++ type name, starting from a given position. The
11778/// delimiter returned separates a type name from the name of its
11779/// context.
11780///
11781/// This is supposed to work correctly on names in cases like this:
11782///
11783/// foo<ns1::name1, ns2::name2>
11784///
11785/// In that case when called with with parameter @p begin set to 0, no
11786/// delimiter is returned, because the type name in this case is:
11787/// 'foo<ns1::name1, ns2::name2>'.
11788///
11789/// But in this case:
11790///
11791/// foo<p1, bar::name>::some_type
11792///
11793/// The "::" returned is the one right before 'some_type'.
11794///
11795/// @param fqn the fully qualified name of the type to consider.
11796///
11797/// @param begin the position from which to look for the delimiter.
11798///
11799/// @param delim_pos out parameter. Is set to the position of the
11800/// delimiter iff the function returned true.
11801///
11802/// @return true iff the function found and returned the delimiter.
11803static bool
11804find_next_delim_in_cplus_type(const string& fqn,
11805 size_t begin,
11806 size_t& delim_pos)
11807{
11808 int angle_count = 0;
11809 bool found = false;
11810 size_t i = begin;
11811 for (; i < fqn.size(); ++i)
11812 {
11813 if (fqn[i] == '<')
11814 ++angle_count;
11815 else if (fqn[i] == '>')
11816 --angle_count;
11817 else if (i + 1 < fqn.size()
11818 && !angle_count
11819 && fqn[i] == ':'
11820 && fqn[i+1] == ':')
11821 {
11822 delim_pos = i;
11823 found = true;
11824 break;
11825 }
11826 }
11827 return found;
11828}
11829
11830/// Decompose a fully qualified name into the list of its components.
11831///
11832/// @param fqn the fully qualified name to decompose.
11833///
11834/// @param comps the resulting list of component to fill.
11835void
11836fqn_to_components(const string& fqn,
11837 list<string>& comps)
11838{
11839 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
11840 do
11841 {
11842 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
11843 comp_end = fqn_size;
11844
11845 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
11846 comps.push_back(comp);
11847
11848 comp_begin = comp_end + 2;
11849 if (comp_begin >= fqn_size)
11850 break;
11851 } while (true);
11852}
11853
11854/// Turn a set of qualified name components (that name a type) into a
11855/// qualified name string.
11856///
11857/// @param comps the name components
11858///
11859/// @return the resulting string, which would be the qualified name of
11860/// a type.
11861string
11862components_to_type_name(const list<string>& comps)
11863{
11864 string result;
11865 for (list<string>::const_iterator c = comps.begin();
11866 c != comps.end();
11867 ++c)
11868 if (c == comps.begin())
11869 result = *c;
11870 else
11871 result += "::" + *c;
11872 return result;
11873}
11874
11875/// This predicate returns true if a given container iterator points
11876/// to the last element of the container, false otherwise.
11877///
11878/// @tparam T the type of the container of the iterator.
11879///
11880/// @param container the container the iterator points into.
11881///
11882/// @param i the iterator to consider.
11883///
11884/// @return true iff the iterator points to the last element of @p
11885/// container.
11886template<typename T>
11887static bool
11888iterator_is_last(T& container,
11889 typename T::const_iterator i)
11890{
11891 typename T::const_iterator next = i;
11892 ++next;
11893 return (next == container.end());
11894}
11895
11896//--------------------------------
11897// <type and decls lookup stuff>
11898// ------------------------------
11899
11900/// Lookup all the type*s* that have a given fully qualified name.
11901///
11902/// @param type_name the fully qualified name of the type to
11903/// lookup.
11904///
11905/// @param type_map the map to look into.
11906///
11907/// @return the vector containing the types named @p type_name. If
11908/// the lookup didn't yield any type, then this function returns nil.
11909static const type_base_wptrs_type*
11910lookup_types_in_map(const interned_string& type_name,
11911 const istring_type_base_wptrs_map_type& type_map)
11912{
11913 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
11914 if (i != type_map.end())
11915 return &i->second;
11916 return 0;
11917}
11918
11919/// Lookup a type (with a given name) in a map that associates a type
11920/// name to a type. If there are several types with a given name,
11921/// then try to return the first one that is not decl-only.
11922/// Otherwise, return the last of such types, that is, the last one
11923/// that got registered.
11924///
11925/// @tparam TypeKind the type of the type this function is supposed to
11926/// return.
11927///
11928/// @param type_name the name of the type to lookup.
11929///
11930/// @param type_map the map in which to look.
11931///
11932/// @return a shared_ptr to the type found. If no type was found or
11933/// if the type found was not of type @p TypeKind then the function
11934/// returns nil.
11935template <class TypeKind>
11936static shared_ptr<TypeKind>
11937lookup_type_in_map(const interned_string& type_name,
11938 const istring_type_base_wptrs_map_type& type_map)
11939{
11940 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
11941 if (i != type_map.end())
11942 {
11943 // Walk the types that have the name "type_name" and return the
11944 // first one that is not declaration-only ...
11945 for (auto j : i->second)
11946 {
11947 type_base_sptr t(j);
11948 decl_base_sptr d = is_decl(t);
11949 if (d && !d->get_is_declaration_only())
11950 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
11951 }
11952 // ... or return the last type with the name "type_name" that
11953 // was recorded. It's likely to be declaration-only if we
11954 // reached this point.
11955 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
11956 }
11957 return shared_ptr<TypeKind>();
11958}
11959
11960/// Lookup a basic type from a translation unit.
11961///
11962/// This is done by looking the type up in the type map that is
11963/// maintained in the translation unit. So this is as fast as
11964/// possible.
11965///
11966/// @param type_name the name of the basic type to look for.
11967///
11968/// @param tu the translation unit to look into.
11969///
11970/// @return the basic type found or nil if no basic type was found.
11973{
11974 return lookup_type_in_map<type_decl>(type_name,
11975 tu.get_types().basic_types());
11976}
11977
11978/// Lookup a basic type from a translation unit.
11979///
11980/// This is done by looking the type up in the type map that is
11981/// maintained in the translation unit. So this is as fast as
11982/// possible.
11983///
11984/// @param type_name the name of the basic type to look for.
11985///
11986/// @param tu the translation unit to look into.
11987///
11988/// @return the basic type found or nil if no basic type was found.
11990lookup_basic_type(const string& type_name, const translation_unit& tu)
11991{
11992 const environment& env = tu.get_environment();
11993
11994 interned_string s = env.intern(type_name);
11995 return lookup_basic_type(s, tu);
11996}
11997
11998/// Lookup a class type from a translation unit.
11999///
12000/// This is done by looking the type up in the type map that is
12001/// maintained in the translation unit. So this is as fast as
12002/// possible.
12003///
12004/// @param fqn the fully qualified name of the class type node to look
12005/// up.
12006///
12007/// @param tu the translation unit to perform lookup from.
12008///
12009/// @return the declaration of the class type IR node found, NULL
12010/// otherwise.
12012lookup_class_type(const string& fqn, const translation_unit& tu)
12013{
12014 const environment& env = tu.get_environment();
12015 interned_string s = env.intern(fqn);
12016 return lookup_class_type(s, tu);
12017}
12018
12019/// Lookup a class type from a translation unit.
12020///
12021/// This is done by looking the type up in the type map that is
12022/// maintained in the translation unit. So this is as fast as
12023/// possible.
12024///
12025/// @param type_name the name of the class type to look for.
12026///
12027/// @param tu the translation unit to look into.
12028///
12029/// @return the class type found or nil if no class type was found.
12032{
12033 return lookup_type_in_map<class_decl>(type_name,
12034 tu.get_types().class_types());
12035}
12036
12037/// Lookup a union type from a translation unit.
12038///
12039/// This is done by looking the type up in the type map that is
12040/// maintained in the translation unit. So this is as fast as
12041/// possible.
12042///
12043/// @param type_name the name of the union type to look for.
12044///
12045/// @param tu the translation unit to look into.
12046///
12047/// @return the union type found or nil if no union type was found.
12048union_decl_sptr
12050{
12051 return lookup_type_in_map<union_decl>(type_name,
12052 tu.get_types().union_types());
12053}
12054
12055/// Lookup a union type from a translation unit.
12056///
12057/// This is done by looking the type up in the type map that is
12058/// maintained in the translation unit. So this is as fast as
12059/// possible.
12060///
12061/// @param fqn the fully qualified name of the type to lookup.
12062///
12063/// @param tu the translation unit to look into.
12064///
12065/// @return the union type found or nil if no union type was found.
12066union_decl_sptr
12067lookup_union_type(const string& fqn, const translation_unit& tu)
12068{
12069 const environment& env = tu.get_environment();
12070 interned_string s = env.intern(fqn);
12071 return lookup_union_type(s, tu);
12072}
12073
12074/// Lookup a union type in a given corpus, from its location.
12075///
12076/// @param loc the location of the union type to look for.
12077///
12078/// @param corp the corpus to look it from.
12079///
12080/// @return the resulting union_decl.
12081union_decl_sptr
12083{
12086 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
12087
12088 return result;
12089}
12090
12091/// Lookup a union type in a given corpus, from its location.
12092///
12093/// @param loc the location of the union type to look for.
12094///
12095/// @param corp the corpus to look it from.
12096///
12097/// @return the resulting union_decl.
12098union_decl_sptr
12099lookup_union_type_per_location(const string& loc, const corpus& corp)
12100{
12101 const environment& env = corp.get_environment();
12102 return lookup_union_type_per_location(env.intern(loc), corp);
12103}
12104
12105/// Lookup an enum type from a translation unit.
12106///
12107/// This is done by looking the type up in the type map that is
12108/// maintained in the translation unit. So this is as fast as
12109/// possible.
12110///
12111/// @param type_name the name of the enum type to look for.
12112///
12113/// @param tu the translation unit to look into.
12114///
12115/// @return the enum type found or nil if no enum type was found.
12118{
12119 return lookup_type_in_map<enum_type_decl>(type_name,
12120 tu.get_types().enum_types());
12121}
12122
12123/// Lookup an enum type from a translation unit.
12124///
12125/// This is done by looking the type up in the type map that is
12126/// maintained in the translation unit. So this is as fast as
12127/// possible.
12128///
12129/// @param type_name the name of the enum type to look for.
12130///
12131/// @param tu the translation unit to look into.
12132///
12133/// @return the enum type found or nil if no enum type was found.
12135lookup_enum_type(const string& type_name, const translation_unit& tu)
12136{
12137 const environment& env = tu.get_environment();
12138 interned_string s = env.intern(type_name);
12139 return lookup_enum_type(s, tu);
12140}
12141
12142/// Lookup a typedef type from a translation unit.
12143///
12144/// This is done by looking the type up in the type map that is
12145/// maintained in the translation unit. So this is as fast as
12146/// possible.
12147///
12148/// @param type_name the name of the typedef type to look for.
12149///
12150/// @param tu the translation unit to look into.
12151///
12152/// @return the typedef type found or nil if no typedef type was
12153/// found.
12156 const translation_unit& tu)
12157{
12158 return lookup_type_in_map<typedef_decl>(type_name,
12159 tu.get_types().typedef_types());
12160}
12161
12162/// Lookup a typedef type from a translation unit.
12163///
12164/// This is done by looking the type up in the type map that is
12165/// maintained in the translation unit. So this is as fast as
12166/// possible.
12167///
12168/// @param type_name the name of the typedef type to look for.
12169///
12170/// @param tu the translation unit to look into.
12171///
12172/// @return the typedef type found or nil if no typedef type was
12173/// found.
12175lookup_typedef_type(const string& type_name, const translation_unit& tu)
12176{
12177 const environment& env = tu.get_environment();
12178 interned_string s = env.intern(type_name);
12179 return lookup_typedef_type(s, tu);
12180}
12181
12182/// Lookup a qualified type from a translation unit.
12183///
12184/// This is done by looking the type up in the type map that is
12185/// maintained in the translation unit. So this is as fast as
12186/// possible.
12187///
12188/// @param type_name the name of the qualified type to look for.
12189///
12190/// @param tu the translation unit to look into.
12191///
12192/// @return the qualified type found or nil if no qualified type was
12193/// found.
12194qualified_type_def_sptr
12196 const translation_unit& tu)
12197{
12198 const type_maps& m = tu.get_types();
12199 return lookup_type_in_map<qualified_type_def>(type_name,
12200 m.qualified_types());
12201}
12202
12203/// Lookup a qualified type from a translation unit.
12204///
12205/// This is done by looking the type up in the type map that is
12206/// maintained in the translation unit. So this is as fast as
12207/// possible.
12208///
12209/// @param underlying_type the underying type of the qualified type to
12210/// look up.
12211///
12212/// @param quals the CV-qualifiers of the qualified type to look for.
12213///
12214/// @param tu the translation unit to look into.
12215///
12216/// @return the qualified type found or nil if no qualified type was
12217/// found.
12218qualified_type_def_sptr
12219lookup_qualified_type(const type_base_sptr& underlying_type,
12221 const translation_unit& tu)
12222{
12223 interned_string type_name = get_name_of_qualified_type(underlying_type,
12224 quals);
12225 return lookup_qualified_type(type_name, tu);
12226}
12227
12228/// Lookup a pointer type from a translation unit.
12229///
12230/// This is done by looking the type up in the type map that is
12231/// maintained in the translation unit. So this is as fast as
12232/// possible.
12233///
12234/// @param type_name the name of the pointer type to look for.
12235///
12236/// @param tu the translation unit to look into.
12237///
12238/// @return the pointer type found or nil if no pointer type was
12239/// found.
12242 const translation_unit& tu)
12243{
12244 const type_maps& m = tu.get_types();
12245 return lookup_type_in_map<pointer_type_def>(type_name,
12246 m.pointer_types());
12247}
12248
12249/// Lookup a pointer type from a translation unit.
12250///
12251/// This is done by looking the type up in the type map that is
12252/// maintained in the translation unit. So this is as fast as
12253/// possible.
12254///
12255/// @param type_name the name of the pointer type to look for.
12256///
12257/// @param tu the translation unit to look into.
12258///
12259/// @return the pointer type found or nil if no pointer type was
12260/// found.
12262lookup_pointer_type(const string& type_name, const translation_unit& tu)
12263{
12264 const environment& env = tu.get_environment();
12265 interned_string s = env.intern(type_name);
12266 return lookup_pointer_type(s, tu);
12267}
12268
12269/// Lookup a pointer type from a translation unit.
12270///
12271/// This is done by looking the type up in the type map that is
12272/// maintained in the translation unit. So this is as fast as
12273/// possible.
12274///
12275/// @param pointed_to_type the pointed-to-type of the pointer to look for.
12276///
12277/// @param tu the translation unit to look into.
12278///
12279/// @return the pointer type found or nil if no pointer type was
12280/// found.
12282lookup_pointer_type(const type_base_sptr& pointed_to_type,
12283 const translation_unit& tu)
12284{
12285 type_base_sptr t = look_through_decl_only(pointed_to_type);
12287 return lookup_pointer_type(type_name, tu);
12288}
12289
12290/// Lookup a reference type from a translation unit.
12291///
12292/// This is done by looking the type up in the type map that is
12293/// maintained in the translation unit. So this is as fast as
12294/// possible.
12295///
12296/// @param type_name the name of the reference type to look for.
12297///
12298/// @param tu the translation unit to look into.
12299///
12300/// @return the reference type found or nil if no reference type was
12301/// found.
12304 const translation_unit& tu)
12305{
12306 const type_maps& m = tu.get_types();
12307 return lookup_type_in_map<reference_type_def>(type_name,
12308 m.reference_types());
12309}
12310
12311/// Lookup a reference type from a translation unit.
12312///
12313/// This is done by looking the type up in the type map that is
12314/// maintained in the translation unit. So this is as fast as
12315/// possible.
12316///
12317/// @param pointed_to_type the pointed-to-type of the reference to
12318/// look up.
12319///
12320/// @param tu the translation unit to look into.
12321///
12322/// @return the reference type found or nil if no reference type was
12323/// found.
12325lookup_reference_type(const type_base_sptr& pointed_to_type,
12326 bool lvalue_reference,
12327 const translation_unit& tu)
12328{
12329 interned_string type_name =
12331 lvalue_reference);
12332 return lookup_reference_type(type_name, tu);
12333}
12334
12335/// Lookup an array type from a translation unit.
12336///
12337/// This is done by looking the type up in the type map that is
12338/// maintained in the translation unit. So this is as fast as
12339/// possible.
12340///
12341/// @param type_name the name of the array type to look for.
12342///
12343/// @param tu the translation unit to look into.
12344///
12345/// @return the array type found or nil if no array type was found.
12348 const translation_unit& tu)
12349{
12350 const type_maps& m = tu.get_types();
12351 return lookup_type_in_map<array_type_def>(type_name,
12352 m.array_types());
12353}
12354
12355/// Lookup a function type from a translation unit.
12356///
12357/// This is done by looking the type up in the type map that is
12358/// maintained in the translation unit. So this is as fast as
12359/// possible.
12360///
12361/// @param type_name the name of the type to lookup.
12362///
12363/// @param tu the translation unit to look into.
12364///
12365/// @return the function type found, or NULL of none was found.
12368 const translation_unit& tu)
12369{
12370 const type_maps& m = tu.get_types();
12371 return lookup_type_in_map<function_type>(type_name,
12372 m.function_types());
12373}
12374
12375/// Lookup a function type from a translation unit.
12376///
12377/// This walks all the function types held by the translation unit and
12378/// compare their sub-type *names*. If the names match then return
12379/// the function type found in the translation unit.
12380///
12381/// @param t the function type to look for.
12382///
12383/// @param tu the translation unit to look into.
12384///
12385/// @return the function type found, or NULL of none was found.
12388 const translation_unit& tu)
12389{
12390 interned_string type_name = get_type_name(t);
12391 return lookup_function_type(type_name, tu);
12392}
12393
12394/// Lookup a function type from a translation unit.
12395///
12396/// This is done by looking the type up in the type map that is
12397/// maintained in the translation unit. So this is as fast as
12398/// possible.
12399///
12400/// @param t the function type to look for.
12401///
12402/// @param tu the translation unit to look into.
12403///
12404/// @return the function type found, or NULL of none was found.
12407 const translation_unit& tu)
12408{return lookup_function_type(*t, tu);}
12409
12410/// Lookup a type in a translation unit.
12411///
12412/// @param fqn the fully qualified name of the type to lookup.
12413///
12414/// @param tu the translation unit to consider.
12415///
12416/// @return the declaration of the type if found, NULL otherwise.
12417const type_base_sptr
12419 const translation_unit& tu)
12420{
12421 type_base_sptr result;
12422 ((result = lookup_typedef_type(fqn, tu))
12423 || (result = lookup_class_type(fqn, tu))
12424 || (result = lookup_union_type(fqn, tu))
12425 || (result = lookup_enum_type(fqn, tu))
12426 || (result = lookup_qualified_type(fqn, tu))
12427 || (result = lookup_pointer_type(fqn, tu))
12428 || (result = lookup_reference_type(fqn, tu))
12429 || (result = lookup_array_type(fqn, tu))
12430 || (result = lookup_function_type(fqn, tu))
12431 || (result = lookup_basic_type(fqn, tu)));
12432
12433 return result;
12434}
12435
12436/// Lookup a type in a translation unit, starting from the global
12437/// namespace.
12438///
12439/// @param fqn the fully qualified name of the type to lookup.
12440///
12441/// @param tu the translation unit to consider.
12442///
12443/// @return the declaration of the type if found, NULL otherwise.
12444type_base_sptr
12445lookup_type(const string& fqn, const translation_unit& tu)
12446{
12447 const environment&env = tu.get_environment();
12448 interned_string ifqn = env.intern(fqn);
12449 return lookup_type(ifqn, tu);
12450}
12451
12452/// Lookup a type from a translation unit.
12453///
12454/// @param fqn the components of the fully qualified name of the node
12455/// to look up.
12456///
12457/// @param tu the translation unit to perform lookup from.
12458///
12459/// @return the declaration of the IR node found, NULL otherwise.
12460const type_base_sptr
12461lookup_type(const type_base_sptr type,
12462 const translation_unit& tu)
12463{
12464 interned_string type_name = get_type_name(type);
12465 return lookup_type(type_name, tu);
12466}
12467
12468/// Lookup a type in a scope.
12469///
12470/// This is really slow as it walks the member types of the scope in
12471/// sequence to find the type with a given name.
12472///
12473/// If possible, users should prefer looking up types from the
12474/// enclosing translation unit or even ABI corpus because both the
12475/// translation unit and the corpus have a map of type, indexed by
12476/// their name. Looking up a type from those maps is thus much
12477/// faster.
12478///
12479/// @param fqn the fully qualified name of the type to lookup.
12480///
12481/// @param skope the scope to look into.
12482///
12483/// @return the declaration of the type if found, NULL otherwise.
12484const type_base_sptr
12485lookup_type_in_scope(const string& fqn,
12486 const scope_decl_sptr& skope)
12487{
12488 list<string> comps;
12489 fqn_to_components(fqn, comps);
12490 return lookup_type_in_scope(comps, skope);
12491}
12492
12493/// Lookup a @ref var_decl in a scope.
12494///
12495/// @param fqn the fuly qualified name of the @var_decl to lookup.
12496///
12497/// @param skope the scope to look into.
12498///
12499/// @return the declaration of the @ref var_decl if found, NULL
12500/// otherwise.
12501const decl_base_sptr
12503 const scope_decl_sptr& skope)
12504{
12505 list<string> comps;
12506 fqn_to_components(fqn, comps);
12507 return lookup_var_decl_in_scope(comps, skope);
12508}
12509
12510/// A generic function (template) to get the name of a node, whatever
12511/// node it is. This has to be specialized for the kind of node we
12512/// want.
12513///
12514/// Note that a node is a member of a scope.
12515///
12516/// @tparam NodeKind the kind of node to consider.
12517///
12518/// @param node the node to get the name from.
12519///
12520/// @return the name of the node.
12521template<typename NodeKind>
12522static const interned_string&
12523get_node_name(shared_ptr<NodeKind> node);
12524
12525/// Gets the name of a class_decl node.
12526///
12527/// @param node the decl_base node to get the name from.
12528///
12529/// @return the name of the node.
12530template<>
12531const interned_string&
12533{return node->get_name();}
12534
12535/// Gets the name of a type_base node.
12536///
12537/// @param node the type_base node to get the name from.
12538///
12539/// @return the name of the node.
12540template<>
12541const interned_string&
12542get_node_name(type_base_sptr node)
12543{return get_type_declaration(node)->get_name();}
12544
12545/// Gets the name of a var_decl node.
12546///
12547/// @param node the var_decl node to get the name from.
12548///
12549/// @return the name of the node.
12550template<>
12551const interned_string&
12553{return node->get_name();}
12554
12555/// Generic function to get the declaration of a given node, whatever
12556/// it is. There has to be specializations for the kind of the nodes
12557/// we want to support.
12558///
12559/// @tparam NodeKind the type of the node we are looking at.
12560///
12561/// @return the declaration.
12562template<typename NodeKind>
12563static decl_base_sptr
12564convert_node_to_decl(shared_ptr<NodeKind> node);
12565
12566/// Lookup a node in a given scope.
12567///
12568/// @tparam the type of the node to lookup.
12569///
12570/// @param fqn the components of the fully qualified name of the node
12571/// to lookup.
12572///
12573/// @param skope the scope to look into.
12574///
12575/// @return the declaration of the looked up node, or NULL if it
12576/// wasn't found.
12577template<typename NodeKind>
12578static const type_or_decl_base_sptr
12579lookup_node_in_scope(const list<string>& fqn,
12580 const scope_decl_sptr& skope)
12581{
12582 type_or_decl_base_sptr resulting_decl;
12583 shared_ptr<NodeKind> node;
12584 bool it_is_last = false;
12585 scope_decl_sptr cur_scope = skope, new_scope, scope;
12586
12587 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
12588 {
12589 new_scope.reset();
12590 it_is_last = iterator_is_last(fqn, c);
12591 for (scope_decl::declarations::const_iterator m =
12592 cur_scope->get_member_decls().begin();
12593 m != cur_scope->get_member_decls().end();
12594 ++m)
12595 {
12596 if (!it_is_last)
12597 {
12598 // looking for a scope
12599 scope = dynamic_pointer_cast<scope_decl>(*m);
12600 if (scope && scope->get_name() == *c)
12601 {
12602 new_scope = scope;
12603 break;
12604 }
12605 }
12606 else
12607 {
12608 //looking for a final type.
12609 node = dynamic_pointer_cast<NodeKind>(*m);
12610 if (node && get_node_name(node) == *c)
12611 {
12612 if (class_decl_sptr cl =
12613 dynamic_pointer_cast<class_decl>(node))
12614 if (cl->get_is_declaration_only()
12615 && !cl->get_definition_of_declaration())
12616 continue;
12617 resulting_decl = node;
12618 break;
12619 }
12620 }
12621 }
12622 if (!new_scope && !resulting_decl)
12623 return decl_base_sptr();
12624 cur_scope = new_scope;
12625 }
12626 ABG_ASSERT(resulting_decl);
12627 return resulting_decl;
12628}
12629
12630/// lookup a type in a scope.
12631///
12632///
12633/// This is really slow as it walks the member types of the scope in
12634/// sequence to find the type with a given name.
12635///
12636/// If possible, users should prefer looking up types from the
12637/// enclosing translation unit or even ABI corpus because both the
12638/// translation unit and the corpus have a map of type, indexed by
12639/// their name. Looking up a type from those maps is thus much
12640/// faster.
12641///
12642/// @param comps the components of the fully qualified name of the
12643/// type to lookup.
12644///
12645/// @param skope the scope to look into.
12646///
12647/// @return the declaration of the type found.
12648const type_base_sptr
12649lookup_type_in_scope(const list<string>& comps,
12650 const scope_decl_sptr& scope)
12651{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
12652
12653/// lookup a type in a scope.
12654///
12655/// This is really slow as it walks the member types of the scope in
12656/// sequence to find the type with a given name.
12657///
12658/// If possible, users should prefer looking up types from the
12659/// enclosing translation unit or even ABI corpus because both the
12660/// translation unit and the corpus have a map of type, indexed by
12661/// their name. Looking up a type from those maps is thus much
12662/// faster.
12663///
12664/// @param type the type to look for.
12665///
12666/// @param access_path a vector of scopes the path of scopes to follow
12667/// before reaching the scope into which to look for @p type. Note
12668/// that the deepest scope (the one immediately containing @p type) is
12669/// at index 0 of this vector, and the top-most scope is the last
12670/// element of the vector.
12671///
12672/// @param scope the top-most scope into which to look for @p type.
12673///
12674/// @return the scope found in @p scope, or NULL if it wasn't found.
12675static const type_base_sptr
12677 const vector<scope_decl*>& access_path,
12678 const scope_decl* scope)
12679{
12680 vector<scope_decl*> a = access_path;
12681 type_base_sptr result;
12682
12683 scope_decl* first_scope = 0;
12684 if (!a.empty())
12685 {
12686 first_scope = a.back();
12687 ABG_ASSERT(first_scope->get_name() == scope->get_name());
12688 a.pop_back();
12689 }
12690
12691 if (a.empty())
12692 {
12693 interned_string n = get_type_name(type, false);
12694 for (scope_decl::declarations::const_iterator i =
12695 scope->get_member_decls().begin();
12696 i != scope->get_member_decls().end();
12697 ++i)
12698 if (is_type(*i) && (*i)->get_name() == n)
12699 {
12700 result = is_type(*i);
12701 break;
12702 }
12703 }
12704 else
12705 {
12706 first_scope = a.back();
12707 interned_string scope_name, cur_scope_name = first_scope->get_name();
12708 for (scope_decl::scopes::const_iterator i =
12709 scope->get_member_scopes().begin();
12710 i != scope->get_member_scopes().end();
12711 ++i)
12712 {
12713 scope_name = (*i)->get_name();
12714 if (scope_name == cur_scope_name)
12715 {
12716 result = lookup_type_in_scope(type, a, (*i).get());
12717 break;
12718 }
12719 }
12720 }
12721 return result;
12722}
12723
12724/// lookup a type in a scope.
12725///
12726/// This is really slow as it walks the member types of the scope in
12727/// sequence to find the type with a given name.
12728///
12729/// If possible, users should prefer looking up types from the
12730/// enclosing translation unit or even ABI corpus because both the
12731/// translation unit and the corpus have a map of type, indexed by
12732/// their name. Looking up a type from those maps is thus much
12733/// faster.
12734///
12735/// @param type the type to look for.
12736///
12737/// @param scope the top-most scope into which to look for @p type.
12738///
12739/// @return the scope found in @p scope, or NULL if it wasn't found.
12740static const type_base_sptr
12741lookup_type_in_scope(const type_base_sptr type,
12742 const scope_decl* scope)
12743{
12744 if (!type || is_function_type(type))
12745 return type_base_sptr();
12746
12747 decl_base_sptr type_decl = get_type_declaration(type);
12748 ABG_ASSERT(type_decl);
12749 vector<scope_decl*> access_path;
12750 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
12751 {
12752 access_path.push_back(s);
12753 if (is_global_scope(s))
12754 break;
12755 }
12756 return lookup_type_in_scope(*type, access_path, scope);
12757}
12758
12759/// Lookup a type from a translation unit by walking the scopes of the
12760/// translation unit in sequence and looking into them.
12761///
12762/// This is really slow as it walks the member types of the scopes in
12763/// sequence to find the type with a given name.
12764///
12765/// If possible, users should prefer looking up types from the
12766/// translation unit or even ABI corpus in a more direct way, by using
12767/// the lookup_type() functins.
12768///
12769///
12770/// This is because both the translation unit and the corpus have a
12771/// map of types, indexed by their name. Looking up a type from those
12772/// maps is thus much faster. @param fqn the components of the fully
12773/// qualified name of the node to look up.
12774///
12775/// @param tu the translation unit to perform lookup from.
12776///
12777/// @return the declaration of the IR node found, NULL otherwise.
12778const type_base_sptr
12779lookup_type_through_scopes(const type_base_sptr type,
12780 const translation_unit& tu)
12781{
12782 if (function_type_sptr fn_type = is_function_type(type))
12783 return lookup_function_type(fn_type, tu);
12784 return lookup_type_in_scope(type, tu.get_global_scope().get());
12785}
12786
12787/// lookup a var_decl in a scope.
12788///
12789/// @param comps the components of the fully qualified name of the
12790/// var_decl to lookup.
12791///
12792/// @param skope the scope to look into.
12793const decl_base_sptr
12794lookup_var_decl_in_scope(const std::list<string>& comps,
12795 const scope_decl_sptr& skope)
12796{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
12797
12798/// Lookup an IR node from a translation unit.
12799///
12800/// @tparam NodeKind the type of the IR node to lookup from the
12801/// translation unit.
12802///
12803/// @param fqn the components of the fully qualified name of the node
12804/// to look up.
12805///
12806/// @param tu the translation unit to perform lookup from.
12807///
12808/// @return the declaration of the IR node found, NULL otherwise.
12809template<typename NodeKind>
12810static const type_or_decl_base_sptr
12811lookup_node_in_translation_unit(const list<string>& fqn,
12812 const translation_unit& tu)
12813{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
12814
12815/// Lookup a type from a translation unit by walking its scopes in
12816/// sequence and by looking into them.
12817///
12818/// This is much slower than using the lookup_type() function.
12819///
12820/// @param fqn the components of the fully qualified name of the node
12821/// to look up.
12822///
12823/// @param tu the translation unit to perform lookup from.
12824///
12825/// @return the declaration of the IR node found, NULL otherwise.
12826type_base_sptr
12827lookup_type_through_scopes(const list<string>& fqn,
12828 const translation_unit& tu)
12829{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
12830
12831
12832/// Lookup a class type from a translation unit by walking its scopes
12833/// in sequence and by looking into them.
12834///
12835/// This is much slower than using the lookup_class_type() function
12836/// because it walks all the scopes of the translation unit in
12837/// sequence and lookup the types to find one that has a given name.
12838///
12839/// @param fqn the components of the fully qualified name of the class
12840/// type node to look up.
12841///
12842/// @param tu the translation unit to perform lookup from.
12843///
12844/// @return the declaration of the class type IR node found, NULL
12845/// otherwise.
12847lookup_class_type_through_scopes(const list<string>& fqn,
12848 const translation_unit& tu)
12849{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
12850
12851/// Lookup a basic type from all the translation units of a given
12852/// corpus.
12853///
12854/// @param fqn the components of the fully qualified name of the basic
12855/// type node to look up.
12856///
12857/// @param tu the translation unit to perform lookup from.
12858///
12859/// @return the declaration of the basic type IR node found, NULL
12860/// otherwise.
12861static type_decl_sptr
12862lookup_basic_type_through_translation_units(const interned_string& type_name,
12863 const corpus& abi_corpus)
12864{
12865 type_decl_sptr result;
12866
12867 for (translation_units::const_iterator tu =
12868 abi_corpus.get_translation_units().begin();
12869 tu != abi_corpus.get_translation_units().end();
12870 ++tu)
12871 if ((result = lookup_basic_type(type_name, **tu)))
12872 break;
12873
12874 return result;
12875}
12876
12877/// Lookup a union type from all the translation units of a given
12878/// corpus.
12879///
12880/// @param fqn the components of the fully qualified name of the union
12881/// type node to look up.
12882///
12883/// @param tu the translation unit to perform lookup from.
12884///
12885/// @return the declaration of the union type IR node found, NULL
12886/// otherwise.
12887static union_decl_sptr
12888lookup_union_type_through_translation_units(const interned_string& type_name,
12889 const corpus & abi_corpus)
12890{
12891 union_decl_sptr result;
12892
12893 for (translation_units::const_iterator tu =
12894 abi_corpus.get_translation_units().begin();
12895 tu != abi_corpus.get_translation_units().end();
12896 ++tu)
12897 if ((result = lookup_union_type(type_name, **tu)))
12898 break;
12899
12900 return result;
12901}
12902
12903/// Lookup an enum type from all the translation units of a given
12904/// corpus.
12905///
12906/// @param fqn the components of the fully qualified name of the enum
12907/// type node to look up.
12908///
12909/// @param tu the translation unit to perform lookup from.
12910///
12911/// @return the declaration of the enum type IR node found, NULL
12912/// otherwise.
12914lookup_enum_type_through_translation_units(const interned_string& type_name,
12915 const corpus & abi_corpus)
12916{
12917 enum_type_decl_sptr result;
12918
12919 for (translation_units::const_iterator tu =
12920 abi_corpus.get_translation_units().begin();
12921 tu != abi_corpus.get_translation_units().end();
12922 ++tu)
12923 if ((result = lookup_enum_type(type_name, **tu)))
12924 break;
12925
12926 return result;
12927}
12928
12929/// Lookup a typedef type definition in all the translation units of a
12930/// given ABI corpus.
12931///
12932/// @param @param qn the fully qualified name of the typedef type to lookup.
12933///
12934/// @param abi_corpus the ABI corpus which to look the type up in.
12935///
12936/// @return the type definition if any was found, or a NULL pointer.
12937static typedef_decl_sptr
12938lookup_typedef_type_through_translation_units(const interned_string& type_name,
12939 const corpus & abi_corpus)
12940{
12941 typedef_decl_sptr result;
12942
12943 for (translation_units::const_iterator tu =
12944 abi_corpus.get_translation_units().begin();
12945 tu != abi_corpus.get_translation_units().end();
12946 ++tu)
12947 if ((result = lookup_typedef_type(type_name, **tu)))
12948 break;
12949
12950 return result;
12951}
12952
12953/// Lookup a qualified type definition in all the translation units of a
12954/// given ABI corpus.
12955///
12956/// @param @param qn the fully qualified name of the qualified type to
12957/// lookup.
12958///
12959/// @param abi_corpus the ABI corpus which to look the type up in.
12960///
12961/// @return the type definition if any was found, or a NULL pointer.
12962static qualified_type_def_sptr
12963lookup_qualified_type_through_translation_units(const interned_string& t_name,
12964 const corpus & abi_corpus)
12965{
12966 qualified_type_def_sptr result;
12967
12968 for (translation_units::const_iterator tu =
12969 abi_corpus.get_translation_units().begin();
12970 tu != abi_corpus.get_translation_units().end();
12971 ++tu)
12972 if ((result = lookup_qualified_type(t_name, **tu)))
12973 break;
12974
12975 return result;
12976}
12977
12978/// Lookup a pointer type definition in all the translation units of a
12979/// given ABI corpus.
12980///
12981/// @param @param qn the fully qualified name of the pointer type to
12982/// lookup.
12983///
12984/// @param abi_corpus the ABI corpus which to look the type up in.
12985///
12986/// @return the type definition if any was found, or a NULL pointer.
12988lookup_pointer_type_through_translation_units(const interned_string& type_name,
12989 const corpus & abi_corpus)
12990{
12991 pointer_type_def_sptr result;
12992
12993 for (translation_units::const_iterator tu =
12994 abi_corpus.get_translation_units().begin();
12995 tu != abi_corpus.get_translation_units().end();
12996 ++tu)
12997 if ((result = lookup_pointer_type(type_name, **tu)))
12998 break;
12999
13000 return result;
13001}
13002
13003/// Lookup a reference type definition in all the translation units of a
13004/// given ABI corpus.
13005///
13006/// @param @param qn the fully qualified name of the reference type to
13007/// lookup.
13008///
13009/// @param abi_corpus the ABI corpus which to look the type up in.
13010///
13011/// @return the type definition if any was found, or a NULL pointer.
13013lookup_reference_type_through_translation_units(const interned_string& t_name,
13014 const corpus & abi_corpus)
13015{
13017
13018 for (translation_units::const_iterator tu =
13019 abi_corpus.get_translation_units().begin();
13020 tu != abi_corpus.get_translation_units().end();
13021 ++tu)
13022 if ((result = lookup_reference_type(t_name, **tu)))
13023 break;
13024
13025 return result;
13026}
13027
13028/// Lookup a array type definition in all the translation units of a
13029/// given ABI corpus.
13030///
13031/// @param @param qn the fully qualified name of the array type to
13032/// lookup.
13033///
13034/// @param abi_corpus the ABI corpus which to look the type up in.
13035///
13036/// @return the type definition if any was found, or a NULL pointer.
13038lookup_array_type_through_translation_units(const interned_string& type_name,
13039 const corpus & abi_corpus)
13040{
13041 array_type_def_sptr result;
13042
13043 for (translation_units::const_iterator tu =
13044 abi_corpus.get_translation_units().begin();
13045 tu != abi_corpus.get_translation_units().end();
13046 ++tu)
13047 if ((result = lookup_array_type(type_name, **tu)))
13048 break;
13049
13050 return result;
13051}
13052
13053/// Lookup a function type definition in all the translation units of
13054/// a given ABI corpus.
13055///
13056/// @param @param qn the fully qualified name of the function type to
13057/// lookup.
13058///
13059/// @param abi_corpus the ABI corpus which to look the type up in.
13060///
13061/// @return the type definition if any was found, or a NULL pointer.
13062static function_type_sptr
13063lookup_function_type_through_translation_units(const interned_string& type_name,
13064 const corpus & abi_corpus)
13065{
13066 function_type_sptr result;
13067
13068 for (translation_units::const_iterator tu =
13069 abi_corpus.get_translation_units().begin();
13070 tu != abi_corpus.get_translation_units().end();
13071 ++tu)
13072 if ((result = lookup_function_type(type_name, **tu)))
13073 break;
13074
13075 return result;
13076}
13077
13078/// Lookup a type definition in all the translation units of a given
13079/// ABI corpus.
13080///
13081/// @param @param qn the fully qualified name of the type to lookup.
13082///
13083/// @param abi_corpus the ABI corpus which to look the type up in.
13084///
13085/// @return the type definition if any was found, or a NULL pointer.
13086type_base_sptr
13088 const corpus& abi_corpus)
13089{
13090 type_base_sptr result;
13091
13092 for (translation_units::const_iterator tu =
13093 abi_corpus.get_translation_units().begin();
13094 tu != abi_corpus.get_translation_units().end();
13095 ++tu)
13096 if ((result = lookup_type(qn, **tu)))
13097 break;
13098
13099 return result;
13100}
13101
13102/// Lookup a type from a given translation unit present in a give corpus.
13103///
13104/// @param type_name the name of the type to look for.
13105///
13106/// @parm tu_path the path of the translation unit to consider.
13107///
13108/// @param corp the corpus to consider.
13109///
13110/// @return the resulting type, if any.
13111type_base_sptr
13113 const string& tu_path,
13114 const corpus& corp)
13115{
13116 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
13117 if (i == corp.priv_->path_tu_map.end())
13118 return type_base_sptr();
13119
13120 translation_unit_sptr tu = i->second;
13121 ABG_ASSERT(tu);
13122
13123 type_base_sptr t = lookup_type(type_name, *tu);
13124 return t;
13125}
13126
13127/// Look into an ABI corpus for a function type.
13128///
13129/// @param fn_type the function type to be looked for in the ABI
13130/// corpus.
13131///
13132/// @param corpus the ABI corpus into which to look for the function
13133/// type.
13134///
13135/// @return the function type found in the corpus.
13138 const corpus& corpus)
13139{
13140 ABG_ASSERT(fn_t);
13141
13142 function_type_sptr result;
13143
13144 if ((result = lookup_function_type(fn_t, corpus)))
13145 return result;
13146
13147 for (translation_units::const_iterator i =
13148 corpus.get_translation_units().begin();
13149 i != corpus.get_translation_units().end();
13150 ++i)
13152 **i)))
13153 return result;
13154
13155 return result;
13156}
13157
13158/// Look into a given corpus to find a type which has the same
13159/// qualified name as a giventype.
13160///
13161/// If the per-corpus type map is non-empty (because the corpus allows
13162/// the One Definition Rule) then the type islooked up in that
13163/// per-corpus type map. Otherwise, the type is looked-up in each
13164/// translation unit.
13165///
13166/// @param t the type which has the same qualified name as the type we
13167/// are looking for.
13168///
13169/// @param corp the ABI corpus to look into for the type.
13171lookup_basic_type(const type_decl& t, const corpus& corp)
13172{return lookup_basic_type(t.get_name(), corp);}
13173
13174/// Look into a given corpus to find a basic type which has a given
13175/// qualified name.
13176///
13177/// If the per-corpus type map is non-empty (because the corpus allows
13178/// the One Definition Rule) then the type islooked up in that
13179/// per-corpus type map. Otherwise, the type is looked-up in each
13180/// translation unit.
13181///
13182/// @param qualified_name the qualified name of the basic type to look
13183/// for.
13184///
13185/// @param corp the corpus to look into.
13187lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
13188{
13190 type_decl_sptr result;
13191
13192 if (!m.empty())
13193 result = lookup_type_in_map<type_decl>(qualified_name, m);
13194 else
13195 result = lookup_basic_type_through_translation_units(qualified_name, corp);
13196
13197 return result;
13198}
13199
13200/// Lookup a @ref type_decl type from a given corpus, by its location.
13201///
13202/// @param loc the location to consider.
13203///
13204/// @param corp the corpus to consider.
13205///
13206/// @return the resulting basic type, if any.
13209 const corpus &corp)
13210{
13213 type_decl_sptr result;
13214
13215 result = lookup_type_in_map<type_decl>(loc, m);
13216
13217 return result;
13218}
13219
13220/// Lookup a @ref type_decl type from a given corpus, by its location.
13221///
13222/// @param loc the location to consider.
13223///
13224/// @param corp the corpus to consider.
13225///
13226/// @return the resulting basic type, if any.
13228lookup_basic_type_per_location(const string &loc, const corpus &corp)
13229{
13230 const environment& env = corp.get_environment();
13231 return lookup_basic_type_per_location(env.intern(loc), corp);
13232}
13233
13234/// Look into a given corpus to find a basic type which has a given
13235/// qualified name.
13236///
13237/// If the per-corpus type map is non-empty (because the corpus allows
13238/// the One Definition Rule) then the type islooked up in that
13239/// per-corpus type map. Otherwise, the type is looked-up in each
13240/// translation unit.
13241///
13242/// @param qualified_name the qualified name of the basic type to look
13243/// for.
13244///
13245/// @param corp the corpus to look into.
13247lookup_basic_type(const string& qualified_name, const corpus& corp)
13248{
13249 return lookup_basic_type(corp.get_environment().intern(qualified_name),
13250 corp);
13251}
13252
13253/// Look into a given corpus to find a class type which has the same
13254/// qualified name as a given type.
13255///
13256/// If the per-corpus type map is non-empty (because the corpus allows
13257/// the One Definition Rule) then the type islooked up in that
13258/// per-corpus type map. Otherwise, the type is looked-up in each
13259/// translation unit.
13260///
13261/// @param t the class decl type which has the same qualified name as
13262/// the type we are looking for.
13263///
13264/// @param corp the corpus to look into.
13267{
13269 return lookup_class_type(s, corp);
13270}
13271
13272/// Look into a given corpus to find a class type which has a given
13273/// qualified name.
13274///
13275/// If the per-corpus type map is non-empty (because the corpus allows
13276/// the One Definition Rule) then the type islooked up in that
13277/// per-corpus type map. Otherwise, the type is looked-up in each
13278/// translation unit.
13279///
13280/// @param qualified_name the qualified name of the type to look for.
13281///
13282/// @param corp the corpus to look into.
13284lookup_class_type(const string& qualified_name, const corpus& corp)
13285{
13286 interned_string s = corp.get_environment().intern(qualified_name);
13287 return lookup_class_type(s, corp);
13288}
13289
13290/// Look into a given corpus to find a class type which has a given
13291/// qualified name.
13292///
13293/// If the per-corpus type map is non-empty (because the corpus allows
13294/// the One Definition Rule) then the type islooked up in that
13295/// per-corpus type map. Otherwise, the type is looked-up in each
13296/// translation unit.
13297///
13298/// @param qualified_name the qualified name of the type to look for.
13299///
13300/// @param corp the corpus to look into.
13302lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13303{
13305
13306 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13307
13308 return result;
13309}
13310
13311/// Look into a given corpus to find the class type*s* that have a
13312/// given qualified name.
13313///
13314/// @param qualified_name the qualified name of the type to look for.
13315///
13316/// @param corp the corpus to look into.
13317///
13318/// @return the vector of class types named @p qualified_name.
13320lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13321{
13323
13324 return lookup_types_in_map(qualified_name, m);
13325}
13326
13327/// Look into a given corpus to find the class type*s* that have a
13328/// given qualified name and that are declaration-only.
13329///
13330/// @param qualified_name the qualified name of the type to look for.
13331///
13332/// @param corp the corpus to look into.
13333///
13334/// @param result the vector of decl-only class types named @p
13335/// qualified_name. This is populated iff the function returns true.
13336///
13337/// @return true iff @p result was populated with the decl-only
13338/// classes named @p qualified_name.
13339bool
13341 const corpus& corp,
13342 type_base_wptrs_type& result)
13343{
13345
13346 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13347 if (!v)
13348 return false;
13349
13350 for (auto type : *v)
13351 {
13352 type_base_sptr t(type);
13354 if (c->get_is_declaration_only()
13355 && !c->get_definition_of_declaration())
13356 result.push_back(type);
13357 }
13358
13359 return !result.empty();
13360}
13361
13362/// Look into a given corpus to find the union type*s* that have a
13363/// given qualified name.
13364///
13365/// @param qualified_name the qualified name of the type to look for.
13366///
13367/// @param corp the corpus to look into.
13368///
13369/// @return the vector of union types named @p qualified_name.
13371lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13372{
13374
13375 return lookup_types_in_map(qualified_name, m);
13376}
13377
13378/// Look into a given corpus to find the class type*s* that have a
13379/// given qualified name.
13380///
13381/// @param qualified_name the qualified name of the type to look for.
13382///
13383/// @param corp the corpus to look into.
13384///
13385/// @return the vector of class types which name is @p qualified_name.
13387lookup_class_types(const string& qualified_name, const corpus& corp)
13388{
13389 interned_string s = corp.get_environment().intern(qualified_name);
13390 return lookup_class_types(s, corp);
13391}
13392
13393/// Look into a given corpus to find the union types that have a given
13394/// qualified name.
13395///
13396/// @param qualified_name the qualified name of the type to look for.
13397///
13398/// @param corp the corpus to look into.
13399///
13400/// @return the vector of union types which name is @p qualified_name.
13402lookup_union_types(const string& qualified_name, const corpus& corp)
13403{
13404 interned_string s = corp.get_environment().intern(qualified_name);
13405 return lookup_union_types(s, corp);
13406}
13407
13408/// Look up a @ref class_decl from a given corpus by its location.
13409///
13410/// @param loc the location to consider.
13411///
13412/// @param corp the corpus to consider.
13413///
13414/// @return the resulting class decl, if any.
13417 const corpus& corp)
13418{
13421 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13422
13423 return result;
13424}
13425
13426/// Look up a @ref class_decl from a given corpus by its location.
13427///
13428/// @param loc the location to consider.
13429///
13430/// @param corp the corpus to consider.
13431///
13432/// @return the resulting class decl, if any.
13434lookup_class_type_per_location(const string &loc, const corpus &corp)
13435{
13436 const environment& env = corp.get_environment();
13437 return lookup_class_type_per_location(env.intern(loc), corp);
13438}
13439
13440/// Look into a given corpus to find a union type which has a given
13441/// qualified name.
13442///
13443/// If the per-corpus type map is non-empty (because the corpus allows
13444/// the One Definition Rule) then the type islooked up in that
13445/// per-corpus type map. Otherwise, the type is looked-up in each
13446/// translation unit.
13447///
13448/// @param qualified_name the qualified name of the type to look for.
13449///
13450/// @param corp the corpus to look into.
13451union_decl_sptr
13452lookup_union_type(const interned_string& type_name, const corpus& corp)
13453{
13455
13456 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13457 if (!result)
13458 result = lookup_union_type_through_translation_units(type_name, corp);
13459
13460 return result;
13461}
13462
13463/// Look into a given corpus to find a union type which has a given
13464/// qualified name.
13465///
13466/// If the per-corpus type map is non-empty (because the corpus allows
13467/// the One Definition Rule) then the type islooked up in that
13468/// per-corpus type map. Otherwise, the type is looked-up in each
13469/// translation unit.
13470///
13471/// @param qualified_name the qualified name of the type to look for.
13472///
13473/// @param corp the corpus to look into.
13474union_decl_sptr
13475lookup_union_type(const string& type_name, const corpus& corp)
13476{
13477 interned_string s = corp.get_environment().intern(type_name);
13478 return lookup_union_type(s, corp);
13479}
13480
13481/// Look into a given corpus to find an enum type which has the same
13482/// qualified name as a given enum type.
13483///
13484/// If the per-corpus type map is non-empty (because the corpus allows
13485/// the One Definition Rule) then the type islooked up in that
13486/// per-corpus type map. Otherwise, the type is looked-up in each
13487/// translation unit.
13488///
13489/// @param t the enum type which has the same qualified name as the
13490/// type we are looking for.
13491///
13492/// @param corp the corpus to look into.
13495{
13497 return lookup_enum_type(s, corp);
13498}
13499
13500/// Look into a given corpus to find an enum type which has a given
13501/// qualified name.
13502///
13503/// If the per-corpus type map is non-empty (because the corpus allows
13504/// the One Definition Rule) then the type islooked up in that
13505/// per-corpus type map. Otherwise, the type is looked-up in each
13506/// translation unit.
13507///
13508/// @param qualified_name the qualified name of the enum type to look
13509/// for.
13510///
13511/// @param corp the corpus to look into.
13513lookup_enum_type(const string& qualified_name, const corpus& corp)
13514{
13515 interned_string s = corp.get_environment().intern(qualified_name);
13516 return lookup_enum_type(s, corp);
13517}
13518
13519/// Look into a given corpus to find an enum type which has a given
13520/// qualified name.
13521///
13522/// If the per-corpus type map is non-empty (because the corpus allows
13523/// the One Definition Rule) then the type islooked up in that
13524/// per-corpus type map. Otherwise, the type is looked-up in each
13525/// translation unit.
13526///
13527/// @param qualified_name the qualified name of the enum type to look
13528/// for.
13529///
13530/// @param corp the corpus to look into.
13532lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
13533{
13535
13536 enum_type_decl_sptr result =
13537 lookup_type_in_map<enum_type_decl>(qualified_name, m);
13538 if (!result)
13539 result = lookup_enum_type_through_translation_units(qualified_name, corp);
13540
13541 return result;
13542}
13543
13544/// Look into a given corpus to find the enum type*s* that have a
13545/// given qualified name.
13546///
13547/// @param qualified_name the qualified name of the type to look for.
13548///
13549/// @param corp the corpus to look into.
13550///
13551/// @return the vector of enum types that which name is @p qualified_name.
13553lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
13554{
13556
13557 return lookup_types_in_map(qualified_name, m);
13558}
13559
13560/// Look into a given corpus to find the enum type*s* that have a
13561/// given qualified name.
13562///
13563/// @param qualified_name the qualified name of the type to look for.
13564///
13565/// @param corp the corpus to look into.
13566///
13567/// @return the vector of enum types that which name is @p qualified_name.
13569lookup_enum_types(const string& qualified_name, const corpus& corp)
13570{
13571 interned_string s = corp.get_environment().intern(qualified_name);
13572 return lookup_enum_types(s, corp);
13573}
13574
13575/// Look up an @ref enum_type_decl from a given corpus, by its location.
13576///
13577/// @param loc the location to consider.
13578///
13579/// @param corp the corpus to look the type from.
13580///
13581/// @return the resulting enum type, if any.
13584{
13587 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
13588
13589 return result;
13590}
13591
13592/// Look up an @ref enum_type_decl from a given corpus, by its location.
13593///
13594/// @param loc the location to consider.
13595///
13596/// @param corp the corpus to look the type from.
13597///
13598/// @return the resulting enum type, if any.
13600lookup_enum_type_per_location(const string &loc, const corpus &corp)
13601{
13602 const environment& env = corp.get_environment();
13603 return lookup_enum_type_per_location(env.intern(loc), corp);
13604}
13605
13606/// Look into a given corpus to find a typedef type which has the
13607/// same qualified name as a given typedef type.
13608///
13609/// If the per-corpus type map is non-empty (because the corpus allows
13610/// the One Definition Rule) then the type islooked up in that
13611/// per-corpus type map. Otherwise, the type is looked-up in each
13612/// translation unit.
13613///
13614/// @param t the typedef type which has the same qualified name as the
13615/// typedef type we are looking for.
13616///
13617/// @param corp the corpus to look into.
13620{
13622 return lookup_typedef_type(s, corp);
13623}
13624
13625/// Look into a given corpus to find a typedef type which has the
13626/// same qualified name as a given typedef type.
13627///
13628/// If the per-corpus type map is non-empty (because the corpus allows
13629/// the One Definition Rule) then the type islooked up in that
13630/// per-corpus type map. Otherwise, the type is looked-up in each
13631/// translation unit.
13632///
13633/// @param t the typedef type which has the same qualified name as the
13634/// typedef type we are looking for.
13635///
13636/// @param corp the corpus to look into.
13638lookup_typedef_type(const string& qualified_name, const corpus& corp)
13639{
13640 interned_string s = corp.get_environment().intern(qualified_name);
13641 return lookup_typedef_type(s, corp);
13642}
13643
13644/// Look into a given corpus to find a typedef type which has a
13645/// given qualified name.
13646///
13647/// If the per-corpus type map is non-empty (because the corpus allows
13648/// the One Definition Rule) then the type islooked up in that
13649/// per-corpus type map. Otherwise, the type is looked-up in each
13650/// translation unit.
13651///
13652/// @param qualified_name the qualified name of the typedef type to
13653/// look for.
13654///
13655/// @param corp the corpus to look into.
13657lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
13658{
13660
13661 typedef_decl_sptr result =
13662 lookup_type_in_map<typedef_decl>(qualified_name, m);
13663 if (!result)
13664 result = lookup_typedef_type_through_translation_units(qualified_name,
13665 corp);
13666
13667 return result;
13668}
13669
13670/// Lookup a @ref typedef_decl from a corpus, by its location.
13671///
13672/// @param loc the location to consider.
13673///
13674/// @param corp the corpus to consider.
13675///
13676/// @return the typedef_decl found, if any.
13679{
13682 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
13683
13684 return result;
13685}
13686
13687/// Lookup a @ref typedef_decl from a corpus, by its location.
13688///
13689/// @param loc the location to consider.
13690///
13691/// @param corp the corpus to consider.
13692///
13693/// @return the typedef_decl found, if any.
13695lookup_typedef_type_per_location(const string &loc, const corpus &corp)
13696{
13697 const environment& env = corp.get_environment();
13698 return lookup_typedef_type_per_location(env.intern(loc), corp);
13699}
13700
13701/// Look into a corpus to find a class, union or typedef type which
13702/// has a given qualified name.
13703///
13704/// If the per-corpus type map is non-empty (because the corpus allows
13705/// the One Definition Rule) then the type islooked up in that
13706/// per-corpus type map. Otherwise, the type is looked-up in each
13707/// translation unit.
13708///
13709/// @param qualified_name the name of the type to find.
13710///
13711/// @param corp the corpus to look into.
13712///
13713/// @return the typedef or class type found.
13714type_base_sptr
13715lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
13716{
13717 type_base_sptr result = lookup_class_type(qualified_name, corp);
13718 if (!result)
13719 result = lookup_union_type(qualified_name, corp);
13720
13721 if (!result)
13722 result = lookup_typedef_type(qualified_name, corp);
13723 return result;
13724}
13725
13726/// Look into a corpus to find a class, typedef or enum type which has
13727/// a given qualified name.
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 qualified_name the qualified name of the type to look for.
13735///
13736/// @param corp the corpus to look into.
13737///
13738/// @return the typedef, class or enum type found.
13739type_base_sptr
13740lookup_class_typedef_or_enum_type(const string& qualified_name,
13741 const corpus& corp)
13742{
13743 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
13744 if (!result)
13745 result = lookup_enum_type(qualified_name, corp);
13746
13747 return result;
13748}
13749
13750/// Look into a given corpus to find a qualified type which has the
13751/// same qualified name as a given type.
13752///
13753/// @param t the type which has the same qualified name as the
13754/// qualified type we are looking for.
13755///
13756/// @param corp the corpus to look into.
13757///
13758/// @return the qualified type found.
13759qualified_type_def_sptr
13761{
13763 return lookup_qualified_type(s, corp);
13764}
13765
13766/// Look into a given corpus to find a qualified type which has a
13767/// given qualified name.
13768///
13769/// @param qualified_name the qualified name of the type to look for.
13770///
13771/// @param corp the corpus to look into.
13772///
13773/// @return the type found.
13774qualified_type_def_sptr
13775lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
13776{
13778 corp.get_types().qualified_types();
13779
13780 qualified_type_def_sptr result =
13781 lookup_type_in_map<qualified_type_def>(qualified_name, m);
13782
13783 if (!result)
13784 result = lookup_qualified_type_through_translation_units(qualified_name,
13785 corp);
13786
13787 return result;
13788}
13789
13790/// Look into a given corpus to find a pointer type which has the same
13791/// qualified name as a given pointer type.
13792///
13793/// @param t the pointer type which has the same qualified name as the
13794/// type we are looking for.
13795///
13796/// @param corp the corpus to look into.
13797///
13798/// @return the pointer type found.
13801{
13803 return lookup_pointer_type(s, corp);
13804}
13805
13806/// Look into a given corpus to find a pointer type which has a given
13807/// qualified name.
13808///
13809/// If the per-corpus type map is non-empty (because the corpus allows
13810/// the One Definition Rule) then the type islooked up in that
13811/// per-corpus type map. Otherwise, the type is looked-up in each
13812/// translation unit.
13813///
13814/// @param qualified_name the qualified name of the pointer type to
13815/// look for.
13816///
13817/// @param corp the corpus to look into.
13818///
13819/// @return the pointer type found.
13821lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
13822{
13824
13825 pointer_type_def_sptr result =
13826 lookup_type_in_map<pointer_type_def>(qualified_name, m);
13827 if (!result)
13828 result = lookup_pointer_type_through_translation_units(qualified_name,
13829 corp);
13830
13831 return result;
13832}
13833
13834/// Look into a given corpus to find a reference type which has the
13835/// same qualified name as a given reference type.
13836///
13837/// If the per-corpus type map is non-empty (because the corpus allows
13838/// the One Definition Rule) then the type islooked up in that
13839/// per-corpus type map. Otherwise, the type is looked-up in each
13840/// translation unit.
13841///
13842/// @param t the reference type which has the same qualified name as
13843/// the reference type we are looking for.
13844///
13845/// @param corp the corpus to look into.
13846///
13847/// @return the reference type found.
13850{
13852 return lookup_reference_type(s, corp);
13853}
13854
13855/// Look into a given corpus to find a reference type which has a
13856/// given qualified name.
13857///
13858/// If the per-corpus type map is non-empty (because the corpus allows
13859/// the One Definition Rule) then the type islooked up in that
13860/// per-corpus type map. Otherwise, the type is looked-up in each
13861/// translation unit.
13862///
13863/// @param qualified_name the qualified name of the reference type to
13864/// look for.
13865///
13866/// @param corp the corpus to look into.
13867///
13868/// @return the reference type found.
13870lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
13871{
13873 corp.get_types().reference_types();
13874
13876 lookup_type_in_map<reference_type_def>(qualified_name, m);
13877 if (!result)
13878 result = lookup_reference_type_through_translation_units(qualified_name,
13879 corp);
13880
13881 return result;
13882}
13883
13884/// Look into a given corpus to find an array type which has a given
13885/// qualified name.
13886///
13887/// If the per-corpus type map is non-empty (because the corpus allows
13888/// the One Definition Rule) then the type islooked up in that
13889/// per-corpus type map. Otherwise, the type is looked-up in each
13890/// translation unit.
13891///
13892/// @param qualified_name the qualified name of the array type to look
13893/// for.
13894///
13895/// @param corp the corpus to look into.
13896///
13897/// @return the array type found.
13900{
13902 return lookup_array_type(s, corp);
13903}
13904
13905/// Look into a given corpus to find an array type which has the same
13906/// qualified name as a given array type.
13907///
13908/// If the per-corpus type map is non-empty (because the corpus allows
13909/// the One Definition Rule) then the type islooked up in that
13910/// per-corpus type map. Otherwise, the type is looked-up in each
13911/// translation unit.
13912///
13913/// @param t the type which has the same qualified name as the type we
13914/// are looking for.
13915///
13916/// @param corp the corpus to look into.
13917///
13918/// @return the type found.
13920lookup_array_type(const interned_string& qualified_name, const corpus& corp)
13921{
13923
13924 array_type_def_sptr result =
13925 lookup_type_in_map<array_type_def>(qualified_name, m);
13926 if (!result)
13927 result = lookup_array_type_through_translation_units(qualified_name, corp);
13928
13929 return result;
13930}
13931
13932/// Look into a given corpus to find a function type which has the same
13933/// qualified name as a given function type.
13934///
13935/// If the per-corpus type map is non-empty (because the corpus allows
13936/// the One Definition Rule) then the type islooked up in that
13937/// per-corpus type map. Otherwise, the type is looked-up in each
13938/// translation unit.
13939///
13940/// @param t the function type which has the same qualified name as
13941/// the function type we are looking for.
13942///
13943/// @param corp the corpus to look into.
13944///
13945/// @return the function type found.
13948{
13949 interned_string type_name = get_type_name(t);
13950 return lookup_function_type(type_name, corp);
13951}
13952
13953/// Look into a given corpus to find a function type which has the same
13954/// qualified name as a given function type.
13955///
13956/// If the per-corpus type map is non-empty (because the corpus allows
13957/// the One Definition Rule) then the type islooked up in that
13958/// per-corpus type map. Otherwise, the type is looked-up in each
13959/// translation unit.
13960///
13961/// @param t the function type which has the same qualified name as
13962/// the function type we are looking for.
13963///
13964/// @param corp the corpus to look into.
13965///
13966/// @return the function type found.
13969 const corpus& corpus)
13970{
13971 if (fn_t)
13972 return lookup_function_type(*fn_t, corpus);
13973 return function_type_sptr();
13974}
13975
13976/// Look into a given corpus to find a function type which has a given
13977/// qualified name.
13978///
13979/// If the per-corpus type map is non-empty (because the corpus allows
13980/// the One Definition Rule) then the type islooked up in that
13981/// per-corpus type map. Otherwise, the type is looked-up in each
13982/// translation unit.
13983///
13984/// @param qualified_name the qualified name of the function type to
13985/// look for.
13986///
13987/// @param corp the corpus to look into.
13988///
13989/// @return the function type found.
13991lookup_function_type(const interned_string& qualified_name, const corpus& corp)
13992{
13994
13995 function_type_sptr result =
13996 lookup_type_in_map<function_type>(qualified_name, m);
13997 if (!result)
13998 result = lookup_function_type_through_translation_units(qualified_name,
13999 corp);
14000
14001 return result;
14002}
14003
14004/// Look into a given corpus to find a type which has a given
14005/// qualified name.
14006///
14007/// If the per-corpus type map is non-empty (because the corpus allows
14008/// the One Definition Rule) then the type islooked up in that
14009/// per-corpus type map. Otherwise, the type is looked-up in each
14010/// translation unit.
14011///
14012/// @param qualified_name the qualified name of the function type to
14013/// look for.
14014///
14015/// @param corp the corpus to look into.
14016///
14017/// @return the function type found.
14018type_base_sptr
14019lookup_type(const interned_string& n, const corpus& corp)
14020{
14021 type_base_sptr result;
14022
14023 ((result = lookup_basic_type(n, corp))
14024 || (result = lookup_class_type(n, corp))
14025 || (result = lookup_union_type(n, corp))
14026 || (result = lookup_enum_type(n, corp))
14027 || (result = lookup_typedef_type(n, corp))
14028 || (result = lookup_qualified_type(n, corp))
14029 || (result = lookup_pointer_type(n, corp))
14030 || (result = lookup_reference_type(n, corp))
14031 || (result = lookup_array_type(n, corp))
14032 || (result= lookup_function_type(n, corp)));
14033
14034 return result;
14035}
14036
14037/// Lookup a type from a corpus, by its location.
14038///
14039/// @param loc the location to consider.
14040///
14041/// @param corp the corpus to look the type from.
14042///
14043/// @return the resulting type, if any found.
14044type_base_sptr
14046{
14047 // TODO: finish this.
14048
14049 //TODO: when we fully support types indexed by their location, this
14050 //function should return a vector of types because at each location,
14051 //there can be several types that are defined (yay, C and C++,
14052 //*sigh*).
14053
14054 type_base_sptr result;
14055 ((result = lookup_basic_type_per_location(loc, corp))
14056 || (result = lookup_class_type_per_location(loc, corp))
14057 || (result = lookup_union_type_per_location(loc, corp))
14058 || (result = lookup_enum_type_per_location(loc, corp))
14059 || (result = lookup_typedef_type_per_location(loc, corp)));
14060
14061 return result;
14062}
14063
14064/// Look into a given corpus to find a type
14065///
14066/// If the per-corpus type map is non-empty (because the corpus allows
14067/// the One Definition Rule) then the type islooked up in that
14068/// per-corpus type map. Otherwise, the type is looked-up in each
14069/// translation unit.
14070///
14071/// @param qualified_name the qualified name of the function type to
14072/// look for.
14073///
14074/// @param corp the corpus to look into.
14075///
14076/// @return the function type found.
14077type_base_sptr
14078lookup_type(const type_base&t, const corpus& corp)
14079{
14081 return lookup_type(n, corp);
14082}
14083
14084/// Look into a given corpus to find a type
14085///
14086/// If the per-corpus type map is non-empty (because the corpus allows
14087/// the One Definition Rule) then the type islooked up in that
14088/// per-corpus type map. Otherwise, the type is looked-up in each
14089/// translation unit.
14090///
14091/// @param qualified_name the qualified name of the function type to
14092/// look for.
14093///
14094/// @param corp the corpus to look into.
14095///
14096/// @return the function type found.
14097type_base_sptr
14098lookup_type(const type_base_sptr&t, const corpus& corp)
14099{
14100 if (t)
14101 return lookup_type(*t, corp);
14102 return type_base_sptr();
14103}
14104
14105/// Update the map that associates a fully qualified name of a given
14106/// type to that type.
14107///
14108///
14109/// @param type the type we are considering.
14110///
14111/// @param types_map the map to update. It's a map that assciates a
14112/// fully qualified name of a type to the type itself.
14113///
14114/// @param use_type_name_as_key if true, use the name of the type as
14115/// the key to look it up later. If false, then use the location of
14116/// the type as a key to look it up later.
14117///
14118/// @return true iff the type was added to the map.
14119template<typename TypeKind>
14120bool
14121maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
14123 bool use_type_name_as_key = true)
14124{
14126
14127 if (use_type_name_as_key)
14128 s = get_type_name(type);
14129 else if (location l = type->get_location())
14130 {
14131 string str = l.expand();
14132 s = type->get_environment().intern(str);
14133 }
14134
14135 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14136 bool result = false;
14137
14138 if (i == types_map.end())
14139 {
14140 types_map[s].push_back(type);
14141 result = true;
14142 }
14143 else
14144 i->second.push_back(type);
14145
14146 return result;
14147}
14148
14149/// This is the specialization for type @ref class_decl of the
14150/// function template:
14151///
14152/// maybe_update_types_lookup_map<T>(scope_decl*,
14153/// const shared_ptr<T>&,
14154/// istring_type_base_wptrs_map_type&)
14155///
14156/// @param class_type the type to consider.
14157///
14158/// @param types_map the type map to update.
14159///
14160/// @return true iff the type was added to the map.
14161template<>
14162bool
14165 bool use_type_name_as_key)
14166{
14167 class_decl_sptr type = class_type;
14168
14169 bool update_qname_map = true;
14170 if (type->get_is_declaration_only())
14171 {
14172 // Let's try to look through decl-only classes to get their
14173 // definition. But if the class doesn't have a definition then
14174 // we'll keep it.
14175 if (class_decl_sptr def =
14176 is_class_type(class_type->get_definition_of_declaration()))
14177 type = def;
14178 }
14179
14180 if (!update_qname_map)
14181 return false;
14182
14184 if (use_type_name_as_key)
14185 {
14186 string qname = type->get_qualified_name();
14187 s = type->get_environment().intern(qname);
14188 }
14189 else if (location l = type->get_location())
14190 {
14191 string str = l.expand();
14192 s = type->get_environment().intern(str);
14193 }
14194
14195 bool result = false;
14196 istring_type_base_wptrs_map_type::iterator i = map.find(s);
14197 if (i == map.end())
14198 {
14199 map[s].push_back(type);
14200 result = true;
14201 }
14202 else
14203 i->second.push_back(type);
14204
14205 return result;
14206}
14207
14208/// This is the specialization for type @ref function_type of the
14209/// function template:
14210///
14211/// maybe_update_types_lookup_map<T>(scope_decl*,
14212/// const shared_ptr<T>&,
14213/// istring_type_base_wptrs_map_type&)
14214///
14215/// @param scope the scope of the type to consider.
14216///
14217/// @param class_type the type to consider.
14218///
14219/// @param types_map the type map to update.
14220///
14221/// @return true iff the type was added to the map.
14222template<>
14223bool
14225(const function_type_sptr& type,
14227 bool /*use_type_name_as_key*/)
14228{
14229 bool result = false;
14231 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14232 if (i == types_map.end())
14233 {
14234 types_map[s].push_back(type);
14235 result = true;
14236 }
14237 else
14238 i->second.push_back(type);
14239
14240 return result;
14241}
14242
14243/// Update the map that associates the fully qualified name of a basic
14244/// type with the type itself.
14245///
14246/// The per-translation unit type map is updated if no type with this
14247/// name was already existing in that map.
14248///
14249/// If no type with this name did already exist in the per-corpus type
14250/// map, then that per-corpus type map is updated. Otherwise, that
14251/// type is erased from that per-corpus map.
14252///
14253/// @param basic_type the basic type to consider.
14254void
14256{
14257 if (translation_unit *tu = basic_type->get_translation_unit())
14258 maybe_update_types_lookup_map<type_decl>
14259 (basic_type, tu->get_types().basic_types());
14260
14261 if (corpus *type_corpus = basic_type->get_corpus())
14262 {
14263 maybe_update_types_lookup_map<type_decl>
14264 (basic_type,
14265 type_corpus->priv_->get_types().basic_types());
14266
14267 maybe_update_types_lookup_map<type_decl>
14268 (basic_type,
14269 type_corpus->get_type_per_loc_map().basic_types(),
14270 /*use_type_name_as_key*/false);
14271
14272 if (corpus *group = type_corpus->get_group())
14273 {
14274 maybe_update_types_lookup_map<type_decl>
14275 (basic_type,
14276 group->priv_->get_types().basic_types());
14277
14278 maybe_update_types_lookup_map<type_decl>
14279 (basic_type,
14280 group->get_type_per_loc_map().basic_types(),
14281 /*use_type_name_as_key*/false);
14282 }
14283 }
14284
14285}
14286
14287/// Update the map that associates the fully qualified name of a class
14288/// type with the type itself.
14289///
14290/// The per-translation unit type map is updated if no type with this
14291/// name was already existing in that map.
14292///
14293/// If no type with this name did already exist in the per-corpus type
14294/// map, then that per-corpus type map is updated. Otherwise, that
14295/// type is erased from that per-corpus map.
14296///
14297/// @param class_type the class type to consider.
14298void
14300{
14301 if (translation_unit *tu = class_type->get_translation_unit())
14303 (class_type, tu->get_types().class_types());
14304
14305 if (corpus *type_corpus = class_type->get_corpus())
14306 {
14308 (class_type,
14309 type_corpus->priv_->get_types().class_types());
14310
14312 (class_type,
14313 type_corpus->get_type_per_loc_map().class_types(),
14314 /*use_type_name_as_key*/false);
14315
14316 if (corpus *group = type_corpus->get_group())
14317 {
14319 (class_type,
14320 group->priv_->get_types().class_types());
14321
14323 (class_type,
14324 group->get_type_per_loc_map().class_types(),
14325 /*use_type_name_as_key*/false);
14326 }
14327 }
14328}
14329
14330/// Update the map that associates the fully qualified name of a union
14331/// type with the type itself.
14332///
14333/// The per-translation unit type map is updated if no type with this
14334/// name was already existing in that map.
14335///
14336/// If no type with this name did already exist in the per-corpus type
14337/// map, then that per-corpus type map is updated. Otherwise, that
14338/// type is erased from that per-corpus map.
14339///
14340/// @param union_type the union type to consider.
14341void
14342maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14343{
14344 if (translation_unit *tu = union_type->get_translation_unit())
14345 maybe_update_types_lookup_map<union_decl>
14346 (union_type, tu->get_types().union_types());
14347
14348 if (corpus *type_corpus = union_type->get_corpus())
14349 {
14350 maybe_update_types_lookup_map<union_decl>
14351 (union_type,
14352 type_corpus->priv_->get_types().union_types());
14353
14354 maybe_update_types_lookup_map<union_decl>
14355 (union_type,
14356 type_corpus->get_type_per_loc_map().union_types(),
14357 /*use_type_name_as_key*/false);
14358
14359 if (corpus *group = type_corpus->get_group())
14360 {
14361 maybe_update_types_lookup_map<union_decl>
14362 (union_type,
14363 group->priv_->get_types().union_types());
14364
14365 maybe_update_types_lookup_map<union_decl>
14366 (union_type,
14367 group->get_type_per_loc_map().union_types(),
14368 /*use_type_name_as_key*/false);
14369 }
14370 }
14371}
14372
14373/// Update the map that associates the fully qualified name of an enum
14374/// type with the type itself.
14375///
14376/// The per-translation unit type map is updated if no type with this
14377/// name was already existing in that map.
14378///
14379/// If no type with this name did already exist in the per-corpus type
14380/// map, then that per-corpus type map is updated. Otherwise, that
14381/// type is erased from that per-corpus map.
14382///
14383/// @param enum_type the type to consider.
14384void
14386{
14387 if (translation_unit *tu = enum_type->get_translation_unit())
14388 maybe_update_types_lookup_map<enum_type_decl>
14389 (enum_type, tu->get_types().enum_types());
14390
14391 if (corpus *type_corpus = enum_type->get_corpus())
14392 {
14393 maybe_update_types_lookup_map<enum_type_decl>
14394 (enum_type,
14395 type_corpus->priv_->get_types().enum_types());
14396
14397 maybe_update_types_lookup_map<enum_type_decl>
14398 (enum_type,
14399 type_corpus->get_type_per_loc_map().enum_types(),
14400 /*use_type_name_as_key*/false);
14401
14402 if (corpus *group = type_corpus->get_group())
14403 {
14404 maybe_update_types_lookup_map<enum_type_decl>
14405 (enum_type,
14406 group->priv_->get_types().enum_types());
14407
14408 maybe_update_types_lookup_map<enum_type_decl>
14409 (enum_type,
14410 group->get_type_per_loc_map().enum_types(),
14411 /*use_type_name_as_key*/false);
14412 }
14413 }
14414
14415}
14416
14417/// Update the map that associates the fully qualified name of a
14418/// typedef type with the type itself.
14419///
14420/// The per-translation unit type map is updated if no type with this
14421/// name was already existing in that map.
14422///
14423/// If no type with this name did already exist in the per-corpus type
14424/// map, then that per-corpus type map is updated. Otherwise, that
14425/// type is erased from that per-corpus map.
14426///
14427/// @param typedef_type the type to consider.
14428void
14430{
14431 if (translation_unit *tu = typedef_type->get_translation_unit())
14432 maybe_update_types_lookup_map<typedef_decl>
14433 (typedef_type, tu->get_types().typedef_types());
14434
14435 if (corpus *type_corpus = typedef_type->get_corpus())
14436 {
14437 maybe_update_types_lookup_map<typedef_decl>
14438 (typedef_type,
14439 type_corpus->priv_->get_types().typedef_types());
14440
14441 maybe_update_types_lookup_map<typedef_decl>
14442 (typedef_type,
14443 type_corpus->get_type_per_loc_map().typedef_types(),
14444 /*use_type_name_as_key*/false);
14445
14446 if (corpus *group = type_corpus->get_group())
14447 {
14448 maybe_update_types_lookup_map<typedef_decl>
14449 (typedef_type,
14450 group->priv_->get_types().typedef_types());
14451
14452 maybe_update_types_lookup_map<typedef_decl>
14453 (typedef_type,
14454 group->get_type_per_loc_map().typedef_types(),
14455 /*use_type_name_as_key*/false);
14456 }
14457 }
14458}
14459
14460/// Update the map that associates the fully qualified name of a
14461/// qualified type with the type itself.
14462///
14463/// The per-translation unit type map is updated if no type with this
14464/// name was already existing in that map.
14465///
14466/// If no type with this name did already exist in the per-corpus type
14467/// map, then that per-corpus type map is updated. Otherwise, that
14468/// type is erased from that per-corpus map.
14469///
14470/// @param qualified_type the type to consider.
14471void
14472maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14473{
14474 if (translation_unit *tu = qualified_type->get_translation_unit())
14475 maybe_update_types_lookup_map<qualified_type_def>
14476 (qualified_type, tu->get_types().qualified_types());
14477
14478 if (corpus *type_corpus = qualified_type->get_corpus())
14479 {
14480 maybe_update_types_lookup_map<qualified_type_def>
14481 (qualified_type,
14482 type_corpus->priv_->get_types().qualified_types());
14483
14484 if (corpus *group = type_corpus->get_group())
14485 {
14486 maybe_update_types_lookup_map<qualified_type_def>
14487 (qualified_type,
14488 group->priv_->get_types().qualified_types());
14489 }
14490 }
14491}
14492
14493/// Update the map that associates the fully qualified name of a
14494/// pointer type with the type itself.
14495///
14496/// The per-translation unit type map is updated if no type with this
14497/// name was already existing in that map.
14498///
14499/// If no type with this name did already exist in the per-corpus type
14500/// map, then that per-corpus type map is updated. Otherwise, that
14501/// type is erased from that per-corpus map.
14502///
14503/// @param pointer_type the type to consider.
14504void
14506{
14507 if (translation_unit *tu = pointer_type->get_translation_unit())
14508 maybe_update_types_lookup_map<pointer_type_def>
14509 (pointer_type, tu->get_types().pointer_types());
14510
14511 if (corpus *type_corpus = pointer_type->get_corpus())
14512 {
14513 maybe_update_types_lookup_map<pointer_type_def>
14514 (pointer_type,
14515 type_corpus->priv_->get_types().pointer_types());
14516
14517 if (corpus *group = type_corpus->get_group())
14518 {
14519 maybe_update_types_lookup_map<pointer_type_def>
14520 (pointer_type,
14521 group->priv_->get_types().pointer_types());
14522 }
14523 }
14524}
14525
14526/// Update the map that associates the fully qualified name of a
14527/// pointer-to-member type with the type itself.
14528///
14529/// The per-translation unit type map is updated if no type with this
14530/// name was already existing in that map.
14531///
14532/// If no type with this name did already exist in the per-corpus type
14533/// map, then that per-corpus type map is updated. Otherwise, that
14534/// type is erased from that per-corpus map.
14535///
14536/// @param ptr_to_mbr_type the type to consider.
14537void
14539{
14540 if (translation_unit *tu = ptr_to_member->get_translation_unit())
14541 maybe_update_types_lookup_map<ptr_to_mbr_type>
14542 (ptr_to_member, tu->get_types().ptr_to_mbr_types());
14543
14544 if (corpus *type_corpus = ptr_to_member->get_corpus())
14545 {
14546 maybe_update_types_lookup_map<ptr_to_mbr_type>
14547 (ptr_to_member,
14548 type_corpus->priv_->get_types().ptr_to_mbr_types());
14549
14550 if (corpus *group = type_corpus->get_group())
14551 {
14552 maybe_update_types_lookup_map<ptr_to_mbr_type>
14553 (ptr_to_member,
14554 group->priv_->get_types().ptr_to_mbr_types());
14555 }
14556 }
14557}
14558
14559/// Update the map that associates the fully qualified name of a
14560/// reference type with the type itself.
14561///
14562/// The per-translation unit type map is updated if no type with this
14563/// name was already existing in that map.
14564///
14565/// If no type with this name did already exist in the per-corpus type
14566/// map, then that per-corpus type map is updated. Otherwise, that
14567/// type is erased from that per-corpus map.
14568///
14569/// @param reference_type the type to consider.
14570void
14572{
14573 if (translation_unit *tu = reference_type->get_translation_unit())
14574 maybe_update_types_lookup_map<reference_type_def>
14575 (reference_type, tu->get_types().reference_types());
14576
14577 if (corpus *type_corpus = reference_type->get_corpus())
14578 {
14579 maybe_update_types_lookup_map<reference_type_def>
14580 (reference_type,
14581 type_corpus->priv_->get_types().reference_types());
14582
14583 if (corpus *group = type_corpus->get_group())
14584 {
14585 maybe_update_types_lookup_map<reference_type_def>
14586 (reference_type,
14587 group->priv_->get_types().reference_types());
14588 }
14589 }
14590}
14591
14592/// Update the map that associates the fully qualified name of a type
14593/// with the type itself.
14594///
14595/// The per-translation unit type map is updated if no type with this
14596/// name was already existing in that map.
14597///
14598/// If no type with this name did already exist in the per-corpus type
14599/// map, then that per-corpus type map is updated. Otherwise, that
14600/// type is erased from that per-corpus map.
14601///
14602/// @param array_type the type to consider.
14603void
14605{
14606 if (translation_unit *tu = array_type->get_translation_unit())
14607 maybe_update_types_lookup_map<array_type_def>
14608 (array_type, tu->get_types().array_types());
14609
14610 if (corpus *type_corpus = array_type->get_corpus())
14611 {
14612 maybe_update_types_lookup_map<array_type_def>
14613 (array_type,
14614 type_corpus->priv_->get_types().array_types());
14615
14616 maybe_update_types_lookup_map<array_type_def>
14617 (array_type,
14618 type_corpus->get_type_per_loc_map().array_types(),
14619 /*use_type_name_as_key*/false);
14620
14621 if (corpus *group = type_corpus->get_group())
14622 {
14623 maybe_update_types_lookup_map<array_type_def>
14624 (array_type,
14625 group->priv_->get_types().array_types());
14626
14627 maybe_update_types_lookup_map<array_type_def>
14628 (array_type,
14629 group->get_type_per_loc_map().array_types(),
14630 /*use_type_name_as_key*/false);
14631 }
14632 }
14633}
14634
14635/// Update the map that associates the fully qualified name of a type
14636/// with the type itself.
14637///
14638/// The per-translation unit type map is updated if no type with this
14639/// name was already existing in that map.
14640///
14641/// If no type with this name did already exist in the per-corpus type
14642/// map, then that per-corpus type map is updated. Otherwise, that
14643/// type is erased from that per-corpus map.
14644///
14645/// @param subrange_type the type to consider.
14646void
14648(const array_type_def::subrange_sptr& subrange_type)
14649{
14650 if (translation_unit *tu = subrange_type->get_translation_unit())
14651 maybe_update_types_lookup_map<array_type_def::subrange_type>
14652 (subrange_type, tu->get_types().subrange_types());
14653
14654 if (corpus *type_corpus = subrange_type->get_corpus())
14655 {
14656 maybe_update_types_lookup_map<array_type_def::subrange_type>
14657 (subrange_type,
14658 type_corpus->priv_->get_types().subrange_types());
14659
14660 maybe_update_types_lookup_map<array_type_def::subrange_type>
14661 (subrange_type,
14662 type_corpus->get_type_per_loc_map().subrange_types(),
14663 /*use_type_name_as_key*/false);
14664
14665 if (corpus *group = subrange_type->get_corpus())
14666 {
14667 maybe_update_types_lookup_map<array_type_def::subrange_type>
14668 (subrange_type,
14669 group->priv_->get_types().subrange_types());
14670
14671 maybe_update_types_lookup_map<array_type_def::subrange_type>
14672 (subrange_type,
14673 group->get_type_per_loc_map().subrange_types(),
14674 /*use_type_name_as_key*/false);
14675 }
14676 }
14677}
14678
14679/// Update the map that associates the fully qualified name of a
14680/// function type with the type itself.
14681///
14682/// The per-translation unit type map is updated if no type with this
14683/// name was already existing in that map.
14684///
14685/// If no type with this name did already exist in the per-corpus type
14686/// map, then that per-corpus type map is updated. Otherwise, that
14687/// type is erased from that per-corpus map.
14688///
14689/// @param scope the scope of the function type.
14690/// @param fn_type the type to consider.
14691void
14693{
14694 if (translation_unit *tu = fn_type->get_translation_unit())
14696 (fn_type, tu->get_types().function_types());
14697
14698 if (corpus *type_corpus = fn_type->get_corpus())
14699 {
14701 (fn_type,
14702 type_corpus->priv_->get_types().function_types());
14703
14704 if (corpus *group = fn_type->get_corpus())
14705 {
14707 (fn_type,
14708 group->priv_->get_types().function_types());
14709 }
14710 }
14711}
14712
14713/// Update the map that associates the fully qualified name of a type
14714/// declaration with the type itself.
14715///
14716/// The per-translation unit type map is updated if no type with this
14717/// name was already existing in that map.
14718///
14719/// If no type with this name did already exist in the per-corpus type
14720/// map, then that per-corpus type map is updated. Otherwise, that
14721/// type is erased from that per-corpus map.
14722///
14723/// @param decl the declaration of the type to consider.
14724void
14725maybe_update_types_lookup_map(const decl_base_sptr& decl)
14726{
14727 if (!is_type(decl))
14728 return;
14729
14730 if (type_decl_sptr basic_type = is_type_decl(decl))
14732 else if (class_decl_sptr class_type = is_class_type(decl))
14734 else if (union_decl_sptr union_type = is_union_type(decl))
14736 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
14738 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
14739 maybe_update_types_lookup_map(typedef_type);
14740 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
14741 maybe_update_types_lookup_map(qualified_type);
14742 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
14743 maybe_update_types_lookup_map(pointer_type);
14744 else if (ptr_to_mbr_type_sptr ptr_to_member = is_ptr_to_mbr_type(decl))
14745 maybe_update_types_lookup_map(ptr_to_member);
14746 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
14747 maybe_update_types_lookup_map(reference_type);
14748 else if (array_type_def_sptr array_type = is_array_type(decl))
14750 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
14751 maybe_update_types_lookup_map(subrange_type);
14752 else if (function_type_sptr fn_type = is_function_type(decl))
14754 else
14756}
14757
14758/// Update the map that associates the fully qualified name of a type
14759/// with the type itself.
14760///
14761/// The per-translation unit type map is updated if no type with this
14762/// name was already existing in that map.
14763///
14764/// If no type with this name did already exist in the per-corpus type
14765/// map, then that per-corpus type map is updated. Otherwise, that
14766/// type is erased from that per-corpus map.
14767///
14768/// @param type the type to consider.
14769void
14770maybe_update_types_lookup_map(const type_base_sptr& type)
14771{
14772 if (decl_base_sptr decl = get_type_declaration(type))
14774 else if (function_type_sptr fn_type = is_function_type(type))
14776 else
14778}
14779
14780//--------------------------------
14781// </type and decls lookup stuff>
14782// ------------------------------
14783
14784/// In a translation unit, lookup a given type or synthesize it if
14785/// it's a qualified type.
14786///
14787/// So this function first looks the type up in the translation unit.
14788/// If it's found, then OK, it's returned. Otherwise, if it's a
14789/// qualified, reference or pointer or function type (a composite
14790/// type), lookup the underlying type, synthesize the type we want
14791/// from it and return it.
14792///
14793/// If the underlying types is not not found, then give up and return
14794/// nil.
14795///
14796/// @return the type that was found or the synthesized type.
14797type_base_sptr
14798synthesize_type_from_translation_unit(const type_base_sptr& type,
14799 translation_unit& tu)
14800{
14801 type_base_sptr result;
14802
14803 result = lookup_type(type, tu);
14804
14805 if (!result)
14806 {
14807 if (qualified_type_def_sptr qual = is_qualified_type(type))
14808 {
14809 type_base_sptr underlying_type =
14810 synthesize_type_from_translation_unit(qual->get_underlying_type(),
14811 tu);
14812 if (underlying_type)
14813 {
14814 result.reset(new qualified_type_def(underlying_type,
14815 qual->get_cv_quals(),
14816 qual->get_location()));
14817 }
14818 }
14819 else if (pointer_type_def_sptr p = is_pointer_type(type))
14820 {
14821 type_base_sptr pointed_to_type =
14822 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
14823 tu);
14824 if (pointed_to_type)
14825 {
14826 result.reset(new pointer_type_def(pointed_to_type,
14827 p->get_size_in_bits(),
14828 p->get_alignment_in_bits(),
14829 p->get_location()));
14830 }
14831 }
14832 else if (reference_type_def_sptr r = is_reference_type(type))
14833 {
14834 type_base_sptr pointed_to_type =
14835 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
14836 if (pointed_to_type)
14837 {
14838 result.reset(new reference_type_def(pointed_to_type,
14839 r->is_lvalue(),
14840 r->get_size_in_bits(),
14841 r->get_alignment_in_bits(),
14842 r->get_location()));
14843 }
14844 }
14845 else if (function_type_sptr f = is_function_type(type))
14847
14848 if (result)
14849 {
14851 canonicalize(result);
14852 }
14853 }
14854
14855 if (result)
14856 tu.priv_->synthesized_types_.push_back(result);
14857
14858 return result;
14859}
14860
14861/// In a translation unit, lookup the sub-types that make up a given
14862/// function type and if the sub-types are all found, synthesize and
14863/// return a function_type with them.
14864///
14865/// This function is like lookup_function_type_in_translation_unit()
14866/// execept that it constructs the function type from the sub-types
14867/// found in the translation, rather than just looking for the
14868/// function types held by the translation unit. This can be useful
14869/// if the translation unit doesnt hold the function type we are
14870/// looking for (i.e, lookup_function_type_in_translation_unit()
14871/// returned NULL) but we still want to see if the sub-types of the
14872/// function types are present in the translation unit.
14873///
14874/// @param fn_type the function type to consider.
14875///
14876/// @param tu the translation unit to look into.
14877///
14878/// @return the resulting synthesized function type if all its
14879/// sub-types have been found, NULL otherwise.
14882 translation_unit& tu)
14883{
14885
14886 const environment& env = tu.get_environment();
14887
14888 type_base_sptr return_type = fn_type.get_return_type();
14889 type_base_sptr result_return_type;
14890 if (!return_type || env.is_void_type(return_type))
14891 result_return_type = env.get_void_type();
14892 else
14893 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
14894 if (!result_return_type)
14895 return nil;
14896
14898 type_base_sptr parm_type;
14900 for (function_type::parameters::const_iterator i =
14901 fn_type.get_parameters().begin();
14902 i != fn_type.get_parameters().end();
14903 ++i)
14904 {
14905 type_base_sptr t = (*i)->get_type();
14906 parm_type = synthesize_type_from_translation_unit(t, tu);
14907 if (!parm_type)
14908 return nil;
14909 parm.reset(new function_decl::parameter(parm_type,
14910 (*i)->get_index(),
14911 (*i)->get_name(),
14912 (*i)->get_location(),
14913 (*i)->get_variadic_marker(),
14914 (*i)->get_is_artificial()));
14915 parms.push_back(parm);
14916 }
14917
14918 class_or_union_sptr class_type;
14919 const method_type* method = is_method_type(&fn_type);
14920 if (method)
14921 {
14922 class_type = is_class_or_union_type
14924 ABG_ASSERT(class_type);
14925 }
14926
14927 function_type_sptr result_fn_type;
14928
14929 if (class_type)
14930 result_fn_type.reset(new method_type(result_return_type,
14931 class_type,
14932 parms,
14933 method->get_is_const(),
14934 fn_type.get_size_in_bits(),
14935 fn_type.get_alignment_in_bits()));
14936 else
14937 result_fn_type.reset(new function_type(result_return_type,
14938 parms,
14939 fn_type.get_size_in_bits(),
14940 fn_type.get_alignment_in_bits()));
14941
14942 tu.priv_->synthesized_types_.push_back(result_fn_type);
14943 tu.bind_function_type_life_time(result_fn_type);
14944
14945 canonicalize(result_fn_type);
14946 return result_fn_type;
14947}
14948
14949/// Demangle a C++ mangled name and return the resulting string
14950///
14951/// @param mangled_name the C++ mangled name to demangle.
14952///
14953/// @return the resulting mangled name.
14954string
14955demangle_cplus_mangled_name(const string& mangled_name)
14956{
14957 if (mangled_name.empty())
14958 return "";
14959
14960 size_t l = 0;
14961 int status = 0;
14962 char * str = abi::__cxa_demangle(mangled_name.c_str(),
14963 NULL, &l, &status);
14964 string demangled_name = mangled_name;
14965 if (str)
14966 {
14967 ABG_ASSERT(status == 0);
14968 demangled_name = str;
14969 free(str);
14970 str = 0;
14971 }
14972 return demangled_name;
14973}
14974
14975/// Return either the type given in parameter if it's non-null, or the
14976/// void type.
14977///
14978/// @param t the type to consider.
14979///
14980/// @param env the environment to use. If NULL, just abort the
14981/// process.
14982///
14983/// @return either @p t if it is non-null, or the void type.
14984type_base_sptr
14985type_or_void(const type_base_sptr t, const environment& env)
14986{
14987 type_base_sptr r;
14988
14989 if (t)
14990 r = t;
14991 else
14992 r = type_base_sptr(env.get_void_type());
14993
14994 return r;
14995}
14996
14997global_scope::~global_scope()
14998{
14999}
15000
15001static bool
15002maybe_propagate_canonical_type(const type_base& lhs_type,
15003 const type_base& rhs_type);
15004
15005/// Test if two types are eligible to the "Linux Kernel Fast Type
15006/// Comparison Optimization", a.k.a LKFTCO.
15007///
15008/// Two types T1 and T2 (who are presumably of the same name and kind)
15009/// are eligible to the LKFTCO if they fulfill the following criteria/
15010///
15011/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
15012/// either class, union or enums.
15013///
15014/// 2/ They are defined in the same translation unit.
15015///
15016/// @param t1 the first type to consider.
15017///
15018/// @param t2 the second type to consider.
15019///
15020/// @return true iff t1 and t2 are eligible to the LKFTCO.
15021static bool
15022types_defined_same_linux_kernel_corpus_public(const type_base& t1,
15023 const type_base& t2)
15024{
15025 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
15026 string t1_file_path, t2_file_path;
15027
15028 /// If the t1 (and t2) are classes/unions/enums from the same linux
15029 /// kernel corpus, let's move on. Otherwise bail out.
15030 if (!(t1_corpus && t2_corpus
15031 && t1_corpus == t2_corpus
15032 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
15033 && (is_class_or_union_type(&t1)
15034 || is_enum_type(&t1))))
15035 return false;
15036
15037 class_or_union *c1 = 0, *c2 = 0;
15038 c1 = is_class_or_union_type(&t1);
15039 c2 = is_class_or_union_type(&t2);
15040
15041 // Two anonymous class types with no naming typedefs cannot be
15042 // eligible to this optimization.
15043 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
15044 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
15045 return false;
15046
15047 // Two anonymous classes with naming typedefs should have the same
15048 // typedef name.
15049 if (c1
15050 && c2
15051 && c1->get_is_anonymous() && c1->get_naming_typedef()
15052 && c2->get_is_anonymous() && c2->get_naming_typedef())
15053 if (c1->get_naming_typedef()->get_name()
15054 != c2->get_naming_typedef()->get_name())
15055 return false;
15056
15057 // Two anonymous enum types cannot be eligible to this optimization.
15058 if (const enum_type_decl *e1 = is_enum_type(&t1))
15059 if (const enum_type_decl *e2 = is_enum_type(&t2))
15060 if (e1->get_is_anonymous() || e2->get_is_anonymous())
15061 return false;
15062
15063 // Look through declaration-only types. That is, get the associated
15064 // definition type.
15067
15068 if (c1 && c2)
15069 {
15070 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
15071 {
15072 if (c1->get_environment().decl_only_class_equals_definition())
15073 // At least one of classes/union is declaration-only.
15074 // Because we are in a context in which a declaration-only
15075 // class/union is equal to all definitions of that
15076 // class/union, we can assume that the two types are
15077 // equal.
15078 return true;
15079 }
15080 }
15081
15082 if (t1.get_size_in_bits() != t2.get_size_in_bits())
15083 return false;
15084
15085 // Look at the file names of the locations of t1 and t2. If they
15086 // are equal, then t1 and t2 are defined in the same file.
15087 {
15088 location l;
15089
15090 if (c1)
15091 l = c1->get_location();
15092 else
15093 l = dynamic_cast<const decl_base&>(t1).get_location();
15094
15095 unsigned line = 0, col = 0;
15096 if (l)
15097 l.expand(t1_file_path, line, col);
15098 if (c2)
15099 l = c2->get_location();
15100 else
15101 l = dynamic_cast<const decl_base&>(t2).get_location();
15102 if (l)
15103 l.expand(t2_file_path, line, col);
15104 }
15105
15106 if (t1_file_path.empty() || t2_file_path.empty())
15107 return false;
15108
15109 if (t1_file_path == t2_file_path)
15110 return true;
15111
15112 return false;
15113}
15114
15115
15116/// Compare a type T against a canonical type.
15117///
15118/// This function is called during the canonicalization process of the
15119/// type T. T is called the "candidate type" because it's in the
15120/// process of being canonicalized. Meaning, it's going to be
15121/// compared to a canonical type C. If T equals C, then the canonical
15122/// type of T is C.
15123///
15124/// The purpose of this function is to allow the debugging of the
15125/// canonicalization of T, if that debugging is activated by
15126/// configuring the libabigail package with
15127/// --enable-debug-type-canonicalization and by running "abidw
15128/// --debug-tc". In that case, T is going to be compared to C twice:
15129/// once with canonical equality and once with structural equality.
15130/// The two comparisons must be equal. Otherwise, the
15131/// canonicalization process is said to be faulty and this function
15132/// aborts.
15133///
15134/// This is a sub-routine of type_base::get_canonical_type_for.
15135///
15136/// @param canonical_type the canonical type to compare the candidate
15137/// type against.
15138///
15139/// @param candidate_type the candidate type to compare against the
15140/// canonical type.
15141///
15142/// @return true iff @p canonical_type equals @p candidate_type.
15143///
15144static bool
15145compare_types_during_canonicalization(const type_base& canonical_type,
15146 const type_base& candidate_type)
15147{
15148#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
15149 const environment& env = canonical_type.get_environment();
15150 if (env.debug_type_canonicalization_is_on())
15151 {
15152 bool canonical_equality = false, structural_equality = false;
15153 env.priv_->use_canonical_type_comparison_ = false;
15154 structural_equality = canonical_type == candidate_type;
15155 env.priv_->use_canonical_type_comparison_ = true;
15156 canonical_equality = canonical_type == candidate_type;
15157 if (canonical_equality != structural_equality)
15158 {
15159 std::cerr << "structural & canonical equality different for type: "
15160 << canonical_type.get_pretty_representation(true, true)
15161 << std::endl;
15163 }
15164 return structural_equality;
15165 }
15166#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
15167 return canonical_type == candidate_type;
15168}
15169
15170/// Compare a canonical type against a candidate canonical type.
15171///
15172/// This is ultimately a sub-routine of the
15173/// type_base::get_canonical_type_for().
15174///
15175/// The goal of this function is to ease debugging because it can be
15176/// called from within type_base::get_canonical_type_for() from the
15177/// prompt of the debugger (with some breakpoint appropriately set) to
15178/// debug the comparison that happens during type canonicalization,
15179/// between a candidate type being canonicalized, and an existing
15180/// canonical type that is registered in the system, in as returned by
15181/// environment::get_canonical_types()
15182///
15183/// @param canonical_type the canonical type to consider.
15184///
15185/// @param candidate_type the candidate type that is being
15186/// canonicalized, and thus compared to @p canonical_type.
15187///
15188/// @return true iff @p canonical_type compares equal to @p
15189/// candidate_type.
15190static bool
15191compare_canonical_type_against_candidate(const type_base& canonical_type,
15192 const type_base& candidate_type)
15193{
15194 environment& env = const_cast<environment&>(canonical_type.get_environment());
15195
15196 // Before the "*it == it" comparison below is done, let's
15197 // perform on-the-fly-canonicalization. For C types, let's
15198 // consider that an unresolved struct declaration 'struct S'
15199 // is different from a definition 'struct S'. This is
15200 // because normally, at this point all the declarations of
15201 // struct S that are compatible with the definition of
15202 // struct S have already been resolved to that definition,
15203 // during the DWARF parsing. The remaining unresolved
15204 // declaration are thus considered different. With this
15205 // setup we can properly handle cases of two *different*
15206 // struct S being defined in the same binary (in different
15207 // translation units), and a third struct S being only
15208 // declared as an opaque type in a third translation unit of
15209 // its own, with no definition in there. In that case, the
15210 // declaration-only struct S should be left alone and not
15211 // resolved to any of the two definitions of struct S.
15212 bool saved_decl_only_class_equals_definition =
15213 env.decl_only_class_equals_definition();
15214 env.do_on_the_fly_canonicalization(true);
15215 // Compare types by considering that decl-only classes don't
15216 // equal their definition.
15217 env.decl_only_class_equals_definition(false);
15218 env.priv_->allow_type_comparison_results_caching(true);
15219 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
15220 candidate_type)
15221 || compare_types_during_canonicalization(canonical_type,
15222 candidate_type));
15223 // Restore the state of the on-the-fly-canonicalization and
15224 // the decl-only-class-being-equal-to-a-matching-definition
15225 // flags.
15226 env.priv_->clear_type_comparison_results_cache();
15227 env.priv_->allow_type_comparison_results_caching(false);
15228 env.do_on_the_fly_canonicalization(false);
15229 env.decl_only_class_equals_definition
15230 (saved_decl_only_class_equals_definition);
15231 return equal;
15232}
15233
15234/// Compare a canonical type against a candidate canonical type.
15235///
15236/// This is ultimately a sub-routine of the
15237/// type_base::get_canonical_type_for().
15238///
15239/// The goal of this function is to ease debugging because it can be
15240/// called from within type_base::get_canonical_type_for() from the
15241/// prompt of the debugger (with some breakpoint appropriately set) to
15242/// debug the comparison that happens during type canonicalization,
15243/// between a candidate type being canonicalized, and an existing
15244/// canonical type that is registered in the system, in as returned by
15245/// environment::get_canonical_types()
15246///
15247/// @param canonical_type the canonical type to consider.
15248///
15249/// @param candidate_type the candidate type that is being
15250/// canonicalized, and thus compared to @p canonical_type.
15251///
15252/// @return true iff @p canonical_type compares equal to @p
15253/// candidate_type.
15254static bool
15255compare_canonical_type_against_candidate(const type_base* canonical_type,
15256 const type_base* candidate_type)
15257{
15258 return compare_canonical_type_against_candidate(*canonical_type,
15259 *candidate_type);
15260}
15261
15262/// Compare a canonical type against a candidate canonical type.
15263///
15264/// This is ultimately a sub-routine of the
15265/// type_base::get_canonical_type_for().
15266///
15267/// The goal of this function is to ease debugging because it can be
15268/// called from within type_base::get_canonical_type_for() from the
15269/// prompt of the debugger (with some breakpoint appropriately set) to
15270/// debug the comparison that happens during type canonicalization,
15271/// between a candidate type being canonicalized, and an existing
15272/// canonical type that is registered in the system, in as returned by
15273/// environment::get_canonical_types()
15274///
15275/// @param canonical_type the canonical type to consider.
15276///
15277/// @param candidate_type the candidate type that is being
15278/// canonicalized, and thus compared to @p canonical_type.
15279///
15280/// @return true iff @p canonical_type compares equal to @p
15281/// candidate_type.
15282static bool
15283compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15284 const type_base_sptr& candidate_type)
15285{
15286 return compare_canonical_type_against_candidate(canonical_type.get(),
15287 candidate_type.get());
15288}
15289
15290/// Compute the canonical type for a given instance of @ref type_base.
15291///
15292/// Consider two types T and T'. The canonical type of T, denoted
15293/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
15294/// otherwise, to compare two types, one just needs to compare their
15295/// canonical types using pointer equality. That makes type
15296/// comparison faster than the structural comparison performed by the
15297/// abigail::ir::equals() overloads.
15298///
15299/// If there is not yet any canonical type for @p t, then @p t is its
15300/// own canonical type. Otherwise, this function returns the
15301/// canonical type of @p t which is the canonical type that has the
15302/// same hash value as @p t and that structurally equals @p t. Note
15303/// that after invoking this function, the life time of the returned
15304/// canonical time is then equals to the life time of the current
15305/// process.
15306///
15307/// @param t a smart pointer to instance of @ref type_base we want to
15308/// compute a canonical type for.
15309///
15310/// @return the canonical type for the current instance of @ref
15311/// type_base.
15312type_base_sptr
15313type_base::get_canonical_type_for(type_base_sptr t)
15314{
15315 if (!t)
15316 return t;
15317
15318 environment& env = const_cast<environment&>(t->get_environment());
15319
15321 // This type should not be canonicalized!
15322 return type_base_sptr();
15323
15324 if (is_decl(t))
15326
15327 // Look through decl-only types (classes, unions and enums)
15328 bool decl_only_class_equals_definition =
15329 (odr_is_relevant(*t) || env.decl_only_class_equals_definition());
15330
15331 class_or_union_sptr class_or_union = is_class_or_union_type(t);
15332
15333 // In the context of types from C++ or languages where we assume the
15334 // "One Definition Rule", we assume that a declaration-only
15335 // non-anonymous class equals all fully defined classes of the same
15336 // name.
15337 //
15338 // Otherwise, all classes, including declaration-only classes are
15339 // canonicalized and only canonical comparison is going to be used
15340 // in the system.
15341 if (decl_only_class_equals_definition)
15342 if (class_or_union)
15343 if (class_or_union->get_is_declaration_only())
15344 return type_base_sptr();
15345
15346 class_decl_sptr is_class = is_class_type(t);
15347 if (t->get_canonical_type())
15348 return t->get_canonical_type();
15349
15350 // For classes and union, ensure that an anonymous class doesn't
15351 // have a linkage name. If it does in the future, then me must be
15352 // mindful that the linkage name respects the type identity
15353 // constraints which states that "if two linkage names are different
15354 // then the two types are different".
15355 ABG_ASSERT(!class_or_union
15356 || !class_or_union->get_is_anonymous()
15357 || class_or_union->get_linkage_name().empty());
15358
15359 // We want the pretty representation of the type, but for an
15360 // internal use, not for a user-facing purpose.
15361 //
15362 // If two classe types Foo are declared, one as a class and the
15363 // other as a struct, but are otherwise equivalent, we want their
15364 // pretty representation to be the same. Hence the 'internal'
15365 // argument of ir::get_pretty_representation() is set to true here.
15366 // So in this case, the pretty representation of Foo is going to be
15367 // "class Foo", regardless of its struct-ness. This also applies to
15368 // composite types which would have "class Foo" as a sub-type.
15369 string repr = t->get_cached_pretty_representation(/*internal=*/true);
15370
15371 // If 't' already has a canonical type 'inside' its corpus
15372 // (t_corpus), then this variable is going to contain that canonical
15373 // type.
15374 type_base_sptr canonical_type_present_in_corpus;
15376 env.get_canonical_types_map();
15377
15378 type_base_sptr result;
15379 environment::canonical_types_map_type::iterator i = types.find(repr);
15380 if (i == types.end())
15381 {
15382 vector<type_base_sptr> v;
15383 v.push_back(t);
15384 types[repr] = v;
15385 result = t;
15386 }
15387 else
15388 {
15389 vector<type_base_sptr> &v = i->second;
15390 // Let's compare 't' structurally (i.e, compare its sub-types
15391 // recursively) against the canonical types of the system. If it
15392 // equals a given canonical type C, then it means C is the
15393 // canonical type of 't'. Otherwise, if 't' is different from
15394 // all the canonical types of the system, then it means 't' is a
15395 // canonical type itself.
15396 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15397 it != v.rend();
15398 ++it)
15399 {
15400 bool equal = compare_canonical_type_against_candidate(*it, t);
15401 if (equal)
15402 {
15403 result = *it;
15404 break;
15405 }
15406 }
15407#ifdef WITH_DEBUG_SELF_COMPARISON
15408 if (env.self_comparison_debug_is_on())
15409 {
15410 // So we are debugging the canonicalization process,
15411 // possibly via the use of 'abidw --debug-abidiff <binary>'.
15412 corpus_sptr corp1, corp2;
15413 env.get_self_comparison_debug_inputs(corp1, corp2);
15414 if (corp1 && corp2 && t->get_corpus() == corp2.get())
15415 {
15416 // If 't' comes from the second corpus, then it *must*
15417 // be equal to its matching canonical type coming from
15418 // the first corpus because the second corpus is the
15419 // abixml representation of the first corpus. In other
15420 // words, all types coming from the second corpus must
15421 // have canonical types coming from the first corpus.
15422 if (result)
15423 {
15424 if (!env.priv_->
15425 check_canonical_type_from_abixml_during_self_comp(t,
15426 result))
15427 {
15428 // The canonical type of the type re-read from abixml
15429 // type doesn't match the canonical type that was
15430 // initially serialized down.
15431 uintptr_t should_have_canonical_type = 0;
15432 string type_id = env.get_type_id_from_type(t.get());
15433 if (type_id.empty())
15434 type_id = "type-id-<not-found>";
15435 else
15436 should_have_canonical_type =
15437 env.get_canonical_type_from_type_id(type_id.c_str());
15438 std::cerr << "error: wrong canonical type for '"
15439 << repr
15440 << "' / type: @"
15441 << std::hex
15442 << t.get()
15443 << "/ canon: @"
15444 << result.get()
15445 << ", type-id: '"
15446 << type_id
15447 << "'. Should have had canonical type: "
15448 << std::hex
15449 << should_have_canonical_type
15450 << std::endl;
15451 }
15452 }
15453 else //!result
15454 {
15455 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
15456 string type_id = env.get_type_id_from_pointer(ptr_val);
15457 if (type_id.empty())
15458 type_id = "type-id-<not-found>";
15459 // We are in the case where 't' is different from all
15460 // the canonical types of the same name that come from
15461 // the first corpus.
15462 //
15463 // If 't' indeed comes from the second corpus then this
15464 // clearly is a canonicalization failure.
15465 //
15466 // There was a problem either during the serialization
15467 // of 't' into abixml, or during the de-serialization
15468 // from abixml into abigail::ir. Further debugging is
15469 // needed to determine what that root cause problem is.
15470 //
15471 // Note that the first canonicalization problem of this
15472 // kind must be fixed before looking at the subsequent
15473 // ones, because the later might well just be
15474 // consequences of the former.
15475 std::cerr << "error: wrong induced canonical type for '"
15476 << repr
15477 << "' from second corpus"
15478 << ", ptr: " << std::hex << t.get()
15479 << " type-id: " << type_id
15480 << std::endl;
15481 }
15482 }
15483 }
15484#endif //WITH_DEBUG_SELF_COMPARISON
15485
15486 if (!result)
15487 {
15488 v.push_back(t);
15489 result = t;
15490 }
15491 }
15492
15493 return result;
15494}
15495
15496/// This method is invoked automatically right after the current
15497/// instance of @ref class_decl has been canonicalized.
15498void
15500{}
15501
15502/// This is a subroutine of the canonicalize() function.
15503///
15504/// When the canonical type C of type T has just been computed, there
15505/// can be cases where T has member functions that C doesn't have.
15506///
15507/// This is possible because non virtual member functions are not
15508/// taken in account when comparing two types.
15509///
15510/// In that case, this function updates C so that it contains the
15511/// member functions.
15512///
15513/// There can also be cases where C has a method M which is not linked
15514/// to any underlying symbol, whereas in T, M is to link to an
15515/// underlying symbol. In that case, this function updates M in C so
15516/// that it's linked to the same underlying symbol as for M in T.
15517static void
15518maybe_adjust_canonical_type(const type_base_sptr& canonical,
15519 const type_base_sptr& type)
15520{
15521 if (type->get_naked_canonical_type())
15522 return;
15523
15524 class_decl_sptr canonical_class = is_class_type(canonical);
15525
15526 if (class_decl_sptr cl = is_class_type(type))
15527 {
15528 if (canonical_class
15529 && canonical_class.get() != cl.get())
15530 {
15531 // Set symbols of member functions that might be missing
15532 // theirs.
15533 for (class_decl::member_functions::const_iterator i =
15534 cl->get_member_functions().begin();
15535 i != cl->get_member_functions().end();
15536 ++i)
15537 if ((*i)->get_symbol())
15538 {
15539 if (method_decl *m = canonical_class->
15540 find_member_function((*i)->get_linkage_name()))
15541 {
15542 elf_symbol_sptr s1 = (*i)->get_symbol();
15543 if (s1 && !m->get_symbol())
15544 // Method 'm' in the canonical type is not
15545 // linked to the underlying symbol of '*i'.
15546 // Let's link it now. have th
15547 m->set_symbol(s1);
15548 }
15549 else
15550 if (canonical_class->get_corpus()
15551 && cl->get_corpus()
15552 && (cl->get_corpus() == canonical_class->get_corpus()))
15553 // There is a member function defined and publicly
15554 // exported in the other class and the canonical
15555 // class doesn't have that member function. This
15556 // should not have happened! For instance, the
15557 // DWARF reader does merge the member functions of
15558 // classes having the same name so that all of them
15559 // end-up having the same member functions. What's
15560 // going on here?
15562 }
15563 }
15564 }
15565
15566 // Make sure the virtual member functions with exported symbols are
15567 // all added to the set of exported functions of the corpus.
15568
15569 // If we are looking at a non-canonicalized class (for instance, a
15570 // decl-only class that has virtual member functoins), let's pretend
15571 // it does have a canonical class so that we can perform the
15572 // necessary virtual member function adjustments
15573 if (class_decl_sptr cl = is_class_type(type))
15575 {
15576 ABG_ASSERT(!canonical_class);
15577 canonical_class = cl;
15578 }
15579
15580 if (canonical_class)
15581 {
15582 if (auto abi_corpus = canonical_class->get_corpus())
15583 {
15584 for (auto& fn : canonical_class->get_member_functions())
15585 {
15586 if (elf_symbol_sptr sym = fn->get_symbol())
15587 {
15588 if (sym->is_defined() && sym->is_public())
15589 {
15590 fn->set_is_in_public_symbol_table(true);
15591 auto b = abi_corpus->get_exported_decls_builder();
15592 b->maybe_add_fn_to_exported_fns(fn.get());
15593 }
15594 else if (!sym->is_defined())
15595 abi_corpus->get_undefined_functions().insert(fn.get());
15596 }
15597 }
15598 }
15599 }
15600
15601 // If an artificial function type equals a non-artfificial one in
15602 // the system, then the canonical type of both should be deemed
15603 // non-artificial. This is important because only non-artificial
15604 // canonical function types are emitted out into abixml, so if don't
15605 // do this we risk missing to emit some function types.
15606 if (is_function_type(type))
15607 if (type->get_is_artificial() != canonical->get_is_artificial())
15608 canonical->set_is_artificial(false);
15609}
15610
15611/// Compute the canonical type of a given type.
15612///
15613/// It means that after invoking this function, comparing the intance
15614/// instance @ref type_base and another one (on which
15615/// type_base::enable_canonical_equality() would have been invoked as
15616/// well) is performed by just comparing the pointer values of the
15617/// canonical types of both types. That equality comparison is
15618/// supposedly faster than structural comparison of the types.
15619///
15620/// @param t a smart pointer to the instance of @ref type_base for
15621/// which to compute the canonical type. After this call,
15622/// t->get_canonical_type() will return the newly computed canonical
15623/// type.
15624///
15625/// @return the canonical type computed for @p t.
15626type_base_sptr
15627canonicalize(type_base_sptr t)
15628{
15629 if (!t)
15630 return t;
15631
15632 if (t->get_canonical_type())
15633 return t->get_canonical_type();
15634
15635 if (t->get_environment().priv_->do_log())
15636 std::cerr << "Canonicalization of type '"
15637 << t->get_pretty_representation(true, true)
15638 << "/@#" << std::hex << t.get() << ": ";
15639
15641
15642 if (t->get_environment().priv_->do_log())
15643 tmr.start();
15644 type_base_sptr canonical = type_base::get_canonical_type_for(t);
15645
15646 if (t->get_environment().priv_->do_log())
15647 tmr.stop();
15648
15649 if (t->get_environment().priv_->do_log())
15650 std::cerr << tmr << "\n";
15651
15652 maybe_adjust_canonical_type(canonical, t);
15653
15654 t->priv_->canonical_type = canonical;
15655 t->priv_->naked_canonical_type = canonical.get();
15656
15657 // So this type is now canonicalized.
15658 //
15659 // It means that:
15660 //
15661 // 1/ Either the canonical type was not propagated during the
15662 // comparison of another type that was being canonicalized
15663 //
15664 // 2/ Or the canonical type has been propagated during the
15665 // comparison of another type that was being canonicalized and
15666 // that propagated canonical type has been confirmed, because
15667 // it was depending on a recursive type which comparison
15668 // succeeded.
15669 ABG_ASSERT(!t->priv_->canonical_type_propagated()
15670 || t->priv_->propagated_canonical_type_confirmed());
15671
15672 if (class_decl_sptr cl = is_class_type(t))
15673 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
15674 if ((canonical = d->get_canonical_type()))
15675 {
15676 d->priv_->canonical_type = canonical;
15677 d->priv_->naked_canonical_type = canonical.get();
15678 }
15679
15680 if (canonical)
15681 {
15682 if (decl_base_sptr d = is_decl_slow(canonical))
15683 {
15684 scope_decl *scope = d->get_scope();
15685 // Add the canonical type to the set of canonical types
15686 // belonging to its scope.
15687 if (scope)
15688 {
15689 if (is_type(scope))
15690 // The scope in question is itself a type (e.g, a class
15691 // or union). Let's call that type ST. We want to add
15692 // 'canonical' to the set of canonical types belonging
15693 // to ST.
15694 if (type_base_sptr c = is_type(scope)->get_canonical_type())
15695 // We want to add 'canonical' to set of canonical
15696 // types belonging to the canonical type of ST. That
15697 // way, just looking at the canonical type of ST is
15698 // enough to get the types that belong to the scope of
15699 // the class of equivalence of ST.
15700 scope = is_scope_decl(is_decl(c)).get();
15701 scope->get_canonical_types().insert(canonical);
15702 }
15703 // else, if the type doesn't have a scope, it's not meant to be
15704 // emitted. This can be the case for the result of the
15705 // function strip_typedef, for instance.
15706 }
15707
15708#ifdef WITH_DEBUG_CT_PROPAGATION
15709 // Update the book-keeping of the set of the types which
15710 // propagated canonical type has been cleared.
15711 //
15712 // If this type 't' which has just been canonicalized was
15713 // previously in the set of types which propagated canonical
15714 // type has been cleared, then remove it from that set because
15715 // its canonical type is now computed and definitely set.
15716 const environment& env = t->get_environment();
15717 env.priv_->erase_type_with_cleared_propagated_canonical_type(t.get());
15718#endif
15719 }
15720
15721 t->on_canonical_type_set();
15722 return canonical;
15723}
15724
15725/// Set the definition of this declaration-only @ref decl_base.
15726///
15727/// @param d the new definition to set.
15728void
15730{
15732 priv_->definition_of_declaration_ = d;
15733 if (type_base *t = is_type(this))
15734 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
15735 t->priv_->canonical_type = canonical_type;
15736
15737 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
15738}
15739
15740/// The constructor of @ref type_base.
15741///
15742/// @param s the size of the type, in bits.
15743///
15744/// @param a the alignment of the type, in bits.
15745type_base::type_base(const environment& e, size_t s, size_t a)
15746 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
15747 priv_(new priv(s, a))
15748{}
15749
15750/// Getter of the canonical type of the current instance of @ref
15751/// type_base.
15752///
15753/// @return a smart pointer to the canonical type of the current
15754/// intance of @ref type_base, or an empty smart pointer if the
15755/// current instance of @ref type_base doesn't have any canonical
15756/// type.
15757type_base_sptr
15759{return priv_->canonical_type.lock();}
15760
15761/// Getter of the canonical type pointer.
15762///
15763/// Note that this function doesn't return a smart pointer, but rather
15764/// the underlying pointer managed by the smart pointer. So it's as
15765/// fast as possible. This getter is to be used in code paths that
15766/// are proven to be performance hot spots; especially, when comparing
15767/// sensitive types like class, function, pointers and reference
15768/// types. Those are compared extremely frequently and thus, their
15769/// accessing the canonical type must be fast.
15770///
15771/// @return the canonical type pointer, not managed by a smart
15772/// pointer.
15773type_base*
15775{return priv_->naked_canonical_type;}
15776
15777/// Get the pretty representation of the current type.
15778///
15779/// The pretty representation is retrieved from a cache. If the cache
15780/// is empty, this function computes the pretty representation, put it
15781/// in the cache and returns it.
15782///
15783/// Note that if the type is *NOT* canonicalized, the pretty
15784/// representation is never cached.
15785///
15786/// @param internal if true, then the pretty representation is to be
15787/// used for purpuses that are internal to the libabigail library
15788/// itself. If you don't know what this means, then you probably
15789/// should set this parameter to "false".
15790const interned_string&
15792{
15793 if (internal)
15794 {
15795 if (!get_naked_canonical_type() || priv_->internal_cached_repr_.empty())
15796 {
15797 string r = ir::get_pretty_representation(this, internal);
15798 priv_->internal_cached_repr_ = get_environment().intern(r);
15799 }
15800 return priv_->internal_cached_repr_;
15801 }
15802
15803 if (!get_naked_canonical_type() || priv_->cached_repr_.empty())
15804 {
15805 string r = ir::get_pretty_representation(this, internal);
15806 priv_->cached_repr_ = get_environment().intern(r);
15807 }
15808
15809 return priv_->cached_repr_;
15810}
15811
15812/// Compares two instances of @ref type_base.
15813///
15814/// If the two intances are different, set a bitfield to give some
15815/// insight about the kind of differences there are.
15816///
15817/// @param l the first artifact of the comparison.
15818///
15819/// @param r the second artifact of the comparison.
15820///
15821/// @param k a pointer to a bitfield that gives information about the
15822/// kind of changes there are between @p l and @p r. This one is set
15823/// iff @p is non-null and if the function returns false.
15824///
15825/// Please note that setting k to a non-null value does have a
15826/// negative performance impact because even if @p l and @p r are not
15827/// equal, the function keeps up the comparison in order to determine
15828/// the different kinds of ways in which they are different.
15829///
15830/// @return true if @p l equals @p r, false otherwise.
15831bool
15832equals(const type_base& l, const type_base& r, change_kind* k)
15833{
15834 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
15836 if (!result)
15837 if (k)
15839 ABG_RETURN(result);
15840}
15841
15842/// Return true iff both type declarations are equal.
15843///
15844/// Note that this doesn't test if the scopes of both types are equal.
15845bool
15847{return equals(*this, other, 0);}
15848
15849/// Inequality operator.
15850///
15851///@param other the instance of @ref type_base to compare the current
15852/// instance against.
15853///
15854/// @return true iff the current instance is different from @p other.
15855bool
15857{return !operator==(other);}
15858
15859/// Setter for the size of the type.
15860///
15861/// @param s the new size -- in bits.
15862void
15864{priv_->size_in_bits = s;}
15865
15866/// Getter for the size of the type.
15867///
15868/// @return the size in bits of the type.
15869size_t
15871{return priv_->size_in_bits;}
15872
15873/// Setter for the alignment of the type.
15874///
15875/// @param a the new alignment -- in bits.
15876void
15878{priv_->alignment_in_bits = a;}
15879
15880/// Getter for the alignment of the type.
15881///
15882/// @return the alignment of the type in bits.
15883size_t
15885{return priv_->alignment_in_bits;}
15886
15887/// Default implementation of traversal for types. This function does
15888/// nothing. It must be implemented by every single new type that is
15889/// written.
15890///
15891/// Please look at e.g, class_decl::traverse() for an example of how
15892/// to implement this.
15893///
15894/// @param v the visitor used to visit the type.
15895bool
15897{
15898 if (v.type_node_has_been_visited(this))
15899 return true;
15900
15901 v.visit_begin(this);
15902 bool result = v.visit_end(this);
15904
15905 return result;
15906}
15907
15908type_base::~type_base()
15909{delete priv_;}
15910
15911// </type_base definitions>
15912
15913// <integral_type definitions>
15914
15915/// Bitwise OR operator for integral_type::modifiers_type.
15916///
15917/// @param l the left-hand side operand.
15918///
15919/// @param r the right-hand side operand.
15920///
15921/// @return the result of the bitwise OR.
15924{
15925 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
15926 |
15927 static_cast<unsigned>(r));
15928}
15929
15930/// Bitwise AND operator for integral_type::modifiers_type.
15931///
15932/// @param l the left-hand side operand.
15933///
15934/// @param r the right-hand side operand.
15935///
15936/// @return the result of the bitwise AND.
15939{
15940 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
15941 &
15942 static_cast<unsigned>(r));
15943}
15944
15945/// Bitwise one's complement operator for integral_type::modifiers_type.
15946///
15947/// @param l the left-hand side operand.
15948///
15949/// @param r the right-hand side operand.
15950///
15951/// @return the result of the bitwise one's complement operator.
15954{
15955 return static_cast<integral_type::modifiers_type>(~static_cast<unsigned>(l));
15956}
15957
15958/// Bitwise |= operator for integral_type::modifiers_type.
15959///
15960/// @param l the left-hand side operand.
15961///
15962/// @param r the right-hand side operand.
15963///
15964/// @return the result of the bitwise |=.
15967{
15968 l = l | r;
15969 return l;
15970}
15971
15972/// Bitwise &= operator for integral_type::modifiers_type.
15973///
15974/// @param l the left-hand side operand.
15975///
15976/// @param r the right-hand side operand.
15977///
15978/// @return the result of the bitwise &=.
15981{
15982 l = l & r;
15983 return l;
15984}
15985
15986/// Parse a word containing one integral type modifier.
15987///
15988/// A word is considered to be a string of characters that doesn't
15989/// contain any white space.
15990///
15991/// @param word the word to parse. It is considered to be a string of
15992/// characters that doesn't contain any white space.
15993///
15994/// @param modifiers out parameter. It's set by this function to the
15995/// parsed modifier iff the function returned true.
15996///
15997/// @return true iff @word was successfully parsed.
15998static bool
15999parse_integral_type_modifier(const string& word,
16001{
16002 if (word == "signed")
16003 modifiers |= integral_type::SIGNED_MODIFIER;
16004 else if (word == "unsigned")
16006 else if (word == "short")
16007 modifiers |= integral_type::SHORT_MODIFIER;
16008 else if (word == "long")
16009 modifiers |= integral_type::LONG_MODIFIER;
16010 else if (word == "long long")
16012 else
16013 return false;
16014
16015 return true;
16016}
16017
16018/// Parse a base type of an integral type from a string.
16019///
16020/// @param type_name the type name to parse.
16021///
16022/// @param base out parameter. This is set to the resulting base type
16023/// parsed, iff the function returned true.
16024///
16025/// @return true iff the function could successfully parse the base
16026/// type.
16027static bool
16028parse_base_integral_type(const string& type_name,
16030{
16031 if (type_name == "int")
16033 else if (type_name == "char")
16035 else if (type_name == "bool" || type_name == "_Bool")
16037 else if (type_name == "double")
16039 else if (type_name =="float")
16041 else if (type_name == "char16_t")
16043 else if (type_name == "char32_t")
16045 else if (type_name == "wchar_t")
16047 else
16048 return false;
16049
16050 return true;
16051}
16052
16053/// Parse an integral type from a string.
16054///
16055/// @param type_name the string containing the integral type to parse.
16056///
16057/// @param base out parameter. Is set by this function to the base
16058/// type of the integral type, iff the function returned true.
16059///
16060/// @param modifiers out parameter If set by this function to the
16061/// modifier of the integral type, iff the function returned true.
16062///
16063/// @return true iff the function could parse an integral type from @p
16064/// type_name.
16065static bool
16066parse_integral_type(const string& type_name,
16069{
16070 string input = type_name;
16071 string::size_type len = input.length();
16072 string::size_type cur_pos = 0, prev_pos = 0;
16073 string cur_word, prev_word;
16074 bool ok = false;
16075
16076 while (cur_pos < len)
16077 {
16078 if (cur_pos < len && isspace(input[cur_pos]))
16079 do
16080 ++cur_pos;
16081 while (cur_pos < len && isspace(input[cur_pos]));
16082
16083 prev_pos = cur_pos;
16084 cur_pos = input.find(' ', prev_pos);
16085 prev_word = cur_word;
16086 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16087
16088 if (cur_pos < len
16089 && cur_word == "long"
16090 && prev_word != "long")
16091 {
16092 if (cur_pos < len && isspace(input[cur_pos]))
16093 do
16094 ++cur_pos;
16095 while (cur_pos < len && isspace(input[cur_pos]));
16096 prev_pos = cur_pos;
16097
16098 cur_pos = input.find(' ', prev_pos);
16099 string saved_prev_word = prev_word;
16100 prev_word = cur_word;
16101 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16102 if (cur_word == "long")
16103 cur_word = "long long";
16104 else
16105 {
16106 cur_pos = prev_pos;
16107 cur_word = prev_word;
16108 prev_word = saved_prev_word;
16109 }
16110 }
16111
16112 if (!parse_integral_type_modifier(cur_word, modifiers))
16113 {
16114 if (!parse_base_integral_type(cur_word, base))
16115 return false;
16116 else
16117 ok = true;
16118 }
16119 else
16120 ok = true;
16121 }
16122
16123 return ok;
16124}
16125
16126/// Parse an integral type from a string.
16127///
16128/// @param str the string containing the integral type to parse.
16129///
16130///@param type the resulting @ref integral_type. Is set to the result
16131///of the parse, iff the function returns true.
16132///
16133/// @return true iff the function could parse an integral type from @p
16134/// str.
16135bool
16136parse_integral_type(const string& str, integral_type& type)
16137{
16139 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
16140
16141 if (!parse_integral_type(str, base_type, modifiers))
16142 return false;
16143
16144 // So this is an integral type.
16145 integral_type int_type(base_type, modifiers);
16146 type = int_type;
16147 return true;
16148}
16149
16150/// Default constructor of the @ref integral_type.
16152 : base_(INT_BASE_TYPE),
16153 modifiers_(NO_MODIFIER)
16154{}
16155
16156/// Constructor of the @ref integral_type.
16157///
16158/// @param b the base type of the integral type.
16159///
16160/// @param m the modifiers of the integral type.
16162 : base_(b), modifiers_(m)
16163{}
16164
16165/// Constructor of the @ref integral_type.
16166///
16167/// @param the name of the integral type to parse to initialize the
16168/// current instance of @ref integral_type.
16169integral_type::integral_type(const string& type_name)
16170 : base_(INT_BASE_TYPE),
16171 modifiers_(NO_MODIFIER)
16172{
16173 bool could_parse = parse_integral_type(type_name, base_, modifiers_);
16174 ABG_ASSERT(could_parse);
16175}
16176
16177/// Getter of the base type of the @ref integral_type.
16178///
16179/// @return the base type of the @ref integral_type.
16182{return base_;}
16183
16184/// Getter of the modifiers bitmap of the @ref integral_type.
16185///
16186/// @return the modifiers bitmap of the @ref integral_type.
16189{return modifiers_;}
16190
16191/// Setter of the modifiers bitmap of the @ref integral_type.
16192///
16193/// @param m the new modifiers.
16194void
16196{modifiers_ = m;}
16197
16198/// Equality operator for the @ref integral_type.
16199///
16200/// @param other the other integral type to compare against.
16201///
16202/// @return true iff @p other equals the current instance of @ref
16203/// integral_type.
16204bool
16206{return base_ == other.base_ && modifiers_ == other.modifiers_;}
16207
16208/// Return the string representation of the current instance of @ref
16209/// integral_type.
16210///
16211/// @param internal if true the string representation is to be used
16212/// for internal purposes. In general, it means it's for type
16213/// canonicalization purposes.
16214///
16215/// @return the string representation of the current instance of @ref
16216/// integral_type.
16217string
16218integral_type::to_string(bool internal) const
16219{
16220 string result;
16221
16222 // Look at modifiers ...
16223 if (modifiers_ & SIGNED_MODIFIER)
16224 result += "signed ";
16225 if (modifiers_ & UNSIGNED_MODIFIER)
16226 result += "unsigned ";
16227 if (!internal)
16228 {
16229 // For canonicalization purposes, we won't emit the "short, long, or
16230 // long long" modifiers. This is because on some platforms, "long
16231 // int" and "long long int" might have the same size. In those
16232 // cases, we want the two types to be equivalent if they have the
16233 // same size. If they don't have the same internal string
16234 // representation, they'd automatically have different canonical
16235 // types and thus be canonically different.
16236 if (modifiers_ & SHORT_MODIFIER)
16237 result += "short ";
16238 if (modifiers_ & LONG_MODIFIER)
16239 result += "long ";
16240 if (modifiers_ & LONG_LONG_MODIFIER)
16241 result += "long long ";
16242 }
16243
16244 // ... and look at base types.
16245 if (base_ == INT_BASE_TYPE)
16246 result += "int";
16247 else if (base_ == CHAR_BASE_TYPE)
16248 result += "char";
16249 else if (base_ == BOOL_BASE_TYPE)
16250 result += "bool";
16251 else if (base_ == DOUBLE_BASE_TYPE)
16252 result += "double";
16253 else if (base_ == FLOAT_BASE_TYPE)
16254 result += "float";
16255 else if (base_ == CHAR16_T_BASE_TYPE)
16256 result += "char16_t";
16257 else if (base_ == CHAR32_T_BASE_TYPE)
16258 result += "char32_t";
16259 else if (base_ == WCHAR_T_BASE_TYPE)
16260 result += "wchar_t";
16261
16262 return result;
16263}
16264
16265/// Convert the current instance of @ref integral_type into its string
16266/// representation.
16267///
16268/// @return the string representation of the current instance of @ref
16269/// integral_type.
16270integral_type::operator string() const
16271{return to_string();}
16272
16273// </integral_type definitions>
16274
16275//<type_decl definitions>
16276
16277/// Constructor.
16278///
16279/// @param env the environment we are operating from.
16280///
16281/// @param name the name of the type declaration.
16282///
16283/// @param size_in_bits the size of the current type_decl, in bits.
16284///
16285/// @param alignment_in_bits the alignment of the current typ, in
16286/// bits.
16287///
16288/// @param locus the source location of the current type declaration.
16289///
16290/// @param linkage_name the linkage_name of the current type declaration.
16291///
16292/// @param vis the visibility of the type declaration.
16293type_decl::type_decl(const environment& env,
16294 const string& name,
16295 size_t size_in_bits,
16296 size_t alignment_in_bits,
16297 const location& locus,
16298 const string& linkage_name,
16299 visibility vis)
16300
16301 : type_or_decl_base(env,
16302 BASIC_TYPE
16303 | ABSTRACT_TYPE_BASE
16304 | ABSTRACT_DECL_BASE),
16305 decl_base(env, name, locus, linkage_name, vis),
16306 type_base(env, size_in_bits, alignment_in_bits)
16307{
16309
16311 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
16312 integral_type int_type(base_type, modifiers);
16313 if (parse_integral_type(name, int_type))
16314 {
16315 // Convert the integral_type into its canonical string
16316 // representation.
16317 string integral_type_name = int_type;
16318
16319 // Set the name of this type_decl to the canonical string
16320 // representation above
16321 set_name(integral_type_name);
16323
16324 if (!get_linkage_name().empty())
16325 set_linkage_name(integral_type_name);
16326 }
16327}
16328
16329/// Compares two instances of @ref type_decl.
16330///
16331/// If the two intances are different, set a bitfield to give some
16332/// insight about the kind of differences there are.
16333///
16334/// @param l the first artifact of the comparison.
16335///
16336/// @param r the second artifact of the comparison.
16337///
16338/// @param k a pointer to a bitfield that gives information about the
16339/// kind of changes there are between @p l and @p r. This one is set
16340/// iff @p k is non-null and the function returns false.
16341///
16342/// Please note that setting k to a non-null value does have a
16343/// negative performance impact because even if @p l and @p r are not
16344/// equal, the function keeps up the comparison in order to determine
16345/// the different kinds of ways in which they are different.
16346///
16347/// @return true if @p l equals @p r, false otherwise.
16348bool
16349equals(const type_decl& l, const type_decl& r, change_kind* k)
16350{
16351 bool result = false;
16352
16353 // Consider the types as decls to compare their decls-related
16354 // properties.
16355 result = equals(static_cast<const decl_base&>(l),
16356 static_cast<const decl_base&>(r),
16357 k);
16358 if (!k && !result)
16360
16361 // Now consider the types a "types' to compare their size-related
16362 // properties.
16363 result &= equals(static_cast<const type_base&>(l),
16364 static_cast<const type_base&>(r),
16365 k);
16366 ABG_RETURN(result);
16367}
16368
16369/// Return true if both types equals.
16370///
16371/// This operator re-uses the overload that takes a decl_base.
16372///
16373/// Note that this does not check the scopes of any of the types.
16374///
16375/// @param o the other type_decl to check agains.
16376bool
16378{
16379 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16380 if (!other)
16381 return false;
16382 return *this == *other;
16383}
16384
16385/// Return true if both types equals.
16386///
16387/// Note that this does not check the scopes of any of the types.
16388///
16389/// @param o the other type_decl to check against.
16390bool
16392{
16393 const type_decl* other = dynamic_cast<const type_decl*>(&o);
16394 if (!other)
16395 return false;
16396 return try_canonical_compare(this, other);
16397}
16398
16399/// Return true if both types equals.
16400///
16401/// Note that this does not check the scopes of any of the types.
16402///
16403/// @param o the other type_decl to check against.
16404///
16405/// @return true iff the current isntance equals @p o
16406bool
16408{
16409 const decl_base& other = o;
16410 return *this == other;
16411}
16412
16413/// Return true if both types equals.
16414///
16415/// Note that this does not check the scopes of any of the types.
16416///
16417/// @param o the other type_decl to check against.
16418///
16419/// @return true iff the current isntance equals @p o
16420bool
16422{return !operator==(o);}
16423
16424/// Return true if both types equals.
16425///
16426/// Note that this does not check the scopes of any of the types.
16427///
16428/// @param o the other type_decl to check against.
16429///
16430/// @return true iff the current isntance equals @p o
16431bool
16433{return !operator==(o);}
16434
16435/// Inequality operator.
16436///
16437/// @param o the other type to compare against.
16438///
16439/// @return true iff the current instance is different from @p o.
16440bool
16442{return !operator==(o);}
16443
16444/// Equality operator for @ref type_decl_sptr.
16445///
16446/// @param l the first operand to compare.
16447///
16448/// @param r the second operand to compare.
16449///
16450/// @return true iff @p l equals @p r.
16451bool
16453{
16454 if (!!l != !!r)
16455 return false;
16456 if (l.get() == r.get())
16457 return true;
16458 return *l == *r;
16459}
16460
16461/// Inequality operator for @ref type_decl_sptr.
16462///
16463/// @param l the first operand to compare.
16464///
16465/// @param r the second operand to compare.
16466///
16467/// @return true iff @p l is different from @p r.
16468bool
16470{return !operator==(l, r);}
16471
16472/// Implementation for the virtual qualified name builder for @ref
16473/// type_decl.
16474///
16475/// @param qualified_name the output parameter to hold the resulting
16476/// qualified name.
16477///
16478/// @param internal set to true if the call is intended for an
16479/// internal use (for technical use inside the library itself), false
16480/// otherwise. If you don't know what this is for, then set it to
16481/// false.
16482void
16484 bool internal) const
16485{qualified_name = get_qualified_name(internal);}
16486
16487/// Implementation for the virtual qualified name builder for @ref
16488/// type_decl.
16489///
16490/// @param qualified_name the output parameter to hold the resulting
16491/// qualified name.
16492///
16493/// @param internal set to true if the call is intended for an
16494/// internal use (for technical use inside the library itself), false
16495/// otherwise. If you don't know what this is for, then set it to
16496/// false.
16497const interned_string&
16499{
16500 const environment& env = get_environment();
16501
16502
16503 if (internal)
16504 if (is_integral_type(this))
16505 {
16507 {
16508 if (decl_base::priv_->internal_qualified_name_.empty())
16509 decl_base::priv_->internal_qualified_name_ =
16510 env.intern(get_internal_integral_type_name(this));
16511 return decl_base::priv_->internal_qualified_name_;
16512 }
16513 else
16514 {
16515 decl_base::priv_->temporary_internal_qualified_name_ =
16516 env.intern(get_internal_integral_type_name(this));
16517 return decl_base::priv_->temporary_internal_qualified_name_;
16518 }
16519 }
16520
16521 return decl_base::get_qualified_name(/*internal=*/false);
16522}
16523
16524/// Get the pretty representation of the current instance of @ref
16525/// type_decl.
16526///
16527/// @param internal set to true if the call is intended to get a
16528/// representation of the decl (or type) for the purpose of canonical
16529/// type comparison. This is mainly used in the function
16530/// type_base::get_canonical_type_for().
16531///
16532/// In other words if the argument for this parameter is true then the
16533/// call is meant for internal use (for technical use inside the
16534/// library itself), false otherwise. If you don't know what this is
16535/// for, then set it to false.
16536///
16537/// @param qualified_name if true, names emitted in the pretty
16538/// representation are fully qualified.
16539///
16540/// @return the pretty representatin of the @ref type_decl.
16541string
16543 bool qualified_name) const
16544{
16545 if (internal)
16546 if (is_integral_type(this))
16547 return get_internal_integral_type_name(this);
16548
16549 if (qualified_name)
16550 return get_qualified_name(internal);
16551 return get_name();
16552}
16553
16554/// This implements the ir_traversable_base::traverse pure virtual
16555/// function.
16556///
16557/// @param v the visitor used on the current instance.
16558///
16559/// @return true if the entire IR node tree got traversed, false
16560/// otherwise.
16561bool
16563{
16564 if (v.type_node_has_been_visited(this))
16565 return true;
16566
16567 v.visit_begin(this);
16568 bool result = v.visit_end(this);
16570
16571 return result;
16572}
16573
16574type_decl::~type_decl()
16575{}
16576//</type_decl definitions>
16577
16578// <scope_type_decl definitions>
16579
16580/// Constructor.
16581///
16582/// @param env the environment we are operating from.
16583///
16584/// @param name the name of the type.
16585///
16586/// @param size_in_bits the size of the type, in bits.
16587///
16588/// @param alignment_in_bits the alignment of the type, in bits.
16589///
16590/// @param locus the source location where the type is defined.
16591///
16592/// @param vis the visibility of the type.
16593scope_type_decl::scope_type_decl(const environment& env,
16594 const string& name,
16595 size_t size_in_bits,
16596 size_t alignment_in_bits,
16597 const location& locus,
16598 visibility vis)
16599 : type_or_decl_base(env,
16600 ABSTRACT_SCOPE_TYPE_DECL
16601 | ABSTRACT_TYPE_BASE
16602 | ABSTRACT_DECL_BASE),
16603 decl_base(env, name, locus, "", vis),
16604 type_base(env, size_in_bits, alignment_in_bits),
16605 scope_decl(env, name, locus)
16606{}
16607
16608/// Compares two instances of @ref scope_type_decl.
16609///
16610/// If the two intances are different, set a bitfield to give some
16611/// insight about the kind of differences there are.
16612///
16613/// @param l the first artifact of the comparison.
16614///
16615/// @param r the second artifact of the comparison.
16616///
16617/// @param k a pointer to a bitfield that gives information about the
16618/// kind of changes there are between @p l and @p r. This one is set
16619/// iff @p k is non-null and the function returns false.
16620///
16621/// Please note that setting k to a non-null value does have a
16622/// negative performance impact because even if @p l and @p r are not
16623/// equal, the function keeps up the comparison in order to determine
16624/// the different kinds of ways in which they are different.
16625///
16626/// @return true if @p l equals @p r, false otherwise.
16627bool
16629{
16630 bool result = equals(static_cast<const scope_decl&>(l),
16631 static_cast<const scope_decl&>(r),
16632 k);
16633
16634 if (!k && !result)
16636
16637 result &= equals(static_cast<const type_base&>(l),
16638 static_cast<const type_base&>(r),
16639 k);
16640
16641 ABG_RETURN(result);
16642}
16643
16644/// Equality operator between two scope_type_decl.
16645///
16646/// Note that this function does not consider the scope of the scope
16647/// types themselves.
16648///
16649/// @return true iff both scope types are equal.
16650bool
16652{
16653 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
16654 if (!other)
16655 return false;
16656 return try_canonical_compare(this, other);
16657}
16658
16659/// Equality operator between two scope_type_decl.
16660///
16661/// This re-uses the equality operator that takes a decl_base.
16662///
16663/// @param o the other scope_type_decl to compare against.
16664///
16665/// @return true iff both scope types are equal.
16666bool
16668{
16669 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16670 if (!other)
16671 return false;
16672
16673 return *this == *other;
16674}
16675
16676/// Traverses an instance of @ref scope_type_decl, visiting all the
16677/// sub-types and decls that it might contain.
16678///
16679/// @param v the visitor that is used to visit every IR sub-node of
16680/// the current node.
16681///
16682/// @return true if either
16683/// - all the children nodes of the current IR node were traversed
16684/// and the calling code should keep going with the traversing.
16685/// - or the current IR node is already being traversed.
16686/// Otherwise, returning false means that the calling code should not
16687/// keep traversing the tree.
16688bool
16690{
16691 if (visiting())
16692 return true;
16693
16694 if (v.type_node_has_been_visited(this))
16695 return true;
16696
16697 if (v.visit_begin(this))
16698 {
16699 visiting(true);
16700 for (scope_decl::declarations::const_iterator i =
16701 get_member_decls().begin();
16702 i != get_member_decls ().end();
16703 ++i)
16704 if (!(*i)->traverse(v))
16705 break;
16706 visiting(false);
16707 }
16708
16709 bool result = v.visit_end(this);
16711
16712 return result;
16713}
16714
16715scope_type_decl::~scope_type_decl()
16716{}
16717// </scope_type_decl definitions>
16718
16719// <namespace_decl>
16720
16721/// Constructor.
16722///
16723/// @param the environment we are operatin from.
16724///
16725/// @param name the name of the namespace.
16726///
16727/// @param locus the source location where the namespace is defined.
16728///
16729/// @param vis the visibility of the namespace.
16731 const string& name,
16732 const location& locus,
16733 visibility vis)
16734 // We need to call the constructor of decl_base directly here
16735 // because it is virtually inherited by scope_decl. Note that we
16736 // just implicitely call the default constructor for scope_decl
16737 // here, as what we really want is to initialize the decl_base
16738 // subobject. Wow, virtual inheritance is useful, but setting it
16739 // up is ugly.
16740 : type_or_decl_base(env,
16741 NAMESPACE_DECL
16742 | ABSTRACT_DECL_BASE
16743 | ABSTRACT_SCOPE_DECL),
16744 decl_base(env, name, locus, "", vis),
16745 scope_decl(env, name, locus)
16746{
16748}
16749
16750/// Build and return a copy of the pretty representation of the
16751/// namespace.
16752///
16753/// @param internal set to true if the call is intended to get a
16754/// representation of the decl (or type) for the purpose of canonical
16755/// type comparison. This is mainly used in the function
16756/// type_base::get_canonical_type_for().
16757///
16758/// In other words if the argument for this parameter is true then the
16759/// call is meant for internal use (for technical use inside the
16760/// library itself), false otherwise. If you don't know what this is
16761/// for, then set it to false.
16762///
16763/// @param qualified_name if true, names emitted in the pretty
16764/// representation are fully qualified.
16765///
16766/// @return a copy of the pretty representation of the namespace.
16767string
16769 bool qualified_name) const
16770{
16771 string r =
16772 "namespace " + scope_decl::get_pretty_representation(internal,
16773 qualified_name);
16774 return r;
16775}
16776
16777/// Return true iff both namespaces and their members are equal.
16778///
16779/// Note that this function does not check if the scope of these
16780/// namespaces are equal.
16781bool
16783{
16784 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
16785 if (!other)
16786 return false;
16787 return scope_decl::operator==(*other);
16788}
16789
16790/// Test if the current namespace_decl is empty or contains empty
16791/// namespaces itself.
16792///
16793/// @return true iff the current namespace_decl is empty or contains
16794/// empty itself.
16795bool
16797{
16798 if (is_empty())
16799 return true;
16800
16801 for (declarations::const_iterator i = get_member_decls().begin();
16802 i != get_member_decls().end();
16803 ++i)
16804 {
16805 if (!is_namespace(*i))
16806 return false;
16807
16809 ABG_ASSERT(ns);
16810
16811 if (!ns->is_empty_or_has_empty_sub_namespaces())
16812 return false;
16813 }
16814
16815 return true;
16816}
16817
16818/// This implements the ir_traversable_base::traverse pure virtual
16819/// function.
16820///
16821/// @param v the visitor used on the current instance and on its
16822/// member nodes.
16823///
16824/// @return true if the entire IR node tree got traversed, false
16825/// otherwise.
16826bool
16828{
16829 if (visiting())
16830 return true;
16831
16832 if (v.visit_begin(this))
16833 {
16834 visiting(true);
16835 scope_decl::declarations::const_iterator i;
16836 for (i = get_member_decls().begin();
16837 i != get_member_decls ().end();
16838 ++i)
16839 {
16841 dynamic_pointer_cast<ir_traversable_base>(*i);
16842 if (t)
16843 if (!t->traverse (v))
16844 break;
16845 }
16846 visiting(false);
16847 }
16848 return v.visit_end(this);
16849}
16850
16851namespace_decl::~namespace_decl()
16852{
16853}
16854
16855// </namespace_decl>
16856
16857// <qualified_type_def>
16858
16859/// Type of the private data of qualified_type_def.
16860class qualified_type_def::priv
16861{
16862 friend class qualified_type_def;
16863
16864 qualified_type_def::CV cv_quals_;
16865 // Before the type is canonicalized, this is used as a temporary
16866 // internal name.
16867 interned_string temporary_internal_name_;
16868 // Once the type is canonicalized, this is used as the internal
16869 // name.
16870 interned_string internal_name_;
16871 weak_ptr<type_base> underlying_type_;
16872
16873 priv()
16874 : cv_quals_(CV_NONE)
16875 {}
16876
16877 priv(qualified_type_def::CV quals,
16878 type_base_sptr t)
16879 : cv_quals_(quals),
16880 underlying_type_(t)
16881 {}
16882
16883 priv(qualified_type_def::CV quals)
16884 : cv_quals_(quals)
16885 {}
16886};// end class qualified_type_def::priv
16887
16888/// Build the name of the current instance of qualified type.
16889///
16890/// @param fully_qualified if true, build a fully qualified name.
16891///
16892/// @param internal set to true if the call is intended for an
16893/// internal use (for technical use inside the library itself), false
16894/// otherwise. If you don't know what this is for, then set it to
16895/// false.
16896///
16897/// @return a copy of the newly-built name.
16898string
16899qualified_type_def::build_name(bool fully_qualified, bool internal) const
16900{
16901 type_base_sptr t = get_underlying_type();
16902 if (!t)
16903 // The qualified type might temporarily have no underlying type,
16904 // especially during the construction of the type, while the
16905 // underlying type is not yet constructed. In that case, let's do
16906 // like if the underlying type is the 'void' type.
16908
16910 fully_qualified,
16911 internal);
16912}
16913
16914/// This function is automatically invoked whenever an instance of
16915/// this type is canonicalized.
16916///
16917/// It's an overload of the virtual type_base::on_canonical_type_set.
16918///
16919/// We put here what is thus meant to be executed only at the point of
16920/// type canonicalization.
16921void
16924
16925/// Constructor of the qualified_type_def
16926///
16927/// @param type the underlying type
16928///
16929/// @param quals a bitfield representing the const/volatile qualifiers
16930///
16931/// @param locus the location of the qualified type definition
16932qualified_type_def::qualified_type_def(type_base_sptr type,
16933 CV quals,
16934 const location& locus)
16935 : type_or_decl_base(type->get_environment(),
16936 QUALIFIED_TYPE
16937 | ABSTRACT_TYPE_BASE
16938 | ABSTRACT_DECL_BASE),
16939 type_base(type->get_environment(), type->get_size_in_bits(),
16940 type->get_alignment_in_bits()),
16941 decl_base(type->get_environment(), "", locus, "",
16942 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
16943 priv_(new priv(quals, type))
16944{
16946 interned_string name = type->get_environment().intern(build_name(false));
16947 set_name(name);
16948}
16949
16950/// Constructor of the qualified_type_def
16951///
16952/// @param env the environment of the type.
16953///
16954/// @param quals a bitfield representing the const/volatile qualifiers
16955///
16956/// @param locus the location of the qualified type definition
16957qualified_type_def::qualified_type_def(const environment& env,
16958 CV quals,
16959 const location& locus)
16960 : type_or_decl_base(env,
16961 QUALIFIED_TYPE
16962 | ABSTRACT_TYPE_BASE
16963 | ABSTRACT_DECL_BASE),
16964 type_base(env, /*size_in_bits=*/0,
16965 /*alignment_in_bits=*/0),
16966 decl_base(env, "", locus, ""),
16967 priv_(new priv(quals))
16968{
16970 // We don't yet have an underlying type. So for naming purpose,
16971 // let's temporarily pretend the underlying type is 'void'.
16972 interned_string name = env.intern("void");
16973 set_name(name);
16974}
16975
16976/// Get the size of the qualified type def.
16977///
16978/// This is an overload for type_base::get_size_in_bits().
16979///
16980/// @return the size of the qualified type.
16981size_t
16983{
16984 size_t s = 0;
16985 if (type_base_sptr ut = get_underlying_type())
16986 {
16987 // We do have the underlying type properly set, so let's make
16988 // the size of the qualified type match the size of its
16989 // underlying type.
16990 s = ut->get_size_in_bits();
16991 if (s != type_base::get_size_in_bits())
16992 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
16993 }
16995}
16996
16997/// Compares two instances of @ref qualified_type_def.
16998///
16999/// If the two intances are different, set a bitfield to give some
17000/// insight about the kind of differences there are.
17001///
17002/// @param l the first artifact of the comparison.
17003///
17004/// @param r the second artifact of the comparison.
17005///
17006/// @param k a pointer to a bitfield that gives information about the
17007/// kind of changes there are between @p l and @p r. This one is set
17008/// iff @p k is non-null and the function returns false.
17009///
17010/// Please note that setting k to a non-null value does have a
17011/// negative performance impact because even if @p l and @p r are not
17012/// equal, the function keeps up the comparison in order to determine
17013/// the different kinds of ways in which they are different.
17014///
17015/// @return true if @p l equals @p r, false otherwise.
17016bool
17018{
17019 bool result = true;
17020 if (l.get_cv_quals() != r.get_cv_quals())
17021 {
17022 result = false;
17023 if (k)
17025 else
17027 }
17028
17030 {
17031 result = false;
17032 if (k)
17033 {
17035 r.get_underlying_type().get()))
17036 // Underlying type changes in which the structure of the
17037 // type changed are considered local changes to the
17038 // qualified type.
17040 else
17041 *k |= SUBTYPE_CHANGE_KIND;
17042 }
17043 else
17044 // okay strictly speaking this is not necessary, but I am
17045 // putting it here to maintenance; that is, so that adding
17046 // subsequent clauses needed to compare two qualified types
17047 // later still works.
17049 }
17050
17051 ABG_RETURN(result);
17052}
17053
17054/// Equality operator for qualified types.
17055///
17056/// Note that this function does not check for equality of the scopes.
17057///
17058///@param o the other qualified type to compare against.
17059///
17060/// @return true iff both qualified types are equal.
17061bool
17063{
17064 const qualified_type_def* other =
17065 dynamic_cast<const qualified_type_def*>(&o);
17066 if (!other)
17067 return false;
17068 return try_canonical_compare(this, other);
17069}
17070
17071/// Equality operator for qualified types.
17072///
17073/// Note that this function does not check for equality of the scopes.
17074/// Also, this re-uses the equality operator above that takes a
17075/// decl_base.
17076///
17077///@param o the other qualified type to compare against.
17078///
17079/// @return true iff both qualified types are equal.
17080bool
17082{
17083 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17084 if (!other)
17085 return false;
17086 return *this == *other;
17087}
17088
17089/// Equality operator for qualified types.
17090///
17091/// Note that this function does not check for equality of the scopes.
17092/// Also, this re-uses the equality operator above that takes a
17093/// decl_base.
17094///
17095///@param o the other qualified type to compare against.
17096///
17097/// @return true iff both qualified types are equal.
17098bool
17100{
17101 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17102 if (!other)
17103 return false;
17104 return *this == *other;
17105}
17106
17107/// Implementation for the virtual qualified name builder for @ref
17108/// qualified_type_def.
17109///
17110/// @param qualified_name the output parameter to hold the resulting
17111/// qualified name.
17112///
17113/// @param internal set to true if the call is intended for an
17114/// internal use (for technical use inside the library itself), false
17115/// otherwise. If you don't know what this is for, then set it to
17116/// false.
17117void
17119 bool internal) const
17120{qualified_name = get_qualified_name(internal);}
17121
17122/// Implementation of the virtual qualified name builder/getter.
17123///
17124/// @param internal set to true if the call is intended for an
17125/// internal use (for technical use inside the library itself), false
17126/// otherwise. If you don't know what this is for, then set it to
17127/// false.
17128///
17129/// @return the resulting qualified name.
17130const interned_string&
17132{
17133 const environment& env = get_environment();
17134
17135
17136 if (!get_canonical_type())
17137 {
17138 // The type hasn't been canonicalized yet. We want to return a
17139 // temporary name that is not cached because the structure of
17140 // this type (and so its name) can change until its
17141 // canonicalized.
17142 if (internal)
17143 {
17144 // We are asked to return a temporary *internal* name.
17145 // Lets compute it and return a reference to where it's
17146 // stored.
17147 if (priv_->temporary_internal_name_.empty())
17148 priv_->temporary_internal_name_ =
17149 env.intern(build_name(true, /*internal=*/true));
17150 return priv_->temporary_internal_name_;
17151 }
17152 else
17153 {
17154 // We are asked to return a temporary non-internal name.
17156 (env.intern(build_name(true, /*internal=*/false)));
17158 }
17159 }
17160 else
17161 {
17162 // The type has already been canonicalized. We want to return
17163 // the definitive name and cache it.
17164 if (internal)
17165 {
17166 if (priv_->internal_name_.empty())
17167 priv_->internal_name_ =
17168 env.intern(build_name(/*qualified=*/true,
17169 /*internal=*/true));
17170 return priv_->internal_name_;
17171 }
17172 else
17173 {
17174 if (peek_qualified_name().empty())
17176 (env.intern(build_name(/*qualified=*/true,
17177 /*internal=*/false)));
17178 return peek_qualified_name();
17179 }
17180 }
17181}
17182
17183/// This implements the ir_traversable_base::traverse pure virtual
17184/// function.
17185///
17186/// @param v the visitor used on the current instance.
17187///
17188/// @return true if the entire IR node tree got traversed, false
17189/// otherwise.
17190bool
17192{
17193 if (v.type_node_has_been_visited(this))
17194 return true;
17195
17196 if (visiting())
17197 return true;
17198
17199 if (v.visit_begin(this))
17200 {
17201 visiting(true);
17202 if (type_base_sptr t = get_underlying_type())
17203 t->traverse(v);
17204 visiting(false);
17205 }
17206 bool result = v.visit_end(this);
17208 return result;
17209}
17210
17211qualified_type_def::~qualified_type_def()
17212{
17213}
17214
17215/// Getter of the const/volatile qualifier bit field
17218{return priv_->cv_quals_;}
17219
17220/// Setter of the const/value qualifiers bit field
17221void
17223{priv_->cv_quals_ = cv_quals;}
17224
17225/// Compute and return the string prefix or suffix representing the
17226/// qualifiers hold by the current instance of @ref
17227/// qualified_type_def.
17228///
17229/// @return the newly-built cv string.
17230string
17232{return get_string_representation_of_cv_quals(priv_->cv_quals_);}
17233
17234/// Getter of the underlying type
17235type_base_sptr
17237{return priv_->underlying_type_.lock();}
17238
17239/// Setter of the underlying type.
17240///
17241/// @param t the new underlying type.
17242void
17244{
17245 ABG_ASSERT(t);
17246 priv_->underlying_type_ = t;
17247 // Now we need to update other properties that depend on the new underlying type.
17248 set_size_in_bits(t->get_size_in_bits());
17249 set_alignment_in_bits(t->get_alignment_in_bits());
17251 set_name(name);
17252 if (scope_decl* s = get_scope())
17253 {
17254 // Now that the name has been updated, we need to update the
17255 // lookup maps accordingly.
17256 scope_decl::declarations::iterator i;
17257 if (s->find_iterator_for_member(this, i))
17259 else
17261 }
17262}
17263
17264/// Non-member equality operator for @ref qualified_type_def
17265///
17266/// @param l the left-hand side of the equality operator
17267///
17268/// @param r the right-hand side of the equality operator
17269///
17270/// @return true iff @p l and @p r equals.
17271bool
17272operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17273{
17274 if (l.get() == r.get())
17275 return true;
17276 if (!!l != !!r)
17277 return false;
17278
17279 return *l == *r;
17280}
17281
17282/// Non-member inequality operator for @ref qualified_type_def
17283///
17284/// @param l the left-hand side of the equality operator
17285///
17286/// @param r the right-hand side of the equality operator
17287///
17288/// @return true iff @p l and @p r equals.
17289bool
17290operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17291{return ! operator==(l, r);}
17292
17293/// Overloaded bitwise OR operator for cv qualifiers.
17296{
17297 return static_cast<qualified_type_def::CV>
17298 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
17299}
17300
17301/// Overloaded bitwise |= operator for cv qualifiers.
17304{
17305 l = l | r;
17306 return l;
17307}
17308
17309/// Overloaded bitwise &= operator for cv qualifiers.
17312{
17313 l = l & r;
17314 return l;
17315}
17316
17317/// Overloaded bitwise AND operator for CV qualifiers.
17320{
17321 return static_cast<qualified_type_def::CV>
17322 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
17323}
17324
17325/// Overloaded bitwise inverting operator for CV qualifiers.
17328{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
17329
17330/// Streaming operator for qualified_type_decl::CV
17331///
17332/// @param o the output stream to serialize the cv qualifier to.
17333///
17334/// @param cv the cv qualifier to serialize.
17335///
17336/// @return the output stream used.
17337std::ostream&
17338operator<<(std::ostream& o, qualified_type_def::CV cv)
17339{
17340 string str;
17341
17342 switch (cv)
17343 {
17344 case qualified_type_def::CV_NONE:
17345 str = "none";
17346 break;
17347 case qualified_type_def::CV_CONST:
17348 str = "const";
17349 break;
17350 case qualified_type_def::CV_VOLATILE:
17351 str = "volatile";
17352 break;
17353 case qualified_type_def::CV_RESTRICT:
17354 str = "restrict";
17355 break;
17356 }
17357
17358 o << str;
17359 return o;
17360}
17361
17362// </qualified_type_def>
17363
17364//<pointer_type_def definitions>
17365
17366/// Private data structure of the @ref pointer_type_def.
17367struct pointer_type_def::priv
17368{
17369 type_base_wptr pointed_to_type_;
17370 type_base* naked_pointed_to_type_;
17371 interned_string internal_qualified_name_;
17372 interned_string temp_internal_qualified_name_;
17373
17374 priv(const type_base_sptr& t)
17375 : pointed_to_type_(type_or_void(t, t->get_environment())),
17376 naked_pointed_to_type_(t.get())
17377 {}
17378
17379 priv()
17380 : naked_pointed_to_type_()
17381 {}
17382}; //end struct pointer_type_def
17383
17384/// This function is automatically invoked whenever an instance of
17385/// this type is canonicalized.
17386///
17387/// It's an overload of the virtual type_base::on_canonical_type_set.
17388///
17389/// We put here what is thus meant to be executed only at the point of
17390/// type canonicalization.
17391void
17394
17395
17396///Constructor of @ref pointer_type_def.
17397///
17398/// @param pointed_to the pointed-to type.
17399///
17400/// @param size_in_bits the size of the type, in bits.
17401///
17402/// @param align_in_bits the alignment of the type, in bits.
17403///
17404/// @param locus the source location where the type was defined.
17405pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
17406 size_t size_in_bits,
17407 size_t align_in_bits,
17408 const location& locus)
17409 : type_or_decl_base(pointed_to->get_environment(),
17410 POINTER_TYPE
17411 | ABSTRACT_TYPE_BASE
17412 | ABSTRACT_DECL_BASE),
17413 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17414 decl_base(pointed_to->get_environment(), "", locus, ""),
17415 priv_(new priv(pointed_to))
17416{
17418 try
17419 {
17420 ABG_ASSERT(pointed_to);
17421 const environment& env = pointed_to->get_environment();
17422 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
17423 string name = (pto ? pto->get_name() : string("void")) + "*";
17424 set_name(env.intern(name));
17425 if (pto)
17426 set_visibility(pto->get_visibility());
17427 }
17428 catch (...)
17429 {}
17430}
17431
17432///Constructor of @ref pointer_type_def.
17433///
17434/// @param env the environment of the type.
17435///
17436/// @param size_in_bits the size of the type, in bits.
17437///
17438/// @param align_in_bits the alignment of the type, in bits.
17439///
17440/// @param locus the source location where the type was defined.
17441pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
17442 size_t alignment_in_bits,
17443 const location& locus)
17444 : type_or_decl_base(env,
17445 POINTER_TYPE
17446 | ABSTRACT_TYPE_BASE
17447 | ABSTRACT_DECL_BASE),
17448 type_base(env, size_in_bits, alignment_in_bits),
17449 decl_base(env, "", locus, ""),
17450 priv_(new priv())
17451{
17453 string name = string("void") + "*";
17454 set_name(env.intern(name));
17455}
17456
17457/// Set the pointed-to type of the pointer.
17458///
17459/// @param t the new pointed-to type.
17460void
17462{
17463 ABG_ASSERT(t);
17464 priv_->pointed_to_type_ = t;
17465 priv_->naked_pointed_to_type_ = t.get();
17466
17467 try
17468 {
17469 const environment& env = t->get_environment();
17470 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
17471 string name = (pto ? pto->get_name() : string("void")) + "*";
17472 set_name(env.intern(name));
17473 if (pto)
17474 set_visibility(pto->get_visibility());
17475 }
17476 catch (...)
17477 {}
17478}
17479
17480/// Compares two instances of @ref pointer_type_def.
17481///
17482/// If the two intances are different, set a bitfield to give some
17483/// insight about the kind of differences there are.
17484///
17485/// @param l the first artifact of the comparison.
17486///
17487/// @param r the second artifact of the comparison.
17488///
17489/// @param k a pointer to a bitfield that gives information about the
17490/// kind of changes there are between @p l and @p r. This one is set
17491/// iff @p k is non-null and the function returns false.
17492///
17493/// Please note that setting k to a non-null value does have a
17494/// negative performance impact because even if @p l and @p r are not
17495/// equal, the function keeps up the comparison in order to determine
17496/// the different kinds of ways in which they are different.
17497///
17498/// @return true if @p l equals @p r, false otherwise.
17499bool
17501{
17502 // In C and C++ languages, a pointer to void equals all other
17503 // pointers.
17504 if (l.get_translation_unit()
17510 return true;
17511
17512 bool result = l.get_pointed_to_type() == r.get_pointed_to_type();
17513 if (!result)
17514 if (k)
17515 {
17516 if (!types_have_similar_structure(&l, &r))
17517 // pointed-to type changes in which the structure of the
17518 // type changed are considered local changes to the pointer
17519 // type.
17521 *k |= SUBTYPE_CHANGE_KIND;
17522 }
17523
17524 ABG_RETURN(result);
17525}
17526
17527/// Return true iff both instances of pointer_type_def are equal.
17528///
17529/// Note that this function does not check for the scopes of the this
17530/// types.
17531bool
17533{
17534 const pointer_type_def* other = is_pointer_type(&o);
17535 if (!other)
17536 return false;
17537 return try_canonical_compare(this, other);
17538}
17539
17540/// Return true iff both instances of pointer_type_def are equal.
17541///
17542/// Note that this function does not check for the scopes of the
17543/// types.
17544///
17545/// @param other the other type to compare against.
17546///
17547/// @return true iff @p other equals the current instance.
17548bool
17550{
17551 const decl_base* o = is_decl(&other);
17552 if (!o)
17553 return false;
17554 return *this == *o;
17555}
17556
17557/// Return true iff both instances of pointer_type_def are equal.
17558///
17559/// Note that this function does not check for the scopes of the
17560/// types.
17561///
17562/// @param other the other type to compare against.
17563///
17564/// @return true iff @p other equals the current instance.
17565bool
17567{
17568 const decl_base& o = other;
17569 return *this == o;
17570}
17571
17572/// Getter of the pointed-to type.
17573///
17574/// @return the pointed-to type.
17575const type_base_sptr
17577{return priv_->pointed_to_type_.lock();}
17578
17579/// Getter of a naked pointer to the pointed-to type.
17580///
17581/// @return a naked pointed to the pointed-to type.
17582type_base*
17584{return priv_->naked_pointed_to_type_;}
17585
17586/// Build and return the qualified name of the current instance of
17587/// @ref pointer_type_def.
17588///
17589/// @param qn output parameter. The resulting qualified name.
17590///
17591/// @param internal set to true if the call is intended for an
17592/// internal use (for technical use inside the library itself), false
17593/// otherwise. If you don't know what this is for, then set it to
17594/// false.
17595void
17597{qn = get_qualified_name(internal);}
17598
17599/// Build, cache and return the qualified name of the current instance
17600/// of @ref pointer_type_def. Subsequent invocations of this function
17601/// return the cached value.
17602///
17603/// Note that this function should work even if the underlying type is
17604/// momentarily empty.
17605///
17606/// @param internal set to true if the call is intended for an
17607/// internal use (for technical use inside the library itself), false
17608/// otherwise. If you don't know what this is for, then set it to
17609/// false.
17610///
17611/// @return the resulting qualified name.
17612const interned_string&
17614{
17615 type_base* pointed_to_type = get_naked_pointed_to_type();
17616 pointed_to_type = look_through_decl_only(pointed_to_type);
17617
17618 if (internal)
17619 {
17620 if (get_canonical_type())
17621 {
17622 if (priv_->internal_qualified_name_.empty())
17623 if (pointed_to_type)
17624 priv_->internal_qualified_name_ =
17625 pointer_declaration_name(this,
17626 /*variable_name=*/"",
17627 /*qualified_name=*/
17628 is_typedef(pointed_to_type)
17629 ? false
17630 : true,
17631 /*internal=*/true);
17632 return priv_->internal_qualified_name_;
17633 }
17634 else
17635 {
17636 // As the type hasn't yet been canonicalized, its structure
17637 // (and so its name) can change. So let's invalidate the
17638 // cache where we store its name at each invocation of this
17639 // function.
17640 if (pointed_to_type)
17641 if (priv_->temp_internal_qualified_name_.empty())
17642 priv_->temp_internal_qualified_name_ =
17643 pointer_declaration_name(this,
17644 /*variable_name=*/"",
17645 /*qualified_name=*/
17646 is_typedef(pointed_to_type)
17647 ? false
17648 : true,
17649 /*internal=*/true);
17650 return priv_->temp_internal_qualified_name_;
17651 }
17652 }
17653 else
17654 {
17656 {
17657 if (decl_base::peek_qualified_name().empty())
17659 (pointer_declaration_name(this,
17660 /*variable_name=*/"",
17661 /*qualified_name=*/true,
17662 /*internal=*/false));
17664 }
17665 else
17666 {
17667 // As the type hasn't yet been canonicalized, its structure
17668 // (and so its name) can change. So let's invalidate the
17669 // cache where we store its name at each invocation of this
17670 // function.
17671 if (pointed_to_type)
17673 (pointer_declaration_name(this,
17674 /*variable_name=*/"",
17675 /*qualified_name=*/true,
17676 /*internal=*/false));
17678 }
17679 }
17680}
17681
17682/// This implements the ir_traversable_base::traverse pure virtual
17683/// function.
17684///
17685/// @param v the visitor used on the current instance.
17686///
17687/// @return true if the entire IR node tree got traversed, false
17688/// otherwise.
17689bool
17691{
17692 if (v.type_node_has_been_visited(this))
17693 return true;
17694
17695 if (visiting())
17696 return true;
17697
17698 if (v.visit_begin(this))
17699 {
17700 visiting(true);
17701 if (type_base_sptr t = get_pointed_to_type())
17702 t->traverse(v);
17703 visiting(false);
17704 }
17705
17706 bool result = v.visit_end(this);
17708 return result;
17709}
17710
17711pointer_type_def::~pointer_type_def()
17712{}
17713
17714/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
17715/// equality; that is, make it compare the pointed to objects too.
17716///
17717/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
17718/// of the equality.
17719///
17720/// @param r the shared_ptr of @ref pointer_type_def on
17721/// right-hand-side of the equality.
17722///
17723/// @return true if the @ref pointer_type_def pointed to by the
17724/// shared_ptrs are equal, false otherwise.
17725bool
17727{
17728 if (l.get() == r.get())
17729 return true;
17730 if (!!l != !!r)
17731 return false;
17732
17733 return *l == *r;
17734}
17735
17736/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
17737/// equality; that is, make it compare the pointed to objects too.
17738///
17739/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
17740/// of the equality.
17741///
17742/// @param r the shared_ptr of @ref pointer_type_def on
17743/// right-hand-side of the equality.
17744///
17745/// @return true iff the @ref pointer_type_def pointed to by the
17746/// shared_ptrs are different.
17747bool
17749{return !operator==(l, r);}
17750
17751// </pointer_type_def definitions>
17752
17753// <reference_type_def definitions>
17754
17755/// Private data structure of the @ref reference_type_def type.
17756struct reference_type_def::priv
17757{
17758
17759 type_base_wptr pointed_to_type_;
17760 bool is_lvalue_;
17761 interned_string internal_qualified_name_;
17762 interned_string temp_internal_qualified_name_;
17763
17764 priv(const type_base_sptr& t, bool is_lvalue)
17765 : pointed_to_type_(type_or_void(t, t->get_environment())),
17766 is_lvalue_(is_lvalue)
17767 {}
17768
17769 priv(bool is_lvalue)
17770 : is_lvalue_(is_lvalue)
17771 {}
17772
17773 priv() = delete;
17774};
17775
17776/// This function is automatically invoked whenever an instance of
17777/// this type is canonicalized.
17778///
17779/// It's an overload of the virtual type_base::on_canonical_type_set.
17780///
17781/// We put here what is thus meant to be executed only at the point of
17782/// type canonicalization.
17783void
17786
17787/// Constructor of the reference_type_def type.
17788///
17789/// @param pointed_to the pointed to type.
17790///
17791/// @param lvalue wether the reference is an lvalue reference. If
17792/// false, the reference is an rvalue one.
17793///
17794/// @param size_in_bits the size of the type, in bits.
17795///
17796/// @param align_in_bits the alignment of the type, in bits.
17797///
17798/// @param locus the source location of the type.
17799reference_type_def::reference_type_def(const type_base_sptr pointed_to,
17800 bool lvalue,
17801 size_t size_in_bits,
17802 size_t align_in_bits,
17803 const location& locus)
17804 : type_or_decl_base(pointed_to->get_environment(),
17805 REFERENCE_TYPE
17806 | ABSTRACT_TYPE_BASE
17807 | ABSTRACT_DECL_BASE),
17808 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17809 decl_base(pointed_to->get_environment(), "", locus, ""),
17810 priv_(new priv(pointed_to, lvalue))
17811{
17813
17814 try
17815 {
17816 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
17817 string name;
17818 if (pto)
17819 {
17820 set_visibility(pto->get_visibility());
17821 name = string(pto->get_name()) + "&";
17822 }
17823 else
17824 name = string(get_type_name(is_function_type(pointed_to),
17825 /*qualified_name=*/true)) + "&";
17826
17827 if (!is_lvalue())
17828 name += "&";
17829 const environment& env = pointed_to->get_environment();
17830 set_name(env.intern(name));
17831 }
17832 catch (...)
17833 {}
17834}
17835
17836/// Constructor of the reference_type_def type.
17837///
17838/// This one creates a type that has no pointed-to type, temporarily.
17839/// This is useful for cases where the underlying type is not yet
17840/// available. It can be set later using
17841/// reference_type_def::set_pointed_to_type().
17842///
17843/// @param env the environment of the type.
17844///
17845/// @param lvalue wether the reference is an lvalue reference. If
17846/// false, the reference is an rvalue one.
17847///
17848/// @param size_in_bits the size of the type, in bits.
17849///
17850/// @param align_in_bits the alignment of the type, in bits.
17851///
17852/// @param locus the source location of the type.
17853reference_type_def::reference_type_def(const environment& env, bool lvalue,
17854 size_t size_in_bits,
17855 size_t alignment_in_bits,
17856 const location& locus)
17857 : type_or_decl_base(env,
17858 REFERENCE_TYPE
17859 | ABSTRACT_TYPE_BASE
17860 | ABSTRACT_DECL_BASE),
17861 type_base(env, size_in_bits, alignment_in_bits),
17862 decl_base(env, "", locus, ""),
17863 priv_(new priv(lvalue))
17864{
17866 string name = "void&";
17867 if (!is_lvalue())
17868 name += "&";
17869
17870 set_name(env.intern(name));
17871 priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
17872}
17873
17874/// Setter of the pointed_to type of the current reference type.
17875///
17876/// @param pointed_to the new pointed to type.
17877void
17878reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
17879{
17880 ABG_ASSERT(pointed_to_type);
17881 priv_->pointed_to_type_ = pointed_to_type;
17882
17883 decl_base_sptr pto;
17884 try
17885 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
17886 catch (...)
17887 {}
17888
17889 if (pto)
17890 {
17891 set_visibility(pto->get_visibility());
17892 string name = string(pto->get_name()) + "&";
17893 if (!is_lvalue())
17894 name += "&";
17895 const environment& env = pto->get_environment();
17896 set_name(env.intern(name));
17897 }
17898}
17899
17900/// Compares two instances of @ref reference_type_def.
17901///
17902/// If the two intances are different, set a bitfield to give some
17903/// insight about the kind of differences there are.
17904///
17905/// @param l the first artifact of the comparison.
17906///
17907/// @param r the second artifact of the comparison.
17908///
17909/// @param k a pointer to a bitfield that gives information about the
17910/// kind of changes there are between @p l and @p r. This one is set
17911/// iff @p k is non-null and the function returns false.
17912///
17913/// Please note that setting k to a non-null value does have a
17914/// negative performance impact because even if @p l and @p r are not
17915/// equal, the function keeps up the comparison in order to determine
17916/// the different kinds of ways in which they are different.
17917///
17918/// @return true if @p l equals @p r, false otherwise.
17919bool
17921{
17922 if (l.is_lvalue() != r.is_lvalue())
17923 {
17924 if (k)
17927 }
17928
17929 // Compare the pointed-to-types modulo the typedefs they might have
17930 bool result = (l.get_pointed_to_type() == r.get_pointed_to_type());
17931 if (!result)
17932 if (k)
17933 {
17934 if (!types_have_similar_structure(&l, &r))
17936 *k |= SUBTYPE_CHANGE_KIND;
17937 }
17938 ABG_RETURN(result);
17939}
17940
17941/// Equality operator of the @ref reference_type_def type.
17942///
17943/// @param o the other instance of @ref reference_type_def to compare
17944/// against.
17945///
17946/// @return true iff the two instances are equal.
17947bool
17949{
17950 const reference_type_def* other =
17951 dynamic_cast<const reference_type_def*>(&o);
17952 if (!other)
17953 return false;
17954 return try_canonical_compare(this, other);
17955}
17956
17957/// Equality operator of the @ref reference_type_def type.
17958///
17959/// @param o the other instance of @ref reference_type_def to compare
17960/// against.
17961///
17962/// @return true iff the two instances are equal.
17963bool
17965{
17966 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17967 if (!other)
17968 return false;
17969 return *this == *other;
17970}
17971
17972/// Equality operator of the @ref reference_type_def type.
17973///
17974/// @param o the other instance of @ref reference_type_def to compare
17975/// against.
17976///
17977/// @return true iff the two instances are equal.
17978bool
17980{
17981 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17982 if (!other)
17983 return false;
17984 return *this == *other;
17985}
17986
17987type_base_sptr
17988reference_type_def::get_pointed_to_type() const
17989{return priv_->pointed_to_type_.lock();}
17990
17991bool
17992reference_type_def::is_lvalue() const
17993{return priv_->is_lvalue_;}
17994
17995/// Build and return the qualified name of the current instance of the
17996/// @ref reference_type_def.
17997///
17998/// @param qn output parameter. Is set to the newly-built qualified
17999/// name of the current instance of @ref reference_type_def.
18000///
18001/// @param internal set to true if the call is intended for an
18002/// internal use (for technical use inside the library itself), false
18003/// otherwise. If you don't know what this is for, then set it to
18004/// false.
18005void
18007{qn = get_qualified_name(internal);}
18008
18009/// Build, cache and return the qualified name of the current instance
18010/// of the @ref reference_type_def. Subsequent invocations of this
18011/// function return the cached value.
18012///
18013/// @param internal set to true if the call is intended for an
18014/// internal use (for technical use inside the library itself), false
18015/// otherwise. If you don't know what this is for, then set it to
18016/// false.
18017///
18018/// @return the newly-built qualified name of the current instance of
18019/// @ref reference_type_def.
18020const interned_string&
18022{
18023 type_base_sptr pointed_to_type = get_pointed_to_type();
18024 pointed_to_type = look_through_decl_only(pointed_to_type);
18025
18026 if (internal)
18027 {
18028 if (get_canonical_type())
18029 {
18030 if (priv_->internal_qualified_name_.empty())
18031 if (pointed_to_type)
18032 priv_->internal_qualified_name_ =
18033 get_name_of_reference_to_type(*pointed_to_type,
18034 is_lvalue(),
18035 /*qualified_name=*/
18036 is_typedef(pointed_to_type)
18037 ? false
18038 : true,
18039 /*internal=*/true);
18040 return priv_->internal_qualified_name_;
18041 }
18042 else
18043 {
18044 // As the type hasn't yet been canonicalized, its structure
18045 // (and so its name) can change. So let's invalidate the
18046 // cache where we store its name at each invocation of this
18047 // function.
18048 if (pointed_to_type)
18049 if (priv_->temp_internal_qualified_name_.empty())
18050 priv_->temp_internal_qualified_name_ =
18051 get_name_of_reference_to_type(*pointed_to_type,
18052 is_lvalue(),
18053 /*qualified_name=*/
18054 is_typedef(pointed_to_type)
18055 ? false
18056 : true,
18057 /*internal=*/true);
18058 return priv_->temp_internal_qualified_name_;
18059 }
18060 }
18061 else
18062 {
18064 {
18066 (get_name_of_reference_to_type(*pointed_to_type,
18067 is_lvalue(),
18068 /*qualified_name=*/true,
18069 /*internal=*/false));
18071 }
18072 else
18073 {
18074 // As the type hasn't yet been canonicalized, its structure
18075 // (and so its name) can change. So let's invalidate the
18076 // cache where we store its name at each invocation of this
18077 // function.
18078 if (pointed_to_type)
18080 (get_name_of_reference_to_type(*pointed_to_type,
18081 is_lvalue(),
18082 /*qualified_name=*/true,
18083 /*internal=*/false));
18085 }
18086 }
18087}
18088
18089/// Get the pretty representation of the current instance of @ref
18090/// reference_type_def.
18091///
18092/// @param internal set to true if the call is intended to get a
18093/// representation of the decl (or type) for the purpose of canonical
18094/// type comparison. This is mainly used in the function
18095/// type_base::get_canonical_type_for().
18096///
18097/// In other words if the argument for this parameter is true then the
18098/// call is meant for internal use (for technical use inside the
18099/// library itself), false otherwise. If you don't know what this is
18100/// for, then set it to false.
18101///
18102/// @param qualified_name if true, names emitted in the pretty
18103/// representation are fully qualified.
18104///
18105/// @return the pretty representatin of the @ref reference_type_def.
18106string
18108 bool qualified_name) const
18109{
18110 string result =
18112 (get_pointed_to_type()),
18113 is_lvalue(),
18114 qualified_name,
18115 internal);
18116
18117 return result;
18118}
18119
18120/// This implements the ir_traversable_base::traverse pure virtual
18121/// function.
18122///
18123/// @param v the visitor used on the current instance.
18124///
18125/// @return true if the entire IR node tree got traversed, false
18126/// otherwise.
18127bool
18129{
18130 if (v.type_node_has_been_visited(this))
18131 return true;
18132
18133 if (visiting())
18134 return true;
18135
18136 if (v.visit_begin(this))
18137 {
18138 visiting(true);
18139 if (type_base_sptr t = get_pointed_to_type())
18140 t->traverse(v);
18141 visiting(false);
18142 }
18143
18144 bool result = v.visit_end(this);
18146 return result;
18147}
18148
18149reference_type_def::~reference_type_def()
18150{}
18151
18152/// Turn equality of shared_ptr of @ref reference_type_def into a deep
18153/// equality; that is, make it compare the pointed to objects too.
18154///
18155/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18156/// of the equality.
18157///
18158/// @param r the shared_ptr of @ref reference_type_def on
18159/// right-hand-side of the equality.
18160///
18161/// @return true if the @ref reference_type_def pointed to by the
18162/// shared_ptrs are equal, false otherwise.
18163bool
18165{
18166 if (l.get() == r.get())
18167 return true;
18168 if (!!l != !!r)
18169 return false;
18170
18171 return *l == *r;
18172}
18173
18174/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
18175/// equality; that is, make it compare the pointed to objects too.
18176///
18177/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18178/// of the equality.
18179///
18180/// @param r the shared_ptr of @ref reference_type_def on
18181/// right-hand-side of the equality.
18182///
18183/// @return true iff the @ref reference_type_def pointed to by the
18184/// shared_ptrs are different.
18185bool
18187{return !operator==(l, r);}
18188
18189// </reference_type_def definitions>
18190
18191// <ptr_to_mbr_type definitions>
18192
18193/// The private data type of @ref ptr_to_mbr_type.
18194struct ptr_to_mbr_type::priv
18195{
18196 // The type of the data member this pointer-to-member-type
18197 // designates.
18198 type_base_sptr dm_type_;
18199 // The class (or typedef to potentially qualified class) containing
18200 // the data member this pointer-to-member-type designates.
18201 type_base_sptr containing_type_;
18202 interned_string internal_qualified_name_;
18203 interned_string temp_internal_qualified_name_;
18204
18205 priv()
18206 {}
18207
18208 priv(const type_base_sptr& dm_type, const type_base_sptr& containing_type)
18209 : dm_type_(dm_type),
18210 containing_type_(containing_type)
18211 {}
18212};// end struct ptr_to_mbr_type::priv
18213
18214/// A constructor for a @ref ptr_to_mbr_type type.
18215///
18216/// @param env the environment to construct the @ref ptr_to_mbr_type in.
18217///
18218/// @param member_type the member type of the of the @ref
18219/// ptr_to_mbr_type to construct.
18220///
18221/// @param containing_type the containing type of the @ref
18222/// ptr_to_mbr_type to construct.
18223///
18224/// @param size_in_bits the size (in bits) of the resulting type.
18225///
18226/// @param alignment_in_bits the alignment (in bits) of the resulting
18227/// type.
18228///
18229/// @param locus the source location of the definition of the
18230/// resulting type.
18231ptr_to_mbr_type::ptr_to_mbr_type(const environment& env,
18232 const type_base_sptr& member_type,
18233 const type_base_sptr& containing_type,
18234 size_t size_in_bits,
18235 size_t alignment_in_bits,
18236 const location& locus)
18237 : type_or_decl_base(env,
18238 POINTER_TO_MEMBER_TYPE
18239 | ABSTRACT_TYPE_BASE
18240 | ABSTRACT_DECL_BASE),
18241 type_base(env, size_in_bits, alignment_in_bits),
18242 decl_base(env, "", locus, ""),
18243 priv_(new priv(member_type, containing_type))
18244{
18246 ABG_ASSERT(member_type);
18247 ABG_ASSERT(containing_type);
18248 interned_string name = ptr_to_mbr_declaration_name(this, "",
18249 /*qualified=*/true,
18250 /*internal=*/false);
18251 set_name(name);
18252}
18253
18254/// Getter of the member type of the current @ref ptr_to_mbr_type.
18255///
18256/// @return the type of the member referred to by the current
18257/// @ptr_to_mbr_type.
18258const type_base_sptr&
18260{return priv_->dm_type_;}
18261
18262/// Getter of the type containing the member pointed-to by the current
18263/// @ref ptr_to_mbr_type.
18264///
18265/// @return the type containing the member pointed-to by the current
18266/// @ref ptr_to_mbr_type.
18267const type_base_sptr&
18269{return priv_->containing_type_;}
18270
18271/// Equality operator for the current @ref ptr_to_mbr_type.
18272///
18273///@param o the other instance of @ref ptr_to_mbr_type to compare the
18274///current instance to.
18275///
18276/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18277bool
18279{
18280 const ptr_to_mbr_type* other =
18281 dynamic_cast<const ptr_to_mbr_type*>(&o);
18282 if (!other)
18283 return false;
18284 return try_canonical_compare(this, other);
18285}
18286
18287/// Equality operator for the current @ref ptr_to_mbr_type.
18288///
18289///@param o the other instance of @ref ptr_to_mbr_type to compare the
18290///current instance to.
18291///
18292/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18293bool
18295{
18296 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18297 if (!other)
18298 return false;
18299 return *this == *other;
18300}
18301
18302/// Equality operator for the current @ref ptr_to_mbr_type.
18303///
18304///@param o the other instance of @ref ptr_to_mbr_type to compare the
18305///current instance to.
18306///
18307/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18308bool
18310{
18311 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18312 if (!other)
18313 return false;
18314 return *this == *other;
18315}
18316
18317/// Get the qualified name for the current @ref ptr_to_mbr_type.
18318///
18319/// @param qualified_name out parameter. This is set to the name of
18320/// the current @ref ptr_to_mbr_type.
18321///
18322/// @param internal if this is true, then the qualified name is for
18323/// the purpose of type canoicalization.
18324void
18326 bool internal) const
18327{qualified_name = get_qualified_name(internal);}
18328
18329/// Get the qualified name for the current @ref ptr_to_mbr_type.
18330///
18331/// @param internal if this is true, then the qualified name is for
18332/// the purpose of type canoicalization.
18333///
18334/// @return the qualified name for the current @ref ptr_to_mbr_type.
18335const interned_string&
18337{
18338 type_base_sptr member_type = get_member_type();
18339 type_base_sptr containing_type = get_containing_type();
18340
18341 if (internal)
18342 {
18343 if (get_canonical_type())
18344 {
18345 if (priv_->internal_qualified_name_.empty())
18346 priv_->internal_qualified_name_ =
18347 ptr_to_mbr_declaration_name(this, "",
18348 /*qualified=*/true,
18349 internal);
18350 return priv_->internal_qualified_name_;
18351 }
18352 else
18353 {
18354 priv_->temp_internal_qualified_name_ =
18355 ptr_to_mbr_declaration_name(this, "", /*qualified=*/true, internal);
18356 return priv_->temp_internal_qualified_name_;
18357 }
18358 }
18359 else
18360 {
18362 (ptr_to_mbr_declaration_name(this, "", /*qualified=*/true,
18363 /*internal=*/false));
18365 }
18366}
18367
18368/// This implements the ir_traversable_base::traverse pure virtual
18369/// function for @ref ptr_to_mbr_type.
18370///
18371/// @param v the visitor used on the current instance.
18372///
18373/// @return true if the entire IR node tree got traversed, false
18374/// otherwise.
18375bool
18377{
18378 if (v.type_node_has_been_visited(this))
18379 return true;
18380
18381 if (visiting())
18382 return true;
18383
18384 if (v.visit_begin(this))
18385 {
18386 visiting(true);
18387 if (type_base_sptr t = get_member_type())
18388 t->traverse(v);
18389
18390 if (type_base_sptr t = get_containing_type())
18391 t->traverse(v);
18392 visiting(false);
18393 }
18394
18395 bool result = v.visit_end(this);
18397 return result;
18398}
18399
18400/// Desctructor for @ref ptr_to_mbr_type.
18402{}
18403
18404
18405/// Compares two instances of @ref ptr_to_mbr_type.
18406///
18407/// If the two intances are different, set a bitfield to give some
18408/// insight about the kind of differences there are.
18409///
18410/// @param l the first artifact of the comparison.
18411///
18412/// @param r the second artifact of the comparison.
18413///
18414/// @param k a pointer to a bitfield that gives information about the
18415/// kind of changes there are between @p l and @p r. This one is set
18416/// iff @p k is non-null and the function returns false.
18417///
18418/// Please note that setting k to a non-null value does have a
18419/// negative performance impact because even if @p l and @p r are not
18420/// equal, the function keeps up the comparison in order to determine
18421/// the different kinds of ways in which they are different.
18422///
18423/// @return true if @p l equals @p r, false otherwise.
18424bool
18426{
18427 bool result = true;
18428
18429 if (!(l.decl_base::operator==(r)))
18430 {
18431 result = false;
18432 if (k)
18434 else
18435 result = false;
18436 }
18437
18438 if (l.get_member_type() != r.get_member_type())
18439 {
18440 if (k)
18441 {
18442 if (!types_have_similar_structure(&l, &r))
18444 *k |= SUBTYPE_CHANGE_KIND;
18445 }
18446 result = false;
18447 }
18448
18450 {
18451 if (k)
18452 {
18453 if (!types_have_similar_structure(&l, &r))
18455 *k |= SUBTYPE_CHANGE_KIND;
18456 }
18457 result = false;
18458 }
18459
18460 ABG_RETURN(result);
18461}
18462
18463// </ptr_to_mbr_type definitions>
18464
18465// <array_type_def definitions>
18466
18467// <array_type_def::subrange_type>
18468array_type_def::subrange_type::~subrange_type() = default;
18469
18470// <array_type_def::subrante_type::bound_value>
18471
18472/// Default constructor of the @ref
18473/// array_type_def::subrange_type::bound_value class.
18474///
18475/// Constructs an unsigned bound_value of value zero.
18477 : s_(UNSIGNED_SIGNEDNESS)
18478{
18479 v_.unsigned_ = 0;
18480}
18481
18482/// Initialize an unsigned bound_value with a given value.
18483///
18484/// @param v the initial bound value.
18486 : s_(UNSIGNED_SIGNEDNESS)
18487{
18488 v_.unsigned_ = v;
18489}
18490
18491/// Initialize a signed bound_value with a given value.
18492///
18493/// @param v the initial bound value.
18495 : s_(SIGNED_SIGNEDNESS)
18496{
18497 v_.signed_ = v;
18498}
18499
18500/// Getter of the signedness (unsigned VS signed) of the bound value.
18501///
18502/// @return the signedness of the bound value.
18503enum array_type_def::subrange_type::bound_value::signedness
18505{return s_;}
18506
18507/// Setter of the signedness (unsigned VS signed) of the bound value.
18508///
18509/// @param s the new signedness of the bound value.
18510void
18512{ s_ = s;}
18513
18514/// Getter of the bound value as a signed value.
18515///
18516/// @return the bound value as signed.
18517int64_t
18519{return v_.signed_;
18520}
18521
18522/// Getter of the bound value as an unsigned value.
18523///
18524/// @return the bound value as unsigned.
18525uint64_t
18527{return v_.unsigned_;}
18528
18529/// Setter of the bound value as unsigned.
18530///
18531/// @param v the new unsigned value.
18532void
18534{
18535 s_ = UNSIGNED_SIGNEDNESS;
18536 v_.unsigned_ = v;
18537}
18538
18539/// Setter of the bound value as signed.
18540///
18541/// @param v the new signed value.
18542void
18544{
18545 s_ = SIGNED_SIGNEDNESS;
18546 v_.signed_ = v;
18547}
18548
18549/// Equality operator of the bound value.
18550///
18551/// @param v the other bound value to compare with.
18552///
18553/// @return true iff the current bound value equals @p v.
18554bool
18556{
18557 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
18558}
18559
18560// </array_type_def::subrante_type::bound_value>
18561
18562struct array_type_def::subrange_type::priv
18563{
18564 bound_value lower_bound_;
18565 bound_value upper_bound_;
18566 type_base_wptr underlying_type_;
18568 bool infinite_;
18569
18570 priv(bound_value ub,
18571 translation_unit::language l = translation_unit::LANG_C11)
18572 : upper_bound_(ub), language_(l), infinite_(false)
18573 {}
18574
18575 priv(bound_value lb, bound_value ub,
18576 translation_unit::language l = translation_unit::LANG_C11)
18577 : lower_bound_(lb), upper_bound_(ub),
18578 language_(l), infinite_(false)
18579 {}
18580
18581 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
18582 translation_unit::language l = translation_unit::LANG_C11)
18583 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
18584 language_(l), infinite_(false)
18585 {}
18586};
18587
18588/// Constructor of an array_type_def::subrange_type type.
18589///
18590/// @param env the environment this type was created from.
18591///
18592/// @param name the name of the subrange type.
18593///
18594/// @param lower_bound the lower bound of the array. This is
18595/// generally zero (at least for C and C++).
18596///
18597/// @param upper_bound the upper bound of the array.
18598///
18599/// @param underlying_type the underlying type of the subrange type.
18600///
18601/// @param loc the source location where the type is defined.
18602array_type_def::subrange_type::subrange_type(const environment& env,
18603 const string& name,
18604 bound_value lower_bound,
18605 bound_value upper_bound,
18606 const type_base_sptr& utype,
18607 const location& loc,
18609 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18610 type_base(env,
18611 utype
18612 ? utype->get_size_in_bits()
18613 : 0,
18614 0),
18615 decl_base(env, name, loc, ""),
18616 priv_(new priv(lower_bound, upper_bound, utype, l))
18617{
18619}
18620
18621/// Constructor of the array_type_def::subrange_type type.
18622///
18623/// @param env the environment this type is being created in.
18624///
18625/// @param name the name of the subrange type.
18626///
18627/// @param lower_bound the lower bound of the array. This is
18628/// generally zero (at least for C and C++).
18629///
18630/// @param upper_bound the upper bound of the array.
18631///
18632/// @param loc the source location where the type is defined.
18633///
18634/// @param l the language that generated this subrange.
18635array_type_def::subrange_type::subrange_type(const environment& env,
18636 const string& name,
18637 bound_value lower_bound,
18638 bound_value upper_bound,
18639 const location& loc,
18641 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18642 type_base(env, /*size-in-bits=*/0, /*alignment=*/0),
18643 decl_base(env, name, loc, ""),
18644 priv_(new priv(lower_bound, upper_bound, l))
18645{
18647}
18648
18649/// Constructor of the array_type_def::subrange_type type.
18650///
18651/// @param env the environment this type is being created from.
18652///
18653/// @param name of the name of type.
18654///
18655/// @param upper_bound the upper bound of the array. The lower bound
18656/// is considered to be zero.
18657///
18658/// @param loc the source location of the type.
18659///
18660/// @param the language that generated this type.
18661array_type_def::subrange_type::subrange_type(const environment& env,
18662 const string& name,
18663 bound_value upper_bound,
18664 const location& loc,
18666 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18667 type_base(env, upper_bound.get_unsigned_value(), 0),
18668 decl_base(env, name, loc, ""),
18669 priv_(new priv(upper_bound, l))
18670{
18672}
18673
18674/// Getter of the underlying type of the subrange, that is, the type
18675/// that defines the range.
18676///
18677/// @return the underlying type.
18678type_base_sptr
18680{return priv_->underlying_type_.lock();}
18681
18682/// Setter of the underlying type of the subrange, that is, the type
18683/// that defines the range.
18684///
18685/// @param u the new underlying type.
18686void
18688{
18689 ABG_ASSERT(priv_->underlying_type_.expired());
18690 priv_->underlying_type_ = u;
18691 if (u)
18692 set_size_in_bits(u->get_size_in_bits());
18693}
18694
18695/// Getter of the upper bound of the subrange type.
18696///
18697/// @return the upper bound of the subrange type.
18698int64_t
18700{return priv_->upper_bound_.get_signed_value();}
18701
18702/// Getter of the lower bound of the subrange type.
18703///
18704/// @return the lower bound of the subrange type.
18705int64_t
18707{return priv_->lower_bound_.get_signed_value();}
18708
18709/// Setter of the upper bound of the subrange type.
18710///
18711/// @param ub the new value of the upper bound.
18712void
18714{priv_->upper_bound_ = ub;}
18715
18716/// Setter of the lower bound.
18717///
18718/// @param lb the new value of the lower bound.
18719void
18721{priv_->lower_bound_ = lb;}
18722
18723/// Getter of the length of the subrange type.
18724///
18725/// Note that a length of zero means the array has an infinite (or
18726/// rather a non-known) size.
18727///
18728/// @return the length of the subrange type.
18729uint64_t
18731{
18732 if (is_non_finite())
18733 return 0;
18734
18735 // A subrange can have an upper bound that is lower than its lower
18736 // bound. This is possible in Ada for instance. In that case, the
18737 // length of the subrange is considered to be zero.
18738 if (get_upper_bound() >= get_lower_bound())
18739 return get_upper_bound() - get_lower_bound() + 1;
18740 return 0;
18741}
18742
18743/// Test if the length of the subrange type is infinite.
18744///
18745/// @return true iff the length of the subrange type is infinite.
18746bool
18748{return priv_->infinite_;}
18749
18750/// Set the infinite-ness status of the subrange type.
18751///
18752/// @param f true iff the length of the subrange type should be set to
18753/// being infinite.
18754void
18756{priv_->infinite_ = f;}
18757
18758/// Getter of the language that generated this type.
18759///
18760/// @return the language of this type.
18763{return priv_->language_;}
18764
18765/// Return a string representation of the sub range.
18766///
18767/// @return the string representation of the sub range.
18768string
18770{
18771 std::ostringstream o;
18772
18774 {
18775 type_base_sptr underlying_type = get_underlying_type();
18776 if (underlying_type)
18777 o << ir::get_pretty_representation(underlying_type, false) << " ";
18778 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
18779 }
18780 else if (is_non_finite())
18781 o << "[]";
18782 else
18783 o << "[" << get_length() << "]";
18784
18785 return o.str();
18786}
18787
18788/// Return a string representation of a vector of subranges
18789///
18790/// @return the string representation of a vector of sub ranges.
18791string
18793{
18794 if (v.empty())
18795 return "[]";
18796
18797 string r;
18798 for (vector<subrange_sptr>::const_iterator i = v.begin();
18799 i != v.end();
18800 ++i)
18801 r += (*i)->as_string();
18802
18803 return r;
18804}
18805
18806/// Compares two isntances of @ref array_type_def::subrange_type.
18807///
18808/// If the two intances are different, set a bitfield to give some
18809/// insight about the kind of differences there are.
18810///
18811/// @param l the first artifact of the comparison.
18812///
18813/// @param r the second artifact of the comparison.
18814///
18815/// @param k a pointer to a bitfield that gives information about the
18816/// kind of changes there are between @p l and @p r. This one is set
18817/// iff @p k is non-null and the function returns false.
18818///
18819/// Please note that setting k to a non-null value does have a
18820/// negative performance impact because even if @p l and @p r are not
18821/// equal, the function keeps up the comparison in order to determine
18822/// the different kinds of ways in which they are different.
18823///
18824/// @return true if @p l equals @p r, false otherwise.
18825bool
18828 change_kind* k)
18829{
18830 bool result = true;
18831
18832 if (l.get_lower_bound() != r.get_lower_bound()
18833 || l.get_upper_bound() != r.get_upper_bound()
18834 || l.get_name() != r.get_name())
18835 {
18836 result = false;
18837 if (k)
18839 else
18840 ABG_RETURN(result);
18841 }
18842
18843 ABG_RETURN(result);
18844}
18845
18846/// Equality operator.
18847///
18848/// @param o the other subrange to test against.
18849///
18850/// @return true iff @p o equals the current instance of
18851/// array_type_def::subrange_type.
18852bool
18854{
18855 const subrange_type* other =
18856 dynamic_cast<const subrange_type*>(&o);
18857 if (!other)
18858 return false;
18859 return try_canonical_compare(this, other);
18860}
18861
18862/// Equality operator.
18863///
18864/// @param o the other subrange to test against.
18865///
18866/// @return true iff @p o equals the current instance of
18867/// array_type_def::subrange_type.
18868bool
18870{
18871 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18872 if (!other)
18873 return false;
18874 return *this == *other;
18875}
18876
18877/// Equality operator.
18878///
18879/// @param o the other subrange to test against.
18880///
18881/// @return true iff @p o equals the current instance of
18882/// array_type_def::subrange_type.
18883bool
18885{
18886 const type_base &t = o;
18887 return operator==(t);
18888}
18889
18890/// Equality operator.
18891///
18892/// @param o the other subrange to test against.
18893///
18894/// @return true iff @p o equals the current instance of
18895/// array_type_def::subrange_type.
18896bool
18898{return !operator==(o);}
18899
18900/// Equality operator.
18901///
18902/// @param o the other subrange to test against.
18903///
18904/// @return true iff @p o equals the current instance of
18905/// array_type_def::subrange_type.
18906bool
18908{return !operator==(o);}
18909
18910/// Inequality operator.
18911///
18912/// @param o the other subrange to test against.
18913///
18914/// @return true iff @p o is different from the current instance of
18915/// array_type_def::subrange_type.
18916bool
18918{return !operator==(o);}
18919
18920/// Build a pretty representation for an
18921/// array_type_def::subrange_type.
18922///
18923/// @param internal set to true if the call is intended to get a
18924/// representation of the decl (or type) for the purpose of canonical
18925/// type comparison. This is mainly used in the function
18926/// type_base::get_canonical_type_for().
18927///
18928/// In other words if the argument for this parameter is true then the
18929/// call is meant for internal use (for technical use inside the
18930/// library itself), false otherwise. If you don't know what this is
18931/// for, then set it to false.
18932///
18933/// @return a copy of the pretty representation of the current
18934/// instance of typedef_decl.
18935string
18937{
18938 string name = get_name();
18939 string repr;
18940
18941 if (name.empty())
18942 repr += "<anonymous range>";
18943 else
18944 repr += "<range " + get_name() + ">";
18945 repr += as_string();
18946
18947 return repr;
18948}
18949
18950/// This implements the ir_traversable_base::traverse pure virtual
18951/// function.
18952///
18953/// @param v the visitor used on the current instance.
18954///
18955/// @return true if the entire IR node tree got traversed, false
18956/// otherwise.
18957bool
18959{
18960 if (v.type_node_has_been_visited(this))
18961 return true;
18962
18963 if (v.visit_begin(this))
18964 {
18965 visiting(true);
18966 if (type_base_sptr u = get_underlying_type())
18967 u->traverse(v);
18968 visiting(false);
18969 }
18970
18971 bool result = v.visit_end(this);
18973 return result;
18974}
18975
18976// </array_type_def::subrange_type>
18977
18978struct array_type_def::priv
18979{
18980 type_base_wptr element_type_;
18981 subranges_type subranges_;
18982 interned_string temp_internal_qualified_name_;
18983 interned_string internal_qualified_name_;
18984
18985 priv(type_base_sptr t)
18986 : element_type_(t)
18987 {}
18988
18989 priv(type_base_sptr t, subranges_type subs)
18990 : element_type_(t), subranges_(subs)
18991 {}
18992
18993 priv()
18994 {}
18995};
18996
18997/// Constructor for the type array_type_def
18998///
18999/// Note how the constructor expects a vector of subrange
19000/// objects. Parsing of the array information always entails
19001/// parsing the subrange info as well, thus the class subrange_type
19002/// is defined inside class array_type_def and also parsed
19003/// simultaneously.
19004///
19005/// @param e_type the type of the elements contained in the array
19006///
19007/// @param subs a vector of the array's subranges(dimensions)
19008///
19009/// @param locus the source location of the array type definition.
19010array_type_def::array_type_def(const type_base_sptr e_type,
19011 const std::vector<subrange_sptr>& subs,
19012 const location& locus)
19014 ARRAY_TYPE
19015 | ABSTRACT_TYPE_BASE
19016 | ABSTRACT_DECL_BASE),
19017 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
19018 decl_base(e_type->get_environment(), locus),
19019 priv_(new priv(e_type))
19020{
19022 append_subranges(subs);
19023}
19024
19025/// Constructor for the type array_type_def
19026///
19027/// This constructor builds a temporary array that has no element type
19028/// associated. Later when the element type is available, it be set
19029/// with the array_type_def::set_element_type() member function.
19030///
19031/// Note how the constructor expects a vector of subrange
19032/// objects. Parsing of the array information always entails
19033/// parsing the subrange info as well, thus the class subrange_type
19034/// is defined inside class array_type_def and also parsed
19035/// simultaneously.
19036///
19037/// @param env the environment of the array type.
19038///
19039/// @param subs a vector of the array's subranges(dimensions)
19040///
19041/// @param locus the source location of the array type definition.
19042array_type_def::array_type_def(const environment& env,
19043 const std::vector<subrange_sptr>& subs,
19044 const location& locus)
19045 : type_or_decl_base(env,
19046 ARRAY_TYPE
19047 | ABSTRACT_TYPE_BASE
19048 | ABSTRACT_DECL_BASE),
19049 type_base(env, 0, 0),
19050 decl_base(env, locus),
19051 priv_(new priv)
19052{
19054 append_subranges(subs);
19055}
19056
19057/// Update the size of the array.
19058///
19059/// This function computes the size of the array and sets it using
19060/// type_base::set_size_in_bits().
19061void
19062array_type_def::update_size()
19063{
19064 type_base_sptr e = priv_->element_type_.lock();
19065 if (e)
19066 {
19067 size_t s = e->get_size_in_bits();
19068 if (s)
19069 {
19070 for (const auto &sub : get_subranges())
19071 s *= sub->get_length();
19073 }
19074 set_alignment_in_bits(e->get_alignment_in_bits());
19075 }
19076}
19077
19078string
19079array_type_def::get_subrange_representation() const
19080{
19082 return r;
19083}
19084
19085/// Get the pretty representation of the current instance of @ref
19086/// array_type_def.
19087///
19088/// @param internal set to true if the call is intended to get a
19089/// representation of the decl (or type) for the purpose of canonical
19090/// type comparison. This is mainly used in the function
19091/// type_base::get_canonical_type_for().
19092///
19093/// In other words if the argument for this parameter is true then the
19094/// call is meant for internal use (for technical use inside the
19095/// library itself), false otherwise. If you don't know what this is
19096/// for, then set it to false.
19097/// @param internal set to true if the call is intended for an
19098/// internal use (for technical use inside the library itself), false
19099/// otherwise. If you don't know what this is for, then set it to
19100/// false.
19101///
19102/// @return the pretty representation of the ABI artifact.
19103string
19105 bool qualified_name) const
19106{
19107 return array_declaration_name(this, /*variable_name=*/"",
19108 qualified_name, internal);
19109}
19110
19111/// Compares two instances of @ref array_type_def.
19112///
19113/// If the two intances are different, set a bitfield to give some
19114/// insight about the kind of differences there are.
19115///
19116/// @param l the first artifact of the comparison.
19117///
19118/// @param r the second artifact of the comparison.
19119///
19120/// @param k a pointer to a bitfield that gives information about the
19121/// kind of changes there are between @p l and @p r. This one is set
19122/// iff @p k is non-null and the function returns false.
19123///
19124/// Please note that setting k to a non-null value does have a
19125/// negative performance impact because even if @p l and @p r are not
19126/// equal, the function keeps up the comparison in order to determine
19127/// the different kinds of ways in which they are different.
19128///
19129/// @return true if @p l equals @p r, false otherwise.
19130bool
19132{
19133 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
19134 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
19135
19136 bool result = true;
19137 if (this_subs.size() != other_subs.size())
19138 {
19139 result = false;
19140 if (k)
19142 else
19144 }
19145
19146 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19147 for (i = this_subs.begin(), j = other_subs.begin();
19148 i != this_subs.end() && j != other_subs.end();
19149 ++i, ++j)
19150 if (**i != **j)
19151 {
19152 result = false;
19153 if (k)
19154 {
19156 break;
19157 }
19158 else
19160 }
19161
19162 // Compare the element types modulo the typedefs they might have
19163 if (l.get_element_type() != r.get_element_type())
19164 {
19165 result = false;
19166 if (k)
19167 *k |= SUBTYPE_CHANGE_KIND;
19168 else
19170 }
19171
19172 ABG_RETURN(result);
19173}
19174
19175/// Test if two variables are equals modulo CV qualifiers.
19176///
19177/// @param l the first array of the comparison.
19178///
19179/// @param r the second array of the comparison.
19180///
19181/// @return true iff @p l equals @p r or, if they are different, the
19182/// difference between the too is just a matter of CV qualifiers.
19183bool
19185{
19186 if (l == r)
19187 return true;
19188
19189 if (!l || !r)
19191
19194
19195 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
19196 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
19197
19198 if (this_subs.size() != other_subs.size())
19200
19201 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19202 for (i = this_subs.begin(), j = other_subs.begin();
19203 i != this_subs.end() && j != other_subs.end();
19204 ++i, ++j)
19205 if (**i != **j)
19207
19208 type_base *first_element_type =
19210 type_base *second_element_type =
19212
19213 if (*first_element_type != *second_element_type)
19215
19216 return true;
19217}
19218
19219/// Get the language of the array.
19220///
19221/// @return the language of the array.
19224{
19225 const std::vector<subrange_sptr>& subranges =
19226 get_subranges();
19227
19228 if (subranges.empty())
19229 return translation_unit::LANG_C11;
19230 return subranges.front()->get_language();
19231}
19232
19233bool
19235{
19236 const array_type_def* other =
19237 dynamic_cast<const array_type_def*>(&o);
19238 if (!other)
19239 return false;
19240 return try_canonical_compare(this, other);
19241}
19242
19243bool
19245{
19246 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19247 if (!other)
19248 return false;
19249 return *this == *other;
19250}
19251
19252/// Getter of the type of an array element.
19253///
19254/// @return the type of an array element.
19255const type_base_sptr
19257{return priv_->element_type_.lock();}
19258
19259/// Setter of the type of array element.
19260///
19261/// Beware that after using this function, one might want to
19262/// re-compute the canonical type of the array, if one has already
19263/// been computed.
19264///
19265/// The intended use of this method is to permit in-place adjustment
19266/// of the element type's qualifiers. In particular, the size of the
19267/// element type should not be changed.
19268///
19269/// @param element_type the new element type to set.
19270void
19271array_type_def::set_element_type(const type_base_sptr& element_type)
19272{
19273 priv_->element_type_ = element_type;
19274 update_size();
19276}
19277
19278/// Append subranges from the vector @param subs to the current
19279/// vector of subranges.
19280void
19281array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
19282{
19283
19284 for (const auto &sub : subs)
19285 priv_->subranges_.push_back(sub);
19286
19287 update_size();
19289}
19290
19291/// @return true if one of the sub-ranges of the array is infinite, or
19292/// if the array has no sub-range at all, also meaning that the size
19293/// of the array is infinite.
19294bool
19296{
19297 if (priv_->subranges_.empty())
19298 return true;
19299
19300 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
19301 priv_->subranges_.begin();
19302 i != priv_->subranges_.end();
19303 ++i)
19304 if ((*i)->is_non_finite())
19305 return true;
19306
19307 return false;
19308}
19309
19310int
19311array_type_def::get_dimension_count() const
19312{return priv_->subranges_.size();}
19313
19314/// Build and return the qualified name of the current instance of the
19315/// @ref array_type_def.
19316///
19317/// @param qn output parameter. Is set to the newly-built qualified
19318/// name of the current instance of @ref array_type_def.
19319///
19320/// @param internal set to true if the call is intended for an
19321/// internal use (for technical use inside the library itself), false
19322/// otherwise. If you don't know what this is for, then set it to
19323/// false.
19324void
19326{qn = get_qualified_name(internal);}
19327
19328/// Compute the qualified name of the array.
19329///
19330/// @param internal set to true if the call is intended for an
19331/// internal use (for technical use inside the library itself), false
19332/// otherwise. If you don't know what this is for, then set it to
19333/// false.
19334///
19335/// @return the resulting qualified name.
19336const interned_string&
19338{
19339 if (internal)
19340 {
19341 if (get_canonical_type())
19342 {
19343 if (priv_->internal_qualified_name_.empty())
19344 priv_->internal_qualified_name_ =
19345 array_declaration_name(this, /*variable_name=*/"",
19346 /*qualified=*/false,
19347 /*internal=*/true);
19348 return priv_->internal_qualified_name_;
19349 }
19350 else
19351 {
19352 priv_->temp_internal_qualified_name_ =
19353 array_declaration_name(this, /*variable_name=*/"",
19354 /*qualified*/false, /*internal*/true);
19355 return priv_->temp_internal_qualified_name_;
19356 }
19357 }
19358 else
19359 {
19360 if (get_canonical_type())
19361 {
19362 if (decl_base::peek_qualified_name().empty())
19363 set_qualified_name(array_declaration_name(this,
19364 /*variable_name=*/"",
19365 /*qualified=*/false,
19366 /*internal=*/false));
19368 }
19369 else
19370 {
19372 (array_declaration_name(this, /*variable_name=*/"",
19373 /*qualified=*/false,
19374 /*internal=*/false));
19376 }
19377 }
19378}
19379
19380/// This implements the ir_traversable_base::traverse pure virtual
19381/// function.
19382///
19383/// @param v the visitor used on the current instance.
19384///
19385/// @return true if the entire IR node tree got traversed, false
19386/// otherwise.
19387bool
19389{
19390 if (v.type_node_has_been_visited(this))
19391 return true;
19392
19393 if (visiting())
19394 return true;
19395
19396 if (v.visit_begin(this))
19397 {
19398 visiting(true);
19399 if (type_base_sptr t = get_element_type())
19400 t->traverse(v);
19401 visiting(false);
19402 }
19403
19404 bool result = v.visit_end(this);
19406 return result;
19407}
19408
19409const location&
19410array_type_def::get_location() const
19411{return decl_base::get_location();}
19412
19413/// Get the array's subranges
19414const std::vector<array_type_def::subrange_sptr>&
19416{return priv_->subranges_;}
19417
19418array_type_def::~array_type_def()
19419{}
19420
19421// </array_type_def definitions>
19422
19423// <enum_type_decl definitions>
19424
19425class enum_type_decl::priv
19426{
19427 type_base_sptr underlying_type_;
19428 enumerators enumerators_;
19429 mutable enumerators sorted_enumerators_;
19430
19431 friend class enum_type_decl;
19432
19433 priv();
19434
19435public:
19436 priv(type_base_sptr underlying_type,
19438 : underlying_type_(underlying_type),
19439 enumerators_(enumerators)
19440 {}
19441}; // end class enum_type_decl::priv
19442
19443/// Constructor.
19444///
19445/// @param name the name of the type declaration.
19446///
19447/// @param locus the source location where the type was defined.
19448///
19449/// @param underlying_type the underlying type of the enum.
19450///
19451/// @param enums the enumerators of this enum type.
19452///
19453/// @param linkage_name the linkage name of the enum.
19454///
19455/// @param vis the visibility of the enum type.
19456enum_type_decl::enum_type_decl(const string& name,
19457 const location& locus,
19458 type_base_sptr underlying_type,
19459 enumerators& enums,
19460 const string& linkage_name,
19461 visibility vis)
19462 : type_or_decl_base(underlying_type->get_environment(),
19463 ENUM_TYPE
19464 | ABSTRACT_TYPE_BASE
19465 | ABSTRACT_DECL_BASE),
19466 type_base(underlying_type->get_environment(),
19467 underlying_type->get_size_in_bits(),
19468 underlying_type->get_alignment_in_bits()),
19469 decl_base(underlying_type->get_environment(),
19470 name, locus, linkage_name, vis),
19471 priv_(new priv(underlying_type, enums))
19472{
19474 for (enumerators::iterator e = get_enumerators().begin();
19475 e != get_enumerators().end();
19476 ++e)
19477 e->set_enum_type(this);
19478}
19479
19480/// Return the underlying type of the enum.
19481type_base_sptr
19483{return priv_->underlying_type_;}
19484
19485/// @return the list of enumerators of the enum.
19488{return priv_->enumerators_;}
19489
19490/// @return the list of enumerators of the enum.
19493{return priv_->enumerators_;}
19494
19495/// Get the lexicographically sorted vector of enumerators.
19496///
19497/// @return the lexicographically sorted vector of enumerators.
19500{
19501 if (priv_->sorted_enumerators_.empty())
19502 {
19503 for (auto e = get_enumerators().rbegin();
19504 e != get_enumerators().rend();
19505 ++e)
19506 priv_->sorted_enumerators_.push_back(*e);
19507
19508 std::sort(priv_->sorted_enumerators_.begin(),
19509 priv_->sorted_enumerators_.end(),
19510 [](const enum_type_decl::enumerator& l,
19512 {
19513 if (l.get_name() == r.get_name())
19514 return l.get_value() < r.get_value();
19515 return (l.get_name() < r.get_name());
19516 });
19517 }
19518
19519 return priv_->sorted_enumerators_;
19520}
19521
19522/// Get the pretty representation of the current instance of @ref
19523/// enum_type_decl.
19524///
19525/// @param internal set to true if the call is intended to get a
19526/// representation of the decl (or type) for the purpose of canonical
19527/// type comparison. This is mainly used in the function
19528/// type_base::get_canonical_type_for().
19529///
19530/// In other words if the argument for this parameter is true then the
19531/// call is meant for internal use (for technical use inside the
19532/// library itself), false otherwise. If you don't know what this is
19533/// for, then set it to false.
19534///
19535/// @param qualified_name if true, names emitted in the pretty
19536/// representation are fully qualified.
19537///
19538/// @return the pretty representation of the enum type.
19539string
19541 bool qualified_name) const
19542{
19543 string r = "enum ";
19544
19545 if (internal && get_is_anonymous())
19546 r += get_type_name(this, qualified_name, /*internal=*/true);
19547 else if (get_is_anonymous())
19548 r += get_enum_flat_representation(*this, "",
19549 /*one_line=*/true,
19550 qualified_name);
19551 else
19553 qualified_name);
19554 return r;
19555}
19556
19557/// This implements the ir_traversable_base::traverse pure virtual
19558/// function.
19559///
19560/// @param v the visitor used on the current instance.
19561///
19562/// @return true if the entire IR node tree got traversed, false
19563/// otherwise.
19564bool
19566{
19567 if (v.type_node_has_been_visited(this))
19568 return true;
19569
19570 if (visiting())
19571 return true;
19572
19573 if (v.visit_begin(this))
19574 {
19575 visiting(true);
19576 if (type_base_sptr t = get_underlying_type())
19577 t->traverse(v);
19578 visiting(false);
19579 }
19580
19581 bool result = v.visit_end(this);
19583 return result;
19584}
19585
19586/// Destructor for the enum type declaration.
19588{}
19589
19590/// Test if two enums differ, but not by a name change.
19591///
19592/// @param l the first enum to consider.
19593///
19594/// @param r the second enum to consider.
19595///
19596/// @return true iff @p l differs from @p r by anything but a name
19597/// change.
19598bool
19600 const enum_type_decl& r,
19601 change_kind* k)
19602{
19603 bool result = false;
19605 {
19606 result = true;
19607 if (k)
19608 *k |= SUBTYPE_CHANGE_KIND;
19609 else
19610 return true;
19611 }
19612
19613 enum_type_decl::enumerators::const_iterator i, j;
19614 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
19615 i != l.get_enumerators().end() && j != r.get_enumerators().end();
19616 ++i, ++j)
19617 if (*i != *j)
19618 {
19619 result = true;
19620 if (k)
19621 {
19623 break;
19624 }
19625 else
19626 return true;
19627 }
19628
19629 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
19630 {
19631 result = true;
19632 if (k)
19634 else
19635 return true;
19636 }
19637
19638 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
19641 string n_l = l.get_name();
19642 string n_r = r.get_name();
19643 local_r.set_qualified_name(qn_l);
19644 local_r.set_name(n_l);
19645
19646 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
19647 {
19648 result = true;
19649 if (k)
19650 {
19651 if (!l.decl_base::operator==(r))
19653 if (!l.type_base::operator==(r))
19655 }
19656 else
19657 {
19658 local_r.set_name(n_r);
19659 local_r.set_qualified_name(qn_r);
19660 return true;
19661 }
19662 }
19663 local_r.set_qualified_name(qn_r);
19664 local_r.set_name(n_r);
19665
19666 return result;
19667}
19668
19669/// Test if a given enumerator is found present in an enum.
19670///
19671/// This is a subroutine of the equals function for enums.
19672///
19673/// @param enr the enumerator to consider.
19674///
19675/// @param enom the enum to consider.
19676///
19677/// @return true iff the enumerator @p enr is present in the enum @p
19678/// enom.
19679bool
19681 const enum_type_decl &enom)
19682{
19683 for (const auto &e : enom.get_enumerators())
19684 if (e == enr)
19685 return true;
19686 return false;
19687}
19688
19689/// Check if two enumerators values are equal.
19690///
19691/// This function doesn't check if the names of the enumerators are
19692/// equal or not.
19693///
19694/// @param enr the first enumerator to consider.
19695///
19696/// @param enl the second enumerator to consider.
19697///
19698/// @return true iff @p enr has the same value as @p enl.
19699static bool
19700enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
19701 const enum_type_decl::enumerator &enl)
19702{return enr.get_value() == enl.get_value();}
19703
19704/// Detect if a given enumerator value is present in an enum.
19705///
19706/// This function looks inside the enumerators of a given enum and
19707/// detect if the enum contains at least one enumerator or a given
19708/// value. The function also detects if the enumerator value we are
19709/// looking at is present in the enum with a different name. An
19710/// enumerator with the same value but with a different name is named
19711/// a "redundant enumerator". The function returns the set of
19712/// enumerators that are redundant with the value we are looking at.
19713///
19714/// @param enr the enumerator to consider.
19715///
19716/// @param enom the enum to consider.
19717///
19718/// @param redundant_enrs if the function returns true, then this
19719/// vector is filled with enumerators that are redundant with the
19720/// value of @p enr.
19721///
19722/// @return true iff the function detects that @p enom contains
19723/// enumerators with the same value as @p enr.
19724static bool
19725is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
19726 const enum_type_decl &enom,
19727 vector<enum_type_decl::enumerator>& redundant_enrs)
19728{
19729 bool found = false;
19730 for (const auto &e : enom.get_enumerators())
19731 if (enumerators_values_are_equal(e, enr))
19732 {
19733 found = true;
19734 if (e != enr)
19735 redundant_enrs.push_back(e);
19736 }
19737
19738 return found;
19739}
19740
19741/// Check if an enumerator value is redundant in a given enum.
19742///
19743/// Given an enumerator value, this function detects if an enum
19744/// contains at least one enumerator with the the same value but with
19745/// a different name.
19746///
19747/// @param enr the enumerator to consider.
19748///
19749/// @param enom the enum to consider.
19750///
19751/// @return true iff @p enr is a redundant enumerator in enom.
19752static bool
19753is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
19754 const enum_type_decl &enom)
19755{
19756 vector<enum_type_decl::enumerator> redundant_enrs;
19757 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
19758 {
19759 if (!redundant_enrs.empty())
19760 return true;
19761 }
19762 return false;
19763}
19764
19765/// Compares two instances of @ref enum_type_decl.
19766///
19767/// If the two intances are different, set a bitfield to give some
19768/// insight about the kind of differences there are.
19769///
19770/// @param l the first artifact of the comparison.
19771///
19772/// @param r the second artifact of the comparison.
19773///
19774/// @param k a pointer to a bitfield that gives information about the
19775/// kind of changes there are between @p l and @p r. This one is set
19776/// iff @p k is non-null and the function returns false.
19777///
19778/// Please note that setting k to a non-null value does have a
19779/// negative performance impact because even if @p l and @p r are not
19780/// equal, the function keeps up the comparison in order to determine
19781/// the different kinds of ways in which they are different.
19782///
19783/// @return true if @p l equals @p r, false otherwise.
19784bool
19786{
19787 bool result = true;
19788
19789 //
19790 // Look through decl-only-enum.
19791 //
19792
19793 const enum_type_decl *def1 =
19796 : &l;
19797
19798 const enum_type_decl *def2 =
19801 : &r;
19802
19803 if (!!def1 != !!def2)
19804 {
19805 // One enum is decl-only while the other is not.
19806 // So the two enums are different.
19807 result = false;
19808 if (k)
19809 *k |= SUBTYPE_CHANGE_KIND;
19810 else
19812 }
19813
19814 //
19815 // At this point, both enums have the same state of decl-only-ness.
19816 // So we can compare oranges to oranges.
19817 //
19818
19819 if (!def1)
19820 def1 = &l;
19821 if (!def2)
19822 def2 = &r;
19823
19824 if (def1->get_underlying_type() != def2->get_underlying_type())
19825 {
19826 result = false;
19827 if (k)
19828 *k |= SUBTYPE_CHANGE_KIND;
19829 else
19831 }
19832
19833 if (!(def1->decl_base::operator==(*def2)
19834 && def1->type_base::operator==(*def2)))
19835 {
19836 result = false;
19837 if (k)
19838 {
19839 if (!def1->decl_base::operator==(*def2))
19841 if (!def1->type_base::operator==(*def2))
19843 }
19844 else
19846 }
19847
19848 // Now compare the enumerators. Note that the order of declaration
19849 // of enumerators should not matter in the comparison.
19850 //
19851 // Also if an enumerator value is redundant, that shouldn't impact
19852 // the comparison.
19853 //
19854 // In that case, note that the two enums below are considered equal:
19855 //
19856 // enum foo
19857 // {
19858 // e0 = 0;
19859 // e1 = 1;
19860 // e2 = 2;
19861 // };
19862 //
19863 // enum foo
19864 // {
19865 // e0 = 0;
19866 // e1 = 1;
19867 // e2 = 2;
19868 // e_added = 1; // <-- this value is redundant with the value
19869 // // of the enumerator e1.
19870 // };
19871 //
19872 // Note however that in the case below, the enums are different.
19873 //
19874 // enum foo
19875 // {
19876 // e0 = 0;
19877 // e1 = 1;
19878 // };
19879 //
19880 // enum foo
19881 // {
19882 // e0 = 0;
19883 // e2 = 1; // <-- this enum value is present in the first version
19884 // // of foo, but is not redundant with any enumerator
19885 // // in the second version of of enum foo.
19886 // };
19887 //
19888 // These two enums are considered equal.
19889
19890 for(const auto &e : def1->get_enumerators())
19891 if (!is_enumerator_present_in_enum(e, *def2)
19892 && (!is_enumerator_value_redundant(e, *def2)
19893 || !is_enumerator_value_redundant(e, *def1)))
19894 {
19895 result = false;
19896 if (k)
19897 {
19899 break;
19900 }
19901 else
19903 }
19904
19905 for(const auto &e : def2->get_enumerators())
19906 if (!is_enumerator_present_in_enum(e, *def1)
19907 && (!is_enumerator_value_redundant(e, *def1)
19908 || !is_enumerator_value_redundant(e, *def2)))
19909 {
19910 result = false;
19911 if (k)
19912 {
19914 break;
19915 }
19916 else
19918 }
19919
19920 ABG_RETURN(result);
19921}
19922
19923/// Equality operator.
19924///
19925/// @param o the other enum to test against.
19926///
19927/// @return true iff @p o equals the current instance of enum type
19928/// decl.
19929bool
19931{
19932 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
19933 if (!op)
19934 return false;
19935 return try_canonical_compare(this, op);
19936}
19937
19938/// Equality operator.
19939///
19940/// @param o the other enum to test against.
19941///
19942/// @return true iff @p o is equals the current instance of enum type
19943/// decl.
19944bool
19946{
19947 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19948 if (!other)
19949 return false;
19950 return *this == *other;
19951}
19952
19953/// Equality operator for @ref enum_type_decl_sptr.
19954///
19955/// @param l the first operand to compare.
19956///
19957/// @param r the second operand to compare.
19958///
19959/// @return true iff @p l equals @p r.
19960bool
19962{
19963 if (!!l != !!r)
19964 return false;
19965 if (l.get() == r.get())
19966 return true;
19967 decl_base_sptr o = r;
19968 return *l == *o;
19969}
19970
19971/// Inequality operator for @ref enum_type_decl_sptr.
19972///
19973/// @param l the first operand to compare.
19974///
19975/// @param r the second operand to compare.
19976///
19977/// @return true iff @p l equals @p r.
19978bool
19980{return !operator==(l, r);}
19981
19982/// The type of the private data of an @ref
19983/// enum_type_decl::enumerator.
19984class enum_type_decl::enumerator::priv
19985{
19986 string name_;
19987 int64_t value_;
19988 string qualified_name_;
19989 enum_type_decl* enum_type_;
19990
19991 friend class enum_type_decl::enumerator;
19992
19993public:
19994
19995 priv()
19996 : enum_type_()
19997 {}
19998
19999 priv(const string& name,
20000 int64_t value,
20001 enum_type_decl* e = 0)
20002 : name_(name),
20003 value_(value),
20004 enum_type_(e)
20005 {}
20006}; // end class enum_type_def::enumerator::priv
20007
20008/// Default constructor of the @ref enum_type_decl::enumerator type.
20010 : priv_(new priv)
20011{}
20012
20013enum_type_decl::enumerator::~enumerator() = default;
20014
20015/// Constructor of the @ref enum_type_decl::enumerator type.
20016///
20017/// @param env the environment we are operating from.
20018///
20019/// @param name the name of the enumerator.
20020///
20021/// @param value the value of the enumerator.
20023 int64_t value)
20024 : priv_(new priv(name, value))
20025{}
20026
20027/// Copy constructor of the @ref enum_type_decl::enumerator type.
20028///
20029/// @param other enumerator to copy.
20031 : priv_(new priv(other.get_name(),
20032 other.get_value(),
20033 other.get_enum_type()))
20034{}
20035
20036/// Assignment operator of the @ref enum_type_decl::enumerator type.
20037///
20038/// @param o
20041{
20042 priv_->name_ = o.get_name();
20043 priv_->value_ = o.get_value();
20044 priv_->enum_type_ = o.get_enum_type();
20045 return *this;
20046}
20047
20048/// Equality operator
20049///
20050/// @param other the enumerator to compare to the current
20051/// instance of enum_type_decl::enumerator.
20052///
20053/// @return true if @p other equals the current instance of
20054/// enum_type_decl::enumerator.
20055bool
20057{
20058 bool names_equal = true;
20059 names_equal = (get_name() == other.get_name());
20060 return names_equal && (get_value() == other.get_value());
20061}
20062
20063/// Inequality operator.
20064///
20065/// @param other the other instance to compare against.
20066///
20067/// @return true iff @p other is different from the current instance.
20068bool
20070{return !operator==(other);}
20071
20072/// Getter for the name of the current instance of
20073/// enum_type_decl::enumerator.
20074///
20075/// @return a reference to the name of the current instance of
20076/// enum_type_decl::enumerator.
20077const string&
20079{return priv_->name_;}
20080
20081/// Getter for the qualified name of the current instance of
20082/// enum_type_decl::enumerator. The first invocation of the method
20083/// builds the qualified name, caches it and return a reference to the
20084/// cached qualified name. Subsequent invocations just return the
20085/// cached value.
20086///
20087/// @param internal set to true if the call is intended for an
20088/// internal use (for technical use inside the library itself), false
20089/// otherwise. If you don't know what this is for, then set it to
20090/// false.
20091///
20092/// @return the qualified name of the current instance of
20093/// enum_type_decl::enumerator.
20094const string&
20096{
20097 if (priv_->qualified_name_.empty())
20098 {
20099 priv_->qualified_name_ =
20100 get_enum_type()->get_qualified_name(internal)
20101 + "::"
20102 + get_name();
20103 }
20104 return priv_->qualified_name_;
20105}
20106
20107/// Setter for the name of @ref enum_type_decl::enumerator.
20108///
20109/// @param n the new name.
20110void
20112{priv_->name_ = n;}
20113
20114/// Getter for the value of @ref enum_type_decl::enumerator.
20115///
20116/// @return the value of the current instance of
20117/// enum_type_decl::enumerator.
20118int64_t
20120{return priv_->value_;}
20121
20122/// Setter for the value of @ref enum_type_decl::enumerator.
20123///
20124/// @param v the new value of the enum_type_decl::enumerator.
20125void
20127{priv_->value_= v;}
20128
20129/// Getter for the enum type that this enumerator is for.
20130///
20131/// @return the enum type that this enumerator is for.
20134{return priv_->enum_type_;}
20135
20136/// Setter for the enum type that this enumerator is for.
20137///
20138/// @param e the new enum type.
20139void
20141{priv_->enum_type_ = e;}
20142// </enum_type_decl definitions>
20143
20144// <typedef_decl definitions>
20145
20146/// Private data structure of the @ref typedef_decl.
20147struct typedef_decl::priv
20148{
20149 type_base_wptr underlying_type_;
20150
20151 priv(const type_base_sptr& t)
20152 : underlying_type_(t)
20153 {}
20154}; // end struct typedef_decl::priv
20155
20156/// Constructor of the typedef_decl type.
20157///
20158/// @param name the name of the typedef.
20159///
20160/// @param underlying_type the underlying type of the typedef.
20161///
20162/// @param locus the source location of the typedef declaration.
20163///
20164/// @param linkage_name the mangled name of the typedef.
20165///
20166/// @param vis the visibility of the typedef type.
20167typedef_decl::typedef_decl(const string& name,
20168 const type_base_sptr underlying_type,
20169 const location& locus,
20170 const string& linkage_name,
20171 visibility vis)
20172 : type_or_decl_base(underlying_type->get_environment(),
20173 TYPEDEF_TYPE
20174 | ABSTRACT_TYPE_BASE
20175 | ABSTRACT_DECL_BASE),
20176 type_base(underlying_type->get_environment(),
20177 underlying_type->get_size_in_bits(),
20178 underlying_type->get_alignment_in_bits()),
20179 decl_base(underlying_type->get_environment(),
20180 name, locus, linkage_name, vis),
20181 priv_(new priv(underlying_type))
20182{
20184}
20185
20186/// Constructor of the typedef_decl type.
20187///
20188/// @param name the name of the typedef.
20189///
20190/// @param env the environment of the current typedef.
20191///
20192/// @param locus the source location of the typedef declaration.
20193///
20194/// @param mangled_name the mangled name of the typedef.
20195///
20196/// @param vis the visibility of the typedef type.
20197typedef_decl::typedef_decl(const string& name,
20198 const environment& env,
20199 const location& locus,
20200 const string& mangled_name,
20201 visibility vis)
20202 : type_or_decl_base(env,
20203 TYPEDEF_TYPE
20204 | ABSTRACT_TYPE_BASE
20205 | ABSTRACT_DECL_BASE),
20206 type_base(env, /*size_in_bits=*/0,
20207 /*alignment_in_bits=*/0),
20208 decl_base(env, name, locus, mangled_name, vis),
20209 priv_(new priv(nullptr))
20210{
20212}
20213
20214/// Return the size of the typedef.
20215///
20216/// This function looks at the size of the underlying type and ensures
20217/// that it's the same as the size of the typedef.
20218///
20219/// @return the size of the typedef.
20220size_t
20222{
20223 if (!get_underlying_type())
20224 return 0;
20225 size_t s = get_underlying_type()->get_size_in_bits();
20226 if (s != type_base::get_size_in_bits())
20227 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
20229}
20230
20231/// Return the alignment of the typedef.
20232///
20233/// This function looks at the alignment of the underlying type and
20234/// ensures that it's the same as the alignment of the typedef.
20235///
20236/// @return the size of the typedef.
20237size_t
20239{
20240 if (!get_underlying_type())
20241 return 0;
20242 size_t s = get_underlying_type()->get_alignment_in_bits();
20244 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
20246}
20247
20248/// Compares two instances of @ref typedef_decl.
20249///
20250/// If the two intances are different, set a bitfield to give some
20251/// insight about the kind of differences there are.
20252///
20253/// @param l the first artifact of the comparison.
20254///
20255/// @param r the second artifact of the comparison.
20256///
20257/// @param k a pointer to a bitfield that gives information about the
20258/// kind of changes there are between @p l and @p r. This one is set
20259/// iff @p k is non-null and the function returns false.
20260///
20261/// Please note that setting k to a non-null value does have a
20262/// negative performance impact because even if @p l and @p r are not
20263/// equal, the function keeps up the comparison in order to determine
20264/// the different kinds of ways in which they are different.
20265///
20266/// @return true if @p l equals @p r, false otherwise.
20267bool
20269{
20270 bool result = true;
20271
20272 // No need to go further if the types have different names or
20273 // different size / alignment.
20274 if (!(l.decl_base::operator==(r)))
20275 {
20276 result = false;
20277 if (k)
20279 else
20281 }
20282
20284 {
20285 // Changes to the underlying type of a typedef are considered
20286 // local, a bit like for pointers.
20287 result = false;
20288 if (k)
20290 else
20292 }
20293
20294 ABG_RETURN(result);
20295}
20296
20297/// Equality operator
20298///
20299/// @param o the other typedef_decl to test against.
20300bool
20302{
20303 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
20304 if (!other)
20305 return false;
20306 return try_canonical_compare(this, other);
20307}
20308
20309/// Equality operator
20310///
20311/// @param o the other typedef_decl to test against.
20312///
20313/// @return true if the current instance of @ref typedef_decl equals
20314/// @p o.
20315bool
20317{
20318 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20319 if (!other)
20320 return false;
20321 return *this == *other;
20322}
20323
20324/// Build a pretty representation for a typedef_decl.
20325///
20326/// @param internal set to true if the call is intended to get a
20327/// representation of the decl (or type) for the purpose of canonical
20328/// type comparison. This is mainly used in the function
20329/// type_base::get_canonical_type_for().
20330///
20331/// In other words if the argument for this parameter is true then the
20332/// call is meant for internal use (for technical use inside the
20333/// library itself), false otherwise. If you don't know what this is
20334/// for, then set it to false.
20335
20336/// @param qualified_name if true, names emitted in the pretty
20337/// representation are fully qualified.
20338///
20339/// @return a copy of the pretty representation of the current
20340/// instance of typedef_decl.
20341string
20343 bool qualified_name) const
20344{
20345
20346 string result = "typedef ";
20347 if (internal)
20348 result += get_name();
20349 else
20350 {
20351 if (qualified_name)
20352 result += get_qualified_name(internal);
20353 else
20354 result += get_name();
20355 }
20356
20357 return result;
20358}
20359
20360/// Getter of the underlying type of the typedef.
20361///
20362/// @return the underlying_type.
20363type_base_sptr
20365{return priv_->underlying_type_.lock();}
20366
20367/// Setter ofthe underlying type of the typedef.
20368///
20369/// @param t the new underlying type of the typedef.
20370void
20372{
20373 priv_->underlying_type_ = t;
20374 set_size_in_bits(t->get_size_in_bits());
20375 set_alignment_in_bits(t->get_alignment_in_bits());
20376}
20377
20378/// Implementation of the virtual "get_qualified_name" method.
20379///
20380/// @param qualified_name the resuling qualified name of the typedef type.
20381///
20382/// @param internal if true, then it means the qualified name is for
20383/// "internal" purposes, meaning mainly for type canonicalization
20384/// purposes.
20385void
20387 bool internal) const
20388{qualified_name = get_qualified_name(internal);}
20389
20390/// Implementation of the virtual "get_qualified_name" method.
20391///
20392/// @param internal if true, then it means the qualified name is for
20393/// "internal" purposes, meaning mainly for type canonicalization
20394/// purposes.
20395///
20396/// @return the qualified name.
20397const interned_string&
20399{
20400 // Note that the qualified name has been already set by
20401 // qualified_name_setter::do_update, which is invoked by
20402 // update_qualified_name. The latter is itself invoked whenever the
20403 // typedef is added to its scope, in scope_decl::add_member_decl.
20404 if (internal)
20405 return decl_base::priv_->internal_qualified_name_;
20406 else
20407 return decl_base::priv_->qualified_name_;
20408}
20409
20410/// This implements the ir_traversable_base::traverse pure virtual
20411/// function.
20412///
20413/// @param v the visitor used on the current instance.
20414///
20415/// @return true if the entire IR node tree got traversed, false
20416/// otherwise.
20417bool
20419{
20420 if (v.type_node_has_been_visited(this))
20421 return true;
20422
20423 if (visiting())
20424 return true;
20425
20426 if (v.visit_begin(this))
20427 {
20428 visiting(true);
20429 if (type_base_sptr t = get_underlying_type())
20430 t->traverse(v);
20431 visiting(false);
20432 }
20433
20434 bool result = v.visit_end(this);
20436 return result;
20437}
20438
20439typedef_decl::~typedef_decl()
20440{}
20441// </typedef_decl definitions>
20442
20443// <var_decl definitions>
20444
20445struct var_decl::priv
20446{
20447 type_base_wptr type_;
20448 type_base* naked_type_;
20449 decl_base::binding binding_;
20450 elf_symbol_sptr symbol_;
20451 interned_string id_;
20452
20453 priv()
20454 : naked_type_(),
20455 binding_(decl_base::BINDING_GLOBAL)
20456 {}
20457
20458 priv(type_base_sptr t,
20460 : type_(t),
20461 naked_type_(t.get()),
20462 binding_(b)
20463 {}
20464
20465 /// Setter of the type of the variable.
20466 ///
20467 /// @param t the new variable type.
20468 void
20469 set_type(type_base_sptr t)
20470 {
20471 type_ = t;
20472 naked_type_ = t.get();
20473 }
20474}; // end struct var_decl::priv
20475
20476/// Constructor of the @ref var_decl type.
20477///
20478/// @param name the name of the variable declaration
20479///
20480/// @param type the type of the variable declaration
20481///
20482/// @param locus the source location where the variable was defined.
20483///
20484/// @param linkage_name the linkage name of the variable.
20485///
20486/// @param vis the visibility of of the variable.
20487///
20488/// @param bind the binding kind of the variable.
20489var_decl::var_decl(const string& name,
20490 type_base_sptr type,
20491 const location& locus,
20492 const string& linkage_name,
20493 visibility vis,
20494 binding bind)
20495 : type_or_decl_base(type->get_environment(),
20496 VAR_DECL | ABSTRACT_DECL_BASE),
20497 decl_base(type->get_environment(), name, locus, linkage_name, vis),
20498 priv_(new priv(type, bind))
20499{
20501}
20502
20503/// Getter of the type of the variable.
20504///
20505/// @return the type of the variable.
20506const type_base_sptr
20508{return priv_->type_.lock();}
20509
20510/// Setter of the type of the variable.
20511///
20512/// @param the new type of the variable.
20513void
20514var_decl::set_type(type_base_sptr& t)
20515{priv_->set_type(t);}
20516
20517/// Getter of the type of the variable.
20518///
20519/// This getter returns a bare pointer, as opposed to a smart pointer.
20520/// It's to be used on performance sensitive code paths identified by
20521/// careful profiling.
20522///
20523/// @return the type of the variable, as a bare pointer.
20524const type_base*
20526{return priv_->naked_type_;}
20527
20528/// Getter of the binding of the variable.
20529///
20530/// @return the biding of the variable.
20533{return priv_->binding_;}
20534
20535/// Setter of the binding of the variable.
20536///
20537/// @param b the new binding value.
20538void
20540{priv_->binding_ = b;}
20541
20542/// Sets the underlying ELF symbol for the current variable.
20543///
20544/// And underlyin$g ELF symbol for the current variable might exist
20545/// only if the corpus that this variable originates from was
20546/// constructed from an ELF binary file.
20547///
20548/// Note that comparing two variables that have underlying ELF symbols
20549/// involves comparing their underlying elf symbols. The decl name
20550/// for the variable thus becomes irrelevant in the comparison.
20551///
20552/// @param sym the new ELF symbol for this variable decl.
20553void
20555{
20556 priv_->symbol_ = sym;
20557 // The variable id cache that depends on the symbol must be
20558 // invalidated because the symbol changed.
20559 priv_->id_ = get_environment().intern("");
20560}
20561
20562/// Gets the the underlying ELF symbol for the current variable,
20563/// that was set using var_decl::set_symbol(). Please read the
20564/// documentation for that member function for more information about
20565/// "underlying ELF symbols".
20566///
20567/// @return sym the underlying ELF symbol for this variable decl, if
20568/// one exists.
20569const elf_symbol_sptr&
20571{return priv_->symbol_;}
20572
20573/// Create a new var_decl that is a clone of the current one.
20574///
20575/// @return the cloned var_decl.
20578{
20580 get_type(),
20581 get_location(),
20584 get_binding()));
20585
20586 v->set_symbol(get_symbol());
20587
20588 if (is_member_decl(*this))
20589 {
20593 get_member_is_static(*this),
20594 get_data_member_offset(*this));
20595 }
20596 else
20598
20599 return v;
20600}
20601/// Setter of the scope of the current var_decl.
20602///
20603/// Note that the decl won't hold a reference on the scope. It's
20604/// rather the scope that holds a reference on its members.
20605///
20606/// @param scope the new scope.
20607void
20608var_decl::set_scope(scope_decl* scope)
20609{
20610 if (!get_context_rel())
20611 set_context_rel(new dm_context_rel(scope));
20612 else
20613 get_context_rel()->set_scope(scope);
20614}
20615
20616/// Compares two instances of @ref var_decl without taking their type
20617/// into account.
20618///
20619/// If the two intances are different modulo their type, set a
20620/// bitfield to give some insight about the kind of differences there
20621/// are.
20622///
20623/// @param l the first artifact of the comparison.
20624///
20625/// @param r the second artifact of the comparison.
20626///
20627/// @param k a pointer to a bitfield that gives information about the
20628/// kind of changes there are between @p l and @p r. This one is set
20629/// iff @p k is non-null and the function returns false.
20630///
20631/// Please note that setting k to a non-null value does have a
20632/// negative performance impact because even if @p l and @p r are not
20633/// equal, the function keeps up the comparison in order to determine
20634/// the different kinds of ways in which they are different.
20635///
20636/// @return true if @p l equals @p r, false otherwise.
20637bool
20639{
20640 bool result = true;
20641
20642 // If there are underlying elf symbols for these variables,
20643 // compare them. And then compare the other parts.
20644 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
20645 if (!!s0 != !!s1)
20646 {
20647 result = false;
20648 if (k)
20650 else
20652 }
20653 else if (s0 && s0 != s1)
20654 {
20655 result = false;
20656 if (k)
20658 else
20660 }
20661 bool symbols_are_equal = (s0 && s1 && result);
20662
20663 if (symbols_are_equal)
20664 {
20665 // The variables have underlying elf symbols that are equal, so
20666 // now, let's compare the decl_base part of the variables w/o
20667 // considering their decl names.
20668 const environment& env = l.get_environment();
20669 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
20670 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
20671 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
20672 bool decl_bases_different = !l.decl_base::operator==(r);
20673 const_cast<var_decl&>(l).set_qualified_name(n1);
20674 const_cast<var_decl&>(r).set_qualified_name(n2);
20675
20676 if (decl_bases_different)
20677 {
20678 result = false;
20679 if (k)
20681 else
20683 }
20684 }
20685 else
20686 if (!l.decl_base::operator==(r))
20687 {
20688 result = false;
20689 if (k)
20691 else
20693 }
20694
20695 const dm_context_rel* c0 =
20696 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
20697 const dm_context_rel* c1 =
20698 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
20699 ABG_ASSERT(c0 && c1);
20700
20701 if (*c0 != *c1)
20702 {
20703 result = false;
20704 if (k)
20706 else
20708 }
20709
20710 ABG_RETURN(result);
20711}
20712
20713/// Compares two instances of @ref var_decl.
20714///
20715/// If the two intances are different, set a bitfield to give some
20716/// insight about the kind of differences there are.
20717///
20718/// @param l the first artifact of the comparison.
20719///
20720/// @param r the second artifact of the comparison.
20721///
20722/// @param k a pointer to a bitfield that gives information about the
20723/// kind of changes there are between @p l and @p r. This one is set
20724/// iff @p k is non-null and the function returns false.
20725///
20726/// Please note that setting k to a non-null value does have a
20727/// negative performance impact because even if @p l and @p r are not
20728/// equal, the function keeps up the comparison in order to determine
20729/// the different kinds of ways in which they are different.
20730///
20731/// @return true if @p l equals @p r, false otherwise.
20732bool
20733equals(const var_decl& l, const var_decl& r, change_kind* k)
20734{
20735 bool result = true;
20736
20737 // First test types of variables. This should be fast because in
20738 // the general case, most types should be canonicalized.
20739 if (*l.get_naked_type() != *r.get_naked_type())
20740 {
20741 result = false;
20742 if (k)
20743 {
20745 r.get_naked_type()))
20746 *k |= (LOCAL_TYPE_CHANGE_KIND);
20747 else
20748 *k |= SUBTYPE_CHANGE_KIND;
20749 }
20750 else
20752 }
20753
20754 result &= var_equals_modulo_types(l, r, k);
20755
20756 ABG_RETURN(result);
20757}
20758
20759/// Comparison operator of @ref var_decl.
20760///
20761/// @param o the instance of @ref var_decl to compare against.
20762///
20763/// @return true iff the current instance of @ref var_decl equals @p o.
20764bool
20766{
20767 const var_decl* other = dynamic_cast<const var_decl*>(&o);
20768 if (!other)
20769 return false;
20770
20771 return equals(*this, *other, 0);
20772}
20773
20774/// Return an ID that tries to uniquely identify the variable inside a
20775/// program or a library.
20776///
20777/// So if the variable has an underlying elf symbol, the ID is the
20778/// concatenation of the symbol name and its version. Otherwise, the
20779/// ID is the linkage name if its non-null. Otherwise, it's the
20780/// pretty representation of the variable.
20781///
20782/// @return the ID.
20785{
20786 if (priv_->id_.empty())
20787 {
20788 string repr = get_name();
20789 string sym_str;
20790 if (elf_symbol_sptr s = get_symbol())
20791 sym_str = s->get_id_string();
20792 else if (!get_linkage_name().empty())
20793 sym_str = get_linkage_name();
20794
20795 const environment& env = get_type()->get_environment();
20796 priv_->id_ = env.intern(repr);
20797 if (!sym_str.empty())
20798 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
20799 }
20800 return priv_->id_;
20801}
20802
20803/// Return the hash value for the current instance.
20804///
20805/// @return the hash value.
20806size_t
20808{
20809 var_decl::hash hash_var;
20810 return hash_var(this);
20811}
20812
20813/// Get the qualified name of a given variable or data member.
20814///
20815///
20816/// Note that if the current instance of @ref var_decl is an anonymous
20817/// data member, then the qualified name is actually the flat
20818/// representation (the definition) of the type of the anonymous data
20819/// member. We chose the flat representation because otherwise, the
20820/// name of an *anonymous* data member is empty, by construction, e.g:
20821///
20822/// struct foo {
20823/// int a;
20824/// union {
20825/// char b;
20826/// char c;
20827/// }; // <---- this data member is anonymous.
20828/// int d;
20829/// }
20830///
20831/// The string returned for the anonymous member here is going to be:
20832///
20833/// "union {char b; char c}"
20834///
20835/// @param internal if true then this is for a purpose to the library,
20836/// otherwise, it's for being displayed to users.
20837///
20838/// @return the resulting qualified name.
20839const interned_string&
20841{
20842 if (is_anonymous_data_member(this)
20843 && decl_base::get_qualified_name().empty())
20844 {
20845 // Display the anonymous data member in a way that makes sense.
20846 string r = get_pretty_representation(internal);
20848 }
20849
20850 return decl_base::get_qualified_name(internal);
20851}
20852
20853/// Build and return the pretty representation of this variable.
20854///
20855/// @param internal set to true if the call is intended to get a
20856/// representation of the decl (or type) for the purpose of canonical
20857/// type comparison. This is mainly used in the function
20858/// type_base::get_canonical_type_for().
20859///
20860/// In other words if the argument for this parameter is true then the
20861/// call is meant for internal use (for technical use inside the
20862/// library itself), false otherwise. If you don't know what this is
20863/// for, then set it to false.
20864///
20865/// @param qualified_name if true, names emitted in the pretty
20866/// representation are fully qualified.
20867///
20868/// @return a copy of the pretty representation of this variable.
20869string
20870var_decl::get_pretty_representation(bool internal, bool qualified_name) const
20871{
20872 string result;
20873
20874 if (is_member_decl(this) && get_member_is_static(this))
20875 result = "static ";
20876
20877 // Detect if the current instance of var_decl is a member of
20878 // an anonymous class or union.
20879 bool member_of_anonymous_class = false;
20880 if (class_or_union* scope = is_at_class_scope(this))
20881 if (scope->get_is_anonymous())
20882 member_of_anonymous_class = true;
20883
20884 type_base_sptr type = get_type();
20885 if (is_array_type(type, /*look_through_qualifiers=*/true)
20886 || is_pointer_type(type, /*look_through_qualifiers=*/true)
20887 || is_reference_type(type, /*look_through_qualifiers=*/true)
20888 || is_ptr_to_mbr_type(type, /*look_through_qualifiers=*/true))
20889 {
20890 string name;
20891 if (member_of_anonymous_class || !qualified_name)
20892 name = get_name();
20893 else
20894 name = get_qualified_name(internal);
20895
20896 if (qualified_type_def_sptr q = is_qualified_type(type))
20897 {
20898 string quals_repr =
20899 get_string_representation_of_cv_quals(q->get_cv_quals());
20900 if (!quals_repr.empty())
20901 name = quals_repr + " " + name;
20902 type = peel_qualified_type(type);
20903 }
20904
20905 name = string(" ") + name;
20906 if (array_type_def_sptr t = is_array_type(type))
20907 result += array_declaration_name(t, name, qualified_name, internal);
20908 else if (pointer_type_def_sptr t = is_pointer_type(type))
20909 result += pointer_declaration_name(t, name, qualified_name, internal);
20910 else if (reference_type_def_sptr t = is_reference_type(type))
20911 result += pointer_declaration_name(t, name, qualified_name, internal);
20912 else if (ptr_to_mbr_type_sptr t = is_ptr_to_mbr_type(type))
20913 result += ptr_to_mbr_declaration_name(t, name,
20914 qualified_name,
20915 internal);
20916 }
20917 else
20918 {
20919 if (/*The current var_decl is to be used as an anonymous data
20920 member. */
20921 get_name().empty())
20922 {
20923 // Display the anonymous data member in a way that
20924 // makes sense.
20925 result +=
20928 "", /*one_line=*/true, internal);
20929 }
20930 else if (data_member_has_anonymous_type(this))
20931 {
20934 "", /*one_line=*/true, internal);
20935 result += " ";
20936 if (!internal
20937 && (member_of_anonymous_class || !qualified_name))
20938 // It doesn't make sense to name the member of an
20939 // anonymous class or union like:
20940 // "__anonymous__::data_member_name". So let's just use
20941 // its non-qualified name.
20942 result += get_name();
20943 else
20944 result += get_qualified_name(internal);
20945 }
20946 else
20947 {
20948 result +=
20950 + " ";
20951
20952 if (!internal
20953 && (member_of_anonymous_class || !qualified_name))
20954 // It doesn't make sense to name the member of an
20955 // anonymous class or union like:
20956 // "__anonymous__::data_member_name". So let's just use
20957 // its non-qualified name.
20958 result += get_name();
20959 else
20960 result += get_qualified_name(internal);
20961 }
20962 }
20963 return result;
20964}
20965
20966/// Get a name that is valid even for an anonymous data member.
20967///
20968/// If the current @ref var_decl is an anonymous data member, then
20969/// return its pretty representation. As of now, that pretty
20970/// representation is actually its flat representation as returned by
20971/// get_class_or_union_flat_representation().
20972///
20973/// Otherwise, just return the name of the current @ref var_decl.
20974///
20975/// @param qualified if true, return the qualified name. This doesn't
20976/// have an effet if the current @ref var_decl represents an anonymous
20977/// data member.
20978string
20980{
20981 string name;
20982 if (is_anonymous_data_member(this))
20983 // This function is used in the comparison engine to determine
20984 // which anonymous data member was deleted. So it's not involved
20985 // in type comparison or canonicalization. We don't want to use
20986 // the 'internal' version of the pretty presentation.
20987 name = get_pretty_representation(/*internal=*/false, qualified);
20988 else
20989 name = get_name();
20990
20991 return name;
20992}
20993
20994/// This implements the ir_traversable_base::traverse pure virtual
20995/// function.
20996///
20997/// @param v the visitor used on the current instance.
20998///
20999/// @return true if the entire IR node tree got traversed, false
21000/// otherwise.
21001bool
21003{
21004 if (visiting())
21005 return true;
21006
21007 if (v.visit_begin(this))
21008 {
21009 visiting(true);
21010 if (type_base_sptr t = get_type())
21011 t->traverse(v);
21012 visiting(false);
21013 }
21014 return v.visit_end(this);
21015}
21016
21017var_decl::~var_decl()
21018{}
21019
21020// </var_decl definitions>
21021
21022/// This function is automatically invoked whenever an instance of
21023/// this type is canonicalized.
21024///
21025/// It's an overload of the virtual type_base::on_canonical_type_set.
21026///
21027/// We put here what is thus meant to be executed only at the point of
21028/// type canonicalization.
21029void
21031{
21032 priv_->cached_name_.clear();
21033 priv_->internal_cached_name_.clear();
21034}
21035
21036/// The most straightforward constructor for the function_type class.
21037///
21038/// @param return_type the return type of the function type.
21039///
21040/// @param parms the list of parameters of the function type.
21041/// Stricto sensu, we just need a list of types; we are using a list
21042/// of parameters (where each parameter also carries the name of the
21043/// parameter and its source location) to try and provide better
21044/// diagnostics whenever it makes sense. If it appears that this
21045/// wasts too many resources, we can fall back to taking just a
21046/// vector of types here.
21047///
21048/// @param size_in_bits the size of this type, in bits.
21049///
21050/// @param alignment_in_bits the alignment of this type, in bits.
21051///
21052/// @param size_in_bits the size of this type.
21053function_type::function_type(type_base_sptr return_type,
21054 const parameters& parms,
21055 size_t size_in_bits,
21056 size_t alignment_in_bits)
21057 : type_or_decl_base(return_type->get_environment(),
21058 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21059 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21060 priv_(new priv(parms, return_type))
21061{
21063
21064 for (parameters::size_type i = 0, j = 1;
21065 i < priv_->parms_.size();
21066 ++i, ++j)
21067 {
21068 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21069 // If the first parameter is artificial, then it certainly
21070 // means that this is a member function, and the first
21071 // parameter is the implicit this pointer. In that case, set
21072 // the index of that implicit parameter to zero. Otherwise,
21073 // the index of the first parameter starts at one.
21074 j = 0;
21075 priv_->parms_[i]->set_index(j);
21076 }
21077}
21078
21079/// A constructor for a function_type that takes no parameters.
21080///
21081/// @param return_type the return type of this function_type.
21082///
21083/// @param size_in_bits the size of this type, in bits.
21084///
21085/// @param alignment_in_bits the alignment of this type, in bits.
21086function_type::function_type(type_base_sptr return_type,
21087 size_t size_in_bits, size_t alignment_in_bits)
21088 : type_or_decl_base(return_type->get_environment(),
21089 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21090 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21091 priv_(new priv(return_type))
21092{
21094}
21095
21096/// A constructor for a function_type that takes no parameter and
21097/// that has no return_type yet. These missing parts can (and must)
21098/// be added later.
21099///
21100/// @param env the environment we are operating from.
21101///
21102/// @param size_in_bits the size of this type, in bits.
21103///
21104/// @param alignment_in_bits the alignment of this type, in bits.
21105function_type::function_type(const environment& env,
21106 size_t size_in_bits,
21107 size_t alignment_in_bits)
21108 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21109 type_base(env, size_in_bits, alignment_in_bits),
21110 priv_(new priv)
21111{
21113}
21114
21115/// Getter for the return type of the current instance of @ref
21116/// function_type.
21117///
21118/// @return the return type.
21119type_base_sptr
21121{return priv_->return_type_.lock();}
21122
21123/// Setter of the return type of the current instance of @ref
21124/// function_type.
21125///
21126/// @param t the new return type to set.
21127void
21129{priv_->return_type_ = t;}
21130
21131/// Getter for the set of parameters of the current intance of @ref
21132/// function_type.
21133///
21134/// @return the parameters of the current instance of @ref
21135/// function_type.
21138{return priv_->parms_;}
21139
21140/// Get the Ith parameter of the vector of parameters of the current
21141/// instance of @ref function_type.
21142///
21143/// Note that the first parameter is at index 0. That parameter is
21144/// the first parameter that comes after the possible implicit "this"
21145/// parameter, when the current instance @ref function_type is for a
21146/// member function. Otherwise, if the current instance of @ref
21147/// function_type is for a non-member function, the parameter at index
21148/// 0 is the first parameter of the function.
21149///
21150///
21151/// @param i the index of the parameter to return. If i is greater
21152/// than the index of the last parameter, then this function returns
21153/// an empty parameter (smart) pointer.
21154///
21155/// @return the @p i th parameter that is not implicit.
21158{
21159 parameter_sptr result;
21160 if (dynamic_cast<const method_type*>(this))
21161 {
21162 if (i + 1 < get_parameters().size())
21163 result = get_parameters()[i + 1];
21164 }
21165 else
21166 {
21167 if (i < get_parameters().size())
21168 result = get_parameters()[i];
21169 }
21170 return result;
21171}
21172
21173/// Setter for the parameters of the current instance of @ref
21174/// function_type.
21175///
21176/// @param p the new vector of parameters to set.
21177void
21179{
21180 priv_->parms_ = p;
21181 for (parameters::size_type i = 0, j = 1;
21182 i < priv_->parms_.size();
21183 ++i, ++j)
21184 {
21185 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21186 // If the first parameter is artificial, then it certainly
21187 // means that this is a member function, and the first
21188 // parameter is the implicit this pointer. In that case, set
21189 // the index of that implicit parameter to zero. Otherwise,
21190 // the index of the first parameter starts at one.
21191 j = 0;
21192 priv_->parms_[i]->set_index(j);
21193 }
21194}
21195
21196/// Append a new parameter to the vector of parameters of the current
21197/// instance of @ref function_type.
21198///
21199/// @param parm the parameter to append.
21200void
21202{
21203 parm->set_index(priv_->parms_.size());
21204 priv_->parms_.push_back(parm);
21205}
21206
21207/// Test if the current instance of @ref function_type is for a
21208/// variadic function.
21209///
21210/// A variadic function is a function that takes a variable number of
21211/// arguments.
21212///
21213/// @return true iff the current instance of @ref function_type is for
21214/// a variadic function.
21215bool
21217{
21218 return (!priv_->parms_.empty()
21219 && priv_->parms_.back()->get_variadic_marker());
21220}
21221
21222/// Compare two function types.
21223///
21224/// In case these function types are actually method types, this
21225/// function avoids comparing two parameters (of the function types)
21226/// if the types of the parameters are actually the types of the
21227/// classes of the method types. This prevents infinite recursion
21228/// during the comparison of two classes that are structurally
21229/// identical.
21230///
21231/// This is a subroutine of the equality operator of function_type.
21232///
21233/// @param lhs the first function type to consider
21234///
21235/// @param rhs the second function type to consider
21236///
21237/// @param k a pointer to a bitfield set by the function to give
21238/// information about the kind of changes carried by @p lhs and @p
21239/// rhs. It is set iff @p k is non-null and the function returns
21240/// false.
21241///
21242/// Please note that setting k to a non-null value does have a
21243/// negative performance impact because even if @p l and @p r are not
21244/// equal, the function keeps up the comparison in order to determine
21245/// the different kinds of ways in which they are different.
21246///
21247///@return true if lhs == rhs, false otherwise.
21248bool
21250{
21251#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
21252
21254
21255 {
21256 // First of all, let's see if these two function types haven't
21257 // already been compared. If so, and if the result of the
21258 // comparison has been cached, let's just re-use it, rather than
21259 // comparing them all over again.
21260 bool cached_result = false;
21261 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
21262 cached_result))
21263 ABG_RETURN(cached_result);
21264 }
21265
21267
21268 bool result = true;
21269
21270 if (!l.type_base::operator==(r))
21271 {
21272 result = false;
21273 if (k)
21275 else
21276 RETURN(result);
21277 }
21278
21279 class_or_union* l_class = 0, *r_class = 0;
21280 if (const method_type* m = dynamic_cast<const method_type*>(&l))
21281 l_class = m->get_class_type().get();
21282
21283 if (const method_type* m = dynamic_cast<const method_type*>(&r))
21284 r_class = m->get_class_type().get();
21285
21286 // Compare the names of the class of the method
21287
21288 if (!!l_class != !!r_class)
21289 {
21290 result = false;
21291 if (k)
21293 else
21294 RETURN(result);
21295 }
21296 else if (l_class
21297 && (l_class->get_qualified_name()
21298 != r_class->get_qualified_name()))
21299 {
21300 result = false;
21301 if (k)
21303 else
21304 RETURN(result);
21305 }
21306
21307 // Then compare the return type; Beware if it's t's a class type
21308 // that is the same as the method class name; we can recurse for
21309 // ever in that case.
21310
21311 decl_base* l_return_type_decl =
21313 decl_base* r_return_type_decl =
21315 bool compare_result_types = true;
21316 string l_rt_name = l_return_type_decl
21317 ? l_return_type_decl->get_qualified_name()
21318 : string();
21319 string r_rt_name = r_return_type_decl
21320 ? r_return_type_decl->get_qualified_name()
21321 : string();
21322
21323 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
21324 ||
21325 (r_class && (r_class->get_qualified_name() == r_rt_name)))
21326 compare_result_types = false;
21327
21328 if (compare_result_types)
21329 {
21330 // Let's not consider typedefs when comparing return types to
21331 // avoid spurious changes.
21332 //
21333 // TODO: We should also do this for parameter types, or rather,
21334 // we should teach the equality operators in the IR, at some
21335 // point, to peel typedefs off.
21337 !=
21339 {
21340 result = false;
21341 if (k)
21342 {
21344 r.get_return_type()))
21346 else
21347 *k |= SUBTYPE_CHANGE_KIND;
21348 }
21349 else
21350 RETURN(result);
21351 }
21352 }
21353 else
21354 if (l_rt_name != r_rt_name)
21355 {
21356 result = false;
21357 if (k)
21358 *k |= SUBTYPE_CHANGE_KIND;
21359 else
21360 RETURN(result);
21361 }
21362
21363 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
21364 for (i = l.get_first_parm(), j = r.get_first_parm();
21365 i != l.get_parameters().end() && j != r.get_parameters().end();
21366 ++i, ++j)
21367 {
21368 if (**i != **j)
21369 {
21370 result = false;
21371 if (k)
21372 {
21373 if (!types_have_similar_structure((*i)->get_type(),
21374 (*j)->get_type()))
21376 else
21377 *k |= SUBTYPE_CHANGE_KIND;
21378 }
21379 else
21380 RETURN(result);
21381 }
21382 }
21383
21384 if ((i != l.get_parameters().end()
21385 || j != r.get_parameters().end()))
21386 {
21387 result = false;
21388 if (k)
21390 else
21391 RETURN(result);
21392 }
21393
21394 RETURN(result);
21395#undef RETURN
21396}
21397
21398/// Get the first parameter of the function.
21399///
21400/// If the function is a non-static member function, the parameter
21401/// returned is the first one following the implicit 'this' parameter.
21402///
21403/// @return the first non implicit parameter of the function.
21404function_type::parameters::const_iterator
21406{
21407 if (get_parameters().empty())
21408 return get_parameters().end();
21409
21410 bool is_method = dynamic_cast<const method_type*>(this);
21411
21412 parameters::const_iterator i = get_parameters().begin();
21413
21414 if (is_method && (*i)->get_is_artificial())
21415 ++i;
21416
21417 return i;
21418}
21419
21420/// Get the first parameter of the function.
21421///
21422/// Note that if the function is a non-static member function, the
21423/// parameter returned is the implicit 'this' parameter.
21424///
21425/// @return the first parameter of the function.
21426function_type::parameters::const_iterator
21428{return get_parameters().begin();}
21429
21430/// Get the name of the current @ref function_type.
21431///
21432/// The name is retrieved from a cache. If the cache is empty, this
21433/// function computes the name of the type, stores it in the cache and
21434/// returns it. Subsequent invocation of the function are going to
21435/// just hit the cache.
21436///
21437/// Note that if the type is *NOT* canonicalized then function type
21438/// name is never cached.
21439///
21440/// @param internal if true then it means the function type name is
21441/// going to be used for purposes that are internal to libabigail
21442/// itself. If you don't know what this is then you probably should
21443/// set this parameter to 'false'.
21444///
21445/// @return the name of the function type.
21446const interned_string&
21448{
21449 if (internal)
21450 {
21452 {
21453 if (priv_->internal_cached_name_.empty())
21454 priv_->internal_cached_name_ =
21455 get_function_type_name(this, /*internal=*/true);
21456 return priv_->internal_cached_name_;
21457 }
21458 else
21459 {
21460 if (priv_->temp_internal_cached_name_.empty())
21461 priv_->temp_internal_cached_name_ =
21462 get_function_type_name(this, /*internal=*/true);
21463 return priv_->temp_internal_cached_name_;
21464 }
21465 }
21466 else
21467 {
21469 {
21470 if (priv_->cached_name_.empty())
21471 priv_->cached_name_ =
21472 get_function_type_name(this, /*internal=*/false);
21473 return priv_->cached_name_;
21474 }
21475 else
21476 {
21477 priv_->cached_name_ =
21478 get_function_type_name(this, /*internal=*/false);
21479 return priv_->cached_name_;
21480 }
21481 }
21482}
21483
21484/// Equality operator for function_type.
21485///
21486/// @param o the other function_type to compare against.
21487///
21488/// @return true iff the two function_type are equal.
21489bool
21491{
21492 const function_type* o = dynamic_cast<const function_type*>(&other);
21493 if (!o)
21494 return false;
21495 return try_canonical_compare(this, o);
21496}
21497
21498/// Return a copy of the pretty representation of the current @ref
21499/// function_type.
21500///
21501/// @param internal set to true if the call is intended to get a
21502/// representation of the decl (or type) for the purpose of canonical
21503/// type comparison. This is mainly used in the function
21504/// type_base::get_canonical_type_for().
21505///
21506/// In other words if the argument for this parameter is true then the
21507/// call is meant for internal use (for technical use inside the
21508/// library itself), false otherwise. If you don't know what this is
21509/// for, then set it to false.
21510///
21511/// @return a copy of the pretty representation of the current @ref
21512/// function_type.
21513string
21515 bool /*qualified_name*/) const
21516{return ir::get_pretty_representation(this, internal);}
21517
21518/// Traverses an instance of @ref function_type, visiting all the
21519/// sub-types and decls that it might contain.
21520///
21521/// @param v the visitor that is used to visit every IR sub-node of
21522/// the current node.
21523///
21524/// @return true if either
21525/// - all the children nodes of the current IR node were traversed
21526/// and the calling code should keep going with the traversing.
21527/// - or the current IR node is already being traversed.
21528/// Otherwise, returning false means that the calling code should not
21529/// keep traversing the tree.
21530bool
21532{
21533 // TODO: should we allow the walker to avoid visiting function type
21534 // twice? I think that if we do, then ir_node_visitor needs an
21535 // option to specifically disallow this feature for function types.
21536
21537 if (visiting())
21538 return true;
21539
21540 if (v.visit_begin(this))
21541 {
21542 visiting(true);
21543 bool keep_going = true;
21544
21545 if (type_base_sptr t = get_return_type())
21546 {
21547 if (!t->traverse(v))
21548 keep_going = false;
21549 }
21550
21551 if (keep_going)
21552 for (parameters::const_iterator i = get_parameters().begin();
21553 i != get_parameters().end();
21554 ++i)
21555 if (type_base_sptr parm_type = (*i)->get_type())
21556 if (!parm_type->traverse(v))
21557 break;
21558
21559 visiting(false);
21560 }
21561 return v.visit_end(this);
21562}
21563
21564function_type::~function_type()
21565{}
21566// </function_type>
21567
21568// <method_type>
21569
21570struct method_type::priv
21571{
21572 class_or_union_wptr class_type_;
21573 bool is_const;
21574
21575 priv()
21576 : is_const()
21577 {}
21578}; // end struct method_type::priv
21579
21580/// Constructor for instances of method_type.
21581///
21582/// Instances of method_decl must be of type method_type.
21583///
21584/// @param return_type the type of the return value of the method.
21585///
21586/// @param class_type the base type of the method type. That is, the
21587/// type of the class the method belongs to.
21588///
21589/// @param p the vector of the parameters of the method.
21590///
21591/// @param is_const whether this method type is for a const method.
21592/// Note that const-ness is a property of the method *type* and of the
21593/// relationship between a method *declaration* and its scope.
21594///
21595/// @param size_in_bits the size of an instance of method_type,
21596/// expressed in bits.
21597///
21598/// @param alignment_in_bits the alignment of an instance of
21599/// method_type, expressed in bits.
21600method_type::method_type (type_base_sptr return_type,
21601 class_or_union_sptr class_type,
21602 const std::vector<function_decl::parameter_sptr>& p,
21603 bool is_const,
21604 size_t size_in_bits,
21605 size_t alignment_in_bits)
21606 : type_or_decl_base(class_type->get_environment(),
21607 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21608 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21609 function_type(return_type, p, size_in_bits, alignment_in_bits),
21610 priv_(new priv)
21611{
21613 set_class_type(class_type);
21614 set_is_const(is_const);
21615}
21616
21617/// Constructor of instances of method_type.
21618///
21619///Instances of method_decl must be of type method_type.
21620///
21621/// @param return_type the type of the return value of the method.
21622///
21623/// @param class_type the type of the class the method belongs to.
21624/// The actual (dynamic) type of class_type must be a pointer
21625/// class_type. We are setting it to pointer to type_base here to
21626/// help client code that is compiled without rtti and thus cannot
21627/// perform dynamic casts.
21628///
21629/// @param p the vector of the parameters of the method type.
21630///
21631/// @param is_const whether this method type is for a const method.
21632/// Note that const-ness is a property of the method *type* and of the
21633/// relationship between a method *declaration* and its scope.
21634///
21635/// @param size_in_bits the size of an instance of method_type,
21636/// expressed in bits.
21637///
21638/// @param alignment_in_bits the alignment of an instance of
21639/// method_type, expressed in bits.
21640method_type::method_type(type_base_sptr return_type,
21641 type_base_sptr class_type,
21642 const std::vector<function_decl::parameter_sptr>& p,
21643 bool is_const,
21644 size_t size_in_bits,
21645 size_t alignment_in_bits)
21646 : type_or_decl_base(class_type->get_environment(),
21647 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21648 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21649 function_type(return_type, p, size_in_bits, alignment_in_bits),
21650 priv_(new priv)
21651{
21653 set_class_type(is_class_type(class_type));
21654 set_is_const(is_const);
21655}
21656
21657/// Constructor of the qualified_type_def
21658///
21659/// @param env the environment we are operating from.
21660///
21661/// @param size_in_bits the size of the type, expressed in bits.
21662///
21663/// @param alignment_in_bits the alignment of the type, expressed in bits
21664method_type::method_type(const environment& env,
21665 size_t size_in_bits,
21666 size_t alignment_in_bits)
21667 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21668 type_base(env, size_in_bits, alignment_in_bits),
21669 function_type(env, size_in_bits, alignment_in_bits),
21670 priv_(new priv)
21671{
21673}
21674
21675/// Constructor of instances of method_type.
21676///
21677/// When constructed with this constructor, and instane of method_type
21678/// must set a return type using method_type::set_return_type
21679///
21680/// @param class_typ the base type of the method type. That is, the
21681/// type of the class (or union) the method belongs to.
21682///
21683/// @param size_in_bits the size of an instance of method_type,
21684/// expressed in bits.
21685///
21686/// @param alignment_in_bits the alignment of an instance of
21687/// method_type, expressed in bits.
21688method_type::method_type(class_or_union_sptr class_type,
21689 bool is_const,
21690 size_t size_in_bits,
21691 size_t alignment_in_bits)
21692 : type_or_decl_base(class_type->get_environment(),
21693 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21694 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21695 function_type(class_type->get_environment(),
21696 size_in_bits,
21697 alignment_in_bits),
21698 priv_(new priv)
21699{
21701 set_class_type(class_type);
21702 set_is_const(is_const);
21703}
21704
21705/// Get the class type this method belongs to.
21706///
21707/// @return the class type.
21708class_or_union_sptr
21710{return class_or_union_sptr(priv_->class_type_);}
21711
21712/// Sets the class type of the current instance of method_type.
21713///
21714/// The class type is the type of the class the method belongs to.
21715///
21716/// @param t the new class type to set.
21717void
21718method_type::set_class_type(const class_or_union_sptr& t)
21719{
21720 if (!t)
21721 return;
21722
21723 priv_->class_type_ = t;
21724}
21725
21726/// Return a copy of the pretty representation of the current @ref
21727/// method_type.
21728///
21729/// @param internal set to true if the call is intended to get a
21730/// representation of the decl (or type) for the purpose of canonical
21731/// type comparison. This is mainly used in the function
21732/// type_base::get_canonical_type_for().
21733///
21734/// In other words if the argument for this parameter is true then the
21735/// call is meant for internal use (for technical use inside the
21736/// library itself), false otherwise. If you don't know what this is
21737/// for, then set it to false.
21738///
21739/// @return a copy of the pretty representation of the current @ref
21740/// method_type.
21741string
21743 bool /*qualified_name*/) const
21744{return ir::get_pretty_representation(*this, internal);}
21745
21746/// Setter of the "is-const" property of @ref method_type.
21747///
21748/// @param the new value of the "is-const" property.
21749void
21751{priv_->is_const = f;}
21752
21753/// Getter of the "is-const" property of @ref method_type.
21754///
21755/// @return true iff the "is-const" property was set.
21756bool
21758{return priv_->is_const;}
21759
21760/// Test if the current method type is for a static method or not.
21761///
21762/// @return true iff the current method_type denotes a the type of a
21763/// static method.
21764bool
21766{
21767 // Let's see if the first parameter is artificial and is a pointer
21768 // to an instance of the same class type as the current class.
21770 if (!get_parameters().empty())
21771 first_parm = get_parameters()[0];
21772 if (!first_parm)
21773 return true;
21774 if (!first_parm->get_is_artificial())
21775 return true;
21776
21777 type_base_sptr this_ptr_type = first_parm->get_type();
21778 // Sometimes, the type of the "this" pointer is "const class_type*
21779 // const". Meaning that the "this pointer" itself is const
21780 // qualified. So let's get the underlying non-qualified pointer.
21781 this_ptr_type = peel_qualified_type(this_ptr_type);
21782 if (!is_pointer_type(this_ptr_type))
21783 return true;
21784
21785 type_base_sptr candidate_class_type =
21786 is_pointer_type(this_ptr_type)->get_pointed_to_type();
21787 candidate_class_type = peel_qualified_type(candidate_class_type);
21788 if (is_class_type(candidate_class_type)
21789 && get_type_name(candidate_class_type) == get_type_name(get_class_type()))
21790 // At this point, we are sure we are looking at a *non-static*
21791 // method.
21792 return false;
21793
21794 return true;
21795}
21796
21797/// The destructor of method_type
21799{}
21800
21801// </method_type>
21802
21803// <function_decl definitions>
21804
21805struct function_decl::priv
21806{
21807 bool declared_inline_;
21808 decl_base::binding binding_;
21809 function_type_wptr type_;
21810 function_type* naked_type_;
21811 elf_symbol_sptr symbol_;
21812 interned_string id_;
21813
21814 priv()
21815 : declared_inline_(false),
21816 binding_(decl_base::BINDING_GLOBAL),
21817 naked_type_()
21818 {}
21819
21820 priv(function_type_sptr t,
21821 bool declared_inline,
21823 : declared_inline_(declared_inline),
21824 binding_(binding),
21825 type_(t),
21826 naked_type_(t.get())
21827 {}
21828
21829 priv(function_type_sptr t,
21830 bool declared_inline,
21833 : declared_inline_(declared_inline),
21834 binding_(binding),
21835 type_(t),
21836 naked_type_(t.get()),
21837 symbol_(s)
21838 {}
21839}; // end sruct function_decl::priv
21840
21841/// Constructor of the @ref function_decl.
21842///
21843/// @param name the name of the function.
21844///
21845/// @param function_type the type of the function.
21846///
21847/// @param declared_inline wether the function is declared inline.
21848///
21849/// @param locus the source location of the function.
21850///
21851/// @param mangled_name the linkage name of the function.
21852///
21853/// @param vis the visibility of the function.
21854///
21855/// @param bind the binding of the function.
21858 bool declared_inline,
21859 const location& locus,
21860 const string& mangled_name,
21861 visibility vis,
21862 binding bind)
21863 : type_or_decl_base(function_type->get_environment(),
21864 FUNCTION_DECL | ABSTRACT_DECL_BASE),
21865 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
21866 priv_(new priv(function_type, declared_inline, bind))
21867{
21869}
21870
21871/// Constructor of the function_decl type.
21872///
21873/// This flavour of constructor is for when the pointer to the
21874/// instance of function_type that the client code has is presented as
21875/// a pointer to type_base. In that case, this constructor saves the
21876/// client code from doing a dynamic_cast to get the function_type
21877/// pointer.
21878///
21879/// @param name the name of the function declaration.
21880///
21881/// @param fn_type the type of the function declaration. The dynamic
21882/// type of this parameter should be 'pointer to function_type'
21883///
21884/// @param declared_inline whether this function was declared inline
21885///
21886/// @param locus the source location of the function declaration.
21887///
21888/// @param linkage_name the mangled name of the function declaration.
21889///
21890/// @param vis the visibility of the function declaration.
21891///
21892/// @param bind the kind of the binding of the function
21893/// declaration.
21895 type_base_sptr fn_type,
21896 bool declared_inline,
21897 const location& locus,
21898 const string& linkage_name,
21899 visibility vis,
21900 binding bind)
21901 : type_or_decl_base(fn_type->get_environment(),
21902 FUNCTION_DECL | ABSTRACT_DECL_BASE),
21903 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
21904 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
21905 declared_inline,
21906 bind))
21907{
21909}
21910
21911/// Get the pretty representation of the current instance of @ref function_decl.
21912///
21913/// @param internal set to true if the call is intended to get a
21914/// representation of the decl (or type) for the purpose of canonical
21915/// type comparison. This is mainly used in the function
21916/// type_base::get_canonical_type_for().
21917///
21918/// In other words if the argument for this parameter is true then the
21919/// call is meant for internal use (for technical use inside the
21920/// library itself), false otherwise. If you don't know what this is
21921/// for, then set it to false.
21922///
21923/// @return the pretty representation for a function.
21924string
21926 bool qualified_name) const
21927{
21928 const method_decl* mem_fn =
21929 dynamic_cast<const method_decl*>(this);
21930
21931 string fn_prefix = mem_fn ? "method ": "function ";
21932 string result;
21933
21934 if (mem_fn
21935 && is_member_function(mem_fn)
21937 fn_prefix += "virtual ";
21938
21939 decl_base_sptr return_type;
21940 if ((mem_fn
21941 && is_member_function(mem_fn)
21942 && (get_member_function_is_dtor(*mem_fn)
21943 || get_member_function_is_ctor(*mem_fn))))
21944 /*cdtors do not have return types. */;
21945 else
21946 return_type = mem_fn
21947 ? get_type_declaration(mem_fn->get_type()->get_return_type())
21949
21950 result = get_pretty_representation_of_declarator(internal);
21951 if (return_type)
21952 {
21953 if (is_npaf_type(is_type(return_type))
21954 || !(is_pointer_to_function_type(is_type(return_type))
21955 || is_pointer_to_array_type(is_type(return_type))))
21956 result = get_type_name(is_type(return_type).get(), qualified_name,
21957 internal) + " " + result;
21958 else if (pointer_type_def_sptr p =
21960 result = add_outer_pointer_to_fn_type_expr(p, result,
21961 /*qualified=*/true,
21962 internal);
21963 else if(pointer_type_def_sptr p =
21964 is_pointer_to_array_type(is_type(return_type)))
21965 result = add_outer_pointer_to_array_type_expr(p, result,
21966 qualified_name,
21967 internal);
21968 else
21970 }
21971
21972 return fn_prefix + result;
21973}
21974
21975/// Compute and return the pretty representation for the part of the
21976/// function declaration that starts at the declarator. That is, the
21977/// return type and the other specifiers of the beginning of the
21978/// function's declaration ar omitted.
21979///
21980/// @param internal set to true if the call is intended to get a
21981/// representation of the decl (or type) for the purpose of canonical
21982/// type comparison. This is mainly used in the function
21983/// type_base::get_canonical_type_for().
21984///
21985/// In other words if the argument for this parameter is true then the
21986/// call is meant for internal use (for technical use inside the
21987/// library itself), false otherwise. If you don't know what this is
21988/// for, then set it to false.
21989///
21990/// @return the pretty representation for the part of the function
21991/// declaration that starts at the declarator.
21992string
21994{
21995 const method_decl* mem_fn =
21996 dynamic_cast<const method_decl*>(this);
21997
21998 string result;
21999
22000 if (mem_fn)
22001 {
22002 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
22003 + "::" + mem_fn->get_name();
22004 }
22005 else
22006 result += get_qualified_name();
22007
22008 std::ostringstream fn_parms;
22009 stream_pretty_representation_of_fn_parms(*get_type(),
22010 fn_parms,
22011 /*qualified=*/true,
22012 internal);
22013 result += fn_parms.str();
22014
22015 if (mem_fn
22016 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
22017 || is_method_type(mem_fn->get_type())->get_is_const()))
22018 result += " const";
22019
22020 return result;
22021}
22022
22023/// Getter for the first non-implicit parameter of a function decl.
22024///
22025/// If the function is a non-static member function, the parameter
22026/// returned is the first one following the implicit 'this' parameter.
22027///
22028/// @return the first non implicit parm.
22029function_decl::parameters::const_iterator
22031{
22032 if (get_parameters().empty())
22033 return get_parameters().end();
22034
22035 bool is_method = dynamic_cast<const method_decl*>(this);
22036
22037 parameters::const_iterator i = get_parameters().begin();
22038 if (is_method)
22039 ++i;
22040
22041 return i;
22042}
22043
22044/// Return the type of the current instance of @ref function_decl.
22045///
22046/// It's either a function_type or method_type.
22047/// @return the type of the current instance of @ref function_decl.
22048const shared_ptr<function_type>
22050{return priv_->type_.lock();}
22051
22052/// Fast getter of the type of the current instance of @ref function_decl.
22053///
22054/// Note that this function returns the underlying pointer managed by
22055/// the smart pointer returned by function_decl::get_type(). It's
22056/// faster than function_decl::get_type(). This getter is to be used
22057/// in code paths that are proven to be performance hot spots;
22058/// especially (for instance) when comparing function types. Those
22059/// are compared extremely frequently when libabigail is used to
22060/// handle huge binaries with a lot of functions.
22061///
22062/// @return the type of the current instance of @ref function_decl.
22063const function_type*
22065{return priv_->naked_type_;}
22066
22067void
22068function_decl::set_type(const function_type_sptr& fn_type)
22069{
22070 priv_->type_ = fn_type;
22071 priv_->naked_type_ = fn_type.get();
22072}
22073
22074/// This sets the underlying ELF symbol for the current function decl.
22075///
22076/// And underlyin$g ELF symbol for the current function decl might
22077/// exist only if the corpus that this function decl originates from
22078/// was constructed from an ELF binary file.
22079///
22080/// Note that comparing two function decls that have underlying ELF
22081/// symbols involves comparing their underlying elf symbols. The decl
22082/// name for the function thus becomes irrelevant in the comparison.
22083///
22084/// @param sym the new ELF symbol for this function decl.
22085void
22087{
22088 priv_->symbol_ = sym;
22089 // The function id cache that depends on the symbol must be
22090 // invalidated because the symbol changed.
22091 priv_->id_ = get_environment().intern("");
22092}
22093
22094/// Gets the the underlying ELF symbol for the current variable,
22095/// that was set using function_decl::set_symbol(). Please read the
22096/// documentation for that member function for more information about
22097/// "underlying ELF symbols".
22098///
22099/// @return sym the underlying ELF symbol for this function decl, if
22100/// one exists.
22101const elf_symbol_sptr&
22103{return priv_->symbol_;}
22104
22105/// Test if the function was declared inline.
22106///
22107/// @return true iff the function was declared inline.
22108bool
22110{return priv_->declared_inline_;}
22111
22112/// Set the property of the function being declared inline.
22113///
22114/// @param value true iff the function was declared inline.
22115void
22117{priv_->declared_inline_ = value;}
22118
22120function_decl::get_binding() const
22121{return priv_->binding_;}
22122
22123/// @return the return type of the current instance of function_decl.
22124const shared_ptr<type_base>
22126{return get_type()->get_return_type();}
22127
22128/// @return the parameters of the function.
22129const std::vector<shared_ptr<function_decl::parameter> >&
22131{return get_type()->get_parameters();}
22132
22133/// Append a parameter to the type of this function.
22134///
22135/// @param parm the parameter to append.
22136void
22137function_decl::append_parameter(shared_ptr<parameter> parm)
22138{get_type()->append_parameter(parm);}
22139
22140/// Append a vector of parameters to the type of this function.
22141///
22142/// @param parms the vector of parameters to append.
22143void
22144function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
22145{
22146 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
22147 i != parms.end();
22148 ++i)
22149 get_type()->append_parameter(*i);
22150}
22151
22152/// Create a new instance of function_decl that is a clone of the
22153/// current one.
22154///
22155/// @return the new clone.
22158{
22160 if (is_member_function(*this))
22161 {
22162 method_decl_sptr
22163 m(new method_decl(get_name(),
22164 get_type(),
22166 get_location(),
22169 get_binding()));
22171 ABG_ASSERT(scope);
22175 get_member_is_static(*this),
22179 f = m;
22180 }
22181 else
22182 {
22183 f.reset(new function_decl(get_name(),
22184 get_type(),
22186 get_location(),
22189 get_binding()));
22191 }
22192 f->set_symbol(get_symbol());
22193
22194 return f;
22195}
22196
22197/// Compares two instances of @ref function_decl.
22198///
22199/// If the two intances are different, set a bitfield to give some
22200/// insight about the kind of differences there are.
22201///
22202/// @param l the first artifact of the comparison.
22203///
22204/// @param r the second artifact of the comparison.
22205///
22206/// @param k a pointer to a bitfield that gives information about the
22207/// kind of changes there are between @p l and @p r. This one is set
22208/// iff @p k is non-null and the function returns false.
22209///
22210/// Please note that setting k to a non-null value does have a
22211/// negative performance impact because even if @p l and @p r are not
22212/// equal, the function keeps up the comparison in order to determine
22213/// the different kinds of ways in which they are different.
22214///
22215/// @return true if @p l equals @p r, false otherwise.
22216bool
22218{
22219 bool result = true;
22220
22221 // Compare function types
22222 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
22223 if (t0 == t1 || *t0 == *t1)
22224 ; // the types are equal, let's move on to compare the other
22225 // properties of the functions.
22226 else
22227 {
22228 result = false;
22229 if (k)
22230 {
22231 if (!types_have_similar_structure(t0, t1))
22233 else
22234 *k |= SUBTYPE_CHANGE_KIND;
22235 }
22236 else
22238 }
22239
22240 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
22241 if (!!s0 != !!s1)
22242 {
22243 result = false;
22244 if (k)
22246 else
22248 }
22249 else if (s0 && s0 != s1)
22250 {
22251 if (!elf_symbols_alias(s0, s1))
22252 {
22253 result = false;
22254 if (k)
22256 else
22258 }
22259 }
22260 bool symbols_are_equal = (s0 && s1 && result);
22261
22262 if (symbols_are_equal)
22263 {
22264 // The functions have underlying elf symbols that are equal,
22265 // so now, let's compare the decl_base part of the functions
22266 // w/o considering their decl names.
22267 interned_string n1 = l.get_name(), n2 = r.get_name();
22269 const_cast<function_decl&>(l).set_name("");
22270 const_cast<function_decl&>(l).set_linkage_name("");
22271 const_cast<function_decl&>(r).set_name("");
22272 const_cast<function_decl&>(r).set_linkage_name("");
22273
22274 bool decl_bases_different = !l.decl_base::operator==(r);
22275
22276 const_cast<function_decl&>(l).set_name(n1);
22277 const_cast<function_decl&>(l).set_linkage_name(ln1);
22278 const_cast<function_decl&>(r).set_name(n2);
22279 const_cast<function_decl&>(r).set_linkage_name(ln2);
22280
22281 if (decl_bases_different)
22282 {
22283 result = false;
22284 if (k)
22286 else
22288 }
22289 }
22290 else
22291 if (!l.decl_base::operator==(r))
22292 {
22293 result = false;
22294 if (k)
22296 else
22298 }
22299
22300 // Compare the remaining properties. Note that we don't take into
22301 // account the fact that the function was declared inline or not as
22302 // that doesn't have any impact on the final ABI.
22303 if (l.get_binding() != r.get_binding())
22304 {
22305 result = false;
22306 if (k)
22308 else
22310 }
22311
22313 {
22314 result = false;
22315 if (k)
22317 else
22319 }
22320
22322 {
22335 {
22336 result = false;
22337 if (k)
22339 else
22341 }
22342 }
22343
22344 ABG_RETURN(result);
22345}
22346
22347/// Comparison operator for @ref function_decl.
22348///
22349/// @param other the other instance of @ref function_decl to compare
22350/// against.
22351///
22352/// @return true iff the current instance of @ref function_decl equals
22353/// @p other.
22354bool
22356{
22357 const function_decl* o = dynamic_cast<const function_decl*>(&other);
22358 if (!o)
22359 return false;
22360 return equals(*this, *o, 0);
22361}
22362
22363/// Return true iff the function takes a variable number of
22364/// parameters.
22365///
22366/// @return true if the function taks a variable number
22367/// of parameters.
22368bool
22370{
22371 return (!get_parameters().empty()
22372 && get_parameters().back()->get_variadic_marker());
22373}
22374
22375/// The virtual implementation of 'get_hash' for a function_decl.
22376///
22377/// This allows decl_base::get_hash to work for function_decls.
22378///
22379/// @return the hash value for function decl.
22380size_t
22382{
22383 function_decl::hash hash_fn;
22384 return hash_fn(*this);
22385}
22386
22387/// Return an ID that tries to uniquely identify the function inside a
22388/// program or a library.
22389///
22390/// So if the function has an underlying elf symbol, the ID is the
22391/// concatenation of the symbol name and its version. Otherwise, the
22392/// ID is the linkage name if its non-null. Otherwise, it's the
22393/// pretty representation of the function.
22394///
22395/// @return the ID.
22398{
22399 if (priv_->id_.empty())
22400 {
22401 const environment& env = get_type()->get_environment();
22402 if (elf_symbol_sptr s = get_symbol())
22403 {
22404 string virtual_member_suffix;
22405 if (is_member_function(this))
22406 {
22407 method_decl* m = is_method_decl(this);
22408 ABG_ASSERT(m);
22410 {
22412 (m->get_type()->get_class_type(),
22413 /*look_through_decl_only=*/true))
22414 virtual_member_suffix += "/o";
22415 }
22416 }
22417 if (s->has_aliases())
22418 // The symbol has several aliases, so let's use a scheme
22419 // that allows all aliased functions to have different
22420 // IDs.
22421 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
22422 else
22423 // Let's use the full symbol name with its version as ID.
22424 priv_->id_ = env.intern(s->get_id_string());
22425
22426 if (!virtual_member_suffix.empty())
22427 priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
22428 }
22429 else if (!get_linkage_name().empty())
22430 priv_->id_= env.intern(get_linkage_name());
22431 else
22432 priv_->id_ = env.intern(get_pretty_representation());
22433 }
22434 return priv_->id_;
22435}
22436
22437/// Test if two function declarations are aliases.
22438///
22439/// Two functions declarations are aliases if their symbols are
22440/// aliases, in the ELF sense.
22441///
22442/// @param f1 the first function to consider.
22443///
22444/// @param f2 the second function to consider.
22445///
22446/// @return true iff @p f1 is an alias of @p f2
22447bool
22449{
22450 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
22451
22452 if (!s1 || !s2)
22453 return false;
22454
22455 return elf_symbols_alias(s1, s2);
22456}
22457
22458/// This implements the ir_traversable_base::traverse pure virtual
22459/// function.
22460///
22461/// @param v the visitor used on the current instance.
22462///
22463/// @return true if the entire IR node tree got traversed, false
22464/// otherwise.
22465bool
22467{
22468 if (visiting())
22469 return true;
22470
22471 if (v.visit_begin(this))
22472 {
22473 visiting(true);
22474 if (type_base_sptr t = get_type())
22475 t->traverse(v);
22476 visiting(false);
22477 }
22478 return v.visit_end(this);
22479}
22480
22481/// Destructor of the @ref function_decl type.
22483{delete priv_;}
22484
22485/// A deep comparison operator for a shared pointer to @ref function_decl
22486///
22487/// This function compares to shared pointers to @ref function_decl by
22488/// looking at the pointed-to instances of @ref function_dec
22489/// comparing them too. If the two pointed-to objects are equal then
22490/// this function returns true.
22491///
22492/// @param l the left-hand side argument of the equality operator.
22493///
22494/// @param r the right-hand side argument of the equality operator.
22495///
22496/// @return true iff @p l equals @p r.
22497bool
22499{
22500 if (l.get() == r.get())
22501 return true;
22502 if (!!l != !!r)
22503 return false;
22504
22505 return *l == *r;
22506}
22507
22508/// A deep inequality operator for smart pointers to functions.
22509///
22510/// @param l the left-hand side argument of the inequality operator.
22511///
22512/// @pram r the right-hand side argument of the inequality operator.
22513///
22514/// @return true iff @p is not equal to @p r.
22515bool
22517{return !operator==(l, r);}
22518
22519// <function_decl definitions>
22520
22521// <function_decl::parameter definitions>
22522
22523struct function_decl::parameter::priv
22524{
22525 type_base_wptr type_;
22526 unsigned index_;
22527 bool variadic_marker_;
22528
22529 priv()
22530 : index_(),
22531 variadic_marker_()
22532 {}
22533
22534 priv(type_base_sptr type,
22535 unsigned index,
22536 bool variadic_marker)
22537 : type_(type),
22538 index_(index),
22539 variadic_marker_(variadic_marker)
22540 {}
22541};// end struct function_decl::parameter::priv
22542
22543function_decl::parameter::parameter(const type_base_sptr type,
22544 unsigned index,
22545 const string& name,
22546 const location& loc,
22547 bool is_variadic)
22548 : type_or_decl_base(type->get_environment(),
22549 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22550 decl_base(type->get_environment(), name, loc),
22551 priv_(new priv(type, index, is_variadic))
22552{
22553 runtime_type_instance(this);
22554}
22555
22556function_decl::parameter::parameter(const type_base_sptr type,
22557 unsigned index,
22558 const string& name,
22559 const location& loc,
22560 bool is_variadic,
22561 bool is_artificial)
22562 : type_or_decl_base(type->get_environment(),
22563 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22564 decl_base(type->get_environment(), name, loc),
22565 priv_(new priv(type, index, is_variadic))
22566{
22567 runtime_type_instance(this);
22568 set_is_artificial(is_artificial);
22569}
22570
22571function_decl::parameter::parameter(const type_base_sptr type,
22572 const string& name,
22573 const location& loc,
22574 bool is_variadic,
22575 bool is_artificial)
22576 : type_or_decl_base(type->get_environment(),
22577 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22578 decl_base(type->get_environment(), name, loc),
22579 priv_(new priv(type, 0, is_variadic))
22580{
22581 runtime_type_instance(this);
22582 set_is_artificial(is_artificial);
22583}
22584
22585function_decl::parameter::parameter(const type_base_sptr type,
22586 unsigned index,
22587 bool variad)
22588 : type_or_decl_base(type->get_environment(),
22589 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22590 decl_base(type->get_environment(), "", location()),
22591 priv_(new priv(type, index, variad))
22592{
22593 runtime_type_instance(this);
22594}
22595
22596function_decl::parameter::~parameter() = default;
22597
22598const type_base_sptr
22599function_decl::parameter::get_type()const
22600{return priv_->type_.lock();}
22601
22602/// @return a copy of the type name of the parameter.
22603interned_string
22605{
22606 const environment& env = get_environment();
22607
22608 type_base_sptr t = get_type();
22609 string str;
22610 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
22611 str = "...";
22612 else
22613 {
22614 ABG_ASSERT(t);
22616 }
22617 return env.intern(str);
22618}
22619
22620/// @return a copy of the pretty representation of the type of the
22621/// parameter.
22622const string
22624{
22625 type_base_sptr t = get_type();
22626 string str;
22627 if (get_variadic_marker()
22628 || get_environment().is_variadic_parameter_type(t))
22629 str = "...";
22630 else
22631 {
22632 ABG_ASSERT(t);
22634 }
22635 return str;
22636}
22637
22638/// Get a name uniquely identifying the parameter in the function.
22639///
22640///@return the unique parm name id.
22643{
22644 const environment& env = get_environment();
22645
22646
22647 std::ostringstream o;
22648 o << "parameter-" << get_index();
22649
22650 return env.intern(o.str());
22651}
22652
22653unsigned
22654function_decl::parameter::get_index() const
22655{return priv_->index_;}
22656
22657void
22658function_decl::parameter::set_index(unsigned i)
22659{priv_->index_ = i;}
22660
22661
22662bool
22663function_decl::parameter::get_variadic_marker() const
22664{return priv_->variadic_marker_;}
22665
22666/// Compares two instances of @ref function_decl::parameter.
22667///
22668/// If the two intances are different, set a bitfield to give some
22669/// insight about the kind of differences there are.
22670///
22671/// @param l the first artifact of the comparison.
22672///
22673/// @param r the second artifact of the comparison.
22674///
22675/// @param k a pointer to a bitfield that gives information about the
22676/// kind of changes there are between @p l and @p r. This one is set
22677/// iff @p k is non-null and the function returns false.
22678///
22679/// Please note that setting k to a non-null value does have a
22680/// negative performance impact because even if @p l and @p r are not
22681/// equal, the function keeps up the comparison in order to determine
22682/// the different kinds of ways in which they are different.
22683///
22684/// @return true if @p l equals @p r, false otherwise.
22685bool
22687 const function_decl::parameter& r,
22688 change_kind* k)
22689{
22690 bool result = true;
22691
22692 if ((l.get_variadic_marker() != r.get_variadic_marker())
22693 || (l.get_index() != r.get_index())
22694 || (!!l.get_type() != !!r.get_type()))
22695 {
22696 result = false;
22697 if (k)
22698 {
22699 if (l.get_index() != r.get_index())
22701 if (l.get_variadic_marker() != r.get_variadic_marker()
22702 || !!l.get_type() != !!r.get_type())
22704 }
22705 else
22707 }
22708
22709 type_base_sptr l_type = peel_typedef_type(l.get_type());
22710 type_base_sptr r_type = peel_typedef_type(r.get_type());
22711 if (l_type != r_type)
22712 {
22713 result = false;
22714 if (k)
22715 {
22716 if (!types_have_similar_structure(l_type, r_type))
22718 else
22719 *k |= SUBTYPE_CHANGE_KIND;
22720 }
22721 else
22723 }
22724
22725 ABG_RETURN(result);
22726}
22727
22728bool
22729function_decl::parameter::operator==(const parameter& o) const
22730{return equals(*this, o, 0);}
22731
22732bool
22733function_decl::parameter::operator==(const decl_base& o) const
22734{
22735 const function_decl::parameter* p =
22736 dynamic_cast<const function_decl::parameter*>(&o);
22737 if (!p)
22738 return false;
22739 return function_decl::parameter::operator==(*p);
22740}
22741
22742/// Non-member equality operator for @ref function_decl::parameter.
22743///
22744/// @param l the left-hand side of the equality operator
22745///
22746/// @param r the right-hand side of the equality operator
22747///
22748/// @return true iff @p l and @p r equals.
22749bool
22752{
22753 if (!!l != !!r)
22754 return false;
22755 if (!l)
22756 return true;
22757 return *l == *r;
22758}
22759
22760/// Non-member inequality operator for @ref function_decl::parameter.
22761///
22762/// @param l the left-hand side of the equality operator
22763///
22764/// @param r the right-hand side of the equality operator
22765///
22766/// @return true iff @p l and @p r different.
22767bool
22770{return !operator==(l, r);}
22771
22772/// Traverse the diff sub-tree under the current instance
22773/// function_decl.
22774///
22775/// @param v the visitor to invoke on each diff node of the sub-tree.
22776///
22777/// @return true if the traversing has to keep going on, false
22778/// otherwise.
22779bool
22781{
22782 if (visiting())
22783 return true;
22784
22785 if (v.visit_begin(this))
22786 {
22787 visiting(true);
22788 if (type_base_sptr t = get_type())
22789 t->traverse(v);
22790 visiting(false);
22791 }
22792 return v.visit_end(this);
22793}
22794
22795/// Get the hash of a decl. If the hash hasn't been computed yet,
22796/// compute it ans store its value; otherwise, just return the hash.
22797///
22798/// @return the hash of the decl.
22799size_t
22801{
22802 function_decl::parameter::hash hash_fn_parm;
22803 return hash_fn_parm(this);
22804}
22805
22806/// Compute the qualified name of the parameter.
22807///
22808/// @param internal set to true if the call is intended for an
22809/// internal use (for technical use inside the library itself), false
22810/// otherwise. If you don't know what this is for, then set it to
22811/// false.
22812///
22813/// @param qn the resulting qualified name.
22814void
22816 bool /*internal*/) const
22817{qualified_name = get_name();}
22818
22819/// Compute and return a copy of the pretty representation of the
22820/// current function parameter.
22821///
22822/// @param internal set to true if the call is intended to get a
22823/// representation of the decl (or type) for the purpose of canonical
22824/// type comparison. This is mainly used in the function
22825/// type_base::get_canonical_type_for().
22826///
22827/// In other words if the argument for this parameter is true then the
22828/// call is meant for internal use (for technical use inside the
22829/// library itself), false otherwise. If you don't know what this is
22830/// for, then set it to false.
22831///
22832/// @return a copy of the textual representation of the current
22833/// function parameter.
22834string
22836 bool qualified_name) const
22837{
22838 const environment& env = get_environment();
22839
22840 string type_repr;
22841 type_base_sptr t = get_type();
22842 if (!t)
22843 type_repr = "void";
22844 else if (env.is_variadic_parameter_type(t))
22845 type_repr = "...";
22846 else
22847 type_repr = ir::get_type_name(t, qualified_name, internal);
22848
22849 string result = type_repr;
22850 string parm_name = get_name_id();
22851
22852 if (!parm_name.empty())
22853 result += " " + parm_name;
22854
22855 return result;
22856}
22857
22858// </function_decl::parameter definitions>
22859
22860// <class_or_union definitions>
22861
22862/// A Constructor for instances of @ref class_or_union
22863///
22864/// @param env the environment we are operating from.
22865///
22866/// @param name the identifier of the class.
22867///
22868/// @param size_in_bits the size of an instance of @ref
22869/// class_or_union, expressed in bits
22870///
22871/// @param align_in_bits the alignment of an instance of @ref class_or_union,
22872/// expressed in bits.
22873///
22874/// @param locus the source location of declaration point this class.
22875///
22876/// @param vis the visibility of instances of @ref class_or_union.
22877///
22878/// @param mem_types the vector of member types of this instance of
22879/// @ref class_or_union.
22880///
22881/// @param data_members the vector of data members of this instance of
22882/// @ref class_or_union.
22883///
22884/// @param member_fns the vector of member functions of this instance
22885/// of @ref class_or_union.
22886class_or_union::class_or_union(const environment& env, const string& name,
22887 size_t size_in_bits, size_t align_in_bits,
22888 const location& locus, visibility vis,
22889 member_types& mem_types,
22891 member_functions& member_fns)
22892 : type_or_decl_base(env,
22893 ABSTRACT_TYPE_BASE
22894 | ABSTRACT_DECL_BASE
22895 | ABSTRACT_SCOPE_TYPE_DECL
22896 | ABSTRACT_SCOPE_DECL),
22897 decl_base(env, name, locus, name, vis),
22898 type_base(env, size_in_bits, align_in_bits),
22899 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
22900 priv_(new priv(data_members, member_fns))
22901{
22902 for (member_types::iterator i = mem_types.begin();
22903 i != mem_types.end();
22904 ++i)
22907
22908 for (data_members::iterator i = data_members.begin();
22909 i != data_members.end();
22910 ++i)
22911 if (!has_scope(*i))
22912 add_decl_to_scope(*i, this);
22913
22914 for (member_functions::iterator i = member_fns.begin();
22915 i != member_fns.end();
22916 ++i)
22917 if (!has_scope(static_pointer_cast<decl_base>(*i)))
22918 add_decl_to_scope(*i, this);
22919}
22920
22921/// A constructor for instances of @ref class_or_union.
22922///
22923/// @param env the environment we are operating from.
22924///
22925/// @param name the name of the class.
22926///
22927/// @param size_in_bits the size of an instance of @ref
22928/// class_or_union, expressed in bits
22929///
22930/// @param align_in_bits the alignment of an instance of @ref class_or_union,
22931/// expressed in bits.
22932///
22933/// @param locus the source location of declaration point this class.
22934///
22935/// @param vis the visibility of instances of @ref class_or_union.
22936class_or_union::class_or_union(const environment& env, const string& name,
22937 size_t size_in_bits, size_t align_in_bits,
22938 const location& locus, visibility vis)
22939 : type_or_decl_base(env,
22940 ABSTRACT_TYPE_BASE
22941 | ABSTRACT_DECL_BASE
22942 | ABSTRACT_SCOPE_TYPE_DECL
22943 | ABSTRACT_SCOPE_DECL),
22944 decl_base(env, name, locus, name, vis),
22945 type_base(env, size_in_bits, align_in_bits),
22946 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
22947 priv_(new priv)
22948{}
22949
22950/// Constructor of the @ref class_or_union type.
22951///
22952/// @param env the @ref environment we are operating from.
22953///
22954/// @param name the name of the @ref class_or_union.
22955///
22956/// @param is_declaration_only a boolean saying whether the instance
22957/// represents a declaration only, or not.
22958class_or_union::class_or_union(const environment& env, const string& name,
22959 bool is_declaration_only)
22960 : type_or_decl_base(env,
22961 ABSTRACT_TYPE_BASE
22962 | ABSTRACT_DECL_BASE
22963 | ABSTRACT_SCOPE_TYPE_DECL
22964 | ABSTRACT_SCOPE_DECL),
22965 decl_base(env, name, location(), name),
22966 type_base(env, 0, 0),
22967 scope_type_decl(env, name, 0, 0, location()),
22968 priv_(new priv)
22969{
22970 set_is_declaration_only(is_declaration_only);
22971}
22972
22973/// This implements the ir_traversable_base::traverse pure virtual
22974/// function.
22975///
22976/// @param v the visitor used on the member nodes of the translation
22977/// unit during the traversal.
22978///
22979/// @return true if the entire IR node tree got traversed, false
22980/// otherwise.
22981bool
22983{
22984 if (v.type_node_has_been_visited(this))
22985 return true;
22986
22987 if (visiting())
22988 return true;
22989
22990 if (v.visit_begin(this))
22991 {
22992 visiting(true);
22993 bool stop = false;
22994
22995 if (!stop)
22996 for (data_members::const_iterator i = get_data_members().begin();
22997 i != get_data_members().end();
22998 ++i)
22999 if (!(*i)->traverse(v))
23000 {
23001 stop = true;
23002 break;
23003 }
23004
23005 if (!stop)
23006 for (member_functions::const_iterator i= get_member_functions().begin();
23007 i != get_member_functions().end();
23008 ++i)
23009 if (!(*i)->traverse(v))
23010 {
23011 stop = true;
23012 break;
23013 }
23014
23015 if (!stop)
23016 for (member_types::const_iterator i = get_member_types().begin();
23017 i != get_member_types().end();
23018 ++i)
23019 if (!(*i)->traverse(v))
23020 {
23021 stop = true;
23022 break;
23023 }
23024
23025 if (!stop)
23026 for (member_function_templates::const_iterator i =
23028 i != get_member_function_templates().end();
23029 ++i)
23030 if (!(*i)->traverse(v))
23031 {
23032 stop = true;
23033 break;
23034 }
23035
23036 if (!stop)
23037 for (member_class_templates::const_iterator i =
23039 i != get_member_class_templates().end();
23040 ++i)
23041 if (!(*i)->traverse(v))
23042 {
23043 stop = true;
23044 break;
23045 }
23046 visiting(false);
23047 }
23048
23049 bool result = v.visit_end(this);
23051 return result;
23052}
23053
23054/// Destrcutor of the @ref class_or_union type.
23056{delete priv_;}
23057
23058/// Add a member declaration to the current instance of class_or_union.
23059/// The member declaration can be either a member type, data member,
23060/// member function, or member template.
23061///
23062/// @param d the member declaration to add.
23063decl_base_sptr
23064class_or_union::add_member_decl(const decl_base_sptr& d)
23065{return insert_member_decl(d);}
23066
23067/// Remove a given decl from the current @ref class_or_union scope.
23068///
23069/// Note that only type declarations are supported by this method for
23070/// now. Support for the other kinds of declaration is left as an
23071/// exercise for the interested reader of the code.
23072///
23073/// @param decl the declaration to remove from this @ref
23074/// class_or_union scope.
23075void
23077{
23078 type_base_sptr t = is_type(decl);
23079
23080 // For now we want to support just removing types from classes. For
23081 // other kinds of IR node, we need more work.
23082 ABG_ASSERT(t);
23083
23085}
23086
23087/// Fixup the members of the type of an anonymous data member.
23088///
23089/// Walk all data members of (the type of) a given anonymous data
23090/// member and set a particular property of the relationship between
23091/// each data member and its containing type.
23092///
23093/// That property records the fact that the data member belongs to the
23094/// anonymous data member we consider.
23095///
23096/// In the future, if there are other properties of this relationship
23097/// to set in this manner, they ought to be added here.
23098///
23099/// @param anon_dm the anonymous data member to consider.
23100void
23102{
23103 class_or_union * anon_dm_type =
23105 if (!anon_dm_type)
23106 return;
23107
23108 for (class_or_union::data_members::const_iterator it =
23109 anon_dm_type->get_non_static_data_members().begin();
23110 it != anon_dm_type->get_non_static_data_members().end();
23111 ++it)
23112 {
23113 dm_context_rel *rel =
23114 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
23115 ABG_ASSERT(rel);
23116 rel->set_anonymous_data_member(anon_dm.get());
23117 }
23118}
23119
23120/// Getter of the alignment of the @ref class_or_union type.
23121///
23122/// If this @ref class_or_union is a declaration of a definition that
23123/// is elsewhere, then the size of the definition is returned.
23124///
23125/// @return the alignment of the @ref class_or_union type.
23126size_t
23128{
23132
23134}
23135
23136/// Setter of the alignment of the class type.
23137///
23138/// If this class is a declaration of a definition that is elsewhere,
23139/// then the new alignment is set to the definition.
23140///
23141/// @param s the new alignment.
23142void
23144{
23148 else
23150}
23151
23152/// Setter of the size of the @ref class_or_union type.
23153///
23154/// If this @ref class_or_union is a declaration of a definition that
23155/// is elsewhere, then the new size is set to the definition.
23156///
23157/// @param s the new size.
23158void
23160{
23164 else
23166}
23167
23168/// Getter of the size of the @ref class_or_union type.
23169///
23170/// If this @ref class_or_union is a declaration of a definition that
23171/// is elsewhere, then the size of the definition is returned.
23172///
23173/// @return the size of the @ref class_or_union type.
23174size_t
23176{
23180
23182}
23183
23184/// Get the number of anonymous member classes contained in this
23185/// class.
23186///
23187/// @return the number of anonymous member classes contained in this
23188/// class.
23189size_t
23191{
23192 int result = 0;
23193 for (member_types::const_iterator it = get_member_types().begin();
23194 it != get_member_types().end();
23195 ++it)
23196 if (class_decl_sptr t = is_class_type(*it))
23197 if (t->get_is_anonymous())
23198 ++result;
23199
23200 return result;
23201}
23202
23203/// Get the number of anonymous member unions contained in this class.
23204///
23205/// @return the number of anonymous member unions contained in this
23206/// class.
23207size_t
23209{
23210 int result = 0;
23211 for (member_types::const_iterator it = get_member_types().begin();
23212 it != get_member_types().end();
23213 ++it)
23214 if (union_decl_sptr t = is_union_type(*it))
23215 if (t->get_is_anonymous())
23216 ++result;
23217
23218 return result;
23219}
23220
23221/// Get the number of anonymous member enums contained in this class.
23222///
23223/// @return the number of anonymous member enums contained in this
23224/// class.
23225size_t
23227{
23228 int result = 0;
23229 for (member_types::const_iterator it = get_member_types().begin();
23230 it != get_member_types().end();
23231 ++it)
23232 if (enum_type_decl_sptr t = is_enum_type(*it))
23233 if (t->get_is_anonymous())
23234 ++result;
23235
23236 return result;
23237}
23238
23239/// Add a data member to the current instance of class_or_union.
23240///
23241/// @param v a var_decl to add as a data member. A proper
23242/// class_or_union::data_member is created from @p v and added to the
23243/// class_or_union. This var_decl should not have been already added
23244/// to a scope.
23245///
23246/// @param access the access specifier for the data member.
23247///
23248/// @param is_laid_out whether the data member was laid out. That is,
23249/// if its offset has been computed. In the pattern of a class
23250/// template for instance, this would be set to false.
23251///
23252/// @param is_static whether the data memer is static.
23253///
23254/// @param offset_in_bits if @p is_laid_out is true, this is the
23255/// offset of the data member, expressed (oh, surprise) in bits.
23256void
23258 bool is_laid_out, bool is_static,
23259 size_t offset_in_bits)
23260{
23261 ABG_ASSERT(!has_scope(v));
23262
23263 priv_->data_members_.push_back(v);
23265 set_data_member_is_laid_out(v, is_laid_out);
23266 set_data_member_offset(v, offset_in_bits);
23267 set_member_access_specifier(v, access);
23268 set_member_is_static(v, is_static);
23269
23270 if (!is_static)
23271 {
23272 // If this is a non-static variable, add it to the set of
23273 // non-static variables, if it's not already in there.
23274 bool is_already_in = false;
23275 for (data_members::const_iterator i =
23276 priv_->non_static_data_members_.begin();
23277 i != priv_->non_static_data_members_.end();
23278 ++i)
23279 if (*i == v)
23280 {
23281 is_already_in = true;
23282 break;
23283 }
23284 if (!is_already_in)
23285 priv_->non_static_data_members_.push_back(v);
23286 }
23287
23288 // If v is an anonymous data member, then fixup its data members.
23289 // For now, the only thing the fixup does is to make the data
23290 // members of the anonymous data member be aware of their containing
23291 // anonymous data member. That is helpful to compute the absolute
23292 // bit offset of each of the members of the anonymous data member.
23294}
23295
23296/// Get the data members of this @ref class_or_union.
23297///
23298/// @return a vector of the data members of this @ref class_or_union.
23301{return priv_->data_members_;}
23302
23303/// Find a data member of a given name in the current @ref class_or_union.
23304///
23305/// @param name the name of the data member to find in the current
23306/// @ref class_or_union.
23307///
23308/// @return a pointer to the @ref var_decl that represents the data
23309/// member to find inside the current @ref class_or_union.
23310const var_decl_sptr
23311class_or_union::find_data_member(const string& name) const
23312{
23313 for (data_members::const_iterator i = get_data_members().begin();
23314 i != get_data_members().end();
23315 ++i)
23316 if ((*i)->get_name() == name)
23317 return *i;
23318
23319 // We haven't found a data member with the name 'name'. Let's look
23320 // closer again, this time in our anonymous data members.
23321 for (data_members::const_iterator i = get_data_members().begin();
23322 i != get_data_members().end();
23323 ++i)
23325 {
23326 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
23327 ABG_ASSERT(type);
23328 if (var_decl_sptr data_member = type->find_data_member(name))
23329 return data_member;
23330 }
23331
23332 return var_decl_sptr();
23333}
23334
23335/// Find an anonymous data member in the class.
23336///
23337/// @param v the anonymous data member to find.
23338///
23339/// @return the anonymous data member found, or nil if none was found.
23340const var_decl_sptr
23342{
23343 if (!v->get_name().empty())
23344 return var_decl_sptr();
23345
23346 for (data_members::const_iterator it = get_non_static_data_members().begin();
23347 it != get_non_static_data_members().end();
23348 ++it)
23349 {
23350 if (is_anonymous_data_member(*it))
23351 if ((*it)->get_pretty_representation(/*internal=*/false, true)
23352 == v->get_pretty_representation(/*internal=*/false, true))
23353 return *it;
23354 }
23355
23356 return var_decl_sptr();
23357}
23358
23359/// Find a given data member.
23360///
23361/// This function takes a @ref var_decl as an argument. If it has a
23362/// non-empty name, then it tries to find a data member which has the
23363/// same name as the argument.
23364///
23365/// If it has an empty name, then the @ref var_decl is considered as
23366/// an anonymous data member. In that case, this function tries to
23367/// find an anonymous data member which type equals that of the @ref
23368/// var_decl argument.
23369///
23370/// @param v this carries either the name of the data member we need
23371/// to look for, or the type of the anonymous data member we are
23372/// looking for.
23373const var_decl_sptr
23375{
23376 if (!v)
23377 return var_decl_sptr();
23378
23379 if (v->get_name().empty())
23381
23382 return find_data_member(v->get_name());
23383}
23384
23385
23386/// Get the non-static data memebers of this @ref class_or_union.
23387///
23388/// @return a vector of the non-static data members of this @ref
23389/// class_or_union.
23392{return priv_->non_static_data_members_;}
23393
23394/// Add a member function.
23395///
23396/// @param f the new member function to add.
23397///
23398/// @param a the access specifier to use for the new member function.
23399///
23400/// @param is_static whether the new member function is static.
23401///
23402/// @param is_ctor whether the new member function is a constructor.
23403///
23404/// @param is_dtor whether the new member function is a destructor.
23405///
23406/// @param is_const whether the new member function is const.
23407void
23410 bool is_static, bool is_ctor,
23411 bool is_dtor, bool is_const)
23412{
23413 ABG_ASSERT(!has_scope(f));
23414
23416
23417 set_member_function_is_ctor(f, is_ctor);
23418 set_member_function_is_dtor(f, is_dtor);
23420 set_member_is_static(f, is_static);
23421 set_member_function_is_const(f, is_const);
23422
23423 priv_->member_functions_.push_back(f);
23424
23425 // Update the map of linkage name -> member functions. It's useful,
23426 // so that class_or_union::find_member_function() can function.
23427 if (!f->get_linkage_name().empty())
23428 priv_->mem_fns_map_[f->get_linkage_name()] = f;
23429}
23430
23431/// Get the member functions of this @ref class_or_union.
23432///
23433/// @return a vector of the member functions of this @ref
23434/// class_or_union.
23437{return priv_->member_functions_;}
23438
23439/// Find a method, using its linkage name as a key.
23440///
23441/// @param linkage_name the linkage name of the method to find.
23442///
23443/// @return the method found, or nil if none was found.
23444const method_decl*
23445class_or_union::find_member_function(const string& linkage_name) const
23446{
23447 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
23448}
23449
23450/// Find a method, using its linkage name as a key.
23451///
23452/// @param linkage_name the linkage name of the method to find.
23453///
23454/// @return the method found, or nil if none was found.
23456class_or_union::find_member_function(const string& linkage_name)
23457{
23458 string_mem_fn_sptr_map_type::const_iterator i =
23459 priv_->mem_fns_map_.find(linkage_name);
23460 if (i == priv_->mem_fns_map_.end())
23461 return 0;
23462 return i->second.get();
23463}
23464
23465/// Find a method, using its linkage name as a key.
23466///
23467/// @param linkage_name the linkage name of the method to find.
23468///
23469/// @return the method found, or nil if none was found.
23470method_decl_sptr
23472{
23473 string_mem_fn_sptr_map_type::const_iterator i =
23474 priv_->mem_fns_map_.find(linkage_name);
23475 if (i == priv_->mem_fns_map_.end())
23476 return 0;
23477 return i->second;
23478}
23479
23480/// Find a method (member function) using its signature (pretty
23481/// representation) as a key.
23482///
23483/// @param s the signature of the method.
23484///
23485/// @return the method found, or nil if none was found.
23486const method_decl*
23488{
23489 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
23490}
23491
23492/// Find a method (member function) using its signature (pretty
23493/// representation) as a key.
23494///
23495/// @param s the signature of the method.
23496///
23497/// @return the method found, or nil if none was found.
23500{
23501 string_mem_fn_ptr_map_type::const_iterator i =
23502 priv_->signature_2_mem_fn_map_.find(s);
23503 if (i == priv_->signature_2_mem_fn_map_.end())
23504 return 0;
23505 return i->second;
23506}
23507
23508/// Get the member function templates of this class.
23509///
23510/// @return a vector of the member function templates of this class.
23511const member_function_templates&
23513{return priv_->member_function_templates_;}
23514
23515/// Get the member class templates of this class.
23516///
23517/// @return a vector of the member class templates of this class.
23518const member_class_templates&
23520{return priv_->member_class_templates_;}
23521
23522/// Append a member function template to the @ref class_or_union.
23523///
23524/// @param m the member function template to append.
23525void
23526class_or_union::add_member_function_template(member_function_template_sptr m)
23527{
23528 decl_base* c = m->as_function_tdecl()->get_scope();
23529 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
23530 /// error message or something like a structured error.
23531 priv_->member_function_templates_.push_back(m);
23532 if (!c)
23533 scope_decl::add_member_decl(m->as_function_tdecl());
23534}
23535
23536/// Append a member class template to the @ref class_or_union.
23537///
23538/// @param m the member function template to append.
23539void
23541{
23542 decl_base* c = m->as_class_tdecl()->get_scope();
23543 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
23544 /// error message or something like a structured error.
23545 m->set_scope(this);
23546 priv_->member_class_templates_.push_back(m);
23547 if (!c)
23548 scope_decl::add_member_decl(m->as_class_tdecl());
23549}
23550
23551///@return true iff the current instance has no member.
23552bool
23554{
23555 return (get_member_types().empty()
23556 && priv_->data_members_.empty()
23557 && priv_->member_functions_.empty()
23558 && priv_->member_function_templates_.empty()
23559 && priv_->member_class_templates_.empty());
23560}
23561
23562/// Insert a data member to this @ref class_or_union type.
23563///
23564/// @param d the data member to insert.
23565///
23566/// @return the decl @p that got inserted.
23567decl_base_sptr
23569{
23570 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
23571 {
23572 add_data_member(v, public_access,
23573 /*is_laid_out=*/false,
23574 /*is_static=*/true,
23575 /*offset_in_bits=*/0);
23576 d = v;
23577 }
23578 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
23579 add_member_function(f, public_access,
23580 /*is_static=*/false,
23581 /*is_ctor=*/false,
23582 /*is_dtor=*/false,
23583 /*is_const=*/false);
23584 else if (member_function_template_sptr f =
23585 dynamic_pointer_cast<member_function_template>(d))
23587 else if (member_class_template_sptr c =
23588 dynamic_pointer_cast<member_class_template>(d))
23590 else
23592
23593 return d;
23594}
23595
23596/// Equality operator.
23597///
23598/// @param other the other @ref class_or_union to compare against.
23599///
23600/// @return true iff @p other equals the current @ref class_or_union.
23601bool
23603{
23604 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
23605 if (!op)
23606 return false;
23607
23608 // If this is a decl-only type (and thus with no canonical type),
23609 // use the canonical type of the definition, if any.
23610 const class_or_union *l = 0;
23612 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
23613 if (l == 0)
23614 l = this;
23615
23616 // Likewise for the other class.
23617 const class_or_union *r = 0;
23618 if (op->get_is_declaration_only())
23619 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
23620 if (r == 0)
23621 r = op;
23622
23623 return try_canonical_compare(l, r);
23624}
23625
23626/// Equality operator.
23627///
23628/// @param other the other @ref class_or_union to compare against.
23629///
23630/// @return true iff @p other equals the current @ref class_or_union.
23631bool
23633{
23634 const decl_base* o = dynamic_cast<const decl_base*>(&other);
23635 if (!o)
23636 return false;
23637 return *this == *o;
23638}
23639
23640/// Equality operator.
23641///
23642/// @param other the other @ref class_or_union to compare against.
23643///
23644/// @return true iff @p other equals the current @ref class_or_union.
23645bool
23647{
23648 const decl_base& o = other;
23650}
23651
23652/// Compares two instances of @ref class_or_union.
23653///
23654/// If the two intances are different, set a bitfield to give some
23655/// insight about the kind of differences there are.
23656///
23657/// @param l the first artifact of the comparison.
23658///
23659/// @param r the second artifact of the comparison.
23660///
23661/// @param k a pointer to a bitfield that gives information about the
23662/// kind of changes there are between @p l and @p r. This one is set
23663/// iff it's non-null and if the function returns false.
23664///
23665/// Please note that setting k to a non-null value does have a
23666/// negative performance impact because even if @p l and @p r are not
23667/// equal, the function keeps up the comparison in order to determine
23668/// the different kinds of ways in which they are different.
23669///
23670/// @return true if @p l equals @p r, false otherwise.
23671bool
23673{
23674 // if one of the classes is declaration-only, look through it to
23675 // get its definition.
23676 bool l_is_decl_only = l.get_is_declaration_only();
23677 bool r_is_decl_only = r.get_is_declaration_only();
23678 if (l_is_decl_only || r_is_decl_only)
23679 {
23680 const class_or_union* def1 = l_is_decl_only
23682 : &l;
23683
23684 const class_or_union* def2 = r_is_decl_only
23686 : &r;
23687
23688 if (!def1 || !def2)
23689 {
23690 if (!l.get_is_anonymous()
23691 && !r.get_is_anonymous()
23692 && l_is_decl_only && r_is_decl_only
23694 // The two decl-only classes differ from their size. A
23695 // true decl-only class should not have a size property to
23696 // begin with. This comes from a DWARF oddity and can
23697 // results in a false positive, so let's not consider that
23698 // change.
23699 return true;
23700
23702 || ((odr_is_relevant(l) && !def1)
23703 || (odr_is_relevant(r) && !def2)))
23706 {
23707 const interned_string& q1 = l.get_scoped_name();
23708 const interned_string& q2 = r.get_scoped_name();
23709 if (q1 == q2)
23710 // Not using RETURN(true) here, because that causes
23711 // performance issues. We don't need to do
23712 // l.priv_->unmark_as_being_compared({l,r}) here because
23713 // we haven't marked l or r as being compared yet, and
23714 // doing so has a peformance cost that shows up on
23715 // performance profiles for *big* libraries.
23716 return true;
23717 else
23718 {
23719 if (k)
23721 // Not using RETURN(true) here, because that causes
23722 // performance issues. We don't need to do
23723 // l.priv_->unmark_as_being_compared({l,r}) here because
23724 // we haven't marked l or r as being compared yet, and
23725 // doing so has a peformance cost that shows up on
23726 // performance profiles for *big* libraries.
23728 }
23729 }
23730 else // A decl-only class is considered different from a
23731 // class definition of the same name.
23732 {
23733 if (!!def1 != !!def2)
23734 {
23735 if (k)
23738 }
23739
23740 // both definitions are empty
23741 if (!(l.decl_base::operator==(r)
23742 && l.type_base::operator==(r)))
23743 {
23744 if (k)
23747 }
23748
23749 return true;
23750 }
23751 }
23752
23753 bool val = *def1 == *def2;
23754 if (!val)
23755 if (k)
23757 ABG_RETURN(val);
23758 }
23759
23760 // No need to go further if the classes have different names or
23761 // different size / alignment.
23762 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
23763 {
23764 if (k)
23767 }
23768
23769 if (types_defined_same_linux_kernel_corpus_public(l, r))
23770 return true;
23771
23772 //TODO: Maybe remove this (cycle detection and canonical type
23773 //propagation handling) from here and have it only in the equal
23774 //overload for class_decl and union_decl because this one ( the
23775 //equal overload for class_or_union) is just a sub-routine of these
23776 //two above.
23777#define RETURN(value) \
23778 return return_comparison_result(l, r, value, \
23779 /*propagate_canonical_type=*/false);
23780
23782
23784
23785 bool result = true;
23786
23787 //compare data_members
23788 {
23789 if (l.get_non_static_data_members().size()
23790 != r.get_non_static_data_members().size())
23791 {
23792 result = false;
23793 if (k)
23795 else
23796 RETURN(result);
23797 }
23798
23799 for (class_or_union::data_members::const_iterator
23800 d0 = l.get_non_static_data_members().begin(),
23801 d1 = r.get_non_static_data_members().begin();
23802 (d0 != l.get_non_static_data_members().end()
23803 && d1 != r.get_non_static_data_members().end());
23804 ++d0, ++d1)
23805 if (**d0 != **d1)
23806 {
23807 result = false;
23808 if (k)
23809 {
23810 // Report any representation change as being local.
23811 if (!types_have_similar_structure((*d0)->get_type(),
23812 (*d1)->get_type())
23813 || (*d0)->get_type() == (*d1)->get_type())
23815 else
23816 *k |= SUBTYPE_CHANGE_KIND;
23817 }
23818 else
23819 RETURN(result);
23820 }
23821 }
23822
23823 // Do not compare member functions. DWARF does not necessarily
23824 // all the member functions, be they virtual or not, in all
23825 // translation units. So we cannot have a clear view of them, per
23826 // class
23827
23828 // compare member function templates
23829 {
23830 if (l.get_member_function_templates().size()
23831 != r.get_member_function_templates().size())
23832 {
23833 result = false;
23834 if (k)
23836 else
23837 RETURN(result);
23838 }
23839
23840 for (member_function_templates::const_iterator
23841 fn_tmpl_it0 = l.get_member_function_templates().begin(),
23842 fn_tmpl_it1 = r.get_member_function_templates().begin();
23843 fn_tmpl_it0 != l.get_member_function_templates().end()
23844 && fn_tmpl_it1 != r.get_member_function_templates().end();
23845 ++fn_tmpl_it0, ++fn_tmpl_it1)
23846 if (**fn_tmpl_it0 != **fn_tmpl_it1)
23847 {
23848 result = false;
23849 if (k)
23850 {
23852 break;
23853 }
23854 else
23855 RETURN(result);
23856 }
23857 }
23858
23859 // compare member class templates
23860 {
23861 if (l.get_member_class_templates().size()
23862 != r.get_member_class_templates().size())
23863 {
23864 result = false;
23865 if (k)
23867 else
23868 RETURN(result);
23869 }
23870
23871 for (member_class_templates::const_iterator
23872 cl_tmpl_it0 = l.get_member_class_templates().begin(),
23873 cl_tmpl_it1 = r.get_member_class_templates().begin();
23874 cl_tmpl_it0 != l.get_member_class_templates().end()
23875 && cl_tmpl_it1 != r.get_member_class_templates().end();
23876 ++cl_tmpl_it0, ++cl_tmpl_it1)
23877 if (**cl_tmpl_it0 != **cl_tmpl_it1)
23878 {
23879 result = false;
23880 if (k)
23881 {
23883 break;
23884 }
23885 else
23886 RETURN(result);
23887 }
23888 }
23889
23890 RETURN(result);
23891#undef RETURN
23892}
23893
23894
23895/// Copy a method of a @ref class_or_union into a new @ref
23896/// class_or_union.
23897///
23898/// @param t the @ref class_or_union into which the method is to be copied.
23899///
23900/// @param method the method to copy into @p t.
23901///
23902/// @return the resulting newly copied method.
23903method_decl_sptr
23904copy_member_function(const class_or_union_sptr& t,
23905 const method_decl_sptr& method)
23906{return copy_member_function(t, method.get());}
23907
23908
23909/// Copy a method of a @ref class_or_union into a new @ref
23910/// class_or_union.
23911///
23912/// @param t the @ref class_or_union into which the method is to be copied.
23913///
23914/// @param method the method to copy into @p t.
23915///
23916/// @return the resulting newly copied method.
23917method_decl_sptr
23918copy_member_function(const class_or_union_sptr& t, const method_decl* method)
23919{
23920 ABG_ASSERT(t);
23921 ABG_ASSERT(method);
23922
23923 method_type_sptr old_type = method->get_type();
23924 ABG_ASSERT(old_type);
23925 method_type_sptr new_type(new method_type(old_type->get_return_type(),
23926 t,
23927 old_type->get_parameters(),
23928 old_type->get_is_const(),
23929 old_type->get_size_in_bits(),
23930 old_type->get_alignment_in_bits()));
23931 t->get_translation_unit()->bind_function_type_life_time(new_type);
23932
23933 method_decl_sptr
23934 new_method(new method_decl(method->get_name(),
23935 new_type,
23936 method->is_declared_inline(),
23937 method->get_location(),
23938 method->get_linkage_name(),
23939 method->get_visibility(),
23940 method->get_binding()));
23941 new_method->set_symbol(method->get_symbol());
23942
23943 if (class_decl_sptr class_type = is_class_type(t))
23944 class_type->add_member_function(new_method,
23948 get_member_is_static(*method),
23952 else
23953 t->add_member_function(new_method,
23955 get_member_is_static(*method),
23959 return new_method;
23960}
23961
23962// </class_or_union definitions>
23963
23964/// @defgroup OnTheFlyCanonicalization On-the-fly Canonicalization
23965/// @{
23966///
23967/// This optimization is also known as "canonical type propagation".
23968///
23969/// During the canonicalization of a type T (which doesn't yet have a
23970/// canonical type), T is compared structurally (member-wise) against
23971/// a type C which already has a canonical type. The comparison
23972/// expression is C == T.
23973///
23974/// During that structural comparison, if a subtype of C (which also
23975/// already has a canonical type) is structurally compared to a
23976/// subtype of T (which doesn't yet have a canonical type) and if they
23977/// are equal, then we can deduce that the canonical type of the
23978/// subtype of C is the canonical type of the subtype of C.
23979///
23980/// Thus, we can canonicalize the sub-type of the T, during the
23981/// canonicalization of T itself. That canonicalization of the
23982/// sub-type of T is what we call the "on-the-fly canonicalization".
23983/// It's on the fly because it happens during a comparison -- which
23984/// itself happens during the canonicalization of T.
23985///
23986/// For now this on-the-fly canonicalization only happens when
23987/// comparing @ref class_decl and @ref function_type.
23988///
23989/// Note however that there is a case when a type is *NOT* eligible to
23990/// this canonical type propagation optimization.
23991///
23992/// The reason why a type is deemed NON-eligible to the canonical type
23993/// propagation optimization is that it "depends" on recursively
23994/// present type. Let me explain.
23995///
23996/// Suppose we have a type T that has sub-types named ST0 and ST1.
23997/// Suppose ST1 itself has a sub-type that is T itself. In this case,
23998/// we say that T is a recursive type, because it has T (itself) as
23999/// one of its sub-types:
24000///
24001/// <PRE>
24002/// T
24003/// +-- ST0
24004/// |
24005/// +-- ST1
24006/// | +
24007/// | |
24008/// | +-- T
24009/// |
24010/// +-- ST2
24011/// </PRE>
24012///
24013/// ST1 is said to "depend" on T because it has T as a sub-type. But
24014/// because T is recursive, then ST1 is said to depend on a recursive
24015/// type. Notice however that ST0 does not depend on any recursive
24016/// type.
24017///
24018/// Now suppose we are comparing T to a type T' that has the same
24019/// structure with sub-types ST0', ST1' and ST2'. During the
24020/// comparison of ST1 against ST1', their sub-type T is compared
24021/// against T'. Because T (resp. T') is a recursive type that is
24022/// already being compared, the comparison of T against T' (as a
24023/// subtypes of ST1 and ST1') returns true, meaning they are
24024/// considered equal. This is done so that we don't enter an infinite
24025/// recursion.
24026///
24027/// That means ST1 is also deemed equal to ST1'. If we are in the
24028/// course of the canonicalization of T' and thus if T (as well as as
24029/// all of its sub-types) is already canonicalized, then the canonical
24030/// type propagation optimization will make us propagate the canonical
24031/// type of ST1 onto ST1'. So the canonical type of ST1' will be
24032/// equal to the canonical type of ST1 as a result of that
24033/// optmization.
24034///
24035/// But then, later down the road, when ST2 is compared against ST2',
24036/// let's suppose that we find out that they are different. Meaning
24037/// that ST2 != ST2'. This means that T != T', i.e, the
24038/// canonicalization of T' failed for now. But most importantly, it
24039/// means that the propagation of the canonical type of ST1 to ST1'
24040/// must now be invalidated. Meaning, ST1' must now be considered as
24041/// not having any canonical type.
24042///
24043/// In other words, during type canonicalization, if ST1' depends on a
24044/// recursive type T', its propagated canonical type must be
24045/// invalidated (set to nullptr) if T' appears to be different from T,
24046/// a.k.a, the canonicalization of T' temporarily failed.
24047///
24048/// This means that any sub-type that depends on recursive types and
24049/// that has been the target of the canonical type propagation
24050/// optimization must be tracked. If the dependant recursive type
24051/// fails its canonicalization, then the sub-type being compared must
24052/// have its propagated canonical type cleared. In other words, its
24053/// propagated canonical type must be cancelled.
24054///
24055/// @}
24056
24057
24058/// If on-the-fly canonicalization is turned on, then this function
24059/// sets the canonical type of its second parameter to the canonical
24060/// type of the first parameter.
24061///
24062/// @param lhs_type the type which canonical type to propagate.
24063///
24064/// @param rhs_type the type which canonical type to set.
24065static bool
24066maybe_propagate_canonical_type(const type_base& lhs_type,
24067 const type_base& rhs_type)
24068{
24069 const environment& env = lhs_type.get_environment();
24070#if WITH_DEBUG_TYPE_CANONICALIZATION
24071 if (!env.priv_->use_canonical_type_comparison_)
24072 return false;
24073#endif
24074
24076 if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
24077 if (!rhs_type.get_canonical_type())
24078 if (env.priv_->propagate_ct(lhs_type, rhs_type))
24079 return true;
24080 return false;
24081}
24082
24083// <class_decl definitions>
24084
24085static void
24086sort_virtual_member_functions(class_decl::member_functions& mem_fns);
24087
24088/// The private data for the class_decl type.
24089struct class_decl::priv
24090{
24091 base_specs bases_;
24092 unordered_map<string, base_spec_sptr> bases_map_;
24093 member_functions virtual_mem_fns_;
24094 virtual_mem_fn_map_type virtual_mem_fns_map_;
24095 bool is_struct_;
24096
24097 priv()
24098 : is_struct_(false)
24099 {}
24100
24101 priv(bool is_struct, class_decl::base_specs& bases)
24102 : bases_(bases),
24103 is_struct_(is_struct)
24104 {
24105 }
24106
24107 priv(bool is_struct)
24108 : is_struct_(is_struct)
24109 {}
24110};// end struct class_decl::priv
24111
24112/// A Constructor for instances of \ref class_decl
24113///
24114/// @param env the environment we are operating from.
24115///
24116/// @param name the identifier of the class.
24117///
24118/// @param size_in_bits the size of an instance of class_decl, expressed
24119/// in bits
24120///
24121/// @param align_in_bits the alignment of an instance of class_decl,
24122/// expressed in bits.
24123///
24124/// @param locus the source location of declaration point this class.
24125///
24126/// @param vis the visibility of instances of class_decl.
24127///
24128/// @param bases the vector of base classes for this instance of class_decl.
24129///
24130/// @param mbrs the vector of member types of this instance of
24131/// class_decl.
24132///
24133/// @param data_mbrs the vector of data members of this instance of
24134/// class_decl.
24135///
24136/// @param mbr_fns the vector of member functions of this instance of
24137/// class_decl.
24138class_decl::class_decl(const environment& env, const string& name,
24139 size_t size_in_bits, size_t align_in_bits,
24140 bool is_struct, const location& locus,
24141 visibility vis, base_specs& bases,
24142 member_types& mbr_types,
24143 data_members& data_mbrs,
24144 member_functions& mbr_fns)
24145 : type_or_decl_base(env,
24146 CLASS_TYPE
24147 | ABSTRACT_TYPE_BASE
24148 | ABSTRACT_DECL_BASE
24149 | ABSTRACT_SCOPE_TYPE_DECL
24150 | ABSTRACT_SCOPE_DECL),
24151 decl_base(env, name, locus, name, vis),
24152 type_base(env, size_in_bits, align_in_bits),
24153 class_or_union(env, name, size_in_bits, align_in_bits,
24154 locus, vis, mbr_types, data_mbrs, mbr_fns),
24155 priv_(new priv(is_struct, bases))
24156{
24158}
24159
24160/// A Constructor for instances of @ref class_decl
24161///
24162/// @param env the environment we are operating from.
24163///
24164/// @param name the identifier of the class.
24165///
24166/// @param size_in_bits the size of an instance of class_decl, expressed
24167/// in bits
24168///
24169/// @param align_in_bits the alignment of an instance of class_decl,
24170/// expressed in bits.
24171///
24172/// @param locus the source location of declaration point this class.
24173///
24174/// @param vis the visibility of instances of class_decl.
24175///
24176/// @param bases the vector of base classes for this instance of class_decl.
24177///
24178/// @param mbrs the vector of member types of this instance of
24179/// class_decl.
24180///
24181/// @param data_mbrs the vector of data members of this instance of
24182/// class_decl.
24183///
24184/// @param mbr_fns the vector of member functions of this instance of
24185/// class_decl.
24186///
24187/// @param is_anonymous whether the newly created instance is
24188/// anonymous.
24189class_decl::class_decl(const environment& env, const string& name,
24190 size_t size_in_bits, size_t align_in_bits,
24191 bool is_struct, const location& locus,
24192 visibility vis, base_specs& bases,
24193 member_types& mbr_types, data_members& data_mbrs,
24194 member_functions& mbr_fns, bool is_anonymous)
24195 : type_or_decl_base(env,
24196 CLASS_TYPE
24197 | ABSTRACT_TYPE_BASE
24198 | ABSTRACT_DECL_BASE
24199 | ABSTRACT_SCOPE_TYPE_DECL
24200 | ABSTRACT_SCOPE_DECL),
24201 decl_base(env, name, locus,
24202 // If the class is anonymous then by default it won't
24203 // have a linkage name. Also, the anonymous class does
24204 // have an internal-only unique name that is generally
24205 // not taken into account when comparing classes; such a
24206 // unique internal-only name, when used as a linkage
24207 // name might introduce spurious comparison false
24208 // negatives.
24209 /*linkage_name=*/is_anonymous ? string() : name,
24210 vis),
24211 type_base(env, size_in_bits, align_in_bits),
24212 class_or_union(env, name, size_in_bits, align_in_bits,
24213 locus, vis, mbr_types, data_mbrs, mbr_fns),
24214 priv_(new priv(is_struct, bases))
24215{
24217 set_is_anonymous(is_anonymous);
24218}
24219
24220/// A constructor for instances of class_decl.
24221///
24222/// @param env the environment we are operating from.
24223///
24224/// @param name the name of the class.
24225///
24226/// @param size_in_bits the size of an instance of class_decl, expressed
24227/// in bits
24228///
24229/// @param align_in_bits the alignment of an instance of class_decl,
24230/// expressed in bits.
24231///
24232/// @param locus the source location of declaration point this class.
24233///
24234/// @param vis the visibility of instances of class_decl.
24235class_decl::class_decl(const environment& env, const string& name,
24236 size_t size_in_bits, size_t align_in_bits,
24237 bool is_struct, const location& locus,
24238 visibility vis)
24239 : type_or_decl_base(env,
24240 CLASS_TYPE
24241 | ABSTRACT_TYPE_BASE
24242 | ABSTRACT_DECL_BASE
24243 | ABSTRACT_SCOPE_TYPE_DECL
24244 | ABSTRACT_SCOPE_DECL),
24245 decl_base(env, name, locus, name, vis),
24246 type_base(env, size_in_bits, align_in_bits),
24247 class_or_union(env, name, size_in_bits, align_in_bits,
24248 locus, vis),
24249 priv_(new priv(is_struct))
24250{
24252}
24253
24254/// A constructor for instances of @ref class_decl.
24255///
24256/// @param env the environment we are operating from.
24257///
24258/// @param name the name of the class.
24259///
24260/// @param size_in_bits the size of an instance of class_decl, expressed
24261/// in bits
24262///
24263/// @param align_in_bits the alignment of an instance of class_decl,
24264/// expressed in bits.
24265///
24266/// @param locus the source location of declaration point this class.
24267///
24268/// @param vis the visibility of instances of class_decl.
24269///
24270/// @param is_anonymous whether the newly created instance is
24271/// anonymous.
24272class_decl:: class_decl(const environment& env, const string& name,
24273 size_t size_in_bits, size_t align_in_bits,
24274 bool is_struct, const location& locus,
24275 visibility vis, bool is_anonymous)
24276 : type_or_decl_base(env,
24277 CLASS_TYPE
24278 | ABSTRACT_TYPE_BASE
24279 | ABSTRACT_DECL_BASE
24280 | ABSTRACT_SCOPE_TYPE_DECL
24281 | ABSTRACT_SCOPE_DECL),
24282 decl_base(env, name, locus,
24283 // If the class is anonymous then by default it won't
24284 // have a linkage name. Also, the anonymous class does
24285 // have an internal-only unique name that is generally
24286 // not taken into account when comparing classes; such a
24287 // unique internal-only name, when used as a linkage
24288 // name might introduce spurious comparison false
24289 // negatives.
24290 /*linkage_name=*/ is_anonymous ? string() : name,
24291 vis),
24292 type_base(env, size_in_bits, align_in_bits),
24293 class_or_union(env, name, size_in_bits, align_in_bits,
24294 locus, vis),
24295 priv_(new priv(is_struct))
24296{
24298 set_is_anonymous(is_anonymous);
24299}
24300
24301/// A constuctor for instances of class_decl that represent a
24302/// declaration without definition.
24303///
24304/// @param env the environment we are operating from.
24305///
24306/// @param name the name of the class.
24307///
24308/// @param is_declaration_only a boolean saying whether the instance
24309/// represents a declaration only, or not.
24310class_decl::class_decl(const environment& env, const string& name,
24311 bool is_struct, bool is_declaration_only)
24312 : type_or_decl_base(env,
24313 CLASS_TYPE
24314 | ABSTRACT_TYPE_BASE
24315 | ABSTRACT_DECL_BASE
24316 | ABSTRACT_SCOPE_TYPE_DECL
24317 | ABSTRACT_SCOPE_DECL),
24318 decl_base(env, name, location(), name),
24319 type_base(env, 0, 0),
24320 class_or_union(env, name, is_declaration_only),
24321 priv_(new priv(is_struct))
24322{
24324}
24325
24326/// This method is invoked automatically right after the current
24327/// instance of @ref class_decl has been canonicalized.
24328///
24329/// Currently, the only thing it does is to sort the virtual member
24330/// functions vector.
24331void
24333{
24335
24336 for (class_decl::virtual_mem_fn_map_type::iterator i =
24337 priv_->virtual_mem_fns_map_.begin();
24338 i != priv_->virtual_mem_fns_map_.end();
24339 ++i)
24340 sort_virtual_member_functions(i->second);
24341}
24342
24343/// Set the "is-struct" flag of the class.
24344///
24345/// @param f the new value of the flag.
24346void
24348{priv_->is_struct_ = f;}
24349
24350/// Test if the class is a struct.
24351///
24352/// @return true iff the class is a struct.
24353bool
24355{return priv_->is_struct_;}
24356
24357/// Add a base specifier to this class.
24358///
24359/// @param b the new base specifier.
24360void
24362{
24363 priv_->bases_.push_back(b);
24364 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
24365}
24366
24367/// Get the base specifiers for this class.
24368///
24369/// @return a vector of the base specifiers.
24372{return priv_->bases_;}
24373
24374/// Find a base class of a given qualified name for the current class.
24375///
24376/// @param qualified_name the qualified name of the base class to look for.
24377///
24378/// @return a pointer to the @ref class_decl that represents the base
24379/// class of name @p qualified_name, if found.
24381class_decl::find_base_class(const string& qualified_name) const
24382{
24383 unordered_map<string, base_spec_sptr>::iterator i =
24384 priv_->bases_map_.find(qualified_name);
24385
24386 if (i != priv_->bases_map_.end())
24387 return i->second->get_base_class();
24388
24389 return class_decl_sptr();
24390}
24391
24392/// Get the virtual member functions of this class.
24393///
24394/// @param return a vector of the virtual member functions of this
24395/// class.
24398{return priv_->virtual_mem_fns_;}
24399
24400/// Get the map that associates a virtual table offset to the virtual
24401/// member functions with that virtual table offset.
24402///
24403/// Usually, there should be a 1:1 mapping between a given vtable
24404/// offset and virtual member functions of that vtable offset. But
24405/// because of some implementation details, there can be several C++
24406/// destructor functions that are *generated* by compilers, for a
24407/// given destructor that is defined in the source code. If the
24408/// destructor is virtual then those generated functions have some
24409/// DWARF attributes in common with the constructor that the user
24410/// actually defined in its source code. Among those attributes are
24411/// the vtable offset of the destructor.
24412///
24413/// @return the map that associates a virtual table offset to the
24414/// virtual member functions with that virtual table offset.
24417{return priv_->virtual_mem_fns_map_;}
24418
24419/// Sort the virtual member functions by their virtual index.
24420void
24422{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
24423
24424/// Getter of the pretty representation of the current instance of
24425/// @ref class_decl.
24426///
24427/// @param internal set to true if the call is intended to get a
24428/// representation of the decl (or type) for the purpose of canonical
24429/// type comparison. This is mainly used in the function
24430/// type_base::get_canonical_type_for().
24431///
24432/// In other words if the argument for this parameter is true then the
24433/// call is meant for internal use (for technical use inside the
24434/// library itself), false otherwise. If you don't know what this is
24435/// for, then set it to false.
24436///
24437/// @param qualified_name if true, names emitted in the pretty
24438/// representation are fully qualified.
24439///
24440/// @return the pretty representaion for a class_decl.
24441string
24443 bool qualified_name) const
24444{
24445 string cl = "class ";
24446 if (!internal && is_struct())
24447 cl = "struct ";
24448
24449 // When computing the pretty representation for internal purposes,
24450 // if an anonymous class is named by a typedef, then consider that
24451 // it has a name, which is the typedef name.
24452 if (get_is_anonymous())
24453 {
24454 if (internal && !get_name().empty())
24455 return cl + get_type_name(this, qualified_name, /*internal=*/true);
24457 /*one_line=*/true,
24458 internal);
24459
24460 }
24461
24462 string result = cl;
24463 if (qualified_name)
24464 result += get_qualified_name(internal);
24465 else
24466 result += get_name();
24467
24468 return result;
24469}
24470
24471decl_base_sptr
24472class_decl::insert_member_decl(decl_base_sptr d)
24473{
24474 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24475 add_member_function(f, public_access,
24476 /*is_virtual=*/false,
24477 /*vtable_offset=*/0,
24478 /*is_static=*/false,
24479 /*is_ctor=*/false,
24480 /*is_dtor=*/false,
24481 /*is_const=*/false);
24482 else
24484
24485 return d;
24486}
24487
24488/// The private data structure of class_decl::base_spec.
24489struct class_decl::base_spec::priv
24490{
24491 class_decl_wptr base_class_;
24492 long offset_in_bits_;
24493 bool is_virtual_;
24494
24495 priv(const class_decl_sptr& cl,
24496 long offset_in_bits,
24497 bool is_virtual)
24498 : base_class_(cl),
24499 offset_in_bits_(offset_in_bits),
24500 is_virtual_(is_virtual)
24501 {}
24502};
24503
24504/// Constructor for base_spec instances.
24505///
24506/// @param base the base class to consider
24507///
24508/// @param a the access specifier of the base class.
24509///
24510/// @param offset_in_bits if positive or null, represents the offset
24511/// of the base in the layout of its containing type.. If negative,
24512/// means that the current base is not laid out in its containing type.
24513///
24514/// @param is_virtual if true, means that the current base class is
24515/// virtual in it's containing type.
24516class_decl::base_spec::base_spec(const class_decl_sptr& base,
24518 long offset_in_bits,
24519 bool is_virtual)
24520 : type_or_decl_base(base->get_environment(),
24521 ABSTRACT_DECL_BASE),
24522 decl_base(base->get_environment(), base->get_name(), base->get_location(),
24523 base->get_linkage_name(), base->get_visibility()),
24524 member_base(a),
24525 priv_(new priv(base, offset_in_bits, is_virtual))
24526{
24528 set_qualified_name(base->get_qualified_name());
24529}
24530
24531/// Get the base class referred to by the current base class
24532/// specifier.
24533///
24534/// @return the base class.
24537{return priv_->base_class_.lock();}
24538
24539/// Getter of the "is-virtual" proprerty of the base class specifier.
24540///
24541/// @return true iff this specifies a virtual base class.
24542bool
24544{return priv_->is_virtual_;}
24545
24546/// Getter of the offset of the base.
24547///
24548/// @return the offset of the base.
24549long
24551{return priv_->offset_in_bits_;}
24552
24553/// Calculate the hash value for a class_decl::base_spec.
24554///
24555/// @return the hash value.
24556size_t
24558{
24560 return h(*this);
24561}
24562
24563/// Traverses an instance of @ref class_decl::base_spec, visiting all
24564/// the sub-types and decls that it might contain.
24565///
24566/// @param v the visitor that is used to visit every IR sub-node of
24567/// the current node.
24568///
24569/// @return true if either
24570/// - all the children nodes of the current IR node were traversed
24571/// and the calling code should keep going with the traversing.
24572/// - or the current IR node is already being traversed.
24573/// Otherwise, returning false means that the calling code should not
24574/// keep traversing the tree.
24575bool
24577{
24578 if (visiting())
24579 return true;
24580
24581 if (v.visit_begin(this))
24582 {
24583 visiting(true);
24584 get_base_class()->traverse(v);
24585 visiting(false);
24586 }
24587
24588 return v.visit_end(this);
24589}
24590
24591/// Constructor for base_spec instances.
24592///
24593/// Note that this constructor is for clients that don't support RTTI
24594/// and that have a base class of type_base, but of dynamic type
24595/// class_decl.
24596///
24597/// @param base the base class to consider. Must be a pointer to an
24598/// instance of class_decl
24599///
24600/// @param a the access specifier of the base class.
24601///
24602/// @param offset_in_bits if positive or null, represents the offset
24603/// of the base in the layout of its containing type.. If negative,
24604/// means that the current base is not laid out in its containing type.
24605///
24606/// @param is_virtual if true, means that the current base class is
24607/// virtual in it's containing type.
24608class_decl::base_spec::base_spec(const type_base_sptr& base,
24610 long offset_in_bits,
24611 bool is_virtual)
24613 ABSTRACT_DECL_BASE),
24618 member_base(a),
24619 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
24620 offset_in_bits,
24621 is_virtual))
24622{
24624}
24625
24626class_decl::base_spec::~base_spec() = default;
24627
24628/// Compares two instances of @ref class_decl::base_spec.
24629///
24630/// If the two intances are different, set a bitfield to give some
24631/// insight about the kind of differences there are.
24632///
24633/// @param l the first artifact of the comparison.
24634///
24635/// @param r the second artifact of the comparison.
24636///
24637/// @param k a pointer to a bitfield that gives information about the
24638/// kind of changes there are between @p l and @p r. This one is set
24639/// iff @p k is non-null and the function returns false.
24640///
24641/// Please note that setting k to a non-null value does have a
24642/// negative performance impact because even if @p l and @p r are not
24643/// equal, the function keeps up the comparison in order to determine
24644/// the different kinds of ways in which they are different.
24645///
24646/// @return true if @p l equals @p r, false otherwise.
24647bool
24649 const class_decl::base_spec& r,
24650 change_kind* k)
24651{
24652 if (!l.member_base::operator==(r))
24653 {
24654 if (k)
24657 }
24658
24660}
24661
24662/// Comparison operator for @ref class_decl::base_spec.
24663///
24664/// @param other the instance of @ref class_decl::base_spec to compare
24665/// against.
24666///
24667/// @return true if the current instance of @ref class_decl::base_spec
24668/// equals @p other.
24669bool
24671{
24672 const class_decl::base_spec* o =
24673 dynamic_cast<const class_decl::base_spec*>(&other);
24674
24675 if (!o)
24676 return false;
24677
24678 return equals(*this, *o, 0);
24679}
24680
24681/// Comparison operator for @ref class_decl::base_spec.
24682///
24683/// @param other the instance of @ref class_decl::base_spec to compare
24684/// against.
24685///
24686/// @return true if the current instance of @ref class_decl::base_spec
24687/// equals @p other.
24688bool
24690{
24691 const class_decl::base_spec* o =
24692 dynamic_cast<const class_decl::base_spec*>(&other);
24693 if (!o)
24694 return false;
24695
24696 return operator==(static_cast<const decl_base&>(*o));
24697}
24698
24699mem_fn_context_rel::~mem_fn_context_rel()
24700{
24701}
24702
24703/// A constructor for instances of method_decl.
24704///
24705/// @param name the name of the method.
24706///
24707/// @param type the type of the method.
24708///
24709/// @param declared_inline whether the method was
24710/// declared inline or not.
24711///
24712/// @param locus the source location of the method.
24713///
24714/// @param linkage_name the mangled name of the method.
24715///
24716/// @param vis the visibility of the method.
24717///
24718/// @param bind the binding of the method.
24719method_decl::method_decl(const string& name,
24720 method_type_sptr type,
24721 bool declared_inline,
24722 const location& locus,
24723 const string& linkage_name,
24724 visibility vis,
24725 binding bind)
24727 METHOD_DECL
24728 | ABSTRACT_DECL_BASE
24729 |FUNCTION_DECL),
24730 decl_base(type->get_environment(), name, locus, linkage_name, vis),
24731 function_decl(name, static_pointer_cast<function_type>(type),
24732 declared_inline, locus, linkage_name, vis, bind)
24733{
24735 set_context_rel(new mem_fn_context_rel(0));
24736 set_member_function_is_const(*this, type->get_is_const());
24737}
24738
24739/// A constructor for instances of method_decl.
24740///
24741/// @param name the name of the method.
24742///
24743/// @param type the type of the method. Must be an instance of
24744/// method_type.
24745///
24746/// @param declared_inline whether the method was
24747/// declared inline or not.
24748///
24749/// @param locus the source location of the method.
24750///
24751/// @param linkage_name the mangled name of the method.
24752///
24753/// @param vis the visibility of the method.
24754///
24755/// @param bind the binding of the method.
24756method_decl::method_decl(const string& name,
24757 function_type_sptr type,
24758 bool declared_inline,
24759 const location& locus,
24760 const string& linkage_name,
24761 visibility vis,
24762 binding bind)
24763 : type_or_decl_base(type->get_environment(),
24764 METHOD_DECL
24765 | ABSTRACT_DECL_BASE
24766 | FUNCTION_DECL),
24767 decl_base(type->get_environment(), name, locus, linkage_name, vis),
24768 function_decl(name, static_pointer_cast<function_type>
24769 (dynamic_pointer_cast<method_type>(type)),
24770 declared_inline, locus, linkage_name, vis, bind)
24771{
24773 set_context_rel(new mem_fn_context_rel(0));
24774}
24775
24776/// A constructor for instances of method_decl.
24777///
24778/// @param name the name of the method.
24779///
24780/// @param type the type of the method. Must be an instance of
24781/// method_type.
24782///
24783/// @param declared_inline whether the method was
24784/// declared inline or not.
24785///
24786/// @param locus the source location of the method.
24787///
24788/// @param linkage_name the mangled name of the method.
24789///
24790/// @param vis the visibility of the method.
24791///
24792/// @param bind the binding of the method.
24793method_decl::method_decl(const string& name,
24794 type_base_sptr type,
24795 bool declared_inline,
24796 const location& locus,
24797 const string& linkage_name,
24798 visibility vis,
24799 binding bind)
24800 : type_or_decl_base(type->get_environment(),
24801 METHOD_DECL
24802 | ABSTRACT_DECL_BASE
24803 | FUNCTION_DECL),
24804 decl_base(type->get_environment(), name, locus, linkage_name, vis),
24805 function_decl(name, static_pointer_cast<function_type>
24806 (dynamic_pointer_cast<method_type>(type)),
24807 declared_inline, locus, linkage_name, vis, bind)
24808{
24810 set_context_rel(new mem_fn_context_rel(0));
24811}
24812
24813/// Set the linkage name of the method.
24814///
24815/// @param l the new linkage name of the method.
24816void
24818{
24819 string old_lname = get_linkage_name();
24821 // Update the linkage_name -> member function map of the containing
24822 // class declaration.
24823 if (!l.empty())
24824 {
24826 class_or_union_sptr cl = t->get_class_type();
24827 method_decl_sptr m(this, sptr_utils::noop_deleter());
24828 cl->priv_->mem_fns_map_[l] = m;
24829 if (!old_lname.empty() && l != old_lname)
24830 {
24831 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
24832 {
24833 ABG_ASSERT(m.get() == this);
24834 cl->priv_->mem_fns_map_.erase(old_lname);
24835 }
24836 }
24837 }
24838}
24839
24840method_decl::~method_decl()
24841{}
24842
24843const method_type_sptr
24845{
24846 method_type_sptr result;
24848 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
24849 return result;
24850}
24851
24852/// Set the containing class of a method_decl.
24853///
24854/// @param scope the new containing class_decl.
24855void
24856method_decl::set_scope(scope_decl* scope)
24857{
24858 if (!get_context_rel())
24859 set_context_rel(new mem_fn_context_rel(scope));
24860 else
24861 get_context_rel()->set_scope(scope);
24862}
24863
24864/// Equality operator for @ref method_decl_sptr.
24865///
24866/// This is a deep equality operator, as it compares the @ref
24867/// method_decl that is pointed-to by the smart pointer.
24868///
24869/// @param l the left-hand side argument of the equality operator.
24870///
24871/// @param r the righ-hand side argument of the equality operator.
24872///
24873/// @return true iff @p l equals @p r.
24874bool
24875operator==(const method_decl_sptr& l, const method_decl_sptr& r)
24876{
24877 if (l.get() == r.get())
24878 return true;
24879 if (!!l != !!r)
24880 return false;
24881
24882 return *l == *r;
24883}
24884
24885/// Inequality operator for @ref method_decl_sptr.
24886///
24887/// This is a deep equality operator, as it compares the @ref
24888/// method_decl that is pointed-to by the smart pointer.
24889///
24890/// @param l the left-hand side argument of the equality operator.
24891///
24892/// @param r the righ-hand side argument of the equality operator.
24893///
24894/// @return true iff @p l differs from @p r.
24895bool
24896operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
24897{return !operator==(l, r);}
24898
24899/// Test if a function_decl is actually a method_decl.
24900///
24901///@param d the @ref function_decl to consider.
24902///
24903/// @return the method_decl sub-object of @p d if inherits
24904/// a method_decl type.
24907{
24908 return dynamic_cast<method_decl*>
24909 (const_cast<type_or_decl_base*>(d));
24910}
24911
24912/// Test if a function_decl is actually a method_decl.
24913///
24914///@param d the @ref function_decl to consider.
24915///
24916/// @return the method_decl sub-object of @p d if inherits
24917/// a method_decl type.
24920{return is_method_decl(&d);}
24921
24922/// Test if a function_decl is actually a method_decl.
24923///
24924///@param d the @ref function_decl to consider.
24925///
24926/// @return the method_decl sub-object of @p d if inherits
24927/// a method_decl type.
24928method_decl_sptr
24930{return dynamic_pointer_cast<method_decl>(d);}
24931
24932/// A "less than" functor to sort a vector of instances of
24933/// method_decl that are virtual.
24934struct virtual_member_function_less_than
24935{
24936 /// The less than operator. First, it sorts the methods by their
24937 /// vtable index. If they have the same vtable index, it sorts them
24938 /// by the name of their ELF symbol. If they don't have elf
24939 /// symbols, it sorts them by considering their pretty
24940 /// representation.
24941 ///
24942 /// Note that this method expects virtual methods.
24943 ///
24944 /// @param f the first method to consider.
24945 ///
24946 /// @param s the second method to consider.
24947 ///
24948 /// @return true if method @p is less than method @s.
24949 bool
24950 operator()(const method_decl& f,
24951 const method_decl& s)
24952 {
24955
24956 ssize_t f_offset = get_member_function_vtable_offset(f);
24957 ssize_t s_offset = get_member_function_vtable_offset(s);
24958 if (f_offset != s_offset) return f_offset < s_offset;
24959
24960 string fn, sn;
24961 // Try the linkage names (important for destructors).
24962 fn = f.get_linkage_name();
24963 sn = s.get_linkage_name();
24964 if (fn != sn) return fn < sn;
24965
24966 // If the functions have symbols, then compare their symbol-id
24967 // string.
24968 elf_symbol_sptr f_sym = f.get_symbol();
24969 elf_symbol_sptr s_sym = s.get_symbol();
24970 if ((!f_sym) != (!s_sym)) return !f_sym;
24971 if (f_sym && s_sym)
24972 {
24973 fn = f_sym->get_id_string();
24974 sn = s_sym->get_id_string();
24975 if (fn != sn) return fn < sn;
24976 }
24977
24978 // None of the functions have symbols or linkage names that
24979 // distinguish them, so compare their pretty representation.
24982 if (fn != sn) return fn < sn;
24983
24984 /// If it's just the file paths that are different then sort them
24985 /// too.
24986 string fn_filepath, sn_filepath;
24987 unsigned line = 0, column = 0;
24988 location fn_loc = f.get_location(), sn_loc = s.get_location();
24989 if (fn_loc)
24990 fn_loc.expand(fn_filepath, line, column);
24991 if (sn_loc)
24992 sn_loc.expand(sn_filepath, line, column);
24993 return fn_filepath < sn_filepath;
24994 }
24995
24996 /// The less than operator. First, it sorts the methods by their
24997 /// vtable index. If they have the same vtable index, it sorts them
24998 /// by the name of their ELF symbol. If they don't have elf
24999 /// symbols, it sorts them by considering their pretty
25000 /// representation.
25001 ///
25002 /// Note that this method expects to take virtual methods.
25003 ///
25004 /// @param f the first method to consider.
25005 ///
25006 /// @param s the second method to consider.
25007 bool
25008 operator()(const method_decl_sptr f,
25009 const method_decl_sptr s)
25010 {return operator()(*f, *s);}
25011}; // end struct virtual_member_function_less_than
25012
25013/// Sort a vector of instances of virtual member functions.
25014///
25015/// @param mem_fns the vector of member functions to sort.
25016static void
25017sort_virtual_member_functions(class_decl::member_functions& mem_fns)
25018{
25019 virtual_member_function_less_than lt;
25020 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25021}
25022
25023/// Add a member function to the current instance of @ref class_or_union.
25024///
25025/// @param f a method_decl to add to the current class. This function
25026/// should not have been already added to a scope.
25027///
25028/// @param access the access specifier for the member function to add.
25029///
25030/// @param is_virtual if this is true then it means the function @p f
25031/// is a virtual function. That also means that the current instance
25032/// of @ref class_or_union is actually an instance of @ref class_decl.
25033///
25034/// @param vtable_offset the offset of the member function in the
25035/// virtual table. This parameter is taken into account only if @p
25036/// is_virtual is true.
25037///
25038/// @param is_static whether the member function is static.
25039///
25040/// @param is_ctor whether the member function is a constructor.
25041///
25042/// @param is_dtor whether the member function is a destructor.
25043///
25044/// @param is_const whether the member function is const.
25045void
25048 bool is_virtual,
25049 size_t vtable_offset,
25050 bool is_static, bool is_ctor,
25051 bool is_dtor, bool is_const)
25052{
25053 add_member_function(f, a, is_static, is_ctor,
25054 is_dtor, is_const);
25055
25056 if (class_decl* klass = is_class_type(this))
25057 {
25058 set_member_function_is_virtual(f, is_virtual);
25059 if (is_virtual)
25060 {
25061 set_member_function_vtable_offset(f, vtable_offset);
25062 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
25063 }
25064 }
25065}
25066
25067/// When a virtual member function has seen its virtualness set by
25068/// set_member_function_is_virtual(), this function ensures that the
25069/// member function is added to the specific vectors and maps of
25070/// virtual member function of its class.
25071///
25072/// @param method the method to fixup.
25073void
25074fixup_virtual_member_function(method_decl_sptr method)
25075{
25076 if (!method || !get_member_function_is_virtual(method))
25077 return;
25078
25079 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
25080
25081 class_decl::member_functions::const_iterator m;
25082 for (m = klass->priv_->virtual_mem_fns_.begin();
25083 m != klass->priv_->virtual_mem_fns_.end();
25084 ++m)
25085 if (m->get() == method.get()
25086 || (*m)->get_linkage_name() == method->get_linkage_name())
25087 break;
25088 if (m == klass->priv_->virtual_mem_fns_.end())
25089 klass->priv_->virtual_mem_fns_.push_back(method);
25090
25091 // Build or udpate the map that associates a vtable offset to the
25092 // number of virtual member functions that "point" to it.
25093 ssize_t voffset = get_member_function_vtable_offset(method);
25094 if (voffset == -1)
25095 return;
25096
25097 class_decl::virtual_mem_fn_map_type::iterator i =
25098 klass->priv_->virtual_mem_fns_map_.find(voffset);
25099 if (i == klass->priv_->virtual_mem_fns_map_.end())
25100 {
25101 class_decl::member_functions virtual_mem_fns_at_voffset;
25102 virtual_mem_fns_at_voffset.push_back(method);
25103 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
25104 }
25105 else
25106 {
25107 for (m = i->second.begin() ; m != i->second.end(); ++m)
25108 if (m->get() == method.get()
25109 || (*m)->get_linkage_name() == method->get_linkage_name())
25110 break;
25111 if (m == i->second.end())
25112 i->second.push_back(method);
25113 }
25114}
25115
25116/// Return true iff the class has no entity in its scope.
25117bool
25119{return priv_->bases_.empty() && has_no_member();}
25120
25121/// Test if the current instance of @ref class_decl has virtual member
25122/// functions.
25123///
25124/// @return true iff the current instance of @ref class_decl has
25125/// virtual member functions.
25126bool
25128{return !get_virtual_mem_fns().empty();}
25129
25130/// Test if the current instance of @ref class_decl has at least one
25131/// virtual base.
25132///
25133/// @return true iff the current instance of @ref class_decl has a
25134/// virtual member function.
25135bool
25137{
25138 for (base_specs::const_iterator b = get_base_specifiers().begin();
25139 b != get_base_specifiers().end();
25140 ++b)
25141 if ((*b)->get_is_virtual()
25142 || (*b)->get_base_class()->has_virtual_bases())
25143 return true;
25144
25145 return false;
25146}
25147
25148/// Test if the current instance has a vtable.
25149///
25150/// This is only valid for a C++ program.
25151///
25152/// Basically this function checks if the class has either virtual
25153/// functions, or virtual bases.
25154bool
25156{
25158 || has_virtual_bases())
25159 return true;
25160 return false;
25161}
25162
25163/// Get the highest vtable offset of all the virtual methods of the
25164/// class.
25165///
25166/// @return the highest vtable offset of all the virtual methods of
25167/// the class.
25168ssize_t
25170{
25171 ssize_t offset = -1;
25172 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
25173 get_virtual_mem_fns_map().begin();
25174 e != get_virtual_mem_fns_map().end();
25175 ++e)
25176 if (e->first > offset)
25177 offset = e->first;
25178
25179 return offset;
25180}
25181
25182/// Return the hash value for the current instance.
25183///
25184/// @return the hash value.
25185size_t
25187{
25188 class_decl::hash hash_class;
25189 return hash_class(this);
25190}
25191
25192/// Test if two methods are equal without taking their symbol or
25193/// linkage name into account.
25194///
25195/// @param f the first method.
25196///
25197/// @param s the second method.
25198///
25199/// @return true iff @p f equals @p s without taking their linkage
25200/// name or symbol into account.
25201static bool
25202methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
25203 const method_decl_sptr& s)
25204{
25205 method_decl_sptr first = f, second = s;
25206 elf_symbol_sptr saved_first_elf_symbol =
25207 first->get_symbol();
25208 elf_symbol_sptr saved_second_elf_symbol =
25209 second->get_symbol();
25210 interned_string saved_first_linkage_name =
25211 first->get_linkage_name();
25212 interned_string saved_second_linkage_name =
25213 second->get_linkage_name();
25214
25215 first->set_symbol(elf_symbol_sptr());
25216 first->set_linkage_name("");
25217 second->set_symbol(elf_symbol_sptr());
25218 second->set_linkage_name("");
25219
25220 bool equal = *first == *second;
25221
25222 first->set_symbol(saved_first_elf_symbol);
25223 first->set_linkage_name(saved_first_linkage_name);
25224 second->set_symbol(saved_second_elf_symbol);
25225 second->set_linkage_name(saved_second_linkage_name);
25226
25227 return equal;
25228}
25229
25230/// Test if a given method is equivalent to at least of other method
25231/// that is in a vector of methods.
25232///
25233/// Note that "equivalent" here means being equal without taking the
25234/// linkage name or the symbol of the methods into account.
25235///
25236/// This is a sub-routine of the 'equals' function that compares @ref
25237/// class_decl.
25238///
25239/// @param method the method to compare.
25240///
25241/// @param fns the vector of functions to compare @p method against.
25242///
25243/// @return true iff @p is equivalent to at least one method in @p
25244/// fns.
25245static bool
25246method_matches_at_least_one_in_vector(const method_decl_sptr& method,
25248{
25249 for (class_decl::member_functions::const_iterator i = fns.begin();
25250 i != fns.end();
25251 ++i)
25252 // Note that the comparison must be done in this order: method ==
25253 // *i This is to keep the consistency of the comparison. It's
25254 // important especially when doing type canonicalization. The
25255 // already canonicalize type is the left operand, and the type
25256 // being canonicalized is the right operand. This comes from the
25257 // code in type_base::get_canonical_type_for().
25258 if (methods_equal_modulo_elf_symbol(method, *i))
25259 return true;
25260
25261 return false;
25262}
25263
25264/// Cancel the canonical type that was propagated.
25265///
25266/// If we are in the process of comparing a type for the purpose of
25267/// canonicalization, and if that type has been the target of the
25268/// canonical type propagation optimization, then clear the propagated
25269/// canonical type. See @ref OnTheFlyCanonicalization for more about
25270/// the canonical type optimization
25271///
25272/// @param t the type to consider.
25273static bool
25274maybe_cancel_propagated_canonical_type(const class_or_union& t)
25275{
25276 const environment& env = t.get_environment();
25277 if (env.do_on_the_fly_canonicalization())
25278 if (is_type(&t)->priv_->canonical_type_propagated())
25279 {
25280 is_type(&t)->priv_->clear_propagated_canonical_type();
25281 env.priv_->remove_from_types_with_non_confirmed_propagated_ct(&t);
25282 return true;
25283 }
25284 return false;
25285}
25286
25287/// Compares two instances of @ref class_decl.
25288///
25289/// If the two intances are different, set a bitfield to give some
25290/// insight about the kind of differences there are.
25291///
25292/// @param l the first artifact of the comparison.
25293///
25294/// @param r the second artifact of the comparison.
25295///
25296/// @param k a pointer to a bitfield that gives information about the
25297/// kind of changes there are between @p l and @p r. This one is set
25298/// iff @p k is non-null and the function returns false.
25299///
25300/// Please note that setting k to a non-null value does have a
25301/// negative performance impact because even if @p l and @p r are not
25302/// equal, the function keeps up the comparison in order to determine
25303/// the different kinds of ways in which they are different.
25304///
25305/// @return true if @p l equals @p r, false otherwise.
25306bool
25308{
25309 {
25310 // First of all, let's see if these two types haven't already been
25311 // compared. If so, and if the result of the comparison has been
25312 // cached, let's just re-use it, rather than comparing them all
25313 // over again.
25314 bool result = false;
25315 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
25316 ABG_RETURN(result);
25317 }
25318
25319 // if one of the classes is declaration-only then we take a fast
25320 // path here.
25322 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
25323 static_cast<const class_or_union&>(r),
25324 k));
25325
25326 bool had_canonical_type = !!r.get_naked_canonical_type();
25327 bool result = true;
25328 if (!equals(static_cast<const class_or_union&>(l),
25329 static_cast<const class_or_union&>(r),
25330 k))
25331 {
25332 result = false;
25333 if (!k)
25334 ABG_RETURN(result);
25335 }
25336
25337 // If comparing the class_or_union 'part' of the type led to
25338 // canonical type propagation, then cancel that because it's too
25339 // early to do that at this point. We still need to compare bases
25340 // virtual members.
25341 if (!had_canonical_type)
25342 maybe_cancel_propagated_canonical_type(r);
25343
25345
25347
25348#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
25349
25350 // Compare bases.
25351 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
25352 {
25353 result = false;
25354 if (k)
25356 else
25357 RETURN(result);
25358 }
25359
25360 for (class_decl::base_specs::const_iterator
25361 b0 = l.get_base_specifiers().begin(),
25362 b1 = r.get_base_specifiers().begin();
25363 (b0 != l.get_base_specifiers().end()
25364 && b1 != r.get_base_specifiers().end());
25365 ++b0, ++b1)
25366 if (*b0 != *b1)
25367 {
25368 result = false;
25369 if (k)
25370 {
25371 if (!types_have_similar_structure((*b0)->get_base_class().get(),
25372 (*b1)->get_base_class().get()))
25374 else
25375 *k |= SUBTYPE_CHANGE_KIND;
25376 break;
25377 }
25378 RETURN(result);
25379 }
25380
25381 // Compare virtual member functions
25382
25383 // We look at the map that associates a given vtable offset to a
25384 // vector of virtual member functions that point to that offset.
25385 //
25386 // This is because there are cases where several functions can
25387 // point to the same virtual table offset.
25388 //
25389 // This is usually the case for virtual destructors. Even though
25390 // there can be only one virtual destructor declared in source
25391 // code, there are actually potentially up to three generated
25392 // functions for that destructor. Some of these generated
25393 // functions can be clones of other functions that are among those
25394 // generated ones. In any cases, they all have the same
25395 // properties, including the vtable offset property.
25396
25397 // So, there should be the same number of different vtable
25398 // offsets, the size of two maps must be equals.
25399 if (l.get_virtual_mem_fns_map().size()
25400 != r.get_virtual_mem_fns_map().size())
25401 {
25402 result = false;
25403 if (k)
25405 else
25406 RETURN(result);
25407 }
25408
25409 // Then, each virtual member function of a given vtable offset in
25410 // the first class type, must match an equivalent virtual member
25411 // function of a the same vtable offset in the second class type.
25412 //
25413 // By "match", I mean that the two virtual member function should
25414 // be equal if we don't take into account their symbol name or
25415 // their linkage name. This is because two destructor functions
25416 // clones (for instance) might have different linkage name, but
25417 // are still equivalent if their other properties are the same.
25418 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
25419 l.get_virtual_mem_fns_map().begin();
25420 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
25421 ++first_v_fn_entry)
25422 {
25423 unsigned voffset = first_v_fn_entry->first;
25424 const class_decl::member_functions& first_vfns =
25425 first_v_fn_entry->second;
25426
25427 const class_decl::virtual_mem_fn_map_type::const_iterator
25428 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
25429
25430 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
25431 {
25432 result = false;
25433 if (k)
25435 RETURN(result);
25436 }
25437
25438 const class_decl::member_functions& second_vfns =
25439 second_v_fn_entry->second;
25440
25441 bool matches = false;
25442 for (class_decl::member_functions::const_iterator i =
25443 first_vfns.begin();
25444 i != first_vfns.end();
25445 ++i)
25446 if (method_matches_at_least_one_in_vector(*i, second_vfns))
25447 {
25448 matches = true;
25449 break;
25450 }
25451
25452 if (!matches)
25453 {
25454 result = false;
25455 if (k)
25456 *k |= SUBTYPE_CHANGE_KIND;
25457 else
25458 RETURN(result);
25459 }
25460 }
25461
25462 RETURN(result);
25463#undef RETURN
25464}
25465
25466/// Copy a method of a class into a new class.
25467///
25468/// @param klass the class into which the method is to be copied.
25469///
25470/// @param method the method to copy into @p klass.
25471///
25472/// @return the resulting newly copied method.
25473method_decl_sptr
25474copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
25475{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
25476
25477/// Copy a method of a class into a new class.
25478///
25479/// @param klass the class into which the method is to be copied.
25480///
25481/// @param method the method to copy into @p klass.
25482///
25483/// @return the resulting newly copied method.
25484method_decl_sptr
25486{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
25487
25488/// Comparison operator for @ref class_decl.
25489///
25490/// @param other the instance of @ref class_decl to compare against.
25491///
25492/// @return true iff the current instance of @ref class_decl equals @p
25493/// other.
25494bool
25496{
25497 const class_decl* op = is_class_type(&other);
25498 if (!op)
25499 return false;
25500
25501 // If this is a decl-only type (and thus with no canonical type),
25502 // use the canonical type of the definition, if any.
25503 const class_decl *l = 0;
25505 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
25506 if (l == 0)
25507 l = this;
25508
25509 ABG_ASSERT(l);
25510
25511 // Likewise for the other type.
25512 const class_decl *r = 0;
25513 if (op->get_is_declaration_only())
25514 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
25515 if (r == 0)
25516 r = op;
25517
25518 ABG_ASSERT(r);
25519
25520 return try_canonical_compare(l, r);
25521}
25522
25523/// Equality operator for class_decl.
25524///
25525/// Re-uses the equality operator that takes a decl_base.
25526///
25527/// @param other the other class_decl to compare against.
25528///
25529/// @return true iff the current instance equals the other one.
25530bool
25532{
25533 const decl_base* o = is_decl(&other);
25534 if (!o)
25535 return false;
25536 return *this == *o;
25537}
25538
25539/// Equality operator for class_decl.
25540///
25541/// Re-uses the equality operator that takes a decl_base.
25542///
25543/// @param other the other class_decl to compare against.
25544///
25545/// @return true iff the current instance equals the other one.
25546bool
25548{
25549 const decl_base& o = other;
25550 return *this == o;
25551}
25552
25553/// Comparison operator for @ref class_decl.
25554///
25555/// @param other the instance of @ref class_decl to compare against.
25556///
25557/// @return true iff the current instance of @ref class_decl equals @p
25558/// other.
25559bool
25561{
25562 const decl_base& o = other;
25563 return *this == o;
25564}
25565
25566/// Turn equality of shared_ptr of class_decl into a deep equality;
25567/// that is, make it compare the pointed to objects too.
25568///
25569/// @param l the shared_ptr of class_decl on left-hand-side of the
25570/// equality.
25571///
25572/// @param r the shared_ptr of class_decl on right-hand-side of the
25573/// equality.
25574///
25575/// @return true if the class_decl pointed to by the shared_ptrs are
25576/// equal, false otherwise.
25577bool
25579{
25580 if (l.get() == r.get())
25581 return true;
25582 if (!!l != !!r)
25583 return false;
25584
25585 return *l == *r;
25586}
25587
25588/// Turn inequality of shared_ptr of class_decl into a deep equality;
25589/// that is, make it compare the pointed to objects too.
25590///
25591/// @param l the shared_ptr of class_decl on left-hand-side of the
25592/// equality.
25593///
25594/// @param r the shared_ptr of class_decl on right-hand-side of the
25595/// equality.
25596///
25597/// @return true if the class_decl pointed to by the shared_ptrs are
25598/// different, false otherwise.
25599bool
25601{return !operator==(l, r);}
25602
25603/// Turn equality of shared_ptr of class_or_union into a deep
25604/// equality; that is, make it compare the pointed to objects too.
25605///
25606/// @param l the left-hand-side operand of the operator
25607///
25608/// @param r the right-hand-side operand of the operator.
25609///
25610/// @return true iff @p l equals @p r.
25611bool
25612operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
25613{
25614 if (l.get() == r.get())
25615 return true;
25616 if (!!l != !!r)
25617 return false;
25618
25619 return *l == *r;
25620}
25621
25622/// Turn inequality of shared_ptr of class_or_union into a deep
25623/// equality; that is, make it compare the pointed to objects too.
25624///
25625/// @param l the left-hand-side operand of the operator
25626///
25627/// @param r the right-hand-side operand of the operator.
25628///
25629/// @return true iff @p l is different from @p r.
25630bool
25631operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
25632{return !operator==(l, r);}
25633
25634/// This implements the ir_traversable_base::traverse pure virtual
25635/// function.
25636///
25637/// @param v the visitor used on the current instance and on its
25638/// members.
25639///
25640/// @return true if the entire IR node tree got traversed, false
25641/// otherwise.
25642bool
25644{
25645 if (v.type_node_has_been_visited(this))
25646 return true;
25647
25648 if (visiting())
25649 return true;
25650
25651 if (v.visit_begin(this))
25652 {
25653 visiting(true);
25654 bool stop = false;
25655
25656 for (base_specs::const_iterator i = get_base_specifiers().begin();
25657 i != get_base_specifiers().end();
25658 ++i)
25659 {
25660 if (!(*i)->traverse(v))
25661 {
25662 stop = true;
25663 break;
25664 }
25665 }
25666
25667 if (!stop)
25668 for (data_members::const_iterator i = get_data_members().begin();
25669 i != get_data_members().end();
25670 ++i)
25671 if (!(*i)->traverse(v))
25672 {
25673 stop = true;
25674 break;
25675 }
25676
25677 if (!stop)
25678 for (member_functions::const_iterator i= get_member_functions().begin();
25679 i != get_member_functions().end();
25680 ++i)
25681 if (!(*i)->traverse(v))
25682 {
25683 stop = true;
25684 break;
25685 }
25686
25687 if (!stop)
25688 for (member_types::const_iterator i = get_member_types().begin();
25689 i != get_member_types().end();
25690 ++i)
25691 if (!(*i)->traverse(v))
25692 {
25693 stop = true;
25694 break;
25695 }
25696
25697 if (!stop)
25698 for (member_function_templates::const_iterator i =
25700 i != get_member_function_templates().end();
25701 ++i)
25702 if (!(*i)->traverse(v))
25703 {
25704 stop = true;
25705 break;
25706 }
25707
25708 if (!stop)
25709 for (member_class_templates::const_iterator i =
25711 i != get_member_class_templates().end();
25712 ++i)
25713 if (!(*i)->traverse(v))
25714 {
25715 stop = true;
25716 break;
25717 }
25718 visiting(false);
25719 }
25720
25721 bool result = v.visit_end(this);
25723 return result;
25724}
25725
25726/// Destructor of the @ref class_decl type.
25728{delete priv_;}
25729
25730context_rel::~context_rel()
25731{}
25732
25733bool
25734member_base::operator==(const member_base& o) const
25735{
25737 && get_is_static() == o.get_is_static());
25738}
25739
25740/// Equality operator for smart pointers to @ref
25741/// class_decl::base_specs.
25742///
25743/// This compares the pointed-to objects.
25744///
25745/// @param l the first instance to consider.
25746///
25747/// @param r the second instance to consider.
25748///
25749/// @return true iff @p l equals @p r.
25750bool
25753{
25754 if (l.get() == r.get())
25755 return true;
25756 if (!!l != !!r)
25757 return false;
25758
25759 return *l == static_cast<const decl_base&>(*r);
25760}
25761
25762/// Inequality operator for smart pointers to @ref
25763/// class_decl::base_specs.
25764///
25765/// This compares the pointed-to objects.
25766///
25767/// @param l the first instance to consider.
25768///
25769/// @param r the second instance to consider.
25770///
25771/// @return true iff @p l is different from @p r.
25772bool
25775{return !operator==(l, r);}
25776
25777/// Test if an ABI artifact is a class base specifier.
25778///
25779/// @param tod the ABI artifact to consider.
25780///
25781/// @return a pointer to the @ref class_decl::base_spec sub-object of
25782/// @p tod iff it's a class base specifier.
25785{
25786 return dynamic_cast<class_decl::base_spec*>
25787 (const_cast<type_or_decl_base*>(tod));
25788}
25789
25790/// Test if an ABI artifact is a class base specifier.
25791///
25792/// @param tod the ABI artifact to consider.
25793///
25794/// @return a pointer to the @ref class_decl::base_spec sub-object of
25795/// @p tod iff it's a class base specifier.
25798{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
25799
25800bool
25801member_function_template::operator==(const member_base& other) const
25802{
25803 try
25804 {
25805 const member_function_template& o =
25806 dynamic_cast<const member_function_template&>(other);
25807
25808 if (!(is_constructor() == o.is_constructor()
25809 && is_const() == o.is_const()
25810 && member_base::operator==(o)))
25811 return false;
25812
25813 if (function_tdecl_sptr ftdecl = as_function_tdecl())
25814 {
25815 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
25816 if (other_ftdecl)
25817 return ftdecl->function_tdecl::operator==(*other_ftdecl);
25818 }
25819 }
25820 catch(...)
25821 {}
25822 return false;
25823}
25824
25825/// Equality operator for smart pointers to @ref
25826/// member_function_template. This is compares the
25827/// pointed-to instances.
25828///
25829/// @param l the first instance to consider.
25830///
25831/// @param r the second instance to consider.
25832///
25833/// @return true iff @p l equals @p r.
25834bool
25835operator==(const member_function_template_sptr& l,
25836 const member_function_template_sptr& r)
25837{
25838 if (l.get() == r.get())
25839 return true;
25840 if (!!l != !!r)
25841 return false;
25842
25843 return *l == *r;
25844}
25845
25846/// Inequality operator for smart pointers to @ref
25847/// member_function_template. This is compares the pointed-to
25848/// instances.
25849///
25850/// @param l the first instance to consider.
25851///
25852/// @param r the second instance to consider.
25853///
25854/// @return true iff @p l equals @p r.
25855bool
25856operator!=(const member_function_template_sptr& l,
25857 const member_function_template_sptr& r)
25858{return !operator==(l, r);}
25859
25860/// This implements the ir_traversable_base::traverse pure virtual
25861/// function.
25862///
25863/// @param v the visitor used on the current instance and on its
25864/// underlying function template.
25865///
25866/// @return true if the entire IR node tree got traversed, false
25867/// otherwise.
25868bool
25870{
25871 if (visiting())
25872 return true;
25873
25874 if (v.visit_begin(this))
25875 {
25876 visiting(true);
25877 if (function_tdecl_sptr f = as_function_tdecl())
25878 f->traverse(v);
25879 visiting(false);
25880 }
25881 return v.visit_end(this);
25882}
25883
25884/// Equality operator of the the @ref member_class_template class.
25885///
25886/// @param other the other @ref member_class_template to compare against.
25887///
25888/// @return true iff the current instance equals @p other.
25889bool
25891{
25892 try
25893 {
25894 const member_class_template& o =
25895 dynamic_cast<const member_class_template&>(other);
25896
25897 if (!member_base::operator==(o))
25898 return false;
25899
25900 return as_class_tdecl()->class_tdecl::operator==(o);
25901 }
25902 catch(...)
25903 {return false;}
25904}
25905
25906/// Equality operator of the the @ref member_class_template class.
25907///
25908/// @param other the other @ref member_class_template to compare against.
25909///
25910/// @return true iff the current instance equals @p other.
25911bool
25913{
25914 if (!decl_base::operator==(other))
25915 return false;
25916 return as_class_tdecl()->class_tdecl::operator==(other);
25917}
25918
25919/// Comparison operator for the @ref member_class_template
25920/// type.
25921///
25922/// @param other the other instance of @ref
25923/// member_class_template to compare against.
25924///
25925/// @return true iff the two instances are equal.
25926bool
25928{
25929 const decl_base* o = dynamic_cast<const decl_base*>(&other);
25930 return *this == *o;
25931}
25932
25933/// Comparison operator for the @ref member_class_template
25934/// type.
25935///
25936/// @param l the first argument of the operator.
25937///
25938/// @param r the second argument of the operator.
25939///
25940/// @return true iff the two instances are equal.
25941bool
25942operator==(const member_class_template_sptr& l,
25943 const member_class_template_sptr& r)
25944{
25945 if (l.get() == r.get())
25946 return true;
25947 if (!!l != !!r)
25948 return false;
25949
25950 return *l == *r;
25951}
25952
25953/// Inequality operator for the @ref member_class_template
25954/// type.
25955///
25956/// @param l the first argument of the operator.
25957///
25958/// @param r the second argument of the operator.
25959///
25960/// @return true iff the two instances are equal.
25961bool
25962operator!=(const member_class_template_sptr& l,
25963 const member_class_template_sptr& r)
25964{return !operator==(l, r);}
25965
25966/// This implements the ir_traversable_base::traverse pure virtual
25967/// function.
25968///
25969/// @param v the visitor used on the current instance and on the class
25970/// pattern of the template.
25971///
25972/// @return true if the entire IR node tree got traversed, false
25973/// otherwise.
25974bool
25976{
25977 if (visiting())
25978 return true;
25979
25980 if (v.visit_begin(this))
25981 {
25982 visiting(true);
25983 if (class_tdecl_sptr t = as_class_tdecl())
25984 t->traverse(v);
25985 visiting(false);
25986 }
25987 return v.visit_end(this);
25988}
25989
25990/// Streaming operator for class_decl::access_specifier.
25991///
25992/// @param o the output stream to serialize the access specifier to.
25993///
25994/// @param a the access specifier to serialize.
25995///
25996/// @return the output stream.
25997std::ostream&
25998operator<<(std::ostream& o, access_specifier a)
25999{
26000 string r;
26001
26002 switch (a)
26003 {
26004 case no_access:
26005 r = "none";
26006 break;
26007 case private_access:
26008 r = "private";
26009 break;
26010 case protected_access:
26011 r = "protected";
26012 break;
26013 case public_access:
26014 r= "public";
26015 break;
26016 };
26017 o << r;
26018 return o;
26019}
26020
26021/// Sets the static-ness property of a class member.
26022///
26023/// @param d the class member to set the static-ness property for.
26024/// Note that this must be a class member otherwise the function
26025/// aborts the current process.
26026///
26027/// @param s this must be true if the member is to be static, false
26028/// otherwise.
26029void
26031{
26033
26035 ABG_ASSERT(c);
26036
26037 c->set_is_static(s);
26038
26039 scope_decl* scope = d.get_scope();
26040
26041 if (class_or_union* cl = is_class_or_union_type(scope))
26042 {
26043 if (var_decl* v = is_var_decl(&d))
26044 {
26045 if (s)
26046 // remove from the non-static data members
26047 for (class_decl::data_members::iterator i =
26048 cl->priv_->non_static_data_members_.begin();
26049 i != cl->priv_->non_static_data_members_.end();
26050 ++i)
26051 {
26052 if ((*i)->get_name() == v->get_name())
26053 {
26054 cl->priv_->non_static_data_members_.erase(i);
26055 break;
26056 }
26057 }
26058 else
26059 {
26060 bool is_already_in_non_static_data_members = false;
26061 for (class_or_union::data_members::iterator i =
26062 cl->priv_->non_static_data_members_.begin();
26063 i != cl->priv_->non_static_data_members_.end();
26064 ++i)
26065 {
26066 if ((*i)->get_name() == v->get_name())
26067 {
26068 is_already_in_non_static_data_members = true;
26069 break;
26070 }
26071 }
26072 if (!is_already_in_non_static_data_members)
26073 {
26074 var_decl_sptr var;
26075 // add to non-static data members.
26076 for (class_or_union::data_members::const_iterator i =
26077 cl->priv_->data_members_.begin();
26078 i != cl->priv_->data_members_.end();
26079 ++i)
26080 {
26081 if ((*i)->get_name() == v->get_name())
26082 {
26083 var = *i;
26084 break;
26085 }
26086 }
26087 ABG_ASSERT(var);
26088 cl->priv_->non_static_data_members_.push_back(var);
26089 }
26090 }
26091 }
26092 }
26093}
26094
26095/// Sets the static-ness property of a class member.
26096///
26097/// @param d the class member to set the static-ness property for.
26098/// Note that this must be a class member otherwise the function
26099/// aborts the current process.
26100///
26101/// @param s this must be true if the member is to be static, false
26102/// otherwise.
26103void
26104set_member_is_static(const decl_base_sptr& d, bool s)
26105{set_member_is_static(*d, s);}
26106
26107// </class_decl>
26108
26109// <union_decl>
26110
26111/// Constructor for the @ref union_decl type.
26112///
26113/// @param env the @ref environment we are operating from.
26114///
26115/// @param name the name of the union type.
26116///
26117/// @param size_in_bits the size of the union, in bits.
26118///
26119/// @param locus the location of the type.
26120///
26121/// @param vis the visibility of instances of @ref union_decl.
26122///
26123/// @param mbr_types the member types of the union.
26124///
26125/// @param data_mbrs the data members of the union.
26126///
26127/// @param member_fns the member functions of the union.
26128union_decl::union_decl(const environment& env, const string& name,
26129 size_t size_in_bits, const location& locus,
26130 visibility vis, member_types& mbr_types,
26131 data_members& data_mbrs, member_functions& member_fns)
26132 : type_or_decl_base(env,
26133 UNION_TYPE
26134 | ABSTRACT_TYPE_BASE
26135 | ABSTRACT_DECL_BASE),
26136 decl_base(env, name, locus, name, vis),
26137 type_base(env, size_in_bits, 0),
26138 class_or_union(env, name, size_in_bits, 0,
26139 locus, vis, mbr_types, data_mbrs, member_fns)
26140{
26142}
26143
26144/// Constructor for the @ref union_decl type.
26145///
26146/// @param env the @ref environment we are operating from.
26147///
26148/// @param name the name of the union type.
26149///
26150/// @param size_in_bits the size of the union, in bits.
26151///
26152/// @param locus the location of the type.
26153///
26154/// @param vis the visibility of instances of @ref union_decl.
26155///
26156/// @param mbr_types the member types of the union.
26157///
26158/// @param data_mbrs the data members of the union.
26159///
26160/// @param member_fns the member functions of the union.
26161///
26162/// @param is_anonymous whether the newly created instance is
26163/// anonymous.
26164union_decl::union_decl(const environment& env, const string& name,
26165 size_t size_in_bits, const location& locus,
26166 visibility vis, member_types& mbr_types,
26167 data_members& data_mbrs, member_functions& member_fns,
26168 bool is_anonymous)
26169 : type_or_decl_base(env,
26170 UNION_TYPE
26171 | ABSTRACT_TYPE_BASE
26172 | ABSTRACT_DECL_BASE),
26173 decl_base(env, name, locus,
26174 // If the class is anonymous then by default it won't
26175 // have a linkage name. Also, the anonymous class does
26176 // have an internal-only unique name that is generally
26177 // not taken into account when comparing classes; such a
26178 // unique internal-only name, when used as a linkage
26179 // name might introduce spurious comparison false
26180 // negatives.
26181 /*linkage_name=*/is_anonymous ? string() : name,
26182 vis),
26183 type_base(env, size_in_bits, 0),
26184 class_or_union(env, name, size_in_bits, 0,
26185 locus, vis, mbr_types, data_mbrs, member_fns)
26186{
26188 set_is_anonymous(is_anonymous);
26189}
26190
26191/// Constructor for the @ref union_decl type.
26192///
26193/// @param env the @ref environment we are operating from.
26194///
26195/// @param name the name of the union type.
26196///
26197/// @param size_in_bits the size of the union, in bits.
26198///
26199/// @param locus the location of the type.
26200///
26201/// @param vis the visibility of instances of @ref union_decl.
26202union_decl::union_decl(const environment& env, const string& name,
26203 size_t size_in_bits, const location& locus,
26204 visibility vis)
26205 : type_or_decl_base(env,
26206 UNION_TYPE
26207 | ABSTRACT_TYPE_BASE
26208 | ABSTRACT_DECL_BASE
26209 | ABSTRACT_SCOPE_TYPE_DECL
26210 | ABSTRACT_SCOPE_DECL),
26211 decl_base(env, name, locus, name, vis),
26212 type_base(env, size_in_bits, 0),
26213 class_or_union(env, name, size_in_bits,
26214 0, locus, vis)
26215{
26217}
26218
26219/// Constructor for the @ref union_decl type.
26220///
26221/// @param env the @ref environment we are operating from.
26222///
26223/// @param name the name of the union type.
26224///
26225/// @param size_in_bits the size of the union, in bits.
26226///
26227/// @param locus the location of the type.
26228///
26229/// @param vis the visibility of instances of @ref union_decl.
26230///
26231/// @param is_anonymous whether the newly created instance is
26232/// anonymous.
26233union_decl::union_decl(const environment& env, const string& name,
26234 size_t size_in_bits, const location& locus,
26235 visibility vis, bool is_anonymous)
26236 : type_or_decl_base(env,
26237 UNION_TYPE
26238 | ABSTRACT_TYPE_BASE
26239 | ABSTRACT_DECL_BASE
26240 | ABSTRACT_SCOPE_TYPE_DECL
26241 | ABSTRACT_SCOPE_DECL),
26242 decl_base(env, name, locus,
26243 // If the class is anonymous then by default it won't
26244 // have a linkage name. Also, the anonymous class does
26245 // have an internal-only unique name that is generally
26246 // not taken into account when comparing classes; such a
26247 // unique internal-only name, when used as a linkage
26248 // name might introduce spurious comparison false
26249 // negatives.
26250 /*linkage_name=*/is_anonymous ? string() : name,
26251 vis),
26252 type_base(env, size_in_bits, 0),
26253 class_or_union(env, name, size_in_bits,
26254 0, locus, vis)
26255{
26257 set_is_anonymous(is_anonymous);
26258}
26259
26260/// Constructor for the @ref union_decl type.
26261///
26262/// @param env the @ref environment we are operating from.
26263///
26264/// @param name the name of the union type.
26265///
26266/// @param is_declaration_only a boolean saying whether the instance
26267/// represents a declaration only, or not.
26268union_decl::union_decl(const environment& env,
26269 const string& name,
26270 bool is_declaration_only)
26271 : type_or_decl_base(env,
26272 UNION_TYPE
26273 | ABSTRACT_TYPE_BASE
26274 | ABSTRACT_DECL_BASE
26275 | ABSTRACT_SCOPE_TYPE_DECL
26276 | ABSTRACT_SCOPE_DECL),
26277 decl_base(env, name, location(), name),
26278 type_base(env, 0, 0),
26279 class_or_union(env, name, is_declaration_only)
26280{
26282}
26283
26284/// Getter of the pretty representation of the current instance of
26285/// @ref union_decl.
26286///
26287/// @param internal set to true if the call is intended to get a
26288/// representation of the decl (or type) for the purpose of canonical
26289/// type comparison. This is mainly used in the function
26290/// type_base::get_canonical_type_for().
26291///
26292/// In other words if the argument for this parameter is true then the
26293/// call is meant for internal use (for technical use inside the
26294/// library itself), false otherwise. If you don't know what this is
26295/// for, then set it to false.
26296///
26297/// @param qualified_name if true, names emitted in the pretty
26298/// representation are fully qualified.
26299///
26300/// @return the pretty representaion for a union_decl.
26301string
26303 bool qualified_name) const
26304{
26305 string repr;
26306 if (get_is_anonymous())
26307 {
26308 if (internal && !get_name().empty())
26309 repr = string("union ") +
26310 get_type_name(this, qualified_name, /*internal=*/true);
26311 else
26313 /*one_line=*/true,
26314 internal);
26315 }
26316 else
26317 {
26318 repr = "union ";
26319 if (qualified_name)
26320 repr += get_qualified_name(internal);
26321 else
26322 repr += get_name();
26323 }
26324
26325 return repr;
26326}
26327
26328/// Comparison operator for @ref union_decl.
26329///
26330/// @param other the instance of @ref union_decl to compare against.
26331///
26332/// @return true iff the current instance of @ref union_decl equals @p
26333/// other.
26334bool
26336{
26337 const union_decl* op = dynamic_cast<const union_decl*>(&other);
26338 if (!op)
26339 return false;
26340 return try_canonical_compare(this, op);
26341}
26342
26343/// Equality operator for union_decl.
26344///
26345/// Re-uses the equality operator that takes a decl_base.
26346///
26347/// @param other the other union_decl to compare against.
26348///
26349/// @return true iff the current instance equals the other one.
26350bool
26352{
26353 const decl_base *o = dynamic_cast<const decl_base*>(&other);
26354 if (!o)
26355 return false;
26356 return *this == *o;
26357}
26358
26359/// Equality operator for union_decl.
26360///
26361/// Re-uses the equality operator that takes a decl_base.
26362///
26363/// @param other the other union_decl to compare against.
26364///
26365/// @return true iff the current instance equals the other one.
26366bool
26368{
26369 const decl_base *o = dynamic_cast<const decl_base*>(&other);
26370 return *this == *o;
26371}
26372
26373/// Comparison operator for @ref union_decl.
26374///
26375/// @param other the instance of @ref union_decl to compare against.
26376///
26377/// @return true iff the current instance of @ref union_decl equals @p
26378/// other.
26379bool
26381{
26382 const decl_base& o = other;
26383 return *this == o;
26384}
26385
26386/// This implements the ir_traversable_base::traverse pure virtual
26387/// function.
26388///
26389/// @param v the visitor used on the current instance and on its
26390/// members.
26391///
26392/// @return true if the entire IR node tree got traversed, false
26393/// otherwise.
26394bool
26396{
26397 if (v.type_node_has_been_visited(this))
26398 return true;
26399
26400 if (visiting())
26401 return true;
26402
26403 if (v.visit_begin(this))
26404 {
26405 visiting(true);
26406 bool stop = false;
26407
26408 if (!stop)
26409 for (data_members::const_iterator i = get_data_members().begin();
26410 i != get_data_members().end();
26411 ++i)
26412 if (!(*i)->traverse(v))
26413 {
26414 stop = true;
26415 break;
26416 }
26417
26418 if (!stop)
26419 for (member_functions::const_iterator i= get_member_functions().begin();
26420 i != get_member_functions().end();
26421 ++i)
26422 if (!(*i)->traverse(v))
26423 {
26424 stop = true;
26425 break;
26426 }
26427
26428 if (!stop)
26429 for (member_types::const_iterator i = get_member_types().begin();
26430 i != get_member_types().end();
26431 ++i)
26432 if (!(*i)->traverse(v))
26433 {
26434 stop = true;
26435 break;
26436 }
26437
26438 if (!stop)
26439 for (member_function_templates::const_iterator i =
26441 i != get_member_function_templates().end();
26442 ++i)
26443 if (!(*i)->traverse(v))
26444 {
26445 stop = true;
26446 break;
26447 }
26448
26449 if (!stop)
26450 for (member_class_templates::const_iterator i =
26452 i != get_member_class_templates().end();
26453 ++i)
26454 if (!(*i)->traverse(v))
26455 {
26456 stop = true;
26457 break;
26458 }
26459 visiting(false);
26460 }
26461
26462 bool result = v.visit_end(this);
26464 return result;
26465}
26466
26467/// Destructor of the @ref union_decl type.
26469{}
26470
26471/// Compares two instances of @ref union_decl.
26472///
26473/// If the two intances are different, set a bitfield to give some
26474/// insight about the kind of differences there are.
26475///
26476/// @param l the first artifact of the comparison.
26477///
26478/// @param r the second artifact of the comparison.
26479///
26480/// @param k a pointer to a bitfield that gives information about the
26481/// kind of changes there are between @p l and @p r. This one is set
26482/// iff @p k is non-null and the function returns false.
26483///
26484/// Please note that setting k to a non-null value does have a
26485/// negative performance impact because even if @p l and @p r are not
26486/// equal, the function keeps up the comparison in order to determine
26487/// the different kinds of ways in which they are different.
26488///
26489/// @return true if @p l equals @p r, false otherwise.
26490bool
26492{
26493
26495
26496 {
26497 // First of all, let's see if these two types haven't already been
26498 // compared. If so, and if the result of the comparison has been
26499 // cached, let's just re-use it, rather than comparing them all
26500 // over again.
26501 bool result = false;
26502 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
26503 ABG_RETURN(result);
26504 }
26505
26506 bool result = equals(static_cast<const class_or_union&>(l),
26507 static_cast<const class_or_union&>(r),
26508 k);
26509
26511}
26512
26513/// Copy a method of a @ref union_decl into a new @ref
26514/// union_decl.
26515///
26516/// @param t the @ref union_decl into which the method is to be copied.
26517///
26518/// @param method the method to copy into @p t.
26519///
26520/// @return the resulting newly copied method.
26521method_decl_sptr
26522copy_member_function(const union_decl_sptr& union_type,
26523 const method_decl_sptr& f)
26524{return copy_member_function(union_type, f.get());}
26525
26526/// Copy a method of a @ref union_decl into a new @ref
26527/// union_decl.
26528///
26529/// @param t the @ref union_decl into which the method is to be copied.
26530///
26531/// @param method the method to copy into @p t.
26532///
26533/// @return the resulting newly copied method.
26534method_decl_sptr
26535copy_member_function(const union_decl_sptr& union_type,
26536 const method_decl* f)
26537{
26538 const class_or_union_sptr t = union_type;
26539 return copy_member_function(t, f);
26540}
26541
26542/// Turn equality of shared_ptr of union_decl into a deep equality;
26543/// that is, make it compare the pointed to objects too.
26544///
26545/// @param l the left-hand-side operand of the operator
26546///
26547/// @param r the right-hand-side operand of the operator.
26548///
26549/// @return true iff @p l equals @p r.
26550bool
26551operator==(const union_decl_sptr& l, const union_decl_sptr& r)
26552{
26553 if (l.get() == r.get())
26554 return true;
26555 if (!!l != !!r)
26556 return false;
26557
26558 return *l == *r;
26559}
26560
26561/// Turn inequality of shared_ptr of union_decl into a deep equality;
26562/// that is, make it compare the pointed to objects too.
26563///
26564/// @param l the left-hand-side operand of the operator
26565///
26566/// @param r the right-hand-side operand of the operator.
26567///
26568/// @return true iff @p l is different from @p r.
26569bool
26570operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
26571{return !operator==(l, r);}
26572// </union_decl>
26573
26574// <template_decl stuff>
26575
26576/// Data type of the private data of the @template_decl type.
26577class template_decl::priv
26578{
26579 friend class template_decl;
26580
26581 std::list<template_parameter_sptr> parms_;
26582public:
26583
26584 priv()
26585 {}
26586}; // end class template_decl::priv
26587
26588/// Add a new template parameter to the current instance of @ref
26589/// template_decl.
26590///
26591/// @param p the new template parameter to add.
26592void
26594{priv_->parms_.push_back(p);}
26595
26596/// Get the list of template parameters of the current instance of
26597/// @ref template_decl.
26598///
26599/// @return the list of template parameters.
26600const std::list<template_parameter_sptr>&
26602{return priv_->parms_;}
26603
26604/// Constructor.
26605///
26606/// @param env the environment we are operating from.
26607///
26608/// @param name the name of the template decl.
26609///
26610/// @param locus the source location where the template declaration is
26611/// defined.
26612///
26613/// @param vis the visibility of the template declaration.
26614template_decl::template_decl(const environment& env,
26615 const string& name,
26616 const location& locus,
26617 visibility vis)
26618 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
26619 decl_base(env, name, locus, /*mangled_name=*/"", vis),
26620 priv_(new priv)
26621{
26623}
26624
26625/// Destructor.
26627{}
26628
26629/// Equality operator.
26630///
26631/// @param o the other instance to compare against.
26632///
26633/// @return true iff @p equals the current instance.
26634bool
26636{
26637 const template_decl* other = dynamic_cast<const template_decl*>(&o);
26638 if (!other)
26639 return false;
26640 return *this == *other;
26641}
26642
26643/// Equality operator.
26644///
26645/// @param o the other instance to compare against.
26646///
26647/// @return true iff @p equals the current instance.
26648bool
26650{
26651 try
26652 {
26653 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
26654 for (t0 = get_template_parameters().begin(),
26655 t1 = o.get_template_parameters().begin();
26656 (t0 != get_template_parameters().end()
26657 && t1 != o.get_template_parameters().end());
26658 ++t0, ++t1)
26659 {
26660 if (**t0 != **t1)
26661 return false;
26662 }
26663
26664 if (t0 != get_template_parameters().end()
26665 || t1 != o.get_template_parameters().end())
26666 return false;
26667
26668 return true;
26669 }
26670 catch(...)
26671 {return false;}
26672}
26673
26674// </template_decl stuff>
26675
26676//<template_parameter>
26677
26678/// The type of the private data of the @ref template_parameter type.
26679class template_parameter::priv
26680{
26681 friend class template_parameter;
26682
26683 unsigned index_;
26684 template_decl_wptr template_decl_;
26685 mutable bool hashing_started_;
26686 mutable bool comparison_started_;
26687
26688 priv();
26689
26690public:
26691
26692 priv(unsigned index, template_decl_sptr enclosing_template_decl)
26693 : index_(index),
26694 template_decl_(enclosing_template_decl),
26695 hashing_started_(),
26696 comparison_started_()
26697 {}
26698}; // end class template_parameter::priv
26699
26700template_parameter::template_parameter(unsigned index,
26701 template_decl_sptr enclosing_template)
26702 : priv_(new priv(index, enclosing_template))
26703 {}
26704
26705unsigned
26706template_parameter::get_index() const
26707{return priv_->index_;}
26708
26710template_parameter::get_enclosing_template_decl() const
26711{return priv_->template_decl_.lock();}
26712
26713bool
26714template_parameter::get_hashing_has_started() const
26715{return priv_->hashing_started_;}
26716
26717void
26718template_parameter::set_hashing_has_started(bool f) const
26719{priv_->hashing_started_ = f;}
26720
26721bool
26722template_parameter::operator==(const template_parameter& o) const
26723{
26724 if (get_index() != o.get_index())
26725 return false;
26726
26727 if (priv_->comparison_started_)
26728 return true;
26729
26730 bool result = false;
26731
26732 // Avoid inifite loops due to the fact that comparison the enclosing
26733 // template decl might lead to comparing this very same template
26734 // parameter with another one ...
26735 priv_->comparison_started_ = true;
26736
26737 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
26738 ;
26739 else if (get_enclosing_template_decl()
26740 && (*get_enclosing_template_decl()
26741 != *o.get_enclosing_template_decl()))
26742 ;
26743 else
26744 result = true;
26745
26746 priv_->comparison_started_ = false;
26747
26748 return result;
26749}
26750
26751/// Inequality operator.
26752///
26753/// @param other the other instance to compare against.
26754///
26755/// @return true iff the other instance is different from the current
26756/// one.
26757bool
26759{return !operator==(other);}
26760
26761/// Destructor.
26763{}
26764
26765/// The type of the private data of the @ref type_tparameter type.
26766class type_tparameter::priv
26767{
26768 friend class type_tparameter;
26769}; // end class type_tparameter::priv
26770
26771/// Constructor of the @ref type_tparameter type.
26772///
26773/// @param index the index the type template parameter.
26774///
26775/// @param enclosing_tdecl the enclosing template declaration.
26776///
26777/// @param name the name of the template parameter.
26778///
26779/// @param locus the location of the declaration of this type template
26780/// parameter.
26781type_tparameter::type_tparameter(unsigned index,
26782 template_decl_sptr enclosing_tdecl,
26783 const string& name,
26784 const location& locus)
26785 : type_or_decl_base(enclosing_tdecl->get_environment(),
26786 ABSTRACT_DECL_BASE
26787 | ABSTRACT_TYPE_BASE
26788 | BASIC_TYPE),
26789 decl_base(enclosing_tdecl->get_environment(), name, locus),
26790 type_base(enclosing_tdecl->get_environment(), 0, 0),
26791 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
26792 template_parameter(index, enclosing_tdecl),
26793 priv_(new priv)
26794{
26796}
26797
26798/// Equality operator.
26799///
26800/// @param other the other template type parameter to compare against.
26801///
26802/// @return true iff @p other equals the current instance.
26803bool
26805{
26806 if (!type_decl::operator==(other))
26807 return false;
26808
26809 try
26810 {
26811 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26813 }
26814 catch (...)
26815 {return false;}
26816}
26817
26818/// Equality operator.
26819///
26820/// @param other the other template type parameter to compare against.
26821///
26822/// @return true iff @p other equals the current instance.
26823bool
26825{
26826 if (!type_decl::operator==(other))
26827 return false;
26828
26829 try
26830 {
26831 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26833 }
26834 catch (...)
26835 {return false;}
26836}
26837
26838/// Equality operator.
26839///
26840/// @param other the other template type parameter to compare against.
26841///
26842/// @return true iff @p other equals the current instance.
26843bool
26845{
26846 if (!decl_base::operator==(other))
26847 return false;
26848
26849 try
26850 {
26851 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26853 }
26854 catch (...)
26855 {return false;}
26856}
26857
26858/// Equality operator.
26859///
26860/// @param other the other template type parameter to compare against.
26861///
26862/// @return true iff @p other equals the current instance.
26863bool
26865{
26866 try
26867 {
26868 const type_base& o = dynamic_cast<const type_base&>(other);
26869 return *this == o;
26870 }
26871 catch(...)
26872 {return false;}
26873}
26874
26875/// Equality operator.
26876///
26877/// @param other the other template type parameter to compare against.
26878///
26879/// @return true iff @p other equals the current instance.
26880bool
26882{return *this == static_cast<const type_base&>(other);}
26883
26884type_tparameter::~type_tparameter()
26885{}
26886
26887/// The type of the private data of the @ref non_type_tparameter type.
26888class non_type_tparameter::priv
26889{
26890 friend class non_type_tparameter;
26891
26892 type_base_wptr type_;
26893
26894 priv();
26895
26896public:
26897
26898 priv(type_base_sptr type)
26899 : type_(type)
26900 {}
26901}; // end class non_type_tparameter::priv
26902
26903/// The constructor for the @ref non_type_tparameter type.
26904///
26905/// @param index the index of the template parameter.
26906///
26907/// @param enclosing_tdecl the enclosing template declaration that
26908/// holds this parameter parameter.
26909///
26910/// @param name the name of the template parameter.
26911///
26912/// @param type the type of the template parameter.
26913///
26914/// @param locus the location of the declaration of this template
26915/// parameter.
26916non_type_tparameter::non_type_tparameter(unsigned index,
26917 template_decl_sptr enclosing_tdecl,
26918 const string& name,
26919 type_base_sptr type,
26920 const location& locus)
26921 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
26922 decl_base(type->get_environment(), name, locus, ""),
26923 template_parameter(index, enclosing_tdecl),
26924 priv_(new priv(type))
26925{
26927}
26928
26929/// Getter for the type of the template parameter.
26930///
26931/// @return the type of the template parameter.
26932const type_base_sptr
26934{return priv_->type_.lock();}
26935
26936/// Get the hash value of the current instance.
26937///
26938/// @return the hash value.
26939size_t
26941{
26942 non_type_tparameter::hash hash_tparm;
26943 return hash_tparm(this);
26944}
26945
26946bool
26948{
26949 if (!decl_base::operator==(other))
26950 return false;
26951
26952 try
26953 {
26954 const non_type_tparameter& o =
26955 dynamic_cast<const non_type_tparameter&>(other);
26956 return (template_parameter::operator==(o)
26957 && get_type() == o.get_type());
26958 }
26959 catch(...)
26960 {return false;}
26961}
26962
26963bool
26965{
26966 try
26967 {
26968 const decl_base& o = dynamic_cast<const decl_base&>(other);
26969 return *this == o;
26970 }
26971 catch(...)
26972 {return false;}
26973}
26974
26975non_type_tparameter::~non_type_tparameter()
26976{}
26977
26978// <template_tparameter stuff>
26979
26980/// Type of the private data of the @ref template_tparameter type.
26981class template_tparameter::priv
26982{
26983}; //end class template_tparameter::priv
26984
26985/// Constructor for the @ref template_tparameter.
26986///
26987/// @param index the index of the template parameter.
26988///
26989/// @param enclosing_tdecl the enclosing template declaration.
26990///
26991/// @param name the name of the template parameter.
26992///
26993/// @param locus the location of the declaration of the template
26994/// parameter.
26995template_tparameter::template_tparameter(unsigned index,
26996 template_decl_sptr enclosing_tdecl,
26997 const string& name,
26998 const location& locus)
26999 : type_or_decl_base(enclosing_tdecl->get_environment(),
27000 ABSTRACT_DECL_BASE
27001 | ABSTRACT_TYPE_BASE
27002 | BASIC_TYPE),
27003 decl_base(enclosing_tdecl->get_environment(), name, locus),
27004 type_base(enclosing_tdecl->get_environment(), 0, 0),
27005 type_decl(enclosing_tdecl->get_environment(), name,
27006 0, 0, locus, name, VISIBILITY_DEFAULT),
27007 type_tparameter(index, enclosing_tdecl, name, locus),
27008 template_decl(enclosing_tdecl->get_environment(), name, locus),
27009 priv_(new priv)
27010{
27012}
27013
27014/// Equality operator.
27015///
27016/// @param other the other template parameter to compare against.
27017///
27018/// @return true iff @p other equals the current instance.
27019bool
27021{
27022 try
27023 {
27024 const template_tparameter& o =
27025 dynamic_cast<const template_tparameter&>(other);
27026 return (type_tparameter::operator==(o)
27028 }
27029 catch(...)
27030 {return false;}
27031}
27032
27033/// Equality operator.
27034///
27035/// @param other the other template parameter to compare against.
27036///
27037/// @return true iff @p other equals the current instance.
27038bool
27040{
27041 try
27042 {
27043 const template_tparameter& o =
27044 dynamic_cast<const template_tparameter&>(other);
27045 return (type_tparameter::operator==(o)
27047 }
27048 catch(...)
27049 {return false;}
27050}
27051
27052bool
27054{
27055 try
27056 {
27057 const template_tparameter& other =
27058 dynamic_cast<const template_tparameter&>(o);
27059 return *this == static_cast<const type_base&>(other);
27060 }
27061 catch(...)
27062 {return false;}
27063}
27064
27065bool
27067{
27068 try
27069 {
27070 const template_tparameter& other =
27071 dynamic_cast<const template_tparameter&>(o);
27072 return type_base::operator==(other);
27073 }
27074 catch(...)
27075 {return false;}
27076}
27077
27078template_tparameter::~template_tparameter()
27079{}
27080
27081// </template_tparameter stuff>
27082
27083// <type_composition stuff>
27084
27085/// The type of the private data of the @ref type_composition type.
27086class type_composition::priv
27087{
27088 friend class type_composition;
27089
27090 type_base_wptr type_;
27091
27092 // Forbid this.
27093 priv();
27094
27095public:
27096
27097 priv(type_base_wptr type)
27098 : type_(type)
27099 {}
27100}; //end class type_composition::priv
27101
27102/// Constructor for the @ref type_composition type.
27103///
27104/// @param index the index of the template type composition.
27105///
27106/// @param tdecl the enclosing template parameter that owns the
27107/// composition.
27108///
27109/// @param t the resulting type.
27110type_composition::type_composition(unsigned index,
27111 template_decl_sptr tdecl,
27112 type_base_sptr t)
27113 : type_or_decl_base(tdecl->get_environment(),
27114 ABSTRACT_DECL_BASE),
27115 decl_base(tdecl->get_environment(), "", location()),
27116 template_parameter(index, tdecl),
27117 priv_(new priv(t))
27118{
27120}
27121
27122/// Getter for the resulting composed type.
27123///
27124/// @return the composed type.
27125const type_base_sptr
27127{return priv_->type_.lock();}
27128
27129/// Setter for the resulting composed type.
27130///
27131/// @param t the composed type.
27132void
27134{priv_->type_ = t;}
27135
27136/// Get the hash value for the current instance.
27137///
27138/// @return the hash value.
27139size_t
27141{
27142 type_composition::hash hash_type_composition;
27143 return hash_type_composition(this);
27144}
27145
27146type_composition::~type_composition()
27147{}
27148
27149// </type_composition stuff>
27150
27151//</template_parameter stuff>
27152
27153// <function_template>
27154
27155class function_tdecl::priv
27156{
27157 friend class function_tdecl;
27158
27159 function_decl_sptr pattern_;
27160 binding binding_;
27161
27162 priv();
27163
27164public:
27165
27166 priv(function_decl_sptr pattern, binding bind)
27167 : pattern_(pattern), binding_(bind)
27168 {}
27169
27170 priv(binding bind)
27171 : binding_(bind)
27172 {}
27173}; // end class function_tdecl::priv
27174
27175/// Constructor for a function template declaration.
27176///
27177/// @param env the environment we are operating from.
27178///
27179/// @param locus the location of the declaration.
27180///
27181/// @param vis the visibility of the declaration. This is the
27182/// visibility the functions instantiated from this template are going
27183/// to have.
27184///
27185/// @param bind the binding of the declaration. This is the binding
27186/// the functions instantiated from this template are going to have.
27187function_tdecl::function_tdecl(const environment& env,
27188 const location& locus,
27189 visibility vis,
27190 binding bind)
27191 : type_or_decl_base(env,
27192 ABSTRACT_DECL_BASE
27193 | TEMPLATE_DECL
27194 | ABSTRACT_SCOPE_DECL),
27195 decl_base(env, "", locus, "", vis),
27196 template_decl(env, "", locus, vis),
27197 scope_decl(env, "", locus),
27198 priv_(new priv(bind))
27199{
27201}
27202
27203/// Constructor for a function template declaration.
27204///
27205/// @param pattern the pattern of the template.
27206///
27207/// @param locus the location of the declaration.
27208///
27209/// @param vis the visibility of the declaration. This is the
27210/// visibility the functions instantiated from this template are going
27211/// to have.
27212///
27213/// @param bind the binding of the declaration. This is the binding
27214/// the functions instantiated from this template are going to have.
27215function_tdecl::function_tdecl(function_decl_sptr pattern,
27216 const location& locus,
27217 visibility vis,
27218 binding bind)
27219 : type_or_decl_base(pattern->get_environment(),
27220 ABSTRACT_DECL_BASE
27221 | TEMPLATE_DECL
27222 | ABSTRACT_SCOPE_DECL),
27223 decl_base(pattern->get_environment(), pattern->get_name(), locus,
27224 pattern->get_name(), vis),
27225 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
27226 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
27227 priv_(new priv(pattern, bind))
27228{
27230}
27231
27232/// Set a new pattern to the function template.
27233///
27234/// @param p the new pattern.
27235void
27237{
27238 priv_->pattern_ = p;
27239 add_decl_to_scope(p, this);
27240 set_name(p->get_name());
27241}
27242
27243/// Get the pattern of the function template.
27244///
27245/// @return the pattern.
27248{return priv_->pattern_;}
27249
27250/// Get the binding of the function template.
27251///
27252/// @return the binding
27255{return priv_->binding_;}
27256
27257/// Comparison operator for the @ref function_tdecl type.
27258///
27259/// @param other the other instance of @ref function_tdecl to compare against.
27260///
27261/// @return true iff the two instance are equal.
27262bool
27264{
27265 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
27266 if (o)
27267 return *this == *o;
27268 return false;
27269}
27270
27271/// Comparison operator for the @ref function_tdecl type.
27272///
27273/// @param other the other instance of @ref function_tdecl to compare against.
27274///
27275/// @return true iff the two instance are equal.
27276bool
27278{
27279 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
27280 if (o)
27281 return *this == *o;
27282 return false;
27283}
27284
27285/// Comparison operator for the @ref function_tdecl type.
27286///
27287/// @param o the other instance of @ref function_tdecl to compare against.
27288///
27289/// @return true iff the two instance are equal.
27290bool
27292{
27293 if (!(get_binding() == o.get_binding()
27294 && template_decl::operator==(o)
27295 && scope_decl::operator==(o)
27296 && !!get_pattern() == !!o.get_pattern()))
27297 return false;
27298
27299 if (get_pattern())
27300 return (*get_pattern() == *o.get_pattern());
27301
27302 return true;
27303}
27304
27305/// This implements the ir_traversable_base::traverse pure virtual
27306/// function.
27307///
27308/// @param v the visitor used on the current instance and on the
27309/// function pattern of the template.
27310///
27311/// @return true if the entire IR node tree got traversed, false
27312/// otherwise.
27313bool
27315{
27316 if (visiting())
27317 return true;
27318
27319 if (!v.visit_begin(this))
27320 {
27321 visiting(true);
27322 if (get_pattern())
27323 get_pattern()->traverse(v);
27324 visiting(false);
27325 }
27326 return v.visit_end(this);
27327}
27328
27329function_tdecl::~function_tdecl()
27330{}
27331
27332// </function_template>
27333
27334// <class template>
27335
27336/// Type of the private data of the the @ref class_tdecl type.
27337class class_tdecl::priv
27338{
27339 friend class class_tdecl;
27340 class_decl_sptr pattern_;
27341
27342public:
27343
27344 priv()
27345 {}
27346
27347 priv(class_decl_sptr pattern)
27348 : pattern_(pattern)
27349 {}
27350}; // end class class_tdecl::priv
27351
27352/// Constructor for the @ref class_tdecl type.
27353///
27354/// @param env the environment we are operating from.
27355///
27356/// @param locus the location of the declaration of the class_tdecl
27357/// type.
27358///
27359/// @param vis the visibility of the instance of class instantiated
27360/// from this template.
27361class_tdecl::class_tdecl(const environment& env,
27362 const location& locus,
27363 visibility vis)
27364 : type_or_decl_base(env,
27365 ABSTRACT_DECL_BASE
27366 | TEMPLATE_DECL
27367 | ABSTRACT_SCOPE_DECL),
27368 decl_base(env, "", locus, "", vis),
27369 template_decl(env, "", locus, vis),
27370 scope_decl(env, "", locus),
27371 priv_(new priv)
27372{
27374}
27375
27376/// Constructor for the @ref class_tdecl type.
27377///
27378/// @param pattern The details of the class template. This must NOT be a
27379/// null pointer. If you really this to be null, please use the
27380/// constructor above instead.
27381///
27382/// @param locus the source location of the declaration of the type.
27383///
27384/// @param vis the visibility of the instances of class instantiated
27385/// from this template.
27386class_tdecl::class_tdecl(class_decl_sptr pattern,
27387 const location& locus,
27388 visibility vis)
27389 : type_or_decl_base(pattern->get_environment(),
27390 ABSTRACT_DECL_BASE
27391 | TEMPLATE_DECL
27392 | ABSTRACT_SCOPE_DECL),
27393 decl_base(pattern->get_environment(), pattern->get_name(),
27394 locus, pattern->get_name(), vis),
27395 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
27396 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
27397 priv_(new priv(pattern))
27398{
27400}
27401
27402/// Setter of the pattern of the template.
27403///
27404/// @param p the new template.
27405void
27407{
27408 priv_->pattern_ = p;
27409 add_decl_to_scope(p, this);
27410 set_name(p->get_name());
27411}
27412
27413/// Getter of the pattern of the template.
27414///
27415/// @return p the new template.
27418{return priv_->pattern_;}
27419
27420bool
27422{
27423 try
27424 {
27425 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
27426
27427 if (!(template_decl::operator==(o)
27428 && scope_decl::operator==(o)
27429 && !!get_pattern() == !!o.get_pattern()))
27430 return false;
27431
27432 if (!get_pattern() || !o.get_pattern())
27433 return true;
27434
27435 return get_pattern()->decl_base::operator==(*o.get_pattern());
27436 }
27437 catch(...) {}
27438 return false;
27439}
27440
27441bool
27443{
27444 try
27445 {
27446 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
27447 return *this == static_cast<const decl_base&>(o);
27448 }
27449 catch(...)
27450 {return false;}
27451}
27452
27453bool
27455{return *this == static_cast<const decl_base&>(o);}
27456
27457/// This implements the ir_traversable_base::traverse pure virtual
27458/// function.
27459///
27460/// @param v the visitor used on the current instance and on the class
27461/// pattern of the template.
27462///
27463/// @return true if the entire IR node tree got traversed, false
27464/// otherwise.
27465bool
27467{
27468 if (visiting())
27469 return true;
27470
27471 if (v.visit_begin(this))
27472 {
27473 visiting(true);
27474 if (class_decl_sptr pattern = get_pattern())
27475 pattern->traverse(v);
27476 visiting(false);
27477 }
27478 return v.visit_end(this);
27479}
27480
27481class_tdecl::~class_tdecl()
27482{}
27483
27484/// This visitor checks if a given type as non-canonicalized sub
27485/// types.
27486class non_canonicalized_subtype_detector : public ir::ir_node_visitor
27487{
27488 type_base* type_;
27489 type_base* has_non_canonical_type_;
27490
27491private:
27492 non_canonicalized_subtype_detector();
27493
27494public:
27495 non_canonicalized_subtype_detector(type_base* type)
27496 : type_(type),
27497 has_non_canonical_type_()
27498 {}
27499
27500 /// Return true if the visitor detected that there is a
27501 /// non-canonicalized sub-type.
27502 ///
27503 /// @return true if the visitor detected that there is a
27504 /// non-canonicalized sub-type.
27505 type_base*
27506 has_non_canonical_type() const
27507 {return has_non_canonical_type_;}
27508
27509 /// The intent of this visitor handler is to avoid looking into
27510 /// sub-types of member functions of the type we are traversing.
27511 bool
27512 visit_begin(function_decl* f)
27513 {
27514 // Do not look at sub-types of non-virtual member functions.
27515 if (is_member_function(f)
27517 return false;
27518 return true;
27519 }
27520
27521 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
27522 /// the 'has_non_canonical_type' flag. And in any case, when
27523 /// visiting a sub-type, do not visit its children nodes. So this
27524 /// function only goes to the level below the level of the top-most
27525 /// type.
27526 ///
27527 /// @return true if we are at the same level as the top-most type,
27528 /// otherwise return false.
27529 bool
27530 visit_begin(type_base* t)
27531 {
27532 if (t != type_)
27533 {
27534 if (!t->get_canonical_type())
27535 // We are looking a sub-type of 'type_' which has no
27536 // canonical type. So tada! we found one! Get out right
27537 // now with the trophy.
27538 has_non_canonical_type_ = t;
27539
27540 return false;
27541 }
27542 return true;
27543 }
27544
27545 /// When we are done visiting a sub-type, if it's been flagged as
27546 /// been non-canonicalized, then stop the traversing.
27547 ///
27548 /// Otherwise, keep going.
27549 ///
27550 /// @return false iff the sub-type that has been visited is
27551 /// non-canonicalized.
27552 bool
27553 visit_end(type_base* )
27554 {
27555 if (has_non_canonical_type_)
27556 return false;
27557 return true;
27558 }
27559}; //end class non_canonicalized_subtype_detector
27560
27561/// Test if a type has sub-types that are non-canonicalized.
27562///
27563/// @param t the type which sub-types to consider.
27564///
27565/// @return true if a type has sub-types that are non-canonicalized.
27566type_base*
27568{
27569 if (!t)
27570 return 0;
27571
27572 non_canonicalized_subtype_detector v(t.get());
27573 t->traverse(v);
27574 return v.has_non_canonical_type();
27575}
27576
27577/// Tests if the change of a given type effectively comes from just
27578/// its sub-types. That is, if the type has changed but its type name
27579/// hasn't changed, then the change of the type mostly likely is a
27580/// sub-type change.
27581///
27582/// @param t_v1 the first version of the type.
27583///
27584/// @param t_v2 the second version of the type.
27585///
27586/// @return true iff the type changed and the change is about its
27587/// sub-types.
27588bool
27589type_has_sub_type_changes(const type_base_sptr t_v1,
27590 const type_base_sptr t_v2)
27591{
27592 type_base_sptr t1 = strip_typedef(t_v1);
27593 type_base_sptr t2 = strip_typedef(t_v2);
27594
27595 string repr1 = get_pretty_representation(t1, /*internal=*/false),
27596 repr2 = get_pretty_representation(t2, /*internal=*/false);
27597 return (t1 != t2 && repr1 == repr2);
27598}
27599
27600/// Make sure that the life time of a given (smart pointer to a) type
27601/// is the same as the life time of the libabigail library.
27602///
27603/// @param t the type to consider.
27604void
27605keep_type_alive(type_base_sptr t)
27606{
27607 const environment& env = t->get_environment();
27608 env.priv_->extra_live_types_.push_back(t);
27609}
27610
27611/// Hash an ABI artifact that is either a type or a decl.
27612///
27613/// This function intends to provides the fastest possible hashing for
27614/// types and decls, while being completely correct.
27615///
27616/// Note that if the artifact is a type and if it has a canonical
27617/// type, the hash value is going to be the pointer value of the
27618/// canonical type. Otherwise, this function computes a hash value
27619/// for the type by recursively walking the type members. This last
27620/// code path is possibly *very* slow and should only be used when
27621/// only handful of types are going to be hashed.
27622///
27623/// If the artifact is a decl, then a combination of the hash of its
27624/// type and the hash of the other properties of the decl is computed.
27625///
27626/// @param tod the type or decl to hash.
27627///
27628/// @return the resulting hash value.
27629size_t
27631{
27632 size_t result = 0;
27633
27634 if (tod == 0)
27635 ;
27636 else if (const type_base* t = is_type(tod))
27637 result = hash_type(t);
27638 else if (const decl_base* d = is_decl(tod))
27639 {
27640 if (var_decl* v = is_var_decl(d))
27641 {
27642 ABG_ASSERT(v->get_type());
27643 size_t h = hash_type_or_decl(v->get_type());
27644 string repr = v->get_pretty_representation(/*internal=*/true);
27645 std::hash<string> hash_string;
27646 h = hashing::combine_hashes(h, hash_string(repr));
27647 result = h;
27648 }
27649 else if (function_decl* f = is_function_decl(d))
27650 {
27651 ABG_ASSERT(f->get_type());
27652 size_t h = hash_type_or_decl(f->get_type());
27653 string repr = f->get_pretty_representation(/*internal=*/true);
27654 std::hash<string> hash_string;
27655 h = hashing::combine_hashes(h, hash_string(repr));
27656 result = h;
27657 }
27659 {
27660 type_base_sptr parm_type = p->get_type();
27661 ABG_ASSERT(parm_type);
27662 std::hash<bool> hash_bool;
27663 std::hash<unsigned> hash_unsigned;
27664 size_t h = hash_type_or_decl(parm_type);
27665 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
27666 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
27667 result = h;
27668 }
27669 else if (class_decl::base_spec *bs = is_class_base_spec(d))
27670 {
27671 member_base::hash hash_member;
27672 std::hash<size_t> hash_size;
27673 std::hash<bool> hash_bool;
27674 type_base_sptr type = bs->get_base_class();
27675 size_t h = hash_type_or_decl(type);
27676 h = hashing::combine_hashes(h, hash_member(*bs));
27677 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
27678 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
27679 result = h;
27680 }
27681 else
27682 // This is a *really* *SLOW* path. If it shows up in a
27683 // performance profile, I bet it'd be a good idea to try to
27684 // avoid it altogether.
27685 result = d->get_hash();
27686 }
27687 else
27688 // We should never get here.
27689 abort();
27690 return result;
27691}
27692
27693/// Hash an ABI artifact that is either a type.
27694///
27695/// This function intends to provides the fastest possible hashing for
27696/// types while being completely correct.
27697///
27698/// Note that if the type artifact has a canonical type, the hash
27699/// value is going to be the pointer value of the canonical type.
27700/// Otherwise, this function computes a hash value for the type by
27701/// recursively walking the type members. This last code path is
27702/// possibly *very* slow and should only be used when only handful of
27703/// types are going to be hashed.
27704///
27705/// @param t the type or decl to hash.
27706///
27707/// @return the resulting hash value.
27708size_t
27710{return hash_as_canonical_type_or_constant(t);}
27711
27712/// Hash an ABI artifact that is either a type of a decl.
27713///
27714/// @param tod the ABI artifact to hash.
27715///
27716/// @return the hash value of the ABI artifact.
27717size_t
27719{return hash_type_or_decl(tod.get());}
27720
27721/// Test if a given type is allowed to be non canonicalized
27722///
27723/// This is a subroutine of hash_as_canonical_type_or_constant.
27724///
27725/// For now, the only types allowed to be non canonicalized in the
27726/// system are (typedefs & pointers to) decl-only class/union, the
27727/// void type and variadic parameter types.
27728///
27729/// @return true iff @p t is a one of the only types allowed to be
27730/// non-canonicalized in the system.
27731bool
27733{
27734 if (!t)
27735 return true;
27736
27737 return (// The IR nodes for the types below are unique across the
27738 // entire ABI corpus. Thus, no need to canonicalize them.
27739 // Maybe we could say otherwise and canonicalize them once
27740 // for all so that they can be removed from here.
27742
27743 // An IR node for the types below can be equal to several
27744 // other types (i.e, a decl-only type t equals a fully
27745 // defined type of the same name in ODR-supported
27746 // languages). Hence, they can't be given a canonical type.
27747 //
27748 // TODO: Maybe add a mode that would detect ODR violations
27749 // that would make a decl-only type co-exists with several
27750 // different definitions of the type in the ABI corpus.
27753 /*look_through_decl_only=*/true)
27755
27756}
27757
27758/// Test if a type is unique in the entire environment.
27759///
27760/// Examples of unique types are void, void* and variadic parameter
27761/// types.
27762///
27763/// @param t the type to test for.
27764///
27765/// @return true iff the type @p t is unique in the entire
27766/// environment.
27767bool
27768is_unique_type(const type_base_sptr& t)
27769{return is_unique_type(t.get());}
27770
27771/// Test if a type is unique in the entire environment.
27772///
27773/// Examples of unique types are void, void* and variadic parameter
27774/// types.
27775///
27776/// @param t the type to test for.
27777///
27778/// @return true iff the type @p t is unique in the entire
27779/// environment.
27780bool
27782{
27783 if (!t)
27784 return false;
27785
27786 const environment& env = t->get_environment();
27787 return (env.is_void_type(t)
27788 || env.is_void_pointer_type(t)
27789 || env.is_variadic_parameter_type(t));
27790}
27791
27792/// For a given type, return its exemplar type.
27793///
27794/// For a given type, its exemplar type is either its canonical type
27795/// or the canonical type of the definition type of a given
27796/// declaration-only type. If the neither of those two types exist,
27797/// then the exemplar type is the given type itself.
27798///
27799/// @param type the input to consider.
27800///
27801/// @return the exemplar type.
27802type_base*
27804{
27805 if (decl_base * decl = is_decl(type))
27806 {
27807 // Make sure we get the real definition of a decl-only type.
27808 decl = look_through_decl_only(decl);
27809 type = is_type(decl);
27810 ABG_ASSERT(type);
27811 }
27812 type_base *exemplar = type->get_naked_canonical_type();
27813 if (!exemplar)
27814 {
27815 // The type has no canonical type. Let's be sure that it's one
27816 // of those rare types that are allowed to be non canonicalized
27817 // in the system.
27818 exemplar = const_cast<type_base*>(type);
27820 }
27821 return exemplar;
27822}
27823
27824/// Test if a given type is allowed to be non canonicalized
27825///
27826/// This is a subroutine of hash_as_canonical_type_or_constant.
27827///
27828/// For now, the only types allowed to be non canonicalized in the
27829/// system are decl-only class/union and the void type.
27830///
27831/// @return true iff @p t is a one of the only types allowed to be
27832/// non-canonicalized in the system.
27833bool
27834is_non_canonicalized_type(const type_base_sptr& t)
27835{return is_non_canonicalized_type(t.get());}
27836
27837/// Hash a type by either returning the pointer value of its canonical
27838/// type or by returning a constant if the type doesn't have a
27839/// canonical type.
27840///
27841/// This is a subroutine of hash_type.
27842///
27843/// @param t the type to consider.
27844///
27845/// @return the hash value.
27846static size_t
27847hash_as_canonical_type_or_constant(const type_base *t)
27848{
27849 type_base *canonical_type = 0;
27850
27851 if (t)
27852 canonical_type = t->get_naked_canonical_type();
27853
27854 if (!canonical_type)
27855 {
27856 // If the type doesn't have a canonical type, maybe it's because
27857 // it's a declaration-only type? If that's the case, let's try
27858 // to get the canonical type of the definition of this
27859 // declaration.
27860 decl_base *decl = is_decl(t);
27861 if (decl
27862 && decl->get_is_declaration_only()
27864 {
27865 type_base *definition =
27867 ABG_ASSERT(definition);
27868 canonical_type = definition->get_naked_canonical_type();
27869 }
27870 }
27871
27872 if (canonical_type)
27873 return reinterpret_cast<size_t>(canonical_type);
27874
27875 // If we reached this point, it means we are seeing a
27876 // non-canonicalized type. It must be a decl-only class or a void
27877 // type, otherwise it means that for some weird reason, the type
27878 // hasn't been canonicalized. It should be!
27880
27881 return 0xDEADBABE;
27882}
27883
27884/// Test if the pretty representation of a given @ref function_decl is
27885/// lexicographically less then the pretty representation of another
27886/// @ref function_decl.
27887///
27888/// @param f the first @ref function_decl to consider for comparison.
27889///
27890/// @param s the second @ref function_decl to consider for comparison.
27891///
27892/// @return true iff the pretty representation of @p f is
27893/// lexicographically less than the pretty representation of @p s.
27894bool
27896{
27899
27900 if (fr != sr)
27901 return fr < sr;
27902
27903 fr = f.get_pretty_representation(/*internal=*/true),
27904 sr = s.get_pretty_representation(/*internal=*/true);
27905
27906 if (fr != sr)
27907 return fr < sr;
27908
27909 if (f.get_symbol())
27910 fr = f.get_symbol()->get_id_string();
27911 else if (!f.get_linkage_name().empty())
27912 fr = f.get_linkage_name();
27913
27914 if (s.get_symbol())
27915 sr = s.get_symbol()->get_id_string();
27916 else if (!s.get_linkage_name().empty())
27917 sr = s.get_linkage_name();
27918
27919 return fr < sr;
27920}
27921
27922/// Test if two types have similar structures, even though they are
27923/// (or can be) different.
27924///
27925/// const and volatile qualifiers are completely ignored.
27926///
27927/// typedef are resolved to their definitions; their names are ignored.
27928///
27929/// Two indirect types (pointers or references) have similar structure
27930/// if their underlying types are of the same kind and have the same
27931/// name. In the indirect types case, the size of the underlying type
27932/// does not matter.
27933///
27934/// Two direct types (i.e, non indirect) have a similar structure if
27935/// they have the same kind, name and size. Two class types have
27936/// similar structure if they have the same name, size, and if the
27937/// types of their data members have similar types.
27938///
27939/// @param first the first type to consider.
27940///
27941/// @param second the second type to consider.
27942///
27943/// @param indirect_type whether to do an indirect comparison
27944///
27945/// @return true iff @p first and @p second have similar structures.
27946bool
27947types_have_similar_structure(const type_base_sptr& first,
27948 const type_base_sptr& second,
27949 bool indirect_type)
27950{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
27951
27952/// Test if two types have similar structures, even though they are
27953/// (or can be) different.
27954///
27955/// const and volatile qualifiers are completely ignored.
27956///
27957/// typedef are resolved to their definitions; their names are ignored.
27958///
27959/// Two indirect types (pointers, references or arrays) have similar
27960/// structure if their underlying types are of the same kind and have
27961/// the same name. In the indirect types case, the size of the
27962/// underlying type does not matter.
27963///
27964/// Two direct types (i.e, non indirect) have a similar structure if
27965/// they have the same kind, name and size. Two class types have
27966/// similar structure if they have the same name, size, and if the
27967/// types of their data members have similar types.
27968///
27969/// @param first the first type to consider.
27970///
27971/// @param second the second type to consider.
27972///
27973/// @param indirect_type if true, then consider @p first and @p
27974/// second as being underlying types of indirect types. Meaning that
27975/// their size does not matter.
27976///
27977/// @return true iff @p first and @p second have similar structures.
27978bool
27980 const type_base* second,
27981 bool indirect_type)
27982{
27983 if (!!first != !!second)
27984 return false;
27985
27986 if (!first)
27987 return false;
27988
27989 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
27990 first = peel_qualified_or_typedef_type(first);
27991 second = peel_qualified_or_typedef_type(second);
27992
27993 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
27994 // various ty2 below cannot be null.
27995 if (typeid(*first) != typeid(*second))
27996 return false;
27997
27998 // Peel off matching pointers.
27999 if (const pointer_type_def* ty1 = is_pointer_type(first))
28000 {
28001 const pointer_type_def* ty2 = is_pointer_type(second);
28002 return types_have_similar_structure(ty1->get_pointed_to_type(),
28003 ty2->get_pointed_to_type(),
28004 /*indirect_type=*/true);
28005 }
28006
28007 // Peel off matching references.
28008 if (const reference_type_def* ty1 = is_reference_type(first))
28009 {
28010 const reference_type_def* ty2 = is_reference_type(second);
28011 if (ty1->is_lvalue() != ty2->is_lvalue())
28012 return false;
28013 return types_have_similar_structure(ty1->get_pointed_to_type(),
28014 ty2->get_pointed_to_type(),
28015 /*indirect_type=*/true);
28016 }
28017
28018 // Peel off matching pointer-to-member types.
28019 if (const ptr_to_mbr_type* ty1 = is_ptr_to_mbr_type(first))
28020 {
28021 const ptr_to_mbr_type* ty2 = is_ptr_to_mbr_type(second);
28022 return (types_have_similar_structure(ty1->get_member_type(),
28023 ty2->get_member_type(),
28024 /*indirect_type=*/true)
28025 && types_have_similar_structure(ty1->get_containing_type(),
28026 ty2->get_containing_type(),
28027 /*indirect_type=*/true));
28028 }
28029
28030 if (const type_decl* ty1 = is_type_decl(first))
28031 {
28032 const type_decl* ty2 = is_type_decl(second);
28033 if (!indirect_type)
28034 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28035 return false;
28036
28037 return ty1->get_name() == ty2->get_name();
28038 }
28039
28040 if (const enum_type_decl* ty1 = is_enum_type(first))
28041 {
28042 const enum_type_decl* ty2 = is_enum_type(second);
28043 if (!indirect_type)
28044 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28045 return false;
28046
28047 return (get_name(ty1->get_underlying_type())
28048 == get_name(ty2->get_underlying_type()));
28049 }
28050
28051 if (const class_decl* ty1 = is_class_type(first))
28052 {
28053 const class_decl* ty2 = is_class_type(second);
28054 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28055 && ty1->get_name() != ty2->get_name())
28056 return false;
28057
28058 if (!indirect_type)
28059 {
28060 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
28061 || (ty1->get_non_static_data_members().size()
28062 != ty2->get_non_static_data_members().size()))
28063 return false;
28064
28065 for (class_or_union::data_members::const_iterator
28066 i = ty1->get_non_static_data_members().begin(),
28067 j = ty2->get_non_static_data_members().begin();
28068 (i != ty1->get_non_static_data_members().end()
28069 && j != ty2->get_non_static_data_members().end());
28070 ++i, ++j)
28071 {
28072 var_decl_sptr dm1 = *i;
28073 var_decl_sptr dm2 = *j;
28074 if (!types_have_similar_structure(dm1->get_type().get(),
28075 dm2->get_type().get(),
28076 indirect_type))
28077 return false;
28078 }
28079 }
28080
28081 return true;
28082 }
28083
28084 if (const union_decl* ty1 = is_union_type(first))
28085 {
28086 const union_decl* ty2 = is_union_type(second);
28087 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28088 && ty1->get_name() != ty2->get_name())
28089 return false;
28090
28091 if (!indirect_type)
28092 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
28093
28094 return true;
28095 }
28096
28097 if (const array_type_def* ty1 = is_array_type(first))
28098 {
28099 const array_type_def* ty2 = is_array_type(second);
28100 // TODO: Handle int[5][2] vs int[2][5] better.
28101 if (!indirect_type)
28102 {
28103 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
28104 || ty1->get_dimension_count() != ty2->get_dimension_count())
28105 return false;
28106 }
28107
28108 if (!types_have_similar_structure(ty1->get_element_type(),
28109 ty2->get_element_type(),
28110 /*indirect_type=*/true))
28111 return false;
28112
28113 return true;
28114 }
28115
28116 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
28117 {
28119 if (ty1->get_upper_bound() != ty2->get_upper_bound()
28120 || ty1->get_lower_bound() != ty2->get_lower_bound()
28121 || ty1->get_language() != ty2->get_language()
28122 || !types_have_similar_structure(ty1->get_underlying_type(),
28123 ty2->get_underlying_type(),
28124 indirect_type))
28125 return false;
28126
28127 return true;
28128 }
28129
28130 if (const function_type* ty1 = is_function_type(first))
28131 {
28132 const function_type* ty2 = is_function_type(second);
28133 if (!types_have_similar_structure(ty1->get_return_type(),
28134 ty2->get_return_type(),
28135 indirect_type))
28136 return false;
28137
28138 if (ty1->get_parameters().size() != ty2->get_parameters().size())
28139 return false;
28140
28141 for (function_type::parameters::const_iterator
28142 i = ty1->get_parameters().begin(),
28143 j = ty2->get_parameters().begin();
28144 (i != ty1->get_parameters().end()
28145 && j != ty2->get_parameters().end());
28146 ++i, ++j)
28147 if (!types_have_similar_structure((*i)->get_type(),
28148 (*j)->get_type(),
28149 indirect_type))
28150 return false;
28151
28152 return true;
28153 }
28154
28155 // All kinds of type should have been handled at this point.
28157
28158 return false;
28159}
28160
28161/// Look for a data member of a given class, struct or union type and
28162/// return it.
28163///
28164/// The data member is designated by its name.
28165///
28166/// @param type the class, struct or union type to consider.
28167///
28168/// @param dm_name the name of the data member to lookup.
28169///
28170/// @return the data member iff it was found in @type or NULL if no
28171/// data member with that name was found.
28172const var_decl*
28174 const char* dm_name)
28175
28176{
28178 if (!cou)
28179 return 0;
28180
28181 return cou->find_data_member(dm_name).get();
28182}
28183
28184/// Look for a data member of a given class, struct or union type and
28185/// return it.
28186///
28187/// The data member is designated by its name.
28188///
28189/// @param type the class, struct or union type to consider.
28190///
28191/// @param dm the data member to lookup.
28192///
28193/// @return the data member iff it was found in @type or NULL if no
28194/// data member with that name was found.
28195const var_decl_sptr
28196lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
28197{
28198 class_or_union_sptr cou = is_class_or_union_type(type);
28199 if (!cou)
28200 return var_decl_sptr();
28201
28202 return cou->find_data_member(dm);
28203}
28204
28205/// Get the function parameter designated by its index.
28206///
28207/// Note that the first function parameter has index 0.
28208///
28209/// @param fun the function to consider.
28210///
28211/// @param parm_index the index of the function parameter to get.
28212///
28213/// @return the function parameter designated by its index, of NULL if
28214/// no function parameter with that index was found.
28217 unsigned parm_index)
28218{
28220 if (!fn)
28221 return 0;
28222
28223 const function_decl::parameters &parms = fn->get_type()->get_parameters();
28224 if (parms.size() <= parm_index)
28225 return 0;
28226
28227 return parms[parm_index].get();
28228}
28229
28230/// Build the internal name of the underlying type of an enum.
28231///
28232/// @param base_name the (unqualified) name of the enum the underlying
28233/// type is destined to.
28234///
28235/// @param is_anonymous true if the underlying type of the enum is to
28236/// be anonymous.
28237string
28239 bool is_anonymous,
28240 uint64_t size)
28241{
28242 std::ostringstream o;
28243
28244 if (is_anonymous)
28245 o << "unnamed-enum";
28246 else
28247 o << "enum-" << base_name;
28248
28249 o << "-underlying-type-" << size;
28250
28251 return o.str();
28252}
28253
28254/// Find the first data member of a class or union which name matches
28255/// a regular expression.
28256///
28257/// @param t the class or union to consider.
28258///
28259/// @param r the regular expression to consider.
28260///
28261/// @return the data member matched by @p r or nil if none was found.
28264 const regex::regex_t_sptr& r)
28265{
28266 for (auto data_member : t.get_data_members())
28267 {
28268 if (regex::match(r, data_member->get_name()))
28269 return data_member;
28270 }
28271
28272 return var_decl_sptr();
28273}
28274
28275/// Find the last data member of a class or union which name matches
28276/// a regular expression.
28277///
28278/// @param t the class or union to consider.
28279///
28280/// @param r the regular expression to consider.
28281///
28282/// @return the data member matched by @p r or nil if none was found.
28285 const regex::regex_t_sptr& regex)
28286{
28287 auto d = t.get_data_members().rbegin();
28288 auto e = t.get_data_members().rend();
28289 for (; d != e; ++d)
28290 {
28291 if (regex::match(regex, (*d)->get_name()))
28292 return *d;
28293 }
28294
28295 return var_decl_sptr();
28296}
28297
28298/// Emit the pretty representation of the parameters of a function
28299/// type.
28300///
28301/// @param fn_type the function type to consider.
28302///
28303/// @param o the output stream to emit the pretty representation to.
28304///
28305/// @param qualified if true, emit fully qualified names.
28306///
28307/// @param internal if true, then the result is to be used for the
28308/// purpose of type canonicalization.
28309static void
28310stream_pretty_representation_of_fn_parms(const function_type& fn_type,
28311 ostream& o, bool qualified,
28312 bool internal)
28313{
28314 o << "(";
28315 if (fn_type.get_parameters().empty())
28316 o << "void";
28317 else
28318 {
28319 type_base_sptr type;
28320 auto end = fn_type.get_parameters().end();
28321 auto first_parm = fn_type.get_first_non_implicit_parm();
28323 const environment& env = fn_type.get_environment();
28324 for (auto i = fn_type.get_first_non_implicit_parm(); i != end; ++i)
28325 {
28326 if (i != first_parm)
28327 o << ", ";
28328 parm = *i;
28329 type = parm->get_type();
28330 if (env.is_variadic_parameter_type(type))
28331 o << "...";
28332 else
28333 {
28334 if (internal)
28335 type = peel_typedef_type(type);
28336 o << get_type_name(type, qualified, internal);
28337 }
28338 }
28339 }
28340 o << ")";
28341}
28342
28343/// When constructing the name of a pointer to function type, add the
28344/// return type to the left of the existing type identifier, and the
28345/// parameters declarator to the right.
28346///
28347/// This function considers the name of the type as an expression.
28348///
28349/// The resulting type expr is going to be made of three parts:
28350/// left_expr inner_expr right_expr.
28351///
28352/// Suppose we want to build the type expression representing:
28353///
28354/// "an array of pointer to function taking a char parameter and
28355/// returning an int".
28356///
28357/// It's going to look like:
28358///
28359/// int(*a[])(char);
28360///
28361/// Suppose the caller of this function started to emit the inner
28362/// "a[]" part of the expression already. It thus calls this
28363/// function with that input "a[]" part. We consider that "a[]" as
28364/// the "type identifier".
28365///
28366/// So the inner_expr is going to be "(*a[])".
28367///
28368/// The left_expr part is "int". The right_expr part is "(char)".
28369///
28370/// In other words, this function adds the left_expr and right_expr to
28371/// the inner_expr. left_expr and right_expr are called "outer
28372/// pointer to function type expression".
28373///
28374/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28375/// array_declaration_name()
28376///
28377/// @param p the pointer to function type to consider.
28378///
28379/// @param input the type-id to use as the inner expression of the
28380/// overall pointer-to-function type expression
28381///
28382/// @param qualified if true then use qualified names in the resulting
28383/// type name.
28384///
28385/// @param internal if true then the resulting type name is going to
28386/// be used for type canonicalization purposes.
28387///
28388/// @return the name of the pointer to function type.
28389static string
28390add_outer_pointer_to_fn_type_expr(const type_base* p,
28391 const string& input,
28392 bool qualified, bool internal)
28393{
28394 if (!p)
28395 return "";
28396
28397 function_type_sptr pointed_to_fn;
28398 string star_or_ref;
28399
28400 if (const pointer_type_def* ptr = is_pointer_type(p))
28401 {
28402 pointed_to_fn = is_function_type(ptr->get_pointed_to_type());
28403 star_or_ref= "*";
28404 }
28405 else if (const reference_type_def* ref = is_reference_type(p))
28406 {
28407 star_or_ref = "&";
28408 pointed_to_fn = is_function_type(ref->get_pointed_to_type());
28409 }
28410
28411 if (!pointed_to_fn)
28412 return "";
28413
28414 std::ostringstream left, right, inner;
28415
28416 inner << "(" << star_or_ref << input << ")";
28417
28418 type_base_sptr type;
28419 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
28420 qualified, internal);
28421 type_base_sptr return_type =
28422 internal
28423 ? peel_typedef_type(pointed_to_fn->get_return_type())
28424 : pointed_to_fn->get_return_type();
28425
28426 string result;
28427
28428 if (is_npaf_type(return_type)
28429 || !(is_pointer_to_function_type(return_type)
28430 || is_pointer_to_array_type(return_type)))
28431 {
28432 if (return_type)
28433 left << get_type_name(return_type, qualified, internal);
28434 result = left.str() + " " + inner.str() + right.str();
28435 }
28436 else if (pointer_type_def_sptr p = is_pointer_to_function_type(return_type))
28437 {
28438 string inner_string = inner.str() + right.str();
28439 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
28440 qualified, internal);
28441 }
28442 else if (pointer_type_def_sptr p = is_pointer_to_array_type(return_type))
28443 {
28444 string inner_string = inner.str() + right.str();
28445 result = add_outer_pointer_to_array_type_expr(p, inner_string,
28446 qualified, internal);
28447 }
28448 else
28450
28451 return result;
28452}
28453
28454/// When constructing the name of a pointer to function type, add the
28455/// return type to the left of the existing type identifier, and the
28456/// parameters declarator to the right.
28457///
28458/// This function considers the name of the type as an expression.
28459///
28460/// The resulting type expr is going to be made of three parts:
28461/// left_expr inner_expr right_expr.
28462///
28463/// Suppose we want to build the type expression representing:
28464///
28465/// "an array of pointer to function taking a char parameter and
28466/// returning an int".
28467///
28468/// It's going to look like:
28469///
28470/// int(*a[])(char);
28471///
28472/// Suppose the caller of this function started to emit the inner
28473/// "a[]" part of the expression already. It thus calls this
28474/// function with that input "a[]" part. We consider that "a[]" as
28475/// the "type identifier".
28476///
28477/// So the inner_expr is going to be "(*a[])".
28478///
28479/// The left_expr part is "int". The right_expr part is "(char)".
28480///
28481/// In other words, this function adds the left_expr and right_expr to
28482/// the inner_expr. left_expr and right_expr are called "outer
28483/// pointer to function type expression".
28484///
28485/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28486/// array_declaration_name()
28487///
28488/// @param p the pointer to function type to consider.
28489///
28490/// @param input the type-id to use as the inner expression of the
28491/// overall pointer-to-function type expression
28492///
28493/// @param qualified if true then use qualified names in the resulting
28494/// type name.
28495///
28496/// @param internal if true then the resulting type name is going to
28497/// be used for type canonicalization purposes.
28498///
28499/// @return the name of the pointer to function type.
28500static string
28501add_outer_pointer_to_fn_type_expr(const type_base_sptr& p,
28502 const string& input,
28503 bool qualified, bool internal)
28504{return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
28505
28506/// When constructing the name of a pointer to array type, add the
28507/// array element type type to the left of the existing type
28508/// identifier, and the array declarator part to the right.
28509///
28510/// This function considers the name of the type as an expression.
28511///
28512/// The resulting type expr is going to be made of three parts:
28513/// left_expr inner_expr right_expr.
28514///
28515/// Suppose we want to build the type expression representing:
28516///
28517/// "a pointer to an array of int".
28518///
28519/// It's going to look like:
28520///
28521/// int(*foo)[];
28522///
28523/// Suppose the caller of this function started to emit the inner
28524/// "foo" part of the expression already. It thus calls this function
28525/// with that input "foo" part. We consider that "foo" as the "type
28526/// identifier".
28527///
28528/// So we are passed an input string that is "foo" and it's going to
28529/// be turned into the inner_expr part, which is going to be "(*foo)".
28530///
28531/// The left_expr part is "int". The right_expr part is "[]".
28532///
28533/// In other words, this function adds the left_expr and right_expr to
28534/// the inner_expr. left_expr and right_expr are called "outer
28535/// pointer to array type expression".
28536///
28537/// The model of this function was taken from the article "Reading C
28538/// type declaration", from Steve Friedl at
28539/// http://unixwiz.net/techtips/reading-cdecl.html.
28540///
28541/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28542/// array_declaration_name()
28543///
28544/// @param p the pointer to array type to consider.
28545///
28546/// @param input the type-id to start from as the inner part of the
28547/// final type name.
28548///
28549/// @param qualified if true then use qualified names in the resulting
28550/// type name.
28551///
28552/// @param internal if true then the resulting type name is going to
28553/// be used for type canonicalization purposes.
28554///
28555/// @return the name of the pointer to array type.
28556static string
28557add_outer_pointer_to_array_type_expr(const type_base* p,
28558 const string& input, bool qualified,
28559 bool internal)
28560{
28561 if (!p)
28562 return "";
28563
28564 string star_or_ref;
28565 type_base_sptr pointed_to_type;
28566
28567 if (const pointer_type_def *ptr = is_pointer_type(p))
28568 {
28569 pointed_to_type = ptr->get_pointed_to_type();
28570 star_or_ref = "*";
28571 }
28572 else if (const reference_type_def *ref = is_reference_type(p))
28573 {
28574 pointed_to_type = ref->get_pointed_to_type();
28575 star_or_ref = "&";
28576 }
28577
28578 array_type_def_sptr array = is_array_type(pointed_to_type);
28579 if (!array)
28580 return "";
28581
28582 std::ostringstream left, right, inner;
28583 inner << "(" << star_or_ref << input << ")";
28584 right << array->get_subrange_representation();
28585 string result;
28586
28587 type_base_sptr array_element_type = array->get_element_type();
28588
28589 if (is_npaf_type(array_element_type)
28590 || !(is_pointer_to_function_type(array_element_type)
28591 || is_pointer_to_array_type(array_element_type)))
28592 {
28593 left << get_type_name(array_element_type, qualified, internal);
28594 result = left.str() + inner.str() + right.str();
28595 }
28596 else if (pointer_type_def_sptr p =
28597 is_pointer_to_function_type(array_element_type))
28598 {
28599 string r = inner.str() + right.str();
28600 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
28601 }
28602 else if (pointer_type_def_sptr p =
28603 is_pointer_to_array_type(array_element_type))
28604 {
28605 string inner_string = inner.str() + right.str();
28606 result = add_outer_pointer_to_array_type_expr(p, inner_string,
28607 qualified, internal);
28608 }
28609 else
28611
28612 return result;
28613}
28614
28615/// When constructing the name of a pointer to array type, add the
28616/// array element type type to the left of the existing type
28617/// identifier, and the array declarator part to the right.
28618///
28619/// This function considers the name of the type as an expression.
28620///
28621/// The resulting type expr is going to be made of three parts:
28622/// left_expr inner_expr right_expr.
28623///
28624/// Suppose we want to build the type expression representing:
28625///
28626/// "a pointer to an array of int".
28627///
28628/// It's going to look like:
28629///
28630/// int(*foo)[];
28631///
28632/// Suppose the caller of this function started to emit the inner
28633/// "foo" part of the expression already. It thus calls this function
28634/// with that input "foo" part. We consider that "foo" as the "type
28635/// identifier".
28636///
28637/// So we are passed an input string that is "foo" and it's going to
28638/// be turned into the inner_expr part, which is going to be "(*foo)".
28639///
28640/// The left_expr part is "int". The right_expr part is "[]".
28641///
28642/// In other words, this function adds the left_expr and right_expr to
28643/// the inner_expr. left_expr and right_expr are called "outer
28644/// pointer to array type expression".
28645///
28646/// The model of this function was taken from the article "Reading C
28647/// type declaration", from Steve Friedl at
28648/// http://unixwiz.net/techtips/reading-cdecl.html.
28649///
28650/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28651/// array_declaration_name()
28652///
28653/// @param p the pointer to array type to consider.
28654///
28655/// @param input the type-id to start from as the inner part of the
28656/// final type name.
28657///
28658/// @param qualified if true then use qualified names in the resulting
28659/// type name.
28660///
28661/// @param internal if true then the resulting type name is going to
28662/// be used for type canonicalization purposes.
28663///
28664/// @return the name of the pointer to array type.
28665static string
28666add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
28667 const string& input, bool qualified,
28668 bool internal)
28669{return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
28670 input, qualified, internal);}
28671
28672/// When constructing the name of a pointer to mebmer type, add the
28673/// return type to the left of the existing type identifier, and the
28674/// parameters declarator to the right.
28675///
28676/// This function considers the name of the type as an expression.
28677///
28678/// The resulting type expr is going to be made of three parts:
28679/// left_expr inner_expr right_expr.
28680///
28681/// Suppose we want to build the type expression representing:
28682///
28683/// "an array of pointer to member function (of a containing struct
28684/// X) taking a char parameter and returning an int".
28685///
28686/// It's going to look like:
28687///
28688/// int (X::* a[])(char);
28689///
28690/// Suppose the caller of this function started to emit the inner
28691/// "a[]" part of the expression already. It thus calls this
28692/// function with that input "a[]" part. We consider that "a[]" as
28693/// the "type identifier".
28694///
28695/// So the inner_expr is going to be "(X::* a[])".
28696///
28697/// The left_expr part is "int". The right_expr part is "(char)".
28698///
28699/// In other words, this function adds the left_expr and right_expr to
28700/// the inner_expr. left_expr and right_expr are called "outer
28701/// pointer to member type expression".
28702///
28703/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
28704///
28705/// @param p the pointer to member type to consider.
28706///
28707/// @param input the type-id to use as the inner expression of the
28708/// overall pointer-to-member type expression
28709///
28710/// @param qualified if true then use qualified names in the resulting
28711/// type name.
28712///
28713/// @param internal if true then the resulting type name is going to
28714/// be used for type canonicalization purposes.
28715///
28716/// @return the name of the pointer to member type.
28717static string
28718add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
28719 const string& input, bool qualified,
28720 bool internal)
28721{
28722 if (!p)
28723 return "";
28724
28725 std::ostringstream left, right, inner;
28726 string containing_type_name = get_type_name(p->get_containing_type(),
28727 qualified, internal);
28728 type_base_sptr mbr_type = p->get_member_type();
28729 string result;
28730 if (function_type_sptr fn_type = is_function_type(mbr_type))
28731 {
28732 inner << "(" << containing_type_name << "::*" << input << ")";
28733 stream_pretty_representation_of_fn_parms(*fn_type, right,
28734 qualified, internal);
28735 type_base_sptr return_type = fn_type->get_return_type();
28736 if (is_npaf_type(return_type)
28737 || !(is_pointer_to_function_type(return_type)
28738 || is_pointer_to_array_type(return_type)
28739 || is_pointer_to_ptr_to_mbr_type(return_type)
28740 || is_ptr_to_mbr_type(return_type)))
28741 {
28742 left << get_type_name(return_type, qualified, internal) << " ";;
28743 result = left.str() + inner.str() + right.str();
28744 }
28745 else if (pointer_type_def_sptr p = is_pointer_type(return_type))
28746 {
28747 string inner_str = inner.str() + right.str();
28748 result = pointer_declaration_name(p, inner_str, qualified, internal);
28749 }
28750 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(return_type))
28751 {
28752 string inner_str = inner.str() + right.str();
28753 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
28754 qualified, internal);
28755 }
28756 else
28758 }
28759 else if (ptr_to_mbr_type_sptr ptr_mbr_type = is_ptr_to_mbr_type(mbr_type))
28760 {
28761 inner << "(" << containing_type_name << "::*" << input << ")";
28762 stream_pretty_representation_of_fn_parms(*fn_type, right,
28763 qualified, internal);
28764 string inner_str = inner.str() + right.str();
28765 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
28766 qualified, internal);
28767 }
28768 else
28769 {
28770 left << get_type_name(p->get_member_type(), qualified, internal) << " ";
28771 inner << containing_type_name << "::*" << input;
28772 result = left.str()+ inner.str();
28773 }
28774
28775 return result;
28776}
28777
28778/// When constructing the name of a pointer to mebmer type, add the
28779/// return type to the left of the existing type identifier, and the
28780/// parameters declarator to the right.
28781///
28782/// This function considers the name of the type as an expression.
28783///
28784/// The resulting type expr is going to be made of three parts:
28785/// left_expr inner_expr right_expr.
28786///
28787/// Suppose we want to build the type expression representing:
28788///
28789/// "an array of pointer to member function (of a containing struct
28790/// X) taking a char parameter and returning an int".
28791///
28792/// It's going to look like:
28793///
28794/// int (X::* a[])(char);
28795///
28796/// Suppose the caller of this function started to emit the inner
28797/// "a[]" part of the expression already. It thus calls this
28798/// function with that input "a[]" part. We consider that "a[]" as
28799/// the "type identifier".
28800///
28801/// So the inner_expr is going to be "(X::* a[])".
28802///
28803/// The left_expr part is "int". The right_expr part is "(char)".
28804///
28805/// In other words, this function adds the left_expr and right_expr to
28806/// the inner_expr. left_expr and right_expr are called "outer
28807/// pointer to member type expression".
28808///
28809/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
28810///
28811/// @param p the pointer to member type to consider.
28812///
28813/// @param input the type-id to use as the inner expression of the
28814/// overall pointer-to-member type expression
28815///
28816/// @param qualified if true then use qualified names in the resulting
28817/// type name.
28818///
28819/// @param internal if true then the resulting type name is going to
28820/// be used for type canonicalization purposes.
28821///
28822/// @return the name of the pointer to member type.
28823static string
28824add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
28825 const string& input, bool qualified,
28826 bool internal)
28827{return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
28828
28829/// This adds the outer parts of a pointer to a pointer-to-member
28830/// expression.
28831///
28832/// Please read the comments of @ref add_outer_ptr_to_mbr_type_expr to
28833/// learn more about this function, which is similar.
28834///
28835/// This is a sub-routine of @ref pointer_declaration_name().
28836///
28837/// @param a pointer (or reference) to a pointer-to-member type.
28838///
28839/// @param input the inner type-id to add the outer parts to.
28840///
28841/// @param qualified if true then use qualified names in the resulting
28842/// type name.
28843///
28844/// @param internal if true then the resulting type name is going to
28845/// be used for type canonicalization purposes.
28846static string
28847add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
28848 const string& input, bool qualified,
28849 bool internal)
28850{
28851 if (!p)
28852 return "";
28853
28854 string star_or_ref;
28855 type_base_sptr pointed_to_type;
28856
28857 if (const pointer_type_def* ptr = is_pointer_type(p))
28858 {
28859 pointed_to_type = ptr->get_pointed_to_type();
28860 star_or_ref = "*";
28861 }
28862 else if (const reference_type_def* ref = is_reference_type(p))
28863 {
28864 pointed_to_type= ref->get_pointed_to_type();
28865 star_or_ref = "&";
28866 }
28867
28868 if (!pointed_to_type)
28869 return "";
28870
28871 ptr_to_mbr_type_sptr pointed_to_ptr_to_mbr =
28872 is_ptr_to_mbr_type(pointed_to_type);
28873 if (!pointed_to_ptr_to_mbr)
28874 return "";
28875
28876 std::ostringstream inner;
28877 inner << star_or_ref << input;
28878 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
28879 inner.str(),
28880 qualified, internal);
28881 return result;
28882}
28883
28884/// Emit the name of a pointer declaration.
28885///
28886/// @param the pointer to consider.
28887///
28888/// @param idname the name of the variable that has @p as a type or
28889/// the id of the type. If it's empty then the resulting name is
28890/// going to be the abstract name of the type.
28891///
28892/// @param qualified if true then the type name is going to be
28893/// fully qualified.
28894///
28895/// @param internal if true then the type name is going to be used for
28896/// type canonicalization purposes.
28897static interned_string
28898pointer_declaration_name(const type_base* ptr,
28899 const string& idname,
28900 bool qualified, bool internal)
28901{
28902 if (!ptr)
28903 return interned_string();
28904
28905 type_base_sptr pointed_to_type;
28906 string star_or_ref;
28907 if (const pointer_type_def* p = is_pointer_type(ptr))
28908 {
28909 pointed_to_type = p->get_pointed_to_type();
28910 star_or_ref = "*";
28911 }
28912 else if (const reference_type_def* p = is_reference_type(ptr))
28913 {
28914 pointed_to_type = p->get_pointed_to_type();
28915 star_or_ref = "&";
28916 }
28917
28918 if (!pointed_to_type)
28919 return interned_string();
28920
28921 string result;
28922 if (is_npaf_type(pointed_to_type)
28923 || !(is_function_type(pointed_to_type)
28924 || is_array_type(pointed_to_type)
28925 || is_ptr_to_mbr_type(pointed_to_type)))
28926 {
28927 result = get_type_name(pointed_to_type,
28928 qualified,
28929 internal)
28930 + star_or_ref;
28931
28932 if (!idname.empty())
28933 result += idname;
28934 }
28935 else
28936 {
28937 // derived type
28938 if (is_function_type(pointed_to_type))
28939 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
28940 qualified, internal);
28941 else if (is_array_type(pointed_to_type))
28942 result = add_outer_pointer_to_array_type_expr(ptr, idname,
28943 qualified, internal);
28944 else if (is_ptr_to_mbr_type(pointed_to_type))
28945 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
28946 qualified, internal);
28947 else
28949 }
28950 return ptr->get_environment().intern(result);
28951}
28952
28953
28954/// Emit the name of a pointer declaration.
28955///
28956/// @param the pointer to consider.
28957///
28958/// @param the name of the variable that has @p as a type. If it's
28959/// empty then the resulting name is going to be the abstract name of
28960/// the type.
28961///
28962/// @param qualified if true then the type name is going to be
28963/// fully qualified.
28964///
28965/// @param internal if true then the type name is going to be used for
28966/// type canonicalization purposes.
28967static interned_string
28968pointer_declaration_name(const type_base_sptr& ptr,
28969 const string& variable_name,
28970 bool qualified, bool internal)
28971{return pointer_declaration_name(ptr.get(), variable_name,
28972 qualified, internal);}
28973
28974/// Emit the name of a array declaration.
28975///
28976/// @param the array to consider.
28977///
28978/// @param the name of the variable that has @p as a type. If it's
28979/// empty then the resulting name is going to be the abstract name of
28980/// the type.
28981///
28982/// @param qualified if true then the type name is going to be
28983/// fully qualified.
28984///
28985/// @param internal if true then the type name is going to be used for
28986/// type canonicalization purposes.
28987static interned_string
28988array_declaration_name(const array_type_def* array,
28989 const string& variable_name,
28990 bool qualified, bool internal)
28991{
28992 if (!array)
28993 return interned_string();
28994
28995 type_base_sptr e_type = array->get_element_type();
28996 string e_type_repr =
28997 (e_type
28998 ? get_type_name(e_type, qualified, internal)
28999 : string("void"));
29000
29001 string result;
29002 if (is_ada_language(array->get_language()))
29003 {
29004 std::ostringstream o;
29005 if (!variable_name.empty())
29006 o << variable_name << " is ";
29007 o << "array ("
29008 << array->get_subrange_representation()
29009 << ") of " << e_type_repr;
29010 result = o.str();
29011 }
29012 else
29013 {
29014 if (is_npaf_type(e_type)
29015 || !(is_pointer_to_function_type(e_type)
29016 || is_pointer_to_array_type(e_type)
29018 || is_ptr_to_mbr_type(e_type)))
29019 {
29020 result = e_type_repr;
29021 if (!variable_name.empty())
29022 result += variable_name;
29023 result += array->get_subrange_representation();
29024 }
29025 else if (pointer_type_def_sptr p = is_pointer_type(e_type))
29026 {
29027 string s = variable_name + array->get_subrange_representation();
29028 result = pointer_declaration_name(p, s, qualified, internal);
29029 }
29030 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(e_type))
29031 {
29032 string s = variable_name + array->get_subrange_representation();
29033 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
29034 }
29035 else
29037 }
29038 return array->get_environment().intern(result);
29039}
29040
29041/// Emit the name of a array declaration.
29042///
29043/// @param the array to consider.
29044///
29045/// @param the name of the variable that has @p as a type. If it's
29046/// empty then the resulting name is going to be the abstract name of
29047/// the type.
29048///
29049/// @param qualified if true then the type name is going to be
29050/// fully qualified.
29051///
29052/// @param internal if true then the type name is going to be used for
29053/// type canonicalization purposes.
29054static interned_string
29055array_declaration_name(const array_type_def_sptr& array,
29056 const string& variable_name,
29057 bool qualified, bool internal)
29058{return array_declaration_name(array.get(), variable_name,
29059 qualified, internal);}
29060
29061/// Emit the name of a pointer-to-member declaration.
29062///
29063/// @param ptr the pointer-to-member to consider.
29064///
29065/// @param variable_name the name of the variable that has @p as a
29066/// type. If it's empty then the resulting name is going to be the
29067/// abstract name of the type.
29068///
29069/// @param qualified if true then the type name is going to be
29070/// fully qualified.
29071///
29072/// @param internal if true then the type name is going to be used for
29073/// type canonicalization purposes.
29074static interned_string
29075ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
29076 const string& variable_name,
29077 bool qualified, bool internal)
29078{
29079 if (!ptr)
29080 return interned_string();
29081
29082 string input = variable_name;
29083 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
29084 qualified, internal);
29085 return ptr->get_environment().intern(result);
29086}
29087
29088/// Emit the name of a pointer-to-member declaration.
29089///
29090/// @param ptr the pointer-to-member to consider.
29091///
29092/// @param variable_name the name of the variable that has @p as a
29093/// type. If it's empty then the resulting name is going to be the
29094/// abstract name of the type.
29095///
29096/// @param qualified if true then the type name is going to be
29097/// fully qualified.
29098///
29099/// @param internal if true then the type name is going to be used for
29100/// type canonicalization purposes.
29101static interned_string
29102ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
29103 const string& variable_name,
29104 bool qualified, bool internal)
29105{
29106 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
29107 qualified, internal);
29108}
29109
29110bool
29112{return true;}
29113
29114// <ir_node_visitor stuff>
29115
29116/// The private data structure of the ir_node_visitor type.
29117struct ir_node_visitor::priv
29118{
29119 pointer_set visited_ir_nodes;
29121
29122 priv()
29124 {}
29125}; // end struct ir_node_visitory::priv
29126
29127/// Default Constructor of the ir_node_visitor type.
29129 : priv_(new priv)
29130{}
29131
29132ir_node_visitor::~ir_node_visitor() = default;
29133
29134/// Set if the walker using this visitor is allowed to re-visit a type
29135/// node that was previously visited or not.
29136///
29137/// @param f if true, then the walker using this visitor is allowed to
29138/// re-visit a type node that was previously visited.
29139void
29141{priv_->allow_visiting_already_visited_type_node = f;}
29142
29143/// Get if the walker using this visitor is allowed to re-visit a type
29144/// node that was previously visited or not.
29145///
29146/// @return true iff the walker using this visitor is allowed to
29147/// re-visit a type node that was previously visited.
29148bool
29150{return priv_->allow_visiting_already_visited_type_node;}
29151
29152/// Mark a given type node as having been visited.
29153///
29154/// Note that for this function to work, the type node must have been
29155/// canonicalized. Otherwise the process is aborted.
29156///
29157/// @param p the type to mark as having been visited.
29158void
29160{
29162 return;
29163
29164 if (p == 0 || type_node_has_been_visited(p))
29165 return;
29166
29167 type_base* canonical_type = p->get_naked_canonical_type();
29169 {
29170 ABG_ASSERT(!canonical_type);
29171 canonical_type = p;
29172 }
29173 ABG_ASSERT(canonical_type);
29174
29175 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
29176 priv_->visited_ir_nodes.insert(canonical_ptr_value);
29177}
29178
29179/// Un-mark all visited type nodes.
29180///
29181/// That is, no type node is going to be considered as having been
29182/// visited anymore.
29183///
29184/// In other words, after invoking this funciton,
29185/// ir_node_visitor::type_node_has_been_visited() is going to return
29186/// false on all type nodes.
29187void
29189{priv_->visited_ir_nodes.clear();}
29190
29191/// Test if a given type node has been marked as visited.
29192///
29193/// @param p the type node to consider.
29194///
29195/// @return true iff the type node @p p has been marked as visited by
29196/// the function ir_node_visitor::mark_type_node_as_visited.
29197bool
29199{
29201 return false;
29202
29203 if (p == 0)
29204 return false;
29205
29206 type_base *canonical_type = p->get_naked_canonical_type();
29208 {
29209 ABG_ASSERT(!canonical_type);
29210 canonical_type = p;
29211 }
29212 ABG_ASSERT(canonical_type);
29213
29214 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
29215 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
29216 if (it == priv_->visited_ir_nodes.end())
29217 return false;
29218
29219 return true;
29220}
29221
29222bool
29223ir_node_visitor::visit_begin(decl_base*)
29224{return true;}
29225
29226bool
29227ir_node_visitor::visit_end(decl_base*)
29228{return true;}
29229
29230bool
29231ir_node_visitor::visit_begin(scope_decl*)
29232{return true;}
29233
29234bool
29235ir_node_visitor::visit_end(scope_decl*)
29236{return true;}
29237
29238bool
29239ir_node_visitor::visit_begin(type_base*)
29240{return true;}
29241
29242bool
29243ir_node_visitor::visit_end(type_base*)
29244{return true;}
29245
29246bool
29247ir_node_visitor::visit_begin(scope_type_decl* t)
29248{return visit_begin(static_cast<type_base*>(t));}
29249
29250bool
29251ir_node_visitor::visit_end(scope_type_decl* t)
29252{return visit_end(static_cast<type_base*>(t));}
29253
29254bool
29255ir_node_visitor::visit_begin(type_decl* t)
29256{return visit_begin(static_cast<type_base*>(t));}
29257
29258bool
29259ir_node_visitor::visit_end(type_decl* t)
29260{return visit_end(static_cast<type_base*>(t));}
29261
29262bool
29263ir_node_visitor::visit_begin(namespace_decl* d)
29264{return visit_begin(static_cast<decl_base*>(d));}
29265
29266bool
29267ir_node_visitor::visit_end(namespace_decl* d)
29268{return visit_end(static_cast<decl_base*>(d));}
29269
29270bool
29271ir_node_visitor::visit_begin(qualified_type_def* t)
29272{return visit_begin(static_cast<type_base*>(t));}
29273
29274bool
29275ir_node_visitor::visit_end(qualified_type_def* t)
29276{return visit_end(static_cast<type_base*>(t));}
29277
29278bool
29279ir_node_visitor::visit_begin(pointer_type_def* t)
29280{return visit_begin(static_cast<type_base*>(t));}
29281
29282bool
29283ir_node_visitor::visit_end(pointer_type_def* t)
29284{return visit_end(static_cast<type_base*>(t));}
29285
29286bool
29287ir_node_visitor::visit_begin(reference_type_def* t)
29288{return visit_begin(static_cast<type_base*>(t));}
29289
29290bool
29291ir_node_visitor::visit_end(reference_type_def* t)
29292{return visit_end(static_cast<type_base*>(t));}
29293
29294bool
29295ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
29296{return visit_begin(static_cast<type_base*>(t));}
29297
29298bool
29299ir_node_visitor::visit_end(ptr_to_mbr_type* t)
29300{return visit_end(static_cast<type_base*>(t));}
29301
29302bool
29303ir_node_visitor::visit_begin(array_type_def* t)
29304{return visit_begin(static_cast<type_base*>(t));}
29305
29306bool
29307ir_node_visitor::visit_end(array_type_def* t)
29308{return visit_end(static_cast<type_base*>(t));}
29309
29310bool
29311ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
29312{return visit_begin(static_cast<type_base*>(t));}
29313
29314bool
29315ir_node_visitor::visit_end(array_type_def::subrange_type* t)
29316{return visit_end(static_cast<type_base*>(t));}
29317
29318bool
29319ir_node_visitor::visit_begin(enum_type_decl* t)
29320{return visit_begin(static_cast<type_base*>(t));}
29321
29322bool
29323ir_node_visitor::visit_end(enum_type_decl* t)
29324{return visit_end(static_cast<type_base*>(t));}
29325
29326bool
29327ir_node_visitor::visit_begin(typedef_decl* t)
29328{return visit_begin(static_cast<type_base*>(t));}
29329
29330bool
29331ir_node_visitor::visit_end(typedef_decl* t)
29332{return visit_end(static_cast<type_base*>(t));}
29333
29334bool
29335ir_node_visitor::visit_begin(function_type* t)
29336{return visit_begin(static_cast<type_base*>(t));}
29337
29338bool
29339ir_node_visitor::visit_end(function_type* t)
29340{return visit_end(static_cast<type_base*>(t));}
29341
29342bool
29343ir_node_visitor::visit_begin(var_decl* d)
29344{return visit_begin(static_cast<decl_base*>(d));}
29345
29346bool
29347ir_node_visitor::visit_end(var_decl* d)
29348{return visit_end(static_cast<decl_base*>(d));}
29349
29350bool
29351ir_node_visitor::visit_begin(function_decl* d)
29352{return visit_begin(static_cast<decl_base*>(d));}
29353
29354bool
29355ir_node_visitor::visit_end(function_decl* d)
29356{return visit_end(static_cast<decl_base*>(d));}
29357
29358bool
29359ir_node_visitor::visit_begin(function_decl::parameter* d)
29360{return visit_begin(static_cast<decl_base*>(d));}
29361
29362bool
29363ir_node_visitor::visit_end(function_decl::parameter* d)
29364{return visit_end(static_cast<decl_base*>(d));}
29365
29366bool
29367ir_node_visitor::visit_begin(function_tdecl* d)
29368{return visit_begin(static_cast<decl_base*>(d));}
29369
29370bool
29371ir_node_visitor::visit_end(function_tdecl* d)
29372{return visit_end(static_cast<decl_base*>(d));}
29373
29374bool
29375ir_node_visitor::visit_begin(class_tdecl* d)
29376{return visit_begin(static_cast<decl_base*>(d));}
29377
29378bool
29379ir_node_visitor::visit_end(class_tdecl* d)
29380{return visit_end(static_cast<decl_base*>(d));}
29381
29382bool
29383ir_node_visitor::visit_begin(class_or_union* t)
29384{return visit_begin(static_cast<type_base*>(t));}
29385
29386bool
29387ir_node_visitor::visit_end(class_or_union* t)
29388{return visit_end(static_cast<type_base*>(t));}
29389
29390bool
29391ir_node_visitor::visit_begin(class_decl* t)
29392{return visit_begin(static_cast<type_base*>(t));}
29393
29394bool
29395ir_node_visitor::visit_end(class_decl* t)
29396{return visit_end(static_cast<type_base*>(t));}
29397
29398bool
29399ir_node_visitor::visit_begin(union_decl* t)
29400{return visit_begin(static_cast<type_base*>(t));}
29401
29402bool
29403ir_node_visitor::visit_end(union_decl* t)
29404{return visit_end(static_cast<type_base*>(t));}
29405
29406bool
29407ir_node_visitor::visit_begin(class_decl::base_spec* d)
29408{return visit_begin(static_cast<decl_base*>(d));}
29409
29410bool
29411ir_node_visitor::visit_end(class_decl::base_spec* d)
29412{return visit_end(static_cast<decl_base*>(d));}
29413
29414bool
29415ir_node_visitor::visit_begin(member_function_template* d)
29416{return visit_begin(static_cast<decl_base*>(d));}
29417
29418bool
29419ir_node_visitor::visit_end(member_function_template* d)
29420{return visit_end(static_cast<decl_base*>(d));}
29421
29422bool
29423ir_node_visitor::visit_begin(member_class_template* d)
29424{return visit_begin(static_cast<decl_base*>(d));}
29425
29426bool
29427ir_node_visitor::visit_end(member_class_template* d)
29428{return visit_end(static_cast<decl_base*>(d));}
29429
29430// </ir_node_visitor stuff>
29431
29432// <debugging facilities>
29433
29434/// Generate a different string at each invocation.
29435///
29436/// @return the resulting string.
29437static string
29438get_next_string()
29439{
29440 static __thread size_t counter;
29441 ++counter;
29442 std::ostringstream o;
29443 o << counter;
29444 return o.str();
29445}
29446
29447/// Convenience typedef for a hash map of pointer to function_decl and
29448/// string.
29449typedef unordered_map<const function_decl*, string,
29450 function_decl::hash,
29452
29453/// Return a string associated to a given function. Two functions
29454/// that compare equal would yield the same string, as far as this
29455/// routine is concerned. And two functions that are different would
29456/// yield different strings.
29457///
29458/// This is used to debug core diffing issues on functions. The
29459/// sequence of strings can be given to the 'testdiff2' program that
29460/// is in the tests/ directory of the source tree, to reproduce core
29461/// diffing issues on string and thus ease the debugging.
29462///
29463/// @param fn the function to generate a string for.
29464///
29465/// @param m the function_decl* <-> string map to be used by this
29466/// function to generate strings associated to a function.
29467///
29468/// @return the resulting string.
29469static const string&
29470fn_to_str(const function_decl* fn,
29472{
29473 fns_to_str_map_type::const_iterator i = m.find(fn);
29474 if (i != m.end())
29475 return i->second;
29476 string s = get_next_string();
29477 return m[fn]= s;
29478}
29479
29480/// Generate a sequence of string that matches a given sequence of
29481/// function. In the resulting sequence, each function is "uniquely
29482/// representated" by a string. For instance, if the same function "foo"
29483/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
29484/// we don't care about the actual string) would appear at index 1 and 3.
29485///
29486/// @param begin the beginning of the sequence of functions to consider.
29487///
29488/// @param end the end of the sequence of functions. This points to
29489/// one-passed-the-end of the actual sequence.
29490///
29491/// @param m the function_decl* <-> string map to be used by this
29492/// function to generate strings associated to a function.
29493///
29494/// @param o the output stream where to emit the generated list of
29495/// strings to.
29496static void
29497fns_to_str(vector<function_decl*>::const_iterator begin,
29498 vector<function_decl*>::const_iterator end,
29500 std::ostream& o)
29501{
29502 vector<function_decl*>::const_iterator i;
29503 for (i = begin; i != end; ++i)
29504 o << "'" << fn_to_str(*i, m) << "' ";
29505}
29506
29507/// For each sequence of functions given in argument, generate a
29508/// sequence of string that matches a given sequence of function. In
29509/// the resulting sequence, each function is "uniquely representated"
29510/// by a string. For instance, if the same function "foo" appears at
29511/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
29512/// care about the actual string) would appear at index 1 and 3.
29513///
29514/// @param a_begin the beginning of the sequence of functions to consider.
29515///
29516/// @param a_end the end of the sequence of functions. This points to
29517/// one-passed-the-end of the actual sequence.
29518///
29519/// @param b_begin the beginning of the second sequence of functions
29520/// to consider.
29521///
29522/// @param b_end the end of the second sequence of functions.
29523///
29524/// @param m the function_decl* <-> string map to be used by this
29525/// function to generate strings associated to a function.
29526///
29527/// @param o the output stream where to emit the generated list of
29528/// strings to.
29529static void
29530fns_to_str(vector<function_decl*>::const_iterator a_begin,
29531 vector<function_decl*>::const_iterator a_end,
29532 vector<function_decl*>::const_iterator b_begin,
29533 vector<function_decl*>::const_iterator b_end,
29535 std::ostream& o)
29536{
29537 fns_to_str(a_begin, a_end, m, o);
29538 o << "->|<- ";
29539 fns_to_str(b_begin, b_end, m, o);
29540 o << "\n";
29541}
29542
29543/// For each sequence of functions given in argument, generate a
29544/// sequence of string that matches a given sequence of function. In
29545/// the resulting sequence, each function is "uniquely representated"
29546/// by a string. For instance, if the same function "foo" appears at
29547/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
29548/// care about the actual string) would appear at index 1 and 3.
29549///
29550/// @param a_begin the beginning of the sequence of functions to consider.
29551///
29552/// @param a_end the end of the sequence of functions. This points to
29553/// one-passed-the-end of the actual sequence.
29554///
29555/// @param b_begin the beginning of the second sequence of functions
29556/// to consider.
29557///
29558/// @param b_end the end of the second sequence of functions.
29559///
29560/// @param o the output stream where to emit the generated list of
29561/// strings to.
29562void
29563fns_to_str(vector<function_decl*>::const_iterator a_begin,
29564 vector<function_decl*>::const_iterator a_end,
29565 vector<function_decl*>::const_iterator b_begin,
29566 vector<function_decl*>::const_iterator b_end,
29567 std::ostream& o)
29568{
29570 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
29571}
29572
29573// </debugging facilities>
29574
29575// </class template>
29576
29577}// end namespace ir
29578}//end namespace abigail
29579
29580namespace
29581{
29582
29583/// Update the qualified parent name, qualified name and scoped name
29584/// of a tree decl node.
29585///
29586/// @return true if the tree walking should continue, false otherwise.
29587///
29588/// @param d the tree node to take in account.
29589bool
29590qualified_name_setter::do_update(abigail::ir::decl_base* d)
29591{
29592 std::string parent_qualified_name;
29593 abigail::ir::scope_decl* parent = d->get_scope();
29594 if (parent)
29595 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
29596 else
29597 d->priv_->qualified_parent_name_ = abigail::interned_string();
29598
29599 const abigail::ir::environment& env = d->get_environment();
29600
29601 if (!d->priv_->qualified_parent_name_.empty())
29602 {
29603 if (d->get_name().empty())
29604 d->priv_->qualified_name_ = abigail::interned_string();
29605 else
29606 {
29607 d->priv_->qualified_name_ =
29608 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
29609 d->priv_->internal_qualified_name_ = env.intern(d->get_name());
29610 }
29611 }
29612
29613 if (d->priv_->scoped_name_.empty())
29614 {
29615 if (parent
29616 && !parent->get_is_anonymous()
29617 && !parent->get_name().empty())
29618 d->priv_->scoped_name_ =
29619 env.intern(parent->get_name() + "::" + d->get_name());
29620 else
29621 d->priv_->scoped_name_ =
29622 env.intern(d->get_name());
29623 }
29624
29625 if (!is_scope_decl(d))
29626 return false;
29627
29628 return true;
29629}
29630
29631/// This is called when we start visiting a decl node, during the
29632/// udpate of the qualified name of a given sub-tree.
29633///
29634/// @param d the decl node we are visiting.
29635///
29636/// @return true iff the traversal should keep going.
29637bool
29638qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
29639{return do_update(d);}
29640
29641/// This is called when we start visiting a type node, during the
29642/// udpate of the qualified name of a given sub-tree.
29643///
29644/// @param d the decl node we are visiting.
29645///
29646/// @return true iff the traversal should keep going.
29647bool
29648qualified_name_setter::visit_begin(abigail::ir::type_base* t)
29649{
29651 return do_update(d);
29652 return false;
29653}
29654}// 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:1714
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:1201
#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:993
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:97
const char * get_string(const char *s) const
Get a pointer to the interned string which has a given value.
Definition: abg-ir.cc:107
interned_string create_string(const std::string &)
Create an interned string with a given value.
Definition: abg-ir.cc:124
interned_string_pool()
Default constructor.
Definition: abg-ir.cc:84
~interned_string_pool()
Destructor.
Definition: abg-ir.cc:133
The abstraction of an interned string.
bool empty() const
Test if the current instance of interned_string is empty.
This class is to hold the value of the bound of a subrange. The value can be either signed or unsigne...
Definition: abg-ir.h:2560
void set_signed(int64_t v)
Setter of the bound value as signed.
Definition: abg-ir.cc:18543
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:18511
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:18504
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition: abg-ir.cc:18518
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition: abg-ir.cc:18555
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition: abg-ir.cc:18526
bound_value()
Default constructor of the array_type_def::subrange_type::bound_value class.
Definition: abg-ir.cc:18476
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition: abg-ir.cc:18533
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++.
Definition: abg-ir.h:2545
void set_lower_bound(int64_t lb)
Setter of the lower bound.
Definition: abg-ir.cc:18720
bool is_non_finite() const
Test if the length of the subrange type is infinite.
Definition: abg-ir.cc:18747
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition: abg-ir.cc:18713
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:18687
string as_string() const
Return a string representation of the sub range.
Definition: abg-ir.cc:18769
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18958
bool operator!=(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:18897
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition: abg-ir.cc:18699
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:18679
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:18853
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition: abg-ir.cc:18706
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:18936
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition: abg-ir.cc:18792
uint64_t get_length() const
Getter of the length of the subrange type.
Definition: abg-ir.cc:18730
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition: abg-ir.cc:18762
The abstraction of an array type.
Definition: abg-ir.h:2519
virtual bool is_non_finite() const
Definition: abg-ir.cc:19295
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:19325
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition: abg-ir.cc:19256
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition: abg-ir.cc:19271
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition: abg-ir.h:2537
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19388
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition: abg-ir.cc:19415
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:19234
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
Definition: abg-ir.h:2540
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of array_type_def.
Definition: abg-ir.cc:19104
translation_unit::language get_language() const
Get the language of the array.
Definition: abg-ir.cc:19223
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition: abg-ir.cc:19281
Abstraction of a base specifier in a class declaration.
Definition: abg-ir.h:4430
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
Definition: abg-ir.cc:24536
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition: abg-ir.cc:24543
long get_offset_in_bits() const
Getter of the offset of the base.
Definition: abg-ir.cc:24550
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:24576
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Definition: abg-ir.cc:24670
virtual size_t get_hash() const
Calculate the hash value for a class_decl::base_spec.
Definition: abg-ir.cc:24557
Abstracts a class declaration.
Definition: abg-ir.h:4233
void is_struct(bool f)
Set the "is-struct" flag of the class.
Definition: abg-ir.cc:24347
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition: abg-ir.cc:25127
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:24416
bool is_struct() const
Test if the class is a struct.
Definition: abg-ir.cc:24354
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition: abg-ir.cc:24371
virtual ~class_decl()
Destructor of the class_decl type.
Definition: abg-ir.cc:25727
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:24332
bool has_vtable() const
Test if the current instance has a vtable.
Definition: abg-ir.cc:25155
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition: abg-ir.cc:25169
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition: abg-ir.cc:25136
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:25643
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition: abg-ir.h:4251
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
Definition: abg-ir.cc:24361
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition: abg-ir.cc:24397
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition: abg-ir.cc:24421
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition: abg-ir.cc:25307
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition: abg-ir.cc:25495
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition: abg-ir.cc:25118
virtual size_t get_hash() const
Return the hash value for the current instance.
Definition: abg-ir.cc:25186
class_decl_sptr find_base_class(const string &) const
Find a base class of a given qualified name for the current class.
Definition: abg-ir.cc:24381
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition: abg-ir.h:4252
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:24442
The base type of class_decl and union_decl.
Definition: abg-ir.h:4031
virtual size_t get_num_anonymous_member_classes() const
Get the number of anonymous member classes contained in this class.
Definition: abg-ir.cc:23190
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:23408
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:23341
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition: abg-ir.cc:23436
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
Definition: abg-ir.cc:23076
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition: abg-ir.cc:23512
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition: abg-ir.cc:23175
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition: abg-ir.cc:23208
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
Definition: abg-ir.cc:23526
unordered_map< ssize_t, member_functions > virtual_mem_fn_map_type
Convenience typedef.
Definition: abg-ir.h:4063
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition: abg-ir.h:4062
const data_members & get_data_members() const
Get the data members of this class_or_union.
Definition: abg-ir.cc:23300
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:23257
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:23487
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:23471
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition: abg-ir.cc:23159
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
Definition: abg-ir.cc:23568
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:23064
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:22982
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition: abg-ir.cc:23540
const data_members & get_non_static_data_members() const
Get the non-static data memebers of this class_or_union.
Definition: abg-ir.cc:23391
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:23445
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:23101
vector< var_decl_sptr > data_members
Convenience typedef.
Definition: abg-ir.h:4061
virtual ~class_or_union()
Destrcutor of the class_or_union type.
Definition: abg-ir.cc:23055
bool has_no_member() const
Definition: abg-ir.cc:23553
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:23602
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26030
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition: abg-ir.cc:23127
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition: abg-ir.cc:23519
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition: abg-ir.cc:23143
vector< type_base_sptr > member_types
Convenience typedef.
Definition: abg-ir.h:4060
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
Definition: abg-ir.cc:23226
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:23311
Abstract a class template.
Definition: abg-ir.h:3834
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition: abg-ir.cc:27417
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
Definition: abg-ir.cc:27406
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:27466
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:27421
The abstraction of the relationship between an entity and its containing scope (its context)....
Definition: abg-ir.h:1247
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition: abg-corpus.h:25
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr<exported_decls_builder>.
Definition: abg-corpus.h:45
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
Definition: abg-corpus.cc:743
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
Definition: abg-corpus.cc:775
type_maps & get_type_per_loc_map()
Get the maps that associate a location string to a certain kind of type.
Definition: abg-corpus.cc:884
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
Definition: abg-corpus.cc:892
const environment & get_environment() const
Getter of the enviroment of the corpus.
Definition: abg-corpus.cc:698
The base type of all declarations.
Definition: abg-ir.h:1538
void set_definition_of_declaration(const decl_base_sptr &)
Set the definition of this declaration-only decl_base.
Definition: abg-ir.cc:15729
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:4948
virtual bool operator!=(const decl_base &) const
Inequality operator.
Definition: abg-ir.cc:5206
scope_decl * get_scope() const
Return the type containing the current decl, if any.
Definition: abg-ir.cc:4777
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
Definition: abg-ir.cc:4486
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:4570
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:5561
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
Definition: abg-ir.cc:4896
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
Definition: abg-ir.cc:4752
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:4932
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition: abg-ir.cc:4808
void clear_qualified_name()
Clear the qualified name of this decl.
Definition: abg-ir.cc:4479
void set_name(const string &n)
Setter for the name of the decl.
Definition: abg-ir.cc:4640
const location & get_location() const
Get the location of a given declaration.
Definition: abg-ir.cc:4590
binding
ELF binding.
Definition: abg-ir.h:1589
typedef_decl_sptr get_naming_typedef() const
Getter for the naming typedef of the current decl.
Definition: abg-ir.cc:4700
const interned_string & get_name() const
Getter for the name of the current decl.
Definition: abg-ir.cc:4796
virtual void set_scope(scope_decl *)
Setter of the scope of the current decl.
Definition: abg-ir.cc:5233
const interned_string & peek_qualified_name() const
Getter for the qualified name.
Definition: abg-ir.cc:4470
const context_rel * get_context_rel() const
Getter for the context relationship.
Definition: abg-ir.cc:4520
friend void set_member_function_is_virtual(function_decl &, bool)
Set the virtual-ness of a member function.
Definition: abg-ir.cc:6665
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Definition: abg-ir.cc:4653
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:8370
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
Definition: abg-ir.cc:4888
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:4916
friend void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5530
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
Definition: abg-ir.cc:4718
void set_location(const location &l)
Set the location for a given declaration.
Definition: abg-ir.cc:4628
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
Definition: abg-ir.cc:4663
void set_visibility(visibility v)
Setter for the visibility of the decl.
Definition: abg-ir.cc:4769
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4513
visibility get_visibility() const
Getter for the visibility of the decl.
Definition: abg-ir.cc:4762
visibility
ELF visibility.
Definition: abg-ir.h:1579
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Definition: abg-ir.cc:4939
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:5222
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition: abg-ir.cc:4904
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition: abg-ir.cc:4745
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5501
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6627
virtual ~decl_base()
Destructor of the decl_base type.
Definition: abg-ir.cc:5210
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:5195
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:4789
bool get_is_anonymous_or_has_anonymous_parent() const
Definition: abg-ir.cc:4686
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
Definition: abg-ir.cc:4675
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:4562
friend bool equals(const decl_base &, const decl_base &, change_kind *)
Compares two instances of decl_base.
Definition: abg-ir.cc:5112
virtual size_t get_hash() const
Get the hash of a decl. If the hash hasn't been computed yet, compute it ans store its value; otherwi...
Definition: abg-ir.cc:4539
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4499
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:4831
The abstraction for a data member context relationship. This relates a data member to its parent clas...
Definition: abg-ir.h:2954
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:3255
void set_anonymous_data_member(var_decl *)
Set the containing anonymous data member of this data member context relationship....
Definition: abg-ir.cc:3265
The abstraction of the version of an ELF symbol.
Definition: abg-ir.h:1194
version & operator=(const version &o)
Assign a version to the current one.
Definition: abg-ir.cc:3168
bool operator==(const version &o) const
Compares the current version against another one.
Definition: abg-ir.cc:3150
bool is_default() const
Getter for the 'is_default' property of the version.
Definition: abg-ir.cc:3130
const string & str() const
Getter for the version name.
Definition: abg-ir.cc:3116
bool operator!=(const version &o) const
Inequality operator.
Definition: abg-ir.cc:3159
Abstraction of an elf symbol.
Definition: abg-ir.h:923
const abg_compat::optional< std::string > & get_namespace() const
Getter of the 'namespace' property.
Definition: abg-ir.cc:2253
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:2576
elf_symbol_sptr get_next_common_instance() const
Get the next common instance of the current common symbol.
Definition: abg-ir.cc:2471
type get_type() const
Getter for the type of the current instance of elf_symbol.
Definition: abg-ir.cc:2087
const elf_symbol_sptr get_main_symbol() const
Get the main symbol of an alias chain.
Definition: abg-ir.cc:2308
void set_is_in_ksymtab(bool is_in_ksymtab)
Setter of the 'is-in-ksymtab' property.
Definition: abg-ir.cc:2232
bool has_aliases() const
Check if the current elf_symbol has an alias.
Definition: abg-ir.cc:2337
void set_name(const string &n)
Setter for the name of the current intance of elf_symbol.
Definition: abg-ir.cc:2077
bool is_suppressed() const
Getter for the 'is-suppressed' property.
Definition: abg-ir.cc:2269
binding
The binding of a symbol.
Definition: abg-ir.h:940
int get_number_of_aliases() const
Get the number of aliases to this elf symbol.
Definition: abg-ir.cc:2344
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:2597
void set_binding(binding b)
Setter for the binding of the current instance of elf_symbol.
Definition: abg-ir.cc:2122
void add_common_instance(const elf_symbol_sptr &)
Add a common instance to the current common elf symbol.
Definition: abg-ir.cc:2482
void add_alias(const elf_symbol_sptr &)
Add an alias to the current elf symbol.
Definition: abg-ir.cc:2361
void set_is_suppressed(bool is_suppressed)
Setter for the 'is-suppressed' property.
Definition: abg-ir.cc:2278
bool is_variable() const
Test if the current instance of elf_symbol is a variable symbol or not.
Definition: abg-ir.cc:2210
elf_symbol_sptr update_main_symbol(const std::string &)
Update the main symbol for a group of aliased symbols.
Definition: abg-ir.cc:2407
void set_size(size_t)
Setter of the size of the symbol.
Definition: abg-ir.cc:2108
const string & get_name() const
Getter for the name of the elf_symbol.
Definition: abg-ir.cc:2070
binding get_binding() const
Getter for the binding of the current instance of elf_symbol.
Definition: abg-ir.cc:2115
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:2663
bool is_function() const
Test if the current instance of elf_symbol is a function symbol or not.
Definition: abg-ir.cc:2201
type
The type of a symbol.
Definition: abg-ir.h:927
void set_version(const version &v)
Setter for the version of the current instance of elf_symbol.
Definition: abg-ir.cc:2136
const abg_compat::optional< uint32_t > & get_crc() const
Getter of the 'crc' property.
Definition: abg-ir.cc:2239
void set_visibility(visibility v)
Setter of the visibility of the current instance of elf_symbol.
Definition: abg-ir.cc:2147
bool does_alias(const elf_symbol &) const
Test if the current symbol aliases another one.
Definition: abg-ir.cc:2722
bool is_main_symbol() const
Tests whether this symbol is the main symbol.
Definition: abg-ir.cc:2322
void set_crc(const abg_compat::optional< uint32_t > &crc)
Setter of the 'crc' property.
Definition: abg-ir.cc:2246
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:1993
visibility
The visibility of the symbol.
Definition: abg-ir.h:949
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition: abg-ir.cc:2129
bool is_common_symbol() const
Return true if the symbol is a common one.
Definition: abg-ir.cc:2440
void set_index(size_t)
Setter for the index.
Definition: abg-ir.cc:2063
visibility get_visibility() const
Getter of the visibility of the current instance of elf_symbol.
Definition: abg-ir.cc:2155
bool has_other_common_instances() const
Return true if this common common symbol has other common instances.
Definition: abg-ir.cc:2456
size_t get_index() const
Getter for the index.
Definition: abg-ir.cc:2056
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
Definition: abg-ir.cc:2527
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:2554
const environment & get_environment() const
Getter of the environment used by the current instance of elf_symbol.
Definition: abg-ir.cc:2049
void set_type(type t)
Setter for the type of the current instance of elf_symbol.
Definition: abg-ir.cc:2094
bool is_public() const
Test if the current instance of elf_symbol is public or not.
Definition: abg-ir.cc:2185
bool is_in_ksymtab() const
Getter of the 'is-in-ksymtab' property.
Definition: abg-ir.cc:2224
size_t get_size() const
Getter of the size of the symbol.
Definition: abg-ir.cc:2101
bool is_defined() const
Test if the current instance of elf_symbol is defined or not.
Definition: abg-ir.cc:2163
void set_namespace(const abg_compat::optional< std::string > &ns)
Setter of the 'namespace' property.
Definition: abg-ir.cc:2260
elf_symbol_sptr get_next_alias() const
Get the next alias of the current symbol.
Definition: abg-ir.cc:2329
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:2708
The abstraction of an enumerator.
Definition: abg-ir.h:2835
enumerator()
Default constructor of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:20009
bool operator!=(const enumerator &other) const
Inequality operator.
Definition: abg-ir.cc:20069
void set_name(const string &n)
Setter for the name of enum_type_decl::enumerator.
Definition: abg-ir.cc:20111
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition: abg-ir.cc:20133
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition: abg-ir.cc:20078
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition: abg-ir.cc:20140
void set_value(int64_t v)
Setter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:20126
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:20095
int64_t get_value() const
Getter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:20119
bool operator==(const enumerator &other) const
Equality operator.
Definition: abg-ir.cc:20056
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:20040
Abstracts a declaration for an enum type.
Definition: abg-ir.h:2750
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition: abg-ir.h:2766
virtual ~enum_type_decl()
Destructor for the enum type declaration.
Definition: abg-ir.cc:19587
const enumerators & get_enumerators() const
Definition: abg-ir.cc:19487
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
Definition: abg-ir.cc:19499
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19565
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition: abg-ir.cc:19482
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:19930
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:19540
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition: abg-ir.h:140
bool decl_only_class_equals_definition() const
Getter of the "decl-only-class-equals-definition" flag.
Definition: abg-ir.cc:3498
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:3565
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:150
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:3645
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:3379
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:3597
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
Definition: abg-ir.cc:3430
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:3398
const config & get_config() const
Getter of the general configuration object.
Definition: abg-ir.cc:3635
environment()
Default constructor of the environment type.
Definition: abg-ir.cc:3280
vector< type_base_sptr > * get_canonical_types(const char *name)
Get the vector of canonical types which have a given "string representation".
Definition: abg-ir.cc:3782
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition: abg-ir.cc:3442
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:3805
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:3417
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:3534
virtual ~environment()
Destructor for the environment type.
Definition: abg-ir.cc:3285
interned_string intern(const string &) const
Do intern a string.
Definition: abg-ir.cc:3628
bool do_on_the_fly_canonicalization() const
Getter for the "on-the-fly-canonicalization" flag.
Definition: abg-ir.cc:3465
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:3671
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Definition: abg-ir.cc:3293
Abstraction of a function parameter.
Definition: abg-ir.h:3286
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
Definition: abg-ir.cc:22815
interned_string get_type_name() const
Definition: abg-ir.cc:22604
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition: abg-ir.cc:22642
const string get_type_pretty_representation() const
Definition: abg-ir.cc:22623
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition: abg-ir.cc:22780
virtual size_t get_hash() const
Get the hash of a decl. If the hash hasn't been computed yet, compute it ans store its value; otherwi...
Definition: abg-ir.cc:22800
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:22835
Abstraction for a function declaration.
Definition: abg-ir.h:3111
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3135
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:21993
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition: abg-ir.cc:22064
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:22466
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition: abg-ir.cc:22144
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition: abg-ir.cc:22369
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition: abg-ir.cc:22030
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition: abg-ir.cc:22049
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:21856
const type_base_sptr get_return_type() const
Definition: abg-ir.cc:22125
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition: abg-ir.cc:22157
const std::vector< parameter_sptr > & get_parameters() const
Definition: abg-ir.cc:22130
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition: abg-ir.cc:22137
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition: abg-ir.cc:22086
virtual ~function_decl()
Destructor of the function_decl type.
Definition: abg-ir.cc:22482
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:22102
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition: abg-ir.cc:22355
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3138
virtual size_t get_hash() const
The virtual implementation of 'get_hash' for a function_decl.
Definition: abg-ir.cc:22381
bool is_declared_inline() const
Test if the function was declared inline.
Definition: abg-ir.cc:22109
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:21925
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:22397
Abstract a function template declaration.
Definition: abg-ir.h:3785
binding get_binding() const
Get the binding of the function template.
Definition: abg-ir.cc:27254
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
Definition: abg-ir.cc:27236
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition: abg-ir.cc:27247
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:27314
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition: abg-ir.cc:27263
Abstraction of a function type.
Definition: abg-ir.h:3390
shared_ptr< function_decl::parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3400
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:21531
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition: abg-ir.cc:21216
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:21427
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:21030
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition: abg-ir.cc:21490
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:21201
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition: abg-ir.cc:21178
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition: abg-ir.cc:21447
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:21157
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition: abg-ir.cc:21120
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition: abg-ir.cc:21128
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:21405
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition: abg-ir.cc:21137
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3402
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:21514
This abstracts the global scope of a given translation unit.
Definition: abg-ir.h:1952
The internal representation of an integral type.
Definition: abg-ir-priv.h:47
void set_modifiers(modifiers_type)
Setter of the modifiers bitmap of the integral_type.
Definition: abg-ir.cc:16195
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
Definition: abg-ir.cc:16218
base_type get_base_type() const
Getter of the base type of the integral_type.
Definition: abg-ir.cc:16181
modifiers_type
The modifiers of the base types above. Several modifiers can be combined for a given base type....
Definition: abg-ir-priv.h:81
@ LONG_LONG_MODIFIER
The "long long" modifier.
Definition: abg-ir-priv.h:92
@ LONG_MODIFIER
The "long" modifier.
Definition: abg-ir-priv.h:90
@ SIGNED_MODIFIER
The "signed" modifier.
Definition: abg-ir-priv.h:84
@ UNSIGNED_MODIFIER
The "unsigned" modier.
Definition: abg-ir-priv.h:86
@ SHORT_MODIFIER
The "short" modifier.
Definition: abg-ir-priv.h:88
bool operator==(const integral_type &) const
Equality operator for the integral_type.
Definition: abg-ir.cc:16205
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:55
@ WCHAR_T_BASE_TYPE
The "wchar_t" base type.
Definition: abg-ir-priv.h:71
@ CHAR32_T_BASE_TYPE
The "char32_t" base type.
Definition: abg-ir-priv.h:69
@ FLOAT_BASE_TYPE
The "float" base type.
Definition: abg-ir-priv.h:65
@ BOOL_BASE_TYPE
The "bool" base type in C++ or "_Bool" in C11.
Definition: abg-ir-priv.h:61
@ CHAR_BASE_TYPE
The "char" base type.
Definition: abg-ir-priv.h:59
@ CHAR16_T_BASE_TYPE
The "char16_t base type.
Definition: abg-ir-priv.h:67
@ INT_BASE_TYPE
The "int" base type.
Definition: abg-ir-priv.h:57
@ DOUBLE_BASE_TYPE
The "double" base type.
Definition: abg-ir-priv.h:63
modifiers_type get_modifiers() const
Getter of the modifiers bitmap of the integral_type.
Definition: abg-ir.cc:16188
integral_type()
Default constructor of the integral_type.
Definition: abg-ir.cc:16151
The base class for the visitor type hierarchy used for traversing a translation unit.
Definition: abg-ir.h:4957
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:29149
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition: abg-ir.cc:29198
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition: abg-ir.cc:29188
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition: abg-ir.cc:29128
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition: abg-ir.cc:29159
The entry point to manage locations.
Definition: abg-ir.h:441
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:517
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:540
The source location of a token.
Definition: abg-ir.h:299
bool get_is_artificial() const
Test if the location is artificial.
Definition: abg-ir.h:340
unsigned get_value() const
Get the value of the location.
Definition: abg-ir.h:387
string expand(void) const
Expand the location into a string.
Definition: abg-ir.cc:482
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:462
Abstraction of a member function context relationship. This relates a member function to its parent c...
Definition: abg-ir.h:4558
bool is_constructor() const
Getter for the 'is-constructor' property.
Definition: abg-ir.h:4636
bool is_const() const
Getter for the 'is-const' property.
Definition: abg-ir.h:4671
size_t vtable_offset() const
Getter for the vtable offset property.
Definition: abg-ir.h:4616
bool is_destructor() const
Getter for the 'is-destructor' property.
Definition: abg-ir.h:4653
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition: abg-ir.h:3880
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition: abg-ir.h:3901
bool get_is_static() const
Definition: abg-ir.h:3913
Abstracts a member class template template.
Definition: abg-ir.h:4763
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
Definition: abg-ir.cc:25890
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:25975
Abstract a member function template.
Definition: abg-ir.h:4708
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:25869
Abstraction of the declaration of a method.
Definition: abg-ir.h:3929
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
Definition: abg-ir.cc:6524
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
Definition: abg-ir.cc:24817
const method_type_sptr get_type() const
Definition: abg-ir.cc:24844
Abstracts the type of a class member function.
Definition: abg-ir.h:3486
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:21718
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition: abg-ir.cc:21750
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
Definition: abg-ir.cc:21765
virtual ~method_type()
The destructor of method_type.
Definition: abg-ir.cc:21798
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:21742
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition: abg-ir.cc:21709
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition: abg-ir.cc:21757
The abstraction of a namespace declaration.
Definition: abg-ir.h:2197
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:16796
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:16827
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition: abg-ir.cc:16730
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition: abg-ir.cc:16782
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:16768
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:26933
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:26947
virtual size_t get_hash() const
Get the hash value of the current instance.
Definition: abg-ir.cc:26940
The abstraction of a pointer type.
Definition: abg-ir.h:2337
void set_pointed_to_type(const type_base_sptr &)
Set the pointed-to type of the pointer.
Definition: abg-ir.cc:17461
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:17596
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:17392
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17690
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition: abg-ir.cc:17532
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition: abg-ir.cc:17576
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition: abg-ir.cc:17583
The abstraction of a pointer-to-member type.
Definition: abg-ir.h:2466
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:18325
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:18268
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
Definition: abg-ir.cc:18309
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:18376
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
Definition: abg-ir.cc:18259
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
Definition: abg-ir.cc:18401
The abstraction of a qualified type.
Definition: abg-ir.h:2226
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:17118
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition: abg-ir.cc:17243
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition: abg-ir.cc:16982
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:17231
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition: abg-ir.h:2245
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:16922
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition: abg-ir.cc:17222
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17191
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition: abg-ir.cc:17217
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition: abg-ir.cc:17236
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition: abg-ir.cc:17062
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition: abg-ir.cc:16899
Abstracts a reference type.
Definition: abg-ir.h:2400
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:18006
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:17784
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18128
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:17878
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition: abg-ir.cc:17948
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:18107
A declaration that introduces a scope.
Definition: abg-ir.h:1809
virtual size_t get_num_anonymous_member_classes() const
Getter for the number of anonymous classes contained in this scope.
Definition: abg-ir.cc:7857
void remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
Definition: abg-ir.cc:8060
void insert_member_type(type_base_sptr t, declarations::iterator before)
Insert a member type.
Definition: abg-ir.cc:8019
void add_member_type(type_base_sptr t)
Add a member type to the current instance of class_or_union.
Definition: abg-ir.cc:8035
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
Definition: abg-ir.cc:7875
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
Definition: abg-ir.cc:7910
std::vector< scope_decl_sptr > scopes
Convenience typedef for a vector of scope_decl_sptr.
Definition: abg-ir.h:1820
bool is_empty() const
Test if the current scope is empty.
Definition: abg-ir.cc:7924
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:8340
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
Definition: abg-ir.cc:7994
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:8106
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
Definition: abg-ir.h:1816
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:7793
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:8292
virtual void remove_member_decl(decl_base_sptr member)
Remove a declaration from the current scope.
Definition: abg-ir.cc:8131
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:7968
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:8005
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7817
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:7781
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
Definition: abg-ir.cc:8079
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:8370
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:8246
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7835
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
Definition: abg-ir.cc:7893
virtual size_t get_hash() const
Return the hash value for the current instance of scope_decl.
Definition: abg-ir.cc:8171
A type that introduces a scope.
Definition: abg-ir.h:2171
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:16689
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition: abg-ir.cc:16651
The base class of templates.
Definition: abg-ir.h:3544
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:26601
virtual ~template_decl()
Destructor.
Definition: abg-ir.cc:26626
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:26593
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:26635
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition: abg-ir.h:3579
virtual ~template_parameter()
Destructor.
Definition: abg-ir.cc:26762
bool operator!=(const template_parameter &) const
Inequality operator.
Definition: abg-ir.cc:26758
Abstracts a template template parameter.
Definition: abg-ir.h:3709
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:27020
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
Definition: abg-ir.h:686
void set_address_size(char)
Setter of the address size in this translation unit.
Definition: abg-ir.cc:1482
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:1397
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:1514
bool operator==(const translation_unit &) const
Compare the current translation unit against another one.
Definition: abg-ir.cc:1524
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
Definition: abg-ir.cc:1440
char get_address_size() const
Getter of the address size in this translation unit.
Definition: abg-ir.cc:1475
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:1378
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
Definition: abg-ir.cc:1424
void set_language(language l)
Setter of the language of the source code of the translation unit.
Definition: abg-ir.cc:1341
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:1550
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
Definition: abg-ir.cc:1277
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
Definition: abg-ir.cc:1464
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:1498
const std::string & get_path() const
Get the path of the current translation unit.
Definition: abg-ir.cc:1354
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:1389
location_manager & get_loc_mgr()
Getter of the location manager for the current translation unit.
Definition: abg-ir.cc:1448
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
Definition: abg-ir.cc:1365
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse virtual function.
Definition: abg-ir.cc:1584
language
The language of the translation unit.
Definition: abg-ir.h:699
bool operator!=(const translation_unit &) const
Inequality operator.
Definition: abg-ir.cc:1539
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:1320
const environment & get_environment() const
Getter of the environment of the current translation_unit.
Definition: abg-ir.cc:1327
const type_maps & get_types() const
Getter of the types of the current translation_unit.
Definition: abg-ir.cc:1304
language get_language() const
Getter of the language of the source code of the translation unit.
Definition: abg-ir.cc:1334
bool visiting() const
This should returns false before and after the node has been visiting. During the visiting of the nod...
Definition: abg-traverse.cc:48
An abstraction helper for type declarations.
Definition: abg-ir.h:1973
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
Definition: abg-ir.cc:15791
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition: abg-ir.cc:15774
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition: abg-ir.cc:15870
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:15896
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:15499
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition: abg-ir.cc:15863
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition: abg-ir.cc:15856
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition: abg-ir.cc:15846
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition: abg-ir.cc:15884
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition: abg-ir.cc:15877
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition: abg-ir.cc:15758
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition: abg-ir.h:3747
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition: abg-ir.cc:27126
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition: abg-ir.cc:27133
virtual size_t get_hash() const
Get the hash value for the current instance.
Definition: abg-ir.cc:27140
A basic type declaration that introduces no scope.
Definition: abg-ir.h:2108
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:16483
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:16562
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:16421
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:16377
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:16542
This is a type that aggregates maps of all the kinds of types that are supported by libabigail.
Definition: abg-ir.h:593
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:661
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:764
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:715
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:619
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:633
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:729
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:647
bool empty() const
Test if the type_maps is empty.
Definition: abg-ir.cc:587
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:674
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:694
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:1213
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:687
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:605
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:750
The base class of both types and declarations.
Definition: abg-ir.h:1368
void set_translation_unit(translation_unit *)
Set the translation_unit this ABI artifact belongs to.
Definition: abg-ir.cc:4243
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:4057
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
Definition: abg-ir.cc:4046
location & get_artificial_location() const
Getter of the artificial location of the artifact.
Definition: abg-ir.cc:4203
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
Definition: abg-ir.cc:4210
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Definition: abg-ir.cc:4235
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
Definition: abg-ir.cc:4080
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:4069
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
Definition: abg-ir.cc:4268
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
Definition: abg-ir.cc:4100
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition: abg-ir.cc:10701
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:4135
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10350
bool hashing_started() const
Getter for the 'hashing_started' property.
Definition: abg-ir.cc:4153
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
Definition: abg-ir.cc:4185
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:1382
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition: abg-ir.cc:4167
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
Definition: abg-ir.cc:10423
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Definition: abg-ir.cc:4260
Abstracts a type template parameter.
Definition: abg-ir.h:3625
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:26804
The abstraction of a typedef declaration.
Definition: abg-ir.h:2889
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:20386
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition: abg-ir.cc:20371
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition: abg-ir.cc:20221
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:20418
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition: abg-ir.cc:20364
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:20301
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition: abg-ir.cc:20238
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:20342
Abstracts a union type declaration.
Definition: abg-ir.h:4488
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26395
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition: abg-ir.cc:26335
virtual ~union_decl()
Destructor of the union_decl type.
Definition: abg-ir.cc:26468
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:26302
Abstracts a variable declaration.
Definition: abg-ir.h:3008
binding get_binding() const
Getter of the binding of the variable.
Definition: abg-ir.cc:20532
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition: abg-ir.cc:20514
void set_binding(binding b)
Setter of the binding of the variable.
Definition: abg-ir.cc:20539
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
Definition: abg-ir.cc:6185
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
Definition: abg-ir.cc:20577
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:20840
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:20525
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6330
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:20507
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:21002
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:20979
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition: abg-ir.cc:20554
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:20570
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition: abg-ir.cc:20765
virtual size_t get_hash() const
Return the hash value for the current instance.
Definition: abg-ir.cc:20807
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:20870
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:20784
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...
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:11304
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
Definition: abg-fwd.h:236
bool is_declaration_only_class_or_union_type(const type_base_sptr &t, bool look_through_decl_only)
Test wheter a type is a declaration-only class.
Definition: abg-ir.cc:10898
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:19599
const type_base_wptrs_type * lookup_class_types(const string &qualified_name, const corpus &corp)
Look into a given corpus to find the class type*s* that have a given qualified name.
Definition: abg-ir.cc:13387
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:12485
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition: abg-ir.cc:27732
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Definition: abg-ir.cc:6440
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
Definition: abg-ir.cc:7201
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
Definition: abg-fwd.h:222
size_t hash_type(const type_base *t)
Hash an ABI artifact that is either a type.
Definition: abg-ir.cc:27709
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:11836
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:5767
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:6140
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base_sptr &t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
Definition: abg-ir.cc:11164
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr &scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to a scope.
Definition: abg-ir.cc:8387
function_decl_sptr is_function_decl(const type_or_decl_base_sptr &d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10317
class_decl_sptr is_class_type(const type_or_decl_base_sptr &d)
Test whether a type is a class.
Definition: abg-ir.cc:10719
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:11623
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:5561
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:11081
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:9959
decl_base * debug(const decl_base *artifact)
Emit a textual representation of an artifact to std error stream for debugging purposes.
Definition: abg-ir.cc:9942
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition: abg-fwd.h:270
access_specifier
Access specifier for class members.
Definition: abg-ir.h:879
pointer_type_def_sptr lookup_pointer_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a pointer type which has a given qualified name.
Definition: abg-ir.cc:13821
class_decl_sptr lookup_class_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a class type which has a given qualified name.
Definition: abg-ir.cc:13302
interned_string get_type_name(const type_base &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
Definition: abg-ir.cc:8914
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition: abg-ir.cc:22448
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:11063
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
Definition: abg-fwd.h:290
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:14225
weak_ptr< function_type > function_type_wptr
Convenience typedef for a weak pointer on a function_type.
Definition: abg-fwd.h:217
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:13715
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
Definition: abg-ir.cc:6665
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition: abg-ir.cc:6564
reference_type_def_sptr lookup_reference_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a reference type which has a given qualified name.
Definition: abg-ir.cc:13870
type_decl_sptr lookup_basic_type_per_location(const string &loc, const corpus &corp)
Lookup a type_decl type from a given corpus, by its location.
Definition: abg-ir.cc:13228
ptr_to_mbr_type_sptr is_ptr_to_mbr_type(const type_or_decl_base_sptr &t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type_sptr.
Definition: abg-ir.cc:11258
class_decl_sptr is_compatible_with_class_type(const decl_base_sptr &t)
Test if a type is a class. This function looks through typedefs.
Definition: abg-ir.cc:10683
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
Definition: abg-corpus.cc:1770
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
Definition: abg-fwd.h:143
const type_base_sptr is_void_pointer_type(const type_base_sptr &t)
Test if a type is a pointer to void type.
Definition: abg-ir.cc:11339
bool operator==(const union_decl_sptr &l, const union_decl_sptr &r)
Turn equality of shared_ptr of union_decl into a deep equality; that is, make it compare the pointed ...
Definition: abg-ir.cc:26551
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:25074
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:335
bool equals_modulo_cv_qualifier(const array_type_def *l, const array_type_def *r)
Test if two variables are equals modulo CV qualifiers.
Definition: abg-ir.cc:19184
const type_base_wptrs_type * lookup_enum_types(const string &qualified_name, const corpus &corp)
Look into a given corpus to find the enum type*s* that have a given qualified name.
Definition: abg-ir.cc:13569
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
Definition: abg-ir.cc:7552
string get_class_or_union_flat_representation(const class_or_union_sptr &cou, const string &indent, bool one_line, bool internal, bool qualified_names)
Get the flat representation of an instance of class_or_union type.
Definition: abg-ir.cc:9547
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10410
scope_decl * is_scope_decl(decl_base *d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5431
union_decl_sptr lookup_union_type(const string &type_name, const corpus &corp)
Look into a given corpus to find a union type which has a given qualified name.
Definition: abg-ir.cc:13475
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition: abg-ir.cc:5858
bool is_template_parameter(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter.
Definition: abg-ir.cc:10284
bool is_anonymous_data_member(const var_decl &d)
Test if a var_decl is an anonymous data member.
Definition: abg-ir.cc:5960
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
Definition: abg-ir.cc:1596
weak_ptr< type_base > type_base_wptr
Convenience typedef for a weak pointer on a type_base.
Definition: abg-fwd.h:129
type_decl_sptr is_integral_type(const type_or_decl_base_sptr &t)
Test if a type is an integral type.
Definition: abg-ir.cc:10550
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:7110
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:25784
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
Definition: abg-ir.cc:5385
scope_decl * get_type_scope(const type_base_sptr &t)
Get the scope of a given type.
Definition: abg-ir.cc:8736
integral_type::modifiers_type operator~(integral_type::modifiers_type l)
Bitwise one's complement operator for integral_type::modifiers_type.
Definition: abg-ir.cc:15953
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:11742
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition: abg-ir.h:888
typedef_decl_sptr lookup_typedef_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a typedef type which has a given qualified name.
Definition: abg-ir.cc:13657
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
Definition: abg-ir.cc:6597
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:13112
var_decl_sptr get_data_member(type_base *clazz, const char *member_name)
Get a given data member, referred to by its name, of a class type.
Definition: abg-ir.cc:9856
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
Definition: abg-ir.cc:27803
type_base_sptr lookup_type_through_scopes(const list< string > &fqn, const translation_unit &tu)
Lookup a type from a translation unit by walking its scopes in sequence and by looking into them.
Definition: abg-ir.cc:12827
location get_location(const decl_base_sptr &decl)
Get the location of a given declaration.
Definition: abg-ir.cc:8698
const typedef_decl * is_typedef(const type_or_decl_base *t)
Test whether a type is a typedef.
Definition: abg-ir.cc:10600
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
Definition: abg-ir.cc:8394
type_base_sptr peel_qualified_or_typedef_type(const type_base_sptr &t)
Return the leaf underlying type of a qualified or typedef type.
Definition: abg-ir.cc:7323
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:10024
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
Definition: abg-ir.cc:7485
enum_type_decl_sptr lookup_enum_type_per_location(const string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
Definition: abg-ir.cc:13600
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
Definition: abg-ir.h:1323
@ LOCAL_TYPE_CHANGE_KIND
This means that a given IR artifact has a local type change.
Definition: abg-ir.h:1327
@ 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:1343
@ 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:1332
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:28284
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:11238
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:5704
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:12847
shared_ptr< class_or_union > is_class_or_union_type(const shared_ptr< type_or_decl_base > &t)
Test if a type is a class_or_union.
Definition: abg-ir.cc:10933
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:9579
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
Definition: abg-ir.cc:5465
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:1779
class_or_union_sptr anonymous_data_member_to_class_or_union(const var_decl_sptr &d)
Get the class_or_union type of a given anonymous data member.
Definition: abg-ir.cc:6085
weak_ptr< class_decl > class_decl_wptr
Convenience typedef for a weak pointer on a class_decl.
Definition: abg-fwd.h:203
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:11862
void unmark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being not compared anymore.
Definition: abg-ir.cc:1050
vector< type_base_sptr > type_base_sptrs_type
Helper typedef for a vector of shared pointer to a type_base.
Definition: abg-ir.h:119
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:10009
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:5801
union_decl_sptr is_union_type(const shared_ptr< type_or_decl_base > &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:10992
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition: abg-ir.cc:10692
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:14798
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition: abg-fwd.h:245
method_type * is_method_type(type_or_decl_base *t)
Test whether a type is a method_type.
Definition: abg-ir.cc:11435
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:13137
qualified_type_def_sptr lookup_qualified_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a qualified type which has a given qualified name.
Definition: abg-ir.cc:13775
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:10876
type_base_sptr lookup_type(const type_base_sptr &t, const corpus &corp)
Look into a given corpus to find a type.
Definition: abg-ir.cc:14098
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:9201
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:13740
const type_base_sptr peel_qualified_type(const type_base_sptr &type)
Return the leaf underlying type of a qualified type.
Definition: abg-ir.cc:7223
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:7270
function_type_sptr lookup_function_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find a function type which has a given qualified name.
Definition: abg-ir.cc:13991
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:6044
type_decl * is_integral_type(const type_or_decl_base *t)
Test if a type is an integral type.
Definition: abg-ir.cc:10530
translation_unit * get_translation_unit(const shared_ptr< decl_base > decl)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:10146
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:6100
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition: abg-ir.cc:6468
const function_type * is_function_type(const type_or_decl_base *t)
Test whether a type is a function_type.
Definition: abg-ir.cc:11405
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
Definition: abg-ir.cc:7159
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:27947
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
Definition: abg-fwd.h:315
enum_type_decl_sptr look_through_decl_only_enum(enum_type_decl_sptr enom)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
Definition: abg-ir.cc:11485
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:10923
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:5728
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition: abg-fwd.h:194
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:7346
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:6524
string get_name(const type_or_decl_base_sptr &tod, bool qualified)
Build and return a copy of the name of an ABI artifact that is either a type of a decl.
Definition: abg-ir.cc:8637
bool is_anonymous_type(const type_base_sptr &t)
Test if a given type is anonymous.
Definition: abg-ir.cc:10486
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:6852
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:951
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:2975
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:11605
array_type_def_sptr is_array_of_qualified_element(const type_base_sptr &type)
Test if an array type is an array to a qualified element type.
Definition: abg-ir.cc:11698
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:10512
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10390
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:11494
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:11385
scope_decl_sptr is_scope_decl(const decl_base_sptr &d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5441
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:8605
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5530
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition: abg-ir.cc:10570
type_base_sptr is_type(const type_or_decl_base_sptr &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10438
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
Definition: abg-ir.cc:6302
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
Definition: abg-ir.cc:9728
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition: abg-fwd.h:211
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
Definition: abg-fwd.h:168
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:14881
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:2847
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:7054
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:20638
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:13087
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:3359
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:7448
decl_base_sptr is_decl_slow(const type_or_decl_base_sptr &t)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10401
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:11178
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
Definition: abg-corpus.cc:1756
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:3056
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
Definition: abg-ir.cc:1742
enum_type_decl_sptr is_compatible_with_enum_type(const decl_base_sptr &t)
Test if a type is an enum. This function looks through typedefs.
Definition: abg-ir.cc:10633
function_decl::parameter_sptr is_function_parameter(const type_or_decl_base_sptr tod)
Test whether an ABI artifact is a function_decl.
Definition: abg-ir.cc:10340
class_or_union_sptr look_through_decl_only_class(class_or_union_sptr klass)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
Definition: abg-ir.cc:11465
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:13340
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:6553
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
Definition: abg-ir.cc:16136
const type_base * peel_typedef_type(const type_base *type)
Return the leaf underlying type node of a typedef_decl node.
Definition: abg-ir.cc:7027
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:8413
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:3276
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:10642
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:149
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:27895
bool elf_symbols_alias(const elf_symbol &s1, const elf_symbol &s2)
Test if two symbols alias.
Definition: abg-ir.cc:2778
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:10253
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition: abg-fwd.h:257
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:240
const location & get_natural_or_artificial_location(const decl_base *decl)
Get the non-artificial (natural) location of a decl.
Definition: abg-ir.cc:9869
string build_qualified_name(const scope_decl *scope, const type_base_sptr &type)
Build and return the qualified name of a type in its scope.
Definition: abg-ir.cc:8674
bool return_comparison_result(T &l, T &r, bool value, bool propagate_canonical_type=true)
Return the result of the comparison of two (sub) types.
Definition: abg-ir.cc:1100
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:27630
array_type_def_sptr is_array_type(const type_or_decl_base_sptr &type, bool look_through_qualifiers)
Test if a type is an array_type_def.
Definition: abg-ir.cc:11666
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
Definition: abg-corpus.cc:1784
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:29451
bool is_template_decl(const decl_base_sptr &decl)
Tests whether a decl is a template.
Definition: abg-ir.cc:11765
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
Definition: abg-fwd.h:265
class_decl_sptr lookup_class_type_per_location(const string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
Definition: abg-ir.cc:13434
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:3008
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:121
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition: abg-fwd.h:137
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:5976
namespace_decl * is_namespace(const decl_base *d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:11614
type_base * peel_typedef_pointer_or_reference_type(const type_base *type, bool peel_qual_type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def or reference_t...
Definition: abg-ir.cc:7409
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:11277
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition: abg-ir.cc:11771
bool try_canonical_compare(const T *l, const T *r)
Compare two types by comparing their canonical types if present.
Definition: abg-ir.cc:902
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:27567
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:158
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:314
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
Definition: abg-ir.cc:1756
function_decl::parameter * is_function_parameter(const type_or_decl_base *tod)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10327
type_decl_sptr lookup_basic_type(const string &qualified_name, const corpus &corp)
Look into a given corpus to find a basic type which has a given qualified name.
Definition: abg-ir.cc:13247
class_or_union * is_at_class_scope(const decl_base &decl)
Tests whether a given decl is at class scope.
Definition: abg-ir.cc:10233
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
Definition: abg-ir.cc:5112
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6330
const decl_base_sptr lookup_var_decl_in_scope(const std::list< string > &comps, const scope_decl_sptr &skope)
lookup a var_decl in a scope.
Definition: abg-ir.cc:12794
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:3033
union_decl_sptr lookup_union_type_per_location(const string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
Definition: abg-ir.cc:12099
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
Definition: abg-ir.cc:15627
weak_ptr< elf_symbol > elf_symbol_wptr
A convenience typedef for a weak pointer to elf_symbol.
Definition: abg-ir.h:891
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition: abg-ir.cc:6496
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:8951
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
Definition: abg-fwd.h:227
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:14255
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:19680
interned_string get_method_type_name(const method_type &fn_type, bool internal)
Get the name of a given method type and return a copy of it.
Definition: abg-ir.cc:9156
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
Definition: abg-ir.cc:7238
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:1666
enum_type_decl_sptr is_enum_type(const type_or_decl_base_sptr &d)
Test if a decl is an enum_type_decl.
Definition: abg-ir.cc:10651
var_decl_sptr has_fake_flexible_array_data_member(const class_decl_sptr &klass)
Test if the last data member of a class is an array with one element.
Definition: abg-ir.cc:10863
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:14045
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:6215
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
Definition: abg-ir.cc:6259
shared_ptr< ir_traversable_base > ir_traversable_base_sptr
Convenience typedef for a shared pointer to ir_traversable_base.
Definition: abg-fwd.h:110
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
Definition: abg-ir.cc:6354
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:28216
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:11586
string get_pretty_representation(const method_type_sptr method, bool internal)
Get the pretty representation of a method type.
Definition: abg-ir.cc:9403
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
Definition: abg-ir.cc:1728
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10350
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:27605
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:24906
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition: abg-ir.cc:5450
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:9423
array_type_def::subrange_sptr is_subrange_type(const type_or_decl_base_sptr &type)
Test if a type is an array_type_def::subrange_type.
Definition: abg-ir.cc:11755
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:8370
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:28238
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:10497
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5501
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition: abg-fwd.h:176
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:6153
const interned_string & get_node_name(var_decl_sptr node)
Gets the name of a var_decl node.
Definition: abg-ir.cc:12552
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:6717
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition: abg-ir.cc:6170
unordered_set< uintptr_t > pointer_set
A convenience typedef for an unordered set of pointer values.
Definition: abg-ir.h:100
type_decl_sptr is_type_decl(const type_or_decl_base_sptr &t)
Test whether a type is a type_decl (a builtin type).
Definition: abg-ir.cc:10520
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:10210
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6627
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:11006
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:9700
bool types_are_compatible(const decl_base_sptr d1, const decl_base_sptr d2)
Test if two types are equal modulo a typedef.
Definition: abg-ir.cc:10115
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:6016
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
Definition: abg-ir.cc:8685
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:11046
weak_ptr< decl_base > decl_base_wptr
Convenience typedef for a weak pointer to a decl_base.
Definition: abg-fwd.h:182
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:9028
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:11637
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:11445
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:10972
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition: abg-ir.cc:9888
bool is_global_scope(const shared_ptr< scope_decl >scope)
Tests whether if a given scope is the global scope.
Definition: abg-ir.cc:10174
typedef_decl_sptr lookup_typedef_type_per_location(const string &loc, const corpus &corp)
Lookup a typedef_decl from a corpus, by its location.
Definition: abg-ir.cc:13695
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:7000
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:8981
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
Definition: abg-fwd.h:307
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:11721
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:8575
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:6316
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:11098
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition: abg-ir.cc:5599
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:28263
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition: abg-ir.cc:10043
bool is_at_global_scope(const decl_base *decl)
Tests whether a given declaration is at global scope.
Definition: abg-ir.cc:10201
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26030
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:11650
weak_ptr< template_decl > template_decl_wptr
Convenience typedef for a weak pointer to template_decl.
Definition: abg-fwd.h:310
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:28173
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:9093
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition: abg-fwd.h:162
const global_scope * get_global_scope(const shared_ptr< decl_base > decl)
Return the global scope as seen by a given declaration.
Definition: abg-ir.cc:8491
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
Definition: abg-ir.cc:7527
bool compare_using_locations(const decl_base *f, const decl_base *s)
Compare decls using their locations.
Definition: abg-ir.cc:3324
string get_enum_flat_representation(const enum_type_decl_sptr &enum_type, const string &indent, bool one_line, bool qualified_names)
Get the flat representation of an instance of enum_type_decl type.
Definition: abg-ir.cc:9670
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:113
array_type_def_sptr lookup_array_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find an array type which has the same qualified name as a given array typ...
Definition: abg-ir.cc:13920
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
Definition: abg-fwd.h:285
var_decl_sptr is_var_decl(const type_or_decl_base_sptr &decl)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:11596
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
Definition: abg-ir.cc:1765
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
Definition: abg-ir.cc:14955
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition: abg-ir.cc:27768
void maybe_update_types_lookup_map(const function_type_sptr &fn_type)
Update the map that associates the fully qualified name of a function type with the type itself.
Definition: abg-ir.cc:14692
void mark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being compared.
Definition: abg-ir.cc:1015
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:8754
bool mark_dependant_types_compared_until(const type_base &r)
In the stack of the current types being compared (as part of type canonicalization),...
Definition: abg-ir.cc:399
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
Definition: abg-corpus.cc:1798
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:7605
interned_string get_function_type_name(const function_type &fn_type, bool internal)
Get the name of a given function type and return a copy of it.
Definition: abg-ir.cc:9065
decl_base_sptr is_decl(const type_or_decl_base_sptr &d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10379
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:1798
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:8929
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
Definition: abg-ir.cc:10275
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10298
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:3066
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:27589
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:14163
var_decl_sptr has_flexible_array_data_member(const class_decl_sptr &klass)
Test if the last data member of a class is an array with non-finite data member.
Definition: abg-ir.cc:10781
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:11415
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:11365
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:11118
const scope_decl * get_top_most_scope_under(const decl_base_sptr decl, const scope_decl_sptr scope)
Return the a scope S containing a given declaration and that is right under a given scope P.
Definition: abg-ir.cc:8562
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:909
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:8651
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:3307
method_decl_sptr copy_member_function(const class_or_union_sptr &t, const method_decl_sptr &method)
Copy a method of a class_or_union into a new class_or_union.
Definition: abg-ir.cc:23904
decl_base_sptr get_type_declaration(const type_base_sptr t)
Get the declaration for a given type.
Definition: abg-ir.cc:10061
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
Definition: abg-fwd.h:295
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:7295
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:14985
pointer_type_def_sptr is_pointer_type(const type_or_decl_base_sptr &t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
Definition: abg-ir.cc:11030
const type_base_wptrs_type * lookup_union_types(const string &qualified_name, const corpus &corp)
Look into a given corpus to find the union types that have a given qualified name.
Definition: abg-ir.cc:13402
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition: abg-ir.cc:5403
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:5012
qualified_type_def_sptr is_qualified_type(const type_or_decl_base_sptr &t)
Test whether a type is a qualified_type_def.
Definition: abg-ir.cc:11375
bool class_or_union_types_of_same_kind(const class_or_union_sptr &first, const class_or_union_sptr &second)
Test if two class or union types are of the same kind.
Definition: abg-ir.cc:10962
reference_type_def_sptr is_reference_type(const type_or_decl_base_sptr &t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
Definition: abg-ir.cc:11222
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition: abg-ir.cc:6381
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:6411
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:10912
enum_type_decl_sptr lookup_enum_type(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find an enum type which has a given qualified name.
Definition: abg-ir.cc:13532
type_base_sptr look_through_decl_only(const type_base_sptr &t)
If a type is is decl-only, then get its definition. Otherwise, just return the initial type.
Definition: abg-ir.cc:11570
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:88
bool base_name(string const &path, string &file_name)
Return the file name part of a file part.
const char * get_anonymous_subrange_internal_name_prefix()
Getter of the prefix for the name of anonymous range.
const char * get_anonymous_enum_internal_name_prefix()
Getter of the prefix for the name of anonymous enums.
const char * get_anonymous_struct_internal_name_prefix()
Getter of the prefix for the name of anonymous structs.
const char * get_anonymous_union_internal_name_prefix()
Getter of the prefix for the name of anonymous unions.
bool decl_names_equal(const string &l, const string &r)
Compare two fully qualified decl names by taking into account that they might have compontents that a...
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
Definition: abg-ir.cc:152
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
Definition: abg-ir.cc:186
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
Definition: abg-ir.cc:169
unordered_map< string, string * > pool_map_type
Convenience typedef for a map of string -> string*.
Definition: abg-ir.cc:74
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:7720
The hashing functor for class_decl::base_spec.
Definition: abg-ir.h:4890
Hasher for the class_decl type.
Definition: abg-ir.h:4391
A functor to sort decls somewhat topologically. That is, types are sorted in a way that makes the one...
Definition: abg-ir-priv.h:1306
The private data of the environment type.
Definition: abg-ir-priv.h:390
A hashing functor fo instances and pointers of function_decl.
Definition: abg-ir.h:4856
A hashing functor for a function_decl::parameter.
Definition: abg-ir.h:3368
Equality functor for instances of function_decl.
Definition: abg-ir.h:4866
The hashing functor for function_type.
Definition: abg-ir.h:3473
The type of the private data of the function_type type.
Definition: abg-ir-priv.h:1825
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:29111
The hashing functor for member_base.
Definition: abg-ir.h:4897
Hasher for the non_type_tparameter type.
Definition: abg-ir.h:3697
Hasher for the scope_decl type.
Definition: abg-ir.h:1938
Private type to hold private members of translation_unit.
Definition: abg-ir-priv.h:144
Definition of the private data of type_base.
Definition: abg-ir-priv.h:180
Hasher for the type_composition type.
Definition: abg-ir.h:3774
A predicate for deep equality of instances of shared_ptr<type_base>
Definition: abg-ir.h:2086
A functor to sort types somewhat topologically. That is, types are sorted in a way that makes the one...
Definition: abg-ir-priv.h:1389
A hashing functor for instances and pointers of var_decl.
Definition: abg-ir.h:4825
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.