libabigail
abg-ir.cc
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -*- mode:
2// C++ -*-
3//
4// Copyright (C) 2013-2023 Red Hat, Inc.
5//
6//Author: Dodji Seketeli
7
8/// @file
9///
10/// Definitions for the Internal Representation artifacts of libabigail.
11
12#include <cxxabi.h>
13#include <algorithm>
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{return get_type() == OBJECT_TYPE || get_type() == TLS_TYPE;}
2212
2213/// Getter of the 'is-in-ksymtab' property.
2214///
2215/// @return true iff the current symbol is in the Linux Kernel
2216/// specific 'ksymtab' symbol table.
2217bool
2219{return priv_->is_in_ksymtab_;}
2220
2221/// Setter of the 'is-in-ksymtab' property.
2222///
2223/// @param is_in_ksymtab this is true iff the current symbol is in the
2224/// Linux Kernel specific 'ksymtab' symbol table.
2225void
2227{priv_->is_in_ksymtab_ = is_in_ksymtab;}
2228
2229/// Getter of the 'crc' property.
2230///
2231/// @return the CRC (modversions) value for Linux Kernel symbols, if any
2234{return priv_->crc_;}
2235
2236/// Setter of the 'crc' property.
2237///
2238/// @param crc the new CRC (modversions) value for Linux Kernel symbols
2239void
2241{priv_->crc_ = crc;}
2242
2243/// Getter of the 'namespace' property.
2244///
2245/// @return the namespace for Linux Kernel symbols, if any
2248{return priv_->namespace_;}
2249
2250/// Setter of the 'namespace' property.
2251///
2252/// @param ns the new namespace for Linux Kernel symbols, if any
2253void
2255{priv_->namespace_ = ns;}
2256
2257/// Getter for the 'is-suppressed' property.
2258///
2259/// @return true iff the current symbol has been suppressed by a
2260/// suppression specification that was provided in the context that
2261/// led to the creation of the corpus this ELF symbol belongs to.
2262bool
2264{return priv_->is_suppressed_;}
2265
2266/// Setter for the 'is-suppressed' property.
2267///
2268/// @param true iff the current symbol has been suppressed by a
2269/// suppression specification that was provided in the context that
2270/// led to the creation of the corpus this ELF symbol belongs to.
2271void
2273{priv_->is_suppressed_ = is_suppressed;}
2274
2275/// @name Elf symbol aliases
2276///
2277/// An alias A for an elf symbol S is a symbol that is defined at the
2278/// same address as S. S is chained to A through the
2279/// elf_symbol::get_next_alias() method.
2280///
2281/// When there are several aliases to a symbol, the main symbol is the
2282/// the first symbol found in the symbol table for a given address.
2283///
2284/// The alias chain is circular. That means if S is the main symbol
2285/// and A is the alias, S is chained to A and A
2286/// is chained back to the main symbol S. The last alias in an alias
2287///chain is always chained to the main symbol.
2288///
2289/// Thus, when looping over the aliases of an elf_symbol A, detecting
2290/// an alias that is equal to the main symbol should logically be a
2291/// loop exit condition.
2292///
2293/// Accessing and adding aliases for instances of elf_symbol is done
2294/// through the member functions below.
2295
2296/// @{
2297
2298/// Get the main symbol of an alias chain.
2299///
2300///@return the main symbol.
2301const elf_symbol_sptr
2303{return priv_->main_symbol_.lock();}
2304
2305/// Get the main symbol of an alias chain.
2306///
2307///@return the main symbol.
2310{return priv_->main_symbol_.lock();}
2311
2312/// Tests whether this symbol is the main symbol.
2313///
2314/// @return true iff this symbol is the main symbol.
2315bool
2317{return get_main_symbol().get() == this;}
2318
2319/// Get the next alias of the current symbol.
2320///
2321///@return the alias, or NULL if there is no alias.
2324{return priv_->next_alias_.lock();}
2325
2326
2327/// Check if the current elf_symbol has an alias.
2328///
2329///@return true iff the current elf_symbol has an alias.
2330bool
2332{return bool(get_next_alias());}
2333
2334/// Get the number of aliases to this elf symbol
2335///
2336/// @return the number of aliases to this elf symbol.
2337int
2339{
2340 int result = 0;
2341
2343 a && a.get() != get_main_symbol().get();
2344 a = a->get_next_alias())
2345 ++result;
2346
2347 return result;
2348}
2349
2350/// Add an alias to the current elf symbol.
2351///
2352/// @param alias the new alias. Note that this elf_symbol should *NOT*
2353/// have aliases prior to the invocation of this function.
2354void
2356{
2357 if (!alias)
2358 return;
2359
2360 ABG_ASSERT(!alias->has_aliases());
2362
2363 if (has_aliases())
2364 {
2365 elf_symbol_sptr last_alias;
2367 a && !a->is_main_symbol();
2368 a = a->get_next_alias())
2369 {
2370 if (a->get_next_alias()->is_main_symbol())
2371 {
2372 ABG_ASSERT(last_alias == 0);
2373 last_alias = a;
2374 }
2375 }
2376 ABG_ASSERT(last_alias);
2377
2378 last_alias->priv_->next_alias_ = alias;
2379 }
2380 else
2381 priv_->next_alias_ = alias;
2382
2383 alias->priv_->next_alias_ = get_main_symbol();
2384 alias->priv_->main_symbol_ = get_main_symbol();
2385}
2386
2387/// Update the main symbol for a group of aliased symbols
2388///
2389/// If after the construction of the symbols (in order of discovery), the
2390/// actual main symbol can be identified (e.g. as the symbol that actually is
2391/// defined in the code), this method offers a way of updating the main symbol
2392/// through one of the aliased symbols.
2393///
2394/// For that, locate the new main symbol by name and update all references to
2395/// the main symbol among the group of aliased symbols.
2396///
2397/// @param name the name of the main symbol
2398///
2399/// @return the new main elf_symbol
2401elf_symbol::update_main_symbol(const std::string& name)
2402{
2404 if (!has_aliases() || get_name() == name)
2405 return get_main_symbol();
2406
2407 // find the new main symbol
2408 elf_symbol_sptr new_main;
2409 // we've already checked this; check the rest of the aliases
2410 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2411 a = a->get_next_alias())
2412 if (a->get_name() == name)
2413 {
2414 new_main = a;
2415 break;
2416 }
2417
2418 if (!new_main)
2419 return get_main_symbol();
2420
2421 // now update all main symbol references
2422 priv_->main_symbol_ = new_main;
2423 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2424 a = a->get_next_alias())
2425 a->priv_->main_symbol_ = new_main;
2426
2427 return new_main;
2428}
2429
2430/// Return true if the symbol is a common one.
2431///
2432/// @return true iff the symbol is common.
2433bool
2435{return priv_->is_common_;}
2436
2437/// Return true if this common common symbol has other common instances.
2438///
2439/// A common instance of a given common symbol is another common
2440/// symbol with the same name. Those exist in relocatable files. The
2441/// linker normally allocates all the instances into a common block in
2442/// the final output file.
2443///
2444/// Note that the current object must be a common symbol, otherwise,
2445/// this function aborts.
2446///
2447/// @return true iff the current common symbol has other common
2448/// instances.
2449bool
2451{
2453 return bool(get_next_common_instance());
2454}
2455
2456/// Get the next common instance of the current common symbol.
2457///
2458/// A common instance of a given common symbol is another common
2459/// symbol with the same name. Those exist in relocatable files. The
2460/// linker normally allocates all the instances into a common block in
2461/// the final output file.
2462///
2463/// @return the next common instance, or nil if there is not any.
2466{return priv_->next_common_instance_.lock();}
2467
2468/// Add a common instance to the current common elf symbol.
2469///
2470/// Note that this symbol must be the main symbol. Being the main
2471/// symbol means being the first common symbol to appear in the symbol
2472/// table.
2473///
2474/// @param common the other common instance to add.
2475void
2477{
2478 if (!common)
2479 return;
2480
2481 ABG_ASSERT(!common->has_other_common_instances());
2484
2486 {
2487 elf_symbol_sptr last_common_instance;
2489 c && (c.get() != get_main_symbol().get());
2490 c = c->get_next_common_instance())
2491 {
2492 if (c->get_next_common_instance().get() == get_main_symbol().get())
2493 {
2494 ABG_ASSERT(last_common_instance == 0);
2495 last_common_instance = c;
2496 }
2497 }
2498 ABG_ASSERT(last_common_instance);
2499
2500 last_common_instance->priv_->next_common_instance_ = common;
2501 }
2502 else
2503 priv_->next_common_instance_ = common;
2504
2505 common->priv_->next_common_instance_ = get_main_symbol();
2506 common->priv_->main_symbol_ = get_main_symbol();
2507}
2508
2509/// Get a string that is representative of a given elf_symbol.
2510///
2511/// If the symbol has a version, then the ID string is the
2512/// concatenation of the name of the symbol, the '@' character, and
2513/// the version of the symbol. If the version is the default version
2514/// of the symbol then the '@' character is replaced by a "@@" string.
2515///
2516/// Otherwise, if the symbol does not have any version, this function
2517/// returns the name of the symbol.
2518///
2519/// @return a the ID string.
2520const string&
2522{
2523 if (priv_->id_string_.empty())
2524 {
2525 string s = get_name ();
2526
2527 if (!get_version().is_empty())
2528 {
2529 if (get_version().is_default())
2530 s += "@@";
2531 else
2532 s += "@";
2533 s += get_version().str();
2534 }
2535 priv_->id_string_ = s;
2536 }
2537
2538 return priv_->id_string_;
2539}
2540
2541/// From the aliases of the current symbol, lookup one with a given name.
2542///
2543/// @param name the name of symbol alias we are looking for.
2544///
2545/// @return the symbol alias that has the name @p name, or nil if none
2546/// has been found.
2548elf_symbol::get_alias_from_name(const string& name) const
2549{
2550 if (name == get_name())
2551 return elf_symbol_sptr(priv_->main_symbol_);
2552
2554 a && a.get() != get_main_symbol().get();
2555 a = a->get_next_alias())
2556 if (a->get_name() == name)
2557 return a;
2558
2559 return elf_symbol_sptr();
2560}
2561
2562/// In the list of aliases of a given elf symbol, get the alias that
2563/// equals this current symbol.
2564///
2565/// @param other the elf symbol to get the potential aliases from.
2566///
2567/// @return the alias of @p other that texually equals the current
2568/// symbol, or nil if no alias textually equals the current symbol.
2571{
2572 for (elf_symbol_sptr a = other.get_next_alias();
2573 a && a.get() != a->get_main_symbol().get();
2574 a = a->get_next_alias())
2575 if (textually_equals(*this, *a))
2576 return a;
2577 return elf_symbol_sptr();
2578}
2579
2580/// Return a comma separated list of the id of the current symbol as
2581/// well as the id string of its aliases.
2582///
2583/// @param syms a map of all the symbols of the corpus the current
2584/// symbol belongs to.
2585///
2586/// @param include_symbol_itself if set to true, then the name of the
2587/// current symbol is included in the list of alias names that is emitted.
2588///
2589/// @return the string.
2590string
2592 bool include_symbol_itself) const
2593{
2594 string result;
2595
2596 if (include_symbol_itself)
2597 result = get_id_string();
2598
2599 vector<elf_symbol_sptr> aliases;
2600 compute_aliases_for_elf_symbol(*this, syms, aliases);
2601 if (!aliases.empty() && include_symbol_itself)
2602 result += ", ";
2603
2604 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2605 i != aliases.end();
2606 ++i)
2607 {
2608 if (i != aliases.begin())
2609 result += ", ";
2610 result += (*i)->get_id_string();
2611 }
2612 return result;
2613}
2614
2615/// Return a comma separated list of the id of the current symbol as
2616/// well as the id string of its aliases.
2617///
2618/// @param include_symbol_itself if set to true, then the name of the
2619/// current symbol is included in the list of alias names that is emitted.
2620///
2621/// @return the string.
2622string
2623elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2624{
2625 vector<elf_symbol_sptr> aliases;
2626 if (include_symbol_itself)
2627 aliases.push_back(get_main_symbol());
2628
2630 a && a.get() != get_main_symbol().get();
2631 a = a->get_next_alias())
2632 aliases.push_back(a);
2633
2634 string result;
2635 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2636 i != aliases.end();
2637 ++i)
2638 {
2639 if (i != aliases.begin())
2640 result += ", ";
2641 result += (*i)->get_id_string();
2642 }
2643
2644 return result;
2645}
2646
2647/// Given the ID of a symbol, get the name and the version of said
2648/// symbol.
2649///
2650/// @param id the symbol ID to consider.
2651///
2652/// @param name the symbol name extracted from the ID. This is set
2653/// only if the function returned true.
2654///
2655/// @param ver the symbol version extracted from the ID.
2656bool
2658 string& name,
2659 string& ver)
2660{
2661 name.clear(), ver.clear();
2662
2663 string::size_type i = id.find('@');
2664 if (i == string::npos)
2665 {
2666 name = id;
2667 return true;
2668 }
2669
2670 name = id.substr(0, i);
2671 ++i;
2672
2673 if (i >= id.size())
2674 return true;
2675
2676 string::size_type j = id.find('@', i);
2677 if (j == string::npos)
2678 j = i;
2679 else
2680 ++j;
2681
2682 if (j >= id.size())
2683 {
2684 ver = "";
2685 return true;
2686 }
2687
2688 ver = id.substr(j);
2689 return true;
2690}
2691
2692///@}
2693
2694/// Test if two main symbols are textually equal, or, if they have
2695/// aliases that are textually equal.
2696///
2697/// @param other the symbol to compare against.
2698///
2699/// @return true iff the current instance of elf symbol equals the @p
2700/// other.
2701bool
2703{
2704 bool are_equal = textually_equals(*this, other);
2705 if (!are_equal)
2706 are_equal = bool(get_alias_which_equals(other));
2707 return are_equal;
2708}
2709
2710/// Test if the current symbol aliases another one.
2711///
2712/// @param o the other symbol to test against.
2713///
2714/// @return true iff the current symbol aliases @p o.
2715bool
2717{
2718 if (*this == o)
2719 return true;
2720
2721 if (get_main_symbol() == o.get_main_symbol())
2722 return true;
2723
2725 a && !a->is_main_symbol();
2726 a = a->get_next_alias())
2727 {
2728 if (o == *a)
2729 return true;
2730 }
2731 return false;
2732}
2733
2734/// Equality operator for smart pointers to elf_symbol.
2735///
2736/// @param lhs the first elf symbol to consider.
2737///
2738/// @param rhs the second elf symbol to consider.
2739///
2740/// @return true iff @p lhs equals @p rhs.
2741bool
2743{
2744 if (!!lhs != !!rhs)
2745 return false;
2746
2747 if (!lhs)
2748 return true;
2749
2750 return *lhs == *rhs;
2751}
2752
2753/// Inequality operator for smart pointers to elf_symbol.
2754///
2755/// @param lhs the first elf symbol to consider.
2756///
2757/// @param rhs the second elf symbol to consider.
2758///
2759/// @return true iff @p lhs is different from @p rhs.
2760bool
2762{return !operator==(lhs, rhs);}
2763
2764/// Test if two symbols alias.
2765///
2766/// @param s1 the first symbol to consider.
2767///
2768/// @param s2 the second symbol to consider.
2769///
2770/// @return true if @p s1 aliases @p s2.
2771bool
2773{return s1.does_alias(s2) || s2.does_alias(s1);}
2774
2775void
2776compute_aliases_for_elf_symbol(const elf_symbol& sym,
2777 const string_elf_symbols_map_type& symtab,
2778 vector<elf_symbol_sptr>& aliases)
2779{
2780
2781 if (elf_symbol_sptr a = sym.get_next_alias())
2782 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2783 aliases.push_back(a);
2784 else
2785 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2786 i != symtab.end();
2787 ++i)
2788 for (elf_symbols::const_iterator j = i->second.begin();
2789 j != i->second.end();
2790 ++j)
2791 {
2792 if (**j == sym)
2793 for (elf_symbol_sptr s = (*j)->get_next_alias();
2794 s && !s->is_main_symbol();
2795 s = s->get_next_alias())
2796 aliases.push_back(s);
2797 else
2798 for (elf_symbol_sptr s = (*j)->get_next_alias();
2799 s && !s->is_main_symbol();
2800 s = s->get_next_alias())
2801 if (*s == sym)
2802 aliases.push_back(*j);
2803 }
2804}
2805
2806/// Test if two symbols alias.
2807///
2808/// @param s1 the first symbol to consider.
2809///
2810/// @param s2 the second symbol to consider.
2811///
2812/// @return true if @p s1 aliases @p s2.
2813bool
2815{
2816 if (!!s1 != !!s2)
2817 return false;
2818 if (s1 == s2)
2819 return true;
2820 return elf_symbols_alias(*s1, *s2);
2821}
2822
2823/// Test if two symbols alias.
2824///
2825/// @param s1 the first symbol to consider.
2826///
2827/// @param s2 the second symbol to consider.
2828///
2829/// @return true if @p s1 aliases @p s2.
2830bool
2832{return elf_symbols_alias(s1.get(), s2.get());}
2833
2834/// Serialize an instance of @ref symbol_type and stream it to a given
2835/// output stream.
2836///
2837/// @param o the output stream to serialize the symbole type to.
2838///
2839/// @param t the symbol type to serialize.
2840std::ostream&
2841operator<<(std::ostream& o, elf_symbol::type t)
2842{
2843 string repr;
2844
2845 switch (t)
2846 {
2847 case elf_symbol::NOTYPE_TYPE:
2848 repr = "unspecified symbol type";
2849 break;
2850 case elf_symbol::OBJECT_TYPE:
2851 repr = "variable symbol type";
2852 break;
2853 case elf_symbol::FUNC_TYPE:
2854 repr = "function symbol type";
2855 break;
2856 case elf_symbol::SECTION_TYPE:
2857 repr = "section symbol type";
2858 break;
2859 case elf_symbol::FILE_TYPE:
2860 repr = "file symbol type";
2861 break;
2862 case elf_symbol::COMMON_TYPE:
2863 repr = "common data object symbol type";
2864 break;
2865 case elf_symbol::TLS_TYPE:
2866 repr = "thread local data object symbol type";
2867 break;
2868 case elf_symbol::GNU_IFUNC_TYPE:
2869 repr = "indirect function symbol type";
2870 break;
2871 default:
2872 {
2873 std::ostringstream s;
2874 s << "unknown symbol type (" << (char)t << ')';
2875 repr = s.str();
2876 }
2877 break;
2878 }
2879
2880 o << repr;
2881 return o;
2882}
2883
2884/// Serialize an instance of @ref symbol_binding and stream it to a
2885/// given output stream.
2886///
2887/// @param o the output stream to serialize the symbole type to.
2888///
2889/// @param b the symbol binding to serialize.
2890std::ostream&
2891operator<<(std::ostream& o, elf_symbol::binding b)
2892{
2893 string repr;
2894
2895 switch (b)
2896 {
2897 case elf_symbol::LOCAL_BINDING:
2898 repr = "local binding";
2899 break;
2900 case elf_symbol::GLOBAL_BINDING:
2901 repr = "global binding";
2902 break;
2903 case elf_symbol::WEAK_BINDING:
2904 repr = "weak binding";
2905 break;
2906 case elf_symbol::GNU_UNIQUE_BINDING:
2907 repr = "GNU unique binding";
2908 break;
2909 default:
2910 {
2911 std::ostringstream s;
2912 s << "unknown binding (" << (unsigned char) b << ")";
2913 repr = s.str();
2914 }
2915 break;
2916 }
2917
2918 o << repr;
2919 return o;
2920}
2921
2922/// Serialize an instance of @ref elf_symbol::visibility and stream it
2923/// to a given output stream.
2924///
2925/// @param o the output stream to serialize the symbole type to.
2926///
2927/// @param v the symbol visibility to serialize.
2928std::ostream&
2929operator<<(std::ostream& o, elf_symbol::visibility v)
2930{
2931 string repr;
2932
2933 switch (v)
2934 {
2935 case elf_symbol::DEFAULT_VISIBILITY:
2936 repr = "default visibility";
2937 break;
2938 case elf_symbol::PROTECTED_VISIBILITY:
2939 repr = "protected visibility";
2940 break;
2941 case elf_symbol::HIDDEN_VISIBILITY:
2942 repr = "hidden visibility";
2943 break;
2944 case elf_symbol::INTERNAL_VISIBILITY:
2945 repr = "internal visibility";
2946 break;
2947 default:
2948 {
2949 std::ostringstream s;
2950 s << "unknown visibility (" << (unsigned char) v << ")";
2951 repr = s.str();
2952 }
2953 break;
2954 }
2955
2956 o << repr;
2957 return o;
2958}
2959
2960/// Convert a string representing a symbol type into an
2961/// elf_symbol::type.
2962///
2963///@param s the string to convert.
2964///
2965///@param t the resulting elf_symbol::type.
2966///
2967/// @return true iff the conversion completed successfully.
2968bool
2970{
2971 if (s == "no-type")
2972 t = elf_symbol::NOTYPE_TYPE;
2973 else if (s == "object-type")
2974 t = elf_symbol::OBJECT_TYPE;
2975 else if (s == "func-type")
2976 t = elf_symbol::FUNC_TYPE;
2977 else if (s == "section-type")
2978 t = elf_symbol::SECTION_TYPE;
2979 else if (s == "file-type")
2980 t = elf_symbol::FILE_TYPE;
2981 else if (s == "common-type")
2982 t = elf_symbol::COMMON_TYPE;
2983 else if (s == "tls-type")
2984 t = elf_symbol::TLS_TYPE;
2985 else if (s == "gnu-ifunc-type")
2986 t = elf_symbol::GNU_IFUNC_TYPE;
2987 else
2988 return false;
2989
2990 return true;
2991}
2992
2993/// Convert a string representing a an elf symbol binding into an
2994/// elf_symbol::binding.
2995///
2996/// @param s the string to convert.
2997///
2998/// @param b the resulting elf_symbol::binding.
2999///
3000/// @return true iff the conversion completed successfully.
3001bool
3003{
3004 if (s == "local-binding")
3005 b = elf_symbol::LOCAL_BINDING;
3006 else if (s == "global-binding")
3007 b = elf_symbol::GLOBAL_BINDING;
3008 else if (s == "weak-binding")
3009 b = elf_symbol::WEAK_BINDING;
3010 else if (s == "gnu-unique-binding")
3011 b = elf_symbol::GNU_UNIQUE_BINDING;
3012 else
3013 return false;
3014
3015 return true;
3016}
3017
3018/// Convert a string representing a an elf symbol visibility into an
3019/// elf_symbol::visibility.
3020///
3021/// @param s the string to convert.
3022///
3023/// @param b the resulting elf_symbol::visibility.
3024///
3025/// @return true iff the conversion completed successfully.
3026bool
3028{
3029 if (s == "default-visibility")
3030 v = elf_symbol::DEFAULT_VISIBILITY;
3031 else if (s == "protected-visibility")
3032 v = elf_symbol::PROTECTED_VISIBILITY;
3033 else if (s == "hidden-visibility")
3034 v = elf_symbol::HIDDEN_VISIBILITY;
3035 else if (s == "internal-visibility")
3036 v = elf_symbol::INTERNAL_VISIBILITY;
3037 else
3038 return false;
3039
3040 return true;
3041}
3042
3043/// Test if the type of an ELF symbol denotes a function symbol.
3044///
3045/// @param t the type of the ELF symbol.
3046///
3047/// @return true iff elf symbol type @p t denotes a function symbol
3048/// type.
3049bool
3051{return t == elf_symbol::FUNC_TYPE;}
3052
3053/// Test if the type of an ELF symbol denotes a function symbol.
3054///
3055/// @param t the type of the ELF symbol.
3056///
3057/// @return true iff elf symbol type @p t denotes a function symbol
3058/// type.
3059bool
3061{return t == elf_symbol::OBJECT_TYPE;}
3062
3063// <elf_symbol::version stuff>
3064
3065struct elf_symbol::version::priv
3066{
3067 string version_;
3068 bool is_default_;
3069
3070 priv()
3071 : is_default_(false)
3072 {}
3073
3074 priv(const string& v,
3075 bool d)
3076 : version_(v),
3077 is_default_(d)
3078 {}
3079}; // end struct elf_symbol::version::priv
3080
3081elf_symbol::version::version()
3082 : priv_(new priv)
3083{}
3084
3085/// @param v the name of the version.
3086///
3087/// @param is_default true if this is a default version.
3088elf_symbol::version::version(const string& v,
3089 bool is_default)
3090 : priv_(new priv(v, is_default))
3091{}
3092
3093elf_symbol::version::version(const elf_symbol::version& v)
3094 : priv_(new priv(v.str(), v.is_default()))
3095{
3096}
3097
3098elf_symbol::version::~version() = default;
3099
3100/// Cast the version_type into a string that is its name.
3101///
3102/// @return the name of the version.
3103elf_symbol::version::operator const string&() const
3104{return priv_->version_;}
3105
3106/// Getter for the version name.
3107///
3108/// @return the version name.
3109const string&
3111{return priv_->version_;}
3112
3113/// Setter for the version name.
3114///
3115/// @param s the version name.
3116void
3118{priv_->version_ = s;}
3119
3120/// Getter for the 'is_default' property of the version.
3121///
3122/// @return true iff this is a default version.
3123bool
3125{return priv_->is_default_;}
3126
3127/// Setter for the 'is_default' property of the version.
3128///
3129/// @param f true if this is the default version.
3130void
3132{priv_->is_default_ = f;}
3133
3134bool
3135elf_symbol::version::is_empty() const
3136{return str().empty();}
3137
3138/// Compares the current version against another one.
3139///
3140/// @param o the other version to compare the current one to.
3141///
3142/// @return true iff the current version equals @p o.
3143bool
3145{return str() == o.str();}
3146
3147/// Inequality operator.
3148///
3149/// @param o the version to compare against the current one.
3150///
3151/// @return true iff both versions are different.
3152bool
3154{return !operator==(o);}
3155
3156/// Assign a version to the current one.
3157///
3158/// @param o the other version to assign to this one.
3159///
3160/// @return a reference to the assigned version.
3163{
3164 str(o.str());
3165 is_default(o.is_default());
3166 return *this;
3167}
3168
3169// </elf_symbol::version stuff>
3170
3171// </elf_symbol stuff>
3172
3173// <class dm_context_rel stuff>
3174struct dm_context_rel::priv
3175{
3176 bool is_laid_out_;
3177 size_t offset_in_bits_;
3178 var_decl* anonymous_data_member_;
3179
3180 priv(bool is_static = false)
3181 : is_laid_out_(!is_static),
3182 offset_in_bits_(0),
3183 anonymous_data_member_()
3184 {}
3185
3186 priv(bool is_laid_out, size_t offset_in_bits)
3187 : is_laid_out_(is_laid_out),
3188 offset_in_bits_(offset_in_bits),
3189 anonymous_data_member_()
3190 {}
3191}; //end struct dm_context_rel::priv
3192
3193dm_context_rel::dm_context_rel()
3194 : context_rel(),
3195 priv_(new priv)
3196{}
3197
3198dm_context_rel::dm_context_rel(scope_decl* s,
3199 bool is_laid_out,
3200 size_t offset_in_bits,
3202 bool is_static)
3203 : context_rel(s, a, is_static),
3204 priv_(new priv(is_laid_out, offset_in_bits))
3205{}
3206
3207dm_context_rel::dm_context_rel(scope_decl* s)
3208 : context_rel(s),
3209 priv_(new priv())
3210{}
3211
3212bool
3213dm_context_rel::get_is_laid_out() const
3214{return priv_->is_laid_out_;}
3215
3216void
3217dm_context_rel::set_is_laid_out(bool f)
3218{priv_->is_laid_out_ = f;}
3219
3220size_t
3221dm_context_rel::get_offset_in_bits() const
3222{return priv_->offset_in_bits_;}
3223
3224void
3225dm_context_rel::set_offset_in_bits(size_t o)
3226{priv_->offset_in_bits_ = o;}
3227
3228bool
3229dm_context_rel::operator==(const dm_context_rel& o) const
3230{
3231 if (!context_rel::operator==(o))
3232 return false;
3233
3234 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3235 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3236}
3237
3238bool
3239dm_context_rel::operator!=(const dm_context_rel& o) const
3240{return !operator==(o);}
3241
3242/// Return a non-nil value if this data member context relationship
3243/// has an anonymous data member. That means, if the data member this
3244/// relation belongs to is part of an anonymous data member.
3245///
3246/// @return the containing anonymous data member of this data member
3247/// relationship. Nil if there is none.
3248const var_decl*
3250{return priv_->anonymous_data_member_;}
3251
3252/// Set the containing anonymous data member of this data member
3253/// context relationship. That means that the data member this
3254/// relation belongs to is part of an anonymous data member.
3255///
3256/// @param anon_dm the containing anonymous data member of this data
3257/// member relationship. Nil if there is none.
3258void
3260{priv_->anonymous_data_member_ = anon_dm;}
3261
3262dm_context_rel::~dm_context_rel()
3263{}
3264// </class dm_context_rel stuff>
3265
3266// <environment stuff>
3267
3268/// Convenience typedef for a map of interned_string -> bool.
3269typedef unordered_map<interned_string,
3271
3272
3273/// Default constructor of the @ref environment type.
3275 :priv_(new priv)
3276{}
3277
3278/// Destructor for the @ref environment type.
3280{}
3281
3282/// Getter the map of canonical types.
3283///
3284/// @return the map of canonical types. The key of the map is the
3285/// hash of the canonical type and its value if the canonical type.
3288{return priv_->canonical_types_;}
3289
3290/// Getter the map of canonical types.
3291///
3292/// @return the map of canonical types. The key of the map is the
3293/// hash of the canonical type and its value if the canonical type.
3296{return const_cast<environment*>(this)->get_canonical_types_map();}
3297
3298/// Helper to detect if a type is either a reference, a pointer, or a
3299/// qualified type.
3300static bool
3301is_ptr_ref_or_qual_type(const type_base *t)
3302{
3303 if (is_pointer_type(t)
3304 || is_reference_type(t)
3305 || is_qualified_type(t))
3306 return true;
3307 return false;
3308}
3309
3310/// Compare decls using their locations.
3311///
3312/// @param f the first decl to compare.
3313///
3314/// @param s the second decl to compare.
3315///
3316/// @return true if @p f compares less than @p s.
3317static bool
3318compare_using_locations(const decl_base *f,
3319 const decl_base *s)
3320{
3321 // If a decl has artificial location, then use that one over the
3322 // natural one.
3325
3326 ABG_ASSERT(fl.get_value() && sl.get_value());
3327 if (fl.get_is_artificial() == sl.get_is_artificial())
3328 {
3329 // The locations of the two artfifacts have the same
3330 // artificial-ness so they can be compared.
3331 string p1, p2;
3332 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3333 fl.expand(p1, l1, c1);
3334 sl.expand(p2, l2, c2);
3335 if (p1 != p2)
3336 return p1 < p2;
3337 if (l1 != l2)
3338 return l1 < l2;
3339 if (c1 != c2)
3340 return c1 < c2;
3341 }
3342
3343 return (get_pretty_representation(f, /*internal=*/false)
3344 < get_pretty_representation(s, /*internal=*/false));
3345}
3346
3347/// A functor to sort decls somewhat topologically. That is, types
3348/// are sorted in a way that makes the ones that are defined "first"
3349/// to come first.
3350///
3351/// The topological criteria is a lexicographic sort of the definition
3352/// location of the type. For types that have no location (or the
3353/// same location), it's their qualified name that is used for the
3354/// lexicographic sort.
3355struct decl_topo_comp
3356{
3357
3358 /// The "Less Than" comparison operator of this functor.
3359 ///
3360 /// @param f the first decl to be considered for the comparison.
3361 ///
3362 /// @param s the second decl to be considered for the comparison.
3363 ///
3364 /// @return true iff @p f is less than @p s.
3365 bool
3366 operator()(const decl_base *f,
3367 const decl_base *s)
3368 {
3369 if (!!f != !!s)
3370 return f && !s;
3371
3372 if (!f)
3373 return false;
3374
3375 // Unique types that are artificially created in the environment
3376 // don't have locations. They ought to be compared on the basis
3377 // of their pretty representation before we start looking at IR
3378 // nodes' locations down the road.
3380 return (get_pretty_representation(f, /*internal=*/false)
3381 < get_pretty_representation(s, /*internal=*/false));
3382
3383 // If both decls come from an abixml file, keep the order they
3384 // have from that abixml file.
3385 if ((!f->get_corpus() && !s->get_corpus())
3386 || (f->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
3387 && s->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN))
3388 return compare_using_locations(f, s);
3389
3390 // If a decl has artificial location, then use that one over the
3391 // natural one.
3392 location fl = get_artificial_or_natural_location(f);
3393 location sl = get_artificial_or_natural_location(s);
3394
3395 if (fl.get_value() && sl.get_value())
3396 return compare_using_locations(f, s);
3397 else if (!!fl != !!sl)
3398 // So one of the decls doesn't have location data.
3399 // The first decl is less than the second if it's the one not
3400 // having location data.
3401 return !fl && sl;
3402
3403 // We reach this point if location data is useless.
3404 if (f->get_is_anonymous()
3405 && s->get_is_anonymous()
3406 && (get_pretty_representation(f, /*internal=*/false)
3407 == get_pretty_representation(s, /*internal=*/false)))
3408 return f->get_name() < s->get_name();
3409
3410 return (get_pretty_representation(f, /*internal=*/false)
3411 < get_pretty_representation(s, /*internal=*/false));
3412 }
3413
3414 /// The "Less Than" comparison operator of this functor.
3415 ///
3416 /// @param f the first decl to be considered for the comparison.
3417 ///
3418 /// @param s the second decl to be considered for the comparison.
3419 ///
3420 /// @return true iff @p f is less than @p s.
3421 bool
3422 operator()(const decl_base_sptr &f,
3423 const decl_base_sptr &s)
3424 {return operator()(f.get(), s.get());}
3425
3426}; // end struct decl_topo_comp
3427
3428/// A functor to sort types somewhat topologically. That is, types
3429/// are sorted in a way that makes the ones that are defined "first"
3430/// to come first.
3431///
3432/// The topological criteria is a lexicographic sort of the definition
3433/// location of the type. For types that have no location, it's their
3434/// qualified name that is used for the lexicographic sort.
3435struct type_topo_comp
3436{
3437 /// Test if a decl has an artificial or natural location.
3438 ///
3439 /// @param d the decl to consider
3440 ///
3441 /// @return true iff @p d has a location.
3442 bool
3443 has_artificial_or_natural_location(const decl_base* d)
3445
3446 /// Test if a type has an artificial or natural location.
3447 ///
3448 /// @param t the type to consider
3449 ///
3450 /// @return true iff @p t has a location.
3451 bool
3452 has_artificial_or_natural_location(const type_base* t)
3453 {
3454 if (decl_base *d = is_decl(t))
3455 return has_artificial_or_natural_location(d);
3456 return false;
3457 }
3458
3459 /// The "Less Than" comparison operator of this functor.
3460 ///
3461 /// @param f the first type to be considered for the comparison.
3462 ///
3463 /// @param s the second type to be considered for the comparison.
3464 ///
3465 /// @return true iff @p f is less than @p s.
3466 bool
3467 operator()(const type_base_sptr &f,
3468 const type_base_sptr &s)
3469 {return operator()(f.get(), s.get());}
3470
3471 /// The "Less Than" comparison operator of this functor.
3472 ///
3473 /// @param f the first type to be considered for the comparison.
3474 ///
3475 /// @param s the second type to be considered for the comparison.
3476 ///
3477 /// @return true iff @p f is less than @p s.
3478 bool
3479 operator()(const type_base *f,
3480 const type_base *s)
3481 {
3482 // If both decls come from an abixml file, keep the order they
3483 // have from that abixml file.
3484 if ((!f->get_corpus() && !s->get_corpus())
3485 || (f->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
3486 && s->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN))
3487 return compare_using_locations(is_decl(f), is_decl(s));
3488
3489 bool f_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(f);
3490 bool s_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(s);
3491
3492 if (f_is_ptr_ref_or_qual != s_is_ptr_ref_or_qual)
3493 return !f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual;
3494
3495 if (f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual
3496 && !has_artificial_or_natural_location(f)
3497 && !has_artificial_or_natural_location(s))
3498 {
3499 string s1 = get_pretty_representation(f, /*internal=*/false);
3500 string s2 = get_pretty_representation(s, /*internal=*/false);
3501 if (s1 == s2)
3502 {
3503 if (qualified_type_def * q = is_qualified_type(f))
3504 {
3505 if (q->get_cv_quals() == qualified_type_def::CV_NONE)
3506 if (!is_qualified_type(s))
3507 // We are looking at two types that are the result of
3508 // an optimization that happens during the IR
3509 // construction. Namely, type f is a cv-qualified
3510 // type with no qualifier (no const, no volatile, no
3511 // nothing, we call it an empty-qualified type).
3512 // These are the result of an optimization which
3513 // removes "redundant qualifiers" from some types.
3514 // For instance, consider a "const reference". The
3515 // const there is redundant because a reference is
3516 // always const. So as a result of the optimizaton
3517 // that type is going to be transformed into an
3518 // empty-qualified reference. If we don't make that
3519 // optimization, then we risk having spurious change
3520 // reports down the road. But then, as a consequence
3521 // of that optimization, we need to sort the
3522 // empty-qualified type and its non-qualified variant
3523 // e.g, to ensure stability in the abixml output; both
3524 // types are logically equal, but here, we decide that
3525 // the empty-qualified one is topologically "less
3526 // than" the non-qualified counterpart.
3527 //
3528 // So here, type f is an empty-qualified type and type
3529 // s is its non-qualified variant. We decide that f
3530 // is topologically less than s.
3531 return true;
3532 }
3533 // Now let's peel off the pointer (or reference types) and
3534 // see if the ultimate underlying types have the same
3535 // textual representation; if not, use that as sorting
3536 // criterion.
3537 type_base *peeled_f =
3539 type_base *peeled_s =
3541
3542 s1 = get_pretty_representation(peeled_f, /*internal=*/false);
3543 s2 = get_pretty_representation(peeled_s, /*internal=*/false);
3544 if (s1 != s2)
3545 return s1 < s2;
3546
3547 // The underlying type of pointer/reference have the same
3548 // textual representation; let's try to peel of typedefs
3549 // as well and we'll consider sorting the result as decls.
3550 peeled_f = peel_typedef_pointer_or_reference_type(peeled_f, true);
3551 peeled_s = peel_typedef_pointer_or_reference_type(peeled_s, true);
3552
3553 s1 = get_pretty_representation(peeled_f, false);
3554 s2 = get_pretty_representation(peeled_s, false);
3555 if (s1 != s2)
3556 return s1 < s2;
3557 }
3558 }
3559
3560 string s1 = get_pretty_representation(f, false);
3561 string s2 = get_pretty_representation(s, false);
3562
3563 if (s1 != s2)
3564 return s1 < s2;
3565
3566 if (is_typedef(f) && is_typedef(s))
3567 {
3568 s1 = get_pretty_representation(is_typedef(f)->get_underlying_type(),
3569 false);
3570 s2 = get_pretty_representation(is_typedef(s)->get_underlying_type(),
3571 false);
3572 if (s1 != s2)
3573 return s1 < s2;
3574 }
3575
3576 type_base *peeled_f = peel_typedef_pointer_or_reference_type(f, true);
3577 type_base *peeled_s = peel_typedef_pointer_or_reference_type(s, true);
3578
3579 s1 = get_pretty_representation(peeled_f, false);
3580 s2 = get_pretty_representation(peeled_s, false);
3581
3582 if (s1 != s2)
3583 return s1 < s2;
3584
3585 decl_base *fd = is_decl(f);
3586 decl_base *sd = is_decl(s);
3587
3588 if (!!fd != !!sd)
3589 return fd && !sd;
3590
3591 // If the two types have no decls, how come we could not sort them
3592 // until now? Let's investigate.
3593 ABG_ASSERT(fd);
3594
3595 // From this point, fd and sd should be non-nil
3596 decl_topo_comp decl_comp;
3597 return decl_comp(fd, sd);
3598 }
3599}; //end struct type_topo_comp
3600
3601/// Sort types in a hopefully stable manner.
3602///
3603/// @param types a set of types with canonical types to sort.
3604///
3605/// @param result the resulting sorted vector.
3606void
3608 vector<type_base_sptr>& result)
3609{
3610 for (auto t: types)
3611 result.push_back(t);
3612
3613 type_topo_comp comp;
3614 std::stable_sort(result.begin(), result.end(), comp);
3615}
3616
3617/// Get the unique @ref type_decl that represents a "void" type for
3618/// the current environment. This node must be the only one
3619/// representing a void type in the system.
3620///
3621/// Note that upon first use of this IR node (by the relevant
3622/// front-end, for instance) it must be added to a scope using e.g,
3623/// the @ref add_decl_to_scope() function.
3624///
3625/// @return the @ref type_decl that represents a "void" type.
3626const type_base_sptr&
3628{
3629 if (!priv_->void_type_)
3630 priv_->void_type_.reset(new type_decl(*this,
3631 intern("void"),
3632 0, 0, location()));
3633 return priv_->void_type_;
3634}
3635
3636/// Getter of the "pointer-to-void" IR node that is shared across the
3637/// ABI corpus. This node must be the only one representing a void
3638/// pointer type in the system.
3639///
3640/// Note that upon first use of this IR node (by the relevant
3641/// front-end, for instance) it must be added to a scope using e.g,
3642/// the @ref add_decl_to_scope() function.
3643///
3644/// @return the "pointer-to-void" IR node.
3645const type_base_sptr&
3647{
3648 if (!priv_->void_pointer_type_)
3649 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3650 0, 0, location()));
3651 return priv_->void_pointer_type_;
3652}
3653
3654/// Get a @ref type_decl instance that represents a the type of a
3655/// variadic function parameter. This node must be the only one
3656/// representing a variadic parameter type in the system.
3657///
3658/// Note that upon first use of this IR node (by the relevant
3659/// front-end, for instance) it must be added to a scope using e.g,
3660/// the @ref add_decl_to_scope() function.
3661///
3662/// @return the Get a @ref type_decl instance that represents a the
3663/// type of a variadic function parameter.
3664const type_base_sptr&
3666{
3667 if (!priv_->variadic_marker_type_)
3668 priv_->variadic_marker_type_.
3670 0, 0, location()));
3671 return priv_->variadic_marker_type_;
3672}
3673
3674/// Getter of the name of the variadic parameter type.
3675///
3676/// @return the name of the variadic parameter type.
3677string&
3679{
3680 static string variadic_parameter_type_name = "variadic parameter type";
3681 return variadic_parameter_type_name;
3682}
3683
3684/// Test if the canonicalization of types created out of the current
3685/// environment is done.
3686///
3687/// @return true iff the canonicalization of types created out of the current
3688/// environment is done.
3689bool
3691{return priv_->canonicalization_is_done_;}
3692
3693/// Set a flag saying if the canonicalization of types created out of
3694/// the current environment is done or not.
3695///
3696/// Note that this function must only be called by internal code of
3697/// the library that creates ABI artifacts (e.g, read an abi corpus
3698/// from elf or from our own xml format and creates representations of
3699/// types out of it) and thus needs to canonicalize types to speed-up
3700/// further type comparison.
3701///
3702/// @param f the new value of the flag.
3703void
3705{priv_->canonicalization_is_done_ = f;}
3706
3707/// Getter for the "on-the-fly-canonicalization" flag.
3708///
3709/// @return true iff @ref OnTheFlyCanonicalization
3710/// "on-the-fly-canonicalization" is to be performed during
3711/// comparison.
3712bool
3714{return priv_->do_on_the_fly_canonicalization_;}
3715
3716/// Setter for the "on-the-fly-canonicalization" flag.
3717///
3718/// @param f If this is true then @ref OnTheFlyCanonicalization
3719/// "on-the-fly-canonicalization" is to be performed during
3720/// comparison.
3721void
3723{priv_->do_on_the_fly_canonicalization_ = f;}
3724
3725/// Getter of the "decl-only-class-equals-definition" flag.
3726///
3727/// Usually, a declaration-only class named 'struct foo' compares
3728/// equal to any class definition named "struct foo'. This is at
3729/// least true for C++.
3730///
3731/// In C, though, because there can be multiple definitions of 'struct
3732/// foo' in the binary, a declaration-only "struct foo" might be
3733/// considered to *NOT* resolve to any of the struct foo defined. In
3734/// that case, the declaration-only "struct foo" is considered
3735/// different from the definitions.
3736///
3737/// This flag controls the behaviour of the comparison of an
3738/// unresolved decl-only class against a definition of the same name.
3739///
3740/// If set to false, the the declaration equals the definition. If
3741/// set to false, then the decalration is considered different from
3742/// the declaration.
3743///
3744/// @return the value of the "decl-only-class-equals-definition" flag.
3745bool
3747{return priv_->decl_only_class_equals_definition_;}
3748
3749/// Setter of the "decl-only-class-equals-definition" flag.
3750///
3751/// Usually, a declaration-only class named 'struct foo' compares
3752/// equal to any class definition named "struct foo'. This is at
3753/// least true for C++.
3754///
3755/// In C, though, because there can be multiple definitions of 'struct
3756/// foo' in the binary, a declaration-only "struct foo" might be
3757/// considered to *NOT* resolve to any of the struct foo defined. In
3758/// that case, the declaration-only "struct foo" is considered
3759/// different from the definitions.
3760///
3761/// This flag controls the behaviour of the comparison of an
3762/// unresolved decl-only class against a definition of the same name.
3763///
3764/// If set to false, the the declaration equals the definition. If
3765/// set to false, then the decalration is considered different from
3766/// the declaration.
3767///
3768/// @param the new value of the "decl-only-class-equals-definition"
3769/// flag.
3770void
3772{priv_->decl_only_class_equals_definition_ = f;}
3773
3774/// Test if a given type is a void type as defined in the current
3775/// environment.
3776///
3777/// @param t the type to consider.
3778///
3779/// @return true iff @p t is a void type as defined in the current
3780/// environment.
3781bool
3782environment::is_void_type(const type_base_sptr& t) const
3783{
3784 if (!t)
3785 return false;
3786 return is_void_type(t.get());
3787}
3788
3789/// Test if a given type is a void type as defined in the current
3790/// environment.
3791///
3792/// @param t the type to consider.
3793///
3794/// @return true iff @p t is a void type as defined in the current
3795/// environment.
3796bool
3798{
3799 if (!t)
3800 return false;
3801 return (t == get_void_type().get()
3802 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3803}
3804
3805/// Test if a given type is the same as the void pointer type of the
3806/// environment.
3807///
3808/// @param t the IR type to test.
3809///
3810/// @return true iff @p t is the void pointer returned by
3811/// environment::get_void_pointer_type().
3812bool
3813environment::is_void_pointer_type(const type_base_sptr& t) const
3814{
3815 if (!t)
3816 return false;
3817
3818 return t.get() == get_void_pointer_type().get();
3819}
3820
3821/// Test if a given type is the same as the void pointer type of the
3822/// environment.
3823///
3824/// @param t the IR type to test.
3825///
3826/// @return true iff @p t is the void pointer returned by
3827/// environment::get_void_pointer_type().
3828bool
3830{
3831 if (!t)
3832 return false;
3833
3834 return t == get_void_pointer_type().get();
3835}
3836
3837/// Test if a type is a variadic parameter type as defined in the
3838/// current environment.
3839///
3840/// @param t the type to consider.
3841///
3842/// @return true iff @p t is a variadic parameter type as defined in
3843/// the current environment.
3844bool
3846{
3847 if (!t)
3848 return false;
3849 return t == get_variadic_parameter_type().get();
3850}
3851
3852/// Test if a type is a variadic parameter type as defined in the
3853/// current environment.
3854///
3855/// @param t the type to consider.
3856///
3857/// @return true iff @p t is a variadic parameter type as defined in
3858/// the current environment.
3859bool
3860environment::is_variadic_parameter_type(const type_base_sptr& t) const
3861{return is_variadic_parameter_type(t.get());}
3862
3863/// Do intern a string.
3864///
3865/// If a value of this string already exists in the interned string
3866/// pool of the current environment, then this function returns a new
3867/// interned_string pointing to that already existing string.
3868/// Otherwise, a new string is created, stored in the interned string
3869/// pool and a new interned_string instance is created to point to
3870/// that new intrerned string, and it's return.
3871///
3872/// @param s the value of the string to intern.
3873///
3874/// @return the interned string.
3876environment::intern(const string& s) const
3877{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3878
3879/// Getter of the general configuration object.
3880///
3881/// @return the configuration object.
3882const config&
3884{return priv_->config_;}
3885
3886/// Getter for a property that says if the user actually did set the
3887/// analyze_exported_interfaces_only() property. If not, it means
3888/// the default behaviour prevails.
3889///
3890/// @return tru iff the user did set the
3891/// analyze_exported_interfaces_only() property.
3892bool
3894{return priv_->analyze_exported_interfaces_only_.has_value();}
3895
3896/// Setter for the property that controls if we are to restrict the
3897/// analysis to the types that are only reachable from the exported
3898/// interfaces only, or if the set of types should be more broad than
3899/// that. Typically, we'd restrict the analysis to types reachable
3900/// from exported interfaces only (stricto sensu, that would really be
3901/// only the types that are part of the ABI of well designed
3902/// libraries) for performance reasons.
3903///
3904/// @param f the value of the flag.
3905void
3907{priv_->analyze_exported_interfaces_only_ = f;}
3908
3909/// Getter for the property that controls if we are to restrict the
3910/// analysis to the types that are only reachable from the exported
3911/// interfaces only, or if the set of types should be more broad than
3912/// that. Typically, we'd restrict the analysis to types reachable
3913/// from exported interfaces only (stricto sensu, that would really be
3914/// only the types that are part of the ABI of well designed
3915/// libraries) for performance reasons.
3916///
3917/// @param f the value of the flag.
3918bool
3920{return priv_->analyze_exported_interfaces_only_.value_or(false);}
3921
3922#ifdef WITH_DEBUG_SELF_COMPARISON
3923/// Setter of the corpus of the input corpus of the self comparison
3924/// that takes place when doing "abidw --debug-abidiff <binary>".
3925///
3926/// The first invocation of this function sets the first corpus of the
3927/// self comparison. The second invocation of this very same function
3928/// sets the second corpus of the self comparison. That second corpus
3929/// is supposed to come from the abixml serialization of the first
3930/// corpus.
3931///
3932/// @param c the corpus of the input binary or the corpus of the
3933/// abixml serialization of the initial binary input.
3934void
3935environment::set_self_comparison_debug_input(const corpus_sptr& c)
3936{
3937 self_comparison_debug_is_on(true);
3938 if (priv_->first_self_comparison_corpus_.expired())
3939 priv_->first_self_comparison_corpus_ = c;
3940 else if (priv_->second_self_comparison_corpus_.expired()
3941 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3942 priv_->second_self_comparison_corpus_ = c;
3943}
3944
3945/// Getter for the corpora of the input binary and the intermediate
3946/// abixml of the self comparison that takes place when doing
3947/// 'abidw --debug-abidiff <binary>'.
3948///
3949/// @param first_corpus output parameter that is set to the corpus of
3950/// the input corpus.
3951///
3952/// @param second_corpus output parameter that is set to the corpus of
3953/// the second corpus.
3954void
3955environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3956 corpus_sptr& second_corpus)
3957{
3958 first_corpus = priv_->first_self_comparison_corpus_.lock();
3959 second_corpus = priv_->second_self_comparison_corpus_.lock();
3960}
3961
3962/// Turn on/off the self comparison debug mode.
3963///
3964/// @param f true iff the self comparison debug mode is turned on.
3965void
3966environment::self_comparison_debug_is_on(bool f)
3967{priv_->self_comparison_debug_on_ = f;}
3968
3969/// Test if we are in the process of the 'self-comparison
3970/// debugging' as triggered by 'abidw --debug-abidiff' command.
3971///
3972/// @return true if self comparison debug is on.
3973bool
3974environment::self_comparison_debug_is_on() const
3975{return priv_->self_comparison_debug_on_;}
3976#endif
3977
3978#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3979/// Set the "type canonicalization debugging" mode, triggered by using
3980/// the command: "abidw --debug-tc".
3981///
3982/// @param flag if true then the type canonicalization debugging mode
3983/// is enabled.
3984void
3985environment::debug_type_canonicalization_is_on(bool flag)
3986{priv_->debug_type_canonicalization_ = flag;}
3987
3988/// Getter of the "type canonicalization debugging" mode, triggered by
3989/// using the command: "abidw --debug-tc".
3990///
3991/// @return true iff the type canonicalization debugging mode is
3992/// enabled.
3993bool
3994environment::debug_type_canonicalization_is_on() const
3995{return priv_->debug_type_canonicalization_;}
3996
3997/// Setter of the "DIE canonicalization debugging" mode, triggered by
3998/// using the command: "abidw --debug-dc".
3999///
4000/// @param flag true iff the DIE canonicalization debugging mode is
4001/// enabled.
4002void
4003environment::debug_die_canonicalization_is_on(bool flag)
4004{priv_->debug_die_canonicalization_ = flag;}
4005
4006/// Getter of the "DIE canonicalization debugging" mode, triggered by
4007/// using the command: "abidw --debug-dc".
4008///
4009/// @return true iff the DIE canonicalization debugging mode is
4010/// enabled.
4011bool
4012environment::debug_die_canonicalization_is_on() const
4013{return priv_->debug_die_canonicalization_;}
4014#endif // WITH_DEBUG_TYPE_CANONICALIZATION
4015
4016/// Get the vector of canonical types which have a given "string
4017/// representation".
4018///
4019/// @param 'name', the textual representation of the type as returned
4020/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
4021/// /*qualified=*/true)
4022///
4023/// This is useful to for debugging purposes as it's handy to use from
4024/// inside a debugger like GDB.
4025///
4026/// @return a pointer to the vector of canonical types having the
4027/// representation @p name, or nullptr if no type with that
4028/// representation exists.
4029vector<type_base_sptr>*
4031{
4032 auto ti = get_canonical_types_map().find(name);
4033 if (ti == get_canonical_types_map().end())
4034 return nullptr;
4035 return &ti->second;
4036}
4037
4038/// Get a given canonical type which has a given "string
4039/// representation".
4040///
4041/// @param 'name', the textual representation of the type as returned
4042/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
4043/// /*qualified=*/true).
4044///
4045/// @param index, the index of the type in the vector of types that
4046/// all have the same textual representation @p 'name'. That vector
4047/// is returned by the function environment::get_canonical_types().
4048///
4049/// @return the canonical type which has the representation @p name,
4050/// and which is at index @p index in the vector of canonical types
4051/// having that same textual representation.
4052type_base*
4053environment::get_canonical_type(const char* name, unsigned index)
4054{
4055 vector<type_base_sptr> *types = get_canonical_types(name);
4056 if (!types ||index >= types->size())
4057 return nullptr;
4058 return (*types)[index].get();
4059}
4060
4061#ifdef WITH_DEBUG_SELF_COMPARISON
4062/// Get the set of abixml type-id and the pointer value of the
4063/// (canonical) type it's associated to.
4064///
4065/// This is useful for debugging purposes, especially in the context
4066/// of the use of the command:
4067/// 'abidw --debug-abidiff <binary>'.
4068///
4069/// @return the set of abixml type-id and the pointer value of the
4070/// (canonical) type it's associated to.
4071const unordered_map<string, uintptr_t>&
4072environment::get_type_id_canonical_type_map() const
4073{return priv_->get_type_id_canonical_type_map();}
4074
4075/// Get the set of abixml type-id and the pointer value of the
4076/// (canonical) type it's associated to.
4077///
4078/// This is useful for debugging purposes, especially in the context
4079/// of the use of the command:
4080/// 'abidw --debug-abidiff <binary>'.
4081///
4082/// @return the set of abixml type-id and the pointer value of the
4083/// (canonical) type it's associated to.
4084unordered_map<string, uintptr_t>&
4085environment::get_type_id_canonical_type_map()
4086{return priv_->get_type_id_canonical_type_map();}
4087
4088/// Getter of the map that associates the values of type pointers to
4089/// their type-id strings.
4090///
4091/// Note that this map is populated at abixml reading time, (by
4092/// build_type()) when a given XML element representing a type is
4093/// read into a corresponding abigail::ir::type_base.
4094///
4095/// This is used only for the purpose of debugging the
4096/// self-comparison process. That is, when invoking "abidw
4097/// --debug-abidiff".
4098///
4099/// @return the map that associates the values of type pointers to
4100/// their type-id strings.
4101const unordered_map<uintptr_t, string>&
4102environment::get_pointer_type_id_map() const
4103{return priv_->get_pointer_type_id_map();}
4104
4105/// Getter of the map that associates the values of type pointers to
4106/// their type-id strings.
4107///
4108/// Note that this map is populated at abixml reading time, (by
4109/// build_type()) when a given XML element representing a type is
4110/// read into a corresponding abigail::ir::type_base.
4111///
4112/// This is used only for the purpose of debugging the
4113/// self-comparison process. That is, when invoking "abidw
4114/// --debug-abidiff".
4115///
4116/// @return the map that associates the values of type pointers to
4117/// their type-id strings.
4118unordered_map<uintptr_t, string>&
4119environment::get_pointer_type_id_map()
4120{return priv_->get_pointer_type_id_map();}
4121
4122/// Getter of the type-id that corresponds to the value of a pointer
4123/// to abigail::ir::type_base that was created from the abixml reader.
4124///
4125/// That value is retrieved from the map returned from
4126/// environment::get_pointer_type_id_map().
4127///
4128/// That map is populated at abixml reading time, (by build_type())
4129/// when a given XML element representing a type is read into a
4130/// corresponding abigail::ir::type_base.
4131///
4132/// This is used only for the purpose of debugging the
4133/// self-comparison process. That is, when invoking "abidw
4134/// --debug-abidiff".
4135///
4136/// @return the type-id strings that corresponds
4137string
4138environment::get_type_id_from_pointer(uintptr_t ptr) const
4139{return priv_->get_type_id_from_pointer(ptr);}
4140
4141/// Getter of the type-id that corresponds to the value of an
4142/// abigail::ir::type_base that was created from the abixml reader.
4143///
4144/// That value is retrieved from the map returned from
4145/// environment::get_pointer_type_id_map().
4146///
4147/// That map is populated at abixml reading time, (by build_type())
4148/// when a given XML element representing a type is read into a
4149/// corresponding abigail::ir::type_base.
4150///
4151/// This is used only for the purpose of debugging the
4152/// self-comparison process. That is, when invoking "abidw
4153/// --debug-abidiff".
4154///
4155/// @return the type-id strings that corresponds
4156string
4157environment::get_type_id_from_type(const type_base *t) const
4158{return priv_->get_type_id_from_type(t);}
4159
4160/// Getter of the canonical type of the artifact designated by a
4161/// type-id.
4162///
4163/// That type-id was generated by the abixml writer at the emitting
4164/// time of the abixml file. The corresponding canonical type was
4165/// stored in the map returned by
4166/// environment::get_type_id_canonical_type_map().
4167///
4168/// This is useful for debugging purposes, especially in the context
4169/// of the use of the command:
4170/// 'abidw --debug-abidiff <binary>'.
4171///
4172/// @return the set of abixml type-id and the pointer value of the
4173/// (canonical) type it's associated to.
4174uintptr_t
4175environment::get_canonical_type_from_type_id(const char* type_id) const
4176{return priv_->get_canonical_type_from_type_id(type_id);}
4177#endif
4178
4179// </environment stuff>
4180
4181// <type_or_decl_base stuff>
4182
4183/// The private data of @ref type_or_decl_base.
4184struct type_or_decl_base::priv
4185{
4186 // This holds the kind of dynamic type of particular instance.
4187 // Yes, this is part of the implementation of a "poor man" runtime
4188 // type identification. We are doing this because profiling shows
4189 // that using dynamic_cast in some places is really to slow and is
4190 // constituting a hotspot. This poor man's implementation made
4191 // things be much faster.
4192 enum type_or_decl_kind kind_;
4193 // This holds the runtime type instance pointer of particular
4194 // instance. In other words, this is the "this pointer" of the
4195 // dynamic type of a particular instance.
4196 void* rtti_;
4197 // This holds a pointer to either the type_base sub-object (if the
4198 // current instance is a type) or the decl_base sub-object (if the
4199 // current instance is a decl). This is used by the is_decl() and
4200 // is_type() functions, which also show up during profiling as
4201 // hotspots, due to their use of dynamic_cast.
4202 void* type_or_decl_ptr_;
4203 bool hashing_started_;
4204 const environment& env_;
4205 translation_unit* translation_unit_;
4206 // The location of an artifact as seen from its input by the
4207 // artifact reader. This might be different from the source
4208 // location advertised by the original emitter of the artifact
4209 // emitter.
4210 location artificial_location_;
4211 // Flags if the current ABI artifact is artificial (i.e, *NOT*
4212 // generated from the initial source code, but rather either
4213 // artificially by the compiler or by libabigail itself).
4214 bool is_artificial_;
4215
4216 /// Constructor of the type_or_decl_base::priv private type.
4217 ///
4218 /// @param e the environment in which the ABI artifact was created.
4219 ///
4220 /// @param k the identifier of the runtime type of the current
4221 /// instance of ABI artifact.
4222 priv(const environment& e,
4223 enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL)
4224 : kind_(k),
4225 rtti_(),
4226 type_or_decl_ptr_(),
4227 hashing_started_(),
4228 env_(e),
4229 translation_unit_(),
4230 is_artificial_()
4231 {}
4232
4234 kind() const
4235 {return kind_;}
4236
4237 void
4238 kind (enum type_or_decl_kind k)
4239 {kind_ |= k;}
4240}; // end struct type_or_decl_base::priv
4241
4242/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
4243/// bitmap type.
4247{
4248 return static_cast<type_or_decl_base::type_or_decl_kind>
4249 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4250}
4251
4252/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4253/// bitmap type.
4257{
4258 l = l | r;
4259 return l;
4260}
4261
4262/// bitwise "AND" operator for the
4263/// type_or_decl_base::type_or_decl_kind bitmap type.
4267{
4268 return static_cast<type_or_decl_base::type_or_decl_kind>
4269 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4270}
4271
4272/// bitwise "A&=" operator for the
4273/// type_or_decl_base::type_or_decl_kind bitmap type.
4277{
4278 l = l & r;
4279 return l;
4280}
4281
4282/// Constructor of @ref type_or_decl_base.
4283///
4284/// @param the environment the current ABI artifact is constructed
4285/// from.
4286///
4287/// @param k the runtime identifier bitmap of the type being built.
4288type_or_decl_base::type_or_decl_base(const environment& e,
4289 enum type_or_decl_kind k)
4290 :priv_(new priv(e, k))
4291{}
4292
4293/// The destructor of the @ref type_or_decl_base type.
4295{}
4296
4297/// Getter of the flag that says if the artefact is artificial.
4298///
4299/// Being artificial means it was not explicitely mentionned in the
4300/// source code, but was rather artificially created by the compiler
4301/// or libabigail.
4302///
4303/// @return true iff the declaration is artificial.
4304bool
4306{return priv_->is_artificial_;}
4307
4308/// Setter of the flag that says if the artefact is artificial.
4309///
4310/// Being artificial means the artefact was not explicitely
4311/// mentionned in the source code, but was rather artificially created
4312/// by the compiler or by libabigail.
4313///
4314/// @param f the new value of the flag that says if the artefact is
4315/// artificial.
4316void
4318{priv_->is_artificial_ = f;}
4319
4320/// Getter for the "kind" property of @ref type_or_decl_base type.
4321///
4322/// This property holds the identifier bitmap of the runtime type of
4323/// an ABI artifact.
4324///
4325/// @return the runtime type identifier bitmap of the current ABI
4326/// artifact.
4329{return priv_->kind();}
4330
4331/// Setter for the "kind" property of @ref type_or_decl_base type.
4332///
4333/// This property holds the identifier bitmap of the runtime type of
4334/// an ABI artifact.
4335///
4336/// @param the runtime type identifier bitmap of the current ABI
4337/// artifact.
4338void
4340{priv_->kind(k);}
4341
4342/// Getter of the pointer to the runtime type sub-object of the
4343/// current instance.
4344///
4345/// @return the pointer to the runtime type sub-object of the current
4346/// instance.
4347const void*
4349{return priv_->rtti_;}
4350
4351/// Getter of the pointer to the runtime type sub-object of the
4352/// current instance.
4353///
4354/// @return the pointer to the runtime type sub-object of the current
4355/// instance.
4356void*
4358{return priv_->rtti_;}
4359
4360/// Setter of the pointer to the runtime type sub-object of the
4361/// current instance.
4362///
4363/// @param i the new pointer to the runtime type sub-object of the
4364/// current instance.
4365void
4367{
4368 priv_->rtti_ = i;
4369 if (type_base* t = dynamic_cast<type_base*>(this))
4370 priv_->type_or_decl_ptr_ = t;
4371 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4372 priv_->type_or_decl_ptr_ = d;
4373}
4374
4375/// Getter of the pointer to either the type_base sub-object of the
4376/// current instance if it's a type, or to the decl_base sub-object of
4377/// the current instance if it's a decl.
4378///
4379/// @return the pointer to either the type_base sub-object of the
4380/// current instance if it's a type, or to the decl_base sub-object of
4381/// the current instance if it's a decl.
4382const void*
4384{return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
4385
4386/// Getter of the pointer to either the type_base sub-object of the
4387/// current instance if it's a type, or to the decl_base sub-object of
4388/// the current instance if it's a decl.
4389///
4390/// @return the pointer to either the type_base sub-object of the
4391/// current instance if it's a type, or to the decl_base sub-object of
4392/// the current instance if it's a decl.
4393void*
4395{return priv_->type_or_decl_ptr_;}
4396
4397/// Getter for the 'hashing_started' property.
4398///
4399/// @return the 'hashing_started' property.
4400bool
4402{return priv_->hashing_started_;}
4403
4404/// Setter for the 'hashing_started' property.
4405///
4406/// @param b the value to set the 'hashing_property' to.
4407void
4409{priv_->hashing_started_ = b;}
4410
4411/// Getter of the environment of the current ABI artifact.
4412///
4413/// @return the environment of the artifact.
4414const environment&
4416{return priv_->env_;}
4417
4418/// Setter of the artificial location of the artificat.
4419///
4420/// The artificial location is a location that was artificially
4421/// generated by libabigail, not generated by the original emitter of
4422/// the ABI meta-data. For instance, when reading an XML element from
4423/// an abixml file, the artificial location is the source location of
4424/// the XML element within the file, not the value of the
4425/// 'location'property that might be carried by the element.
4426///
4427/// Artificial locations might be useful to ensure that abixml emitted
4428/// by the abixml writer are sorted the same way as the input abixml
4429/// read by the reader.
4430///
4431/// @param l the new artificial location.
4432void
4434{priv_->artificial_location_ = l;}
4435
4436/// Getter of the artificial location of the artifact.
4437///
4438/// The artificial location is a location that was artificially
4439/// generated by libabigail, not generated by the original emitter of
4440/// the ABI meta-data. For instance, when reading an XML element from
4441/// an abixml file, the artificial location is the source location of
4442/// the XML element within the file, not the value of the
4443/// 'location'property that might be carried by the element.
4444///
4445/// Artificial locations might be useful to ensure that the abixml
4446/// emitted by the abixml writer is sorted the same way as the input
4447/// abixml read by the reader.
4448///
4449/// @return the new artificial location.
4450location&
4452{return priv_->artificial_location_;}
4453
4454/// Test if the current ABI artifact carries an artificial location.
4455///
4456/// @return true iff the current ABI artifact carries an artificial location.
4457bool
4459{
4460 return (priv_->artificial_location_
4461 && priv_->artificial_location_.get_is_artificial());
4462}
4463
4464/// Get the @ref corpus this ABI artifact belongs to.
4465///
4466/// @return the corpus this ABI artifact belongs to, or nil if it
4467/// belongs to none for now.
4468corpus*
4470{
4472 if (!tu)
4473 return 0;
4474 return tu->get_corpus();
4475}
4476
4477
4478/// Get the @ref corpus this ABI artifact belongs to.
4479///
4480/// @return the corpus this ABI artifact belongs to, or nil if it
4481/// belongs to none for now.
4482const corpus*
4484{return const_cast<type_or_decl_base*>(this)->get_corpus();}
4485
4486/// Set the @ref translation_unit this ABI artifact belongs to.
4487///
4488/// Note that adding an ABI artifact to a containining on should
4489/// invoke this member function.
4490void
4492{priv_->translation_unit_ = tu;}
4493
4494
4495/// Get the @ref translation_unit this ABI artifact belongs to.
4496///
4497/// @return the translation unit this ABI artifact belongs to, or nil
4498/// if belongs to none for now.
4501{return priv_->translation_unit_;}
4502
4503/// Get the @ref translation_unit this ABI artifact belongs to.
4504///
4505/// @return the translation unit this ABI artifact belongs to, or nil
4506/// if belongs to none for now.
4507const translation_unit*
4509{return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
4510
4511/// Traverse the the ABI artifact.
4512///
4513/// @param v the visitor used to traverse the sub-tree nodes of the
4514/// artifact.
4515bool
4517{return true;}
4518
4519/// Non-member equality operator for the @type_or_decl_base type.
4520///
4521/// @param lr the left-hand operand of the equality.
4522///
4523/// @param rr the right-hand operatnr of the equality.
4524///
4525/// @return true iff @p lr equals @p rr.
4526bool
4528{
4529 const type_or_decl_base* l = &lr;
4530 const type_or_decl_base* r = &rr;
4531
4532 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4533 *dr = dynamic_cast<const decl_base*>(r);
4534
4535 if (!!dl != !!dr)
4536 return false;
4537
4538 if (dl && dr)
4539 return *dl == *dr;
4540
4541 const type_base* tl = dynamic_cast<const type_base*>(l),
4542 *tr = dynamic_cast<const type_base*>(r);
4543
4544 if (!!tl != !!tr)
4545 return false;
4546
4547 if (tl && tr)
4548 return *tl == *tr;
4549
4550 return false;
4551}
4552
4553/// Non-member equality operator for the @type_or_decl_base type.
4554///
4555/// @param l the left-hand operand of the equality.
4556///
4557/// @param r the right-hand operatnr of the equality.
4558///
4559/// @return true iff @p l equals @p r.
4560bool
4562{
4563 if (!! l != !!r)
4564 return false;
4565
4566 if (!l)
4567 return true;
4568
4569 return *r == *l;
4570}
4571
4572/// Non-member inequality operator for the @type_or_decl_base type.
4573///
4574/// @param l the left-hand operand of the equality.
4575///
4576/// @param r the right-hand operator of the equality.
4577///
4578/// @return true iff @p l is different from @p r.
4579bool
4581{return !operator==(l, r);}
4582
4583// </type_or_decl_base stuff>
4584
4585// <Decl definition>
4586
4587struct decl_base::priv
4588{
4589 bool in_pub_sym_tab_;
4590 bool is_anonymous_;
4591 location location_;
4592 context_rel *context_;
4593 interned_string name_;
4594 interned_string qualified_parent_name_;
4595 // This temporary qualified name is the cache used for the qualified
4596 // name before the type associated to this decl (if applicable) is
4597 // canonicalized. Once the type is canonicalized, the cached use is
4598 // the data member qualified_parent_name_ above.
4599 interned_string temporary_qualified_name_;
4600 // This is the fully qualified name of the decl. It contains the
4601 // name of the decl and the qualified name of its scope. So if in
4602 // the parent scopes of the decl, there is one anonymous struct,
4603 // somewhere in the name, there is going to by an
4604 // __anonymous_struct__ string, even if the anonymous struct is not
4605 // the direct containing scope of this decl.
4606 interned_string qualified_name_;
4607 interned_string temporary_internal_qualified_name_;
4608 interned_string internal_qualified_name_;
4609 // Unline qualified_name_, scoped_name_ contains the name of the
4610 // decl and the name of its scope; not the qualified name of the
4611 // scope.
4612 interned_string scoped_name_;
4613 interned_string linkage_name_;
4614 visibility visibility_;
4615 decl_base_sptr declaration_;
4616 decl_base_wptr definition_of_declaration_;
4617 decl_base* naked_definition_of_declaration_;
4618 bool is_declaration_only_;
4619 typedef_decl_sptr naming_typedef_;
4620
4621 priv()
4622 : in_pub_sym_tab_(false),
4623 is_anonymous_(true),
4624 context_(),
4625 visibility_(VISIBILITY_DEFAULT),
4626 naked_definition_of_declaration_(),
4627 is_declaration_only_(false)
4628 {}
4629
4630 priv(interned_string name, interned_string linkage_name, visibility vis)
4631 : in_pub_sym_tab_(false),
4632 context_(),
4633 name_(name),
4634 qualified_name_(name),
4635 linkage_name_(linkage_name),
4636 visibility_(vis),
4637 naked_definition_of_declaration_(),
4638 is_declaration_only_(false)
4639 {
4640 is_anonymous_ = name_.empty();
4641 }
4642
4643 ~priv()
4644 {
4645 delete context_;
4646 }
4647};// end struct decl_base::priv
4648
4649/// Constructor for the @ref decl_base type.
4650///
4651/// @param e the environment the current @ref decl_base is being
4652/// created in.
4653///
4654/// @param name the name of the declaration.
4655///
4656/// @param locus the location where to find the declaration in the
4657/// source code.
4658///
4659/// @param linkage_name the linkage name of the declaration.
4660///
4661/// @param vis the visibility of the declaration.
4662decl_base::decl_base(const environment& e,
4663 const string& name,
4664 const location& locus,
4665 const string& linkage_name,
4666 visibility vis)
4667 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4668 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4669{
4670 set_location(locus);
4671}
4672
4673/// Constructor.
4674///
4675/// @param e the environment this instance of @ref decl_base is
4676/// created in.
4677///
4678/// @param name the name of the declaration being constructed.
4679///
4680/// @param locus the source location of the declaration being constructed.
4681///
4682/// @param linkage_name the linkage name of the declaration being
4683/// constructed.
4684///
4685/// @param vis the visibility of the declaration being constructed.
4686decl_base::decl_base(const environment& e,
4687 const interned_string& name,
4688 const location& locus,
4689 const interned_string& linkage_name,
4690 visibility vis)
4691 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4692 priv_(new priv(name, linkage_name, vis))
4693{
4694 set_location(locus);
4695}
4696
4697/// Constructor for the @ref decl_base type.
4698///
4699///@param environment the environment this instance of @ref decl_base
4700/// is being constructed in.
4701///
4702/// @param l the location where to find the declaration in the source
4703/// code.
4704decl_base::decl_base(const environment& e, const location& l)
4705 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4706 priv_(new priv())
4707{
4708 set_location(l);
4709}
4710
4711/// Getter for the qualified name.
4712///
4713/// Unlike decl_base::get_qualified_name() this doesn't try to update
4714/// the qualified name.
4715///
4716/// @return the qualified name.
4717const interned_string&
4719{return priv_->qualified_name_;}
4720
4721/// Clear the qualified name of this decl.
4722///
4723/// This is useful to ensure that the cache for the qualified name of
4724/// the decl is refreshed right after type canonicalization, for
4725/// instance.
4726void
4728{priv_->qualified_name_.clear();}
4729
4730/// Setter for the qualified name.
4731///
4732/// @param n the new qualified name.
4733void
4735{priv_->qualified_name_ = n;}
4736
4737/// Getter of the temporary qualified name of the current declaration.
4738///
4739/// This temporary qualified name is used as a qualified name cache by
4740/// the type for which this is the declaration (when applicable)
4741/// before the type is canonicalized. Once the type is canonicalized,
4742/// it's the result of decl_base::peek_qualified_name() that becomes
4743/// the qualified name cached.
4744///
4745/// @return the temporary qualified name.
4746const interned_string&
4748{return priv_->temporary_qualified_name_;}
4749
4750/// Setter for the temporary qualified name of the current
4751/// declaration.
4752///
4753///@param n the new temporary qualified name.
4754///
4755/// This temporary qualified name is used as a qualified name cache by
4756/// the type for which this is the declaration (when applicable)
4757/// before the type is canonicalized. Once the type is canonicalized,
4758/// it's the result of decl_base::peek_qualified_name() that becomes
4759/// the qualified name cached.
4760void
4762{priv_->temporary_qualified_name_ = n;}
4763
4764///Getter for the context relationship.
4765///
4766///@return the context relationship for the current decl_base.
4767const context_rel*
4769{return priv_->context_;}
4770
4771///Getter for the context relationship.
4772///
4773///@return the context relationship for the current decl_base.
4776{return priv_->context_;}
4777
4778void
4779decl_base::set_context_rel(context_rel *c)
4780{priv_->context_ = c;}
4781
4782/// Get the hash of a decl. If the hash hasn't been computed yet,
4783/// compute it ans store its value; otherwise, just return the hash.
4784///
4785/// @return the hash of the decl.
4786size_t
4788{
4789 size_t result = 0;
4790
4791 if (const type_base* t = dynamic_cast<const type_base*>(this))
4792 {
4794 result = hash(t);
4795 }
4796 else
4797 // If we reach this point, it mean we are missing a virtual
4798 // overload for decl_base::get_hash. Add it!
4799 abort();
4800
4801 return result;
4802}
4803
4804/// Test if the decl is defined in a ELF symbol table as a public
4805/// symbol.
4806///
4807/// @return true iff the decl is defined in a ELF symbol table as a
4808/// public symbol.
4809bool
4811{return priv_->in_pub_sym_tab_;}
4812
4813/// Set the flag saying if this decl is from a symbol that is in
4814/// a public symbols table, defined as public (global or weak).
4815///
4816/// @param f the new flag value.
4817void
4819{priv_->in_pub_sym_tab_ = f;}
4820
4821/// Get the location of a given declaration.
4822///
4823/// The location is an abstraction for the tripplet {file path,
4824/// line, column} that defines where the declaration appeared in the
4825/// source code.
4826///
4827/// To get the value of the tripplet {file path, line, column} from
4828/// the @ref location, you need to use the
4829/// location_manager::expand_location() method.
4830///
4831/// The instance of @ref location_manager that you want is
4832/// accessible from the instance of @ref translation_unit that the
4833/// current instance of @ref decl_base belongs to, via a call to
4834/// translation_unit::get_loc_mgr().
4835///
4836/// @return the location of the current instance of @ref decl_base.
4837const location&
4839{return priv_->location_;}
4840
4841/// Set the location for a given declaration.
4842///
4843/// The location is an abstraction for the tripplet {file path,
4844/// line, column} that defines where the declaration appeared in the
4845/// source code.
4846///
4847/// To create a location from a tripplet {file path, line, column},
4848/// you need to use the method @ref
4849/// location_manager::create_new_location().
4850///
4851/// Note that there can be two kinds of location. An artificial
4852/// location and a non-artificial one. The non-artificial location is
4853/// the one emitted by the original emitter of the ABI artifact, for
4854/// instance, if the ABI artifact comes from debug info, then the
4855/// source location that is present in the debug info represent a
4856/// non-artificial location. When looking at an abixml file on the
4857/// other hand, the value of the 'location' attribute of an XML
4858/// element describing an artifact is the non-artificial location.
4859/// The artificial location is the location (line number from the
4860/// beginning of the file) of the XML element within the abixml file.
4861///
4862/// So, if the location that is being set is artificial, note that the
4863/// type_or_decl_base::has_artificial_location() method of this decl will
4864/// subsequently return true and that artificial location will have to
4865/// be retrieved using type_or_decl_base::get_artificial_location().
4866/// If the location is non-artificial however,
4867/// type_or_decl_base::has_artificial_location() will subsequently
4868/// return false and the non-artificial location will have to be
4869/// retrieved using decl_base::get_location().
4870///
4871/// The instance of @ref location_manager that you want is
4872/// accessible from the instance of @ref translation_unit that the
4873/// current instance of @ref decl_base belongs to, via a call to
4874/// translation_unit::get_loc_mgr().
4875void
4877{
4878 if (l.get_is_artificial())
4880 else
4881 priv_->location_ = l;
4882}
4883
4884/// Setter for the name of the decl.
4885///
4886/// @param n the new name to set.
4887void
4888decl_base::set_name(const string& n)
4889{
4890 priv_->name_ = get_environment().intern(n);
4891 priv_->is_anonymous_ = n.empty();
4892}
4893
4894/// Test if the current declaration is anonymous.
4895///
4896/// Being anonymous means that the declaration was created without a
4897/// name. This can usually happen for enum or struct types.
4898///
4899/// @return true iff the type is anonymous.
4900bool
4902{return priv_->is_anonymous_;}
4903
4904/// Set the "is_anonymous" flag of the current declaration.
4905///
4906/// Being anonymous means that the declaration was created without a
4907/// name. This can usually happen for enum or struct types.
4908///
4909/// @param f the new value of the flag.
4910void
4912{priv_->is_anonymous_ = f;}
4913
4914
4915/// Get the "has_anonymous_parent" flag of the current declaration.
4916///
4917/// Having an anoymous parent means having a anonymous parent scope
4918/// (containing type or namespace) which is either direct or indirect.
4919///
4920/// @return true iff the current decl has a direct or indirect scope
4921/// which is anonymous.
4922bool
4924{
4925 scope_decl *scope = get_scope();
4926 if (!scope)
4927 return false;
4928 return scope->get_is_anonymous();
4929}
4930
4931/// @return the logical "OR" of decl_base::get_is_anonymous() and
4932/// decl_base::get_has_anonymous_parent().
4933bool
4936
4937/// Getter for the naming typedef of the current decl.
4938///
4939/// Consider the C idiom:
4940///
4941/// typedef struct {int member;} foo_type;
4942///
4943/// In that idiom, foo_type is the naming typedef of the anonymous
4944/// struct that is declared.
4945///
4946/// @return the naming typedef, if any. Otherwise, returns nil.
4949{return priv_->naming_typedef_;}
4950
4951/// Set the naming typedef of the current instance of @ref decl_base.
4952///
4953/// Consider the C idiom:
4954///
4955/// typedef struct {int member;} foo_type;
4956///
4957/// In that idiom, foo_type is the naming typedef of the anonymous
4958/// struct that is declared.
4959///
4960/// After completion of this function, the decl will not be considered
4961/// anonymous anymore. It's name is going to be the name of the
4962/// naming typedef.
4963///
4964/// @param typedef_type the new naming typedef.
4965void
4967{
4968 // A naming typedef is usually for an anonymous type.
4970 // Whe the typedef-named decl is saved into abixml, it's
4971 // not anonymous anymore. Its name is the typedef name.
4972 // So when we read it back, we must still be able to
4973 // apply the naming typedef to the decl.
4974 || t->get_name() == get_name());
4975 // Only non canonicalized types can be edited this way.
4976 ABG_ASSERT(is_type(this)
4977 && is_type(this)->get_naked_canonical_type() == nullptr);
4978
4979 priv_->naming_typedef_ = t;
4980 set_name(t->get_name());
4981 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4982 set_qualified_name(get_environment().intern(qualified_name));
4983 set_is_anonymous(false);
4984 // Now that the qualified type of the decl has changed, let's update
4985 // the qualified names of the member types of this decls.
4986 update_qualified_name(this);
4987}
4988
4989/// Getter for the mangled name.
4990///
4991/// @return the new mangled name.
4992const interned_string&
4994{return priv_->linkage_name_;}
4995
4996/// Setter for the linkage name.
4997///
4998/// @param m the new linkage name.
4999void
5001{
5002 const environment& env = get_environment();
5003 priv_->linkage_name_ = env.intern(m);
5004}
5005
5006/// Getter for the visibility of the decl.
5007///
5008/// @return the new visibility.
5011{return priv_->visibility_;}
5012
5013/// Setter for the visibility of the decl.
5014///
5015/// @param v the new visibility.
5016void
5018{priv_->visibility_ = v;}
5019
5020/// Return the type containing the current decl, if any.
5021///
5022/// @return the type that contains the current decl, or NULL if there
5023/// is none.
5026{
5027 if (priv_->context_)
5028 return priv_->context_->get_scope();
5029 return 0;
5030}
5031
5032/// Return a copy of the qualified name of the parent of the current
5033/// decl.
5034///
5035/// @return the newly-built qualified name of the of the current decl.
5036const interned_string&
5038{return priv_->qualified_parent_name_;}
5039
5040/// Getter for the name of the current decl.
5041///
5042/// @return the name of the current decl.
5043const interned_string&
5045{return priv_->name_;}
5046
5047/// Compute the qualified name of the decl.
5048///
5049/// @param qn the resulting qualified name.
5050///
5051/// @param internal set to true if the call is intended for an
5052/// internal use (for technical use inside the library itself), false
5053/// otherwise. If you don't know what this is for, then set it to
5054/// false.
5055void
5057{qn = get_qualified_name(internal);}
5058
5059/// Get the pretty representatin of the current declaration.
5060///
5061///
5062/// @param internal set to true if the call is intended to get a
5063/// representation of the decl (or type) for the purpose of canonical
5064/// type comparison. This is mainly used in the function
5065/// type_base::get_canonical_type_for().
5066///
5067/// In other words if the argument for this parameter is true then the
5068/// call is meant for internal use (for technical use inside the
5069/// library itself), false otherwise. If you don't know what this is
5070/// for, then set it to false.
5071///
5072/// @param qualified_name if true, names emitted in the pretty
5073/// representation are fully qualified.
5074///
5075/// @return the default pretty representation for a decl. This is
5076/// basically the fully qualified name of the decl optionally prefixed
5077/// with a meaningful string to add context for the user.
5078string
5080 bool qualified_name) const
5081{
5082 if (internal
5083 && get_is_anonymous()
5084 && has_generic_anonymous_internal_type_name(this))
5085 {
5086 // We are looking at an anonymous enum, union or class and we
5087 // want an *internal* pretty representation for it. All
5088 // anonymous types of this kind in the same namespace must have
5089 // the same internal representation for type canonicalization to
5090 // work properly.
5091 //
5092 // OK, in practise, we are certainly looking at an enum because
5093 // classes and unions should have their own overloaded virtual
5094 // member function for this.
5095 string name = get_generic_anonymous_internal_type_name(this);
5096 if (qualified_name && !get_qualified_parent_name().empty())
5097 name = get_qualified_parent_name() + "::" + name;
5098 return name;
5099 }
5100
5101 if (qualified_name)
5102 return get_qualified_name(internal);
5103 return get_name();
5104}
5105
5106/// Return the qualified name of the decl.
5107///
5108/// This is the fully qualified name of the decl. It's made of the
5109/// concatenation of the name of the decl with the qualified name of
5110/// its scope.
5111///
5112/// Note that the value returned by this function is computed by @ref
5113/// update_qualified_name when the decl is added to its scope.
5114///
5115/// @param internal set to true if the call is intended for an
5116/// internal use (for technical use inside the library itself), false
5117/// otherwise. If you don't know what this is for, then set it to
5118/// false.
5119///
5120/// @return the resulting qualified name.
5121const interned_string&
5122decl_base::get_qualified_name(bool /*internal*/) const
5123{return priv_->qualified_name_;}
5124
5125/// Return the scoped name of the decl.
5126///
5127/// This is made of the concatenation of the name of the decl with the
5128/// name of its scope. It doesn't contain the qualified name of its
5129/// scope, unlike what is returned by decl_base::get_qualified_name.
5130///
5131/// Note that the value returned by this function is computed by @ref
5132/// update_qualified_name when the decl is added to its scope.
5133///
5134/// @return the scoped name of the decl.
5135const interned_string&
5137{return priv_->scoped_name_;}
5138
5139/// If this @ref decl_base is a definition, get its earlier
5140/// declaration.
5141///
5142/// @return the earlier declaration of the class, if any.
5143const decl_base_sptr
5145{return priv_->declaration_;}
5146
5147/// set the earlier declaration of this @ref decl_base definition.
5148///
5149/// @param d the earlier declaration to set. Note that it's set only
5150/// if it's a pure declaration.
5151void
5153{
5154 if (d && d->get_is_declaration_only())
5155 priv_->declaration_ = d;
5156}
5157
5158
5159/// If this @ref decl_base is declaration-only, get its definition, if
5160/// any.
5161///
5162/// @return the definition of this decl-only @ref decl_base.
5163const decl_base_sptr
5165{return priv_->definition_of_declaration_.lock();}
5166
5167/// If this @ref decl_base is declaration-only, get its definition,
5168/// if any.
5169///
5170/// Note that this function doesn't return a smart pointer, but rather
5171/// the underlying pointer managed by the smart pointer. So it's as
5172/// fast as possible. This getter is to be used in code paths that
5173/// are proven to be performance hot spots; especially, when comparing
5174/// sensitive types like enums, classes or unions. Those are compared
5175/// extremely frequently and thus, their access to the definition of
5176/// declaration must be fast.
5177///
5178/// @return the definition of the declaration.
5179const decl_base*
5181{return priv_->naked_definition_of_declaration_;}
5182
5183/// Test if a @ref decl_base is a declaration-only decl.
5184///
5185/// @return true iff the current @ref decl_base is declaration-only.
5186bool
5188{return priv_->is_declaration_only_;}
5189
5190/// Set a flag saying if the @ref enum_type_decl is a declaration-only
5191/// @ref enum_type_decl.
5192///
5193/// @param f true if the @ref enum_type_decl is a declaration-only
5194/// @ref enum_type_decl.
5195void
5197{
5198 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
5199
5200 priv_->is_declaration_only_ = f;
5201
5202 if (update_types_lookup_map)
5203 if (scope_decl* s = get_scope())
5204 {
5205 scope_decl::declarations::iterator i;
5206 if (s->find_iterator_for_member(this, i))
5208 else
5210 }
5211}
5212
5215{
5216 return static_cast<change_kind>(static_cast<unsigned>(l)
5217 | static_cast<unsigned>(r));
5218}
5219
5222{
5223 return static_cast<change_kind>(static_cast<unsigned>(l)
5224 & static_cast<unsigned>(r));
5225}
5226
5229{
5230 l = l | r;
5231 return l;
5232}
5233
5236{
5237 l = l & r;
5238 return l;
5239}
5240
5241/// Compare the properties that belong to the "is-a-member-relation"
5242/// of a decl.
5243///
5244/// For instance, access specifiers are part of the
5245/// "is-a-member-relation" of a decl.
5246///
5247/// This comparison however doesn't take decl names into account. So
5248/// typedefs for instance are decls that we want to compare with this
5249/// function.
5250///
5251/// This function is a sub-routine of the more general 'equals'
5252/// overload for instances of decl_base.
5253///
5254/// @param l the left-hand side operand of the comparison.
5255///
5256/// @param r the right-hand side operand of the comparison.
5257///
5258/// @return true iff @p l compare equals, as a member decl, to @p r.
5259bool
5261 const decl_base& r,
5262 change_kind* k)
5263{
5264 bool result = true;
5265 if (is_member_decl(l) && is_member_decl(r))
5266 {
5267 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
5268 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
5269
5270 access_specifier la = no_access, ra = no_access;
5271 bool member_types_or_functions =
5272 ((is_type(l) && is_type(r))
5273 || (is_function_decl(l) && is_function_decl(r)));
5274
5275 if (member_types_or_functions)
5276 {
5277 // Access specifiers on member types in DWARF is not
5278 // reliable; in the same DSO, the same struct can be either
5279 // a class or a struct, and the access specifiers of its
5280 // member types are not necessarily given, so they
5281 // effectively can be considered differently, again, in the
5282 // same DSO. So, here, let's avoid considering those!
5283 // during comparison.
5284 la = r1->get_access_specifier();
5285 ra = r2->get_access_specifier();
5286 r1->set_access_specifier(no_access);
5287 r2->set_access_specifier(no_access);
5288 }
5289
5290 bool rels_are_different = *r1 != *r2;
5291
5292 if (member_types_or_functions)
5293 {
5294 // restore the access specifiers.
5295 r1->set_access_specifier(la);
5296 r2->set_access_specifier(ra);
5297 }
5298
5299 if (rels_are_different)
5300 {
5301 result = false;
5302 if (k)
5304 }
5305 }
5306 ABG_RETURN(result);
5307}
5308
5309/// Get the name of a decl for the purpose of comparing two decl
5310/// names.
5311///
5312/// This is a sub-routine of the 'equal' overload for decl_base.
5313///
5314/// This function takes into account the fact that all anonymous names
5315/// shall have the same name for the purpose of comparison.
5316///
5317/// For decls that are part of an anonymous scope, only the
5318/// non-qualified name should be taken into account.
5319static interned_string
5320get_decl_name_for_comparison(const decl_base &d)
5321{
5322 if (has_generic_anonymous_internal_type_name(&d)
5323 && d.get_is_anonymous())
5324 {
5325 // The decl is anonymous. It should have the same name as the
5326 // other anymous types of the same kind.
5327 string r;
5328 r += get_generic_anonymous_internal_type_name(&d);
5329 return d.get_environment().intern(r);
5330 }
5331
5334 || is_typedef(&d))
5335 ? d.get_name()
5336 : d.get_qualified_name(/*internal=*/true);
5337 return n;
5338}
5339
5340/// Compares two instances of @ref decl_base.
5341///
5342/// If the two intances are different, set a bitfield to give some
5343/// insight about the kind of differences there are.
5344///
5345/// @param l the first artifact of the comparison.
5346///
5347/// @param r the second artifact of the comparison.
5348///
5349/// @param k a pointer to a bitfield that gives information about the
5350/// kind of changes there are between @p l and @p r. This one is set
5351/// iff it's non-null and if the function returns false.
5352///
5353/// Please note that setting k to a non-null value does have a
5354/// negative performance impact because even if @p l and @p r are not
5355/// equal, the function keeps up the comparison in order to determine
5356/// the different kinds of ways in which they are different.
5357///
5358/// @return true if @p l equals @p r, false otherwise.
5359bool
5360equals(const decl_base& l, const decl_base& r, change_kind* k)
5361{
5362 bool result = true;
5363 const interned_string &l_linkage_name = l.get_linkage_name();
5364 const interned_string &r_linkage_name = r.get_linkage_name();
5365 if (!l_linkage_name.empty() && !r_linkage_name.empty())
5366 {
5367 if (l_linkage_name != r_linkage_name)
5368 {
5369 // Linkage names are different. That usually means the two
5370 // decls are different, unless we are looking at two
5371 // function declarations which have two different symbols
5372 // that are aliases of each other.
5373 const function_decl *f1 = is_function_decl(&l),
5374 *f2 = is_function_decl(&r);
5375 if (f1 && f2 && function_decls_alias(*f1, *f2))
5376 ;// The two functions are aliases, so they are not
5377 // different.
5378 else
5379 {
5380 result = false;
5381 if (k)
5383 else
5385 }
5386 }
5387 }
5388
5389 // This is the qualified name of the decls that we want to compare.
5390 // We want to use the "internal" version of the qualified name as
5391 // that one is stable even for anonymous decls.
5392 interned_string ln = get_decl_name_for_comparison(l);
5393 interned_string rn = get_decl_name_for_comparison(r);
5394
5395 /// If both of the current decls have an anonymous scope then let's
5396 /// compare their name component by component by properly handling
5397 /// anonymous scopes. That's the slow path.
5398 ///
5399 /// Otherwise, let's just compare their name, the obvious way.
5400 /// That's the fast path because in that case the names are
5401 /// interned_string and comparing them is much faster.
5402 bool decls_are_same = (ln == rn);
5403 if (!decls_are_same
5404 && l.get_is_anonymous()
5406 && r.get_is_anonymous()
5408 // Both decls are anonymous and their scope are *NOT* anonymous.
5409 // So we consider the decls to have equivalent names (both
5410 // anonymous, remember). We are still in the fast path here.
5411 decls_are_same = true;
5412
5413 if (!decls_are_same
5416 // This is the slow path as we are comparing the decl qualified
5417 // names component by component, properly handling anonymous
5418 // scopes.
5419 decls_are_same = tools_utils::decl_names_equal(ln, rn);
5420
5421 if (!decls_are_same)
5422 {
5423 result = false;
5424 if (k)
5426 else
5428 }
5429
5430 result &= maybe_compare_as_member_decls(l, r, k);
5431
5432 ABG_RETURN(result);
5433}
5434
5435/// Return true iff the two decls have the same name.
5436///
5437/// This function doesn't test if the scopes of the the two decls are
5438/// equal.
5439///
5440/// Note that this virtual function is to be implemented by classes
5441/// that extend the \p decl_base class.
5442bool
5444{return equals(*this, other, 0);}
5445
5446/// Inequality operator.
5447///
5448/// @param other to other instance of @ref decl_base to compare the
5449/// current instance to.
5450///
5451/// @return true iff the current instance of @ref decl_base is
5452/// different from @p other.
5453bool
5455{return !operator==(other);}
5456
5457/// Destructor of the @ref decl_base type.
5459{delete priv_;}
5460
5461/// This implements the ir_traversable_base::traverse pure virtual
5462/// function.
5463///
5464/// @param v the visitor used on the member nodes of the translation
5465/// unit during the traversal.
5466///
5467/// @return true if the entire IR node tree got traversed, false
5468/// otherwise.
5469bool
5471{
5472 // Do nothing in the base class.
5473 return true;
5474}
5475
5476/// Setter of the scope of the current decl.
5477///
5478/// Note that the decl won't hold a reference on the scope. It's
5479/// rather the scope that holds a reference on its members.
5480void
5482{
5483 if (!priv_->context_)
5484 priv_->context_ = new context_rel(scope);
5485 else
5486 priv_->context_->set_scope(scope);
5487}
5488
5489// </decl_base definition>
5490
5491/// Streaming operator for the decl_base::visibility.
5492///
5493/// @param o the output stream to serialize the visibility to.
5494///
5495/// @param v the visibility to serialize.
5496///
5497/// @return the output stream.
5498std::ostream&
5499operator<<(std::ostream& o, decl_base::visibility v)
5500{
5501 string r;
5502 switch (v)
5503 {
5504 case decl_base::VISIBILITY_NONE:
5505 r = "none";
5506 break;
5507 case decl_base::VISIBILITY_DEFAULT:
5508 r = "default";
5509 break;
5510 case decl_base::VISIBILITY_PROTECTED:
5511 r = "protected";
5512 break;
5513 case decl_base::VISIBILITY_HIDDEN:
5514 r = "hidden";
5515 break;
5516 case decl_base::VISIBILITY_INTERNAL:
5517 r = "internal";
5518 break;
5519 }
5520 return o;
5521}
5522
5523/// Streaming operator for decl_base::binding.
5524///
5525/// @param o the output stream to serialize the visibility to.
5526///
5527/// @param b the binding to serialize.
5528///
5529/// @return the output stream.
5530std::ostream&
5531operator<<(std::ostream& o, decl_base::binding b)
5532{
5533 string r;
5534 switch (b)
5535 {
5536 case decl_base::BINDING_NONE:
5537 r = "none";
5538 break;
5539 case decl_base::BINDING_LOCAL:
5540 r = "local";
5541 break;
5542 case decl_base::BINDING_GLOBAL:
5543 r = "global";
5544 break;
5545 case decl_base::BINDING_WEAK:
5546 r = "weak";
5547 break;
5548 }
5549 o << r;
5550 return o;
5551}
5552
5553/// Turn equality of shared_ptr of decl_base into a deep equality;
5554/// that is, make it compare the pointed to objects, not just the
5555/// pointers.
5556///
5557/// @param l the shared_ptr of decl_base on left-hand-side of the
5558/// equality.
5559///
5560/// @param r the shared_ptr of decl_base on right-hand-side of the
5561/// equality.
5562///
5563/// @return true if the decl_base pointed to by the shared_ptrs are
5564/// equal, false otherwise.
5565bool
5566operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5567{
5568 if (l.get() == r.get())
5569 return true;
5570 if (!!l != !!r)
5571 return false;
5572
5573 return *l == *r;
5574}
5575
5576/// Inequality operator of shared_ptr of @ref decl_base.
5577///
5578/// This is a deep equality operator, that is, it compares the
5579/// pointed-to objects, rather than just the pointers.
5580///
5581/// @param l the left-hand-side operand.
5582///
5583/// @param r the right-hand-side operand.
5584///
5585/// @return true iff @p l is different from @p r.
5586bool
5587operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5588{return !operator==(l, r);}
5589
5590/// Turn equality of shared_ptr of type_base into a deep equality;
5591/// that is, make it compare the pointed to objects too.
5592///
5593/// @param l the shared_ptr of type_base on left-hand-side of the
5594/// equality.
5595///
5596/// @param r the shared_ptr of type_base on right-hand-side of the
5597/// equality.
5598///
5599/// @return true if the type_base pointed to by the shared_ptrs are
5600/// equal, false otherwise.
5601bool
5602operator==(const type_base_sptr& l, const type_base_sptr& r)
5603{
5604 if (l.get() == r.get())
5605 return true;
5606 if (!!l != !!r)
5607 return false;
5608
5609 return *l == *r;
5610}
5611
5612/// Turn inequality of shared_ptr of type_base into a deep equality;
5613/// that is, make it compare the pointed to objects..
5614///
5615/// @param l the shared_ptr of type_base on left-hand-side of the
5616/// equality.
5617///
5618/// @param r the shared_ptr of type_base on right-hand-side of the
5619/// equality.
5620///
5621/// @return true iff the type_base pointed to by the shared_ptrs are
5622/// different.
5623bool
5624operator!=(const type_base_sptr& l, const type_base_sptr& r)
5625{return !operator==(l, r);}
5626
5627/// Tests if a declaration has got a scope.
5628///
5629/// @param d the declaration to consider.
5630///
5631/// @return true if the declaration has got a scope, false otherwise.
5632bool
5634{return (d.get_scope());}
5635
5636/// Tests if a declaration has got a scope.
5637///
5638/// @param d the declaration to consider.
5639///
5640/// @return true if the declaration has got a scope, false otherwise.
5641bool
5642has_scope(const decl_base_sptr d)
5643{return has_scope(*d.get());}
5644
5645/// Tests if a declaration is a class member.
5646///
5647/// @param d the declaration to consider.
5648///
5649/// @return true if @p d is a class member, false otherwise.
5650bool
5651is_member_decl(const decl_base_sptr d)
5652{return is_at_class_scope(d) || is_method_decl(d);}
5653
5654/// Tests if a declaration is a class member.
5655///
5656/// @param d the declaration to consider.
5657///
5658/// @return true if @p d is a class member, false otherwise.
5659bool
5661{return is_at_class_scope(d) || is_method_decl(d);}
5662
5663/// Tests if a declaration is a class member.
5664///
5665/// @param d the declaration to consider.
5666///
5667/// @return true if @p d is a class member, false otherwise.
5668bool
5670{return is_at_class_scope(d) || is_method_decl(d);}
5671
5672/// Test if a declaration is a @ref scope_decl.
5673///
5674/// @param d the declaration to take in account.
5675///
5676/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5677/// if d is a @ref scope_decl.
5680{return dynamic_cast<scope_decl*>(d);}
5681
5682/// Test if a declaration is a @ref scope_decl.
5683///
5684/// @param d the declaration to take in account.
5685///
5686/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5687/// if d is a @ref scope_decl.
5689is_scope_decl(const decl_base_sptr& d)
5690{return dynamic_pointer_cast<scope_decl>(d);}
5691
5692/// Tests if a type is a class member.
5693///
5694/// @param t the type to consider.
5695///
5696/// @return true if @p t is a class member type, false otherwise.
5697bool
5698is_member_type(const type_base_sptr& t)
5699{
5700 decl_base_sptr d = get_type_declaration(t);
5701 return is_member_decl(d);
5702}
5703
5704/// Test if a type is user-defined.
5705///
5706/// A type is considered user-defined if it's a
5707/// struct/class/union/enum that is *NOT* artificial.
5708///
5709/// @param t the type to consider.
5710///
5711/// @return true iff the type @p t is user-defined.
5712bool
5714{
5715 if (t == 0)
5716 return false;
5717
5719 decl_base *d = is_decl(t);
5720
5722 && d && !d->get_is_artificial())
5723 return true;
5724
5725 return false;
5726}
5727
5728/// Test if a type is user-defined.
5729///
5730/// A type is considered user-defined if it's a
5731/// struct/class/union/enum.
5732///
5733///
5734/// @param t the type to consider.
5735///
5736/// @return true iff the type @p t is user-defined.
5737bool
5738is_user_defined_type(const type_base_sptr& t)
5739{return is_user_defined_type(t.get());}
5740
5741/// Gets the access specifier for a class member.
5742///
5743/// @param d the declaration of the class member to consider. Note
5744/// that this must be a class member otherwise the function aborts the
5745/// current process.
5746///
5747/// @return the access specifier for the class member @p d.
5750{
5752
5753 const context_rel* c = d.get_context_rel();
5754 ABG_ASSERT(c);
5755
5756 return c->get_access_specifier();
5757}
5758
5759/// Gets the access specifier for a class member.
5760///
5761/// @param d the declaration of the class member to consider. Note
5762/// that this must be a class member otherwise the function aborts the
5763/// current process.
5764///
5765/// @return the access specifier for the class member @p d.
5767get_member_access_specifier(const decl_base_sptr& d)
5768{return get_member_access_specifier(*d);}
5769
5770/// Sets the access specifier for a class member.
5771///
5772/// @param d the class member to set the access specifier for. Note
5773/// that this must be a class member otherwise the function aborts the
5774/// current process.
5775///
5776/// @param a the new access specifier to set the class member to.
5777void
5780{
5782
5784 ABG_ASSERT(c);
5785
5786 c->set_access_specifier(a);
5787}
5788
5789/// Sets the access specifier for a class member.
5790///
5791/// @param d the class member to set the access specifier for. Note
5792/// that this must be a class member otherwise the function aborts the
5793/// current process.
5794///
5795/// @param a the new access specifier to set the class member to.
5796void
5797set_member_access_specifier(const decl_base_sptr& d,
5800
5801/// Gets a flag saying if a class member is static or not.
5802///
5803/// @param d the declaration for the class member to consider. Note
5804/// that this must be a class member otherwise the function aborts the
5805/// current process.
5806///
5807/// @return true if the class member @p d is static, false otherwise.
5808bool
5810{
5812
5813 const context_rel* c = d.get_context_rel();
5814 ABG_ASSERT(c);
5815
5816 return c->get_is_static();
5817}
5818
5819/// Gets a flag saying if a class member is static or not.
5820///
5821/// @param d the declaration for the class member to consider. Note
5822/// that this must be a class member otherwise the function aborts the
5823/// current process.
5824///
5825/// @return true if the class member @p d is static, false otherwise.
5826bool
5828{return get_member_is_static(*d);}
5829
5830/// Gets a flag saying if a class member is static or not.
5831///
5832/// @param d the declaration for the class member to consider. Note
5833/// that this must be a class member otherwise the function aborts the
5834/// current process.
5835///
5836/// @return true if the class member @p d is static, false otherwise.
5837bool
5838get_member_is_static(const decl_base_sptr& d)
5839{return get_member_is_static(*d);}
5840
5841/// Test if a var_decl is a data member.
5842///
5843/// @param v the var_decl to consider.
5844///
5845/// @return true if @p v is data member, false otherwise.
5846bool
5848{return is_at_class_scope(v);}
5849
5850/// Test if a var_decl is a data member.
5851///
5852/// @param v the var_decl to consider.
5853///
5854/// @return true if @p v is data member, false otherwise.
5855bool
5857{return is_data_member(*v);}
5858
5859/// Test if a var_decl is a data member.
5860///
5861/// @param v the var_decl to consider.
5862///
5863/// @return true if @p v is data member, false otherwise.
5864bool
5866{return is_at_class_scope(d);}
5867
5868/// Test if a decl is a data member.
5869///
5870/// @param d the decl to consider.
5871///
5872/// @return a pointer to the data member iff @p d is a data member, or
5873/// a null pointer.
5875is_data_member(const decl_base_sptr& d)
5876{
5877 if (var_decl_sptr v = is_var_decl(d))
5878 {
5879 if (is_data_member(v))
5880 return v;
5881 }
5882 return var_decl_sptr();
5883}
5884
5885/// Test if a decl is a data member.
5886///
5887/// @param d the decl to consider.
5888///
5889/// @return a pointer to the data member iff @p d is a data member, or
5890/// a null pointer.
5893{
5894 if (var_decl_sptr v = is_var_decl(d))
5895 {
5896 if (is_data_member(v))
5897 return v;
5898 }
5899 return var_decl_sptr();
5900}
5901
5902/// Test if a decl is a data member.
5903///
5904/// @param d the decl to consider.
5905///
5906/// @return a pointer to the data member iff @p d is a data member, or
5907/// a null pointer.
5908var_decl*
5910{
5911 if (var_decl *v = is_var_decl(d))
5912 if (is_data_member(v))
5913 return v;
5914 return 0;
5915}
5916
5917/// Test if a decl is a data member.
5918///
5919/// @param d the decl to consider.
5920///
5921/// @return a pointer to the data member iff @p d is a data member, or
5922/// a null pointer.
5923var_decl*
5925{
5926 if (var_decl *v = is_var_decl(d))
5927 if (is_data_member(v))
5928 return v;
5929 return 0;
5930}
5931
5932/// Get the first non-anonymous data member of a given anonymous data
5933/// member.
5934///
5935/// E.g:
5936///
5937/// struct S
5938/// {
5939/// union // <-- for this anonymous data member, the function
5940/// // returns a.
5941/// {
5942/// int a;
5943/// charb;
5944/// };
5945/// };
5946///
5947/// @return anon_dm the anonymous data member to consider.
5948///
5949/// @return the first non-anonymous data member of @p anon_dm. If no
5950/// data member was found then this function returns @p anon_dm.
5951const var_decl_sptr
5953{
5954 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5955 return anon_dm;
5956
5957 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5958 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5959
5960 if (is_anonymous_data_member(first))
5962
5963 return first;
5964}
5965
5966/// In the context of a given class or union, this function returns
5967/// the data member that is located after a given data member.
5968///
5969/// @param klass the class or union to consider.
5970///
5971/// @param the data member to consider.
5972///
5973/// @return the data member that is located right after @p
5974/// data_member.
5975const var_decl_sptr
5977 const var_decl_sptr &data_member)
5978{
5979 if (!klass ||!data_member)
5980 return var_decl_sptr();
5981
5982 for (class_or_union::data_members::const_iterator it =
5983 klass->get_non_static_data_members().begin();
5984 it != klass->get_non_static_data_members().end();
5985 ++it)
5986 if (**it == *data_member)
5987 {
5988 ++it;
5989 if (it != klass->get_non_static_data_members().end())
5991 break;
5992 }
5993
5994 return var_decl_sptr();
5995}
5996
5997/// In the context of a given class or union, this function returns
5998/// the data member that is located after a given data member.
5999///
6000/// @param klass the class or union to consider.
6001///
6002/// @param the data member to consider.
6003///
6004/// @return the data member that is located right after @p
6005/// data_member.
6006const var_decl_sptr
6007get_next_data_member(const class_or_union_sptr& klass,
6008 const var_decl_sptr &data_member)
6009{return get_next_data_member(klass.get(), data_member);}
6010
6011/// Get the last data member of a class type.
6012///
6013/// @param klass the class type to consider.
6016{return klass.get_non_static_data_members().back();}
6017
6018/// Get the last data member of a class type.
6019///
6020/// @param klass the class type to consider.
6023{return get_last_data_member(*klass);}
6024
6025/// Get the last data member of a class type.
6026///
6027/// @param klass the class type to consider.
6029get_last_data_member(const class_or_union_sptr &klass)
6030{return get_last_data_member(klass.get());}
6031
6032/// Test if a decl is an anonymous data member.
6033///
6034/// @param d the decl to consider.
6035///
6036/// @return true iff @p d is an anonymous data member.
6037bool
6039{return is_anonymous_data_member(&d);}
6040
6041/// Test if a decl is an anonymous data member.
6042///
6043/// @param d the decl to consider.
6044///
6045/// @return the var_decl representing the data member iff @p d is an
6046/// anonymous data member.
6047const var_decl*
6049{
6050 if (const var_decl* v = is_data_member(d))
6051 {
6053 return v;
6054 }
6055 return 0;
6056}
6057
6058/// Test if a decl is an anonymous data member.
6059///
6060/// @param d the decl to consider.
6061///
6062/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6063/// it's an anonymous data member. Otherwise returns a nil pointer.
6064const var_decl*
6066{
6067 if (const var_decl* v = is_data_member(d))
6068 {
6070 return v;
6071 }
6072 return 0;
6073}
6074
6075/// Test if a decl is an anonymous data member.
6076///
6077/// @param d the decl to consider.
6078///
6079/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6080/// it's an anonymous data member. Otherwise returns a nil pointer.
6083{
6084 if (var_decl_sptr v = is_data_member(d))
6085 {
6087 return v;
6088 }
6089 return var_decl_sptr();
6090}
6091
6092/// Test if a decl is an anonymous data member.
6093///
6094/// @param d the decl to consider.
6095///
6096/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6097/// it's an anonymous data member. Otherwise returns a nil pointer.
6099is_anonymous_data_member(const decl_base_sptr& d)
6100{
6101 if (var_decl_sptr v = is_data_member(d))
6102 return is_anonymous_data_member(v);
6103 return var_decl_sptr();
6104}
6105
6106/// Test if a @ref var_decl is an anonymous data member.
6107///
6108/// @param d the @ref var_decl to consider.
6109///
6110/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6111/// it's an anonymous data member. Otherwise returns a nil pointer.
6114{
6115 if (is_anonymous_data_member(d.get()))
6116 return d;
6117 return var_decl_sptr();
6118}
6119
6120/// Test if a @ref var_decl is an anonymous data member.
6121///
6122/// @param d the @ref var_decl to consider.
6123///
6124/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6125/// it's an anonymous data member. Otherwise returns a nil pointer.
6126const var_decl*
6128{
6129 if (d && is_anonymous_data_member(*d))
6130 return d;
6131 return 0;
6132}
6133
6134/// Test if a @ref var_decl is an anonymous data member.
6135///
6136/// @param d the @ref var_decl to consider.
6137///
6138/// @return true iff @p d is an anonymous data member.
6139bool
6141{
6142 return (is_data_member(d)
6143 && d.get_is_anonymous()
6144 && d.get_name().empty()
6146}
6147
6148/// Test if a @ref var_decl is a data member belonging to an anonymous
6149/// type.
6150///
6151/// @param d the @ref var_decl to consider.
6152///
6153/// @return true iff @p d is a data member belonging to an anonymous
6154/// type.
6155bool
6157{
6158 if (is_data_member(d))
6159 {
6160 scope_decl* scope = d.get_scope();
6161 if (scope && scope->get_is_anonymous())
6162 return true;
6163 }
6164 return false;
6165}
6166
6167/// Test if a @ref var_decl is a data member belonging to an anonymous
6168/// type.
6169///
6170/// @param d the @ref var_decl to consider.
6171///
6172/// @return true iff @p d is a data member belonging to an anonymous
6173/// type.
6174bool
6177
6178/// Test if a @ref var_decl is a data member belonging to an anonymous
6179/// type.
6180///
6181/// @param d the @ref var_decl to consider.
6182///
6183/// @return true iff @p d is a data member belonging to an anonymous
6184/// type.
6185bool
6188
6189/// Get the @ref class_or_union type of a given anonymous data member.
6190///
6191/// @param d the anonymous data member to consider.
6192///
6193/// @return the @ref class_or_union type of the anonymous data member
6194/// @p d.
6197{
6198 if ((d = is_anonymous_data_member(d)))
6199 return is_class_or_union_type(d->get_type().get());
6200 return 0;
6201}
6202
6203/// Get the @ref class_or_union type of a given anonymous data member.
6204///
6205/// @param d the anonymous data member to consider.
6206///
6207/// @return the @ref class_or_union type of the anonymous data member
6208/// @p d.
6209class_or_union_sptr
6211{
6213 return is_class_or_union_type(d.get_type());
6214 return class_or_union_sptr();
6215}
6216
6217/// Test if a data member has annonymous type or not.
6218///
6219/// @param d the data member to consider.
6220///
6221/// @return the anonymous class or union type iff @p turns out to have
6222/// an anonymous type. Otherwise, returns nil.
6223const class_or_union_sptr
6225{
6226 if (is_data_member(d))
6227 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
6228 if (cou->get_is_anonymous())
6229 return cou;
6230
6231 return class_or_union_sptr();
6232}
6233
6234/// Test if a data member has annonymous type or not.
6235///
6236/// @param d the data member to consider.
6237///
6238/// @return the anonymous class or union type iff @p turns out to have
6239/// an anonymous type. Otherwise, returns nil.
6240const class_or_union_sptr
6242{
6243 if (d)
6245 return class_or_union_sptr();
6246}
6247
6248/// Test if a data member has annonymous type or not.
6249///
6250/// @param d the data member to consider.
6251///
6252/// @return the anonymous class or union type iff @p turns out to have
6253/// an anonymous type. Otherwise, returns nil.
6254const class_or_union_sptr
6256{return data_member_has_anonymous_type(d.get());}
6257
6258/// Get the @ref class_or_union type of a given anonymous data member.
6259///
6260/// @param d the anonymous data member to consider.
6261///
6262/// @return the @ref class_or_union type of the anonymous data member
6263/// @p d.
6264class_or_union_sptr
6266{
6268 return is_class_or_union_type(v->get_type());
6269 return class_or_union_sptr();
6270}
6271
6272/// Test if a given anonymous data member exists in a class or union.
6273///
6274/// @param anon_dm the anonymous data member to consider.
6275///
6276/// @param clazz the class to consider.
6277///
6278/// @return true iff @p anon_dm exists in the @clazz.
6279bool
6281 const class_or_union& clazz)
6282{
6283 if (!anon_dm.get_is_anonymous()
6284 || !is_class_or_union_type(anon_dm.get_type()))
6285 return false;
6286
6287 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
6288 ABG_ASSERT(cl);
6289
6290 // Look for the presence of each data member of anon_dm in clazz.
6291 //
6292 // If one data member of anon_dm is not present in clazz, then the
6293 // data member anon_dm is considered to not exist in clazz.
6294 for (auto anon_dm_m : cl->get_non_static_data_members())
6295 {
6296 // If the data member anon_dm_m is not an anonymous data member,
6297 // it's easy to look for it.
6298 if (!is_anonymous_data_member(anon_dm_m))
6299 {
6300 if (!clazz.find_data_member(anon_dm_m->get_name()))
6301 return false;
6302 }
6303 // If anon_dm_m is itself an anonymous data member then recurse
6304 else
6305 {
6306 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
6307 return false;
6308 }
6309 }
6310
6311 return true;
6312}
6313
6314/// Test if a given decl is anonymous or has a naming typedef.
6315///
6316/// @param d the decl to consider.
6317///
6318/// @return true iff @p d is anonymous or has a naming typedef.
6319bool
6321{
6322 if (d.get_is_anonymous() || d.get_naming_typedef())
6323 return true;
6324 return false;
6325}
6326
6327/// Set the offset of a data member into its containing class.
6328///
6329/// @param m the data member to consider.
6330///
6331/// @param o the offset, in bits.
6332void
6334{
6336
6337 dm_context_rel* ctxt_rel =
6338 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6339 ABG_ASSERT(ctxt_rel);
6340
6341 ctxt_rel->set_offset_in_bits(o);
6342}
6343
6344/// Get the offset of a data member.
6345///
6346/// @param m the data member to consider.
6347///
6348/// @return the offset (in bits) of @p m in its containing class.
6349uint64_t
6351{
6353 const dm_context_rel* ctxt_rel =
6354 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6355 ABG_ASSERT(ctxt_rel);
6356 return ctxt_rel->get_offset_in_bits();
6357}
6358
6359/// Get the offset of a data member.
6360///
6361/// @param m the data member to consider.
6362///
6363/// @return the offset (in bits) of @p m in its containing class.
6364uint64_t
6366{return get_data_member_offset(*m);}
6367
6368/// Get the offset of a data member.
6369///
6370/// @param m the data member to consider.
6371///
6372/// @return the offset (in bits) of @p m in its containing class.
6373uint64_t
6374get_data_member_offset(const decl_base_sptr d)
6375{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6376
6377/// Get the offset of the non-static data member that comes after a
6378/// given one.
6379///
6380/// If there is no data member after after the one given to this
6381/// function (maybe because the given one is the last data member of
6382/// the class type) then the function return false.
6383///
6384/// @param klass the class to consider.
6385///
6386/// @param dm the data member before the one we want to retrieve.
6387///
6388/// @param offset out parameter. This parameter is set by the
6389/// function to the offset of the data member that comes right after
6390/// the data member @p dm, iff the function returns true.
6391///
6392/// @return true iff the data member coming right after @p dm was
6393/// found.
6394bool
6396 const var_decl_sptr& dm,
6397 uint64_t& offset)
6398{
6399 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6400 if (!next_dm)
6401 return false;
6402 offset = get_data_member_offset(next_dm);
6403 return true;
6404}
6405
6406/// Get the offset of the non-static data member that comes after a
6407/// given one.
6408///
6409/// If there is no data member after after the one given to this
6410/// function (maybe because the given one is the last data member of
6411/// the class type) then the function return false.
6412///
6413/// @param klass the class to consider.
6414///
6415/// @param dm the data member before the one we want to retrieve.
6416///
6417/// @param offset out parameter. This parameter is set by the
6418/// function to the offset of the data member that comes right after
6419/// the data member @p dm, iff the function returns true.
6420///
6421/// @return true iff the data member coming right after @p dm was
6422/// found.
6423bool
6424get_next_data_member_offset(const class_or_union_sptr& klass,
6425 const var_decl_sptr& dm,
6426 uint64_t& offset)
6427{return get_next_data_member_offset(klass.get(), dm, offset);}
6428
6429/// Get the absolute offset of a data member.
6430///
6431/// If the data member is part of an anonymous data member then this
6432/// returns the absolute offset -- relative to the beginning of the
6433/// containing class of the anonymous data member.
6434///
6435/// @param m the data member to consider.
6436///
6437/// @return the aboslute offset of the data member @p m.
6438uint64_t
6440{
6442 const dm_context_rel* ctxt_rel =
6443 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6444 ABG_ASSERT(ctxt_rel);
6445
6446 const var_decl *containing_anonymous_data_member =
6447 ctxt_rel->get_anonymous_data_member();
6448
6449 uint64_t containing_anonymous_data_member_offset = 0;
6450 if (containing_anonymous_data_member)
6451 containing_anonymous_data_member_offset =
6452 get_absolute_data_member_offset(*containing_anonymous_data_member);
6453
6454 return (ctxt_rel->get_offset_in_bits()
6455 +
6456 containing_anonymous_data_member_offset);
6457}
6458
6459/// Get the absolute offset of a data member.
6460///
6461/// If the data member is part of an anonymous data member then this
6462/// returns the absolute offset -- relative to the beginning of the
6463/// containing class of the anonymous data member.
6464///
6465/// @param m the data member to consider.
6466///
6467/// @return the aboslute offset of the data member @p m.
6468uint64_t
6470{
6471 if (!m)
6472 return 0;
6474}
6475
6476/// Get the size of a given variable.
6477///
6478/// @param v the variable to consider.
6479///
6480/// @return the size of variable @p v.
6481uint64_t
6483{
6484 type_base_sptr t = v->get_type();
6485 ABG_ASSERT(t);
6486
6487 return t->get_size_in_bits();
6488}
6489
6490/// Set a flag saying if a data member is laid out.
6491///
6492/// @param m the data member to consider.
6493///
6494/// @param l true if @p m is to be considered as laid out.
6495void
6497{
6499 dm_context_rel* ctxt_rel =
6500 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6501 ctxt_rel->set_is_laid_out(l);
6502}
6503
6504/// Test whether a data member is laid out.
6505///
6506/// @param m the data member to consider.
6507///
6508/// @return true if @p m is laid out, false otherwise.
6509bool
6511{
6513 const dm_context_rel* ctxt_rel =
6514 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6515
6516 return ctxt_rel->get_is_laid_out();
6517}
6518
6519/// Test whether a data member is laid out.
6520///
6521/// @param m the data member to consider.
6522///
6523/// @return true if @p m is laid out, false otherwise.
6524bool
6526{return get_data_member_is_laid_out(*m);}
6527
6528/// Test whether a function_decl is a member function.
6529///
6530/// @param f the function_decl to test.
6531///
6532/// @return true if @p f is a member function, false otherwise.
6533bool
6535{return is_member_decl(f);}
6536
6537/// Test whether a function_decl is a member function.
6538///
6539/// @param f the function_decl to test.
6540///
6541/// @return true if @p f is a member function, false otherwise.
6542bool
6544{return is_member_decl(*f);}
6545
6546/// Test whether a function_decl is a member function.
6547///
6548/// @param f the function_decl to test.
6549///
6550/// @return true if @p f is a member function, false otherwise.
6551bool
6553{return is_member_decl(*f);}
6554
6555/// Test whether a member function is a constructor.
6556///
6557/// @param f the member function to test.
6558///
6559/// @return true if @p f is a constructor, false otherwise.
6560bool
6562{
6564
6565 const method_decl* m = is_method_decl(&f);
6566 ABG_ASSERT(m);
6567
6568 const mem_fn_context_rel* ctxt =
6569 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6570
6571 return ctxt->is_constructor();
6572}
6573
6574/// Test whether a member function is a constructor.
6575///
6576/// @param f the member function to test.
6577///
6578/// @return true if @p f is a constructor, false otherwise.
6579bool
6581{return get_member_function_is_ctor(*f);}
6582
6583
6584/// Setter for the is_ctor property of the member function.
6585///
6586/// @param f the member function to set.
6587///
6588/// @param f the new boolean value of the is_ctor property. Is true
6589/// if @p f is a constructor, false otherwise.
6590void
6592{
6594
6595 method_decl* m = is_method_decl(&f);
6596 ABG_ASSERT(m);
6597
6598 mem_fn_context_rel* ctxt =
6599 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6600
6601 ctxt->is_constructor(c);
6602}
6603
6604/// Setter for the is_ctor property of the member function.
6605///
6606/// @param f the member function to set.
6607///
6608/// @param f the new boolean value of the is_ctor property. Is true
6609/// if @p f is a constructor, false otherwise.
6610void
6613
6614/// Test whether a member function is a destructor.
6615///
6616/// @param f the function to test.
6617///
6618/// @return true if @p f is a destructor, false otherwise.
6619bool
6621{
6623
6624 const method_decl* m = is_method_decl(&f);
6625 ABG_ASSERT(m);
6626
6627 const mem_fn_context_rel* ctxt =
6628 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6629
6630 return ctxt->is_destructor();
6631}
6632
6633/// Test whether a member function is a destructor.
6634///
6635/// @param f the function to test.
6636///
6637/// @return true if @p f is a destructor, false otherwise.
6638bool
6640{return get_member_function_is_dtor(*f);}
6641
6642/// Set the destructor-ness property of a member function.
6643///
6644/// @param f the function to set.
6645///
6646/// @param d true if @p f is a destructor, false otherwise.
6647void
6649{
6651
6652 method_decl* m = is_method_decl(&f);
6653 ABG_ASSERT(m);
6654
6655 mem_fn_context_rel* ctxt =
6656 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6657
6658 ctxt->is_destructor(d);
6659}
6660
6661/// Set the destructor-ness property of a member function.
6662///
6663/// @param f the function to set.
6664///
6665/// @param d true if @p f is a destructor, false otherwise.
6666void
6669
6670/// Test whether a member function is const.
6671///
6672/// @param f the function to test.
6673///
6674/// @return true if @p f is const, false otherwise.
6675bool
6677{
6679
6680 const method_decl* m = is_method_decl(&f);
6681 ABG_ASSERT(m);
6682
6683 const mem_fn_context_rel* ctxt =
6684 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6685
6686 return ctxt->is_const();
6687}
6688
6689/// Test whether a member function is const.
6690///
6691/// @param f the function to test.
6692///
6693/// @return true if @p f is const, false otherwise.
6694bool
6696{return get_member_function_is_const(*f);}
6697
6698/// set the const-ness property of a member function.
6699///
6700/// @param f the function to set.
6701///
6702/// @param is_const the new value of the const-ness property of @p f
6703void
6705{
6707
6708 method_decl* m = is_method_decl(&f);
6709 ABG_ASSERT(m);
6710
6711 mem_fn_context_rel* ctxt =
6712 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6713
6714 ctxt->is_const(is_const);
6715}
6716
6717/// set the const-ness property of a member function.
6718///
6719/// @param f the function to set.
6720///
6721/// @param is_const the new value of the const-ness property of @p f
6722void
6724{set_member_function_is_const(*f, is_const);}
6725
6726/// Test if a virtual member function has a vtable offset set.
6727///
6728/// @param f the virtual member function to consider.
6729///
6730/// @return true iff the virtual member function has its vtable offset
6731/// set, i.e, if the vtable offset of @p is different from -1.
6732bool
6734{return get_member_function_vtable_offset(f) != -1;}
6735
6736/// Get the vtable offset of a member function.
6737///
6738/// @param f the member function to consider.
6739///
6740/// @return the vtable offset of @p f. Note that a vtable offset of
6741/// value -1 means that the member function does *NOT* yet have a
6742/// vtable offset associated to it.
6743ssize_t
6745{
6747
6748 const method_decl* m =
6749 dynamic_cast<const method_decl*>(&f);
6750 ABG_ASSERT(m);
6751
6752 const mem_fn_context_rel* ctxt =
6753 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6754
6755 return ctxt->vtable_offset();
6756}
6757
6758/// Get the vtable offset of a member function.
6759///
6760/// @param f the member function to consider.
6761///
6762/// @return the vtable offset of @p f. Note that a vtable offset of
6763/// value -1 means that the member function does *NOT* yet have a
6764/// vtable offset associated to it.
6765ssize_t
6768
6769/// Set the vtable offset of a member function.
6770///
6771/// @param f the member function to consider.
6772///
6773/// @param s the new vtable offset. Please note that a vtable offset
6774/// of value -1 means that the virtual member function does not (yet)
6775/// have any vtable offset associated to it.
6776void
6778{
6780
6781 method_decl* m = is_method_decl(&f);
6782 ABG_ASSERT(m);
6783
6784 mem_fn_context_rel* ctxt =
6785 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6786
6787 ctxt->vtable_offset(s);
6788}
6789
6790/// Get the vtable offset of a member function.
6791///
6792/// @param f the member function to consider.
6793///
6794/// @param s the new vtable offset. Please note that a vtable offset
6795/// of value -1 means that the virtual member function does not (yet)
6796/// have any vtable offset associated to it.
6797void
6799{return set_member_function_vtable_offset(*f, s);}
6800
6801/// Test if a given member function is virtual.
6802///
6803/// @param mem_fn the member function to consider.
6804///
6805/// @return true iff a @p mem_fn is virtual.
6806bool
6808{
6810
6811 const method_decl* m =
6812 dynamic_cast<const method_decl*>(&f);
6813 ABG_ASSERT(m);
6814
6815 const mem_fn_context_rel* ctxt =
6816 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6817
6818 return ctxt->is_virtual();
6819}
6820
6821/// Test if a given member function is virtual.
6822///
6823/// @param mem_fn the member function to consider.
6824///
6825/// @return true iff a @p mem_fn is virtual.
6826bool
6828{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6829
6830/// Test if a given member function is virtual.
6831///
6832/// @param mem_fn the member function to consider.
6833///
6834/// @return true iff a @p mem_fn is virtual.
6835bool
6837{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6838
6839/// Set the virtual-ness of a member function.
6840///
6841/// @param f the member function to consider.
6842///
6843/// @param is_virtual set to true if the function is virtual.
6844void
6846{
6848
6849 method_decl* m = is_method_decl(&f);
6850 ABG_ASSERT(m);
6851
6852 mem_fn_context_rel* ctxt =
6853 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6854
6855 ctxt->is_virtual(is_virtual);
6856}
6857
6858/// Set the virtual-ness of a member function.
6859///
6860/// @param f the member function to consider.
6861///
6862/// @param is_virtual set to true if the function is virtual.
6863void
6865{
6866 if (fn)
6867 {
6868 set_member_function_is_virtual(*fn, is_virtual);
6870 (dynamic_pointer_cast<method_decl>(fn));
6871 }
6872}
6873
6874/// Recursively returns the the underlying type of a typedef. The
6875/// return type should not be a typedef of anything anymore.
6876///
6877///
6878/// Also recursively strip typedefs from the sub-types of the type
6879/// given in arguments.
6880///
6881/// Note that this function builds types in which typedefs are
6882/// stripped off. Usually, types are held by their scope, so their
6883/// life time is bound to the life time of their scope. But as this
6884/// function cannot really insert the built type into it's scope, it
6885/// must ensure that the newly built type stays live long enough.
6886///
6887/// So, if the newly built type has a canonical type, this function
6888/// returns the canonical type. Otherwise, this function ensure that
6889/// the newly built type has a life time that is the same as the life
6890/// time of the entire libabigail library.
6891///
6892/// @param type the type to strip the typedefs from.
6893///
6894/// @return the resulting type stripped from its typedefs, or just
6895/// return @p type if it has no typedef in any of its sub-types.
6896type_base_sptr
6897strip_typedef(const type_base_sptr type)
6898{
6899 if (!type)
6900 return type;
6901
6902 // If type is a class type then do not try to strip typedefs from it.
6903 // And if it has no canonical type (which can mean that it's a
6904 // declaration-only class), then, make sure its live for ever and
6905 // return it.
6906 if (class_decl_sptr cl = is_class_type(type))
6907 {
6908 if (!cl->get_canonical_type())
6909 keep_type_alive(type);
6910 return type;
6911 }
6912
6913 const environment& env = type->get_environment();
6914 type_base_sptr t = type;
6915
6916 if (const typedef_decl_sptr ty = is_typedef(t))
6917 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6918 else if (const reference_type_def_sptr ty = is_reference_type(t))
6919 {
6920 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6921 env));
6922 ABG_ASSERT(p);
6923 t.reset(new reference_type_def(p,
6924 ty->is_lvalue(),
6925 ty->get_size_in_bits(),
6926 ty->get_alignment_in_bits(),
6927 ty->get_location()));
6928 }
6929 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6930 {
6931 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6932 env));
6933 ABG_ASSERT(p);
6934 t.reset(new pointer_type_def(p,
6935 ty->get_size_in_bits(),
6936 ty->get_alignment_in_bits(),
6937 ty->get_location()));
6938 }
6939 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6940 {
6941 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6942 env));
6943 ABG_ASSERT(p);
6944 t.reset(new qualified_type_def(p,
6945 ty->get_cv_quals(),
6946 ty->get_location()));
6947 }
6948 else if (const array_type_def_sptr ty = is_array_type(t))
6949 {
6950 type_base_sptr p = strip_typedef(ty->get_element_type());
6951 ABG_ASSERT(p);
6952 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6953 }
6954 else if (const method_type_sptr ty = is_method_type(t))
6955 {
6957 for (function_decl::parameters::const_iterator i =
6958 ty->get_parameters().begin();
6959 i != ty->get_parameters().end();
6960 ++i)
6961 {
6963 type_base_sptr typ = strip_typedef(p->get_type());
6964 ABG_ASSERT(typ);
6966 (new function_decl::parameter(typ,
6967 p->get_index(),
6968 p->get_name(),
6969 p->get_location(),
6970 p->get_variadic_marker(),
6971 p->get_is_artificial()));
6972 parm.push_back(stripped);
6973 }
6974 type_base_sptr p = strip_typedef(ty->get_return_type());
6975 ABG_ASSERT(!!p == !!ty->get_return_type());
6976 t.reset(new method_type(p, ty->get_class_type(),
6977 parm, ty->get_is_const(),
6978 ty->get_size_in_bits(),
6979 ty->get_alignment_in_bits()));
6980 }
6981 else if (const function_type_sptr ty = is_function_type(t))
6982 {
6984 for (function_decl::parameters::const_iterator i =
6985 ty->get_parameters().begin();
6986 i != ty->get_parameters().end();
6987 ++i)
6988 {
6990 type_base_sptr typ = strip_typedef(p->get_type());
6991 ABG_ASSERT(typ);
6993 (new function_decl::parameter(typ,
6994 p->get_index(),
6995 p->get_name(),
6996 p->get_location(),
6997 p->get_variadic_marker(),
6998 p->get_is_artificial()));
6999 parm.push_back(stripped);
7000 }
7001 type_base_sptr p = strip_typedef(ty->get_return_type());
7002 ABG_ASSERT(!!p == !!ty->get_return_type());
7003 t.reset(new function_type(p, parm,
7004 ty->get_size_in_bits(),
7005 ty->get_alignment_in_bits()));
7006 }
7007
7008 if (!t->get_translation_unit())
7009 t->set_translation_unit(type->get_translation_unit());
7010
7011 if (!(type->get_canonical_type() && canonicalize(t)))
7012 keep_type_alive(t);
7013
7014 return t->get_canonical_type() ? t->get_canonical_type() : t;
7015}
7016
7017/// Strip qualification from a qualified type, when it makes sense.
7018///
7019/// DWARF constructs "const reference". This is redundant because a
7020/// reference is always const. It also constructs the useless "const
7021/// void" type. The issue is these redundant types then leak into the
7022/// IR and make for bad diagnostics.
7023///
7024/// This function thus strips the const qualifier from the type in
7025/// that case. It might contain code to strip other cases like this
7026/// in the future.
7027///
7028/// @param t the type to strip const qualification from.
7029///
7030/// @return the stripped type or just return @p t.
7031decl_base_sptr
7032strip_useless_const_qualification(const qualified_type_def_sptr t)
7033{
7034 if (!t)
7035 return t;
7036
7037 decl_base_sptr result = t;
7038 type_base_sptr u = t->get_underlying_type();
7039 const environment& env = t->get_environment();
7040
7041 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
7042 && (is_reference_type(u)))
7043 || (t->get_cv_quals() & qualified_type_def::CV_CONST
7044 && env.is_void_type(u))
7045 || t->get_cv_quals() == qualified_type_def::CV_NONE)
7046 // Let's strip the const qualifier because a reference is always
7047 // 'const' and a const void doesn't make sense. They will just
7048 // lead to spurious changes later down the pipeline, that we'll
7049 // have to deal with by doing painful and error-prone editing of
7050 // the diff IR. Dropping that useless and inconsistent artefact
7051 // right here seems to be a good way to go.
7052 result = is_decl(u);
7053
7054 return result;
7055}
7056
7057/// Merge redundant qualifiers from a tree of qualified types.
7058///
7059/// Suppose a tree of qualified types leads to:
7060///
7061/// const virtual const restrict const int;
7062///
7063/// Suppose the IR tree of qualified types ressembles (with C meaning
7064/// const, V meaning virtual and R meaning restrict):
7065///
7066/// [C|V]-->[C|R] -->[C] --> [int].
7067///
7068/// This function walks the IR and remove the redundant CV qualifiers
7069/// so the IR becomes:
7070///
7071/// [C|V] --> [R] --> [] -->[int].
7072///
7073/// Note that the empty qualified type (noted []) represents a
7074/// qualified type with no qualifier. It's rare, but it can exist.
7075/// I've put it here just for the sake of example.
7076///
7077/// The resulting IR thus represents the (merged) type:
7078///
7079/// const virtual restrict int.
7080///
7081/// This function is a sub-routine of the overload @ref
7082/// strip_useless_const_qualification which doesn't return any value.
7083///
7084/// @param t the qualified type to consider.
7085///
7086/// @param redundant_quals the (redundant) qualifiers to be removed
7087/// from the qualifiers of the underlying types of @p t.
7088///
7089/// @return the underlying type of @p t which might have had its
7090/// redundant qualifiers removed.
7091static qualified_type_def_sptr
7092strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
7093 qualified_type_def::CV redundant_quals)
7094{
7095 if (!t)
7096 return t;
7097
7098 // We must NOT edit canonicalized types.
7099 ABG_ASSERT(!t->get_canonical_type());
7100
7101 qualified_type_def_sptr underlying_qualified_type =
7102 is_qualified_type(t->get_underlying_type());
7103
7104 // Let's build 'currated qualifiers' that are the qualifiers of the
7105 // current type from which redundant qualifiers are removed.
7106 qualified_type_def::CV currated_quals = t->get_cv_quals();
7107
7108 // Remove the redundant qualifiers from these currated qualifiers
7109 currated_quals &= ~redundant_quals;
7110 t->set_cv_quals(currated_quals);
7111
7112 // The redundant qualifiers, moving forward, is now the union of the
7113 // previous set of redundant qualifiers and the currated qualifiers.
7114 redundant_quals |= currated_quals;
7115
7116 qualified_type_def_sptr result = t;
7117 if (underlying_qualified_type)
7118 // Now remove the redundant qualifiers from the qualified types
7119 // potentially carried by the underlying type.
7120 result =
7121 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
7122 redundant_quals);
7123
7124 return result;
7125}
7126
7127/// Merge redundant qualifiers from a tree of qualified types.
7128///
7129/// Suppose a tree of qualified types leads to:
7130///
7131/// const virtual const restrict const int;
7132///
7133/// Suppose the IR tree of qualified types ressembles (with C meaning
7134/// const, V meaning virtual and R meaning restrict):
7135///
7136/// [C|V]-->[C|R] -->[C] --> [int].
7137///
7138/// This function walks the IR and remove the redundant CV qualifiers
7139/// so the IR becomes:
7140///
7141/// [C|V] --> [R] --> [] -->[int].
7142///
7143/// Note that the empty qualified type (noted []) represents a
7144/// qualified type with no qualifier. It's rare, but it can exist.
7145/// I've put it here just for the sake of example.
7146///
7147/// The resulting IR thus represents the (merged) type:
7148///
7149/// const virtual restrict int.
7150///
7151/// @param t the qualified type to consider. The IR below the
7152/// argument to this parameter will be edited to remove redundant
7153/// qualifiers where applicable.
7154void
7155strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
7156{
7157 if (!t)
7158 return;
7159
7160 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
7161 strip_redundant_quals_from_underyling_types(t, redundant_quals);
7162}
7163
7164/// Return the leaf underlying type node of a @ref typedef_decl node.
7165///
7166/// If the underlying type of a @ref typedef_decl node is itself a
7167/// @ref typedef_decl node, then recursively look at the underlying
7168/// type nodes to get the first one that is not a a @ref typedef_decl
7169/// node. This is what a leaf underlying type node means.
7170///
7171/// Otherwise, if the underlying type node of @ref typedef_decl is
7172/// *NOT* a @ref typedef_decl node, then just return the underlying
7173/// type node.
7174///
7175/// And if the type node considered is not a @ref typedef_decl node,
7176/// then just return it.
7177///
7178/// @return the leaf underlying type node of a @p type.
7179type_base_sptr
7180peel_typedef_type(const type_base_sptr& type)
7181{
7182 typedef_decl_sptr t = is_typedef(type);
7183 if (!t)
7184 return type;
7185
7186 if (is_typedef(t->get_underlying_type()))
7187 return peel_typedef_type(t->get_underlying_type());
7188 return t->get_underlying_type();
7189}
7190
7191/// Return the leaf underlying type node of a @ref typedef_decl node.
7192///
7193/// If the underlying type of a @ref typedef_decl node is itself a
7194/// @ref typedef_decl node, then recursively look at the underlying
7195/// type nodes to get the first one that is not a a @ref typedef_decl
7196/// node. This is what a leaf underlying type node means.
7197///
7198/// Otherwise, if the underlying type node of @ref typedef_decl is
7199/// *NOT* a @ref typedef_decl node, then just return the underlying
7200/// type node.
7201///
7202/// And if the type node considered is not a @ref typedef_decl node,
7203/// then just return it.
7204///
7205/// @return the leaf underlying type node of a @p type.
7206const type_base*
7208{
7209 const typedef_decl* t = is_typedef(type);
7210 if (!t)
7211 return type;
7212
7213 return peel_typedef_type(t->get_underlying_type()).get();
7214}
7215
7216/// Return the leaf pointed-to type node of a @ref pointer_type_def
7217/// node.
7218///
7219/// If the pointed-to type of a @ref pointer_type_def node is itself a
7220/// @ref pointer_type_def node, then recursively look at the
7221/// pointed-to type nodes to get the first one that is not a a @ref
7222/// pointer_type_def node. This is what a leaf pointed-to type node
7223/// means.
7224///
7225/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7226/// *NOT* a @ref pointer_type_def node, then just return the
7227/// pointed-to type node.
7228///
7229/// And if the type node considered is not a @ref pointer_type_def
7230/// node, then just return it.
7231///
7232/// @return the leaf pointed-to type node of a @p type.
7233type_base_sptr
7234peel_pointer_type(const type_base_sptr& type)
7235{
7237 if (!t)
7238 return type;
7239
7240 if (is_pointer_type(t->get_pointed_to_type()))
7241 return peel_pointer_type(t->get_pointed_to_type());
7242 return t->get_pointed_to_type();
7243}
7244
7245/// Return the leaf pointed-to type node of a @ref pointer_type_def
7246/// node.
7247///
7248/// If the pointed-to type of a @ref pointer_type_def node is itself a
7249/// @ref pointer_type_def node, then recursively look at the
7250/// pointed-to type nodes to get the first one that is not a a @ref
7251/// pointer_type_def node. This is what a leaf pointed-to type node
7252/// means.
7253///
7254/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7255/// *NOT* a @ref pointer_type_def node, then just return the
7256/// pointed-to type node.
7257///
7258/// And if the type node considered is not a @ref pointer_type_def
7259/// node, then just return it.
7260///
7261/// @return the leaf pointed-to type node of a @p type.
7262const type_base*
7264{
7265 const pointer_type_def* t = is_pointer_type(type);
7266 if (!t)
7267 return type;
7268
7269 return peel_pointer_type(t->get_pointed_to_type()).get();
7270}
7271
7272/// Return the leaf pointed-to type node of a @ref reference_type_def
7273/// node.
7274///
7275/// If the pointed-to type of a @ref reference_type_def node is itself
7276/// a @ref reference_type_def node, then recursively look at the
7277/// pointed-to type nodes to get the first one that is not a a @ref
7278/// reference_type_def node. This is what a leaf pointed-to type node
7279/// means.
7280///
7281/// Otherwise, if the pointed-to type node of @ref reference_type_def
7282/// is *NOT* a @ref reference_type_def node, then just return the
7283/// pointed-to type node.
7284///
7285/// And if the type node considered is not a @ref reference_type_def
7286/// node, then just return it.
7287///
7288/// @return the leaf pointed-to type node of a @p type.
7289type_base_sptr
7290peel_reference_type(const type_base_sptr& type)
7291{
7293 if (!t)
7294 return type;
7295
7296 if (is_reference_type(t->get_pointed_to_type()))
7297 return peel_reference_type(t->get_pointed_to_type());
7298 return t->get_pointed_to_type();
7299}
7300
7301/// Return the leaf pointed-to type node of a @ref reference_type_def
7302/// node.
7303///
7304/// If the pointed-to type of a @ref reference_type_def node is itself
7305/// a @ref reference_type_def node, then recursively look at the
7306/// pointed-to type nodes to get the first one that is not a a @ref
7307/// reference_type_def node. This is what a leaf pointed-to type node
7308/// means.
7309///
7310/// Otherwise, if the pointed-to type node of @ref reference_type_def
7311/// is *NOT* a @ref reference_type_def node, then just return the
7312/// pointed-to type node.
7313///
7314/// And if the type node considered is not a @ref reference_type_def
7315/// node, then just return it.
7316///
7317/// @return the leaf pointed-to type node of a @p type.
7318const type_base*
7320{
7321 const reference_type_def* t = is_reference_type(type);
7322 if (!t)
7323 return type;
7324
7325 return peel_reference_type(t->get_pointed_to_type()).get();
7326}
7327
7328/// Return the leaf element type of an array.
7329///
7330/// If the element type is itself an array, then recursively return
7331/// the element type of that array itself.
7332///
7333/// @param type the array type to consider. If this is not an array
7334/// type, this type is returned by the function.
7335///
7336/// @return the leaf element type of the array @p type, or, if it's
7337/// not an array type, then just return @p.
7338const type_base_sptr
7339peel_array_type(const type_base_sptr& type)
7340{
7341 const array_type_def_sptr t = is_array_type(type);
7342 if (!t)
7343 return type;
7344
7345 return peel_array_type(t->get_element_type());
7346}
7347
7348/// Return the leaf element type of an array.
7349///
7350/// If the element type is itself an array, then recursively return
7351/// the element type of that array itself.
7352///
7353/// @param type the array type to consider. If this is not an array
7354/// type, this type is returned by the function.
7355///
7356/// @return the leaf element type of the array @p type, or, if it's
7357/// not an array type, then just return @p.
7358const type_base*
7360{
7361 const array_type_def* t = is_array_type(type);
7362 if (!t)
7363 return type;
7364
7365 return peel_array_type(t->get_element_type()).get();
7366}
7367
7368/// Return the leaf underlying type of a qualified type.
7369///
7370/// If the underlying type is itself a qualified type, then
7371/// recursively return the first underlying type of that qualified
7372/// type to return the first underlying type that is not a qualified type.
7373///
7374/// If the underlying type is NOT a qualified type, then just return
7375/// that underlying type.
7376///
7377/// @param type the qualified type to consider.
7378///
7379/// @return the leaf underlying type.
7380const type_base*
7382{
7383 const qualified_type_def* t = is_qualified_type(type);
7384 if (!t)
7385 return type;
7386
7387 return peel_qualified_type(t->get_underlying_type().get());
7388}
7389
7390/// Return the leaf underlying type of a qualified type.
7391///
7392/// If the underlying type is itself a qualified type, then
7393/// recursively return the first underlying type of that qualified
7394/// type to return the first underlying type that is not a qualified type.
7395///
7396/// If the underlying type is NOT a qualified type, then just return
7397/// that underlying type.
7398///
7399/// @param type the qualified type to consider.
7400///
7401/// @return the leaf underlying type.
7402const type_base_sptr
7403peel_qualified_type(const type_base_sptr& type)
7404{
7405 const qualified_type_def_sptr t = is_qualified_type(type);
7406 if (!t)
7407 return type;
7408
7409 return peel_qualified_type(t->get_underlying_type());
7410}
7411
7412/// Return the leaf underlying type of a qualified or typedef type.
7413///
7414/// If the underlying type is itself a qualified or typedef type, then
7415/// recursively return the first underlying type of that qualified or
7416/// typedef type to return the first underlying type that is not a
7417/// qualified or typedef type.
7418///
7419/// If the underlying type is NOT a qualified nor a typedef type, then
7420/// just return that underlying type.
7421///
7422/// @param type the qualified or typedef type to consider.
7423///
7424/// @return the leaf underlying type.
7425type_base*
7427{
7428 while (is_typedef(type) || is_qualified_type(type))
7429 {
7430 if (const typedef_decl* t = is_typedef(type))
7431 type = peel_typedef_type(t);
7432
7433 if (const qualified_type_def* t = is_qualified_type(type))
7434 type = peel_qualified_type(t);
7435 }
7436
7437 return const_cast<type_base*>(type);
7438}
7439
7440/// Return the leaf underlying type of a qualified or typedef type.
7441///
7442/// If the underlying type is itself a qualified or typedef type, then
7443/// recursively return the first underlying type of that qualified or
7444/// typedef type to return the first underlying type that is not a
7445/// qualified or typedef type.
7446///
7447/// If the underlying type is NOT a qualified nor a typedef type, then
7448/// just return that underlying type.
7449///
7450/// @param type the qualified or typedef type to consider.
7451///
7452/// @return the leaf underlying type.
7453type_base_sptr
7454peel_qualified_or_typedef_type(const type_base_sptr &t)
7455{
7456 type_base_sptr type = t;
7457 while (is_typedef(type) || is_qualified_type(type))
7458 {
7459 if (typedef_decl_sptr t = is_typedef(type))
7460 type = peel_typedef_type(t);
7461
7462 if (qualified_type_def_sptr t = is_qualified_type(type))
7463 type = peel_qualified_type(t);
7464 }
7465
7466 return type;
7467}
7468
7469/// Return the leaf underlying or pointed-to type node of a @ref
7470/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7471/// or @ref array_type_def node.
7472///
7473/// @param type the type to peel.
7474///
7475/// @return the leaf underlying or pointed-to type node of @p type.
7476type_base_sptr
7478{
7479 type_base_sptr typ = type;
7480 while (is_typedef(typ)
7481 || is_pointer_type(typ)
7482 || is_reference_type(typ)
7483 || is_array_type(typ))
7484 {
7485 if (typedef_decl_sptr t = is_typedef(typ))
7486 typ = peel_typedef_type(t);
7487
7489 typ = peel_pointer_type(t);
7490
7492 typ = peel_reference_type(t);
7493
7494 if (const array_type_def_sptr t = is_array_type(typ))
7495 typ = peel_array_type(t);
7496 }
7497
7498 return typ;
7499}
7500
7501/// Return the leaf underlying or pointed-to type node of a @ref
7502/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7503/// node.
7504///
7505/// @param type the type to peel.
7506///
7507/// @return the leaf underlying or pointed-to type node of @p type.
7508type_base*
7510{
7511 while (is_typedef(type)
7512 || is_pointer_type(type)
7513 || is_reference_type(type)
7514 || is_array_type(type))
7515 {
7516 if (const typedef_decl* t = is_typedef(type))
7517 type = peel_typedef_type(t);
7518
7519 if (const pointer_type_def* t = is_pointer_type(type))
7520 type = peel_pointer_type(t);
7521
7522 if (const reference_type_def* t = is_reference_type(type))
7523 type = peel_reference_type(t);
7524
7525 if (const array_type_def* t = is_array_type(type))
7526 type = peel_array_type(t);
7527 }
7528
7529 return const_cast<type_base*>(type);
7530}
7531
7532/// Return the leaf underlying or pointed-to type node of a @ref
7533/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7534/// node.
7535///
7536/// @param type the type to peel.
7537///
7538/// @return the leaf underlying or pointed-to type node of @p type.
7539type_base*
7541 bool peel_qual_type)
7542{
7543 while (is_typedef(type)
7544 || is_pointer_type(type)
7545 || is_reference_type(type)
7546 || is_array_type(type)
7547 || (peel_qual_type && is_qualified_type(type)))
7548 {
7549 if (const typedef_decl* t = is_typedef(type))
7550 type = peel_typedef_type(t);
7551
7552 if (const pointer_type_def* t = is_pointer_type(type))
7553 type = peel_pointer_type(t);
7554
7555 if (const reference_type_def* t = is_reference_type(type))
7556 type = peel_reference_type(t);
7557
7558 if (const array_type_def* t = is_array_type(type))
7559 type = peel_array_type(t);
7560
7561 if (peel_qual_type)
7562 if (const qualified_type_def* t = is_qualified_type(type))
7563 type = peel_qualified_type(t);
7564 }
7565
7566 return const_cast<type_base*>(type);
7567}
7568
7569/// Return the leaf underlying or pointed-to type node of a, @ref
7570/// pointer_type_def, @ref reference_type_def or @ref
7571/// qualified_type_def type node.
7572///
7573/// @param type the type to peel.
7574///
7575/// @param peel_qualified_type if true, also peel qualified types.
7576///
7577/// @return the leaf underlying or pointed-to type node of @p type.
7578type_base*
7580 bool peel_qual_type)
7581{
7582 while (is_pointer_type(type)
7583 || is_reference_type(type)
7584 || is_array_type(type)
7585 || (peel_qual_type && is_qualified_type(type)))
7586 {
7587 if (const pointer_type_def* t = is_pointer_type(type))
7588 type = peel_pointer_type(t);
7589
7590 if (const reference_type_def* t = is_reference_type(type))
7591 type = peel_reference_type(t);
7592
7593 if (const array_type_def* t = is_array_type(type))
7594 type = peel_array_type(t);
7595
7596 if (peel_qual_type)
7597 if (const qualified_type_def* t = is_qualified_type(type))
7598 type = peel_qualified_type(t);
7599 }
7600
7601 return const_cast<type_base*>(type);
7602}
7603
7604/// Clone an array type.
7605///
7606/// Note that the element type of the new array is shared witht the
7607/// old one.
7608///
7609/// @param array the array type to clone.
7610///
7611/// @return a newly built array type. Note that it needs to be added
7612/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7613/// bound to the one of that scope. Otherwise, its lifetime is bound
7614/// to the lifetime of its containing shared pointer.
7617{
7618 vector<array_type_def::subrange_sptr> subranges;
7619
7620 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7621 array->get_subranges().begin();
7622 i != array->get_subranges().end();
7623 ++i)
7624 {
7626 (new array_type_def::subrange_type(array->get_environment(),
7627 (*i)->get_name(),
7628 (*i)->get_lower_bound(),
7629 (*i)->get_upper_bound(),
7630 (*i)->get_underlying_type(),
7631 (*i)->get_location(),
7632 (*i)->get_language()));
7633 subrange->is_non_finite((*i)->is_non_finite());
7634 if (scope_decl *scope = (*i)->get_scope())
7635 add_decl_to_scope(subrange, scope);
7636 subranges.push_back(subrange);
7637 }
7638
7639 array_type_def_sptr result
7640 (new array_type_def(array->get_element_type(),
7641 subranges, array->get_location()));
7642
7643 return result;
7644}
7645
7646/// Clone a typedef type.
7647///
7648/// Note that the underlying type of the newly constructed typedef is
7649/// shared with the old one.
7650///
7651/// @param t the typedef to clone.
7652///
7653/// @return the newly constructed typedef. Note that it needs to be
7654/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7655/// to be bound to the one of that scope. Otherwise, its lifetime is
7656/// bound to the lifetime of its containing shared pointer.
7659{
7660 if (!t)
7661 return t;
7662
7663 typedef_decl_sptr result
7664 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7665 t->get_location(), t->get_linkage_name(),
7666 t->get_visibility()));
7667 return result;
7668}
7669
7670/// Clone a qualifiend type.
7671///
7672/// Note that underlying type of the newly constructed qualified type
7673/// is shared with the old one.
7674///
7675/// @param t the qualified type to clone.
7676///
7677/// @return the newly constructed qualified type. Note that it needs
7678/// to be added to a scope (e.g, using add_decl_to_scope) for its
7679/// lifetime to be bound to the one of that scope. Otherwise, its
7680/// lifetime is bound to the lifetime of its containing shared
7681/// pointer.
7682qualified_type_def_sptr
7683clone_qualified_type(const qualified_type_def_sptr& t)
7684{
7685 if (!t)
7686 return t;
7687
7688 qualified_type_def_sptr result
7689 (new qualified_type_def(t->get_underlying_type(),
7690 t->get_cv_quals(), t->get_location()));
7691
7692 return result;
7693}
7694
7695/// Clone a typedef, an array or a qualified tree.
7696///
7697/// @param type the typedef, array or qualified tree to clone. any
7698/// order.
7699///
7700/// @return the cloned type, or NULL if @type was neither a typedef,
7701/// array nor a qualified type.
7702static type_base_sptr
7703clone_typedef_array_qualified_type(type_base_sptr type)
7704{
7705 if (!type)
7706 return type;
7707
7708 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7709 type_base_sptr result;
7710
7711 if (typedef_decl_sptr t = is_typedef(type))
7712 result = clone_typedef(is_typedef(t));
7713 else if (qualified_type_def_sptr t = is_qualified_type(type))
7714 result = clone_qualified_type(t);
7715 else if (array_type_def_sptr t = is_array_type(type))
7716 result = clone_array(t);
7717 else
7718 return type_base_sptr();
7719
7720 if (scope)
7721 add_decl_to_scope(is_decl(result), scope);
7722
7723 return result;
7724}
7725
7726/// Clone a type tree made of an array or a typedef of array.
7727///
7728/// Note that this can be a tree which root node is a typedef an which
7729/// sub-tree can be any arbitrary combination of typedef, qualified
7730/// type and arrays.
7731///
7732/// @param t the array or typedef of qualified array to consider.
7733///
7734/// @return a clone of @p t.
7735type_base_sptr
7736clone_array_tree(const type_base_sptr t)
7737{
7739
7740 scope_decl* scope = is_decl(t)->get_scope();
7741 type_base_sptr result = clone_typedef_array_qualified_type(t);
7742 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7743
7744 type_base_sptr subtree;
7745 if (typedef_decl_sptr type = is_typedef(result))
7746 {
7747 type_base_sptr s =
7748 clone_typedef_array_qualified_type(type->get_underlying_type());
7749 if (s)
7750 {
7751 subtree = s;
7752 type->set_underlying_type(subtree);
7753 }
7754 }
7755 else if (array_type_def_sptr type = is_array_type(result))
7756 {
7757 type_base_sptr s =
7758 clone_typedef_array_qualified_type(type->get_element_type());
7759 if (s)
7760 {
7761 subtree = s;
7762 type->set_element_type(subtree);
7763 }
7764 }
7765 add_decl_to_scope(is_decl(subtree), scope);
7766
7767 for (;;)
7768 {
7769 if (typedef_decl_sptr t = is_typedef(subtree))
7770 {
7771 type_base_sptr s =
7772 clone_typedef_array_qualified_type(t->get_underlying_type());
7773 if (s)
7774 {
7775 scope_decl* scope =
7776 is_decl(t->get_underlying_type())->get_scope();
7777 ABG_ASSERT(scope);
7778 add_decl_to_scope(is_decl(s), scope);
7779 t->set_underlying_type (s);
7780 subtree = s;
7781 }
7782 else
7783 break;
7784 }
7785 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7786 {
7787 type_base_sptr s =
7788 clone_typedef_array_qualified_type(t->get_underlying_type());
7789 if (s)
7790 {
7791 scope_decl* scope =
7792 is_decl(t->get_underlying_type())->get_scope();
7793 ABG_ASSERT(scope);
7794 add_decl_to_scope(is_decl(s), scope);
7795 t->set_underlying_type(s);
7796 subtree = s;
7797 }
7798 else
7799 break;
7800 }
7801 else if (array_type_def_sptr t = is_array_type(subtree))
7802 {
7803 type_base_sptr e = t->get_element_type();
7804 if (is_typedef(e) || is_qualified_type(e))
7805 {
7806 type_base_sptr s =
7807 clone_typedef_array_qualified_type(e);
7808 if (s)
7809 {
7810 scope_decl* scope = is_decl(e)->get_scope();
7811 ABG_ASSERT(scope);
7812 add_decl_to_scope(is_decl(s), scope);
7813 t->set_element_type(s);
7814 }
7815 else
7816 break;
7817 }
7818 break;
7819 }
7820 else
7821 break;
7822 }
7823 return result;
7824}
7825
7826/// Update the qualified name of a given sub-tree.
7827///
7828/// @param d the sub-tree for which to update the qualified name.
7829static void
7830update_qualified_name(decl_base * d)
7831{
7832 ::qualified_name_setter setter;
7833 d->traverse(setter);
7834}
7835
7836/// Update the qualified name of a given sub-tree.
7837///
7838/// @param d the sub-tree for which to update the qualified name.
7839static void
7840update_qualified_name(decl_base_sptr d)
7841{return update_qualified_name(d.get());}
7842
7843// <scope_decl stuff>
7844
7845/// Hash a type by returning the pointer value of its canonical type.
7846///
7847/// @param l the type to hash.
7848///
7849/// @return the the pointer value of the canonical type of @p l.
7850size_t
7851canonical_type_hash::operator()(const type_base_sptr& l) const
7852{return operator()(l.get());}
7853
7854/// Hash a (canonical) type by returning its pointer value
7855///
7856/// @param l the canonical type to hash.
7857///
7858/// @return the pointer value of the canonical type of @p l.
7859size_t
7861{return reinterpret_cast<size_t>(l);}
7862
7863struct scope_decl::priv
7864{
7865 declarations members_;
7866 declarations sorted_members_;
7867 type_base_sptrs_type member_types_;
7868 type_base_sptrs_type sorted_member_types_;
7869 scopes member_scopes_;
7870 canonical_type_sptr_set_type canonical_types_;
7871 type_base_sptrs_type sorted_canonical_types_;
7872}; // end struct scope_decl::priv
7873
7874/// Constructor of the @ref scope_decl type.
7875///
7876/// @param the environment to use for the new instance.
7877///
7878/// @param the name of the scope decl.
7879///
7880/// @param locus the source location where the scope_decl is defined.
7881///
7882/// @param vis the visibility of the declaration.
7883scope_decl::scope_decl(const environment& env,
7884 const string& name,
7885 const location& locus,
7886 visibility vis)
7887 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7888 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7889 priv_(new priv)
7890{}
7891
7892/// Constructor of the @ref scope_decl type.
7893///
7894/// @param the environment to use for the new instance.
7895///
7896/// @param l the source location where the scope_decl is defined.
7897///
7898/// @param vis the visibility of the declaration.
7899scope_decl::scope_decl(const environment& env, location& l)
7900 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7901 decl_base(env, "", l),
7902 priv_(new priv)
7903{}
7904
7905/// @eturn the set of canonical types of the the current scope.
7908{return priv_->canonical_types_;}
7909
7910/// @eturn the set of canonical types of the the current scope.
7913{return const_cast<scope_decl*>(this)->get_canonical_types();}
7914
7915/// Return a vector of sorted canonical types of the current scope.
7916///
7917/// The types are sorted "almost topologically". That means, they are
7918/// sorted using the lexicographic order of the string representing
7919/// the location their definition point. If a type doesn't have a
7920/// location, then its pretty representation is used.
7921///
7922/// @return a vector of sorted canonical types of the current scope.
7925{
7926 if (priv_->sorted_canonical_types_.empty())
7927 {
7928 for (canonical_type_sptr_set_type::const_iterator e =
7929 get_canonical_types().begin();
7930 e != get_canonical_types().end();
7931 ++e)
7932 priv_->sorted_canonical_types_.push_back(*e);
7933
7934 type_topo_comp comp;
7935 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7936 priv_->sorted_canonical_types_.end(),
7937 comp);
7938 }
7939 return priv_->sorted_canonical_types_;
7940}
7941
7942/// Getter for the member declarations carried by the current @ref
7943/// scope_decl.
7944///
7945/// @return the member declarations carried by the current @ref
7946/// scope_decl.
7949{return priv_->members_;}
7950
7951/// Getter for the member declarations carried by the current @ref
7952/// scope_decl.
7953///
7954/// @return the member declarations carried by the current @ref
7955/// scope_decl.
7958{return priv_->members_;}
7959
7960/// Getter for the sorted member declarations carried by the current
7961/// @ref scope_decl.
7962///
7963/// @return the sorted member declarations carried by the current @ref
7964/// scope_decl. The declarations are sorted topologically.
7967{
7968 decl_topo_comp comp;
7969 if (priv_->sorted_members_.empty())
7970 {
7971 for (declarations::const_iterator i = get_member_decls().begin();
7972 i != get_member_decls().end();
7973 ++i)
7974 priv_->sorted_members_.push_back(*i);
7975
7976 std::stable_sort(priv_->sorted_members_.begin(),
7977 priv_->sorted_members_.end(),
7978 comp);
7979 }
7980 return priv_->sorted_members_;
7981}
7982
7983/// Getter for the number of anonymous classes contained in this
7984/// scope.
7985///
7986/// @return the number of anonymous classes contained in this scope.
7987size_t
7989{
7990 int result = 0;
7991 for (declarations::const_iterator it = get_member_decls().begin();
7992 it != get_member_decls().end();
7993 ++it)
7994 if (class_decl_sptr t = is_class_type(*it))
7995 if (t->get_is_anonymous())
7996 ++result;
7997
7998 return result;
7999}
8000
8001/// Getter for the number of anonymous unions contained in this
8002/// scope.
8003///
8004/// @return the number of anonymous unions contained in this scope.
8005size_t
8007{
8008 int result = 0;
8009 for (declarations::const_iterator it = get_member_decls().begin();
8010 it != get_member_decls().end();
8011 ++it)
8012 if (union_decl_sptr t = is_union_type(*it))
8013 if (t->get_is_anonymous())
8014 ++result;
8015
8016 return result;
8017}
8018
8019/// Getter for the number of anonymous enums contained in this
8020/// scope.
8021///
8022/// @return the number of anonymous enums contained in this scope.
8023size_t
8025{
8026 int result = 0;
8027 for (declarations::const_iterator it = get_member_decls().begin();
8028 it != get_member_decls().end();
8029 ++it)
8030 if (enum_type_decl_sptr t = is_enum_type(*it))
8031 if (t->get_is_anonymous())
8032 ++result;
8033
8034 return result;
8035}
8036
8037/// Getter for the scopes carried by the current scope.
8038///
8039/// @return the scopes carried by the current scope.
8042{return priv_->member_scopes_;}
8043
8044/// Getter for the scopes carried by the current scope.
8045///
8046/// @return the scopes carried by the current scope.
8047const scope_decl::scopes&
8049{return priv_->member_scopes_;}
8050
8051/// Test if the current scope is empty.
8052///
8053/// @return true iff the current scope is empty.
8054bool
8056{
8057 return (get_member_decls().empty()
8058 && get_canonical_types().empty());
8059}
8060
8061/// Set the translation unit of a decl
8062///
8063/// It also perform some IR integrity checks.
8064///
8065/// This is a sub-routine of scope_decl::{insert,add}_member_decl.
8066///
8067/// @param decl the decl to set the translation unit for.
8068///
8069/// @param tu the translation unit to set.
8070static void
8071maybe_set_translation_unit(const decl_base_sptr& decl,
8072 translation_unit* tu)
8073{
8074 if (translation_unit* existing_tu = decl->get_translation_unit())
8075 // The decl already belongs to a translation unit.
8076 // Either:
8077 //
8078 // 1/ it's a unique type, in which case we should not add it to
8079 // any translation unique since unique types are "logically"
8080 // supposed to belong to no translation unit in particular, as
8081 // they are unique.
8082 //
8083 // 2/ or the decl was already added to this translation unit.
8084 ABG_ASSERT(tu == existing_tu || is_unique_type(is_type(decl)));
8085 else
8086 decl->set_translation_unit(tu);
8087}
8088
8089/// Add a member decl to this scope. Note that user code should not
8090/// use this, but rather use add_decl_to_scope.
8091///
8092/// Note that this function updates the qualified name of the member
8093/// decl that is added. It also sets the scope of the member. Thus,
8094/// it ABG_ASSERTs that member should not have its scope set, prior to
8095/// calling this function.
8096///
8097/// @param member the new member decl to add to this scope.
8098decl_base_sptr
8099scope_decl::add_member_decl(const decl_base_sptr& member)
8100{
8101 ABG_ASSERT(!has_scope(member));
8102
8103 member->set_scope(this);
8104 priv_->members_.push_back(member);
8105 if (is_type(member))
8106 priv_->member_types_.push_back(is_type(member));
8107
8108 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8109 priv_->member_scopes_.push_back(m);
8110
8111 update_qualified_name(member);
8112
8114 maybe_set_translation_unit(member, tu);
8115
8117
8118 return member;
8119}
8120
8121/// Get the member types of this @ref scope_decl.
8122///
8123/// @return a vector of the member types of this ref class_or_union.
8126{return priv_->member_types_;}
8127
8128/// Find a member type of a given name, inside the current @ref
8129/// scope_decl.
8130///
8131/// @param name the name of the member type to look for.
8132///
8133/// @return a pointer to the @ref type_base that represents the member
8134/// type of name @p name, for the current scope.
8135type_base_sptr
8136scope_decl::find_member_type(const string& name) const
8137{
8138 for (auto t : get_member_types())
8139 if (get_type_name(t, /*qualified*/false) == name)
8140 return t;
8141 return type_base_sptr();
8142}
8143
8144/// Insert a member type.
8145///
8146/// @param t the type to insert in the @ref scope_decl type.
8147///
8148/// @param an iterator right before which @p t has to be inserted.
8149void
8151 declarations::iterator before)
8152{
8153 decl_base_sptr d = get_type_declaration(t);
8154 ABG_ASSERT(d);
8155 ABG_ASSERT(!has_scope(d));
8156
8157 priv_->member_types_.push_back(t);
8158 insert_member_decl(d, before);
8159}
8160
8161/// Add a member type to the current instance of class_or_union.
8162///
8163/// @param t the member type to add. It must not have been added to a
8164/// scope, otherwise this will violate an ABG_ASSERTion.
8165void
8168
8169/// Add a member type to the current instance of class_or_union.
8170///
8171/// @param t the type to be added as a member type to the current
8172/// instance of class_or_union. An instance of class_or_union::member_type
8173/// will be created out of @p t and and added to the the class.
8174///
8175/// @param a the access specifier for the member type to be created.
8176type_base_sptr
8178{
8179 decl_base_sptr d = get_type_declaration(t);
8180 ABG_ASSERT(d);
8182 add_member_type(t);
8184 return t;
8185}
8186
8187/// Remove a member type from the current @ref class_or_union scope.
8188///
8189/// @param t the type to remove.
8190void
8192{
8193 for (auto i = priv_->member_types_.begin();
8194 i != priv_->member_types_.end();
8195 ++i)
8196 {
8197 if (*((*i)) == *t)
8198 {
8199 priv_->member_types_.erase(i);
8200 return;
8201 }
8202 }
8203}
8204
8205/// Get the sorted member types of this @ref scope_decl
8206///
8207/// @return a vector of the sorted member types of this ref
8208/// class_or_union.
8211{
8212 if (priv_->sorted_member_types_.empty())
8213 {
8214 for (auto t : get_member_types())
8215 priv_->sorted_member_types_.push_back(t);
8216
8217 type_topo_comp comp;
8218 std::stable_sort(priv_->sorted_member_types_.begin(),
8219 priv_->sorted_member_types_.end(),
8220 comp);
8221 }
8222 return priv_->sorted_member_types_;
8223}
8224
8225/// Insert a member decl to this scope, right before an element
8226/// pointed to by a given iterator. Note that user code should not
8227/// use this, but rather use insert_decl_into_scope.
8228///
8229/// Note that this function updates the qualified name of the inserted
8230/// member.
8231///
8232/// @param member the new member decl to add to this scope.
8233///
8234/// @param before an interator pointing to the element before which
8235/// the new member should be inserted.
8236decl_base_sptr
8238 declarations::iterator before)
8239{
8240 ABG_ASSERT(!member->get_scope());
8241
8242 member->set_scope(this);
8243 priv_->members_.insert(before, member);
8244
8245 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8246 priv_-> member_scopes_.push_back(m);
8247
8248 update_qualified_name(member);
8249
8251 maybe_set_translation_unit(member, tu);
8252
8254
8255 return member;
8256}
8257
8258/// Remove a declaration from the current scope.
8259///
8260/// @param member the declaration to remove from the scope.
8261void
8263{
8264 for (declarations::iterator i = priv_->members_.begin();
8265 i != priv_->members_.end();
8266 ++i)
8267 {
8268 if (**i == *member)
8269 {
8270 priv_->members_.erase(i);
8271 // Do not access i after this point as it's invalided by the
8272 // erase call.
8273 break;
8274 }
8275 }
8276
8277 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8278 if (scope)
8279 {
8280 for (scopes::iterator i = priv_->member_scopes_.begin();
8281 i != priv_->member_scopes_.end();
8282 ++i)
8283 {
8284 if (**i == *member)
8285 {
8286 priv_->member_scopes_.erase(i);
8287 break;
8288 }
8289 }
8290 }
8291
8292 member->set_scope(nullptr);
8293 member->set_translation_unit(nullptr);
8294}
8295
8296/// Return the hash value for the current instance of scope_decl.
8297///
8298/// This method can trigger the computing of the hash value, if need be.
8299///
8300/// @return the hash value.
8301size_t
8303{
8304 scope_decl::hash hash_scope;
8305 return hash_scope(this);
8306}
8307
8308/// Compares two instances of @ref scope_decl.
8309///
8310/// If the two intances are different, set a bitfield to give some
8311/// insight about the kind of differences there are.
8312///
8313/// @param l the first artifact of the comparison.
8314///
8315/// @param r the second artifact of the comparison.
8316///
8317/// @param k a pointer to a bitfield that gives information about the
8318/// kind of changes there are between @p l and @p r. This one is set
8319/// iff @p k is non-null and the function returns false.
8320///
8321/// Please note that setting k to a non-null value does have a
8322/// negative performance impact because even if @p l and @p r are not
8323/// equal, the function keeps up the comparison in order to determine
8324/// the different kinds of ways in which they are different.
8325///
8326/// @return true if @p l equals @p r, false otherwise.
8327bool
8329{
8330 bool result = true;
8331
8332 if (!l.decl_base::operator==(r))
8333 {
8334 result = false;
8335 if (k)
8337 else
8339 }
8340
8341 scope_decl::declarations::const_iterator i, j;
8342 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8343 i != l.get_member_decls().end() && j != r.get_member_decls().end();
8344 ++i, ++j)
8345 {
8346 if (**i != **j)
8347 {
8348 result = false;
8349 if (k)
8350 {
8351 *k |= SUBTYPE_CHANGE_KIND;
8352 break;
8353 }
8354 else
8356 }
8357 }
8358
8359 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8360 {
8361 result = false;
8362 if (k)
8364 else
8366 }
8367
8368 ABG_RETURN(result);
8369}
8370
8371/// Return true iff both scopes have the same names and have the same
8372/// member decls.
8373///
8374/// This function doesn't check for equality of the scopes of its
8375/// arguments.
8376bool
8378{
8379 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8380 if (!other)
8381 return false;
8382
8383 return equals(*this, *other, 0);
8384}
8385
8386/// Equality operator for @ref scope_decl_sptr.
8387///
8388/// @param l the left hand side operand of the equality operator.
8389///
8390/// @pram r the right hand side operand of the equalify operator.
8391///
8392/// @return true iff @p l equals @p r.
8393bool
8395{
8396 if (!!l != !!r)
8397 return false;
8398 if (l.get() == r.get())
8399 return true;
8400 return *l == *r;
8401}
8402
8403/// Inequality operator for @ref scope_decl_sptr.
8404///
8405/// @param l the left hand side operand of the equality operator.
8406///
8407/// @pram r the right hand side operand of the equalify operator.
8408///
8409/// @return true iff @p l equals @p r.
8410bool
8412{return !operator==(l, r);}
8413
8414/// Find a member of the current scope and return an iterator on it.
8415///
8416/// @param decl the scope member to find.
8417///
8418/// @param i the iterator to set to the member @p decl. This is set
8419/// iff the function returns true.
8420///
8421/// @return true if the member decl was found, false otherwise.
8422bool
8424 declarations::iterator& i)
8425{
8426 if (!decl)
8427 return false;
8428
8429 if (get_member_decls().empty())
8430 {
8431 i = get_member_decls().end();
8432 return false;
8433 }
8434
8435 for (declarations::iterator it = get_member_decls().begin();
8436 it != get_member_decls().end();
8437 ++it)
8438 {
8439 if ((*it).get() == decl)
8440 {
8441 i = it;
8442 return true;
8443 }
8444 }
8445
8446 return false;
8447}
8448
8449/// Find a member of the current scope and return an iterator on it.
8450///
8451/// @param decl the scope member to find.
8452///
8453/// @param i the iterator to set to the member @p decl. This is set
8454/// iff the function returns true.
8455///
8456/// @return true if the member decl was found, false otherwise.
8457bool
8459 declarations::iterator& i)
8460{return find_iterator_for_member(decl.get(), i);}
8461
8462/// This implements the ir_traversable_base::traverse pure virtual
8463/// function.
8464///
8465/// @param v the visitor used on the current instance of scope_decl
8466/// and on its member nodes.
8467///
8468/// @return true if the traversal of the tree should continue, false
8469/// otherwise.
8470bool
8472{
8473 if (visiting())
8474 return true;
8475
8476 if (v.visit_begin(this))
8477 {
8478 visiting(true);
8479 for (scope_decl::declarations::const_iterator i =
8480 get_member_decls().begin();
8481 i != get_member_decls ().end();
8482 ++i)
8483 if (!(*i)->traverse(v))
8484 break;
8485 visiting(false);
8486 }
8487 return v.visit_end(this);
8488}
8489
8490scope_decl::~scope_decl()
8491{}
8492
8493/// Appends a declaration to a given scope, if the declaration
8494/// doesn't already belong to one and if the declaration is not for a
8495/// type that is supposed to be unique.
8496///
8497/// @param decl the declaration to add to the scope
8498///
8499/// @param scope the scope to append the declaration to
8500decl_base_sptr
8501add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8502{
8503 ABG_ASSERT(scope);
8504
8505 if (scope && decl && !decl->get_scope())
8506 decl = scope->add_member_decl(decl);
8507
8508 return decl;
8509}
8510
8511/// Appends a declaration to a given scope, if the declaration doesn't
8512/// already belong to a scope.
8513///
8514/// @param decl the declaration to add append to the scope
8515///
8516/// @param scope the scope to append the decl to
8517decl_base_sptr
8518add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8519{return add_decl_to_scope(decl, scope.get());}
8520
8521/// Remove a given decl from its scope
8522///
8523/// @param decl the decl to remove from its scope.
8524void
8525remove_decl_from_scope(decl_base_sptr decl)
8526{
8527 if (!decl)
8528 return;
8529
8530 scope_decl* scope = decl->get_scope();
8531 scope->remove_member_decl(decl);
8532}
8533
8534/// Inserts a declaration into a given scope, before a given IR child
8535/// node of the scope.
8536///
8537/// @param decl the declaration to insert into the scope.
8538///
8539/// @param before an iterator pointing to the child IR node before
8540/// which to insert the declaration.
8541///
8542/// @param scope the scope into which to insert the declaration.
8543decl_base_sptr
8544insert_decl_into_scope(decl_base_sptr decl,
8545 scope_decl::declarations::iterator before,
8546 scope_decl* scope)
8547{
8548 if (scope && decl && !decl->get_scope())
8549 {
8550 decl_base_sptr d = scope->insert_member_decl(decl, before);
8551 decl = d;
8552 }
8553 return decl;
8554}
8555
8556/// Inserts a declaration into a given scope, before a given IR child
8557/// node of the scope.
8558///
8559/// @param decl the declaration to insert into the scope.
8560///
8561/// @param before an iterator pointing to the child IR node before
8562/// which to insert the declaration.
8563///
8564/// @param scope the scope into which to insert the declaration.
8565decl_base_sptr
8566insert_decl_into_scope(decl_base_sptr decl,
8567 scope_decl::declarations::iterator before,
8568 scope_decl_sptr scope)
8569{return insert_decl_into_scope(decl, before, scope.get());}
8570
8571/// Constructor of the @ref global_scope type.
8572///
8573/// @param tu the translation unit the scope belongs to.
8574global_scope::global_scope(translation_unit *tu)
8575 : type_or_decl_base(tu->get_environment(),
8576 GLOBAL_SCOPE_DECL
8577 | ABSTRACT_DECL_BASE
8578 | ABSTRACT_SCOPE_DECL),
8579 decl_base(tu->get_environment(), "", location()),
8580 scope_decl(tu->get_environment(), "", location()),
8581 translation_unit_(tu)
8582{
8583 runtime_type_instance(this);
8584}
8585
8586/// return the global scope as seen by a given declaration.
8587///
8588/// @param decl the declaration to consider.
8589///
8590/// @return the global scope of the decl, or a null pointer if the
8591/// decl is not yet added to a translation_unit.
8592const global_scope*
8594{
8595 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8596 return s;
8597
8598 scope_decl* scope = decl.get_scope();
8599 while (scope && !dynamic_cast<global_scope*>(scope))
8600 scope = scope->get_scope();
8601
8602 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8603}
8604
8605/// return the global scope as seen by a given declaration.
8606///
8607/// @param decl the declaration to consider.
8608///
8609/// @return the global scope of the decl, or a null pointer if the
8610/// decl is not yet added to a translation_unit.
8611const global_scope*
8613{return get_global_scope(*decl);}
8614
8615/// Return the global scope as seen by a given declaration.
8616///
8617/// @param decl the declaration to consider.
8618///
8619/// @return the global scope of the decl, or a null pointer if the
8620/// decl is not yet added to a translation_unit.
8621const global_scope*
8622get_global_scope(const shared_ptr<decl_base> decl)
8623{return get_global_scope(decl.get());}
8624
8625/// Return the a scope S containing a given declaration and that is
8626/// right under a given scope P.
8627///
8628/// Note that @p scope must come before @p decl in topological
8629/// order.
8630///
8631/// @param decl the decl for which to find a scope.
8632///
8633/// @param scope the scope under which the resulting scope must be.
8634///
8635/// @return the resulting scope.
8636const scope_decl*
8638 const scope_decl* scope)
8639{
8640 if (!decl)
8641 return 0;
8642
8643 if (scope == 0)
8644 return get_global_scope(decl);
8645
8646 // Handle the case where decl is a scope itself.
8647 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8648 if (!s)
8649 s = decl->get_scope();
8650
8651 if (is_global_scope(s))
8652 return scope;
8653
8654 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8655 // same. The caller needs to be prepared to deal with this case.
8656 if (s == scope)
8657 return s;
8658
8659 while (s && !is_global_scope(s) && s->get_scope() != scope)
8660 s = s->get_scope();
8661
8662 if (!s || is_global_scope(s))
8663 // SCOPE must come before decl in topological order, but I don't
8664 // know how to ensure that ...
8665 return scope;
8666 ABG_ASSERT(s);
8667
8668 return s;
8669}
8670
8671/// Return the a scope S containing a given declaration and that is
8672/// right under a given scope P.
8673///
8674/// @param decl the decl for which to find a scope.
8675///
8676/// @param scope the scope under which the resulting scope must be.
8677///
8678/// @return the resulting scope.
8679const scope_decl*
8680get_top_most_scope_under(const decl_base_sptr decl,
8681 const scope_decl* scope)
8682{return get_top_most_scope_under(decl.get(), scope);}
8683
8684/// Return the a scope S containing a given declaration and that is
8685/// right under a given scope P.
8686///
8687/// @param decl the decl for which to find a scope.
8688///
8689/// @param scope the scope under which the resulting scope must be.
8690///
8691/// @return the resulting scope.
8692const scope_decl*
8693get_top_most_scope_under(const decl_base_sptr decl,
8694 const scope_decl_sptr scope)
8695{return get_top_most_scope_under(decl, scope.get());}
8696
8697// </scope_decl stuff>
8698
8699
8700/// Get the string representation of a CV qualifier bitmap.
8701///
8702/// @param cv_quals the bitmap of CV qualifiers to consider.
8703///
8704/// @return the string representation.
8705string
8707{
8708 string repr;
8709 if (cv_quals & qualified_type_def::CV_RESTRICT)
8710 repr = "restrict";
8711 if (cv_quals & qualified_type_def::CV_CONST)
8712 {
8713 if (!repr.empty())
8714 repr += ' ';
8715 repr += "const";
8716 }
8717 if (cv_quals & qualified_type_def::CV_VOLATILE)
8718 {
8719 if (!repr.empty())
8720 repr += ' ';
8721 repr += "volatile";
8722 }
8723 return repr;
8724}
8725
8726/// Build and return a copy of the name of an ABI artifact that is
8727/// either a type or a decl.
8728///
8729/// @param tod the ABI artifact to get the name for.
8730///
8731/// @param qualified if yes, return the qualified name of @p tod;
8732/// otherwise, return the non-qualified name;
8733///
8734/// @return the name of @p tod.
8735string
8736get_name(const type_or_decl_base *tod, bool qualified)
8737{
8738 string result;
8739
8740 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8741
8742 if (type_base* t = dynamic_cast<type_base*>(a))
8743 result = get_type_name(t, qualified);
8744 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8745 {
8746 if (qualified)
8747 result = d->get_qualified_name();
8748 else
8749 result = d->get_name();
8750 }
8751 else
8752 // We should never reach this point.
8753 abort();
8754
8755 return result;
8756}
8757
8758/// Build and return a copy of the name of an ABI artifact that is
8759/// either a type of a decl.
8760///
8761/// @param tod the ABI artifact to get the name for.
8762///
8763/// @param qualified if yes, return the qualified name of @p tod;
8764/// otherwise, return the non-qualified name;
8765///
8766/// @return the name of @p tod.
8767string
8768get_name(const type_or_decl_base_sptr& tod, bool qualified)
8769{return get_name(tod.get(), qualified);}
8770
8771/// Build and return a qualified name from a name and its scope.
8772///
8773/// The name is supposed to be for an entity that is part of the
8774/// scope.
8775///
8776/// @param the scope to consider.
8777///
8778/// @param name of the name to consider.
8779///
8780/// @return a copy of the string that represents the qualified name.
8781string
8782build_qualified_name(const scope_decl* scope, const string& name)
8783{
8784 if (name.empty())
8785 return "";
8786
8787 string qualified_name;
8788 if (scope)
8789 qualified_name = scope->get_qualified_name();
8790
8791 if (qualified_name.empty())
8792 qualified_name = name;
8793 else
8794 qualified_name = qualified_name + "::" + name;
8795
8796 return qualified_name;
8797}
8798
8799/// Build and return the qualified name of a type in its scope.
8800///
8801/// @param scope the scope of the type to consider.
8802///
8803/// @param type the type to consider.
8804string
8805build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8806{return build_qualified_name(scope, get_name((type)));}
8807
8808// </scope_decl stuff>
8809
8810/// Get the location of the declaration of a given type.
8811///
8812/// @param type the type to consider.
8813///
8814/// @return the location of the declaration of type @p type.
8816get_location(const type_base_sptr& type)
8817{
8818 if (decl_base_sptr decl = get_type_declaration(type))
8819 return get_location(decl);
8820 return location();
8821}
8822
8823/// Get the location of a given declaration.
8824///
8825/// @param decl the declaration to consider.
8826///
8827/// @return the location of the declaration @p decl.
8829get_location(const decl_base_sptr& decl)
8830{
8831 location loc = decl->get_location();
8832 if (!loc)
8833 {
8834 if (class_or_union_sptr c = is_class_or_union_type(decl))
8835 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8836 {
8837 c = is_class_or_union_type(c->get_definition_of_declaration());
8838 loc = c->get_location();
8839 }
8840 }
8841 return loc;
8842}
8843
8844/// Get the scope of a given type.
8845///
8846/// @param t the type to consider.
8847///
8848/// @return the scope of type @p t or 0 if the type has no scope yet.
8851{
8852 if (!t)
8853 return 0;
8854
8856 if (d)
8857 return d->get_scope();
8858 return 0;
8859}
8860
8861/// Get the scope of a given type.
8862///
8863/// @param t the type to consider.
8864///
8865/// @return the scope of type @p t or 0 if the type has no scope yet.
8867get_type_scope(const type_base_sptr& t)
8868{return get_type_scope(t.get());}
8869
8870/// Get the name of a given type and return a copy of it.
8871///
8872/// @param t the type to consider.
8873///
8874/// @param qualified if true then return the qualified name of the
8875/// type.
8876///
8877/// @param internal set to true if the call is intended for an
8878/// internal use (for technical use inside the library itself), false
8879/// otherwise. If you don't know what this is for, then set it to
8880/// false.
8881///
8882/// @return a copy of the type name if the type has a name, or the
8883/// empty string if it does not.
8885get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8886{return get_type_name(t.get(), qualified, internal);}
8887
8888/// Return true iff a decl is for a type type that has a generic
8889/// anonymous internal type name.
8890///
8891/// @param d the decl to considier.
8892///
8893/// @return true iff @p d is for a type type that has a generic
8894/// anonymous internal type name.
8895static bool
8896has_generic_anonymous_internal_type_name(const decl_base *d)
8897{
8898 return (is_class_or_union_type(d)
8899 || is_enum_type(d)
8900 || is_subrange_type(d));
8901}
8902
8903/// Return the generic internal name of an anonymous type.
8904///
8905/// For internal purposes, we want to define a generic name for all
8906/// anonymous types of a certain kind. For instance, all anonymous
8907/// structs will be have a generic name of "__anonymous_struct__", all
8908/// anonymous unions will have a generic name of
8909/// "__anonymous_union__", etc.
8910///
8911/// That generic name can be used as a hash to put all anonymous types
8912/// of a certain kind in the same hash table bucket, for instance.
8913static interned_string
8914get_generic_anonymous_internal_type_name(const decl_base *d)
8915{
8916 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8917
8918 const environment&env = d->get_environment();
8919
8920 interned_string result;
8921 if (is_class_type(d))
8922 result =
8924 else if (is_union_type(d))
8925 result =
8927 else if (is_enum_type(d))
8928 result =
8930 else if (is_subrange_type(d))
8931 result =
8933 else
8935
8936 return result;
8937}
8938
8939/// Get the internal name for a given integral type.
8940///
8941/// All integral types that have the modifiers 'short, long or long
8942/// long' have the same internal name. This is so that they can all
8943/// have the same canonical type if they are of the same size.
8944/// Otherwise, 'long int' and 'long long int' would have different
8945/// canonical types even though they are equivalent from an ABI point
8946/// of view.
8947///
8948/// @param t the integral type to consider
8949///
8950/// @return the internal name for @p t if it's an integral type, or
8951/// the empty string if @p t is not an integral type.
8952static string
8953get_internal_integral_type_name(const type_base* t)
8954{
8955 string name;
8956 type_decl *type = is_integral_type(t);
8957
8958 if (!type)
8959 return name;
8960
8961 integral_type int_type;
8962 if (parse_integral_type(type->get_name(), int_type))
8963 name = int_type.to_string(/*internal=*/true);
8964
8965 return name;
8966}
8967
8968/// Get the name of a given type and return a copy of it.
8969///
8970/// @param t the type to consider.
8971///
8972/// @param qualified if true then return the qualified name of the
8973/// type.
8974///
8975/// @param internal set to true if the call is intended for an
8976/// internal use (for technical use inside the library itself), false
8977/// otherwise. If you don't know what this is for, then set it to
8978/// false.
8979///
8980/// @return a copy of the type name if the type has a name, or the
8981/// empty string if it does not.
8982interned_string
8983get_type_name(const type_base* t, bool qualified, bool internal)
8984{
8985 const decl_base* d = dynamic_cast<const decl_base*>(t);
8986 if (!d)
8987 {
8988 const function_type* fn_type = is_function_type(t);
8989 ABG_ASSERT(fn_type);
8990 return fn_type->get_cached_name(internal);
8991 }
8992
8993 const environment&env = d->get_environment();
8994
8995 // All anonymous types of a given kind get to have the same internal
8996 // name for internal purpose. This to allow them to be compared
8997 // among themselves during type canonicalization.
8998 if (internal)
8999 {
9000 if (d->get_is_anonymous())
9001 {
9002 string r;
9003 r += get_generic_anonymous_internal_type_name(d);
9004 return t->get_environment().intern(r);
9005 }
9006
9007 if (is_typedef(t))
9008 return d->get_name();
9009
9010 if (qualified)
9011 return d->get_qualified_name(internal);
9012
9013 return env.intern(get_internal_integral_type_name(t));
9014 }
9015
9016 if (d->get_is_anonymous())
9017 {
9019 return env.intern
9021 /*one_line=*/true,
9022 internal, qualified));
9023 }
9024
9025 if (qualified)
9026 return d->get_qualified_name(internal);
9027 return d->get_name();
9028}
9029
9030/// Get the name of a given type and return a copy of it.
9031///
9032/// @param t the type to consider.
9033///
9034/// @param qualified if true then return the qualified name of the
9035/// type.
9036///
9037/// @param internal set to true if the call is intended for an
9038/// internal use (for technical use inside the library itself), false
9039/// otherwise. If you don't know what this is for, then set it to
9040/// false.
9041///
9042/// @return a copy of the type name if the type has a name, or the
9043/// empty string if it does not.
9045get_type_name(const type_base& t, bool qualified, bool internal)
9046{return get_type_name(&t, qualified, internal);}
9047
9048/// Get the name of the pointer to a given type.
9049///
9050/// @param pointed_to_type the pointed-to-type to consider.
9051///
9052/// @param qualified this is true if the resulting name should be of a
9053/// pointer to a *fully-qualified* pointed-to-type.
9054///
9055/// @param internal true if the name is for libabigail-internal
9056/// purposes.
9057///
9058/// @return the name (string representation) of the pointer.
9061 bool qualified, bool internal)
9062{
9063 const environment& env = pointed_to_type.get_environment();
9064 string tn = get_type_name(pointed_to_type, qualified, internal);
9065 tn = tn + "*";
9066
9067 return env.intern(tn);
9068}
9069
9070/// Get the name of the reference to a given type.
9071///
9072/// @param pointed_to_type the pointed-to-type to consider.
9073///
9074/// @param qualified this is true if the resulting name should be of a
9075/// reference to a *fully-qualified* pointed-to-type.
9076///
9077/// @param internal true if the name is for libabigail-internal
9078/// purposes.
9079///
9080/// @return the name (string representation) of the reference.
9083 bool lvalue_reference,
9084 bool qualified, bool internal)
9085{
9086 const environment& env = pointed_to_type.get_environment();
9087
9088 string name = get_type_name(pointed_to_type, qualified, internal);
9089 if (lvalue_reference)
9090 name = name + "&";
9091 else
9092 name = name + "&&";
9093
9094 return env.intern(name);
9095}
9096
9097/// Get the name of a qualified type, given the underlying type and
9098/// its qualifiers.
9099///
9100/// @param underlying_type the underlying type to consider.
9101///
9102/// @param quals the CV qualifiers of the name.
9103///
9104/// @param qualified true if we should consider the fully qualified
9105/// name of @p underlying_type.
9106///
9107/// @param internal true if the result is to be used for
9108/// libabigail-internal purposes.
9109///
9110/// @return the name (string representation) of the qualified type.
9112get_name_of_qualified_type(const type_base_sptr& underlying_type,
9114 bool qualified, bool internal)
9115{
9116 const environment& env = underlying_type->get_environment();
9117
9118 string quals_repr = get_string_representation_of_cv_quals(quals);
9119 string name = get_type_name(underlying_type, qualified, internal);
9120
9121 if (quals_repr.empty() && internal)
9122 // We are asked to return the internal name, that might be used
9123 // for type canonicalization. For that canonicalization, we need
9124 // to make a difference between a no-op qualified type which
9125 // underlying type is foo (the qualified type is named "none
9126 // foo"), and the name of foo, which is just "foo".
9127 //
9128 // Please remember that this has to be kept in sync with what is
9129 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
9130 // change this code here, please change that code there too.
9131 quals_repr = "";
9132
9133 if (!quals_repr.empty())
9134 {
9135 if (is_pointer_type(peel_qualified_type(underlying_type))
9136 || is_reference_type(peel_qualified_type(underlying_type)))
9137 {
9138 name += " ";
9139 name += quals_repr;
9140 }
9141 else
9142 name = quals_repr + " " + name;
9143 }
9144
9145 return env.intern(name);
9146}
9147
9148/// Get the name of a given function type and return a copy of it.
9149///
9150/// @param fn_type the function type to consider.
9151///
9152/// @param internal set to true if the call is intended for an
9153/// internal use (for technical use inside the library itself), false
9154/// otherwise. If you don't know what this is for, then set it to
9155/// false.
9156///
9157/// @return a copy of the function type name
9160 bool internal)
9161{return get_function_type_name(fn_type.get(), internal);}
9162
9163/// Get the name of a given function type and return a copy of it.
9164///
9165/// @param fn_type the function type to consider.
9166///
9167/// @param internal set to true if the call is intended for an
9168/// internal use (for technical use inside the library itself), false
9169/// otherwise. If you don't know what this is for, then set it to
9170/// false.
9171///
9172/// @return a copy of the function type name
9175 bool internal)
9176{
9177 ABG_ASSERT(fn_type);
9178
9179 if (const method_type* method = is_method_type(fn_type))
9180 return get_method_type_name(method, internal);
9181
9182 return get_function_type_name(*fn_type, internal);
9183}
9184
9185/// Get the name of a given function type and return a copy of it.
9186///
9187/// @param fn_type the function type to consider.
9188///
9189/// @param internal set to true if the call is intended for an
9190/// internal use (for technical use inside the library itself), false
9191/// otherwise. If you don't know what this is for, then set it to
9192/// false.
9193///
9194/// @return a copy of the function type name
9197 bool internal)
9198{
9199 std::ostringstream o;
9200 // When the function name is used for internal purposes (e.g, for
9201 // canonicalization), we want its representation to stay the same,
9202 // regardless of typedefs. So let's strip typedefs from the return
9203 // type.
9204 type_base_sptr return_type =
9205 internal
9207 : fn_type.get_return_type();
9208 const environment& env = fn_type.get_environment();
9209
9210 o << get_pretty_representation(return_type, internal) << " ";
9211 stream_pretty_representation_of_fn_parms(fn_type, o,
9212 /*qualified=*/true,
9213 internal);
9214 return env.intern(o.str());
9215}
9216
9217/// Get the ID of a function, or, if the ID can designate several
9218/// different functions, get its pretty representation.
9219///
9220/// @param fn the function to consider
9221///
9222/// @return the function ID of pretty representation of @p fn.
9225{
9226 ABG_ASSERT(fn);
9227
9228 interned_string result = fn->get_environment().intern(fn->get_id());
9229
9230 if (const corpus *c = fn->get_corpus())
9231 {
9233 c->get_exported_decls_builder();
9234 if (b->fn_id_maps_to_several_fns(fn))
9235 result = fn->get_environment().intern(fn->get_pretty_representation());
9236 }
9237
9238 return result;
9239}
9240
9241/// Get the name of a given method type and return a copy of it.
9242///
9243/// @param fn_type the function type to consider.
9244///
9245/// @param internal set to true if the call is intended for an
9246/// internal use (for technical use inside the library itself), false
9247/// otherwise. If you don't know what this is for, then set it to
9248/// false.
9249///
9250/// @return a copy of the function type name
9253 bool internal)
9254{return get_method_type_name(fn_type.get(), internal);}
9255
9256/// Get the name of a given method type and return a copy of it.
9257///
9258/// @param fn_type the function type to consider.
9259///
9260/// @param internal set to true if the call is intended for an
9261/// internal use (for technical use inside the library itself), false
9262/// otherwise. If you don't know what this is for, then set it to
9263/// false.
9264///
9265/// @return a copy of the function type name
9268 bool internal)
9269{
9270 if (fn_type)
9271 return get_method_type_name(*fn_type, internal);
9272
9273 return interned_string();
9274}
9275
9276/// Get the name of a given method type and return a copy of it.
9277///
9278/// @param fn_type the function type to consider.
9279///
9280/// @param internal set to true if the call is intended for an
9281/// internal use (for technical use inside the library itself), false
9282/// otherwise. If you don't know what this is for, then set it to
9283/// false.
9284///
9285/// @return a copy of the function type name
9288 bool internal)
9289{
9290 std::ostringstream o;
9291 // When the function name is used for internal purposes (e.g, for
9292 // canonicalization), we want its representation to stay the same,
9293 // regardless of typedefs. So let's strip typedefs from the return
9294 // type.
9295 type_base_sptr return_type =
9296 internal
9298 : fn_type.get_return_type();
9299 const environment& env = fn_type.get_environment();
9300
9301 if (return_type)
9302 o << return_type->get_cached_pretty_representation(internal);
9303 else
9304 // There are still some abixml files out there in which "void"
9305 // can be expressed as an empty type.
9306 o << "void";
9307
9308 class_or_union_sptr class_type = fn_type.get_class_type();
9309 ABG_ASSERT(class_type);
9310
9311 o << " (" << class_type->get_qualified_name(internal) << "::*) ";
9312 stream_pretty_representation_of_fn_parms(fn_type, o,
9313 /*qualified=*/true,
9314 internal);
9315
9316 return env.intern(o.str());
9317}
9318
9319/// Build and return a copy of the pretty representation of an ABI
9320/// artifact that could be either a type of a decl.
9321///
9322/// param tod the ABI artifact to consider.
9323///
9324/// @param internal set to true if the call is intended for an
9325/// internal use (for technical use inside the library itself), false
9326/// otherwise. If you don't know what this is for, then set it to
9327/// false.
9328///
9329/// @return a copy of the pretty representation of an ABI artifact
9330/// that could be either a type of a decl.
9331string
9333{
9334 string result;
9335
9336 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9337 result = get_pretty_representation(t, internal);
9338 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9339 result = get_pretty_representation(d, internal);
9340 else
9341 // We should never reach this point
9342 abort();
9343
9344 return result;
9345}
9346
9347/// Build and return a copy of the pretty representation of an ABI
9348/// artifact that could be either a type of a decl.
9349///
9350/// param tod the ABI artifact to consider.
9351///
9352/// @param internal set to true if the call is intended for an
9353/// internal use (for technical use inside the library itself), false
9354/// otherwise. If you don't know what this is for, then set it to
9355/// false.
9356///
9357/// @return a copy of the pretty representation of an ABI artifact
9358/// that could be either a type of a decl.
9359string
9361{return get_pretty_representation(tod.get(), internal);}
9362
9363/// Get a copy of the pretty representation of a decl.
9364///
9365/// @param d the decl to consider.
9366///
9367/// @param internal set to true if the call is intended for an
9368/// internal use (for technical use inside the library itself), false
9369/// otherwise. If you don't know what this is for, then set it to
9370/// false.
9371///
9372/// @return the pretty representation of the decl.
9373string
9374get_pretty_representation(const decl_base* d, bool internal)
9375{
9376 if (!d)
9377 return "";
9378 return d->get_pretty_representation(internal);
9379}
9380
9381/// Get a copy of the pretty representation of a type.
9382///
9383/// @param d the type to consider.
9384///
9385/// @param internal set to true if the call is intended for an
9386/// internal use (for technical use inside the library itself), false
9387/// otherwise. If you don't know what this is for, then set it to
9388/// false.
9389///
9390/// @return the pretty representation of the type.
9391string
9392get_pretty_representation(const type_base* t, bool internal)
9393{
9394 if (!t)
9395 return "void";
9396 if (const function_type* fn_type = is_function_type(t))
9397 return get_pretty_representation(fn_type, internal);
9398
9399 const decl_base* d = get_type_declaration(t);
9400 ABG_ASSERT(d);
9401 return get_pretty_representation(d, internal);
9402}
9403
9404/// Get a copy of the pretty representation of a decl.
9405///
9406/// @param d the decl to consider.
9407///
9408/// @param internal set to true if the call is intended for an
9409/// internal use (for technical use inside the library itself), false
9410/// otherwise. If you don't know what this is for, then set it to
9411/// false.
9412///
9413/// @return the pretty representation of the decl.
9414string
9415get_pretty_representation(const decl_base_sptr& d, bool internal)
9416{return get_pretty_representation(d.get(), internal);}
9417
9418/// Get a copy of the pretty representation of a type.
9419///
9420/// @param d the type to consider.
9421///
9422/// @param internal set to true if the call is intended for an
9423/// internal use (for technical use inside the library itself), false
9424/// otherwise. If you don't know what this is for, then set it to
9425/// false.
9426///
9427/// @return the pretty representation of the type.
9428string
9429get_pretty_representation(const type_base_sptr& t, bool internal)
9430{return get_pretty_representation(t.get(), internal);}
9431
9432/// Get the pretty representation of a function type.
9433///
9434/// @param fn_type the function type to consider.
9435///
9436/// @param internal set to true if the call is intended for an
9437/// internal use (for technical use inside the library itself), false
9438/// otherwise. If you don't know what this is for, then set it to
9439/// false.
9440///
9441/// @return the string represenation of the function type.
9442string
9444 bool internal)
9445{return get_pretty_representation(fn_type.get(), internal);}
9446
9447/// Get the pretty representation of a function type.
9448///
9449/// @param fn_type the function type to consider.
9450///
9451/// @param internal set to true if the call is intended for an
9452/// internal use (for technical use inside the library itself), false
9453/// otherwise. If you don't know what this is for, then set it to
9454/// false.
9455///
9456/// @return the string represenation of the function type.
9457string
9458get_pretty_representation(const function_type* fn_type, bool internal)
9459{
9460 if (!fn_type)
9461 return "void";
9462
9463 if (const method_type* method = is_method_type(fn_type))
9464 return get_pretty_representation(method, internal);
9465
9466 return get_pretty_representation(*fn_type, internal);
9467}
9468
9469/// Get the pretty representation of a function type.
9470///
9471/// @param fn_type the function type to consider.
9472///
9473/// @param internal set to true if the call is intended for an
9474/// internal use (for technical use inside the library itself), false
9475/// otherwise. If you don't know what this is for, then set it to
9476/// false.
9477///
9478/// @return the string represenation of the function type.
9479string
9480get_pretty_representation(const function_type& fn_type, bool internal)
9481{
9482 std::ostringstream o;
9483 o << "function type " << get_function_type_name(fn_type, internal);
9484 return o.str();
9485}
9486
9487/// Get the pretty representation of a method type.
9488///
9489/// @param method the method type to consider.
9490///
9491/// @param internal set to true if the call is intended for an
9492/// internal use (for technical use inside the library itself), false
9493/// otherwise. If you don't know what this is for, then set it to
9494/// false.
9495///
9496/// @return the string represenation of the method type.
9497string
9498get_pretty_representation(const method_type& method, bool internal)
9499{
9500 std::ostringstream o;
9501 o << "method type " << get_method_type_name(method, internal);
9502 return o.str();
9503}
9504
9505/// Get the pretty representation of a method type.
9506///
9507/// @param method the method type to consider.
9508///
9509/// @param internal set to true if the call is intended for an
9510/// internal use (for technical use inside the library itself), false
9511/// otherwise. If you don't know what this is for, then set it to
9512/// false.
9513///
9514/// @return the string represenation of the method type.
9515string
9516get_pretty_representation(const method_type* method, bool internal)
9517{
9518 if (!method)
9519 return "void";
9520 return get_pretty_representation(*method, internal);
9521}
9522
9523/// Get the pretty representation of a method type.
9524///
9525/// @param method the method type to consider.
9526///
9527/// @param internal set to true if the call is intended for an
9528/// internal use (for technical use inside the library itself), false
9529/// otherwise. If you don't know what this is for, then set it to
9530/// false.
9531///
9532/// @return the string represenation of the method type.
9533string
9535{return get_pretty_representation(method.get(), internal);}
9536
9537/// Get the flat representation of an instance of @ref class_or_union
9538/// type.
9539///
9540/// The flat representation of a given @ref class_or_union type is the
9541/// actual definition of the type, for instance:
9542///
9543/// struct foo {int a; char b;}
9544///
9545///@param cou the instance of @ref class_or_union to consider.
9546///
9547///@param indent the identation spaces to use in the representation.
9548///
9549///@param one_line if true, then the flat representation stands on one
9550///line. Otherwise, it stands on multiple lines.
9551///
9552///@return the resulting flat representation.
9553string
9555 const string& indent,
9556 bool one_line,
9557 bool internal,
9558 bool qualified_names)
9559{
9560 string repr;
9561 string local_indent = " ";
9562
9563 if (class_decl* clazz = is_class_type(&cou))
9564 {
9565 repr = indent;
9566 if (!internal && clazz->is_struct())
9567 repr += "struct";
9568 else
9569 repr += "class";
9570 }
9571 else if (is_union_type(cou))
9572 repr = indent + "union";
9573 else
9574 return "";
9575
9576 repr += " ";
9577
9578 string name = cou.get_qualified_name();
9579
9580 if (!cou.get_is_anonymous())
9581 repr += name;
9582
9583 repr += "{";
9584
9585 if (!one_line)
9586 repr += "\n";
9587
9588 string real_indent;
9590 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9591 dm != dmems.end();
9592 ++dm)
9593 {
9594 if (dm != dmems.begin())
9595 {
9596 if (one_line)
9597 real_indent = " ";
9598 else
9599 real_indent = "\n" + indent + local_indent;
9600 }
9601
9603 repr +=
9606 real_indent, one_line, internal, qualified_names);
9607 else
9608 {
9609 if (one_line)
9610 {
9611 if (dm != dmems.begin())
9612 repr += real_indent;
9613 repr += (*dm)->get_pretty_representation(internal,
9614 qualified_names);
9615 }
9616 else
9617 repr +=
9618 real_indent+ (*dm)->get_pretty_representation(internal,
9619 qualified_names);
9620 }
9621 repr += ";";
9622 }
9623
9624 if (one_line)
9625 repr += "}";
9626 else
9627 repr += indent + "}";
9628
9629 return repr;
9630}
9631
9632/// Get the flat representation of an instance of @ref class_or_union
9633/// type.
9634///
9635/// The flat representation of a given @ref class_or_union type is the
9636/// actual definition of the type, for instance:
9637///
9638/// struct foo {int a; char b;}
9639///
9640///@param cou the instance of @ref class_or_union to consider.
9641///
9642///@param indent the identation spaces to use in the representation.
9643///
9644///@param one_line if true, then the flat representation stands on one
9645///line. Otherwise, it stands on multiple lines.
9646///
9647///@return the resulting flat representation.
9648string
9650 const string& indent,
9651 bool one_line,
9652 bool internal,
9653 bool qualified_names)
9654{
9655 if (cou)
9656 return get_class_or_union_flat_representation(*cou, indent, one_line,
9657 internal, qualified_names);
9658 return "";
9659}
9660
9661/// Get the flat representation of an instance of @ref class_or_union
9662/// type.
9663///
9664/// The flat representation of a given @ref class_or_union type is the
9665/// actual definition of the type, for instance:
9666///
9667/// struct foo {int a; char b;}
9668///
9669///@param cou the instance of @ref class_or_union to consider.
9670///
9671///@param indent the identation spaces to use in the representation.
9672///
9673///@param one_line if true, then the flat representation stands on one
9674///line. Otherwise, it stands on multiple lines.
9675///
9676///@return the resulting flat representation.
9677string
9678get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9679 const string& indent,
9680 bool one_line,
9681 bool internal,
9682 bool qualified_names)
9684 indent,
9685 one_line,
9686 internal,
9687 qualified_names);}
9688
9689/// Get the flat representation of an instance of @ref enum_type_decl
9690/// type.
9691///
9692/// The flat representation of a given @ref enum_type_decl type is the
9693/// actual definition of the type, for instance:
9694///
9695/// enum {E_0 =0, E_1 = 1}
9696///
9697///@param enum_type the enum type to consider.
9698///
9699///@param indent the identation spaces to use in the representation.
9700///
9701///@param one_line if true, then the flat representation stands on one
9702///line. Otherwise, it stands on multiple lines.
9703///
9704///@param qualified_names use qualified names when applicable.
9705///Typically, if this is true, the name of the enum is going to be
9706///qualified.
9707///
9708///@return the resulting flat representation.
9709string
9711 const string& indent, bool one_line,
9712 bool qualified_names)
9713{
9714 string repr;
9715 std::ostringstream o;
9716 string local_indent = " ";
9717
9718 repr = indent + "enum ";
9719
9720 if (!enum_type.get_is_anonymous())
9721 o << (qualified_names
9722 ? enum_type.get_qualified_name()
9723 : enum_type.get_name()) + " ";
9724
9725 o << "{";
9726
9727 if (!one_line)
9728 o << "\n";
9729
9730 for (const auto &enumerator : enum_type.get_sorted_enumerators())
9731 {
9732 if (!one_line)
9733 o << "\n" + indent;
9734
9735 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
9736 }
9737
9738 if (!one_line)
9739 o << "\n" + indent << "}";
9740 else
9741 o << "}";
9742
9743 repr =o.str();
9744
9745 return repr;
9746}
9747
9748/// Get the flat representation of an instance of @ref enum_type_decl
9749/// type.
9750///
9751/// The flat representation of a given @ref enum_type_decl type is the
9752/// actual definition of the type, for instance:
9753///
9754/// enum {E_0 =0, E_1 = 1}
9755///
9756///@param enum_type the enum type to consider.
9757///
9758///@param indent the identation spaces to use in the representation.
9759///
9760///@param one_line if true, then the flat representation stands on one
9761///line. Otherwise, it stands on multiple lines.
9762///
9763///@param qualified_names use qualified names when applicable.
9764///Typically, if this is true, the name of the enum is going to be
9765///qualified.
9766///
9767///@return the resulting flat representation.
9768string
9770 const string& indent, bool one_line,
9771 bool qualified_names)
9772{
9773 if (!enum_type)
9774 return "";
9775
9776 return get_enum_flat_representation(*enum_type, indent,
9777 one_line, qualified_names);
9778}
9779
9780/// Get the flat representation of an instance of @ref enum_type_decl
9781/// type.
9782///
9783/// The flat representation of a given @ref enum_type_decl type is the
9784/// actual definition of the type, for instance:
9785///
9786/// enum {E_0 =0, E_1 = 1}
9787///
9788///@param enum_type the enum type to consider.
9789///
9790///@param indent the identation spaces to use in the representation.
9791///
9792///@param one_line if true, then the flat representation stands on one
9793///line. Otherwise, it stands on multiple lines.
9794///
9795///@param qualified_names use qualified names when applicable.
9796///Typically, if this is true, the name of the enum is going to be
9797///qualified.
9798///
9799///@return the resulting flat representation.
9800string
9802 const string& indent, bool one_line,
9803 bool qualified_names)
9804{
9805 return get_enum_flat_representation(enum_type.get(),
9806 indent, one_line,
9807 qualified_names);
9808}
9809
9810/// Get the flat representation of an instance of @ref enum_type_decl
9811/// type.
9812///
9813/// The flat representation of a given @ref enum_type_decl type is the
9814/// actual definition of the type, for instance:
9815///
9816/// enum {E_0 =0, E_1 = 1}
9817///
9818///@param enum_type the enum type to consider.
9819///
9820///@param indent the identation spaces to use in the representation.
9821///
9822///@param one_line if true, then the flat representation stands on one
9823///line. Otherwise, it stands on multiple lines.
9824///
9825///@param qualified_names use qualified names when applicable.
9826///Typically, if this is true, the name of the enum is going to be
9827///qualified.
9828///
9829///@return the resulting flat representation.
9830string
9832 const string& indent,
9833 bool one_line,
9834 bool internal,
9835 bool qualified_name)
9836
9837{
9838 string repr;
9839 if (const class_or_union* cou = is_class_or_union_type(&coe))
9840 repr = get_class_or_union_flat_representation(cou, indent, one_line,
9841 internal, qualified_name);
9842 else if (const enum_type_decl* enom = is_enum_type(&coe))
9843 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9844
9845 return repr;
9846}
9847
9848/// Get the textual representation of a type for debugging purposes.
9849///
9850/// If the type is a class/union, this shows the data members, virtual
9851/// member functions, size, pointer value of its canonical type, etc.
9852/// Otherwise, this just shows the name of the artifact as returned by
9853/// type_or_decl_base:get_pretty_representation().
9854///
9855/// @param artifact the artifact to show a debugging representation of.
9856///
9857/// @return a debugging string representation of @p artifact.
9858string
9860{
9861 if (!artifact)
9862 return string("");
9863
9864 class_or_union * c = is_class_or_union_type(artifact);
9865 if (c)
9866 {
9867 class_decl *clazz = is_class_type(c);
9868 string name = c->get_qualified_name();
9869 std::ostringstream o;
9870 if (clazz)
9871 {
9872 if (clazz->is_struct())
9873 o << "struct ";
9874 else
9875 o << "class ";
9876 }
9877 else if (is_union_type(c))
9878 o << "union ";
9879 o << name;
9880
9881 if (clazz)
9882 {
9883 if (!clazz->get_base_specifiers().empty())
9884 o << " :" << std::endl;
9885 for (auto &b : clazz->get_base_specifiers())
9886 {
9887 o << " ";
9888 if (b->get_is_virtual())
9889 o << "virtual ";
9890 o << b->get_base_class()->get_qualified_name()
9891 << std::endl;
9892 }
9893 }
9894 o << std::endl
9895 << "{"
9896 << " // size in bits: " << c->get_size_in_bits() << "\n"
9897 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9898 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9899 << " // translation unit: " << c->get_translation_unit()->get_absolute_path() << std::endl
9900 << " // @: " << std::hex << is_type(c)
9901 << ", @canonical: " << c->get_canonical_type().get() << std::dec
9902 << "\n\n";
9903
9904 for (auto m : c->get_data_members())
9905 {
9906 type_base_sptr t = m->get_type();
9908
9909 o << " "
9910 << m->get_pretty_representation(/*internal=*/false,
9911 /*qualified=*/false)
9912 << ";";
9913
9914 if (t && t->get_canonical_type())
9915 o << " // uses canonical type '@"
9916 << std::hex << t->get_canonical_type().get() << std::dec;
9917
9918 o << "'" << std::endl;
9919 }
9920
9921 if (clazz && clazz->has_vtable())
9922 {
9923 o << " // virtual member functions\n\n";
9924 for (auto f : clazz->get_virtual_mem_fns())
9925 o << " " << f->get_pretty_representation(/*internal=*/false,
9926 /*qualified=*/false)
9927 << ";" << std::endl;
9928 }
9929
9930 o << "};" << std::endl;
9931
9932 return o.str();
9933 }
9934 else if (const enum_type_decl* e = is_enum_type(artifact))
9935 {
9936 string name = e->get_qualified_name();
9937 std::ostringstream o;
9938 o << "enum " << name
9939 << " : "
9940 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9941 true)
9942 << "\n"
9943 << "{\n"
9944 << " // size in bits: " << e->get_size_in_bits() << "\n"
9945 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9946 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9947 << " // translation unit: "
9948 << e->get_translation_unit()->get_absolute_path() << "\n"
9949 << " // @: " << std::hex << is_type(e)
9950 << ", @canonical: " << e->get_canonical_type().get() << std::dec
9951 << "\n\n";
9952
9953 for (const auto &enom : e->get_enumerators())
9954 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9955
9956 o << "};\n";
9957
9958 return o.str();
9959 }
9960 return artifact->get_pretty_representation(/*internal=*/true,
9961 /*qualified=*/true);
9962}
9963
9964/// Get a given data member, referred to by its name, of a class type.
9965///
9966/// @param clazz the class to consider.
9967///
9968/// @param member_name name of the data member to get.
9969///
9970/// @return the resulting data member or nullptr if none was found.
9972get_data_member(class_or_union *clazz, const char* member_name)
9973{
9974 if (!clazz)
9975 return var_decl_sptr();
9976 return clazz->find_data_member(member_name);
9977}
9978
9979/// Get a given data member, referred to by its name, of a class type.
9980///
9981/// @param clazz the class to consider.
9982///
9983/// @param member_name name of the data member to get.
9984///
9985/// @return the resulting data member or nullptr if none was found.
9987get_data_member(type_base *clazz, const char* member_name)
9988{return get_data_member(is_class_or_union_type(clazz), member_name);}
9989
9990/// Get the non-artificial (natural) location of a decl.
9991///
9992/// If the decl doesn't have a natural location then return its
9993/// artificial one.
9994///
9995/// @param decl the decl to consider.
9996///
9997/// @return the natural location @p decl if it has one; otherwise,
9998/// return its artificial one.
9999const location&
10001{
10002 ABG_ASSERT(decl);
10003
10004 if (decl->get_location())
10005 return decl->get_location();
10006 return decl->get_artificial_location();
10007}
10008
10009/// Get the artificial location of a decl.
10010///
10011/// If the decl doesn't have an artificial location then return its
10012/// natural one.
10013///
10014/// @param decl the decl to consider.
10015///
10016/// @return the artificial location @p decl if it has one; otherwise,
10017/// return its natural one.
10018const location&
10020{
10021 ABG_ASSERT(decl);
10022
10023 if (decl->has_artificial_location())
10024 return decl->get_artificial_location();
10025 return decl->get_location();
10026}
10027
10028/// Emit a textual representation of an artifact to std error stream
10029/// for debugging purposes.
10030///
10031/// This is useful to invoke from within a command line debugger like
10032/// GDB to help make sense of a given ABI artifact.
10033///
10034/// @param artifact the ABI artifact to emit the debugging
10035/// representation for.
10036///
10037/// @return the artifact @p artifact.
10039debug(const type_or_decl_base* artifact)
10040{
10041 std::cerr << get_debug_representation(artifact) << std::endl;
10042 return const_cast<type_or_decl_base*>(artifact);
10043}
10044
10045/// Emit a textual representation of an artifact to std error stream
10046/// for debugging purposes.
10047///
10048/// This is useful to invoke from within a command line debugger like
10049/// GDB to help make sense of a given ABI artifact.
10050///
10051/// @param artifact the ABI artifact to emit the debugging
10052/// representation for.
10053///
10054/// @return the artifact @p artifact.
10055type_base*
10056debug(const type_base* artifact)
10057{
10058 debug(static_cast<const type_or_decl_base*>(artifact));
10059 return const_cast<type_base*>(artifact);
10060}
10061
10062/// Emit a textual representation of an artifact to std error stream
10063/// for debugging purposes.
10064///
10065/// This is useful to invoke from within a command line debugger like
10066/// GDB to help make sense of a given ABI artifact.
10067///
10068/// @param artifact the ABI artifact to emit the debugging
10069/// representation for.
10070///
10071/// @return the artifact @p artifact.
10072decl_base*
10073debug(const decl_base* artifact)
10074{
10075 debug(static_cast<const type_or_decl_base*>(artifact));
10076 return const_cast<decl_base*>(artifact);
10077}
10078
10079/// Test if two ABI artifacts are equal.
10080///
10081/// This can be useful when used from the command line of a debugger
10082/// like GDB.
10083///
10084/// @param l the first ABI artifact to consider in the comparison.
10085///
10086/// @param r the second ABI artifact to consider in the comparison.
10087///
10088/// @return true iff @p l equals @p r.
10089bool
10091{
10092 if (!!l != !!r)
10093 return false;
10094 if (!l && !r)
10095 return true;
10096
10097 return (*l == *r);
10098}
10099
10100/// Emit a trace of a comparison operand stack.
10101///
10102/// @param vect the operand stack to emit the trace for.
10103///
10104/// @param o the output stream to emit the trace to.
10105static void
10106debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
10107{
10108 for (auto t : vect)
10109 {
10110 o << "|" << t->get_pretty_representation()
10111 << "@" << std::hex << t << std::dec;
10112 }
10113 if (!vect.empty())
10114 o << "|";
10115}
10116
10117/// Construct a trace of the two comparison operand stacks.
10118///
10119/// @param the environment in which the comparison operand stacks are.
10120///
10121/// @return a string representing the trace.
10122static string
10123print_comp_stack(const environment& env)
10124{
10125 std::ostringstream o;
10126 o << "left-operands: ";
10127 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
10128 o << "\n" << "right-operands: ";
10129 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10130 o << "\n";
10131 return o.str();
10132}
10133
10134/// Emit a trace of the two comparison operands stack on the standard
10135/// error stream.
10136///
10137/// @param env the environment the comparison operands stack belong
10138/// to.
10139void
10141{
10142 std::cerr << print_comp_stack(env);
10143 std::cerr << std::endl;
10144}
10145
10146/// By looking at the language of the TU a given ABI artifact belongs
10147/// to, test if the ONE Definition Rule should apply.
10148///
10149/// To date, it applies to c++, java and ada.
10150///
10151/// @param artifact the ABI artifact to consider.
10152///
10153/// @return true iff the One Definition Rule should apply.
10154bool
10156{
10158 artifact.get_translation_unit()->get_language();
10159
10161 || is_java_language(l)
10162 || is_ada_language(l))
10163 return true;
10164
10165 return false;
10166}
10167
10168/// Get the declaration for a given type.
10169///
10170/// @param t the type to consider.
10171///
10172/// @return the declaration for the type to return.
10173const decl_base*
10175{return dynamic_cast<const decl_base*>(t);}
10176
10177/// Get the declaration for a given type.
10178///
10179/// @param t the type to consider.
10180///
10181/// @return the declaration for the type to return.
10182decl_base*
10184{return dynamic_cast<decl_base*>(t);}
10185
10186/// Get the declaration for a given type.
10187///
10188/// @param t the type to consider.
10189///
10190/// @return the declaration for the type to return.
10191decl_base_sptr
10192get_type_declaration(const type_base_sptr t)
10193{return dynamic_pointer_cast<decl_base>(t);}
10194
10195/// Test if two types are equal modulo a typedef.
10196///
10197/// Type A and B are compatible if
10198///
10199/// - A and B are equal
10200/// - or if one type is a typedef of the other one.
10201///
10202/// @param type1 the first type to consider.
10203///
10204/// @param type2 the second type to consider.
10205///
10206/// @return true iff @p type1 and @p type2 are compatible.
10207bool
10208types_are_compatible(const type_base_sptr type1,
10209 const type_base_sptr type2)
10210{
10211 if (!type1 || !type2)
10212 return false;
10213
10214 if (type1 == type2)
10215 return true;
10216
10217 // Normally we should strip typedefs entirely, but this is
10218 // potentially costly, especially on binaries with huge changesets
10219 // like the Linux Kernel. So we just get the leaf types for now.
10220 //
10221 // Maybe there should be an option by which users accepts to pay the
10222 // CPU usage toll in exchange for finer filtering?
10223
10224 // type_base_sptr t1 = strip_typedef(type1);
10225 // type_base_sptr t2 = strip_typedef(type2);
10226
10227 type_base_sptr t1 = peel_typedef_type(type1);
10228 type_base_sptr t2 = peel_typedef_type(type2);
10229
10230 return t1 == t2;
10231}
10232
10233/// Test if two types are equal modulo a typedef.
10234///
10235/// Type A and B are compatible if
10236///
10237/// - A and B are equal
10238/// - or if one type is a typedef of the other one.
10239///
10240/// @param type1 the declaration of the first type to consider.
10241///
10242/// @param type2 the declaration of the second type to consider.
10243///
10244/// @return true iff @p type1 and @p type2 are compatible.
10245bool
10246types_are_compatible(const decl_base_sptr d1,
10247 const decl_base_sptr d2)
10248{return types_are_compatible(is_type(d1), is_type(d2));}
10249
10250/// Return the translation unit a declaration belongs to.
10251///
10252/// @param decl the declaration to consider.
10253///
10254/// @return the resulting translation unit, or null if the decl is not
10255/// yet added to a translation unit.
10258{return const_cast<translation_unit*>(decl.get_translation_unit());}
10259
10260/// Return the translation unit a declaration belongs to.
10261///
10262/// @param decl the declaration to consider.
10263///
10264/// @return the resulting translation unit, or null if the decl is not
10265/// yet added to a translation unit.
10268{return decl ? get_translation_unit(*decl) : 0;}
10269
10270/// Return the translation unit a declaration belongs to.
10271///
10272/// @param decl the declaration to consider.
10273///
10274/// @return the resulting translation unit, or null if the decl is not
10275/// yet added to a translation unit.
10277get_translation_unit(const shared_ptr<decl_base> decl)
10278{return get_translation_unit(decl.get());}
10279
10280/// Tests whether if a given scope is the global scope.
10281///
10282/// @param scope the scope to consider.
10283///
10284/// @return true iff the current scope is the global one.
10285bool
10287{return !!dynamic_cast<const global_scope*>(&scope);}
10288
10289/// Tests whether if a given scope is the global scope.
10290///
10291/// @param scope the scope to consider.
10292///
10293/// @return the @ref global_scope* representing the scope @p scope or
10294/// 0 if @p scope is not a global scope.
10295const global_scope*
10297{return dynamic_cast<const global_scope*>(scope);}
10298
10299/// Tests whether if a given scope is the global scope.
10300///
10301/// @param scope the scope to consider.
10302///
10303/// @return true iff the current scope is the global one.
10304bool
10305is_global_scope(const shared_ptr<scope_decl>scope)
10306{return is_global_scope(scope.get());}
10307
10308/// Tests whether a given declaration is at global scope.
10309///
10310/// @param decl the decl to consider.
10311///
10312/// @return true iff decl is at global scope.
10313bool
10315{return (is_global_scope(decl.get_scope()));}
10316
10317/// Tests whether a given declaration is at global scope.
10318///
10319/// @param decl the decl to consider.
10320///
10321/// @return true iff decl is at global scope.
10322bool
10323is_at_global_scope(const decl_base_sptr decl)
10324{return (decl && is_global_scope(decl->get_scope()));}
10325
10326/// Tests whether a given declaration is at global scope.
10327///
10328/// @param decl the decl to consider.
10329///
10330/// @return true iff decl is at global scope.
10331bool
10333{return is_at_global_scope(*decl);}
10334
10335/// Tests whether a given decl is at class scope.
10336///
10337/// @param decl the decl to consider.
10338///
10339/// @return true iff decl is at class scope.
10341is_at_class_scope(const decl_base_sptr decl)
10342{return is_at_class_scope(decl.get());}
10343
10344/// Tests whether a given decl is at class scope.
10345///
10346/// @param decl the decl to consider.
10347///
10348/// @return true iff decl is at class scope.
10351{
10352 if (!decl)
10353 return 0;
10354
10355 return is_at_class_scope(*decl);
10356}
10357
10358/// Tests whether a given decl is at class scope.
10359///
10360/// @param decl the decl to consider.
10361///
10362/// @return true iff decl is at class scope.
10365{
10366 scope_decl* scope = decl.get_scope();
10367 if (class_or_union* cl = is_class_type(scope))
10368 return cl;
10369 if (class_or_union* cl = is_union_type(scope))
10370 return cl;
10371 return 0;
10372}
10373
10374/// Find a data member inside an anonymous data member.
10375///
10376/// An anonymous data member has a type which is a class or union.
10377/// This function looks for a data member inside the type of that
10378/// anonymous data member.
10379///
10380/// @param anon_dm the anonymous data member to consider.
10381///
10382/// @param name the name of the data member to look for.
10385 const string& name)
10386{
10387 const class_or_union* containing_class_or_union =
10389
10390 if (!containing_class_or_union)
10391 return var_decl_sptr();
10392
10393 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10394 return result;
10395}
10396
10397/// Tests whether a given decl is at template scope.
10398///
10399/// Note that only template parameters , types that are compositions,
10400/// and template patterns (function or class) can be at template scope.
10401///
10402/// @param decl the decl to consider.
10403///
10404/// @return true iff the decl is at template scope.
10405bool
10406is_at_template_scope(const shared_ptr<decl_base> decl)
10407{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10408
10409/// Tests whether a decl is a template parameter.
10410///
10411/// @param decl the decl to consider.
10412///
10413/// @return true iff decl is a template parameter.
10414bool
10415is_template_parameter(const shared_ptr<decl_base> decl)
10416{
10417 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10418 || dynamic_pointer_cast<non_type_tparameter>(decl)
10419 || dynamic_pointer_cast<template_tparameter>(decl)));
10420}
10421
10422/// Test whether a declaration is a @ref function_decl.
10423///
10424/// @param d the declaration to test for.
10425///
10426/// @return a shared pointer to @ref function_decl if @p d is a @ref
10427/// function_decl. Otherwise, a nil shared pointer.
10430{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10431
10432/// Test whether a declaration is a @ref function_decl.
10433///
10434/// @param d the declaration to test for.
10435///
10436/// @return true if @p d is a function_decl.
10437bool
10439{return is_function_decl(&d);}
10440
10441/// Test whether a declaration is a @ref function_decl.
10442///
10443/// @param d the declaration to test for.
10444///
10445/// @return a shared pointer to @ref function_decl if @p d is a @ref
10446/// function_decl. Otherwise, a nil shared pointer.
10449{return dynamic_pointer_cast<function_decl>(d);}
10450
10451/// Test whether a declaration is a @ref function_decl.
10452///
10453/// @param d the declaration to test for.
10454///
10455/// @return a pointer to @ref function_decl if @p d is a @ref
10456/// function_decl. Otherwise, a nil shared pointer.
10459{
10460 return dynamic_cast<function_decl::parameter*>
10461 (const_cast<type_or_decl_base*>(tod));
10462}
10463
10464/// Test whether an ABI artifact is a @ref function_decl.
10465///
10466/// @param tod the declaration to test for.
10467///
10468/// @return a pointer to @ref function_decl if @p d is a @ref
10469/// function_decl. Otherwise, a nil shared pointer.
10472{return dynamic_pointer_cast<function_decl::parameter>(tod);}
10473
10474/// Test if an ABI artifact is a declaration.
10475///
10476/// @param d the artifact to consider.
10477///
10478/// @param return the declaration sub-object of @p d if it's a
10479/// declaration, or NULL if it is not.
10480decl_base*
10482{
10483 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10484 {
10485 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10486 // The artifact is a decl-only (like a function or a
10487 // variable). That is, it's not a type that also has a
10488 // declaration. In this case, we are in the fast path and we
10489 // have a pointer to the decl sub-object handy. Just return
10490 // it ...
10491 return reinterpret_cast<decl_base*>
10492 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10493
10494 // ... Otherwise, we are in the slow path, which is that the
10495 // artifact is a type which has a declaration. In that case,
10496 // let's use the slow dynamic_cast because we don't have the
10497 // pointer to the decl sub-object handily present.
10498 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10499 }
10500 return 0;
10501}
10502
10503/// Test if an ABI artifact is a declaration.
10504///
10505/// @param d the artifact to consider.
10506///
10507/// @param return the declaration sub-object of @p d if it's a
10508/// declaration, or NULL if it is not.
10509decl_base_sptr
10511{return dynamic_pointer_cast<decl_base>(d);}
10512
10513/// Test if an ABI artifact is a declaration.
10514///
10515/// This is done using a slow path that uses dynamic_cast.
10516///
10517/// @param d the artifact to consider.
10518///
10519/// @param return the declaration sub-object of @p d if it's a
10520decl_base*
10522{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10523
10524/// Test if an ABI artifact is a declaration.
10525///
10526/// This is done using a slow path that uses dynamic_cast.
10527///
10528/// @param d the artifact to consider.
10529///
10530/// @param return the declaration sub-object of @p d if it's a
10531decl_base_sptr
10533{return dynamic_pointer_cast<decl_base>(t);}
10534
10535/// Test whether a declaration is a type.
10536///
10537/// @param d the IR artefact to test for.
10538///
10539/// @return true if the artifact is a type, false otherwise.
10540bool
10542{
10543 if (dynamic_cast<const type_base*>(&tod))
10544 return true;
10545 return false;
10546}
10547
10548/// Test whether a declaration is a type.
10549///
10550/// @param d the IR artefact to test for.
10551///
10552/// @return true if the artifact is a type, false otherwise.
10553type_base*
10555{
10556 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10557 return reinterpret_cast<type_base*>
10558 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10559
10560 return 0;
10561}
10562
10563/// Test whether a declaration is a type.
10564///
10565/// @param d the IR artefact to test for.
10566///
10567/// @return true if the artifact is a type, false otherwise.
10568type_base_sptr
10570{return dynamic_pointer_cast<type_base>(tod);}
10571
10572/// Test whether a declaration is a type.
10573///
10574/// @param d the declaration to test for.
10575///
10576/// @return true if the declaration is a type, false otherwise.
10577
10578/// Test if a given type is anonymous.
10579///
10580/// Note that this function considers that an anonymous class that is
10581/// named by a typedef is not anonymous anymore. This is the C idiom:
10582///
10583/// typedef struct {int member;} s_type;
10584///
10585/// The typedef s_type becomes the name of the originally anonymous
10586/// struct.
10587///
10588/// @param t the type to consider.
10589///
10590/// @return true iff @p t is anonymous.
10591bool
10593{
10594 const decl_base* d = get_type_declaration(t);
10595 if (d)
10596 if (d->get_is_anonymous())
10597 {
10599 {
10600 // An anonymous class that is named by a typedef is not
10601 // considered anonymous anymore.
10602 if (!cou->get_naming_typedef())
10603 return true;
10604 }
10605 else
10606 return true;
10607 }
10608 return false;
10609}
10610
10611/// Test if a given type is anonymous.
10612///
10613/// @param t the type to consider.
10614///
10615/// @return true iff @p t is anonymous.
10616bool
10617is_anonymous_type(const type_base_sptr& t)
10618{return is_anonymous_type(t.get());}
10619
10620/// Test if a type is a neither a pointer, an array nor a function
10621/// type.
10622///
10623/// @param t the type to consider.
10624///
10625/// @return true if the @p t is NOT a pointer, an array nor a
10626/// function.
10627bool
10628is_npaf_type(const type_base_sptr& t)
10629{
10630 if (!(is_pointer_type(t)
10631 || is_array_type(t)
10632 || is_function_type(t)
10633 || is_ptr_to_mbr_type(t)))
10634 return true;
10635 return false;
10636}
10637
10638/// Test whether a type is a type_decl (a builtin type).
10639///
10640/// @return the type_decl* for @t if it's type_decl, otherwise, return
10641/// nil.
10642const type_decl*
10644{return dynamic_cast<const type_decl*>(t);}
10645
10646/// Test whether a type is a type_decl (a builtin type).
10647///
10648/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10649/// return nil.
10652{return dynamic_pointer_cast<type_decl>(t);}
10653
10654/// Test if a type is an integral type.
10655///
10656/// @param t the type to test.
10657///
10658/// @return the integral type @p t can be converted to, or nil if @p
10659/// is not an integral type.
10660type_decl*
10662{
10663 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10664 if (!type)
10665 return nullptr;
10666
10667 integral_type int_type;
10668 if (!parse_integral_type(type->get_name(), int_type))
10669 return nullptr;
10670
10671 return type;
10672}
10673
10674/// Test if a type is an integral type.
10675///
10676/// @param t the type to test.
10677///
10678/// @return the integral type @p t can be converted to, or nil if @p
10679/// is not an integral type.
10682{
10683 const type_decl_sptr type = is_type_decl(t);
10684 if (!type)
10685 return type_decl_sptr();
10686
10687 integral_type int_type;
10688 if (!parse_integral_type(type->get_name(), int_type))
10689 return type_decl_sptr();
10690
10691 return type;
10692}
10693
10694/// Test whether a type is a typedef.
10695///
10696/// @param t the type to test for.
10697///
10698/// @return the typedef declaration of the @p t, or NULL if it's not a
10699/// typedef.
10702{return dynamic_pointer_cast<typedef_decl>(t);}
10703
10704/// Test whether a type is a typedef.
10705///
10706/// @param t the declaration of the type to test for.
10707///
10708/// @return the typedef declaration of the @p t, or NULL if it's not a
10709/// typedef.
10710const typedef_decl*
10712{return dynamic_cast<const typedef_decl*>(t);}
10713
10714/// Test whether a type is a typedef.
10715///
10716/// @param t the declaration of the type to test for.
10717///
10718/// @return the typedef declaration of the @p t, or NULL if it's not a
10719/// typedef.
10722{return dynamic_cast<typedef_decl*>(t);}
10723
10724/// Test whether a type is a typedef.
10725///
10726/// @param t the declaration of the type to test for.
10727///
10728/// @return the typedef declaration of the @p t, or NULL if it's not a
10729/// typedef.
10730const typedef_decl*
10732{return dynamic_cast<const typedef_decl*>(t);}
10733/// Test if a type is an enum. This function looks through typedefs.
10734///
10735/// @parm t the type to consider.
10736///
10737/// @return the enum_decl if @p t is an @ref enum_decl or null
10738/// otherwise.
10740is_compatible_with_enum_type(const type_base_sptr& t)
10741{
10742 if (!t)
10743 return enum_type_decl_sptr();
10744
10745 // Normally we should strip typedefs entirely, but this is
10746 // potentially costly, especially on binaries with huge changesets
10747 // like the Linux Kernel. So we just get the leaf types for now.
10748 //
10749 // Maybe there should be an option by which users accepts to pay the
10750 // CPU usage toll in exchange for finer filtering?
10751
10752 // type_base_sptr ty = strip_typedef(t);
10753 type_base_sptr ty = peel_typedef_type(t);;
10754 return is_enum_type(ty);
10755}
10756
10757/// Test if a type is an enum. This function looks through typedefs.
10758///
10759/// @parm t the type to consider.
10760///
10761/// @return the enum_decl if @p t is an @ref enum_decl or null
10762/// otherwise.
10764is_compatible_with_enum_type(const decl_base_sptr& t)
10766
10767/// Test if a decl is an enum_type_decl
10768///
10769/// @param d the decl to test for.
10770///
10771/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
10772const enum_type_decl*
10774{return dynamic_cast<const enum_type_decl*>(d);}
10775
10776/// Test if a decl is an enum_type_decl
10777///
10778/// @param d the decl to test for.
10779///
10780/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
10783{return dynamic_pointer_cast<enum_type_decl>(d);}
10784
10785/// Test if a type is a class. This function looks through typedefs.
10786///
10787/// @parm t the type to consider.
10788///
10789/// @return the class_decl if @p t is a class_decl or null otherwise.
10791is_compatible_with_class_type(const type_base_sptr& t)
10792{
10793 if (!t)
10794 return class_decl_sptr();
10795
10796 // Normally we should strip typedefs entirely, but this is
10797 // potentially costly, especially on binaries with huge changesets
10798 // like the Linux Kernel. So we just get the leaf types for now.
10799 //
10800 // Maybe there should be an option by which users accepts to pay the
10801 // CPU usage toll in exchange for finer filtering?
10802
10803 // type_base_sptr ty = strip_typedef(t);
10804 type_base_sptr ty = peel_typedef_type(t);
10805 return is_class_type(ty);
10806}
10807
10808/// Test if a type is a class. This function looks through typedefs.
10809///
10810/// @parm t the type to consider.
10811///
10812/// @return the class_decl if @p t is a class_decl or null otherwise.
10814is_compatible_with_class_type(const decl_base_sptr& t)
10816
10817/// Test whether a type is a class.
10818///
10819/// @parm t the type to consider.
10820///
10821/// @return true iff @p t is a class_decl.
10822bool
10824{return is_class_type(&t);}
10825
10826/// Test whether a type is a class.
10827///
10828/// @parm t the type to consider.
10829///
10830/// @return the class_decl if @p t is a class_decl or null otherwise.
10833{
10834 if (!t)
10835 return 0;
10836
10837 if (t->kind() & type_or_decl_base::CLASS_TYPE)
10838 return reinterpret_cast<class_decl*>
10839 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10840
10841 return 0;
10842}
10843
10844/// Test whether a type is a class.
10845///
10846/// @parm t the type to consider.
10847///
10848/// @return the class_decl if @p t is a class_decl or null otherwise.
10851{return dynamic_pointer_cast<class_decl>(d);}
10852
10853/// Test if the last data member of a class is an array with
10854/// non-finite data member.
10855///
10856/// The flexible data member idiom is a well known C idiom:
10857/// https://en.wikipedia.org/wiki/Flexible_array_member.
10858///
10859/// @param klass the class to consider.
10860///
10861/// @return the data member which type is a flexible array, if any, or
10862/// nil.
10865{
10866 var_decl_sptr nil;
10868 if (dms.empty())
10869 return nil;
10870
10871 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
10872 {// The type of the last data member is an array.
10873 if (array->is_non_finite())
10874 // The array has a non-finite size. We are thus looking at a
10875 // flexible array data member. Let's return it.
10876 return dms.back();
10877 }
10878
10879 return nil;
10880}
10881
10882/// Test if the last data member of a class is an array with
10883/// non-finite data member.
10884///
10885/// The flexible data member idiom is a well known C idiom:
10886/// https://en.wikipedia.org/wiki/Flexible_array_member.
10887///
10888/// @param klass the class to consider.
10889///
10890/// @return the data member which type is a flexible array, if any, or
10891/// nil.
10894{
10895 if (!klass)
10896 return var_decl_sptr();
10897
10898 return has_flexible_array_data_member(*klass);
10899}
10900
10901/// Test if the last data member of a class is an array with
10902/// non-finite data member.
10903///
10904/// The flexible data member idiom is a well known C idiom:
10905/// https://en.wikipedia.org/wiki/Flexible_array_member.
10906///
10907/// @param klass the class to consider.
10908///
10909/// @return the data member which type is a flexible array, if any, or
10910/// nil.
10913{return has_flexible_array_data_member(klass.get());}
10914
10915/// Test if the last data member of a class is an array with
10916/// one element.
10917///
10918/// An array with one element is a way to mimic the flexible data
10919/// member idiom that was later standardized in C99.
10920///
10921/// To learn more about the flexible data member idiom, please
10922/// consider reading :
10923/// https://en.wikipedia.org/wiki/Flexible_array_member.
10924///
10925/// The various ways of representing that idiom pre-standardization
10926/// are presented in this article:
10927/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10928///
10929/// @param klass the class to consider.
10930///
10931/// @return the data member which type is a fake flexible array, if
10932/// any, or nil.
10935{
10936 var_decl_sptr nil;
10938 if (dms.empty())
10939 return nil;
10940
10941 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
10942 {// The type of the last data member is an array.
10943 if (array->get_subranges().size() == 1
10944 && array->get_subranges()[0]->get_length() == 1)
10945 // The array has a size of one. We are thus looking at a
10946 // "fake" flexible array data member. Let's return it.
10947 return dms.back();
10948 }
10949
10950 return nil;
10951}
10952
10953/// Test if the last data member of a class is an array with
10954/// one element.
10955///
10956/// An array with one element is a way to mimic the flexible data
10957/// member idiom that was later standardized in C99.
10958///
10959/// To learn more about the flexible data member idiom, please
10960/// consider reading :
10961/// https://en.wikipedia.org/wiki/Flexible_array_member.
10962///
10963/// The various ways of representing that idiom pre-standardization
10964/// are presented in this article:
10965/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10966///
10967/// @param klass the class to consider.
10968///
10969/// @return the data member which type is a fake flexible array, if
10970/// any, or nil.
10974
10975/// Test if the last data member of a class is an array with
10976/// one element.
10977///
10978/// An array with one element is a way to mimic the flexible data
10979/// member idiom that was later standardized in C99.
10980///
10981/// To learn more about the flexible data member idiom, please
10982/// consider reading :
10983/// https://en.wikipedia.org/wiki/Flexible_array_member.
10984///
10985/// The various ways of representing that idiom pre-standardization
10986/// are presented in this article:
10987/// https://developers.redhat.com/articles/2022/09/29/benefits-limitations-flexible-array-members#
10988///
10989/// @param klass the class to consider.
10990///
10991/// @return the data member which type is a fake flexible array, if
10992/// any, or nil.
10995{return has_fake_flexible_array_data_member(klass.get());}
10996
10997/// Test wheter a type is a declaration-only class.
10998///
10999/// @param t the type to considier.
11000///
11001/// @param look_through_decl_only if true, then look through the
11002/// decl-only class to see if it actually has a class definition in
11003/// the same ABI corpus.
11004///
11005/// @return true iff @p t is a declaration-only class.
11006bool
11009{
11010 if (class_or_union *klass = is_class_or_union_type(t))
11011 {
11013 klass = look_through_decl_only_class(klass);
11014 return klass->get_is_declaration_only();
11015 }
11016 return false;
11017}
11018
11019/// Test wheter a type is a declaration-only class.
11020///
11021/// @param t the type to considier.
11022///
11023/// @param look_through_decl_only if true, then look through the
11024/// decl-only class to see if it actually has a class definition in
11025/// the same ABI corpus.
11026///
11027/// @return true iff @p t is a declaration-only class.
11028bool
11032
11033/// Test wheter a type is a declaration-only class.
11034///
11035/// @param t the type to considier.
11036///
11037/// @param look_through_decl_only if true, then look through the
11038/// decl-only class to see if it actually has a class definition in
11039/// the same ABI corpus.
11040///
11041/// @return true iff @p t is a declaration-only class.
11042bool
11043is_declaration_only_class_type(const type_base_sptr& t,
11046
11047/// Test if a type is a @ref class_or_union.
11048///
11049/// @param t the type to consider.
11050///
11051/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11052/// nil otherwise.
11055{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
11056
11057/// Test if a type is a @ref class_or_union.
11058///
11059/// @param t the type to consider.
11060///
11061/// @return the @ref class_or_union is @p is a @ref class_or_union, or
11062/// nil otherwise.
11063shared_ptr<class_or_union>
11064is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
11065{return dynamic_pointer_cast<class_or_union>(t);}
11066
11067/// Test if two class or union types are of the same kind.
11068///
11069/// @param first the first type to consider.
11070///
11071/// @param second the second type to consider.
11072///
11073/// @return true iff @p first is of the same kind as @p second.
11074bool
11076 const class_or_union* second)
11077{
11078 if ((is_class_type(first) && is_class_type(second))
11079 || (is_union_type(first) && is_union_type(second)))
11080 return true;
11081
11082 return false;
11083}
11084
11085/// Test if two class or union types are of the same kind.
11086///
11087/// @param first the first type to consider.
11088///
11089/// @param second the second type to consider.
11090///
11091/// @return true iff @p first is of the same kind as @p second.
11092bool
11093class_or_union_types_of_same_kind(const class_or_union_sptr& first,
11094 const class_or_union_sptr& second)
11095{return class_or_union_types_of_same_kind(first.get(), second.get());}
11096
11097/// Test if a type is a @ref union_decl.
11098///
11099/// @param t the type to consider.
11100///
11101/// @return true iff @p t is a union_decl.
11102bool
11104{return is_union_type(&t);}
11105
11106/// Test if a type is a @ref union_decl.
11107///
11108/// @param t the type to consider.
11109///
11110/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11111/// otherwise.
11114{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
11115
11116/// Test if a type is a @ref union_decl.
11117///
11118/// @param t the type to consider.
11119///
11120/// @return the @ref union_decl is @p is a @ref union_decl, or nil
11121/// otherwise.
11122union_decl_sptr
11123is_union_type(const shared_ptr<type_or_decl_base>& t)
11124{return dynamic_pointer_cast<union_decl>(t);}
11125
11126/// Test whether a type is a pointer_type_def.
11127///
11128/// @param t the type to test.
11129///
11130/// @param look_through_decl_only if this is true, then look through
11131/// qualified types to see if the underlying type is a
11132/// pointer_type_def.
11133///
11134/// @return the @ref pointer_type_def_sptr if @p t is a
11135/// pointer_type_def, null otherwise.
11136const pointer_type_def*
11138 bool look_through_qualifiers)
11139{
11140 if (!t)
11141 return 0;
11142
11143 const type_base* type = is_type(t);
11144 if (look_through_qualifiers)
11145 type = peel_qualified_type(is_type(t));
11146
11147 return dynamic_cast<pointer_type_def*>(const_cast<type_base*>(type));
11148}
11149
11150/// Test whether a type is a pointer_type_def.
11151///
11152/// @param t the type to test.
11153///
11154/// @param look_through_decl_only if this is true, then look through
11155/// qualified types to see if the underlying type is a
11156/// pointer_type_def.
11157///
11158/// @return the @ref pointer_type_def_sptr if @p t is a
11159/// pointer_type_def, null otherwise.
11162 bool look_through_qualifiers)
11163{
11164 type_base_sptr type = is_type(t);
11165 if (look_through_qualifiers)
11166 type = peel_qualified_type(type);
11167 return dynamic_pointer_cast<pointer_type_def>(type);
11168}
11169
11170/// Test if a type is a pointer to function type.
11171///
11172/// @param t the type to consider.
11173///
11174/// @return the @ref pointer_type_def_sptr iff @p t is a pointer to
11175/// function type.
11177is_pointer_to_function_type(const type_base_sptr& t)
11178{
11180 {
11181 if (is_function_type(p->get_pointed_to_type()))
11182 return p;
11183 }
11184 return pointer_type_def_sptr();
11185}
11186
11187/// Test if a type is a pointer to array type.
11188///
11189/// @param t the type to consider.
11190///
11191/// @return the pointer_type_def_sptr iff @p t is a pointer to array
11192/// type.
11194is_pointer_to_array_type(const type_base_sptr& t)
11195{
11197 {
11198 if (is_array_type(p->get_pointed_to_type()))
11199 return p;
11200 }
11201 return pointer_type_def_sptr();
11202}
11203
11204/// Test if we are looking at a pointer to a
11205/// neither-a-pointer-to-an-array-nor-a-function type.
11206///
11207/// @param t the type to consider.
11208///
11209/// @return the @ref pointer_type_def_sptr type iff @p t is a
11210/// neither-a-pointer-an-array-nor-a-function type.
11212is_pointer_to_npaf_type(const type_base_sptr& t)
11213{
11215 {
11216 if (is_npaf_type(p->get_pointed_to_type()))
11217 return p;
11218 }
11219 return pointer_type_def_sptr();
11220}
11221
11222/// Test if we are looking at a pointer to pointer to member type.
11223///
11224/// @param t the type to consider.
11225///
11226/// @return the @ref pointer_type_def_sptr type iff @p t is a pointer
11227/// to pointer to member type.
11229is_pointer_to_ptr_to_mbr_type(const type_base_sptr& t)
11230{
11232 {
11233 if (is_ptr_to_mbr_type(p->get_pointed_to_type()))
11234 return p;
11235 }
11236 return pointer_type_def_sptr();
11237}
11238
11239/// Test if a type is a typedef, pointer or reference to a decl-only
11240/// class/union.
11241///
11242/// This looks into qualified types too.
11243///
11244/// @param t the type to consider.
11245///
11246/// @return true iff @p t is a type is a typedef, pointer or reference
11247/// to a decl-only class/union.
11248bool
11250{
11251 const type_base * type =
11252 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11253
11255 /*look_through_decl_only=*/true))
11256 return true;
11257
11258 return false;
11259}
11260
11261/// Test if a type is a typedef of a class or union type, or a typedef
11262/// of a qualified class or union type.
11263///
11264/// Note that if the type is directly a class or union type, the
11265/// function returns true as well.
11266///
11267/// @param t the type to consider.
11268///
11269/// @return true iff @p t is a typedef of a class or union type, or a
11270/// typedef of a qualified class or union type.
11271bool
11273{
11274 if (!t)
11275 return false;
11276
11279 return true;
11280
11281return false;
11282}
11283
11284/// Test if a type is a typedef of a class or union type, or a typedef
11285/// of a qualified class or union type.
11286///
11287/// Note that if the type is directly a class or union type, the
11288/// function returns true as well.
11289///
11290/// @param t the type to consider.
11291///
11292/// @return true iff @p t is a typedef of a class or union type, or a
11293/// typedef of a qualified class or union type.
11294bool
11297
11298/// Test whether a type is a reference_type_def.
11299///
11300/// @param t the type to test.
11301///
11302/// @param look_through_decl_only if this is true, then look through
11303/// qualified types to see if the underlying type is a
11304/// reference_type_def.
11305///
11306/// @return the @ref reference_type_def_sptr if @p t is a
11307/// reference_type_def, null otherwise.
11310 bool look_through_qualifiers)
11311{
11312 const type_base* type = is_type(t);
11313 if (!type)
11314 return nullptr;
11315
11316 if (look_through_qualifiers)
11317 type = peel_qualified_type(type);
11318 return dynamic_cast<reference_type_def*>(const_cast<type_base*>(type));
11319}
11320
11321/// Test whether a type is a reference_type_def.
11322///
11323/// @param t the type to test.
11324///
11325/// @param look_through_decl_only if this is true, then look through
11326/// qualified types to see if the underlying type is a
11327/// reference_type_def.
11328///
11329/// @return the @ref reference_type_def_sptr if @p t is a
11330/// reference_type_def, null otherwise.
11331const reference_type_def*
11333 bool look_through_qualifiers)
11334{
11335 const type_base* type = is_type(t);
11336
11337 if (look_through_qualifiers)
11338 type = peel_qualified_type(type);
11339 return dynamic_cast<const reference_type_def*>(type);
11340}
11341
11342/// Test whether a type is a reference_type_def.
11343///
11344/// @param t the type to test.
11345///
11346/// @param look_through_decl_only if this is true, then look through
11347/// qualified types to see if the underlying type is a
11348/// reference_type_def.
11349///
11350/// @return the @ref reference_type_def_sptr if @p t is a
11351/// reference_type_def, null otherwise.
11354 bool look_through_qualifiers)
11355{
11356 type_base_sptr type = is_type(t);
11357 if (look_through_qualifiers)
11358 type = peel_qualified_type(type);
11359 return dynamic_pointer_cast<reference_type_def>(type);
11360}
11361
11362/// Test whether a type is a @ref ptr_to_mbr_type.
11363///
11364/// @param t the type to test.
11365///
11366/// @return the @ref ptr_to_mbr_type* if @p t is a @ref
11367/// ptr_to_mbr_type type, null otherwise.
11368const ptr_to_mbr_type*
11370 bool look_through_qualifiers)
11371{
11372 const type_base* type = is_type(t);
11373 if (look_through_qualifiers)
11374 type = peel_qualified_type(type);
11375 return dynamic_cast<const ptr_to_mbr_type*>(type);
11376}
11377
11378/// Test whether a type is a @ref ptr_to_mbr_type_sptr.
11379///
11380/// @param t the type to test.
11381///
11382/// @param look_through_decl_only if this is true, then look through
11383/// qualified types to see if the underlying type is a
11384/// ptr_to_mbr_type..
11385///
11386/// @return the @ref ptr_to_mbr_type_sptr if @p t is a @ref
11387/// ptr_to_mbr_type type, null otherwise.
11390 bool look_through_qualifiers)
11391{
11392 type_base_sptr type = is_type(t);
11393 if (look_through_qualifiers)
11394 type = peel_qualified_type(type);
11395 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
11396}
11397
11398/// Test if a type is equivalent to a pointer to void type.
11399///
11400/// Note that this looks trough typedefs or CV qualifiers to look for
11401/// the void pointer.
11402///
11403/// @param type the type to consider.
11404///
11405/// @return the actual void pointer if @p is eqivalent to a void
11406/// pointer or NULL if it's not.
11407const type_base*
11409{
11410 type = peel_qualified_or_typedef_type(type);
11411
11412 const pointer_type_def * t = is_pointer_type(type);
11413 if (!t)
11414 return 0;
11415
11416 // Look through typedefs in the pointed-to type as well.
11417 type_base * ty = t->get_pointed_to_type().get();
11419 if (ty && ty->get_environment().is_void_type(ty))
11420 return ty;
11421
11422 return 0;
11423}
11424
11425/// Test if a type is equivalent to a pointer to void type.
11426///
11427/// Note that this looks trough typedefs or CV qualifiers to look for
11428/// the void pointer.
11429///
11430/// @param type the type to consider.
11431///
11432/// @return the actual void pointer if @p is eqivalent to a void
11433/// pointer or NULL if it's not.
11434const type_base*
11436{return is_void_pointer_type_equivalent(&type);}
11437
11438/// Test if a type is a pointer to void type.
11439///
11440/// @param type the type to consider.
11441///
11442/// @return the actual void pointer if @p is a void pointer or NULL if
11443/// it's not.
11444const type_base*
11446{
11447 if (!t)
11448 return nullptr;
11449
11450 if (t->get_environment().get_void_pointer_type().get() == t)
11451 return t;
11452
11453 const pointer_type_def* ptr = is_pointer_type(t);
11454 if (!ptr)
11455 return nullptr;
11456
11458 return t;
11459
11460 return nullptr;
11461}
11462
11463/// Test if a type is a pointer to void type.
11464///
11465/// @param type the type to consider.
11466///
11467/// @return the actual void pointer if @p is a void pointer or NULL if
11468/// it's not.
11469const type_base_sptr
11470is_void_pointer_type(const type_base_sptr& t)
11471{
11472 type_base_sptr nil;
11473 if (!t)
11474 return nil;
11475
11476 if (t->get_environment().get_void_pointer_type().get() == t.get())
11477 return t;
11478
11479 const pointer_type_def* ptr = is_pointer_type(t.get());
11480 if (!ptr)
11481 return nil;
11482
11483 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11484 return t;
11485
11486 return nil;
11487}
11488
11489/// Test whether a type is a reference_type_def.
11490///
11491/// @param t the type to test.
11492///
11493/// @return the @ref reference_type_def_sptr if @p t is a
11494/// reference_type_def, null otherwise.
11497{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11498
11499/// Test whether a type is a qualified_type_def.
11500///
11501/// @param t the type to test.
11502///
11503/// @return the @ref qualified_type_def_sptr if @p t is a
11504/// qualified_type_def, null otherwise.
11505qualified_type_def_sptr
11507{return dynamic_pointer_cast<qualified_type_def>(t);}
11508
11509/// Test whether a type is a function_type.
11510///
11511/// @param t the type to test.
11512///
11513/// @return the @ref function_type_sptr if @p t is a
11514/// function_type, null otherwise.
11517{return dynamic_pointer_cast<function_type>(t);}
11518
11519/// Test whether a type is a function_type.
11520///
11521/// @param t the type to test.
11522///
11523/// @return the @ref function_type_sptr if @p t is a
11524/// function_type, null otherwise.
11527{return dynamic_cast<function_type*>(t);}
11528
11529/// Test whether a type is a function_type.
11530///
11531/// @param t the type to test.
11532///
11533/// @return the @ref function_type_sptr if @p t is a
11534/// function_type, null otherwise.
11535const function_type*
11537{return dynamic_cast<const function_type*>(t);}
11538
11539/// Test whether a type is a method_type.
11540///
11541/// @param t the type to test.
11542///
11543/// @return the @ref method_type_sptr if @p t is a
11544/// method_type, null otherwise.
11547{return dynamic_pointer_cast<method_type>(t);}
11548
11549/// Test whether a type is a method_type.
11550///
11551/// @param t the type to test.
11552///
11553/// @return the @ref method_type_sptr if @p t is a
11554/// method_type, null otherwise.
11555const method_type*
11557{return dynamic_cast<const method_type*>(t);}
11558
11559/// Test whether a type is a method_type.
11560///
11561/// @param t the type to test.
11562///
11563/// @return the @ref method_type_sptr if @p t is a
11564/// method_type, null otherwise.
11567{return dynamic_cast<method_type*>(t);}
11568
11569/// If a class (or union) is a decl-only class, get its definition.
11570/// Otherwise, just return the initial class.
11571///
11572/// @param the_class the class (or union) to consider.
11573///
11574/// @return either the definition of the class, or the class itself.
11578
11579/// If a class (or union) is a decl-only class, get its definition.
11580/// Otherwise, just return the initial class.
11581///
11582/// @param the_class the class (or union) to consider.
11583///
11584/// @return either the definition of the class, or the class itself.
11585class_or_union_sptr
11588
11589/// If a class (or union) is a decl-only class, get its definition.
11590/// Otherwise, just return the initial class.
11591///
11592/// @param klass the class (or union) to consider.
11593///
11594/// @return either the definition of the class, or the class itself.
11595class_or_union_sptr
11596look_through_decl_only_class(class_or_union_sptr klass)
11598
11599/// If an enum is a decl-only enum, get its definition.
11600/// Otherwise, just return the initial enum.
11601///
11602/// @param the_enum the enum to consider.
11603///
11604/// @return either the definition of the enum, or the enum itself.
11607{return is_enum_type(look_through_decl_only(the_enum));}
11608
11609/// If an enum is a decl-only enum, get its definition.
11610/// Otherwise, just return the initial enum.
11611///
11612/// @param enom the enum to consider.
11613///
11614/// @return either the definition of the enum, or the enum itself.
11617{return is_enum_type(look_through_decl_only(enom));}
11618
11619/// If a decl is decl-only get its definition. Otherwise, just return nil.
11620///
11621/// @param d the decl to consider.
11622///
11623/// @return either the definition of the decl, or nil.
11624decl_base_sptr
11626{
11627 decl_base_sptr decl;
11630
11631 if (!decl)
11632 return decl;
11633
11634 while (decl->get_is_declaration_only()
11635 && decl->get_definition_of_declaration())
11636 decl = decl->get_definition_of_declaration();
11637
11638 return decl;
11639}
11640
11641/// If a decl is decl-only enum, get its definition. Otherwise, just
11642/// return the initial decl.
11643///
11644/// @param d the decl to consider.
11645///
11646/// @return either the definition of the enum, or the decl itself.
11647decl_base*
11649{
11650 if (!d)
11651 return d;
11652
11653 decl_base* result = look_through_decl_only(*d).get();
11654 if (!result)
11655 result = d;
11656
11657 return result;
11658}
11659
11660/// If a decl is decl-only get its definition. Otherwise, just return nil.
11661///
11662/// @param d the decl to consider.
11663///
11664/// @return either the definition of the decl, or nil.
11665decl_base_sptr
11666look_through_decl_only(const decl_base_sptr& d)
11667{
11668 if (!d)
11669 return d;
11670
11671 decl_base_sptr result = look_through_decl_only(*d);
11672 if (!result)
11673 result = d;
11674
11675 return result;
11676}
11677
11678/// If a type is is decl-only, then get its definition. Otherwise,
11679/// just return the initial type.
11680///
11681/// @param d the decl to consider.
11682///
11683/// @return either the definition of the decl, or the initial type.
11684type_base*
11686{
11687 decl_base* d = is_decl(t);
11688 if (!d)
11689 return t;
11691 return is_type(d);
11692}
11693
11694/// If a type is is decl-only, then get its definition. Otherwise,
11695/// just return the initial type.
11696///
11697/// @param d the decl to consider.
11698///
11699/// @return either the definition of the decl, or the initial type.
11700type_base_sptr
11701look_through_decl_only(const type_base_sptr& t)
11702{
11703 decl_base_sptr d = is_decl(t);
11704 if (!d)
11705 return t;
11707 return is_type(d);
11708}
11709
11710/// Tests if a declaration is a variable declaration.
11711///
11712/// @param decl the decl to test.
11713///
11714/// @return the var_decl_sptr iff decl is a variable declaration; nil
11715/// otherwise.
11716var_decl*
11718{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
11719
11720/// Tests if a declaration is a variable declaration.
11721///
11722/// @param decl the decl to test.
11723///
11724/// @return the var_decl_sptr iff decl is a variable declaration; nil
11725/// otherwise.
11728{return dynamic_pointer_cast<var_decl>(decl);}
11729
11730/// Tests if a declaration is a namespace declaration.
11731///
11732/// @param d the decalration to consider.
11733///
11734/// @return the namespace declaration if @p d is a namespace.
11736is_namespace(const decl_base_sptr& d)
11737{return dynamic_pointer_cast<namespace_decl>(d);}
11738
11739/// Tests if a declaration is a namespace declaration.
11740///
11741/// @param d the decalration to consider.
11742///
11743/// @return the namespace declaration if @p d is a namespace.
11746{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
11747
11748/// Tests whether a decl is a template parameter composition type.
11749///
11750/// @param decl the declaration to consider.
11751///
11752/// @return true iff decl is a template parameter composition type.
11753bool
11754is_template_parm_composition_type(const shared_ptr<decl_base> decl)
11755{
11756 return (decl
11757 && is_at_template_scope(decl)
11758 && is_type(decl)
11759 && !is_template_parameter(decl));
11760}
11761
11762/// Test whether a decl is the pattern of a function template.
11763///
11764/// @param decl the decl to consider.
11765///
11766/// @return true iff decl is the pattern of a function template.
11767bool
11768is_function_template_pattern(const shared_ptr<decl_base> decl)
11769{
11770 return (decl
11771 && dynamic_pointer_cast<function_decl>(decl)
11772 && dynamic_cast<template_decl*>(decl->get_scope()));
11773}
11774
11775/// Test if a type is an array_type_def.
11776///
11777/// @param type the type to consider.
11778///
11779/// @return true iff @p type is an array_type_def.
11782 bool look_through_qualifiers)
11783{
11784 const type_base* t = is_type(type);
11785
11786 if (look_through_qualifiers)
11787 t = peel_qualified_type(t);
11788 return dynamic_cast<array_type_def*>(const_cast<type_base*>(t));
11789}
11790
11791/// Test if a type is an array_type_def.
11792///
11793/// @param type the type to consider.
11794///
11795/// @return true iff @p type is an array_type_def.
11798 bool look_through_qualifiers)
11799{
11800 type_base_sptr t = is_type(type);
11801
11802 if (look_through_qualifiers)
11803 t = peel_qualified_type(t);
11804 return dynamic_pointer_cast<array_type_def>(t);
11805}
11806
11807/// Tests if the element of a given array is a qualified type.
11808///
11809/// @param array the array type to consider.
11810///
11811/// @return the qualified element of the array iff it's a qualified
11812/// type. Otherwise, return a nil object.
11813qualified_type_def_sptr
11815{
11816 if (!array)
11817 return qualified_type_def_sptr();
11818
11819 return is_qualified_type(array->get_element_type());
11820}
11821
11822/// Test if an array type is an array to a qualified element type.
11823///
11824/// @param type the array type to consider.
11825///
11826/// @return true the array @p type iff it's an array to a qualified
11827/// element type.
11829is_array_of_qualified_element(const type_base_sptr& type)
11830{
11831 if (array_type_def_sptr array = is_array_type(type))
11833 return array;
11834
11835 return array_type_def_sptr();
11836}
11837
11838/// Test if a type is a typedef of an array.
11839///
11840/// Note that the function looks through qualified and typedefs types
11841/// of the underlying type of the current typedef. In other words, if
11842/// we are looking at a typedef of a CV-qualified array, or at a
11843/// typedef of a CV-qualified typedef of an array, this function will
11844/// still return TRUE.
11845///
11846/// @param t the type to consider.
11847///
11848/// @return true if t is a typedef which underlying type is an array.
11849/// That array might be either cv-qualified array or a typedef'ed
11850/// array, or a combination of both.
11852is_typedef_of_array(const type_base_sptr& t)
11853{
11854 array_type_def_sptr result;
11855
11856 if (typedef_decl_sptr typdef = is_typedef(t))
11857 {
11858 type_base_sptr u =
11859 peel_qualified_or_typedef_type(typdef->get_underlying_type());
11860 result = is_array_type(u);
11861 }
11862
11863 return result;
11864}
11865
11866/// Test if a type is an array_type_def::subrange_type.
11867///
11868/// @param type the type to consider.
11869///
11870/// @return the array_type_def::subrange_type which @p type is a type
11871/// of, or nil if it's not of that type.
11872array_type_def::subrange_type*
11874{
11875 return dynamic_cast<array_type_def::subrange_type*>
11876 (const_cast<type_or_decl_base*>(type));
11877}
11878
11879/// Test if a type is an array_type_def::subrange_type.
11880///
11881/// @param type the type to consider.
11882///
11883/// @return the array_type_def::subrange_type which @p type is a type
11884/// of, or nil if it's not of that type.
11887{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
11888
11889/// Tests whether a decl is a template.
11890///
11891/// @param decl the decl to consider.
11892///
11893/// @return true iff decl is a function template, class template, or
11894/// template template parameter.
11895bool
11896is_template_decl(const decl_base_sptr& decl)
11897{return decl && dynamic_pointer_cast<template_decl>(decl);}
11898
11899/// This enum describe the kind of entity to lookup, while using the
11900/// lookup API.
11902{
11903 LOOKUP_ENTITY_TYPE,
11904 LOOKUP_ENTITY_VAR,
11905};
11906
11907/// Find the first relevant delimiter (the "::" string) in a fully
11908/// qualified C++ type name, starting from a given position. The
11909/// delimiter returned separates a type name from the name of its
11910/// context.
11911///
11912/// This is supposed to work correctly on names in cases like this:
11913///
11914/// foo<ns1::name1, ns2::name2>
11915///
11916/// In that case when called with with parameter @p begin set to 0, no
11917/// delimiter is returned, because the type name in this case is:
11918/// 'foo<ns1::name1, ns2::name2>'.
11919///
11920/// But in this case:
11921///
11922/// foo<p1, bar::name>::some_type
11923///
11924/// The "::" returned is the one right before 'some_type'.
11925///
11926/// @param fqn the fully qualified name of the type to consider.
11927///
11928/// @param begin the position from which to look for the delimiter.
11929///
11930/// @param delim_pos out parameter. Is set to the position of the
11931/// delimiter iff the function returned true.
11932///
11933/// @return true iff the function found and returned the delimiter.
11934static bool
11935find_next_delim_in_cplus_type(const string& fqn,
11936 size_t begin,
11937 size_t& delim_pos)
11938{
11939 int angle_count = 0;
11940 bool found = false;
11941 size_t i = begin;
11942 for (; i < fqn.size(); ++i)
11943 {
11944 if (fqn[i] == '<')
11945 ++angle_count;
11946 else if (fqn[i] == '>')
11947 --angle_count;
11948 else if (i + 1 < fqn.size()
11949 && !angle_count
11950 && fqn[i] == ':'
11951 && fqn[i+1] == ':')
11952 {
11953 delim_pos = i;
11954 found = true;
11955 break;
11956 }
11957 }
11958 return found;
11959}
11960
11961/// Decompose a fully qualified name into the list of its components.
11962///
11963/// @param fqn the fully qualified name to decompose.
11964///
11965/// @param comps the resulting list of component to fill.
11966void
11967fqn_to_components(const string& fqn,
11968 list<string>& comps)
11969{
11970 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
11971 do
11972 {
11973 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
11974 comp_end = fqn_size;
11975
11976 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
11977 comps.push_back(comp);
11978
11979 comp_begin = comp_end + 2;
11980 if (comp_begin >= fqn_size)
11981 break;
11982 } while (true);
11983}
11984
11985/// Turn a set of qualified name components (that name a type) into a
11986/// qualified name string.
11987///
11988/// @param comps the name components
11989///
11990/// @return the resulting string, which would be the qualified name of
11991/// a type.
11992string
11993components_to_type_name(const list<string>& comps)
11994{
11995 string result;
11996 for (list<string>::const_iterator c = comps.begin();
11997 c != comps.end();
11998 ++c)
11999 if (c == comps.begin())
12000 result = *c;
12001 else
12002 result += "::" + *c;
12003 return result;
12004}
12005
12006/// This predicate returns true if a given container iterator points
12007/// to the last element of the container, false otherwise.
12008///
12009/// @tparam T the type of the container of the iterator.
12010///
12011/// @param container the container the iterator points into.
12012///
12013/// @param i the iterator to consider.
12014///
12015/// @return true iff the iterator points to the last element of @p
12016/// container.
12017template<typename T>
12018static bool
12019iterator_is_last(T& container,
12020 typename T::const_iterator i)
12021{
12022 typename T::const_iterator next = i;
12023 ++next;
12024 return (next == container.end());
12025}
12026
12027//--------------------------------
12028// <type and decls lookup stuff>
12029// ------------------------------
12030
12031/// Lookup all the type*s* that have a given fully qualified name.
12032///
12033/// @param type_name the fully qualified name of the type to
12034/// lookup.
12035///
12036/// @param type_map the map to look into.
12037///
12038/// @return the vector containing the types named @p type_name. If
12039/// the lookup didn't yield any type, then this function returns nil.
12040static const type_base_wptrs_type*
12041lookup_types_in_map(const interned_string& type_name,
12042 const istring_type_base_wptrs_map_type& type_map)
12043{
12044 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12045 if (i != type_map.end())
12046 return &i->second;
12047 return 0;
12048}
12049
12050/// Lookup a type (with a given name) in a map that associates a type
12051/// name to a type. If there are several types with a given name,
12052/// then try to return the first one that is not decl-only.
12053/// Otherwise, return the last of such types, that is, the last one
12054/// that got registered.
12055///
12056/// @tparam TypeKind the type of the type this function is supposed to
12057/// return.
12058///
12059/// @param type_name the name of the type to lookup.
12060///
12061/// @param type_map the map in which to look.
12062///
12063/// @return a shared_ptr to the type found. If no type was found or
12064/// if the type found was not of type @p TypeKind then the function
12065/// returns nil.
12066template <class TypeKind>
12067static shared_ptr<TypeKind>
12068lookup_type_in_map(const interned_string& type_name,
12069 const istring_type_base_wptrs_map_type& type_map)
12070{
12071 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12072 if (i != type_map.end())
12073 {
12074 // Walk the types that have the name "type_name" and return the
12075 // first one that is not declaration-only ...
12076 for (auto j : i->second)
12077 {
12078 type_base_sptr t(j);
12079 decl_base_sptr d = is_decl(t);
12080 if (d && !d->get_is_declaration_only())
12081 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
12082 }
12083 // ... or return the last type with the name "type_name" that
12084 // was recorded. It's likely to be declaration-only if we
12085 // reached this point.
12086 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
12087 }
12088 return shared_ptr<TypeKind>();
12089}
12090
12091/// Lookup a basic type from a translation unit.
12092///
12093/// This is done by looking the type up in the type map that is
12094/// maintained in the translation unit. So this is as fast as
12095/// possible.
12096///
12097/// @param type_name the name of the basic type to look for.
12098///
12099/// @param tu the translation unit to look into.
12100///
12101/// @return the basic type found or nil if no basic type was found.
12104{
12105 return lookup_type_in_map<type_decl>(type_name,
12106 tu.get_types().basic_types());
12107}
12108
12109/// Lookup a basic type from a translation unit.
12110///
12111/// This is done by looking the type up in the type map that is
12112/// maintained in the translation unit. So this is as fast as
12113/// possible.
12114///
12115/// @param type_name the name of the basic type to look for.
12116///
12117/// @param tu the translation unit to look into.
12118///
12119/// @return the basic type found or nil if no basic type was found.
12121lookup_basic_type(const string& type_name, const translation_unit& tu)
12122{
12123 const environment& env = tu.get_environment();
12124
12125 interned_string s = env.intern(type_name);
12126 return lookup_basic_type(s, tu);
12127}
12128
12129/// Lookup a class type from a translation unit.
12130///
12131/// This is done by looking the type up in the type map that is
12132/// maintained in the translation unit. So this is as fast as
12133/// possible.
12134///
12135/// @param fqn the fully qualified name of the class type node to look
12136/// up.
12137///
12138/// @param tu the translation unit to perform lookup from.
12139///
12140/// @return the declaration of the class type IR node found, NULL
12141/// otherwise.
12143lookup_class_type(const string& fqn, const translation_unit& tu)
12144{
12145 const environment& env = tu.get_environment();
12146 interned_string s = env.intern(fqn);
12147 return lookup_class_type(s, tu);
12148}
12149
12150/// Lookup a class type from a translation unit.
12151///
12152/// This is done by looking the type up in the type map that is
12153/// maintained in the translation unit. So this is as fast as
12154/// possible.
12155///
12156/// @param type_name the name of the class type to look for.
12157///
12158/// @param tu the translation unit to look into.
12159///
12160/// @return the class type found or nil if no class type was found.
12163{
12164 return lookup_type_in_map<class_decl>(type_name,
12165 tu.get_types().class_types());
12166}
12167
12168/// Lookup a union type from a translation unit.
12169///
12170/// This is done by looking the type up in the type map that is
12171/// maintained in the translation unit. So this is as fast as
12172/// possible.
12173///
12174/// @param type_name the name of the union type to look for.
12175///
12176/// @param tu the translation unit to look into.
12177///
12178/// @return the union type found or nil if no union type was found.
12179union_decl_sptr
12181{
12182 return lookup_type_in_map<union_decl>(type_name,
12183 tu.get_types().union_types());
12184}
12185
12186/// Lookup a union type from a translation unit.
12187///
12188/// This is done by looking the type up in the type map that is
12189/// maintained in the translation unit. So this is as fast as
12190/// possible.
12191///
12192/// @param fqn the fully qualified name of the type to lookup.
12193///
12194/// @param tu the translation unit to look into.
12195///
12196/// @return the union type found or nil if no union type was found.
12197union_decl_sptr
12198lookup_union_type(const string& fqn, const translation_unit& tu)
12199{
12200 const environment& env = tu.get_environment();
12201 interned_string s = env.intern(fqn);
12202 return lookup_union_type(s, tu);
12203}
12204
12205/// Lookup a union type in a given corpus, from its location.
12206///
12207/// @param loc the location of the union type to look for.
12208///
12209/// @param corp the corpus to look it from.
12210///
12211/// @return the resulting union_decl.
12212union_decl_sptr
12214{
12217 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
12218
12219 return result;
12220}
12221
12222/// Lookup a union type in a given corpus, from its location.
12223///
12224/// @param loc the location of the union type to look for.
12225///
12226/// @param corp the corpus to look it from.
12227///
12228/// @return the resulting union_decl.
12229union_decl_sptr
12230lookup_union_type_per_location(const string& loc, const corpus& corp)
12231{
12232 const environment& env = corp.get_environment();
12233 return lookup_union_type_per_location(env.intern(loc), corp);
12234}
12235
12236/// Lookup an enum type from a translation unit.
12237///
12238/// This is done by looking the type up in the type map that is
12239/// maintained in the translation unit. So this is as fast as
12240/// possible.
12241///
12242/// @param type_name the name of the enum type to look for.
12243///
12244/// @param tu the translation unit to look into.
12245///
12246/// @return the enum type found or nil if no enum type was found.
12249{
12250 return lookup_type_in_map<enum_type_decl>(type_name,
12251 tu.get_types().enum_types());
12252}
12253
12254/// Lookup an enum type from a translation unit.
12255///
12256/// This is done by looking the type up in the type map that is
12257/// maintained in the translation unit. So this is as fast as
12258/// possible.
12259///
12260/// @param type_name the name of the enum type to look for.
12261///
12262/// @param tu the translation unit to look into.
12263///
12264/// @return the enum type found or nil if no enum type was found.
12266lookup_enum_type(const string& type_name, const translation_unit& tu)
12267{
12268 const environment& env = tu.get_environment();
12269 interned_string s = env.intern(type_name);
12270 return lookup_enum_type(s, tu);
12271}
12272
12273/// Lookup a typedef type from a translation unit.
12274///
12275/// This is done by looking the type up in the type map that is
12276/// maintained in the translation unit. So this is as fast as
12277/// possible.
12278///
12279/// @param type_name the name of the typedef type to look for.
12280///
12281/// @param tu the translation unit to look into.
12282///
12283/// @return the typedef type found or nil if no typedef type was
12284/// found.
12287 const translation_unit& tu)
12288{
12289 return lookup_type_in_map<typedef_decl>(type_name,
12290 tu.get_types().typedef_types());
12291}
12292
12293/// Lookup a typedef type from a translation unit.
12294///
12295/// This is done by looking the type up in the type map that is
12296/// maintained in the translation unit. So this is as fast as
12297/// possible.
12298///
12299/// @param type_name the name of the typedef type to look for.
12300///
12301/// @param tu the translation unit to look into.
12302///
12303/// @return the typedef type found or nil if no typedef type was
12304/// found.
12306lookup_typedef_type(const string& type_name, const translation_unit& tu)
12307{
12308 const environment& env = tu.get_environment();
12309 interned_string s = env.intern(type_name);
12310 return lookup_typedef_type(s, tu);
12311}
12312
12313/// Lookup a qualified type from a translation unit.
12314///
12315/// This is done by looking the type up in the type map that is
12316/// maintained in the translation unit. So this is as fast as
12317/// possible.
12318///
12319/// @param type_name the name of the qualified type to look for.
12320///
12321/// @param tu the translation unit to look into.
12322///
12323/// @return the qualified type found or nil if no qualified type was
12324/// found.
12325qualified_type_def_sptr
12327 const translation_unit& tu)
12328{
12329 const type_maps& m = tu.get_types();
12330 return lookup_type_in_map<qualified_type_def>(type_name,
12331 m.qualified_types());
12332}
12333
12334/// Lookup a qualified type from a translation unit.
12335///
12336/// This is done by looking the type up in the type map that is
12337/// maintained in the translation unit. So this is as fast as
12338/// possible.
12339///
12340/// @param underlying_type the underying type of the qualified type to
12341/// look up.
12342///
12343/// @param quals the CV-qualifiers of the qualified type to look for.
12344///
12345/// @param tu the translation unit to look into.
12346///
12347/// @return the qualified type found or nil if no qualified type was
12348/// found.
12349qualified_type_def_sptr
12350lookup_qualified_type(const type_base_sptr& underlying_type,
12352 const translation_unit& tu)
12353{
12354 interned_string type_name = get_name_of_qualified_type(underlying_type,
12355 quals);
12356 return lookup_qualified_type(type_name, tu);
12357}
12358
12359/// Lookup a pointer type from a translation unit.
12360///
12361/// This is done by looking the type up in the type map that is
12362/// maintained in the translation unit. So this is as fast as
12363/// possible.
12364///
12365/// @param type_name the name of the pointer type to look for.
12366///
12367/// @param tu the translation unit to look into.
12368///
12369/// @return the pointer type found or nil if no pointer type was
12370/// found.
12373 const translation_unit& tu)
12374{
12375 const type_maps& m = tu.get_types();
12376 return lookup_type_in_map<pointer_type_def>(type_name,
12377 m.pointer_types());
12378}
12379
12380/// Lookup a pointer type from a translation unit.
12381///
12382/// This is done by looking the type up in the type map that is
12383/// maintained in the translation unit. So this is as fast as
12384/// possible.
12385///
12386/// @param type_name the name of the pointer type to look for.
12387///
12388/// @param tu the translation unit to look into.
12389///
12390/// @return the pointer type found or nil if no pointer type was
12391/// found.
12393lookup_pointer_type(const string& type_name, const translation_unit& tu)
12394{
12395 const environment& env = tu.get_environment();
12396 interned_string s = env.intern(type_name);
12397 return lookup_pointer_type(s, tu);
12398}
12399
12400/// Lookup a pointer type from a translation unit.
12401///
12402/// This is done by looking the type up in the type map that is
12403/// maintained in the translation unit. So this is as fast as
12404/// possible.
12405///
12406/// @param pointed_to_type the pointed-to-type of the pointer to look for.
12407///
12408/// @param tu the translation unit to look into.
12409///
12410/// @return the pointer type found or nil if no pointer type was
12411/// found.
12413lookup_pointer_type(const type_base_sptr& pointed_to_type,
12414 const translation_unit& tu)
12415{
12416 type_base_sptr t = look_through_decl_only(pointed_to_type);
12418 return lookup_pointer_type(type_name, tu);
12419}
12420
12421/// Lookup a reference type from a translation unit.
12422///
12423/// This is done by looking the type up in the type map that is
12424/// maintained in the translation unit. So this is as fast as
12425/// possible.
12426///
12427/// @param type_name the name of the reference type to look for.
12428///
12429/// @param tu the translation unit to look into.
12430///
12431/// @return the reference type found or nil if no reference type was
12432/// found.
12435 const translation_unit& tu)
12436{
12437 const type_maps& m = tu.get_types();
12438 return lookup_type_in_map<reference_type_def>(type_name,
12439 m.reference_types());
12440}
12441
12442/// Lookup a reference type from a translation unit.
12443///
12444/// This is done by looking the type up in the type map that is
12445/// maintained in the translation unit. So this is as fast as
12446/// possible.
12447///
12448/// @param pointed_to_type the pointed-to-type of the reference to
12449/// look up.
12450///
12451/// @param tu the translation unit to look into.
12452///
12453/// @return the reference type found or nil if no reference type was
12454/// found.
12456lookup_reference_type(const type_base_sptr& pointed_to_type,
12457 bool lvalue_reference,
12458 const translation_unit& tu)
12459{
12460 interned_string type_name =
12462 lvalue_reference);
12463 return lookup_reference_type(type_name, tu);
12464}
12465
12466/// Lookup an array type from a translation unit.
12467///
12468/// This is done by looking the type up in the type map that is
12469/// maintained in the translation unit. So this is as fast as
12470/// possible.
12471///
12472/// @param type_name the name of the array type to look for.
12473///
12474/// @param tu the translation unit to look into.
12475///
12476/// @return the array type found or nil if no array type was found.
12479 const translation_unit& tu)
12480{
12481 const type_maps& m = tu.get_types();
12482 return lookup_type_in_map<array_type_def>(type_name,
12483 m.array_types());
12484}
12485
12486/// Lookup a function type from a translation unit.
12487///
12488/// This is done by looking the type up in the type map that is
12489/// maintained in the translation unit. So this is as fast as
12490/// possible.
12491///
12492/// @param type_name the name of the type to lookup.
12493///
12494/// @param tu the translation unit to look into.
12495///
12496/// @return the function type found, or NULL of none was found.
12499 const translation_unit& tu)
12500{
12501 const type_maps& m = tu.get_types();
12502 return lookup_type_in_map<function_type>(type_name,
12503 m.function_types());
12504}
12505
12506/// Lookup a function type from a translation unit.
12507///
12508/// This walks all the function types held by the translation unit and
12509/// compare their sub-type *names*. If the names match then return
12510/// the function type found in the translation unit.
12511///
12512/// @param t the function type to look for.
12513///
12514/// @param tu the translation unit to look into.
12515///
12516/// @return the function type found, or NULL of none was found.
12519 const translation_unit& tu)
12520{
12521 interned_string type_name = get_type_name(t);
12522 return lookup_function_type(type_name, tu);
12523}
12524
12525/// Lookup a function type from a translation unit.
12526///
12527/// This is done by looking the type up in the type map that is
12528/// maintained in the translation unit. So this is as fast as
12529/// possible.
12530///
12531/// @param t the function type to look for.
12532///
12533/// @param tu the translation unit to look into.
12534///
12535/// @return the function type found, or NULL of none was found.
12538 const translation_unit& tu)
12539{return lookup_function_type(*t, tu);}
12540
12541/// Lookup a type in a translation unit.
12542///
12543/// @param fqn the fully qualified name of the type to lookup.
12544///
12545/// @param tu the translation unit to consider.
12546///
12547/// @return the declaration of the type if found, NULL otherwise.
12548const type_base_sptr
12550 const translation_unit& tu)
12551{
12552 type_base_sptr result;
12553 ((result = lookup_typedef_type(fqn, tu))
12554 || (result = lookup_class_type(fqn, tu))
12555 || (result = lookup_union_type(fqn, tu))
12556 || (result = lookup_enum_type(fqn, tu))
12557 || (result = lookup_qualified_type(fqn, tu))
12558 || (result = lookup_pointer_type(fqn, tu))
12559 || (result = lookup_reference_type(fqn, tu))
12560 || (result = lookup_array_type(fqn, tu))
12561 || (result = lookup_function_type(fqn, tu))
12562 || (result = lookup_basic_type(fqn, tu)));
12563
12564 return result;
12565}
12566
12567/// Lookup a type in a translation unit, starting from the global
12568/// namespace.
12569///
12570/// @param fqn the fully qualified name of the type to lookup.
12571///
12572/// @param tu the translation unit to consider.
12573///
12574/// @return the declaration of the type if found, NULL otherwise.
12575type_base_sptr
12576lookup_type(const string& fqn, const translation_unit& tu)
12577{
12578 const environment&env = tu.get_environment();
12579 interned_string ifqn = env.intern(fqn);
12580 return lookup_type(ifqn, tu);
12581}
12582
12583/// Lookup a type from a translation unit.
12584///
12585/// @param fqn the components of the fully qualified name of the node
12586/// to look up.
12587///
12588/// @param tu the translation unit to perform lookup from.
12589///
12590/// @return the declaration of the IR node found, NULL otherwise.
12591const type_base_sptr
12592lookup_type(const type_base_sptr type,
12593 const translation_unit& tu)
12594{
12595 interned_string type_name = get_type_name(type);
12596 return lookup_type(type_name, tu);
12597}
12598
12599/// Lookup a type in a scope.
12600///
12601/// This is really slow as it walks the member types of the scope in
12602/// sequence to find the type with a given name.
12603///
12604/// If possible, users should prefer looking up types from the
12605/// enclosing translation unit or even ABI corpus because both the
12606/// translation unit and the corpus have a map of type, indexed by
12607/// their name. Looking up a type from those maps is thus much
12608/// faster.
12609///
12610/// @param fqn the fully qualified name of the type to lookup.
12611///
12612/// @param skope the scope to look into.
12613///
12614/// @return the declaration of the type if found, NULL otherwise.
12615const type_base_sptr
12616lookup_type_in_scope(const string& fqn,
12617 const scope_decl_sptr& skope)
12618{
12619 list<string> comps;
12620 fqn_to_components(fqn, comps);
12621 return lookup_type_in_scope(comps, skope);
12622}
12623
12624/// Lookup a @ref var_decl in a scope.
12625///
12626/// @param fqn the fuly qualified name of the @var_decl to lookup.
12627///
12628/// @param skope the scope to look into.
12629///
12630/// @return the declaration of the @ref var_decl if found, NULL
12631/// otherwise.
12632const decl_base_sptr
12634 const scope_decl_sptr& skope)
12635{
12636 list<string> comps;
12637 fqn_to_components(fqn, comps);
12638 return lookup_var_decl_in_scope(comps, skope);
12639}
12640
12641/// A generic function (template) to get the name of a node, whatever
12642/// node it is. This has to be specialized for the kind of node we
12643/// want.
12644///
12645/// Note that a node is a member of a scope.
12646///
12647/// @tparam NodeKind the kind of node to consider.
12648///
12649/// @param node the node to get the name from.
12650///
12651/// @return the name of the node.
12652template<typename NodeKind>
12653static const interned_string&
12654get_node_name(shared_ptr<NodeKind> node);
12655
12656/// Gets the name of a class_decl node.
12657///
12658/// @param node the decl_base node to get the name from.
12659///
12660/// @return the name of the node.
12661template<>
12662const interned_string&
12664{return node->get_name();}
12665
12666/// Gets the name of a type_base node.
12667///
12668/// @param node the type_base node to get the name from.
12669///
12670/// @return the name of the node.
12671template<>
12672const interned_string&
12673get_node_name(type_base_sptr node)
12674{return get_type_declaration(node)->get_name();}
12675
12676/// Gets the name of a var_decl node.
12677///
12678/// @param node the var_decl node to get the name from.
12679///
12680/// @return the name of the node.
12681template<>
12682const interned_string&
12684{return node->get_name();}
12685
12686/// Generic function to get the declaration of a given node, whatever
12687/// it is. There has to be specializations for the kind of the nodes
12688/// we want to support.
12689///
12690/// @tparam NodeKind the type of the node we are looking at.
12691///
12692/// @return the declaration.
12693template<typename NodeKind>
12694static decl_base_sptr
12695convert_node_to_decl(shared_ptr<NodeKind> node);
12696
12697/// Lookup a node in a given scope.
12698///
12699/// @tparam the type of the node to lookup.
12700///
12701/// @param fqn the components of the fully qualified name of the node
12702/// to lookup.
12703///
12704/// @param skope the scope to look into.
12705///
12706/// @return the declaration of the looked up node, or NULL if it
12707/// wasn't found.
12708template<typename NodeKind>
12709static const type_or_decl_base_sptr
12710lookup_node_in_scope(const list<string>& fqn,
12711 const scope_decl_sptr& skope)
12712{
12713 type_or_decl_base_sptr resulting_decl;
12714 shared_ptr<NodeKind> node;
12715 bool it_is_last = false;
12716 scope_decl_sptr cur_scope = skope, new_scope, scope;
12717
12718 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
12719 {
12720 new_scope.reset();
12721 it_is_last = iterator_is_last(fqn, c);
12722 for (scope_decl::declarations::const_iterator m =
12723 cur_scope->get_member_decls().begin();
12724 m != cur_scope->get_member_decls().end();
12725 ++m)
12726 {
12727 if (!it_is_last)
12728 {
12729 // looking for a scope
12730 scope = dynamic_pointer_cast<scope_decl>(*m);
12731 if (scope && scope->get_name() == *c)
12732 {
12733 new_scope = scope;
12734 break;
12735 }
12736 }
12737 else
12738 {
12739 //looking for a final type.
12740 node = dynamic_pointer_cast<NodeKind>(*m);
12741 if (node && get_node_name(node) == *c)
12742 {
12743 if (class_decl_sptr cl =
12744 dynamic_pointer_cast<class_decl>(node))
12745 if (cl->get_is_declaration_only()
12746 && !cl->get_definition_of_declaration())
12747 continue;
12748 resulting_decl = node;
12749 break;
12750 }
12751 }
12752 }
12753 if (!new_scope && !resulting_decl)
12754 return decl_base_sptr();
12755 cur_scope = new_scope;
12756 }
12757 ABG_ASSERT(resulting_decl);
12758 return resulting_decl;
12759}
12760
12761/// lookup a type in a scope.
12762///
12763///
12764/// This is really slow as it walks the member types of the scope in
12765/// sequence to find the type with a given name.
12766///
12767/// If possible, users should prefer looking up types from the
12768/// enclosing translation unit or even ABI corpus because both the
12769/// translation unit and the corpus have a map of type, indexed by
12770/// their name. Looking up a type from those maps is thus much
12771/// faster.
12772///
12773/// @param comps the components of the fully qualified name of the
12774/// type to lookup.
12775///
12776/// @param skope the scope to look into.
12777///
12778/// @return the declaration of the type found.
12779const type_base_sptr
12780lookup_type_in_scope(const list<string>& comps,
12781 const scope_decl_sptr& scope)
12782{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
12783
12784/// lookup a type in a scope.
12785///
12786/// This is really slow as it walks the member types of the scope in
12787/// sequence to find the type with a given name.
12788///
12789/// If possible, users should prefer looking up types from the
12790/// enclosing translation unit or even ABI corpus because both the
12791/// translation unit and the corpus have a map of type, indexed by
12792/// their name. Looking up a type from those maps is thus much
12793/// faster.
12794///
12795/// @param type the type to look for.
12796///
12797/// @param access_path a vector of scopes the path of scopes to follow
12798/// before reaching the scope into which to look for @p type. Note
12799/// that the deepest scope (the one immediately containing @p type) is
12800/// at index 0 of this vector, and the top-most scope is the last
12801/// element of the vector.
12802///
12803/// @param scope the top-most scope into which to look for @p type.
12804///
12805/// @return the scope found in @p scope, or NULL if it wasn't found.
12806static const type_base_sptr
12808 const vector<scope_decl*>& access_path,
12809 const scope_decl* scope)
12810{
12811 vector<scope_decl*> a = access_path;
12812 type_base_sptr result;
12813
12814 scope_decl* first_scope = 0;
12815 if (!a.empty())
12816 {
12817 first_scope = a.back();
12818 ABG_ASSERT(first_scope->get_name() == scope->get_name());
12819 a.pop_back();
12820 }
12821
12822 if (a.empty())
12823 {
12824 interned_string n = get_type_name(type, false);
12825 for (scope_decl::declarations::const_iterator i =
12826 scope->get_member_decls().begin();
12827 i != scope->get_member_decls().end();
12828 ++i)
12829 if (is_type(*i) && (*i)->get_name() == n)
12830 {
12831 result = is_type(*i);
12832 break;
12833 }
12834 }
12835 else
12836 {
12837 first_scope = a.back();
12838 interned_string scope_name, cur_scope_name = first_scope->get_name();
12839 for (scope_decl::scopes::const_iterator i =
12840 scope->get_member_scopes().begin();
12841 i != scope->get_member_scopes().end();
12842 ++i)
12843 {
12844 scope_name = (*i)->get_name();
12845 if (scope_name == cur_scope_name)
12846 {
12847 result = lookup_type_in_scope(type, a, (*i).get());
12848 break;
12849 }
12850 }
12851 }
12852 return result;
12853}
12854
12855/// lookup a type in a scope.
12856///
12857/// This is really slow as it walks the member types of the scope in
12858/// sequence to find the type with a given name.
12859///
12860/// If possible, users should prefer looking up types from the
12861/// enclosing translation unit or even ABI corpus because both the
12862/// translation unit and the corpus have a map of type, indexed by
12863/// their name. Looking up a type from those maps is thus much
12864/// faster.
12865///
12866/// @param type the type to look for.
12867///
12868/// @param scope the top-most scope into which to look for @p type.
12869///
12870/// @return the scope found in @p scope, or NULL if it wasn't found.
12871static const type_base_sptr
12872lookup_type_in_scope(const type_base_sptr type,
12873 const scope_decl* scope)
12874{
12875 if (!type || is_function_type(type))
12876 return type_base_sptr();
12877
12878 decl_base_sptr type_decl = get_type_declaration(type);
12879 ABG_ASSERT(type_decl);
12880 vector<scope_decl*> access_path;
12881 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
12882 {
12883 access_path.push_back(s);
12884 if (is_global_scope(s))
12885 break;
12886 }
12887 return lookup_type_in_scope(*type, access_path, scope);
12888}
12889
12890/// Lookup a type from a translation unit by walking the scopes of the
12891/// translation unit in sequence and looking into them.
12892///
12893/// This is really slow as it walks the member types of the scopes in
12894/// sequence to find the type with a given name.
12895///
12896/// If possible, users should prefer looking up types from the
12897/// translation unit or even ABI corpus in a more direct way, by using
12898/// the lookup_type() functins.
12899///
12900///
12901/// This is because both the translation unit and the corpus have a
12902/// map of types, indexed by their name. Looking up a type from those
12903/// maps is thus much faster. @param fqn the components of the fully
12904/// qualified name of the node to look up.
12905///
12906/// @param tu the translation unit to perform lookup from.
12907///
12908/// @return the declaration of the IR node found, NULL otherwise.
12909const type_base_sptr
12910lookup_type_through_scopes(const type_base_sptr type,
12911 const translation_unit& tu)
12912{
12913 if (function_type_sptr fn_type = is_function_type(type))
12914 return lookup_function_type(fn_type, tu);
12915 return lookup_type_in_scope(type, tu.get_global_scope().get());
12916}
12917
12918/// lookup a var_decl in a scope.
12919///
12920/// @param comps the components of the fully qualified name of the
12921/// var_decl to lookup.
12922///
12923/// @param skope the scope to look into.
12924const decl_base_sptr
12925lookup_var_decl_in_scope(const std::list<string>& comps,
12926 const scope_decl_sptr& skope)
12927{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
12928
12929/// Lookup an IR node from a translation unit.
12930///
12931/// @tparam NodeKind the type of the IR node to lookup from the
12932/// translation unit.
12933///
12934/// @param fqn the components of the fully qualified name of the node
12935/// to look up.
12936///
12937/// @param tu the translation unit to perform lookup from.
12938///
12939/// @return the declaration of the IR node found, NULL otherwise.
12940template<typename NodeKind>
12941static const type_or_decl_base_sptr
12942lookup_node_in_translation_unit(const list<string>& fqn,
12943 const translation_unit& tu)
12944{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
12945
12946/// Lookup a type from a translation unit by walking its scopes in
12947/// sequence and by looking into them.
12948///
12949/// This is much slower than using the lookup_type() function.
12950///
12951/// @param fqn the components of the fully qualified name of the node
12952/// to look up.
12953///
12954/// @param tu the translation unit to perform lookup from.
12955///
12956/// @return the declaration of the IR node found, NULL otherwise.
12957type_base_sptr
12958lookup_type_through_scopes(const list<string>& fqn,
12959 const translation_unit& tu)
12960{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
12961
12962
12963/// Lookup a class type from a translation unit by walking its scopes
12964/// in sequence and by looking into them.
12965///
12966/// This is much slower than using the lookup_class_type() function
12967/// because it walks all the scopes of the translation unit in
12968/// sequence and lookup the types to find one that has a given name.
12969///
12970/// @param fqn the components of the fully qualified name of the class
12971/// type node to look up.
12972///
12973/// @param tu the translation unit to perform lookup from.
12974///
12975/// @return the declaration of the class type IR node found, NULL
12976/// otherwise.
12978lookup_class_type_through_scopes(const list<string>& fqn,
12979 const translation_unit& tu)
12980{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
12981
12982/// Lookup a basic type from all the translation units of a given
12983/// corpus.
12984///
12985/// @param fqn the components of the fully qualified name of the basic
12986/// type node to look up.
12987///
12988/// @param tu the translation unit to perform lookup from.
12989///
12990/// @return the declaration of the basic type IR node found, NULL
12991/// otherwise.
12992static type_decl_sptr
12993lookup_basic_type_through_translation_units(const interned_string& type_name,
12994 const corpus& abi_corpus)
12995{
12996 type_decl_sptr result;
12997
12998 for (translation_units::const_iterator tu =
12999 abi_corpus.get_translation_units().begin();
13000 tu != abi_corpus.get_translation_units().end();
13001 ++tu)
13002 if ((result = lookup_basic_type(type_name, **tu)))
13003 break;
13004
13005 return result;
13006}
13007
13008/// Lookup a union type from all the translation units of a given
13009/// corpus.
13010///
13011/// @param fqn the components of the fully qualified name of the union
13012/// type node to look up.
13013///
13014/// @param tu the translation unit to perform lookup from.
13015///
13016/// @return the declaration of the union type IR node found, NULL
13017/// otherwise.
13018static union_decl_sptr
13019lookup_union_type_through_translation_units(const interned_string& type_name,
13020 const corpus & abi_corpus)
13021{
13022 union_decl_sptr result;
13023
13024 for (translation_units::const_iterator tu =
13025 abi_corpus.get_translation_units().begin();
13026 tu != abi_corpus.get_translation_units().end();
13027 ++tu)
13028 if ((result = lookup_union_type(type_name, **tu)))
13029 break;
13030
13031 return result;
13032}
13033
13034/// Lookup an enum type from all the translation units of a given
13035/// corpus.
13036///
13037/// @param fqn the components of the fully qualified name of the enum
13038/// type node to look up.
13039///
13040/// @param tu the translation unit to perform lookup from.
13041///
13042/// @return the declaration of the enum type IR node found, NULL
13043/// otherwise.
13045lookup_enum_type_through_translation_units(const interned_string& type_name,
13046 const corpus & abi_corpus)
13047{
13048 enum_type_decl_sptr result;
13049
13050 for (translation_units::const_iterator tu =
13051 abi_corpus.get_translation_units().begin();
13052 tu != abi_corpus.get_translation_units().end();
13053 ++tu)
13054 if ((result = lookup_enum_type(type_name, **tu)))
13055 break;
13056
13057 return result;
13058}
13059
13060/// Lookup a typedef type definition in all the translation units of a
13061/// given ABI corpus.
13062///
13063/// @param @param qn the fully qualified name of the typedef type to lookup.
13064///
13065/// @param abi_corpus the ABI corpus which to look the type up in.
13066///
13067/// @return the type definition if any was found, or a NULL pointer.
13068static typedef_decl_sptr
13069lookup_typedef_type_through_translation_units(const interned_string& type_name,
13070 const corpus & abi_corpus)
13071{
13072 typedef_decl_sptr result;
13073
13074 for (translation_units::const_iterator tu =
13075 abi_corpus.get_translation_units().begin();
13076 tu != abi_corpus.get_translation_units().end();
13077 ++tu)
13078 if ((result = lookup_typedef_type(type_name, **tu)))
13079 break;
13080
13081 return result;
13082}
13083
13084/// Lookup a qualified type definition in all the translation units of a
13085/// given ABI corpus.
13086///
13087/// @param @param qn the fully qualified name of the qualified type to
13088/// lookup.
13089///
13090/// @param abi_corpus the ABI corpus which to look the type up in.
13091///
13092/// @return the type definition if any was found, or a NULL pointer.
13093static qualified_type_def_sptr
13094lookup_qualified_type_through_translation_units(const interned_string& t_name,
13095 const corpus & abi_corpus)
13096{
13097 qualified_type_def_sptr result;
13098
13099 for (translation_units::const_iterator tu =
13100 abi_corpus.get_translation_units().begin();
13101 tu != abi_corpus.get_translation_units().end();
13102 ++tu)
13103 if ((result = lookup_qualified_type(t_name, **tu)))
13104 break;
13105
13106 return result;
13107}
13108
13109/// Lookup a pointer type definition in all the translation units of a
13110/// given ABI corpus.
13111///
13112/// @param @param qn the fully qualified name of the pointer type to
13113/// lookup.
13114///
13115/// @param abi_corpus the ABI corpus which to look the type up in.
13116///
13117/// @return the type definition if any was found, or a NULL pointer.
13119lookup_pointer_type_through_translation_units(const interned_string& type_name,
13120 const corpus & abi_corpus)
13121{
13122 pointer_type_def_sptr result;
13123
13124 for (translation_units::const_iterator tu =
13125 abi_corpus.get_translation_units().begin();
13126 tu != abi_corpus.get_translation_units().end();
13127 ++tu)
13128 if ((result = lookup_pointer_type(type_name, **tu)))
13129 break;
13130
13131 return result;
13132}
13133
13134/// Lookup a reference type definition in all the translation units of a
13135/// given ABI corpus.
13136///
13137/// @param @param qn the fully qualified name of the reference type to
13138/// lookup.
13139///
13140/// @param abi_corpus the ABI corpus which to look the type up in.
13141///
13142/// @return the type definition if any was found, or a NULL pointer.
13144lookup_reference_type_through_translation_units(const interned_string& t_name,
13145 const corpus & abi_corpus)
13146{
13148
13149 for (translation_units::const_iterator tu =
13150 abi_corpus.get_translation_units().begin();
13151 tu != abi_corpus.get_translation_units().end();
13152 ++tu)
13153 if ((result = lookup_reference_type(t_name, **tu)))
13154 break;
13155
13156 return result;
13157}
13158
13159/// Lookup a array type definition in all the translation units of a
13160/// given ABI corpus.
13161///
13162/// @param @param qn the fully qualified name of the array type to
13163/// lookup.
13164///
13165/// @param abi_corpus the ABI corpus which to look the type up in.
13166///
13167/// @return the type definition if any was found, or a NULL pointer.
13169lookup_array_type_through_translation_units(const interned_string& type_name,
13170 const corpus & abi_corpus)
13171{
13172 array_type_def_sptr result;
13173
13174 for (translation_units::const_iterator tu =
13175 abi_corpus.get_translation_units().begin();
13176 tu != abi_corpus.get_translation_units().end();
13177 ++tu)
13178 if ((result = lookup_array_type(type_name, **tu)))
13179 break;
13180
13181 return result;
13182}
13183
13184/// Lookup a function type definition in all the translation units of
13185/// a given ABI corpus.
13186///
13187/// @param @param qn the fully qualified name of the function type to
13188/// lookup.
13189///
13190/// @param abi_corpus the ABI corpus which to look the type up in.
13191///
13192/// @return the type definition if any was found, or a NULL pointer.
13193static function_type_sptr
13194lookup_function_type_through_translation_units(const interned_string& type_name,
13195 const corpus & abi_corpus)
13196{
13197 function_type_sptr result;
13198
13199 for (translation_units::const_iterator tu =
13200 abi_corpus.get_translation_units().begin();
13201 tu != abi_corpus.get_translation_units().end();
13202 ++tu)
13203 if ((result = lookup_function_type(type_name, **tu)))
13204 break;
13205
13206 return result;
13207}
13208
13209/// Lookup a type definition in all the translation units of a given
13210/// ABI corpus.
13211///
13212/// @param @param qn the fully qualified name of the type to lookup.
13213///
13214/// @param abi_corpus the ABI corpus which to look the type up in.
13215///
13216/// @return the type definition if any was found, or a NULL pointer.
13217type_base_sptr
13219 const corpus& abi_corpus)
13220{
13221 type_base_sptr result;
13222
13223 for (translation_units::const_iterator tu =
13224 abi_corpus.get_translation_units().begin();
13225 tu != abi_corpus.get_translation_units().end();
13226 ++tu)
13227 if ((result = lookup_type(qn, **tu)))
13228 break;
13229
13230 return result;
13231}
13232
13233/// Lookup a type from a given translation unit present in a give corpus.
13234///
13235/// @param type_name the name of the type to look for.
13236///
13237/// @parm tu_path the path of the translation unit to consider.
13238///
13239/// @param corp the corpus to consider.
13240///
13241/// @return the resulting type, if any.
13242type_base_sptr
13244 const string& tu_path,
13245 const corpus& corp)
13246{
13247 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
13248 if (i == corp.priv_->path_tu_map.end())
13249 return type_base_sptr();
13250
13251 translation_unit_sptr tu = i->second;
13252 ABG_ASSERT(tu);
13253
13254 type_base_sptr t = lookup_type(type_name, *tu);
13255 return t;
13256}
13257
13258/// Look into an ABI corpus for a function type.
13259///
13260/// @param fn_type the function type to be looked for in the ABI
13261/// corpus.
13262///
13263/// @param corpus the ABI corpus into which to look for the function
13264/// type.
13265///
13266/// @return the function type found in the corpus.
13269 const corpus& corpus)
13270{
13271 ABG_ASSERT(fn_t);
13272
13273 function_type_sptr result;
13274
13275 if ((result = lookup_function_type(fn_t, corpus)))
13276 return result;
13277
13278 for (translation_units::const_iterator i =
13279 corpus.get_translation_units().begin();
13280 i != corpus.get_translation_units().end();
13281 ++i)
13283 **i)))
13284 return result;
13285
13286 return result;
13287}
13288
13289/// Look into a given corpus to find a type which has the same
13290/// qualified name as a giventype.
13291///
13292/// If the per-corpus type map is non-empty (because the corpus allows
13293/// the One Definition Rule) then the type islooked up in that
13294/// per-corpus type map. Otherwise, the type is looked-up in each
13295/// translation unit.
13296///
13297/// @param t the type which has the same qualified name as the type we
13298/// are looking for.
13299///
13300/// @param corp the ABI corpus to look into for the type.
13302lookup_basic_type(const type_decl& t, const corpus& corp)
13303{return lookup_basic_type(t.get_name(), corp);}
13304
13305/// Look into a given corpus to find a basic type which has a given
13306/// qualified name.
13307///
13308/// If the per-corpus type map is non-empty (because the corpus allows
13309/// the One Definition Rule) then the type islooked up in that
13310/// per-corpus type map. Otherwise, the type is looked-up in each
13311/// translation unit.
13312///
13313/// @param qualified_name the qualified name of the basic type to look
13314/// for.
13315///
13316/// @param corp the corpus to look into.
13318lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
13319{
13321 type_decl_sptr result;
13322
13323 if (!m.empty())
13324 result = lookup_type_in_map<type_decl>(qualified_name, m);
13325 else
13326 result = lookup_basic_type_through_translation_units(qualified_name, corp);
13327
13328 return result;
13329}
13330
13331/// Lookup a @ref type_decl type from a given corpus, by its location.
13332///
13333/// @param loc the location to consider.
13334///
13335/// @param corp the corpus to consider.
13336///
13337/// @return the resulting basic type, if any.
13340 const corpus &corp)
13341{
13344 type_decl_sptr result;
13345
13346 result = lookup_type_in_map<type_decl>(loc, m);
13347
13348 return result;
13349}
13350
13351/// Lookup a @ref type_decl type from a given corpus, by its location.
13352///
13353/// @param loc the location to consider.
13354///
13355/// @param corp the corpus to consider.
13356///
13357/// @return the resulting basic type, if any.
13359lookup_basic_type_per_location(const string &loc, const corpus &corp)
13360{
13361 const environment& env = corp.get_environment();
13362 return lookup_basic_type_per_location(env.intern(loc), corp);
13363}
13364
13365/// Look into a given corpus to find a basic type which has a given
13366/// qualified name.
13367///
13368/// If the per-corpus type map is non-empty (because the corpus allows
13369/// the One Definition Rule) then the type islooked up in that
13370/// per-corpus type map. Otherwise, the type is looked-up in each
13371/// translation unit.
13372///
13373/// @param qualified_name the qualified name of the basic type to look
13374/// for.
13375///
13376/// @param corp the corpus to look into.
13378lookup_basic_type(const string& qualified_name, const corpus& corp)
13379{
13380 return lookup_basic_type(corp.get_environment().intern(qualified_name),
13381 corp);
13382}
13383
13384/// Look into a given corpus to find a class type which has the same
13385/// qualified name as a given type.
13386///
13387/// If the per-corpus type map is non-empty (because the corpus allows
13388/// the One Definition Rule) then the type islooked up in that
13389/// per-corpus type map. Otherwise, the type is looked-up in each
13390/// translation unit.
13391///
13392/// @param t the class decl type which has the same qualified name as
13393/// the type we are looking for.
13394///
13395/// @param corp the corpus to look into.
13398{
13400 return lookup_class_type(s, corp);
13401}
13402
13403/// Look into a given corpus to find a class type which has a given
13404/// qualified name.
13405///
13406/// If the per-corpus type map is non-empty (because the corpus allows
13407/// the One Definition Rule) then the type islooked up in that
13408/// per-corpus type map. Otherwise, the type is looked-up in each
13409/// translation unit.
13410///
13411/// @param qualified_name the qualified name of the type to look for.
13412///
13413/// @param corp the corpus to look into.
13415lookup_class_type(const string& qualified_name, const corpus& corp)
13416{
13417 interned_string s = corp.get_environment().intern(qualified_name);
13418 return lookup_class_type(s, corp);
13419}
13420
13421/// Look into a given corpus to find a class type which has a given
13422/// qualified name.
13423///
13424/// If the per-corpus type map is non-empty (because the corpus allows
13425/// the One Definition Rule) then the type islooked up in that
13426/// per-corpus type map. Otherwise, the type is looked-up in each
13427/// translation unit.
13428///
13429/// @param qualified_name the qualified name of the type to look for.
13430///
13431/// @param corp the corpus to look into.
13433lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13434{
13436
13437 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13438
13439 return result;
13440}
13441
13442/// Look into a given corpus to find the class type*s* that have a
13443/// given qualified name.
13444///
13445/// @param qualified_name the qualified name of the type to look for.
13446///
13447/// @param corp the corpus to look into.
13448///
13449/// @return the vector of class types named @p qualified_name.
13451lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13452{
13454
13455 return lookup_types_in_map(qualified_name, m);
13456}
13457
13458/// Look into a given corpus to find the class type*s* that have a
13459/// given qualified name and that are declaration-only.
13460///
13461/// @param qualified_name the qualified name of the type to look for.
13462///
13463/// @param corp the corpus to look into.
13464///
13465/// @param result the vector of decl-only class types named @p
13466/// qualified_name. This is populated iff the function returns true.
13467///
13468/// @return true iff @p result was populated with the decl-only
13469/// classes named @p qualified_name.
13470bool
13472 const corpus& corp,
13473 type_base_wptrs_type& result)
13474{
13476
13477 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13478 if (!v)
13479 return false;
13480
13481 for (auto type : *v)
13482 {
13483 type_base_sptr t(type);
13485 if (c->get_is_declaration_only()
13486 && !c->get_definition_of_declaration())
13487 result.push_back(type);
13488 }
13489
13490 return !result.empty();
13491}
13492
13493/// Look into a given corpus to find the union type*s* that have a
13494/// given qualified name.
13495///
13496/// @param qualified_name the qualified name of the type to look for.
13497///
13498/// @param corp the corpus to look into.
13499///
13500/// @return the vector of union types named @p qualified_name.
13502lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13503{
13505
13506 return lookup_types_in_map(qualified_name, m);
13507}
13508
13509/// Look into a given corpus to find the class type*s* that have a
13510/// given qualified name.
13511///
13512/// @param qualified_name the qualified name of the type to look for.
13513///
13514/// @param corp the corpus to look into.
13515///
13516/// @return the vector of class types which name is @p qualified_name.
13518lookup_class_types(const string& qualified_name, const corpus& corp)
13519{
13520 interned_string s = corp.get_environment().intern(qualified_name);
13521 return lookup_class_types(s, corp);
13522}
13523
13524/// Look into a given corpus to find the union types that have a given
13525/// qualified name.
13526///
13527/// @param qualified_name the qualified name of the type to look for.
13528///
13529/// @param corp the corpus to look into.
13530///
13531/// @return the vector of union types which name is @p qualified_name.
13533lookup_union_types(const string& qualified_name, const corpus& corp)
13534{
13535 interned_string s = corp.get_environment().intern(qualified_name);
13536 return lookup_union_types(s, corp);
13537}
13538
13539/// Look up a @ref class_decl from a given corpus by its location.
13540///
13541/// @param loc the location to consider.
13542///
13543/// @param corp the corpus to consider.
13544///
13545/// @return the resulting class decl, if any.
13548 const corpus& corp)
13549{
13552 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13553
13554 return result;
13555}
13556
13557/// Look up a @ref class_decl from a given corpus by its location.
13558///
13559/// @param loc the location to consider.
13560///
13561/// @param corp the corpus to consider.
13562///
13563/// @return the resulting class decl, if any.
13565lookup_class_type_per_location(const string &loc, const corpus &corp)
13566{
13567 const environment& env = corp.get_environment();
13568 return lookup_class_type_per_location(env.intern(loc), corp);
13569}
13570
13571/// Look into a given corpus to find a union type which has a given
13572/// qualified name.
13573///
13574/// If the per-corpus type map is non-empty (because the corpus allows
13575/// the One Definition Rule) then the type islooked up in that
13576/// per-corpus type map. Otherwise, the type is looked-up in each
13577/// translation unit.
13578///
13579/// @param qualified_name the qualified name of the type to look for.
13580///
13581/// @param corp the corpus to look into.
13582union_decl_sptr
13583lookup_union_type(const interned_string& type_name, const corpus& corp)
13584{
13586
13587 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13588 if (!result)
13589 result = lookup_union_type_through_translation_units(type_name, corp);
13590
13591 return result;
13592}
13593
13594/// Look into a given corpus to find a union type which has a given
13595/// qualified name.
13596///
13597/// If the per-corpus type map is non-empty (because the corpus allows
13598/// the One Definition Rule) then the type islooked up in that
13599/// per-corpus type map. Otherwise, the type is looked-up in each
13600/// translation unit.
13601///
13602/// @param qualified_name the qualified name of the type to look for.
13603///
13604/// @param corp the corpus to look into.
13605union_decl_sptr
13606lookup_union_type(const string& type_name, const corpus& corp)
13607{
13608 interned_string s = corp.get_environment().intern(type_name);
13609 return lookup_union_type(s, corp);
13610}
13611
13612/// Look into a given corpus to find an enum type which has the same
13613/// qualified name as a given enum type.
13614///
13615/// If the per-corpus type map is non-empty (because the corpus allows
13616/// the One Definition Rule) then the type islooked up in that
13617/// per-corpus type map. Otherwise, the type is looked-up in each
13618/// translation unit.
13619///
13620/// @param t the enum type which has the same qualified name as the
13621/// type we are looking for.
13622///
13623/// @param corp the corpus to look into.
13626{
13628 return lookup_enum_type(s, corp);
13629}
13630
13631/// Look into a given corpus to find an enum type which has a given
13632/// qualified name.
13633///
13634/// If the per-corpus type map is non-empty (because the corpus allows
13635/// the One Definition Rule) then the type islooked up in that
13636/// per-corpus type map. Otherwise, the type is looked-up in each
13637/// translation unit.
13638///
13639/// @param qualified_name the qualified name of the enum type to look
13640/// for.
13641///
13642/// @param corp the corpus to look into.
13644lookup_enum_type(const string& qualified_name, const corpus& corp)
13645{
13646 interned_string s = corp.get_environment().intern(qualified_name);
13647 return lookup_enum_type(s, corp);
13648}
13649
13650/// Look into a given corpus to find an enum type which has a given
13651/// qualified name.
13652///
13653/// If the per-corpus type map is non-empty (because the corpus allows
13654/// the One Definition Rule) then the type islooked up in that
13655/// per-corpus type map. Otherwise, the type is looked-up in each
13656/// translation unit.
13657///
13658/// @param qualified_name the qualified name of the enum type to look
13659/// for.
13660///
13661/// @param corp the corpus to look into.
13663lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
13664{
13666
13667 enum_type_decl_sptr result =
13668 lookup_type_in_map<enum_type_decl>(qualified_name, m);
13669 if (!result)
13670 result = lookup_enum_type_through_translation_units(qualified_name, corp);
13671
13672 return result;
13673}
13674
13675/// Look into a given corpus to find the enum type*s* that have a
13676/// given qualified name.
13677///
13678/// @param qualified_name the qualified name of the type to look for.
13679///
13680/// @param corp the corpus to look into.
13681///
13682/// @return the vector of enum types that which name is @p qualified_name.
13684lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
13685{
13687
13688 return lookup_types_in_map(qualified_name, m);
13689}
13690
13691/// Look into a given corpus to find the enum type*s* that have a
13692/// given qualified name.
13693///
13694/// @param qualified_name the qualified name of the type to look for.
13695///
13696/// @param corp the corpus to look into.
13697///
13698/// @return the vector of enum types that which name is @p qualified_name.
13700lookup_enum_types(const string& qualified_name, const corpus& corp)
13701{
13702 interned_string s = corp.get_environment().intern(qualified_name);
13703 return lookup_enum_types(s, corp);
13704}
13705
13706/// Look up an @ref enum_type_decl from a given corpus, by its location.
13707///
13708/// @param loc the location to consider.
13709///
13710/// @param corp the corpus to look the type from.
13711///
13712/// @return the resulting enum type, if any.
13715{
13718 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
13719
13720 return result;
13721}
13722
13723/// Look up an @ref enum_type_decl from a given corpus, by its location.
13724///
13725/// @param loc the location to consider.
13726///
13727/// @param corp the corpus to look the type from.
13728///
13729/// @return the resulting enum type, if any.
13731lookup_enum_type_per_location(const string &loc, const corpus &corp)
13732{
13733 const environment& env = corp.get_environment();
13734 return lookup_enum_type_per_location(env.intern(loc), corp);
13735}
13736
13737/// Look into a given corpus to find a typedef type which has the
13738/// same qualified name as a given typedef type.
13739///
13740/// If the per-corpus type map is non-empty (because the corpus allows
13741/// the One Definition Rule) then the type islooked up in that
13742/// per-corpus type map. Otherwise, the type is looked-up in each
13743/// translation unit.
13744///
13745/// @param t the typedef type which has the same qualified name as the
13746/// typedef type we are looking for.
13747///
13748/// @param corp the corpus to look into.
13751{
13753 return lookup_typedef_type(s, corp);
13754}
13755
13756/// Look into a given corpus to find a typedef type which has the
13757/// same qualified name as a given typedef type.
13758///
13759/// If the per-corpus type map is non-empty (because the corpus allows
13760/// the One Definition Rule) then the type islooked up in that
13761/// per-corpus type map. Otherwise, the type is looked-up in each
13762/// translation unit.
13763///
13764/// @param t the typedef type which has the same qualified name as the
13765/// typedef type we are looking for.
13766///
13767/// @param corp the corpus to look into.
13769lookup_typedef_type(const string& qualified_name, const corpus& corp)
13770{
13771 interned_string s = corp.get_environment().intern(qualified_name);
13772 return lookup_typedef_type(s, corp);
13773}
13774
13775/// Look into a given corpus to find a typedef type which has a
13776/// given qualified name.
13777///
13778/// If the per-corpus type map is non-empty (because the corpus allows
13779/// the One Definition Rule) then the type islooked up in that
13780/// per-corpus type map. Otherwise, the type is looked-up in each
13781/// translation unit.
13782///
13783/// @param qualified_name the qualified name of the typedef type to
13784/// look for.
13785///
13786/// @param corp the corpus to look into.
13788lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
13789{
13791
13792 typedef_decl_sptr result =
13793 lookup_type_in_map<typedef_decl>(qualified_name, m);
13794 if (!result)
13795 result = lookup_typedef_type_through_translation_units(qualified_name,
13796 corp);
13797
13798 return result;
13799}
13800
13801/// Lookup a @ref typedef_decl from a corpus, by its location.
13802///
13803/// @param loc the location to consider.
13804///
13805/// @param corp the corpus to consider.
13806///
13807/// @return the typedef_decl found, if any.
13810{
13813 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
13814
13815 return result;
13816}
13817
13818/// Lookup a @ref typedef_decl from a corpus, by its location.
13819///
13820/// @param loc the location to consider.
13821///
13822/// @param corp the corpus to consider.
13823///
13824/// @return the typedef_decl found, if any.
13826lookup_typedef_type_per_location(const string &loc, const corpus &corp)
13827{
13828 const environment& env = corp.get_environment();
13829 return lookup_typedef_type_per_location(env.intern(loc), corp);
13830}
13831
13832/// Look into a corpus to find a class, union or typedef type which
13833/// has a given qualified name.
13834///
13835/// If the per-corpus type map is non-empty (because the corpus allows
13836/// the One Definition Rule) then the type islooked up in that
13837/// per-corpus type map. Otherwise, the type is looked-up in each
13838/// translation unit.
13839///
13840/// @param qualified_name the name of the type to find.
13841///
13842/// @param corp the corpus to look into.
13843///
13844/// @return the typedef or class type found.
13845type_base_sptr
13846lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
13847{
13848 type_base_sptr result = lookup_class_type(qualified_name, corp);
13849 if (!result)
13850 result = lookup_union_type(qualified_name, corp);
13851
13852 if (!result)
13853 result = lookup_typedef_type(qualified_name, corp);
13854 return result;
13855}
13856
13857/// Look into a corpus to find a class, typedef or enum type which has
13858/// a given qualified name.
13859///
13860/// If the per-corpus type map is non-empty (because the corpus allows
13861/// the One Definition Rule) then the type islooked up in that
13862/// per-corpus type map. Otherwise, the type is looked-up in each
13863/// translation unit.
13864///
13865/// @param qualified_name the qualified name of the type to look for.
13866///
13867/// @param corp the corpus to look into.
13868///
13869/// @return the typedef, class or enum type found.
13870type_base_sptr
13871lookup_class_typedef_or_enum_type(const string& qualified_name,
13872 const corpus& corp)
13873{
13874 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
13875 if (!result)
13876 result = lookup_enum_type(qualified_name, corp);
13877
13878 return result;
13879}
13880
13881/// Look into a given corpus to find a qualified type which has the
13882/// same qualified name as a given type.
13883///
13884/// @param t the type which has the same qualified name as the
13885/// qualified type we are looking for.
13886///
13887/// @param corp the corpus to look into.
13888///
13889/// @return the qualified type found.
13890qualified_type_def_sptr
13892{
13894 return lookup_qualified_type(s, corp);
13895}
13896
13897/// Look into a given corpus to find a qualified type which has a
13898/// given qualified name.
13899///
13900/// @param qualified_name the qualified name of the type to look for.
13901///
13902/// @param corp the corpus to look into.
13903///
13904/// @return the type found.
13905qualified_type_def_sptr
13906lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
13907{
13909 corp.get_types().qualified_types();
13910
13911 qualified_type_def_sptr result =
13912 lookup_type_in_map<qualified_type_def>(qualified_name, m);
13913
13914 if (!result)
13915 result = lookup_qualified_type_through_translation_units(qualified_name,
13916 corp);
13917
13918 return result;
13919}
13920
13921/// Look into a given corpus to find a pointer type which has the same
13922/// qualified name as a given pointer type.
13923///
13924/// @param t the pointer type which has the same qualified name as the
13925/// type we are looking for.
13926///
13927/// @param corp the corpus to look into.
13928///
13929/// @return the pointer type found.
13932{
13934 return lookup_pointer_type(s, corp);
13935}
13936
13937/// Look into a given corpus to find a pointer type which has a given
13938/// qualified name.
13939///
13940/// If the per-corpus type map is non-empty (because the corpus allows
13941/// the One Definition Rule) then the type islooked up in that
13942/// per-corpus type map. Otherwise, the type is looked-up in each
13943/// translation unit.
13944///
13945/// @param qualified_name the qualified name of the pointer type to
13946/// look for.
13947///
13948/// @param corp the corpus to look into.
13949///
13950/// @return the pointer type found.
13952lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
13953{
13955
13956 pointer_type_def_sptr result =
13957 lookup_type_in_map<pointer_type_def>(qualified_name, m);
13958 if (!result)
13959 result = lookup_pointer_type_through_translation_units(qualified_name,
13960 corp);
13961
13962 return result;
13963}
13964
13965/// Look into a given corpus to find a reference type which has the
13966/// same qualified name as a given reference type.
13967///
13968/// If the per-corpus type map is non-empty (because the corpus allows
13969/// the One Definition Rule) then the type islooked up in that
13970/// per-corpus type map. Otherwise, the type is looked-up in each
13971/// translation unit.
13972///
13973/// @param t the reference type which has the same qualified name as
13974/// the reference type we are looking for.
13975///
13976/// @param corp the corpus to look into.
13977///
13978/// @return the reference type found.
13981{
13983 return lookup_reference_type(s, corp);
13984}
13985
13986/// Look into a given corpus to find a reference type which has a
13987/// given qualified name.
13988///
13989/// If the per-corpus type map is non-empty (because the corpus allows
13990/// the One Definition Rule) then the type islooked up in that
13991/// per-corpus type map. Otherwise, the type is looked-up in each
13992/// translation unit.
13993///
13994/// @param qualified_name the qualified name of the reference type to
13995/// look for.
13996///
13997/// @param corp the corpus to look into.
13998///
13999/// @return the reference type found.
14001lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
14002{
14004 corp.get_types().reference_types();
14005
14007 lookup_type_in_map<reference_type_def>(qualified_name, m);
14008 if (!result)
14009 result = lookup_reference_type_through_translation_units(qualified_name,
14010 corp);
14011
14012 return result;
14013}
14014
14015/// Look into a given corpus to find an array type which has a given
14016/// qualified name.
14017///
14018/// If the per-corpus type map is non-empty (because the corpus allows
14019/// the One Definition Rule) then the type islooked up in that
14020/// per-corpus type map. Otherwise, the type is looked-up in each
14021/// translation unit.
14022///
14023/// @param qualified_name the qualified name of the array type to look
14024/// for.
14025///
14026/// @param corp the corpus to look into.
14027///
14028/// @return the array type found.
14031{
14033 return lookup_array_type(s, corp);
14034}
14035
14036/// Look into a given corpus to find an array type which has the same
14037/// qualified name as a given array type.
14038///
14039/// If the per-corpus type map is non-empty (because the corpus allows
14040/// the One Definition Rule) then the type islooked up in that
14041/// per-corpus type map. Otherwise, the type is looked-up in each
14042/// translation unit.
14043///
14044/// @param t the type which has the same qualified name as the type we
14045/// are looking for.
14046///
14047/// @param corp the corpus to look into.
14048///
14049/// @return the type found.
14051lookup_array_type(const interned_string& qualified_name, const corpus& corp)
14052{
14054
14055 array_type_def_sptr result =
14056 lookup_type_in_map<array_type_def>(qualified_name, m);
14057 if (!result)
14058 result = lookup_array_type_through_translation_units(qualified_name, corp);
14059
14060 return result;
14061}
14062
14063/// Look into a given corpus to find a function type which has the same
14064/// qualified name as a given function 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 t the function type which has the same qualified name as
14072/// the function type we are looking for.
14073///
14074/// @param corp the corpus to look into.
14075///
14076/// @return the function type found.
14079{
14080 interned_string type_name = get_type_name(t);
14081 return lookup_function_type(type_name, corp);
14082}
14083
14084/// Look into a given corpus to find a function type which has the same
14085/// qualified name as a given function type.
14086///
14087/// If the per-corpus type map is non-empty (because the corpus allows
14088/// the One Definition Rule) then the type islooked up in that
14089/// per-corpus type map. Otherwise, the type is looked-up in each
14090/// translation unit.
14091///
14092/// @param t the function type which has the same qualified name as
14093/// the function type we are looking for.
14094///
14095/// @param corp the corpus to look into.
14096///
14097/// @return the function type found.
14100 const corpus& corpus)
14101{
14102 if (fn_t)
14103 return lookup_function_type(*fn_t, corpus);
14104 return function_type_sptr();
14105}
14106
14107/// Look into a given corpus to find a function type which has a given
14108/// qualified name.
14109///
14110/// If the per-corpus type map is non-empty (because the corpus allows
14111/// the One Definition Rule) then the type islooked up in that
14112/// per-corpus type map. Otherwise, the type is looked-up in each
14113/// translation unit.
14114///
14115/// @param qualified_name the qualified name of the function type to
14116/// look for.
14117///
14118/// @param corp the corpus to look into.
14119///
14120/// @return the function type found.
14122lookup_function_type(const interned_string& qualified_name, const corpus& corp)
14123{
14125
14126 function_type_sptr result =
14127 lookup_type_in_map<function_type>(qualified_name, m);
14128 if (!result)
14129 result = lookup_function_type_through_translation_units(qualified_name,
14130 corp);
14131
14132 return result;
14133}
14134
14135/// Look into a given corpus to find a type which has a given
14136/// qualified name.
14137///
14138/// If the per-corpus type map is non-empty (because the corpus allows
14139/// the One Definition Rule) then the type islooked up in that
14140/// per-corpus type map. Otherwise, the type is looked-up in each
14141/// translation unit.
14142///
14143/// @param qualified_name the qualified name of the function type to
14144/// look for.
14145///
14146/// @param corp the corpus to look into.
14147///
14148/// @return the function type found.
14149type_base_sptr
14150lookup_type(const interned_string& n, const corpus& corp)
14151{
14152 type_base_sptr result;
14153
14154 ((result = lookup_basic_type(n, corp))
14155 || (result = lookup_class_type(n, corp))
14156 || (result = lookup_union_type(n, corp))
14157 || (result = lookup_enum_type(n, corp))
14158 || (result = lookup_typedef_type(n, corp))
14159 || (result = lookup_qualified_type(n, corp))
14160 || (result = lookup_pointer_type(n, corp))
14161 || (result = lookup_reference_type(n, corp))
14162 || (result = lookup_array_type(n, corp))
14163 || (result= lookup_function_type(n, corp)));
14164
14165 return result;
14166}
14167
14168/// Lookup a type from a corpus, by its location.
14169///
14170/// @param loc the location to consider.
14171///
14172/// @param corp the corpus to look the type from.
14173///
14174/// @return the resulting type, if any found.
14175type_base_sptr
14177{
14178 // TODO: finish this.
14179
14180 //TODO: when we fully support types indexed by their location, this
14181 //function should return a vector of types because at each location,
14182 //there can be several types that are defined (yay, C and C++,
14183 //*sigh*).
14184
14185 type_base_sptr result;
14186 ((result = lookup_basic_type_per_location(loc, corp))
14187 || (result = lookup_class_type_per_location(loc, corp))
14188 || (result = lookup_union_type_per_location(loc, corp))
14189 || (result = lookup_enum_type_per_location(loc, corp))
14190 || (result = lookup_typedef_type_per_location(loc, corp)));
14191
14192 return result;
14193}
14194
14195/// Look into a given corpus to find a type
14196///
14197/// If the per-corpus type map is non-empty (because the corpus allows
14198/// the One Definition Rule) then the type islooked up in that
14199/// per-corpus type map. Otherwise, the type is looked-up in each
14200/// translation unit.
14201///
14202/// @param qualified_name the qualified name of the function type to
14203/// look for.
14204///
14205/// @param corp the corpus to look into.
14206///
14207/// @return the function type found.
14208type_base_sptr
14209lookup_type(const type_base&t, const corpus& corp)
14210{
14212 return lookup_type(n, corp);
14213}
14214
14215/// Look into a given corpus to find a type
14216///
14217/// If the per-corpus type map is non-empty (because the corpus allows
14218/// the One Definition Rule) then the type islooked up in that
14219/// per-corpus type map. Otherwise, the type is looked-up in each
14220/// translation unit.
14221///
14222/// @param qualified_name the qualified name of the function type to
14223/// look for.
14224///
14225/// @param corp the corpus to look into.
14226///
14227/// @return the function type found.
14228type_base_sptr
14229lookup_type(const type_base_sptr&t, const corpus& corp)
14230{
14231 if (t)
14232 return lookup_type(*t, corp);
14233 return type_base_sptr();
14234}
14235
14236/// Update the map that associates a fully qualified name of a given
14237/// type to that type.
14238///
14239///
14240/// @param type the type we are considering.
14241///
14242/// @param types_map the map to update. It's a map that assciates a
14243/// fully qualified name of a type to the type itself.
14244///
14245/// @param use_type_name_as_key if true, use the name of the type as
14246/// the key to look it up later. If false, then use the location of
14247/// the type as a key to look it up later.
14248///
14249/// @return true iff the type was added to the map.
14250template<typename TypeKind>
14251bool
14252maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
14254 bool use_type_name_as_key = true)
14255{
14257
14258 if (use_type_name_as_key)
14259 s = get_type_name(type);
14260 else if (location l = type->get_location())
14261 {
14262 string str = l.expand();
14263 s = type->get_environment().intern(str);
14264 }
14265
14266 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14267 bool result = false;
14268
14269 if (i == types_map.end())
14270 {
14271 types_map[s].push_back(type);
14272 result = true;
14273 }
14274 else
14275 i->second.push_back(type);
14276
14277 return result;
14278}
14279
14280/// This is the specialization for type @ref class_decl of the
14281/// function template:
14282///
14283/// maybe_update_types_lookup_map<T>(scope_decl*,
14284/// const shared_ptr<T>&,
14285/// istring_type_base_wptrs_map_type&)
14286///
14287/// @param class_type the type to consider.
14288///
14289/// @param types_map the type map to update.
14290///
14291/// @return true iff the type was added to the map.
14292template<>
14293bool
14296 bool use_type_name_as_key)
14297{
14298 class_decl_sptr type = class_type;
14299
14300 bool update_qname_map = true;
14301 if (type->get_is_declaration_only())
14302 {
14303 // Let's try to look through decl-only classes to get their
14304 // definition. But if the class doesn't have a definition then
14305 // we'll keep it.
14306 if (class_decl_sptr def =
14307 is_class_type(class_type->get_definition_of_declaration()))
14308 type = def;
14309 }
14310
14311 if (!update_qname_map)
14312 return false;
14313
14315 if (use_type_name_as_key)
14316 {
14317 string qname = type->get_qualified_name();
14318 s = type->get_environment().intern(qname);
14319 }
14320 else if (location l = type->get_location())
14321 {
14322 string str = l.expand();
14323 s = type->get_environment().intern(str);
14324 }
14325
14326 bool result = false;
14327 istring_type_base_wptrs_map_type::iterator i = map.find(s);
14328 if (i == map.end())
14329 {
14330 map[s].push_back(type);
14331 result = true;
14332 }
14333 else
14334 i->second.push_back(type);
14335
14336 return result;
14337}
14338
14339/// This is the specialization for type @ref function_type of the
14340/// function template:
14341///
14342/// maybe_update_types_lookup_map<T>(scope_decl*,
14343/// const shared_ptr<T>&,
14344/// istring_type_base_wptrs_map_type&)
14345///
14346/// @param scope the scope of the type to consider.
14347///
14348/// @param class_type the type to consider.
14349///
14350/// @param types_map the type map to update.
14351///
14352/// @return true iff the type was added to the map.
14353template<>
14354bool
14356(const function_type_sptr& type,
14358 bool /*use_type_name_as_key*/)
14359{
14360 bool result = false;
14362 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14363 if (i == types_map.end())
14364 {
14365 types_map[s].push_back(type);
14366 result = true;
14367 }
14368 else
14369 i->second.push_back(type);
14370
14371 return result;
14372}
14373
14374/// Update the map that associates the fully qualified name of a basic
14375/// type with the type itself.
14376///
14377/// The per-translation unit type map is updated if no type with this
14378/// name was already existing in that map.
14379///
14380/// If no type with this name did already exist in the per-corpus type
14381/// map, then that per-corpus type map is updated. Otherwise, that
14382/// type is erased from that per-corpus map.
14383///
14384/// @param basic_type the basic type to consider.
14385void
14387{
14388 if (translation_unit *tu = basic_type->get_translation_unit())
14389 maybe_update_types_lookup_map<type_decl>
14390 (basic_type, tu->get_types().basic_types());
14391
14392 if (corpus *type_corpus = basic_type->get_corpus())
14393 {
14394 maybe_update_types_lookup_map<type_decl>
14395 (basic_type,
14396 type_corpus->priv_->get_types().basic_types());
14397
14398 maybe_update_types_lookup_map<type_decl>
14399 (basic_type,
14400 type_corpus->get_type_per_loc_map().basic_types(),
14401 /*use_type_name_as_key*/false);
14402
14403 if (corpus *group = type_corpus->get_group())
14404 {
14405 maybe_update_types_lookup_map<type_decl>
14406 (basic_type,
14407 group->priv_->get_types().basic_types());
14408
14409 maybe_update_types_lookup_map<type_decl>
14410 (basic_type,
14411 group->get_type_per_loc_map().basic_types(),
14412 /*use_type_name_as_key*/false);
14413 }
14414 }
14415
14416}
14417
14418/// Update the map that associates the fully qualified name of a class
14419/// type with the type itself.
14420///
14421/// The per-translation unit type map is updated if no type with this
14422/// name was already existing in that map.
14423///
14424/// If no type with this name did already exist in the per-corpus type
14425/// map, then that per-corpus type map is updated. Otherwise, that
14426/// type is erased from that per-corpus map.
14427///
14428/// @param class_type the class type to consider.
14429void
14431{
14432 if (translation_unit *tu = class_type->get_translation_unit())
14434 (class_type, tu->get_types().class_types());
14435
14436 if (corpus *type_corpus = class_type->get_corpus())
14437 {
14439 (class_type,
14440 type_corpus->priv_->get_types().class_types());
14441
14443 (class_type,
14444 type_corpus->get_type_per_loc_map().class_types(),
14445 /*use_type_name_as_key*/false);
14446
14447 if (corpus *group = type_corpus->get_group())
14448 {
14450 (class_type,
14451 group->priv_->get_types().class_types());
14452
14454 (class_type,
14455 group->get_type_per_loc_map().class_types(),
14456 /*use_type_name_as_key*/false);
14457 }
14458 }
14459}
14460
14461/// Update the map that associates the fully qualified name of a union
14462/// type with the type itself.
14463///
14464/// The per-translation unit type map is updated if no type with this
14465/// name was already existing in that map.
14466///
14467/// If no type with this name did already exist in the per-corpus type
14468/// map, then that per-corpus type map is updated. Otherwise, that
14469/// type is erased from that per-corpus map.
14470///
14471/// @param union_type the union type to consider.
14472void
14473maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14474{
14475 if (translation_unit *tu = union_type->get_translation_unit())
14476 maybe_update_types_lookup_map<union_decl>
14477 (union_type, tu->get_types().union_types());
14478
14479 if (corpus *type_corpus = union_type->get_corpus())
14480 {
14481 maybe_update_types_lookup_map<union_decl>
14482 (union_type,
14483 type_corpus->priv_->get_types().union_types());
14484
14485 maybe_update_types_lookup_map<union_decl>
14486 (union_type,
14487 type_corpus->get_type_per_loc_map().union_types(),
14488 /*use_type_name_as_key*/false);
14489
14490 if (corpus *group = type_corpus->get_group())
14491 {
14492 maybe_update_types_lookup_map<union_decl>
14493 (union_type,
14494 group->priv_->get_types().union_types());
14495
14496 maybe_update_types_lookup_map<union_decl>
14497 (union_type,
14498 group->get_type_per_loc_map().union_types(),
14499 /*use_type_name_as_key*/false);
14500 }
14501 }
14502}
14503
14504/// Update the map that associates the fully qualified name of an enum
14505/// type with the type itself.
14506///
14507/// The per-translation unit type map is updated if no type with this
14508/// name was already existing in that map.
14509///
14510/// If no type with this name did already exist in the per-corpus type
14511/// map, then that per-corpus type map is updated. Otherwise, that
14512/// type is erased from that per-corpus map.
14513///
14514/// @param enum_type the type to consider.
14515void
14517{
14518 if (translation_unit *tu = enum_type->get_translation_unit())
14519 maybe_update_types_lookup_map<enum_type_decl>
14520 (enum_type, tu->get_types().enum_types());
14521
14522 if (corpus *type_corpus = enum_type->get_corpus())
14523 {
14524 maybe_update_types_lookup_map<enum_type_decl>
14525 (enum_type,
14526 type_corpus->priv_->get_types().enum_types());
14527
14528 maybe_update_types_lookup_map<enum_type_decl>
14529 (enum_type,
14530 type_corpus->get_type_per_loc_map().enum_types(),
14531 /*use_type_name_as_key*/false);
14532
14533 if (corpus *group = type_corpus->get_group())
14534 {
14535 maybe_update_types_lookup_map<enum_type_decl>
14536 (enum_type,
14537 group->priv_->get_types().enum_types());
14538
14539 maybe_update_types_lookup_map<enum_type_decl>
14540 (enum_type,
14541 group->get_type_per_loc_map().enum_types(),
14542 /*use_type_name_as_key*/false);
14543 }
14544 }
14545
14546}
14547
14548/// Update the map that associates the fully qualified name of a
14549/// typedef type with the type itself.
14550///
14551/// The per-translation unit type map is updated if no type with this
14552/// name was already existing in that map.
14553///
14554/// If no type with this name did already exist in the per-corpus type
14555/// map, then that per-corpus type map is updated. Otherwise, that
14556/// type is erased from that per-corpus map.
14557///
14558/// @param typedef_type the type to consider.
14559void
14561{
14562 if (translation_unit *tu = typedef_type->get_translation_unit())
14563 maybe_update_types_lookup_map<typedef_decl>
14564 (typedef_type, tu->get_types().typedef_types());
14565
14566 if (corpus *type_corpus = typedef_type->get_corpus())
14567 {
14568 maybe_update_types_lookup_map<typedef_decl>
14569 (typedef_type,
14570 type_corpus->priv_->get_types().typedef_types());
14571
14572 maybe_update_types_lookup_map<typedef_decl>
14573 (typedef_type,
14574 type_corpus->get_type_per_loc_map().typedef_types(),
14575 /*use_type_name_as_key*/false);
14576
14577 if (corpus *group = type_corpus->get_group())
14578 {
14579 maybe_update_types_lookup_map<typedef_decl>
14580 (typedef_type,
14581 group->priv_->get_types().typedef_types());
14582
14583 maybe_update_types_lookup_map<typedef_decl>
14584 (typedef_type,
14585 group->get_type_per_loc_map().typedef_types(),
14586 /*use_type_name_as_key*/false);
14587 }
14588 }
14589}
14590
14591/// Update the map that associates the fully qualified name of a
14592/// qualified type with the type itself.
14593///
14594/// The per-translation unit type map is updated if no type with this
14595/// name was already existing in that map.
14596///
14597/// If no type with this name did already exist in the per-corpus type
14598/// map, then that per-corpus type map is updated. Otherwise, that
14599/// type is erased from that per-corpus map.
14600///
14601/// @param qualified_type the type to consider.
14602void
14603maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14604{
14605 if (translation_unit *tu = qualified_type->get_translation_unit())
14606 maybe_update_types_lookup_map<qualified_type_def>
14607 (qualified_type, tu->get_types().qualified_types());
14608
14609 if (corpus *type_corpus = qualified_type->get_corpus())
14610 {
14611 maybe_update_types_lookup_map<qualified_type_def>
14612 (qualified_type,
14613 type_corpus->priv_->get_types().qualified_types());
14614
14615 if (corpus *group = type_corpus->get_group())
14616 {
14617 maybe_update_types_lookup_map<qualified_type_def>
14618 (qualified_type,
14619 group->priv_->get_types().qualified_types());
14620 }
14621 }
14622}
14623
14624/// Update the map that associates the fully qualified name of a
14625/// pointer type with the type itself.
14626///
14627/// The per-translation unit type map is updated if no type with this
14628/// name was already existing in that map.
14629///
14630/// If no type with this name did already exist in the per-corpus type
14631/// map, then that per-corpus type map is updated. Otherwise, that
14632/// type is erased from that per-corpus map.
14633///
14634/// @param pointer_type the type to consider.
14635void
14637{
14638 if (translation_unit *tu = pointer_type->get_translation_unit())
14639 maybe_update_types_lookup_map<pointer_type_def>
14640 (pointer_type, tu->get_types().pointer_types());
14641
14642 if (corpus *type_corpus = pointer_type->get_corpus())
14643 {
14644 maybe_update_types_lookup_map<pointer_type_def>
14645 (pointer_type,
14646 type_corpus->priv_->get_types().pointer_types());
14647
14648 if (corpus *group = type_corpus->get_group())
14649 {
14650 maybe_update_types_lookup_map<pointer_type_def>
14651 (pointer_type,
14652 group->priv_->get_types().pointer_types());
14653 }
14654 }
14655}
14656
14657/// Update the map that associates the fully qualified name of a
14658/// pointer-to-member type with the type itself.
14659///
14660/// The per-translation unit type map is updated if no type with this
14661/// name was already existing in that map.
14662///
14663/// If no type with this name did already exist in the per-corpus type
14664/// map, then that per-corpus type map is updated. Otherwise, that
14665/// type is erased from that per-corpus map.
14666///
14667/// @param ptr_to_mbr_type the type to consider.
14668void
14670{
14671 if (translation_unit *tu = ptr_to_member->get_translation_unit())
14672 maybe_update_types_lookup_map<ptr_to_mbr_type>
14673 (ptr_to_member, tu->get_types().ptr_to_mbr_types());
14674
14675 if (corpus *type_corpus = ptr_to_member->get_corpus())
14676 {
14677 maybe_update_types_lookup_map<ptr_to_mbr_type>
14678 (ptr_to_member,
14679 type_corpus->priv_->get_types().ptr_to_mbr_types());
14680
14681 if (corpus *group = type_corpus->get_group())
14682 {
14683 maybe_update_types_lookup_map<ptr_to_mbr_type>
14684 (ptr_to_member,
14685 group->priv_->get_types().ptr_to_mbr_types());
14686 }
14687 }
14688}
14689
14690/// Update the map that associates the fully qualified name of a
14691/// reference type with the type itself.
14692///
14693/// The per-translation unit type map is updated if no type with this
14694/// name was already existing in that map.
14695///
14696/// If no type with this name did already exist in the per-corpus type
14697/// map, then that per-corpus type map is updated. Otherwise, that
14698/// type is erased from that per-corpus map.
14699///
14700/// @param reference_type the type to consider.
14701void
14703{
14704 if (translation_unit *tu = reference_type->get_translation_unit())
14705 maybe_update_types_lookup_map<reference_type_def>
14706 (reference_type, tu->get_types().reference_types());
14707
14708 if (corpus *type_corpus = reference_type->get_corpus())
14709 {
14710 maybe_update_types_lookup_map<reference_type_def>
14711 (reference_type,
14712 type_corpus->priv_->get_types().reference_types());
14713
14714 if (corpus *group = type_corpus->get_group())
14715 {
14716 maybe_update_types_lookup_map<reference_type_def>
14717 (reference_type,
14718 group->priv_->get_types().reference_types());
14719 }
14720 }
14721}
14722
14723/// Update the map that associates the fully qualified name of a type
14724/// with the type itself.
14725///
14726/// The per-translation unit type map is updated if no type with this
14727/// name was already existing in that map.
14728///
14729/// If no type with this name did already exist in the per-corpus type
14730/// map, then that per-corpus type map is updated. Otherwise, that
14731/// type is erased from that per-corpus map.
14732///
14733/// @param array_type the type to consider.
14734void
14736{
14737 if (translation_unit *tu = array_type->get_translation_unit())
14738 maybe_update_types_lookup_map<array_type_def>
14739 (array_type, tu->get_types().array_types());
14740
14741 if (corpus *type_corpus = array_type->get_corpus())
14742 {
14743 maybe_update_types_lookup_map<array_type_def>
14744 (array_type,
14745 type_corpus->priv_->get_types().array_types());
14746
14747 maybe_update_types_lookup_map<array_type_def>
14748 (array_type,
14749 type_corpus->get_type_per_loc_map().array_types(),
14750 /*use_type_name_as_key*/false);
14751
14752 if (corpus *group = type_corpus->get_group())
14753 {
14754 maybe_update_types_lookup_map<array_type_def>
14755 (array_type,
14756 group->priv_->get_types().array_types());
14757
14758 maybe_update_types_lookup_map<array_type_def>
14759 (array_type,
14760 group->get_type_per_loc_map().array_types(),
14761 /*use_type_name_as_key*/false);
14762 }
14763 }
14764}
14765
14766/// Update the map that associates the fully qualified name of a type
14767/// with the type itself.
14768///
14769/// The per-translation unit type map is updated if no type with this
14770/// name was already existing in that map.
14771///
14772/// If no type with this name did already exist in the per-corpus type
14773/// map, then that per-corpus type map is updated. Otherwise, that
14774/// type is erased from that per-corpus map.
14775///
14776/// @param subrange_type the type to consider.
14777void
14779(const array_type_def::subrange_sptr& subrange_type)
14780{
14781 if (translation_unit *tu = subrange_type->get_translation_unit())
14782 maybe_update_types_lookup_map<array_type_def::subrange_type>
14783 (subrange_type, tu->get_types().subrange_types());
14784
14785 if (corpus *type_corpus = subrange_type->get_corpus())
14786 {
14787 maybe_update_types_lookup_map<array_type_def::subrange_type>
14788 (subrange_type,
14789 type_corpus->priv_->get_types().subrange_types());
14790
14791 maybe_update_types_lookup_map<array_type_def::subrange_type>
14792 (subrange_type,
14793 type_corpus->get_type_per_loc_map().subrange_types(),
14794 /*use_type_name_as_key*/false);
14795
14796 if (corpus *group = subrange_type->get_corpus())
14797 {
14798 maybe_update_types_lookup_map<array_type_def::subrange_type>
14799 (subrange_type,
14800 group->priv_->get_types().subrange_types());
14801
14802 maybe_update_types_lookup_map<array_type_def::subrange_type>
14803 (subrange_type,
14804 group->get_type_per_loc_map().subrange_types(),
14805 /*use_type_name_as_key*/false);
14806 }
14807 }
14808}
14809
14810/// Update the map that associates the fully qualified name of a
14811/// function type with the type itself.
14812///
14813/// The per-translation unit type map is updated if no type with this
14814/// name was already existing in that map.
14815///
14816/// If no type with this name did already exist in the per-corpus type
14817/// map, then that per-corpus type map is updated. Otherwise, that
14818/// type is erased from that per-corpus map.
14819///
14820/// @param scope the scope of the function type.
14821/// @param fn_type the type to consider.
14822void
14824{
14825 if (translation_unit *tu = fn_type->get_translation_unit())
14827 (fn_type, tu->get_types().function_types());
14828
14829 if (corpus *type_corpus = fn_type->get_corpus())
14830 {
14832 (fn_type,
14833 type_corpus->priv_->get_types().function_types());
14834
14835 if (corpus *group = fn_type->get_corpus())
14836 {
14838 (fn_type,
14839 group->priv_->get_types().function_types());
14840 }
14841 }
14842}
14843
14844/// Update the map that associates the fully qualified name of a type
14845/// declaration with the type itself.
14846///
14847/// The per-translation unit type map is updated if no type with this
14848/// name was already existing in that map.
14849///
14850/// If no type with this name did already exist in the per-corpus type
14851/// map, then that per-corpus type map is updated. Otherwise, that
14852/// type is erased from that per-corpus map.
14853///
14854/// @param decl the declaration of the type to consider.
14855void
14856maybe_update_types_lookup_map(const decl_base_sptr& decl)
14857{
14858 if (!is_type(decl))
14859 return;
14860
14861 if (type_decl_sptr basic_type = is_type_decl(decl))
14863 else if (class_decl_sptr class_type = is_class_type(decl))
14865 else if (union_decl_sptr union_type = is_union_type(decl))
14867 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
14869 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
14870 maybe_update_types_lookup_map(typedef_type);
14871 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
14872 maybe_update_types_lookup_map(qualified_type);
14873 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
14874 maybe_update_types_lookup_map(pointer_type);
14875 else if (ptr_to_mbr_type_sptr ptr_to_member = is_ptr_to_mbr_type(decl))
14876 maybe_update_types_lookup_map(ptr_to_member);
14877 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
14878 maybe_update_types_lookup_map(reference_type);
14879 else if (array_type_def_sptr array_type = is_array_type(decl))
14881 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
14882 maybe_update_types_lookup_map(subrange_type);
14883 else if (function_type_sptr fn_type = is_function_type(decl))
14885 else
14887}
14888
14889/// Update the map that associates the fully qualified name of a type
14890/// with the type itself.
14891///
14892/// The per-translation unit type map is updated if no type with this
14893/// name was already existing in that map.
14894///
14895/// If no type with this name did already exist in the per-corpus type
14896/// map, then that per-corpus type map is updated. Otherwise, that
14897/// type is erased from that per-corpus map.
14898///
14899/// @param type the type to consider.
14900void
14901maybe_update_types_lookup_map(const type_base_sptr& type)
14902{
14903 if (decl_base_sptr decl = get_type_declaration(type))
14905 else if (function_type_sptr fn_type = is_function_type(type))
14907 else
14909}
14910
14911//--------------------------------
14912// </type and decls lookup stuff>
14913// ------------------------------
14914
14915/// In a translation unit, lookup a given type or synthesize it if
14916/// it's a qualified type.
14917///
14918/// So this function first looks the type up in the translation unit.
14919/// If it's found, then OK, it's returned. Otherwise, if it's a
14920/// qualified, reference or pointer or function type (a composite
14921/// type), lookup the underlying type, synthesize the type we want
14922/// from it and return it.
14923///
14924/// If the underlying types is not not found, then give up and return
14925/// nil.
14926///
14927/// @return the type that was found or the synthesized type.
14928type_base_sptr
14929synthesize_type_from_translation_unit(const type_base_sptr& type,
14930 translation_unit& tu)
14931{
14932 type_base_sptr result;
14933
14934 result = lookup_type(type, tu);
14935
14936 if (!result)
14937 {
14938 if (qualified_type_def_sptr qual = is_qualified_type(type))
14939 {
14940 type_base_sptr underlying_type =
14941 synthesize_type_from_translation_unit(qual->get_underlying_type(),
14942 tu);
14943 if (underlying_type)
14944 {
14945 result.reset(new qualified_type_def(underlying_type,
14946 qual->get_cv_quals(),
14947 qual->get_location()));
14948 }
14949 }
14950 else if (pointer_type_def_sptr p = is_pointer_type(type))
14951 {
14952 type_base_sptr pointed_to_type =
14953 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
14954 tu);
14955 if (pointed_to_type)
14956 {
14957 result.reset(new pointer_type_def(pointed_to_type,
14958 p->get_size_in_bits(),
14959 p->get_alignment_in_bits(),
14960 p->get_location()));
14961 }
14962 }
14963 else if (reference_type_def_sptr r = is_reference_type(type))
14964 {
14965 type_base_sptr pointed_to_type =
14966 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
14967 if (pointed_to_type)
14968 {
14969 result.reset(new reference_type_def(pointed_to_type,
14970 r->is_lvalue(),
14971 r->get_size_in_bits(),
14972 r->get_alignment_in_bits(),
14973 r->get_location()));
14974 }
14975 }
14976 else if (function_type_sptr f = is_function_type(type))
14978
14979 if (result)
14980 {
14982 canonicalize(result);
14983 }
14984 }
14985
14986 if (result)
14987 tu.priv_->synthesized_types_.push_back(result);
14988
14989 return result;
14990}
14991
14992/// In a translation unit, lookup the sub-types that make up a given
14993/// function type and if the sub-types are all found, synthesize and
14994/// return a function_type with them.
14995///
14996/// This function is like lookup_function_type_in_translation_unit()
14997/// execept that it constructs the function type from the sub-types
14998/// found in the translation, rather than just looking for the
14999/// function types held by the translation unit. This can be useful
15000/// if the translation unit doesnt hold the function type we are
15001/// looking for (i.e, lookup_function_type_in_translation_unit()
15002/// returned NULL) but we still want to see if the sub-types of the
15003/// function types are present in the translation unit.
15004///
15005/// @param fn_type the function type to consider.
15006///
15007/// @param tu the translation unit to look into.
15008///
15009/// @return the resulting synthesized function type if all its
15010/// sub-types have been found, NULL otherwise.
15013 translation_unit& tu)
15014{
15016
15017 const environment& env = tu.get_environment();
15018
15019 type_base_sptr return_type = fn_type.get_return_type();
15020 type_base_sptr result_return_type;
15021 if (!return_type || env.is_void_type(return_type))
15022 result_return_type = env.get_void_type();
15023 else
15024 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
15025 if (!result_return_type)
15026 return nil;
15027
15029 type_base_sptr parm_type;
15031 for (function_type::parameters::const_iterator i =
15032 fn_type.get_parameters().begin();
15033 i != fn_type.get_parameters().end();
15034 ++i)
15035 {
15036 type_base_sptr t = (*i)->get_type();
15037 parm_type = synthesize_type_from_translation_unit(t, tu);
15038 if (!parm_type)
15039 return nil;
15040 parm.reset(new function_decl::parameter(parm_type,
15041 (*i)->get_index(),
15042 (*i)->get_name(),
15043 (*i)->get_location(),
15044 (*i)->get_variadic_marker(),
15045 (*i)->get_is_artificial()));
15046 parms.push_back(parm);
15047 }
15048
15049 class_or_union_sptr class_type;
15050 const method_type* method = is_method_type(&fn_type);
15051 if (method)
15052 {
15053 class_type = is_class_or_union_type
15055 ABG_ASSERT(class_type);
15056 }
15057
15058 function_type_sptr result_fn_type;
15059
15060 if (class_type)
15061 result_fn_type.reset(new method_type(result_return_type,
15062 class_type,
15063 parms,
15064 method->get_is_const(),
15065 fn_type.get_size_in_bits(),
15066 fn_type.get_alignment_in_bits()));
15067 else
15068 result_fn_type.reset(new function_type(result_return_type,
15069 parms,
15070 fn_type.get_size_in_bits(),
15071 fn_type.get_alignment_in_bits()));
15072
15073 tu.priv_->synthesized_types_.push_back(result_fn_type);
15074 tu.bind_function_type_life_time(result_fn_type);
15075
15076 canonicalize(result_fn_type);
15077 return result_fn_type;
15078}
15079
15080/// Demangle a C++ mangled name and return the resulting string
15081///
15082/// @param mangled_name the C++ mangled name to demangle.
15083///
15084/// @return the resulting mangled name.
15085string
15086demangle_cplus_mangled_name(const string& mangled_name)
15087{
15088 if (mangled_name.empty())
15089 return "";
15090
15091 size_t l = 0;
15092 int status = 0;
15093 char * str = abi::__cxa_demangle(mangled_name.c_str(),
15094 NULL, &l, &status);
15095 string demangled_name = mangled_name;
15096 if (str)
15097 {
15098 ABG_ASSERT(status == 0);
15099 demangled_name = str;
15100 free(str);
15101 str = 0;
15102 }
15103 return demangled_name;
15104}
15105
15106/// Return either the type given in parameter if it's non-null, or the
15107/// void type.
15108///
15109/// @param t the type to consider.
15110///
15111/// @param env the environment to use. If NULL, just abort the
15112/// process.
15113///
15114/// @return either @p t if it is non-null, or the void type.
15115type_base_sptr
15116type_or_void(const type_base_sptr t, const environment& env)
15117{
15118 type_base_sptr r;
15119
15120 if (t)
15121 r = t;
15122 else
15123 r = type_base_sptr(env.get_void_type());
15124
15125 return r;
15126}
15127
15128global_scope::~global_scope()
15129{
15130}
15131
15132static bool
15133maybe_propagate_canonical_type(const type_base& lhs_type,
15134 const type_base& rhs_type);
15135
15136/// Test if two types are eligible to the "Linux Kernel Fast Type
15137/// Comparison Optimization", a.k.a LKFTCO.
15138///
15139/// Two types T1 and T2 (who are presumably of the same name and kind)
15140/// are eligible to the LKFTCO if they fulfill the following criteria/
15141///
15142/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
15143/// either class, union or enums.
15144///
15145/// 2/ They are defined in the same translation unit.
15146///
15147/// @param t1 the first type to consider.
15148///
15149/// @param t2 the second type to consider.
15150///
15151/// @return true iff t1 and t2 are eligible to the LKFTCO.
15152static bool
15153types_defined_same_linux_kernel_corpus_public(const type_base& t1,
15154 const type_base& t2)
15155{
15156 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
15157 string t1_file_path, t2_file_path;
15158
15159 /// If the t1 (and t2) are classes/unions/enums from the same linux
15160 /// kernel corpus, let's move on. Otherwise bail out.
15161 if (!(t1_corpus && t2_corpus
15162 && t1_corpus == t2_corpus
15163 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
15164 && (is_class_or_union_type(&t1)
15165 || is_enum_type(&t1))))
15166 return false;
15167
15168 class_or_union *c1 = 0, *c2 = 0;
15169 c1 = is_class_or_union_type(&t1);
15170 c2 = is_class_or_union_type(&t2);
15171
15172 // Two anonymous class types with no naming typedefs cannot be
15173 // eligible to this optimization.
15174 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
15175 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
15176 return false;
15177
15178 // Two anonymous classes with naming typedefs should have the same
15179 // typedef name.
15180 if (c1
15181 && c2
15182 && c1->get_is_anonymous() && c1->get_naming_typedef()
15183 && c2->get_is_anonymous() && c2->get_naming_typedef())
15184 if (c1->get_naming_typedef()->get_name()
15185 != c2->get_naming_typedef()->get_name())
15186 return false;
15187
15188 // Two anonymous enum types cannot be eligible to this optimization.
15189 if (const enum_type_decl *e1 = is_enum_type(&t1))
15190 if (const enum_type_decl *e2 = is_enum_type(&t2))
15191 if (e1->get_is_anonymous() || e2->get_is_anonymous())
15192 return false;
15193
15194 // Look through declaration-only types. That is, get the associated
15195 // definition type.
15198
15199 if (c1 && c2)
15200 {
15201 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
15202 {
15203 if (c1->get_environment().decl_only_class_equals_definition())
15204 // At least one of classes/union is declaration-only.
15205 // Because we are in a context in which a declaration-only
15206 // class/union is equal to all definitions of that
15207 // class/union, we can assume that the two types are
15208 // equal.
15209 return true;
15210 }
15211 }
15212
15213 if (t1.get_size_in_bits() != t2.get_size_in_bits())
15214 return false;
15215
15216 // Look at the file names of the locations of t1 and t2. If they
15217 // are equal, then t1 and t2 are defined in the same file.
15218 {
15219 location l;
15220
15221 if (c1)
15222 l = c1->get_location();
15223 else
15224 l = dynamic_cast<const decl_base&>(t1).get_location();
15225
15226 unsigned line = 0, col = 0;
15227 if (l)
15228 l.expand(t1_file_path, line, col);
15229 if (c2)
15230 l = c2->get_location();
15231 else
15232 l = dynamic_cast<const decl_base&>(t2).get_location();
15233 if (l)
15234 l.expand(t2_file_path, line, col);
15235 }
15236
15237 if (t1_file_path.empty() || t2_file_path.empty())
15238 return false;
15239
15240 if (t1_file_path == t2_file_path)
15241 return true;
15242
15243 return false;
15244}
15245
15246
15247/// Compare a type T against a canonical type.
15248///
15249/// This function is called during the canonicalization process of the
15250/// type T. T is called the "candidate type" because it's in the
15251/// process of being canonicalized. Meaning, it's going to be
15252/// compared to a canonical type C. If T equals C, then the canonical
15253/// type of T is C.
15254///
15255/// The purpose of this function is to allow the debugging of the
15256/// canonicalization of T, if that debugging is activated by
15257/// configuring the libabigail package with
15258/// --enable-debug-type-canonicalization and by running "abidw
15259/// --debug-tc". In that case, T is going to be compared to C twice:
15260/// once with canonical equality and once with structural equality.
15261/// The two comparisons must be equal. Otherwise, the
15262/// canonicalization process is said to be faulty and this function
15263/// aborts.
15264///
15265/// This is a sub-routine of type_base::get_canonical_type_for.
15266///
15267/// @param canonical_type the canonical type to compare the candidate
15268/// type against.
15269///
15270/// @param candidate_type the candidate type to compare against the
15271/// canonical type.
15272///
15273/// @return true iff @p canonical_type equals @p candidate_type.
15274///
15275static bool
15276compare_types_during_canonicalization(const type_base& canonical_type,
15277 const type_base& candidate_type)
15278{
15279#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
15280 const environment& env = canonical_type.get_environment();
15281 if (env.debug_type_canonicalization_is_on())
15282 {
15283 bool canonical_equality = false, structural_equality = false;
15284 env.priv_->use_canonical_type_comparison_ = false;
15285 structural_equality = canonical_type == candidate_type;
15286 env.priv_->use_canonical_type_comparison_ = true;
15287 canonical_equality = canonical_type == candidate_type;
15288 if (canonical_equality != structural_equality)
15289 {
15290 std::cerr << "structural & canonical equality different for type: "
15291 << canonical_type.get_pretty_representation(true, true)
15292 << std::endl;
15294 }
15295 return structural_equality;
15296 }
15297#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
15298 return canonical_type == candidate_type;
15299}
15300
15301/// Compare a canonical type against a candidate canonical type.
15302///
15303/// This is ultimately a sub-routine of the
15304/// type_base::get_canonical_type_for().
15305///
15306/// The goal of this function is to ease debugging because it can be
15307/// called from within type_base::get_canonical_type_for() from the
15308/// prompt of the debugger (with some breakpoint appropriately set) to
15309/// debug the comparison that happens during type canonicalization,
15310/// between a candidate type being canonicalized, and an existing
15311/// canonical type that is registered in the system, in as returned by
15312/// environment::get_canonical_types()
15313///
15314/// @param canonical_type the canonical type to consider.
15315///
15316/// @param candidate_type the candidate type that is being
15317/// canonicalized, and thus compared to @p canonical_type.
15318///
15319/// @return true iff @p canonical_type compares equal to @p
15320/// candidate_type.
15321static bool
15322compare_canonical_type_against_candidate(const type_base& canonical_type,
15323 const type_base& candidate_type)
15324{
15325 environment& env = const_cast<environment&>(canonical_type.get_environment());
15326
15327 // Before the "*it == it" comparison below is done, let's
15328 // perform on-the-fly-canonicalization. For C types, let's
15329 // consider that an unresolved struct declaration 'struct S'
15330 // is different from a definition 'struct S'. This is
15331 // because normally, at this point all the declarations of
15332 // struct S that are compatible with the definition of
15333 // struct S have already been resolved to that definition,
15334 // during the DWARF parsing. The remaining unresolved
15335 // declaration are thus considered different. With this
15336 // setup we can properly handle cases of two *different*
15337 // struct S being defined in the same binary (in different
15338 // translation units), and a third struct S being only
15339 // declared as an opaque type in a third translation unit of
15340 // its own, with no definition in there. In that case, the
15341 // declaration-only struct S should be left alone and not
15342 // resolved to any of the two definitions of struct S.
15343 bool saved_decl_only_class_equals_definition =
15344 env.decl_only_class_equals_definition();
15345 env.do_on_the_fly_canonicalization(true);
15346 // Compare types by considering that decl-only classes don't
15347 // equal their definition.
15348 env.decl_only_class_equals_definition(false);
15349 env.priv_->allow_type_comparison_results_caching(true);
15350 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
15351 candidate_type)
15352 || compare_types_during_canonicalization(canonical_type,
15353 candidate_type));
15354 // Restore the state of the on-the-fly-canonicalization and
15355 // the decl-only-class-being-equal-to-a-matching-definition
15356 // flags.
15357 env.priv_->clear_type_comparison_results_cache();
15358 env.priv_->allow_type_comparison_results_caching(false);
15359 env.do_on_the_fly_canonicalization(false);
15360 env.decl_only_class_equals_definition
15361 (saved_decl_only_class_equals_definition);
15362 return equal;
15363}
15364
15365/// Compare a canonical type against a candidate canonical type.
15366///
15367/// This is ultimately a sub-routine of the
15368/// type_base::get_canonical_type_for().
15369///
15370/// The goal of this function is to ease debugging because it can be
15371/// called from within type_base::get_canonical_type_for() from the
15372/// prompt of the debugger (with some breakpoint appropriately set) to
15373/// debug the comparison that happens during type canonicalization,
15374/// between a candidate type being canonicalized, and an existing
15375/// canonical type that is registered in the system, in as returned by
15376/// environment::get_canonical_types()
15377///
15378/// @param canonical_type the canonical type to consider.
15379///
15380/// @param candidate_type the candidate type that is being
15381/// canonicalized, and thus compared to @p canonical_type.
15382///
15383/// @return true iff @p canonical_type compares equal to @p
15384/// candidate_type.
15385static bool
15386compare_canonical_type_against_candidate(const type_base* canonical_type,
15387 const type_base* candidate_type)
15388{
15389 return compare_canonical_type_against_candidate(*canonical_type,
15390 *candidate_type);
15391}
15392
15393/// Compare a canonical type against a candidate canonical type.
15394///
15395/// This is ultimately a sub-routine of the
15396/// type_base::get_canonical_type_for().
15397///
15398/// The goal of this function is to ease debugging because it can be
15399/// called from within type_base::get_canonical_type_for() from the
15400/// prompt of the debugger (with some breakpoint appropriately set) to
15401/// debug the comparison that happens during type canonicalization,
15402/// between a candidate type being canonicalized, and an existing
15403/// canonical type that is registered in the system, in as returned by
15404/// environment::get_canonical_types()
15405///
15406/// @param canonical_type the canonical type to consider.
15407///
15408/// @param candidate_type the candidate type that is being
15409/// canonicalized, and thus compared to @p canonical_type.
15410///
15411/// @return true iff @p canonical_type compares equal to @p
15412/// candidate_type.
15413static bool
15414compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15415 const type_base_sptr& candidate_type)
15416{
15417 return compare_canonical_type_against_candidate(canonical_type.get(),
15418 candidate_type.get());
15419}
15420
15421/// Compute the canonical type for a given instance of @ref type_base.
15422///
15423/// Consider two types T and T'. The canonical type of T, denoted
15424/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
15425/// otherwise, to compare two types, one just needs to compare their
15426/// canonical types using pointer equality. That makes type
15427/// comparison faster than the structural comparison performed by the
15428/// abigail::ir::equals() overloads.
15429///
15430/// If there is not yet any canonical type for @p t, then @p t is its
15431/// own canonical type. Otherwise, this function returns the
15432/// canonical type of @p t which is the canonical type that has the
15433/// same hash value as @p t and that structurally equals @p t. Note
15434/// that after invoking this function, the life time of the returned
15435/// canonical time is then equals to the life time of the current
15436/// process.
15437///
15438/// @param t a smart pointer to instance of @ref type_base we want to
15439/// compute a canonical type for.
15440///
15441/// @return the canonical type for the current instance of @ref
15442/// type_base.
15443type_base_sptr
15444type_base::get_canonical_type_for(type_base_sptr t)
15445{
15446 if (!t)
15447 return t;
15448
15449 environment& env = const_cast<environment&>(t->get_environment());
15450
15452 // This type should not be canonicalized!
15453 return type_base_sptr();
15454
15455 if (is_decl(t))
15457
15458 // Look through decl-only types (classes, unions and enums)
15459 bool decl_only_class_equals_definition =
15460 (odr_is_relevant(*t) || env.decl_only_class_equals_definition());
15461
15462 class_or_union_sptr class_or_union = is_class_or_union_type(t);
15463
15464 // In the context of types from C++ or languages where we assume the
15465 // "One Definition Rule", we assume that a declaration-only
15466 // non-anonymous class equals all fully defined classes of the same
15467 // name.
15468 //
15469 // Otherwise, all classes, including declaration-only classes are
15470 // canonicalized and only canonical comparison is going to be used
15471 // in the system.
15472 if (decl_only_class_equals_definition)
15473 if (class_or_union)
15474 if (class_or_union->get_is_declaration_only())
15475 return type_base_sptr();
15476
15477 class_decl_sptr is_class = is_class_type(t);
15478 if (t->get_canonical_type())
15479 return t->get_canonical_type();
15480
15481 // For classes and union, ensure that an anonymous class doesn't
15482 // have a linkage name. If it does in the future, then me must be
15483 // mindful that the linkage name respects the type identity
15484 // constraints which states that "if two linkage names are different
15485 // then the two types are different".
15486 ABG_ASSERT(!class_or_union
15487 || !class_or_union->get_is_anonymous()
15488 || class_or_union->get_linkage_name().empty());
15489
15490 // We want the pretty representation of the type, but for an
15491 // internal use, not for a user-facing purpose.
15492 //
15493 // If two classe types Foo are declared, one as a class and the
15494 // other as a struct, but are otherwise equivalent, we want their
15495 // pretty representation to be the same. Hence the 'internal'
15496 // argument of ir::get_pretty_representation() is set to true here.
15497 // So in this case, the pretty representation of Foo is going to be
15498 // "class Foo", regardless of its struct-ness. This also applies to
15499 // composite types which would have "class Foo" as a sub-type.
15500 string repr = t->get_cached_pretty_representation(/*internal=*/true);
15501
15502 // If 't' already has a canonical type 'inside' its corpus
15503 // (t_corpus), then this variable is going to contain that canonical
15504 // type.
15505 type_base_sptr canonical_type_present_in_corpus;
15507 env.get_canonical_types_map();
15508
15509 type_base_sptr result;
15510 environment::canonical_types_map_type::iterator i = types.find(repr);
15511 if (i == types.end())
15512 {
15513 vector<type_base_sptr> v;
15514 v.push_back(t);
15515 types[repr] = v;
15516 result = t;
15517 }
15518 else
15519 {
15520 vector<type_base_sptr> &v = i->second;
15521 // Let's compare 't' structurally (i.e, compare its sub-types
15522 // recursively) against the canonical types of the system. If it
15523 // equals a given canonical type C, then it means C is the
15524 // canonical type of 't'. Otherwise, if 't' is different from
15525 // all the canonical types of the system, then it means 't' is a
15526 // canonical type itself.
15527 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15528 it != v.rend();
15529 ++it)
15530 {
15531 bool equal = compare_canonical_type_against_candidate(*it, t);
15532 if (equal)
15533 {
15534 result = *it;
15535 break;
15536 }
15537 }
15538#ifdef WITH_DEBUG_SELF_COMPARISON
15539 if (env.self_comparison_debug_is_on())
15540 {
15541 // So we are debugging the canonicalization process,
15542 // possibly via the use of 'abidw --debug-abidiff <binary>'.
15543 corpus_sptr corp1, corp2;
15544 env.get_self_comparison_debug_inputs(corp1, corp2);
15545 if (corp1 && corp2 && t->get_corpus() == corp2.get())
15546 {
15547 // If 't' comes from the second corpus, then it *must*
15548 // be equal to its matching canonical type coming from
15549 // the first corpus because the second corpus is the
15550 // abixml representation of the first corpus. In other
15551 // words, all types coming from the second corpus must
15552 // have canonical types coming from the first corpus.
15553 if (result)
15554 {
15555 if (!env.priv_->
15556 check_canonical_type_from_abixml_during_self_comp(t,
15557 result))
15558 {
15559 // The canonical type of the type re-read from abixml
15560 // type doesn't match the canonical type that was
15561 // initially serialized down.
15562 uintptr_t should_have_canonical_type = 0;
15563 string type_id = env.get_type_id_from_type(t.get());
15564 if (type_id.empty())
15565 type_id = "type-id-<not-found>";
15566 else
15567 should_have_canonical_type =
15568 env.get_canonical_type_from_type_id(type_id.c_str());
15569 std::cerr << "error: wrong canonical type for '"
15570 << repr
15571 << "' / type: @"
15572 << std::hex
15573 << t.get()
15574 << "/ canon: @"
15575 << result.get()
15576 << ", type-id: '"
15577 << type_id
15578 << "'. Should have had canonical type: "
15579 << std::hex
15580 << should_have_canonical_type
15581 << std::endl;
15582 }
15583 }
15584 else //!result
15585 {
15586 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
15587 string type_id = env.get_type_id_from_pointer(ptr_val);
15588 if (type_id.empty())
15589 type_id = "type-id-<not-found>";
15590 // We are in the case where 't' is different from all
15591 // the canonical types of the same name that come from
15592 // the first corpus.
15593 //
15594 // If 't' indeed comes from the second corpus then this
15595 // clearly is a canonicalization failure.
15596 //
15597 // There was a problem either during the serialization
15598 // of 't' into abixml, or during the de-serialization
15599 // from abixml into abigail::ir. Further debugging is
15600 // needed to determine what that root cause problem is.
15601 //
15602 // Note that the first canonicalization problem of this
15603 // kind must be fixed before looking at the subsequent
15604 // ones, because the later might well just be
15605 // consequences of the former.
15606 std::cerr << "error: wrong induced canonical type for '"
15607 << repr
15608 << "' from second corpus"
15609 << ", ptr: " << std::hex << t.get()
15610 << " type-id: " << type_id
15611 << std::endl;
15612 }
15613 }
15614 }
15615#endif //WITH_DEBUG_SELF_COMPARISON
15616
15617 if (!result)
15618 {
15619 v.push_back(t);
15620 result = t;
15621 }
15622 }
15623
15624 return result;
15625}
15626
15627/// This method is invoked automatically right after the current
15628/// instance of @ref class_decl has been canonicalized.
15629void
15631{}
15632
15633/// This is a subroutine of the canonicalize() function.
15634///
15635/// When the canonical type C of type T has just been computed, there
15636/// can be cases where T has member functions that C doesn't have.
15637///
15638/// This is possible because non virtual member functions are not
15639/// taken in account when comparing two types.
15640///
15641/// In that case, this function updates C so that it contains the
15642/// member functions.
15643///
15644/// There can also be cases where C has a method M which is not linked
15645/// to any underlying symbol, whereas in T, M is to link to an
15646/// underlying symbol. In that case, this function updates M in C so
15647/// that it's linked to the same underlying symbol as for M in T.
15648static void
15649maybe_adjust_canonical_type(const type_base_sptr& canonical,
15650 const type_base_sptr& type)
15651{
15652 if (type->get_naked_canonical_type())
15653 return;
15654
15655 class_decl_sptr canonical_class = is_class_type(canonical);
15656
15657 if (class_decl_sptr cl = is_class_type(type))
15658 {
15659 if (canonical_class
15660 && canonical_class.get() != cl.get())
15661 {
15662 // Set symbols of member functions that might be missing
15663 // theirs.
15664 for (class_decl::member_functions::const_iterator i =
15665 cl->get_member_functions().begin();
15666 i != cl->get_member_functions().end();
15667 ++i)
15668 if ((*i)->get_symbol())
15669 {
15670 if (method_decl *m = canonical_class->
15671 find_member_function((*i)->get_linkage_name()))
15672 {
15673 elf_symbol_sptr s1 = (*i)->get_symbol();
15674 if (s1 && !m->get_symbol())
15675 // Method 'm' in the canonical type is not
15676 // linked to the underlying symbol of '*i'.
15677 // Let's link it now. have th
15678 m->set_symbol(s1);
15679 }
15680 else
15681 // There is a member function defined and publicly
15682 // exported in the other class, and the canonical
15683 // class doesn't have that member function. Let's
15684 // copy that member function to the canonical class
15685 // then.
15686 {
15687 method_decl_sptr method =
15688 copy_member_function (canonical_class, *i);
15689 canonicalize(method->get_type());
15690 }
15691 }
15692 }
15693 }
15694
15695 // Make sure the virtual member functions with exported symbols are
15696 // all added to the set of exported functions of the corpus.
15697
15698 // If we are looking at a non-canonicalized class (for instance, a
15699 // decl-only class that has virtual member functoins), let's pretend
15700 // it does have a canonical class so that we can perform the
15701 // necessary virtual member function adjustments
15702 if (class_decl_sptr cl = is_class_type(type))
15704 {
15705 ABG_ASSERT(!canonical_class);
15706 canonical_class = cl;
15707 }
15708
15709 if (canonical_class)
15710 {
15711 if (auto abi_corpus = canonical_class->get_corpus())
15712 {
15713 for (auto& fn : canonical_class->get_member_functions())
15714 {
15715 if (elf_symbol_sptr sym = fn->get_symbol())
15716 if (sym->is_defined() && sym->is_public())
15717 {
15718 fn->set_is_in_public_symbol_table(true);
15719 auto b = abi_corpus->get_exported_decls_builder();
15720 b->maybe_add_fn_to_exported_fns(fn.get());
15721 }
15722 }
15723 }
15724 }
15725
15726 // If an artificial function type equals a non-artfificial one in
15727 // the system, then the canonical type of both should be deemed
15728 // non-artificial. This is important because only non-artificial
15729 // canonical function types are emitted out into abixml, so if don't
15730 // do this we risk missing to emit some function types.
15731 if (is_function_type(type))
15732 if (type->get_is_artificial() != canonical->get_is_artificial())
15733 canonical->set_is_artificial(false);
15734}
15735
15736/// Compute the canonical type of a given type.
15737///
15738/// It means that after invoking this function, comparing the intance
15739/// instance @ref type_base and another one (on which
15740/// type_base::enable_canonical_equality() would have been invoked as
15741/// well) is performed by just comparing the pointer values of the
15742/// canonical types of both types. That equality comparison is
15743/// supposedly faster than structural comparison of the types.
15744///
15745/// @param t a smart pointer to the instance of @ref type_base for
15746/// which to compute the canonical type. After this call,
15747/// t->get_canonical_type() will return the newly computed canonical
15748/// type.
15749///
15750/// @return the canonical type computed for @p t.
15751type_base_sptr
15752canonicalize(type_base_sptr t)
15753{
15754 if (!t)
15755 return t;
15756
15757 if (t->get_canonical_type())
15758 return t->get_canonical_type();
15759
15760 if (t->get_environment().priv_->do_log())
15761 std::cerr << "Canonicalization of type '"
15762 << t->get_pretty_representation(true, true)
15763 << "/@#" << std::hex << t.get() << ": ";
15764
15766
15767 if (t->get_environment().priv_->do_log())
15768 tmr.start();
15769 type_base_sptr canonical = type_base::get_canonical_type_for(t);
15770
15771 if (t->get_environment().priv_->do_log())
15772 tmr.stop();
15773
15774 if (t->get_environment().priv_->do_log())
15775 std::cerr << tmr << "\n";
15776
15777 maybe_adjust_canonical_type(canonical, t);
15778
15779 t->priv_->canonical_type = canonical;
15780 t->priv_->naked_canonical_type = canonical.get();
15781
15782 // So this type is now canonicalized.
15783 //
15784 // It means that:
15785 //
15786 // 1/ Either the canonical type was not propagated during the
15787 // comparison of another type that was being canonicalized
15788 //
15789 // 2/ Or the canonical type has been propagated during the
15790 // comparison of another type that was being canonicalized and
15791 // that propagated canonical type has been confirmed, because
15792 // it was depending on a recursive type which comparison
15793 // succeeded.
15794 ABG_ASSERT(!t->priv_->canonical_type_propagated()
15795 || t->priv_->propagated_canonical_type_confirmed());
15796
15797 if (class_decl_sptr cl = is_class_type(t))
15798 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
15799 if ((canonical = d->get_canonical_type()))
15800 {
15801 d->priv_->canonical_type = canonical;
15802 d->priv_->naked_canonical_type = canonical.get();
15803 }
15804
15805 if (canonical)
15806 {
15807 if (decl_base_sptr d = is_decl_slow(canonical))
15808 {
15809 scope_decl *scope = d->get_scope();
15810 // Add the canonical type to the set of canonical types
15811 // belonging to its scope.
15812 if (scope)
15813 {
15814 if (is_type(scope))
15815 // The scope in question is itself a type (e.g, a class
15816 // or union). Let's call that type ST. We want to add
15817 // 'canonical' to the set of canonical types belonging
15818 // to ST.
15819 if (type_base_sptr c = is_type(scope)->get_canonical_type())
15820 // We want to add 'canonical' to set of canonical
15821 // types belonging to the canonical type of ST. That
15822 // way, just looking at the canonical type of ST is
15823 // enough to get the types that belong to the scope of
15824 // the class of equivalence of ST.
15825 scope = is_scope_decl(is_decl(c)).get();
15826 scope->get_canonical_types().insert(canonical);
15827 }
15828 // else, if the type doesn't have a scope, it's not meant to be
15829 // emitted. This can be the case for the result of the
15830 // function strip_typedef, for instance.
15831 }
15832
15833#ifdef WITH_DEBUG_CT_PROPAGATION
15834 // Update the book-keeping of the set of the types which
15835 // propagated canonical type has been cleared.
15836 //
15837 // If this type 't' which has just been canonicalized was
15838 // previously in the set of types which propagated canonical
15839 // type has been cleared, then remove it from that set because
15840 // its canonical type is now computed and definitely set.
15841 const environment& env = t->get_environment();
15842 env.priv_->erase_type_with_cleared_propagated_canonical_type(t.get());
15843#endif
15844 }
15845
15846 t->on_canonical_type_set();
15847 return canonical;
15848}
15849
15850/// Set the definition of this declaration-only @ref decl_base.
15851///
15852/// @param d the new definition to set.
15853void
15855{
15857 priv_->definition_of_declaration_ = d;
15858 if (type_base *t = is_type(this))
15859 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
15860 t->priv_->canonical_type = canonical_type;
15861
15862 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
15863}
15864
15865/// The constructor of @ref type_base.
15866///
15867/// @param s the size of the type, in bits.
15868///
15869/// @param a the alignment of the type, in bits.
15870type_base::type_base(const environment& e, size_t s, size_t a)
15871 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
15872 priv_(new priv(s, a))
15873{}
15874
15875/// Getter of the canonical type of the current instance of @ref
15876/// type_base.
15877///
15878/// @return a smart pointer to the canonical type of the current
15879/// intance of @ref type_base, or an empty smart pointer if the
15880/// current instance of @ref type_base doesn't have any canonical
15881/// type.
15882type_base_sptr
15884{return priv_->canonical_type.lock();}
15885
15886/// Getter of the canonical type pointer.
15887///
15888/// Note that this function doesn't return a smart pointer, but rather
15889/// the underlying pointer managed by the smart pointer. So it's as
15890/// fast as possible. This getter is to be used in code paths that
15891/// are proven to be performance hot spots; especially, when comparing
15892/// sensitive types like class, function, pointers and reference
15893/// types. Those are compared extremely frequently and thus, their
15894/// accessing the canonical type must be fast.
15895///
15896/// @return the canonical type pointer, not managed by a smart
15897/// pointer.
15898type_base*
15900{return priv_->naked_canonical_type;}
15901
15902/// Get the pretty representation of the current type.
15903///
15904/// The pretty representation is retrieved from a cache. If the cache
15905/// is empty, this function computes the pretty representation, put it
15906/// in the cache and returns it.
15907///
15908/// Note that if the type is *NOT* canonicalized, the pretty
15909/// representation is never cached.
15910///
15911/// @param internal if true, then the pretty representation is to be
15912/// used for purpuses that are internal to the libabigail library
15913/// itself. If you don't know what this means, then you probably
15914/// should set this parameter to "false".
15915const interned_string&
15917{
15918 if (internal)
15919 {
15920 if (!get_naked_canonical_type() || priv_->internal_cached_repr_.empty())
15921 {
15922 string r = ir::get_pretty_representation(this, internal);
15923 priv_->internal_cached_repr_ = get_environment().intern(r);
15924 }
15925 return priv_->internal_cached_repr_;
15926 }
15927
15928 if (!get_naked_canonical_type() || priv_->cached_repr_.empty())
15929 {
15930 string r = ir::get_pretty_representation(this, internal);
15931 priv_->cached_repr_ = get_environment().intern(r);
15932 }
15933
15934 return priv_->cached_repr_;
15935}
15936
15937/// Compares two instances of @ref type_base.
15938///
15939/// If the two intances are different, set a bitfield to give some
15940/// insight about the kind of differences there are.
15941///
15942/// @param l the first artifact of the comparison.
15943///
15944/// @param r the second artifact of the comparison.
15945///
15946/// @param k a pointer to a bitfield that gives information about the
15947/// kind of changes there are between @p l and @p r. This one is set
15948/// iff @p is non-null and if the function returns false.
15949///
15950/// Please note that setting k to a non-null value does have a
15951/// negative performance impact because even if @p l and @p r are not
15952/// equal, the function keeps up the comparison in order to determine
15953/// the different kinds of ways in which they are different.
15954///
15955/// @return true if @p l equals @p r, false otherwise.
15956bool
15957equals(const type_base& l, const type_base& r, change_kind* k)
15958{
15959 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
15961 if (!result)
15962 if (k)
15964 ABG_RETURN(result);
15965}
15966
15967/// Return true iff both type declarations are equal.
15968///
15969/// Note that this doesn't test if the scopes of both types are equal.
15970bool
15972{return equals(*this, other, 0);}
15973
15974/// Inequality operator.
15975///
15976///@param other the instance of @ref type_base to compare the current
15977/// instance against.
15978///
15979/// @return true iff the current instance is different from @p other.
15980bool
15982{return !operator==(other);}
15983
15984/// Setter for the size of the type.
15985///
15986/// @param s the new size -- in bits.
15987void
15989{priv_->size_in_bits = s;}
15990
15991/// Getter for the size of the type.
15992///
15993/// @return the size in bits of the type.
15994size_t
15996{return priv_->size_in_bits;}
15997
15998/// Setter for the alignment of the type.
15999///
16000/// @param a the new alignment -- in bits.
16001void
16003{priv_->alignment_in_bits = a;}
16004
16005/// Getter for the alignment of the type.
16006///
16007/// @return the alignment of the type in bits.
16008size_t
16010{return priv_->alignment_in_bits;}
16011
16012/// Default implementation of traversal for types. This function does
16013/// nothing. It must be implemented by every single new type that is
16014/// written.
16015///
16016/// Please look at e.g, class_decl::traverse() for an example of how
16017/// to implement this.
16018///
16019/// @param v the visitor used to visit the type.
16020bool
16022{
16023 if (v.type_node_has_been_visited(this))
16024 return true;
16025
16026 v.visit_begin(this);
16027 bool result = v.visit_end(this);
16029
16030 return result;
16031}
16032
16033type_base::~type_base()
16034{delete priv_;}
16035
16036// </type_base definitions>
16037
16038// <integral_type definitions>
16039
16040/// Bitwise OR operator for integral_type::modifiers_type.
16041///
16042/// @param l the left-hand side operand.
16043///
16044/// @param r the right-hand side operand.
16045///
16046/// @return the result of the bitwise OR.
16049{
16050 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
16051 |
16052 static_cast<unsigned>(r));
16053}
16054
16055/// Bitwise AND operator for integral_type::modifiers_type.
16056///
16057/// @param l the left-hand side operand.
16058///
16059/// @param r the right-hand side operand.
16060///
16061/// @return the result of the bitwise AND.
16064{
16065 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
16066 &
16067 static_cast<unsigned>(r));
16068}
16069
16070/// Bitwise one's complement operator for integral_type::modifiers_type.
16071///
16072/// @param l the left-hand side operand.
16073///
16074/// @param r the right-hand side operand.
16075///
16076/// @return the result of the bitwise one's complement operator.
16079{
16080 return static_cast<integral_type::modifiers_type>(~static_cast<unsigned>(l));
16081}
16082
16083/// Bitwise |= operator for integral_type::modifiers_type.
16084///
16085/// @param l the left-hand side operand.
16086///
16087/// @param r the right-hand side operand.
16088///
16089/// @return the result of the bitwise |=.
16092{
16093 l = l | r;
16094 return l;
16095}
16096
16097/// Bitwise &= operator for integral_type::modifiers_type.
16098///
16099/// @param l the left-hand side operand.
16100///
16101/// @param r the right-hand side operand.
16102///
16103/// @return the result of the bitwise &=.
16106{
16107 l = l & r;
16108 return l;
16109}
16110
16111/// Parse a word containing one integral type modifier.
16112///
16113/// A word is considered to be a string of characters that doesn't
16114/// contain any white space.
16115///
16116/// @param word the word to parse. It is considered to be a string of
16117/// characters that doesn't contain any white space.
16118///
16119/// @param modifiers out parameter. It's set by this function to the
16120/// parsed modifier iff the function returned true.
16121///
16122/// @return true iff @word was successfully parsed.
16123static bool
16124parse_integral_type_modifier(const string& word,
16126{
16127 if (word == "signed")
16128 modifiers |= integral_type::SIGNED_MODIFIER;
16129 else if (word == "unsigned")
16131 else if (word == "short")
16132 modifiers |= integral_type::SHORT_MODIFIER;
16133 else if (word == "long")
16134 modifiers |= integral_type::LONG_MODIFIER;
16135 else if (word == "long long")
16137 else
16138 return false;
16139
16140 return true;
16141}
16142
16143/// Parse a base type of an integral type from a string.
16144///
16145/// @param type_name the type name to parse.
16146///
16147/// @param base out parameter. This is set to the resulting base type
16148/// parsed, iff the function returned true.
16149///
16150/// @return true iff the function could successfully parse the base
16151/// type.
16152static bool
16153parse_base_integral_type(const string& type_name,
16155{
16156 if (type_name == "int")
16158 else if (type_name == "char")
16160 else if (type_name == "bool" || type_name == "_Bool")
16162 else if (type_name == "double")
16164 else if (type_name =="float")
16166 else if (type_name == "char16_t")
16168 else if (type_name == "char32_t")
16170 else if (type_name == "wchar_t")
16172 else
16173 return false;
16174
16175 return true;
16176}
16177
16178/// Parse an integral type from a string.
16179///
16180/// @param type_name the string containing the integral type to parse.
16181///
16182/// @param base out parameter. Is set by this function to the base
16183/// type of the integral type, iff the function returned true.
16184///
16185/// @param modifiers out parameter If set by this function to the
16186/// modifier of the integral type, iff the function returned true.
16187///
16188/// @return true iff the function could parse an integral type from @p
16189/// type_name.
16190static bool
16191parse_integral_type(const string& type_name,
16194{
16195 string input = type_name;
16196 string::size_type len = input.length();
16197 string::size_type cur_pos = 0, prev_pos = 0;
16198 string cur_word, prev_word;
16199 bool ok = false;
16200
16201 while (cur_pos < len)
16202 {
16203 if (cur_pos < len && isspace(input[cur_pos]))
16204 do
16205 ++cur_pos;
16206 while (cur_pos < len && isspace(input[cur_pos]));
16207
16208 prev_pos = cur_pos;
16209 cur_pos = input.find(' ', prev_pos);
16210 prev_word = cur_word;
16211 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16212
16213 if (cur_pos < len
16214 && cur_word == "long"
16215 && prev_word != "long")
16216 {
16217 if (cur_pos < len && isspace(input[cur_pos]))
16218 do
16219 ++cur_pos;
16220 while (cur_pos < len && isspace(input[cur_pos]));
16221 prev_pos = cur_pos;
16222
16223 cur_pos = input.find(' ', prev_pos);
16224 string saved_prev_word = prev_word;
16225 prev_word = cur_word;
16226 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16227 if (cur_word == "long")
16228 cur_word = "long long";
16229 else
16230 {
16231 cur_pos = prev_pos;
16232 cur_word = prev_word;
16233 prev_word = saved_prev_word;
16234 }
16235 }
16236
16237 if (!parse_integral_type_modifier(cur_word, modifiers))
16238 {
16239 if (!parse_base_integral_type(cur_word, base))
16240 return false;
16241 else
16242 ok = true;
16243 }
16244 else
16245 ok = true;
16246 }
16247
16248 return ok;
16249}
16250
16251/// Parse an integral type from a string.
16252///
16253/// @param str the string containing the integral type to parse.
16254///
16255///@param type the resulting @ref integral_type. Is set to the result
16256///of the parse, iff the function returns true.
16257///
16258/// @return true iff the function could parse an integral type from @p
16259/// str.
16260bool
16261parse_integral_type(const string& str, integral_type& type)
16262{
16264 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
16265
16266 if (!parse_integral_type(str, base_type, modifiers))
16267 return false;
16268
16269 // So this is an integral type.
16270 integral_type int_type(base_type, modifiers);
16271 type = int_type;
16272 return true;
16273}
16274
16275/// Default constructor of the @ref integral_type.
16277 : base_(INT_BASE_TYPE),
16278 modifiers_(NO_MODIFIER)
16279{}
16280
16281/// Constructor of the @ref integral_type.
16282///
16283/// @param b the base type of the integral type.
16284///
16285/// @param m the modifiers of the integral type.
16287 : base_(b), modifiers_(m)
16288{}
16289
16290/// Constructor of the @ref integral_type.
16291///
16292/// @param the name of the integral type to parse to initialize the
16293/// current instance of @ref integral_type.
16294integral_type::integral_type(const string& type_name)
16295 : base_(INT_BASE_TYPE),
16296 modifiers_(NO_MODIFIER)
16297{
16298 bool could_parse = parse_integral_type(type_name, base_, modifiers_);
16299 ABG_ASSERT(could_parse);
16300}
16301
16302/// Getter of the base type of the @ref integral_type.
16303///
16304/// @return the base type of the @ref integral_type.
16307{return base_;}
16308
16309/// Getter of the modifiers bitmap of the @ref integral_type.
16310///
16311/// @return the modifiers bitmap of the @ref integral_type.
16314{return modifiers_;}
16315
16316/// Setter of the modifiers bitmap of the @ref integral_type.
16317///
16318/// @param m the new modifiers.
16319void
16321{modifiers_ = m;}
16322
16323/// Equality operator for the @ref integral_type.
16324///
16325/// @param other the other integral type to compare against.
16326///
16327/// @return true iff @p other equals the current instance of @ref
16328/// integral_type.
16329bool
16331{return base_ == other.base_ && modifiers_ == other.modifiers_;}
16332
16333/// Return the string representation of the current instance of @ref
16334/// integral_type.
16335///
16336/// @param internal if true the string representation is to be used
16337/// for internal purposes. In general, it means it's for type
16338/// canonicalization purposes.
16339///
16340/// @return the string representation of the current instance of @ref
16341/// integral_type.
16342string
16343integral_type::to_string(bool internal) const
16344{
16345 string result;
16346
16347 // Look at modifiers ...
16348 if (modifiers_ & SIGNED_MODIFIER)
16349 result += "signed ";
16350 if (modifiers_ & UNSIGNED_MODIFIER)
16351 result += "unsigned ";
16352 if (!internal)
16353 {
16354 // For canonicalization purposes, we won't emit the "short, long, or
16355 // long long" modifiers. This is because on some platforms, "long
16356 // int" and "long long int" might have the same size. In those
16357 // cases, we want the two types to be equivalent if they have the
16358 // same size. If they don't have the same internal string
16359 // representation, they'd automatically have different canonical
16360 // types and thus be canonically different.
16361 if (modifiers_ & SHORT_MODIFIER)
16362 result += "short ";
16363 if (modifiers_ & LONG_MODIFIER)
16364 result += "long ";
16365 if (modifiers_ & LONG_LONG_MODIFIER)
16366 result += "long long ";
16367 }
16368
16369 // ... and look at base types.
16370 if (base_ == INT_BASE_TYPE)
16371 result += "int";
16372 else if (base_ == CHAR_BASE_TYPE)
16373 result += "char";
16374 else if (base_ == BOOL_BASE_TYPE)
16375 result += "bool";
16376 else if (base_ == DOUBLE_BASE_TYPE)
16377 result += "double";
16378 else if (base_ == FLOAT_BASE_TYPE)
16379 result += "float";
16380 else if (base_ == CHAR16_T_BASE_TYPE)
16381 result += "char16_t";
16382 else if (base_ == CHAR32_T_BASE_TYPE)
16383 result += "char32_t";
16384 else if (base_ == WCHAR_T_BASE_TYPE)
16385 result += "wchar_t";
16386
16387 return result;
16388}
16389
16390/// Convert the current instance of @ref integral_type into its string
16391/// representation.
16392///
16393/// @return the string representation of the current instance of @ref
16394/// integral_type.
16395integral_type::operator string() const
16396{return to_string();}
16397
16398// </integral_type definitions>
16399
16400//<type_decl definitions>
16401
16402/// Constructor.
16403///
16404/// @param env the environment we are operating from.
16405///
16406/// @param name the name of the type declaration.
16407///
16408/// @param size_in_bits the size of the current type_decl, in bits.
16409///
16410/// @param alignment_in_bits the alignment of the current typ, in
16411/// bits.
16412///
16413/// @param locus the source location of the current type declaration.
16414///
16415/// @param linkage_name the linkage_name of the current type declaration.
16416///
16417/// @param vis the visibility of the type declaration.
16418type_decl::type_decl(const environment& env,
16419 const string& name,
16420 size_t size_in_bits,
16421 size_t alignment_in_bits,
16422 const location& locus,
16423 const string& linkage_name,
16424 visibility vis)
16425
16426 : type_or_decl_base(env,
16427 BASIC_TYPE
16428 | ABSTRACT_TYPE_BASE
16429 | ABSTRACT_DECL_BASE),
16430 decl_base(env, name, locus, linkage_name, vis),
16431 type_base(env, size_in_bits, alignment_in_bits)
16432{
16434
16436 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
16437 integral_type int_type(base_type, modifiers);
16438 if (parse_integral_type(name, int_type))
16439 {
16440 // Convert the integral_type into its canonical string
16441 // representation.
16442 string integral_type_name = int_type;
16443
16444 // Set the name of this type_decl to the canonical string
16445 // representation above
16446 set_name(integral_type_name);
16448
16449 if (!get_linkage_name().empty())
16450 set_linkage_name(integral_type_name);
16451 }
16452}
16453
16454/// Compares two instances of @ref type_decl.
16455///
16456/// If the two intances are different, set a bitfield to give some
16457/// insight about the kind of differences there are.
16458///
16459/// @param l the first artifact of the comparison.
16460///
16461/// @param r the second artifact of the comparison.
16462///
16463/// @param k a pointer to a bitfield that gives information about the
16464/// kind of changes there are between @p l and @p r. This one is set
16465/// iff @p k is non-null and the function returns false.
16466///
16467/// Please note that setting k to a non-null value does have a
16468/// negative performance impact because even if @p l and @p r are not
16469/// equal, the function keeps up the comparison in order to determine
16470/// the different kinds of ways in which they are different.
16471///
16472/// @return true if @p l equals @p r, false otherwise.
16473bool
16474equals(const type_decl& l, const type_decl& r, change_kind* k)
16475{
16476 bool result = false;
16477
16478 // Consider the types as decls to compare their decls-related
16479 // properties.
16480 result = equals(static_cast<const decl_base&>(l),
16481 static_cast<const decl_base&>(r),
16482 k);
16483 if (!k && !result)
16485
16486 // Now consider the types a "types' to compare their size-related
16487 // properties.
16488 result &= equals(static_cast<const type_base&>(l),
16489 static_cast<const type_base&>(r),
16490 k);
16491 ABG_RETURN(result);
16492}
16493
16494/// Return true if both types equals.
16495///
16496/// This operator re-uses the overload that takes a decl_base.
16497///
16498/// Note that this does not check the scopes of any of the types.
16499///
16500/// @param o the other type_decl to check agains.
16501bool
16503{
16504 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16505 if (!other)
16506 return false;
16507 return *this == *other;
16508}
16509
16510/// Return true if both types equals.
16511///
16512/// Note that this does not check the scopes of any of the types.
16513///
16514/// @param o the other type_decl to check against.
16515bool
16517{
16518 const type_decl* other = dynamic_cast<const type_decl*>(&o);
16519 if (!other)
16520 return false;
16521 return try_canonical_compare(this, other);
16522}
16523
16524/// Return true if both types equals.
16525///
16526/// Note that this does not check the scopes of any of the types.
16527///
16528/// @param o the other type_decl to check against.
16529///
16530/// @return true iff the current isntance equals @p o
16531bool
16533{
16534 const decl_base& other = o;
16535 return *this == other;
16536}
16537
16538/// Return true if both types equals.
16539///
16540/// Note that this does not check the scopes of any of the types.
16541///
16542/// @param o the other type_decl to check against.
16543///
16544/// @return true iff the current isntance equals @p o
16545bool
16547{return !operator==(o);}
16548
16549/// Return true if both types equals.
16550///
16551/// Note that this does not check the scopes of any of the types.
16552///
16553/// @param o the other type_decl to check against.
16554///
16555/// @return true iff the current isntance equals @p o
16556bool
16558{return !operator==(o);}
16559
16560/// Inequality operator.
16561///
16562/// @param o the other type to compare against.
16563///
16564/// @return true iff the current instance is different from @p o.
16565bool
16567{return !operator==(o);}
16568
16569/// Equality operator for @ref type_decl_sptr.
16570///
16571/// @param l the first operand to compare.
16572///
16573/// @param r the second operand to compare.
16574///
16575/// @return true iff @p l equals @p r.
16576bool
16578{
16579 if (!!l != !!r)
16580 return false;
16581 if (l.get() == r.get())
16582 return true;
16583 return *l == *r;
16584}
16585
16586/// Inequality operator for @ref type_decl_sptr.
16587///
16588/// @param l the first operand to compare.
16589///
16590/// @param r the second operand to compare.
16591///
16592/// @return true iff @p l is different from @p r.
16593bool
16595{return !operator==(l, r);}
16596
16597/// Implementation for the virtual qualified name builder for @ref
16598/// type_decl.
16599///
16600/// @param qualified_name the output parameter to hold the resulting
16601/// qualified name.
16602///
16603/// @param internal set to true if the call is intended for an
16604/// internal use (for technical use inside the library itself), false
16605/// otherwise. If you don't know what this is for, then set it to
16606/// false.
16607void
16609 bool internal) const
16610{qualified_name = get_qualified_name(internal);}
16611
16612/// Implementation for the virtual qualified name builder for @ref
16613/// type_decl.
16614///
16615/// @param qualified_name the output parameter to hold the resulting
16616/// qualified name.
16617///
16618/// @param internal set to true if the call is intended for an
16619/// internal use (for technical use inside the library itself), false
16620/// otherwise. If you don't know what this is for, then set it to
16621/// false.
16622const interned_string&
16624{
16625 const environment& env = get_environment();
16626
16627
16628 if (internal)
16629 if (is_integral_type(this))
16630 {
16632 {
16633 if (decl_base::priv_->internal_qualified_name_.empty())
16634 decl_base::priv_->internal_qualified_name_ =
16635 env.intern(get_internal_integral_type_name(this));
16636 return decl_base::priv_->internal_qualified_name_;
16637 }
16638 else
16639 {
16640 decl_base::priv_->temporary_internal_qualified_name_ =
16641 env.intern(get_internal_integral_type_name(this));
16642 return decl_base::priv_->temporary_internal_qualified_name_;
16643 }
16644 }
16645
16646 return decl_base::get_qualified_name(/*internal=*/false);
16647}
16648
16649/// Get the pretty representation of the current instance of @ref
16650/// type_decl.
16651///
16652/// @param internal set to true if the call is intended to get a
16653/// representation of the decl (or type) for the purpose of canonical
16654/// type comparison. This is mainly used in the function
16655/// type_base::get_canonical_type_for().
16656///
16657/// In other words if the argument for this parameter is true then the
16658/// call is meant for internal use (for technical use inside the
16659/// library itself), false otherwise. If you don't know what this is
16660/// for, then set it to false.
16661///
16662/// @param qualified_name if true, names emitted in the pretty
16663/// representation are fully qualified.
16664///
16665/// @return the pretty representatin of the @ref type_decl.
16666string
16668 bool qualified_name) const
16669{
16670 if (internal)
16671 if (is_integral_type(this))
16672 return get_internal_integral_type_name(this);
16673
16674 if (qualified_name)
16675 return get_qualified_name(internal);
16676 return get_name();
16677}
16678
16679/// This implements the ir_traversable_base::traverse pure virtual
16680/// function.
16681///
16682/// @param v the visitor used on the current instance.
16683///
16684/// @return true if the entire IR node tree got traversed, false
16685/// otherwise.
16686bool
16688{
16689 if (v.type_node_has_been_visited(this))
16690 return true;
16691
16692 v.visit_begin(this);
16693 bool result = v.visit_end(this);
16695
16696 return result;
16697}
16698
16699type_decl::~type_decl()
16700{}
16701//</type_decl definitions>
16702
16703// <scope_type_decl definitions>
16704
16705/// Constructor.
16706///
16707/// @param env the environment we are operating from.
16708///
16709/// @param name the name of the type.
16710///
16711/// @param size_in_bits the size of the type, in bits.
16712///
16713/// @param alignment_in_bits the alignment of the type, in bits.
16714///
16715/// @param locus the source location where the type is defined.
16716///
16717/// @param vis the visibility of the type.
16718scope_type_decl::scope_type_decl(const environment& env,
16719 const string& name,
16720 size_t size_in_bits,
16721 size_t alignment_in_bits,
16722 const location& locus,
16723 visibility vis)
16724 : type_or_decl_base(env,
16725 ABSTRACT_SCOPE_TYPE_DECL
16726 | ABSTRACT_TYPE_BASE
16727 | ABSTRACT_DECL_BASE),
16728 decl_base(env, name, locus, "", vis),
16729 type_base(env, size_in_bits, alignment_in_bits),
16730 scope_decl(env, name, locus)
16731{}
16732
16733/// Compares two instances of @ref scope_type_decl.
16734///
16735/// If the two intances are different, set a bitfield to give some
16736/// insight about the kind of differences there are.
16737///
16738/// @param l the first artifact of the comparison.
16739///
16740/// @param r the second artifact of the comparison.
16741///
16742/// @param k a pointer to a bitfield that gives information about the
16743/// kind of changes there are between @p l and @p r. This one is set
16744/// iff @p k is non-null and the function returns false.
16745///
16746/// Please note that setting k to a non-null value does have a
16747/// negative performance impact because even if @p l and @p r are not
16748/// equal, the function keeps up the comparison in order to determine
16749/// the different kinds of ways in which they are different.
16750///
16751/// @return true if @p l equals @p r, false otherwise.
16752bool
16754{
16755 bool result = equals(static_cast<const scope_decl&>(l),
16756 static_cast<const scope_decl&>(r),
16757 k);
16758
16759 if (!k && !result)
16761
16762 result &= equals(static_cast<const type_base&>(l),
16763 static_cast<const type_base&>(r),
16764 k);
16765
16766 ABG_RETURN(result);
16767}
16768
16769/// Equality operator between two scope_type_decl.
16770///
16771/// Note that this function does not consider the scope of the scope
16772/// types themselves.
16773///
16774/// @return true iff both scope types are equal.
16775bool
16777{
16778 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
16779 if (!other)
16780 return false;
16781 return try_canonical_compare(this, other);
16782}
16783
16784/// Equality operator between two scope_type_decl.
16785///
16786/// This re-uses the equality operator that takes a decl_base.
16787///
16788/// @param o the other scope_type_decl to compare against.
16789///
16790/// @return true iff both scope types are equal.
16791bool
16793{
16794 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16795 if (!other)
16796 return false;
16797
16798 return *this == *other;
16799}
16800
16801/// Traverses an instance of @ref scope_type_decl, visiting all the
16802/// sub-types and decls that it might contain.
16803///
16804/// @param v the visitor that is used to visit every IR sub-node of
16805/// the current node.
16806///
16807/// @return true if either
16808/// - all the children nodes of the current IR node were traversed
16809/// and the calling code should keep going with the traversing.
16810/// - or the current IR node is already being traversed.
16811/// Otherwise, returning false means that the calling code should not
16812/// keep traversing the tree.
16813bool
16815{
16816 if (visiting())
16817 return true;
16818
16819 if (v.type_node_has_been_visited(this))
16820 return true;
16821
16822 if (v.visit_begin(this))
16823 {
16824 visiting(true);
16825 for (scope_decl::declarations::const_iterator i =
16826 get_member_decls().begin();
16827 i != get_member_decls ().end();
16828 ++i)
16829 if (!(*i)->traverse(v))
16830 break;
16831 visiting(false);
16832 }
16833
16834 bool result = v.visit_end(this);
16836
16837 return result;
16838}
16839
16840scope_type_decl::~scope_type_decl()
16841{}
16842// </scope_type_decl definitions>
16843
16844// <namespace_decl>
16845
16846/// Constructor.
16847///
16848/// @param the environment we are operatin from.
16849///
16850/// @param name the name of the namespace.
16851///
16852/// @param locus the source location where the namespace is defined.
16853///
16854/// @param vis the visibility of the namespace.
16856 const string& name,
16857 const location& locus,
16858 visibility vis)
16859 // We need to call the constructor of decl_base directly here
16860 // because it is virtually inherited by scope_decl. Note that we
16861 // just implicitely call the default constructor for scope_decl
16862 // here, as what we really want is to initialize the decl_base
16863 // subobject. Wow, virtual inheritance is useful, but setting it
16864 // up is ugly.
16865 : type_or_decl_base(env,
16866 NAMESPACE_DECL
16867 | ABSTRACT_DECL_BASE
16868 | ABSTRACT_SCOPE_DECL),
16869 decl_base(env, name, locus, "", vis),
16870 scope_decl(env, name, locus)
16871{
16873}
16874
16875/// Build and return a copy of the pretty representation of the
16876/// namespace.
16877///
16878/// @param internal set to true if the call is intended to get a
16879/// representation of the decl (or type) for the purpose of canonical
16880/// type comparison. This is mainly used in the function
16881/// type_base::get_canonical_type_for().
16882///
16883/// In other words if the argument for this parameter is true then the
16884/// call is meant for internal use (for technical use inside the
16885/// library itself), false otherwise. If you don't know what this is
16886/// for, then set it to false.
16887///
16888/// @param qualified_name if true, names emitted in the pretty
16889/// representation are fully qualified.
16890///
16891/// @return a copy of the pretty representation of the namespace.
16892string
16894 bool qualified_name) const
16895{
16896 string r =
16897 "namespace " + scope_decl::get_pretty_representation(internal,
16898 qualified_name);
16899 return r;
16900}
16901
16902/// Return true iff both namespaces and their members are equal.
16903///
16904/// Note that this function does not check if the scope of these
16905/// namespaces are equal.
16906bool
16908{
16909 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
16910 if (!other)
16911 return false;
16912 return scope_decl::operator==(*other);
16913}
16914
16915/// Test if the current namespace_decl is empty or contains empty
16916/// namespaces itself.
16917///
16918/// @return true iff the current namespace_decl is empty or contains
16919/// empty itself.
16920bool
16922{
16923 if (is_empty())
16924 return true;
16925
16926 for (declarations::const_iterator i = get_member_decls().begin();
16927 i != get_member_decls().end();
16928 ++i)
16929 {
16930 if (!is_namespace(*i))
16931 return false;
16932
16934 ABG_ASSERT(ns);
16935
16936 if (!ns->is_empty_or_has_empty_sub_namespaces())
16937 return false;
16938 }
16939
16940 return true;
16941}
16942
16943/// This implements the ir_traversable_base::traverse pure virtual
16944/// function.
16945///
16946/// @param v the visitor used on the current instance and on its
16947/// member nodes.
16948///
16949/// @return true if the entire IR node tree got traversed, false
16950/// otherwise.
16951bool
16953{
16954 if (visiting())
16955 return true;
16956
16957 if (v.visit_begin(this))
16958 {
16959 visiting(true);
16960 scope_decl::declarations::const_iterator i;
16961 for (i = get_member_decls().begin();
16962 i != get_member_decls ().end();
16963 ++i)
16964 {
16966 dynamic_pointer_cast<ir_traversable_base>(*i);
16967 if (t)
16968 if (!t->traverse (v))
16969 break;
16970 }
16971 visiting(false);
16972 }
16973 return v.visit_end(this);
16974}
16975
16976namespace_decl::~namespace_decl()
16977{
16978}
16979
16980// </namespace_decl>
16981
16982// <qualified_type_def>
16983
16984/// Type of the private data of qualified_type_def.
16985class qualified_type_def::priv
16986{
16987 friend class qualified_type_def;
16988
16989 qualified_type_def::CV cv_quals_;
16990 // Before the type is canonicalized, this is used as a temporary
16991 // internal name.
16992 interned_string temporary_internal_name_;
16993 // Once the type is canonicalized, this is used as the internal
16994 // name.
16995 interned_string internal_name_;
16996 weak_ptr<type_base> underlying_type_;
16997
16998 priv()
16999 : cv_quals_(CV_NONE)
17000 {}
17001
17002 priv(qualified_type_def::CV quals,
17003 type_base_sptr t)
17004 : cv_quals_(quals),
17005 underlying_type_(t)
17006 {}
17007
17008 priv(qualified_type_def::CV quals)
17009 : cv_quals_(quals)
17010 {}
17011};// end class qualified_type_def::priv
17012
17013/// Build the name of the current instance of qualified type.
17014///
17015/// @param fully_qualified if true, build a fully qualified name.
17016///
17017/// @param internal set to true if the call is intended for an
17018/// internal use (for technical use inside the library itself), false
17019/// otherwise. If you don't know what this is for, then set it to
17020/// false.
17021///
17022/// @return a copy of the newly-built name.
17023string
17024qualified_type_def::build_name(bool fully_qualified, bool internal) const
17025{
17026 type_base_sptr t = get_underlying_type();
17027 if (!t)
17028 // The qualified type might temporarily have no underlying type,
17029 // especially during the construction of the type, while the
17030 // underlying type is not yet constructed. In that case, let's do
17031 // like if the underlying type is the 'void' type.
17033
17035 fully_qualified,
17036 internal);
17037}
17038
17039/// This function is automatically invoked whenever an instance of
17040/// this type is canonicalized.
17041///
17042/// It's an overload of the virtual type_base::on_canonical_type_set.
17043///
17044/// We put here what is thus meant to be executed only at the point of
17045/// type canonicalization.
17046void
17049
17050/// Constructor of the qualified_type_def
17051///
17052/// @param type the underlying type
17053///
17054/// @param quals a bitfield representing the const/volatile qualifiers
17055///
17056/// @param locus the location of the qualified type definition
17057qualified_type_def::qualified_type_def(type_base_sptr type,
17058 CV quals,
17059 const location& locus)
17060 : type_or_decl_base(type->get_environment(),
17061 QUALIFIED_TYPE
17062 | ABSTRACT_TYPE_BASE
17063 | ABSTRACT_DECL_BASE),
17064 type_base(type->get_environment(), type->get_size_in_bits(),
17065 type->get_alignment_in_bits()),
17066 decl_base(type->get_environment(), "", locus, "",
17067 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
17068 priv_(new priv(quals, type))
17069{
17071 interned_string name = type->get_environment().intern(build_name(false));
17072 set_name(name);
17073}
17074
17075/// Constructor of the qualified_type_def
17076///
17077/// @param env the environment of the type.
17078///
17079/// @param quals a bitfield representing the const/volatile qualifiers
17080///
17081/// @param locus the location of the qualified type definition
17082qualified_type_def::qualified_type_def(const environment& env,
17083 CV quals,
17084 const location& locus)
17085 : type_or_decl_base(env,
17086 QUALIFIED_TYPE
17087 | ABSTRACT_TYPE_BASE
17088 | ABSTRACT_DECL_BASE),
17089 type_base(env, /*size_in_bits=*/0,
17090 /*alignment_in_bits=*/0),
17091 decl_base(env, "", locus, ""),
17092 priv_(new priv(quals))
17093{
17095 // We don't yet have an underlying type. So for naming purpose,
17096 // let's temporarily pretend the underlying type is 'void'.
17097 interned_string name = env.intern("void");
17098 set_name(name);
17099}
17100
17101/// Get the size of the qualified type def.
17102///
17103/// This is an overload for type_base::get_size_in_bits().
17104///
17105/// @return the size of the qualified type.
17106size_t
17108{
17109 size_t s = 0;
17110 if (type_base_sptr ut = get_underlying_type())
17111 {
17112 // We do have the underlying type properly set, so let's make
17113 // the size of the qualified type match the size of its
17114 // underlying type.
17115 s = ut->get_size_in_bits();
17116 if (s != type_base::get_size_in_bits())
17117 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
17118 }
17120}
17121
17122/// Compares two instances of @ref qualified_type_def.
17123///
17124/// If the two intances are different, set a bitfield to give some
17125/// insight about the kind of differences there are.
17126///
17127/// @param l the first artifact of the comparison.
17128///
17129/// @param r the second artifact of the comparison.
17130///
17131/// @param k a pointer to a bitfield that gives information about the
17132/// kind of changes there are between @p l and @p r. This one is set
17133/// iff @p k is non-null and the function returns false.
17134///
17135/// Please note that setting k to a non-null value does have a
17136/// negative performance impact because even if @p l and @p r are not
17137/// equal, the function keeps up the comparison in order to determine
17138/// the different kinds of ways in which they are different.
17139///
17140/// @return true if @p l equals @p r, false otherwise.
17141bool
17143{
17144 bool result = true;
17145 if (l.get_cv_quals() != r.get_cv_quals())
17146 {
17147 result = false;
17148 if (k)
17150 else
17152 }
17153
17155 {
17156 result = false;
17157 if (k)
17158 {
17160 r.get_underlying_type().get()))
17161 // Underlying type changes in which the structure of the
17162 // type changed are considered local changes to the
17163 // qualified type.
17165 else
17166 *k |= SUBTYPE_CHANGE_KIND;
17167 }
17168 else
17169 // okay strictly speaking this is not necessary, but I am
17170 // putting it here to maintenance; that is, so that adding
17171 // subsequent clauses needed to compare two qualified types
17172 // later still works.
17174 }
17175
17176 ABG_RETURN(result);
17177}
17178
17179/// Equality operator for qualified types.
17180///
17181/// Note that this function does not check for equality of the scopes.
17182///
17183///@param o the other qualified type to compare against.
17184///
17185/// @return true iff both qualified types are equal.
17186bool
17188{
17189 const qualified_type_def* other =
17190 dynamic_cast<const qualified_type_def*>(&o);
17191 if (!other)
17192 return false;
17193 return try_canonical_compare(this, other);
17194}
17195
17196/// Equality operator for qualified types.
17197///
17198/// Note that this function does not check for equality of the scopes.
17199/// Also, this re-uses the equality operator above that takes a
17200/// decl_base.
17201///
17202///@param o the other qualified type to compare against.
17203///
17204/// @return true iff both qualified types are equal.
17205bool
17207{
17208 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17209 if (!other)
17210 return false;
17211 return *this == *other;
17212}
17213
17214/// Equality operator for qualified types.
17215///
17216/// Note that this function does not check for equality of the scopes.
17217/// Also, this re-uses the equality operator above that takes a
17218/// decl_base.
17219///
17220///@param o the other qualified type to compare against.
17221///
17222/// @return true iff both qualified types are equal.
17223bool
17225{
17226 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17227 if (!other)
17228 return false;
17229 return *this == *other;
17230}
17231
17232/// Implementation for the virtual qualified name builder for @ref
17233/// qualified_type_def.
17234///
17235/// @param qualified_name the output parameter to hold the resulting
17236/// qualified name.
17237///
17238/// @param internal set to true if the call is intended for an
17239/// internal use (for technical use inside the library itself), false
17240/// otherwise. If you don't know what this is for, then set it to
17241/// false.
17242void
17244 bool internal) const
17245{qualified_name = get_qualified_name(internal);}
17246
17247/// Implementation of the virtual qualified name builder/getter.
17248///
17249/// @param internal set to true if the call is intended for an
17250/// internal use (for technical use inside the library itself), false
17251/// otherwise. If you don't know what this is for, then set it to
17252/// false.
17253///
17254/// @return the resulting qualified name.
17255const interned_string&
17257{
17258 const environment& env = get_environment();
17259
17260
17261 if (!get_canonical_type())
17262 {
17263 // The type hasn't been canonicalized yet. We want to return a
17264 // temporary name that is not cached because the structure of
17265 // this type (and so its name) can change until its
17266 // canonicalized.
17267 if (internal)
17268 {
17269 // We are asked to return a temporary *internal* name.
17270 // Lets compute it and return a reference to where it's
17271 // stored.
17272 if (priv_->temporary_internal_name_.empty())
17273 priv_->temporary_internal_name_ =
17274 env.intern(build_name(true, /*internal=*/true));
17275 return priv_->temporary_internal_name_;
17276 }
17277 else
17278 {
17279 // We are asked to return a temporary non-internal name.
17281 (env.intern(build_name(true, /*internal=*/false)));
17283 }
17284 }
17285 else
17286 {
17287 // The type has already been canonicalized. We want to return
17288 // the definitive name and cache it.
17289 if (internal)
17290 {
17291 if (priv_->internal_name_.empty())
17292 priv_->internal_name_ =
17293 env.intern(build_name(/*qualified=*/true,
17294 /*internal=*/true));
17295 return priv_->internal_name_;
17296 }
17297 else
17298 {
17299 if (peek_qualified_name().empty())
17301 (env.intern(build_name(/*qualified=*/true,
17302 /*internal=*/false)));
17303 return peek_qualified_name();
17304 }
17305 }
17306}
17307
17308/// This implements the ir_traversable_base::traverse pure virtual
17309/// function.
17310///
17311/// @param v the visitor used on the current instance.
17312///
17313/// @return true if the entire IR node tree got traversed, false
17314/// otherwise.
17315bool
17317{
17318 if (v.type_node_has_been_visited(this))
17319 return true;
17320
17321 if (visiting())
17322 return true;
17323
17324 if (v.visit_begin(this))
17325 {
17326 visiting(true);
17327 if (type_base_sptr t = get_underlying_type())
17328 t->traverse(v);
17329 visiting(false);
17330 }
17331 bool result = v.visit_end(this);
17333 return result;
17334}
17335
17336qualified_type_def::~qualified_type_def()
17337{
17338}
17339
17340/// Getter of the const/volatile qualifier bit field
17343{return priv_->cv_quals_;}
17344
17345/// Setter of the const/value qualifiers bit field
17346void
17348{priv_->cv_quals_ = cv_quals;}
17349
17350/// Compute and return the string prefix or suffix representing the
17351/// qualifiers hold by the current instance of @ref
17352/// qualified_type_def.
17353///
17354/// @return the newly-built cv string.
17355string
17357{return get_string_representation_of_cv_quals(priv_->cv_quals_);}
17358
17359/// Getter of the underlying type
17360type_base_sptr
17362{return priv_->underlying_type_.lock();}
17363
17364/// Setter of the underlying type.
17365///
17366/// @param t the new underlying type.
17367void
17369{
17370 ABG_ASSERT(t);
17371 priv_->underlying_type_ = t;
17372 // Now we need to update other properties that depend on the new underlying type.
17373 set_size_in_bits(t->get_size_in_bits());
17374 set_alignment_in_bits(t->get_alignment_in_bits());
17376 set_name(name);
17377 if (scope_decl* s = get_scope())
17378 {
17379 // Now that the name has been updated, we need to update the
17380 // lookup maps accordingly.
17381 scope_decl::declarations::iterator i;
17382 if (s->find_iterator_for_member(this, i))
17384 else
17386 }
17387}
17388
17389/// Non-member equality operator for @ref qualified_type_def
17390///
17391/// @param l the left-hand side of the equality operator
17392///
17393/// @param r the right-hand side of the equality operator
17394///
17395/// @return true iff @p l and @p r equals.
17396bool
17397operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17398{
17399 if (l.get() == r.get())
17400 return true;
17401 if (!!l != !!r)
17402 return false;
17403
17404 return *l == *r;
17405}
17406
17407/// Non-member inequality operator for @ref qualified_type_def
17408///
17409/// @param l the left-hand side of the equality operator
17410///
17411/// @param r the right-hand side of the equality operator
17412///
17413/// @return true iff @p l and @p r equals.
17414bool
17415operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
17416{return ! operator==(l, r);}
17417
17418/// Overloaded bitwise OR operator for cv qualifiers.
17421{
17422 return static_cast<qualified_type_def::CV>
17423 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
17424}
17425
17426/// Overloaded bitwise |= operator for cv qualifiers.
17429{
17430 l = l | r;
17431 return l;
17432}
17433
17434/// Overloaded bitwise &= operator for cv qualifiers.
17437{
17438 l = l & r;
17439 return l;
17440}
17441
17442/// Overloaded bitwise AND operator for CV qualifiers.
17445{
17446 return static_cast<qualified_type_def::CV>
17447 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
17448}
17449
17450/// Overloaded bitwise inverting operator for CV qualifiers.
17453{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
17454
17455/// Streaming operator for qualified_type_decl::CV
17456///
17457/// @param o the output stream to serialize the cv qualifier to.
17458///
17459/// @param cv the cv qualifier to serialize.
17460///
17461/// @return the output stream used.
17462std::ostream&
17463operator<<(std::ostream& o, qualified_type_def::CV cv)
17464{
17465 string str;
17466
17467 switch (cv)
17468 {
17469 case qualified_type_def::CV_NONE:
17470 str = "none";
17471 break;
17472 case qualified_type_def::CV_CONST:
17473 str = "const";
17474 break;
17475 case qualified_type_def::CV_VOLATILE:
17476 str = "volatile";
17477 break;
17478 case qualified_type_def::CV_RESTRICT:
17479 str = "restrict";
17480 break;
17481 }
17482
17483 o << str;
17484 return o;
17485}
17486
17487// </qualified_type_def>
17488
17489//<pointer_type_def definitions>
17490
17491/// Private data structure of the @ref pointer_type_def.
17492struct pointer_type_def::priv
17493{
17494 type_base_wptr pointed_to_type_;
17495 type_base* naked_pointed_to_type_;
17496 interned_string internal_qualified_name_;
17497 interned_string temp_internal_qualified_name_;
17498
17499 priv(const type_base_sptr& t)
17500 : pointed_to_type_(type_or_void(t, t->get_environment())),
17501 naked_pointed_to_type_(t.get())
17502 {}
17503
17504 priv()
17505 : naked_pointed_to_type_()
17506 {}
17507}; //end struct pointer_type_def
17508
17509/// This function is automatically invoked whenever an instance of
17510/// this type is canonicalized.
17511///
17512/// It's an overload of the virtual type_base::on_canonical_type_set.
17513///
17514/// We put here what is thus meant to be executed only at the point of
17515/// type canonicalization.
17516void
17519
17520
17521///Constructor of @ref pointer_type_def.
17522///
17523/// @param pointed_to the pointed-to type.
17524///
17525/// @param size_in_bits the size of the type, in bits.
17526///
17527/// @param align_in_bits the alignment of the type, in bits.
17528///
17529/// @param locus the source location where the type was defined.
17530pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
17531 size_t size_in_bits,
17532 size_t align_in_bits,
17533 const location& locus)
17534 : type_or_decl_base(pointed_to->get_environment(),
17535 POINTER_TYPE
17536 | ABSTRACT_TYPE_BASE
17537 | ABSTRACT_DECL_BASE),
17538 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17539 decl_base(pointed_to->get_environment(), "", locus, ""),
17540 priv_(new priv(pointed_to))
17541{
17543 try
17544 {
17545 ABG_ASSERT(pointed_to);
17546 const environment& env = pointed_to->get_environment();
17547 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
17548 string name = (pto ? pto->get_name() : string("void")) + "*";
17549 set_name(env.intern(name));
17550 if (pto)
17551 set_visibility(pto->get_visibility());
17552 }
17553 catch (...)
17554 {}
17555}
17556
17557///Constructor of @ref pointer_type_def.
17558///
17559/// @param env the environment of the type.
17560///
17561/// @param size_in_bits the size of the type, in bits.
17562///
17563/// @param align_in_bits the alignment of the type, in bits.
17564///
17565/// @param locus the source location where the type was defined.
17566pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
17567 size_t alignment_in_bits,
17568 const location& locus)
17569 : type_or_decl_base(env,
17570 POINTER_TYPE
17571 | ABSTRACT_TYPE_BASE
17572 | ABSTRACT_DECL_BASE),
17573 type_base(env, size_in_bits, alignment_in_bits),
17574 decl_base(env, "", locus, ""),
17575 priv_(new priv())
17576{
17578 string name = string("void") + "*";
17579 set_name(env.intern(name));
17580}
17581
17582/// Set the pointed-to type of the pointer.
17583///
17584/// @param t the new pointed-to type.
17585void
17587{
17588 ABG_ASSERT(t);
17589 priv_->pointed_to_type_ = t;
17590 priv_->naked_pointed_to_type_ = t.get();
17591
17592 try
17593 {
17594 const environment& env = t->get_environment();
17595 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
17596 string name = (pto ? pto->get_name() : string("void")) + "*";
17597 set_name(env.intern(name));
17598 if (pto)
17599 set_visibility(pto->get_visibility());
17600 }
17601 catch (...)
17602 {}
17603}
17604
17605/// Compares two instances of @ref pointer_type_def.
17606///
17607/// If the two intances are different, set a bitfield to give some
17608/// insight about the kind of differences there are.
17609///
17610/// @param l the first artifact of the comparison.
17611///
17612/// @param r the second artifact of the comparison.
17613///
17614/// @param k a pointer to a bitfield that gives information about the
17615/// kind of changes there are between @p l and @p r. This one is set
17616/// iff @p k is non-null and the function returns false.
17617///
17618/// Please note that setting k to a non-null value does have a
17619/// negative performance impact because even if @p l and @p r are not
17620/// equal, the function keeps up the comparison in order to determine
17621/// the different kinds of ways in which they are different.
17622///
17623/// @return true if @p l equals @p r, false otherwise.
17624bool
17626{
17627 // In C and C++ languages, a pointer to void equals all other
17628 // pointers.
17629 if (l.get_translation_unit()
17635 return true;
17636
17637 bool result = l.get_pointed_to_type() == r.get_pointed_to_type();
17638 if (!result)
17639 if (k)
17640 {
17641 if (!types_have_similar_structure(&l, &r))
17642 // pointed-to type changes in which the structure of the
17643 // type changed are considered local changes to the pointer
17644 // type.
17646 *k |= SUBTYPE_CHANGE_KIND;
17647 }
17648
17649 ABG_RETURN(result);
17650}
17651
17652/// Return true iff both instances of pointer_type_def are equal.
17653///
17654/// Note that this function does not check for the scopes of the this
17655/// types.
17656bool
17658{
17659 const pointer_type_def* other = is_pointer_type(&o);
17660 if (!other)
17661 return false;
17662 return try_canonical_compare(this, other);
17663}
17664
17665/// Return true iff both instances of pointer_type_def are equal.
17666///
17667/// Note that this function does not check for the scopes of the
17668/// types.
17669///
17670/// @param other the other type to compare against.
17671///
17672/// @return true iff @p other equals the current instance.
17673bool
17675{
17676 const decl_base* o = is_decl(&other);
17677 if (!o)
17678 return false;
17679 return *this == *o;
17680}
17681
17682/// Return true iff both instances of pointer_type_def are equal.
17683///
17684/// Note that this function does not check for the scopes of the
17685/// types.
17686///
17687/// @param other the other type to compare against.
17688///
17689/// @return true iff @p other equals the current instance.
17690bool
17692{
17693 const decl_base& o = other;
17694 return *this == o;
17695}
17696
17697/// Getter of the pointed-to type.
17698///
17699/// @return the pointed-to type.
17700const type_base_sptr
17702{return priv_->pointed_to_type_.lock();}
17703
17704/// Getter of a naked pointer to the pointed-to type.
17705///
17706/// @return a naked pointed to the pointed-to type.
17707type_base*
17709{return priv_->naked_pointed_to_type_;}
17710
17711/// Build and return the qualified name of the current instance of
17712/// @ref pointer_type_def.
17713///
17714/// @param qn output parameter. The resulting qualified name.
17715///
17716/// @param internal set to true if the call is intended for an
17717/// internal use (for technical use inside the library itself), false
17718/// otherwise. If you don't know what this is for, then set it to
17719/// false.
17720void
17722{qn = get_qualified_name(internal);}
17723
17724/// Build, cache and return the qualified name of the current instance
17725/// of @ref pointer_type_def. Subsequent invocations of this function
17726/// return the cached value.
17727///
17728/// Note that this function should work even if the underlying type is
17729/// momentarily empty.
17730///
17731/// @param internal set to true if the call is intended for an
17732/// internal use (for technical use inside the library itself), false
17733/// otherwise. If you don't know what this is for, then set it to
17734/// false.
17735///
17736/// @return the resulting qualified name.
17737const interned_string&
17739{
17740 type_base* pointed_to_type = get_naked_pointed_to_type();
17741 pointed_to_type = look_through_decl_only(pointed_to_type);
17742
17743 if (internal)
17744 {
17745 if (get_canonical_type())
17746 {
17747 if (priv_->internal_qualified_name_.empty())
17748 if (pointed_to_type)
17749 priv_->internal_qualified_name_ =
17750 pointer_declaration_name(this,
17751 /*variable_name=*/"",
17752 /*qualified_name=*/
17753 is_typedef(pointed_to_type)
17754 ? false
17755 : true,
17756 /*internal=*/true);
17757 return priv_->internal_qualified_name_;
17758 }
17759 else
17760 {
17761 // As the type hasn't yet been canonicalized, its structure
17762 // (and so its name) can change. So let's invalidate the
17763 // cache where we store its name at each invocation of this
17764 // function.
17765 if (pointed_to_type)
17766 if (priv_->temp_internal_qualified_name_.empty())
17767 priv_->temp_internal_qualified_name_ =
17768 pointer_declaration_name(this,
17769 /*variable_name=*/"",
17770 /*qualified_name=*/
17771 is_typedef(pointed_to_type)
17772 ? false
17773 : true,
17774 /*internal=*/true);
17775 return priv_->temp_internal_qualified_name_;
17776 }
17777 }
17778 else
17779 {
17781 {
17782 if (decl_base::peek_qualified_name().empty())
17784 (pointer_declaration_name(this,
17785 /*variable_name=*/"",
17786 /*qualified_name=*/true,
17787 /*internal=*/false));
17789 }
17790 else
17791 {
17792 // As the type hasn't yet been canonicalized, its structure
17793 // (and so its name) can change. So let's invalidate the
17794 // cache where we store its name at each invocation of this
17795 // function.
17796 if (pointed_to_type)
17798 (pointer_declaration_name(this,
17799 /*variable_name=*/"",
17800 /*qualified_name=*/true,
17801 /*internal=*/false));
17803 }
17804 }
17805}
17806
17807/// This implements the ir_traversable_base::traverse pure virtual
17808/// function.
17809///
17810/// @param v the visitor used on the current instance.
17811///
17812/// @return true if the entire IR node tree got traversed, false
17813/// otherwise.
17814bool
17816{
17817 if (v.type_node_has_been_visited(this))
17818 return true;
17819
17820 if (visiting())
17821 return true;
17822
17823 if (v.visit_begin(this))
17824 {
17825 visiting(true);
17826 if (type_base_sptr t = get_pointed_to_type())
17827 t->traverse(v);
17828 visiting(false);
17829 }
17830
17831 bool result = v.visit_end(this);
17833 return result;
17834}
17835
17836pointer_type_def::~pointer_type_def()
17837{}
17838
17839/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
17840/// equality; that is, make it compare the pointed to objects too.
17841///
17842/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
17843/// of the equality.
17844///
17845/// @param r the shared_ptr of @ref pointer_type_def on
17846/// right-hand-side of the equality.
17847///
17848/// @return true if the @ref pointer_type_def pointed to by the
17849/// shared_ptrs are equal, false otherwise.
17850bool
17852{
17853 if (l.get() == r.get())
17854 return true;
17855 if (!!l != !!r)
17856 return false;
17857
17858 return *l == *r;
17859}
17860
17861/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
17862/// equality; that is, make it compare the pointed to objects too.
17863///
17864/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
17865/// of the equality.
17866///
17867/// @param r the shared_ptr of @ref pointer_type_def on
17868/// right-hand-side of the equality.
17869///
17870/// @return true iff the @ref pointer_type_def pointed to by the
17871/// shared_ptrs are different.
17872bool
17874{return !operator==(l, r);}
17875
17876// </pointer_type_def definitions>
17877
17878// <reference_type_def definitions>
17879
17880/// Private data structure of the @ref reference_type_def type.
17881struct reference_type_def::priv
17882{
17883
17884 type_base_wptr pointed_to_type_;
17885 bool is_lvalue_;
17886 interned_string internal_qualified_name_;
17887 interned_string temp_internal_qualified_name_;
17888
17889 priv(const type_base_sptr& t, bool is_lvalue)
17890 : pointed_to_type_(type_or_void(t, t->get_environment())),
17891 is_lvalue_(is_lvalue)
17892 {}
17893
17894 priv(bool is_lvalue)
17895 : is_lvalue_(is_lvalue)
17896 {}
17897
17898 priv() = delete;
17899};
17900
17901/// This function is automatically invoked whenever an instance of
17902/// this type is canonicalized.
17903///
17904/// It's an overload of the virtual type_base::on_canonical_type_set.
17905///
17906/// We put here what is thus meant to be executed only at the point of
17907/// type canonicalization.
17908void
17911
17912/// Constructor of the reference_type_def type.
17913///
17914/// @param pointed_to the pointed to type.
17915///
17916/// @param lvalue wether the reference is an lvalue reference. If
17917/// false, the reference is an rvalue one.
17918///
17919/// @param size_in_bits the size of the type, in bits.
17920///
17921/// @param align_in_bits the alignment of the type, in bits.
17922///
17923/// @param locus the source location of the type.
17924reference_type_def::reference_type_def(const type_base_sptr pointed_to,
17925 bool lvalue,
17926 size_t size_in_bits,
17927 size_t align_in_bits,
17928 const location& locus)
17929 : type_or_decl_base(pointed_to->get_environment(),
17930 REFERENCE_TYPE
17931 | ABSTRACT_TYPE_BASE
17932 | ABSTRACT_DECL_BASE),
17933 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17934 decl_base(pointed_to->get_environment(), "", locus, ""),
17935 priv_(new priv(pointed_to, lvalue))
17936{
17938
17939 try
17940 {
17941 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
17942 string name;
17943 if (pto)
17944 {
17945 set_visibility(pto->get_visibility());
17946 name = string(pto->get_name()) + "&";
17947 }
17948 else
17949 name = string(get_type_name(is_function_type(pointed_to),
17950 /*qualified_name=*/true)) + "&";
17951
17952 if (!is_lvalue())
17953 name += "&";
17954 const environment& env = pointed_to->get_environment();
17955 set_name(env.intern(name));
17956 }
17957 catch (...)
17958 {}
17959}
17960
17961/// Constructor of the reference_type_def type.
17962///
17963/// This one creates a type that has no pointed-to type, temporarily.
17964/// This is useful for cases where the underlying type is not yet
17965/// available. It can be set later using
17966/// reference_type_def::set_pointed_to_type().
17967///
17968/// @param env the environment of the type.
17969///
17970/// @param lvalue wether the reference is an lvalue reference. If
17971/// false, the reference is an rvalue one.
17972///
17973/// @param size_in_bits the size of the type, in bits.
17974///
17975/// @param align_in_bits the alignment of the type, in bits.
17976///
17977/// @param locus the source location of the type.
17978reference_type_def::reference_type_def(const environment& env, bool lvalue,
17979 size_t size_in_bits,
17980 size_t alignment_in_bits,
17981 const location& locus)
17982 : type_or_decl_base(env,
17983 REFERENCE_TYPE
17984 | ABSTRACT_TYPE_BASE
17985 | ABSTRACT_DECL_BASE),
17986 type_base(env, size_in_bits, alignment_in_bits),
17987 decl_base(env, "", locus, ""),
17988 priv_(new priv(lvalue))
17989{
17991 string name = "void&";
17992 if (!is_lvalue())
17993 name += "&";
17994
17995 set_name(env.intern(name));
17996 priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
17997}
17998
17999/// Setter of the pointed_to type of the current reference type.
18000///
18001/// @param pointed_to the new pointed to type.
18002void
18003reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
18004{
18005 ABG_ASSERT(pointed_to_type);
18006 priv_->pointed_to_type_ = pointed_to_type;
18007
18008 decl_base_sptr pto;
18009 try
18010 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
18011 catch (...)
18012 {}
18013
18014 if (pto)
18015 {
18016 set_visibility(pto->get_visibility());
18017 string name = string(pto->get_name()) + "&";
18018 if (!is_lvalue())
18019 name += "&";
18020 const environment& env = pto->get_environment();
18021 set_name(env.intern(name));
18022 }
18023}
18024
18025/// Compares two instances of @ref reference_type_def.
18026///
18027/// If the two intances are different, set a bitfield to give some
18028/// insight about the kind of differences there are.
18029///
18030/// @param l the first artifact of the comparison.
18031///
18032/// @param r the second artifact of the comparison.
18033///
18034/// @param k a pointer to a bitfield that gives information about the
18035/// kind of changes there are between @p l and @p r. This one is set
18036/// iff @p k is non-null and the function returns false.
18037///
18038/// Please note that setting k to a non-null value does have a
18039/// negative performance impact because even if @p l and @p r are not
18040/// equal, the function keeps up the comparison in order to determine
18041/// the different kinds of ways in which they are different.
18042///
18043/// @return true if @p l equals @p r, false otherwise.
18044bool
18046{
18047 if (l.is_lvalue() != r.is_lvalue())
18048 {
18049 if (k)
18052 }
18053
18054 // Compare the pointed-to-types modulo the typedefs they might have
18055 bool result = (l.get_pointed_to_type() == r.get_pointed_to_type());
18056 if (!result)
18057 if (k)
18058 {
18059 if (!types_have_similar_structure(&l, &r))
18061 *k |= SUBTYPE_CHANGE_KIND;
18062 }
18063 ABG_RETURN(result);
18064}
18065
18066/// Equality operator of the @ref reference_type_def type.
18067///
18068/// @param o the other instance of @ref reference_type_def to compare
18069/// against.
18070///
18071/// @return true iff the two instances are equal.
18072bool
18074{
18075 const reference_type_def* other =
18076 dynamic_cast<const reference_type_def*>(&o);
18077 if (!other)
18078 return false;
18079 return try_canonical_compare(this, other);
18080}
18081
18082/// Equality operator of the @ref reference_type_def type.
18083///
18084/// @param o the other instance of @ref reference_type_def to compare
18085/// against.
18086///
18087/// @return true iff the two instances are equal.
18088bool
18090{
18091 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18092 if (!other)
18093 return false;
18094 return *this == *other;
18095}
18096
18097/// Equality operator of the @ref reference_type_def type.
18098///
18099/// @param o the other instance of @ref reference_type_def to compare
18100/// against.
18101///
18102/// @return true iff the two instances are equal.
18103bool
18105{
18106 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18107 if (!other)
18108 return false;
18109 return *this == *other;
18110}
18111
18112type_base_sptr
18113reference_type_def::get_pointed_to_type() const
18114{return priv_->pointed_to_type_.lock();}
18115
18116bool
18117reference_type_def::is_lvalue() const
18118{return priv_->is_lvalue_;}
18119
18120/// Build and return the qualified name of the current instance of the
18121/// @ref reference_type_def.
18122///
18123/// @param qn output parameter. Is set to the newly-built qualified
18124/// name of the current instance of @ref reference_type_def.
18125///
18126/// @param internal set to true if the call is intended for an
18127/// internal use (for technical use inside the library itself), false
18128/// otherwise. If you don't know what this is for, then set it to
18129/// false.
18130void
18132{qn = get_qualified_name(internal);}
18133
18134/// Build, cache and return the qualified name of the current instance
18135/// of the @ref reference_type_def. Subsequent invocations of this
18136/// function return the cached value.
18137///
18138/// @param internal set to true if the call is intended for an
18139/// internal use (for technical use inside the library itself), false
18140/// otherwise. If you don't know what this is for, then set it to
18141/// false.
18142///
18143/// @return the newly-built qualified name of the current instance of
18144/// @ref reference_type_def.
18145const interned_string&
18147{
18148 type_base_sptr pointed_to_type = get_pointed_to_type();
18149 pointed_to_type = look_through_decl_only(pointed_to_type);
18150
18151 if (internal)
18152 {
18153 if (get_canonical_type())
18154 {
18155 if (priv_->internal_qualified_name_.empty())
18156 if (pointed_to_type)
18157 priv_->internal_qualified_name_ =
18158 get_name_of_reference_to_type(*pointed_to_type,
18159 is_lvalue(),
18160 /*qualified_name=*/
18161 is_typedef(pointed_to_type)
18162 ? false
18163 : true,
18164 /*internal=*/true);
18165 return priv_->internal_qualified_name_;
18166 }
18167 else
18168 {
18169 // As the type hasn't yet been canonicalized, its structure
18170 // (and so its name) can change. So let's invalidate the
18171 // cache where we store its name at each invocation of this
18172 // function.
18173 if (pointed_to_type)
18174 if (priv_->temp_internal_qualified_name_.empty())
18175 priv_->temp_internal_qualified_name_ =
18176 get_name_of_reference_to_type(*pointed_to_type,
18177 is_lvalue(),
18178 /*qualified_name=*/
18179 is_typedef(pointed_to_type)
18180 ? false
18181 : true,
18182 /*internal=*/true);
18183 return priv_->temp_internal_qualified_name_;
18184 }
18185 }
18186 else
18187 {
18189 {
18191 (get_name_of_reference_to_type(*pointed_to_type,
18192 is_lvalue(),
18193 /*qualified_name=*/true,
18194 /*internal=*/false));
18196 }
18197 else
18198 {
18199 // As the type hasn't yet been canonicalized, its structure
18200 // (and so its name) can change. So let's invalidate the
18201 // cache where we store its name at each invocation of this
18202 // function.
18203 if (pointed_to_type)
18205 (get_name_of_reference_to_type(*pointed_to_type,
18206 is_lvalue(),
18207 /*qualified_name=*/true,
18208 /*internal=*/false));
18210 }
18211 }
18212}
18213
18214/// Get the pretty representation of the current instance of @ref
18215/// reference_type_def.
18216///
18217/// @param internal set to true if the call is intended to get a
18218/// representation of the decl (or type) for the purpose of canonical
18219/// type comparison. This is mainly used in the function
18220/// type_base::get_canonical_type_for().
18221///
18222/// In other words if the argument for this parameter is true then the
18223/// call is meant for internal use (for technical use inside the
18224/// library itself), false otherwise. If you don't know what this is
18225/// for, then set it to false.
18226///
18227/// @param qualified_name if true, names emitted in the pretty
18228/// representation are fully qualified.
18229///
18230/// @return the pretty representatin of the @ref reference_type_def.
18231string
18233 bool qualified_name) const
18234{
18235 string result =
18237 (get_pointed_to_type()),
18238 is_lvalue(),
18239 qualified_name,
18240 internal);
18241
18242 return result;
18243}
18244
18245/// This implements the ir_traversable_base::traverse pure virtual
18246/// function.
18247///
18248/// @param v the visitor used on the current instance.
18249///
18250/// @return true if the entire IR node tree got traversed, false
18251/// otherwise.
18252bool
18254{
18255 if (v.type_node_has_been_visited(this))
18256 return true;
18257
18258 if (visiting())
18259 return true;
18260
18261 if (v.visit_begin(this))
18262 {
18263 visiting(true);
18264 if (type_base_sptr t = get_pointed_to_type())
18265 t->traverse(v);
18266 visiting(false);
18267 }
18268
18269 bool result = v.visit_end(this);
18271 return result;
18272}
18273
18274reference_type_def::~reference_type_def()
18275{}
18276
18277/// Turn equality of shared_ptr of @ref reference_type_def into a deep
18278/// equality; that is, make it compare the pointed to objects too.
18279///
18280/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18281/// of the equality.
18282///
18283/// @param r the shared_ptr of @ref reference_type_def on
18284/// right-hand-side of the equality.
18285///
18286/// @return true if the @ref reference_type_def pointed to by the
18287/// shared_ptrs are equal, false otherwise.
18288bool
18290{
18291 if (l.get() == r.get())
18292 return true;
18293 if (!!l != !!r)
18294 return false;
18295
18296 return *l == *r;
18297}
18298
18299/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
18300/// equality; that is, make it compare the pointed to objects too.
18301///
18302/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
18303/// of the equality.
18304///
18305/// @param r the shared_ptr of @ref reference_type_def on
18306/// right-hand-side of the equality.
18307///
18308/// @return true iff the @ref reference_type_def pointed to by the
18309/// shared_ptrs are different.
18310bool
18312{return !operator==(l, r);}
18313
18314// </reference_type_def definitions>
18315
18316// <ptr_to_mbr_type definitions>
18317
18318/// The private data type of @ref ptr_to_mbr_type.
18319struct ptr_to_mbr_type::priv
18320{
18321 // The type of the data member this pointer-to-member-type
18322 // designates.
18323 type_base_sptr dm_type_;
18324 // The class (or typedef to potentially qualified class) containing
18325 // the data member this pointer-to-member-type designates.
18326 type_base_sptr containing_type_;
18327 interned_string internal_qualified_name_;
18328 interned_string temp_internal_qualified_name_;
18329
18330 priv()
18331 {}
18332
18333 priv(const type_base_sptr& dm_type, const type_base_sptr& containing_type)
18334 : dm_type_(dm_type),
18335 containing_type_(containing_type)
18336 {}
18337};// end struct ptr_to_mbr_type::priv
18338
18339/// A constructor for a @ref ptr_to_mbr_type type.
18340///
18341/// @param env the environment to construct the @ref ptr_to_mbr_type in.
18342///
18343/// @param member_type the member type of the of the @ref
18344/// ptr_to_mbr_type to construct.
18345///
18346/// @param containing_type the containing type of the @ref
18347/// ptr_to_mbr_type to construct.
18348///
18349/// @param size_in_bits the size (in bits) of the resulting type.
18350///
18351/// @param alignment_in_bits the alignment (in bits) of the resulting
18352/// type.
18353///
18354/// @param locus the source location of the definition of the
18355/// resulting type.
18356ptr_to_mbr_type::ptr_to_mbr_type(const environment& env,
18357 const type_base_sptr& member_type,
18358 const type_base_sptr& containing_type,
18359 size_t size_in_bits,
18360 size_t alignment_in_bits,
18361 const location& locus)
18362 : type_or_decl_base(env,
18363 POINTER_TO_MEMBER_TYPE
18364 | ABSTRACT_TYPE_BASE
18365 | ABSTRACT_DECL_BASE),
18366 type_base(env, size_in_bits, alignment_in_bits),
18367 decl_base(env, "", locus, ""),
18368 priv_(new priv(member_type, containing_type))
18369{
18371 ABG_ASSERT(member_type);
18372 ABG_ASSERT(containing_type);
18373 interned_string name = ptr_to_mbr_declaration_name(this, "",
18374 /*qualified=*/true,
18375 /*internal=*/false);
18376 set_name(name);
18377}
18378
18379/// Getter of the member type of the current @ref ptr_to_mbr_type.
18380///
18381/// @return the type of the member referred to by the current
18382/// @ptr_to_mbr_type.
18383const type_base_sptr&
18385{return priv_->dm_type_;}
18386
18387/// Getter of the type containing the member pointed-to by the current
18388/// @ref ptr_to_mbr_type.
18389///
18390/// @return the type containing the member pointed-to by the current
18391/// @ref ptr_to_mbr_type.
18392const type_base_sptr&
18394{return priv_->containing_type_;}
18395
18396/// Equality operator for the current @ref ptr_to_mbr_type.
18397///
18398///@param o the other instance of @ref ptr_to_mbr_type to compare the
18399///current instance to.
18400///
18401/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18402bool
18404{
18405 const ptr_to_mbr_type* other =
18406 dynamic_cast<const ptr_to_mbr_type*>(&o);
18407 if (!other)
18408 return false;
18409 return try_canonical_compare(this, other);
18410}
18411
18412/// Equality operator for the current @ref ptr_to_mbr_type.
18413///
18414///@param o the other instance of @ref ptr_to_mbr_type to compare the
18415///current instance to.
18416///
18417/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18418bool
18420{
18421 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18422 if (!other)
18423 return false;
18424 return *this == *other;
18425}
18426
18427/// Equality operator for the current @ref ptr_to_mbr_type.
18428///
18429///@param o the other instance of @ref ptr_to_mbr_type to compare the
18430///current instance to.
18431///
18432/// @return true iff the current @ref ptr_to_mbr_type equals @p o.
18433bool
18435{
18436 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18437 if (!other)
18438 return false;
18439 return *this == *other;
18440}
18441
18442/// Get the qualified name for the current @ref ptr_to_mbr_type.
18443///
18444/// @param qualified_name out parameter. This is set to the name of
18445/// the current @ref ptr_to_mbr_type.
18446///
18447/// @param internal if this is true, then the qualified name is for
18448/// the purpose of type canoicalization.
18449void
18451 bool internal) const
18452{qualified_name = get_qualified_name(internal);}
18453
18454/// Get the qualified name for the current @ref ptr_to_mbr_type.
18455///
18456/// @param internal if this is true, then the qualified name is for
18457/// the purpose of type canoicalization.
18458///
18459/// @return the qualified name for the current @ref ptr_to_mbr_type.
18460const interned_string&
18462{
18463 type_base_sptr member_type = get_member_type();
18464 type_base_sptr containing_type = get_containing_type();
18465
18466 if (internal)
18467 {
18468 if (get_canonical_type())
18469 {
18470 if (priv_->internal_qualified_name_.empty())
18471 priv_->internal_qualified_name_ =
18472 ptr_to_mbr_declaration_name(this, "",
18473 /*qualified=*/true,
18474 internal);
18475 return priv_->internal_qualified_name_;
18476 }
18477 else
18478 {
18479 priv_->temp_internal_qualified_name_ =
18480 ptr_to_mbr_declaration_name(this, "", /*qualified=*/true, internal);
18481 return priv_->temp_internal_qualified_name_;
18482 }
18483 }
18484 else
18485 {
18487 (ptr_to_mbr_declaration_name(this, "", /*qualified=*/true,
18488 /*internal=*/false));
18490 }
18491}
18492
18493/// This implements the ir_traversable_base::traverse pure virtual
18494/// function for @ref ptr_to_mbr_type.
18495///
18496/// @param v the visitor used on the current instance.
18497///
18498/// @return true if the entire IR node tree got traversed, false
18499/// otherwise.
18500bool
18502{
18503 if (v.type_node_has_been_visited(this))
18504 return true;
18505
18506 if (visiting())
18507 return true;
18508
18509 if (v.visit_begin(this))
18510 {
18511 visiting(true);
18512 if (type_base_sptr t = get_member_type())
18513 t->traverse(v);
18514
18515 if (type_base_sptr t = get_containing_type())
18516 t->traverse(v);
18517 visiting(false);
18518 }
18519
18520 bool result = v.visit_end(this);
18522 return result;
18523}
18524
18525/// Desctructor for @ref ptr_to_mbr_type.
18527{}
18528
18529
18530/// Compares two instances of @ref ptr_to_mbr_type.
18531///
18532/// If the two intances are different, set a bitfield to give some
18533/// insight about the kind of differences there are.
18534///
18535/// @param l the first artifact of the comparison.
18536///
18537/// @param r the second artifact of the comparison.
18538///
18539/// @param k a pointer to a bitfield that gives information about the
18540/// kind of changes there are between @p l and @p r. This one is set
18541/// iff @p k is non-null and the function returns false.
18542///
18543/// Please note that setting k to a non-null value does have a
18544/// negative performance impact because even if @p l and @p r are not
18545/// equal, the function keeps up the comparison in order to determine
18546/// the different kinds of ways in which they are different.
18547///
18548/// @return true if @p l equals @p r, false otherwise.
18549bool
18551{
18552 bool result = true;
18553
18554 if (!(l.decl_base::operator==(r)))
18555 {
18556 result = false;
18557 if (k)
18559 else
18560 result = false;
18561 }
18562
18563 if (l.get_member_type() != r.get_member_type())
18564 {
18565 if (k)
18566 {
18567 if (!types_have_similar_structure(&l, &r))
18569 *k |= SUBTYPE_CHANGE_KIND;
18570 }
18571 result = false;
18572 }
18573
18575 {
18576 if (k)
18577 {
18578 if (!types_have_similar_structure(&l, &r))
18580 *k |= SUBTYPE_CHANGE_KIND;
18581 }
18582 result = false;
18583 }
18584
18585 ABG_RETURN(result);
18586}
18587
18588// </ptr_to_mbr_type definitions>
18589
18590// <array_type_def definitions>
18591
18592// <array_type_def::subrange_type>
18593array_type_def::subrange_type::~subrange_type() = default;
18594
18595// <array_type_def::subrante_type::bound_value>
18596
18597/// Default constructor of the @ref
18598/// array_type_def::subrange_type::bound_value class.
18599///
18600/// Constructs an unsigned bound_value of value zero.
18602 : s_(UNSIGNED_SIGNEDNESS)
18603{
18604 v_.unsigned_ = 0;
18605}
18606
18607/// Initialize an unsigned bound_value with a given value.
18608///
18609/// @param v the initial bound value.
18611 : s_(UNSIGNED_SIGNEDNESS)
18612{
18613 v_.unsigned_ = v;
18614}
18615
18616/// Initialize a signed bound_value with a given value.
18617///
18618/// @param v the initial bound value.
18620 : s_(SIGNED_SIGNEDNESS)
18621{
18622 v_.signed_ = v;
18623}
18624
18625/// Getter of the signedness (unsigned VS signed) of the bound value.
18626///
18627/// @return the signedness of the bound value.
18628enum array_type_def::subrange_type::bound_value::signedness
18630{return s_;}
18631
18632/// Setter of the signedness (unsigned VS signed) of the bound value.
18633///
18634/// @param s the new signedness of the bound value.
18635void
18637{ s_ = s;}
18638
18639/// Getter of the bound value as a signed value.
18640///
18641/// @return the bound value as signed.
18642int64_t
18644{return v_.signed_;
18645}
18646
18647/// Getter of the bound value as an unsigned value.
18648///
18649/// @return the bound value as unsigned.
18650uint64_t
18652{return v_.unsigned_;}
18653
18654/// Setter of the bound value as unsigned.
18655///
18656/// @param v the new unsigned value.
18657void
18659{
18660 s_ = UNSIGNED_SIGNEDNESS;
18661 v_.unsigned_ = v;
18662}
18663
18664/// Setter of the bound value as signed.
18665///
18666/// @param v the new signed value.
18667void
18669{
18670 s_ = SIGNED_SIGNEDNESS;
18671 v_.signed_ = v;
18672}
18673
18674/// Equality operator of the bound value.
18675///
18676/// @param v the other bound value to compare with.
18677///
18678/// @return true iff the current bound value equals @p v.
18679bool
18681{
18682 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
18683}
18684
18685// </array_type_def::subrante_type::bound_value>
18686
18687struct array_type_def::subrange_type::priv
18688{
18689 bound_value lower_bound_;
18690 bound_value upper_bound_;
18691 type_base_wptr underlying_type_;
18693 bool infinite_;
18694
18695 priv(bound_value ub,
18696 translation_unit::language l = translation_unit::LANG_C11)
18697 : upper_bound_(ub), language_(l), infinite_(false)
18698 {}
18699
18700 priv(bound_value lb, bound_value ub,
18701 translation_unit::language l = translation_unit::LANG_C11)
18702 : lower_bound_(lb), upper_bound_(ub),
18703 language_(l), infinite_(false)
18704 {}
18705
18706 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
18707 translation_unit::language l = translation_unit::LANG_C11)
18708 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
18709 language_(l), infinite_(false)
18710 {}
18711};
18712
18713/// Constructor of an array_type_def::subrange_type type.
18714///
18715/// @param env the environment this type was created from.
18716///
18717/// @param name the name of the subrange type.
18718///
18719/// @param lower_bound the lower bound of the array. This is
18720/// generally zero (at least for C and C++).
18721///
18722/// @param upper_bound the upper bound of the array.
18723///
18724/// @param underlying_type the underlying type of the subrange type.
18725///
18726/// @param loc the source location where the type is defined.
18727array_type_def::subrange_type::subrange_type(const environment& env,
18728 const string& name,
18729 bound_value lower_bound,
18730 bound_value upper_bound,
18731 const type_base_sptr& utype,
18732 const location& loc,
18734 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18735 type_base(env,
18736 upper_bound.get_unsigned_value()
18737 - lower_bound.get_unsigned_value(),
18738 0),
18739 decl_base(env, name, loc, ""),
18740 priv_(new priv(lower_bound, upper_bound, utype, l))
18741{
18743}
18744
18745/// Constructor of the array_type_def::subrange_type type.
18746///
18747/// @param env the environment this type is being created in.
18748///
18749/// @param name the name of the subrange type.
18750///
18751/// @param lower_bound the lower bound of the array. This is
18752/// generally zero (at least for C and C++).
18753///
18754/// @param upper_bound the upper bound of the array.
18755///
18756/// @param loc the source location where the type is defined.
18757///
18758/// @param l the language that generated this subrange.
18759array_type_def::subrange_type::subrange_type(const environment& env,
18760 const string& name,
18761 bound_value lower_bound,
18762 bound_value upper_bound,
18763 const location& loc,
18765 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18766 type_base(env,
18767 upper_bound.get_unsigned_value()
18768 - lower_bound.get_unsigned_value(), 0),
18769 decl_base(env, name, loc, ""),
18770 priv_(new priv(lower_bound, upper_bound, l))
18771{
18773}
18774
18775/// Constructor of the array_type_def::subrange_type type.
18776///
18777/// @param env the environment this type is being created from.
18778///
18779/// @param name of the name of type.
18780///
18781/// @param upper_bound the upper bound of the array. The lower bound
18782/// is considered to be zero.
18783///
18784/// @param loc the source location of the type.
18785///
18786/// @param the language that generated this type.
18787array_type_def::subrange_type::subrange_type(const environment& env,
18788 const string& name,
18789 bound_value upper_bound,
18790 const location& loc,
18792 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18793 type_base(env, upper_bound.get_unsigned_value(), 0),
18794 decl_base(env, name, loc, ""),
18795 priv_(new priv(upper_bound, l))
18796{
18798}
18799
18800/// Getter of the underlying type of the subrange, that is, the type
18801/// that defines the range.
18802///
18803/// @return the underlying type.
18804type_base_sptr
18806{return priv_->underlying_type_.lock();}
18807
18808/// Setter of the underlying type of the subrange, that is, the type
18809/// that defines the range.
18810///
18811/// @param u the new underlying type.
18812void
18814{
18815 ABG_ASSERT(priv_->underlying_type_.expired());
18816 priv_->underlying_type_ = u;
18817}
18818
18819/// Getter of the upper bound of the subrange type.
18820///
18821/// @return the upper bound of the subrange type.
18822int64_t
18824{return priv_->upper_bound_.get_signed_value();}
18825
18826/// Getter of the lower bound of the subrange type.
18827///
18828/// @return the lower bound of the subrange type.
18829int64_t
18831{return priv_->lower_bound_.get_signed_value();}
18832
18833/// Setter of the upper bound of the subrange type.
18834///
18835/// @param ub the new value of the upper bound.
18836void
18838{priv_->upper_bound_ = ub;}
18839
18840/// Setter of the lower bound.
18841///
18842/// @param lb the new value of the lower bound.
18843void
18845{priv_->lower_bound_ = lb;}
18846
18847/// Getter of the length of the subrange type.
18848///
18849/// Note that a length of zero means the array has an infinite (or
18850/// rather a non-known) size.
18851///
18852/// @return the length of the subrange type.
18853uint64_t
18855{
18856 if (is_non_finite())
18857 return 0;
18858
18859 // A subrange can have an upper bound that is lower than its lower
18860 // bound. This is possible in Ada for instance. In that case, the
18861 // length of the subrange is considered to be zero.
18862 if (get_upper_bound() >= get_lower_bound())
18863 return get_upper_bound() - get_lower_bound() + 1;
18864 return 0;
18865}
18866
18867/// Test if the length of the subrange type is infinite.
18868///
18869/// @return true iff the length of the subrange type is infinite.
18870bool
18872{return priv_->infinite_;}
18873
18874/// Set the infinite-ness status of the subrange type.
18875///
18876/// @param f true iff the length of the subrange type should be set to
18877/// being infinite.
18878void
18880{priv_->infinite_ = f;}
18881
18882/// Getter of the language that generated this type.
18883///
18884/// @return the language of this type.
18887{return priv_->language_;}
18888
18889/// Return a string representation of the sub range.
18890///
18891/// @return the string representation of the sub range.
18892string
18894{
18895 std::ostringstream o;
18896
18898 {
18899 type_base_sptr underlying_type = get_underlying_type();
18900 if (underlying_type)
18901 o << ir::get_pretty_representation(underlying_type, false) << " ";
18902 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
18903 }
18904 else if (is_non_finite())
18905 o << "[]";
18906 else
18907 o << "[" << get_length() << "]";
18908
18909 return o.str();
18910}
18911
18912/// Return a string representation of a vector of subranges
18913///
18914/// @return the string representation of a vector of sub ranges.
18915string
18917{
18918 if (v.empty())
18919 return "[]";
18920
18921 string r;
18922 for (vector<subrange_sptr>::const_iterator i = v.begin();
18923 i != v.end();
18924 ++i)
18925 r += (*i)->as_string();
18926
18927 return r;
18928}
18929
18930/// Compares two isntances of @ref array_type_def::subrange_type.
18931///
18932/// If the two intances are different, set a bitfield to give some
18933/// insight about the kind of differences there are.
18934///
18935/// @param l the first artifact of the comparison.
18936///
18937/// @param r the second artifact of the comparison.
18938///
18939/// @param k a pointer to a bitfield that gives information about the
18940/// kind of changes there are between @p l and @p r. This one is set
18941/// iff @p k is non-null and the function returns false.
18942///
18943/// Please note that setting k to a non-null value does have a
18944/// negative performance impact because even if @p l and @p r are not
18945/// equal, the function keeps up the comparison in order to determine
18946/// the different kinds of ways in which they are different.
18947///
18948/// @return true if @p l equals @p r, false otherwise.
18949bool
18952 change_kind* k)
18953{
18954 bool result = true;
18955
18956 if (l.get_lower_bound() != r.get_lower_bound()
18957 || l.get_upper_bound() != r.get_upper_bound()
18958 || l.get_name() != r.get_name())
18959 {
18960 result = false;
18961 if (k)
18963 else
18964 ABG_RETURN(result);
18965 }
18966
18967 ABG_RETURN(result);
18968}
18969
18970/// Equality operator.
18971///
18972/// @param o the other subrange to test against.
18973///
18974/// @return true iff @p o equals the current instance of
18975/// array_type_def::subrange_type.
18976bool
18978{
18979 const subrange_type* other =
18980 dynamic_cast<const subrange_type*>(&o);
18981 if (!other)
18982 return false;
18983 return try_canonical_compare(this, other);
18984}
18985
18986/// Equality operator.
18987///
18988/// @param o the other subrange to test against.
18989///
18990/// @return true iff @p o equals the current instance of
18991/// array_type_def::subrange_type.
18992bool
18994{
18995 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18996 if (!other)
18997 return false;
18998 return *this == *other;
18999}
19000
19001/// Equality operator.
19002///
19003/// @param o the other subrange to test against.
19004///
19005/// @return true iff @p o equals the current instance of
19006/// array_type_def::subrange_type.
19007bool
19009{
19010 const type_base &t = o;
19011 return operator==(t);
19012}
19013
19014/// Equality operator.
19015///
19016/// @param o the other subrange to test against.
19017///
19018/// @return true iff @p o equals the current instance of
19019/// array_type_def::subrange_type.
19020bool
19022{return !operator==(o);}
19023
19024/// Equality operator.
19025///
19026/// @param o the other subrange to test against.
19027///
19028/// @return true iff @p o equals the current instance of
19029/// array_type_def::subrange_type.
19030bool
19032{return !operator==(o);}
19033
19034/// Inequality operator.
19035///
19036/// @param o the other subrange to test against.
19037///
19038/// @return true iff @p o is different from the current instance of
19039/// array_type_def::subrange_type.
19040bool
19042{return !operator==(o);}
19043
19044/// Build a pretty representation for an
19045/// array_type_def::subrange_type.
19046///
19047/// @param internal set to true if the call is intended to get a
19048/// representation of the decl (or type) for the purpose of canonical
19049/// type comparison. This is mainly used in the function
19050/// type_base::get_canonical_type_for().
19051///
19052/// In other words if the argument for this parameter is true then the
19053/// call is meant for internal use (for technical use inside the
19054/// library itself), false otherwise. If you don't know what this is
19055/// for, then set it to false.
19056///
19057/// @return a copy of the pretty representation of the current
19058/// instance of typedef_decl.
19059string
19061{
19062 string name = get_name();
19063 string repr;
19064
19065 if (name.empty())
19066 repr += "<anonymous range>";
19067 else
19068 repr += "<range " + get_name() + ">";
19069 repr += as_string();
19070
19071 return repr;
19072}
19073
19074/// This implements the ir_traversable_base::traverse pure virtual
19075/// function.
19076///
19077/// @param v the visitor used on the current instance.
19078///
19079/// @return true if the entire IR node tree got traversed, false
19080/// otherwise.
19081bool
19083{
19084 if (v.type_node_has_been_visited(this))
19085 return true;
19086
19087 if (v.visit_begin(this))
19088 {
19089 visiting(true);
19090 if (type_base_sptr u = get_underlying_type())
19091 u->traverse(v);
19092 visiting(false);
19093 }
19094
19095 bool result = v.visit_end(this);
19097 return result;
19098}
19099
19100// </array_type_def::subrange_type>
19101
19102struct array_type_def::priv
19103{
19104 type_base_wptr element_type_;
19105 subranges_type subranges_;
19106 interned_string temp_internal_qualified_name_;
19107 interned_string internal_qualified_name_;
19108
19109 priv(type_base_sptr t)
19110 : element_type_(t)
19111 {}
19112
19113 priv(type_base_sptr t, subranges_type subs)
19114 : element_type_(t), subranges_(subs)
19115 {}
19116
19117 priv()
19118 {}
19119};
19120
19121/// Constructor for the type array_type_def
19122///
19123/// Note how the constructor expects a vector of subrange
19124/// objects. Parsing of the array information always entails
19125/// parsing the subrange info as well, thus the class subrange_type
19126/// is defined inside class array_type_def and also parsed
19127/// simultaneously.
19128///
19129/// @param e_type the type of the elements contained in the array
19130///
19131/// @param subs a vector of the array's subranges(dimensions)
19132///
19133/// @param locus the source location of the array type definition.
19134array_type_def::array_type_def(const type_base_sptr e_type,
19135 const std::vector<subrange_sptr>& subs,
19136 const location& locus)
19138 ARRAY_TYPE
19139 | ABSTRACT_TYPE_BASE
19140 | ABSTRACT_DECL_BASE),
19141 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
19142 decl_base(e_type->get_environment(), locus),
19143 priv_(new priv(e_type))
19144{
19146 append_subranges(subs);
19147}
19148
19149/// Constructor for the type array_type_def
19150///
19151/// This constructor builds a temporary array that has no element type
19152/// associated. Later when the element type is available, it be set
19153/// with the array_type_def::set_element_type() member function.
19154///
19155/// Note how the constructor expects a vector of subrange
19156/// objects. Parsing of the array information always entails
19157/// parsing the subrange info as well, thus the class subrange_type
19158/// is defined inside class array_type_def and also parsed
19159/// simultaneously.
19160///
19161/// @param env the environment of the array type.
19162///
19163/// @param subs a vector of the array's subranges(dimensions)
19164///
19165/// @param locus the source location of the array type definition.
19166array_type_def::array_type_def(const environment& env,
19167 const std::vector<subrange_sptr>& subs,
19168 const location& locus)
19169 : type_or_decl_base(env,
19170 ARRAY_TYPE
19171 | ABSTRACT_TYPE_BASE
19172 | ABSTRACT_DECL_BASE),
19173 type_base(env, 0, 0),
19174 decl_base(env, locus),
19175 priv_(new priv)
19176{
19178 append_subranges(subs);
19179}
19180
19181/// Update the size of the array.
19182///
19183/// This function computes the size of the array and sets it using
19184/// type_base::set_size_in_bits().
19185void
19186array_type_def::update_size()
19187{
19188 type_base_sptr e = priv_->element_type_.lock();
19189 if (e)
19190 {
19191 size_t s = e->get_size_in_bits();
19192 if (s)
19193 {
19194 for (const auto &sub : get_subranges())
19195 s *= sub->get_length();
19197 }
19198 set_alignment_in_bits(e->get_alignment_in_bits());
19199 }
19200}
19201
19202string
19203array_type_def::get_subrange_representation() const
19204{
19206 return r;
19207}
19208
19209/// Get the pretty representation of the current instance of @ref
19210/// array_type_def.
19211///
19212/// @param internal set to true if the call is intended to get a
19213/// representation of the decl (or type) for the purpose of canonical
19214/// type comparison. This is mainly used in the function
19215/// type_base::get_canonical_type_for().
19216///
19217/// In other words if the argument for this parameter is true then the
19218/// call is meant for internal use (for technical use inside the
19219/// library itself), false otherwise. If you don't know what this is
19220/// for, then set it to false.
19221/// @param internal set to true if the call is intended for an
19222/// internal use (for technical use inside the library itself), false
19223/// otherwise. If you don't know what this is for, then set it to
19224/// false.
19225///
19226/// @return the pretty representation of the ABI artifact.
19227string
19229 bool qualified_name) const
19230{
19231 return array_declaration_name(this, /*variable_name=*/"",
19232 qualified_name, internal);
19233}
19234
19235/// Compares two instances of @ref array_type_def.
19236///
19237/// If the two intances are different, set a bitfield to give some
19238/// insight about the kind of differences there are.
19239///
19240/// @param l the first artifact of the comparison.
19241///
19242/// @param r the second artifact of the comparison.
19243///
19244/// @param k a pointer to a bitfield that gives information about the
19245/// kind of changes there are between @p l and @p r. This one is set
19246/// iff @p k is non-null and the function returns false.
19247///
19248/// Please note that setting k to a non-null value does have a
19249/// negative performance impact because even if @p l and @p r are not
19250/// equal, the function keeps up the comparison in order to determine
19251/// the different kinds of ways in which they are different.
19252///
19253/// @return true if @p l equals @p r, false otherwise.
19254bool
19256{
19257 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
19258 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
19259
19260 bool result = true;
19261 if (this_subs.size() != other_subs.size())
19262 {
19263 result = false;
19264 if (k)
19266 else
19268 }
19269
19270 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19271 for (i = this_subs.begin(), j = other_subs.begin();
19272 i != this_subs.end() && j != other_subs.end();
19273 ++i, ++j)
19274 if (**i != **j)
19275 {
19276 result = false;
19277 if (k)
19278 {
19280 break;
19281 }
19282 else
19284 }
19285
19286 // Compare the element types modulo the typedefs they might have
19287 if (l.get_element_type() != r.get_element_type())
19288 {
19289 result = false;
19290 if (k)
19291 *k |= SUBTYPE_CHANGE_KIND;
19292 else
19294 }
19295
19296 ABG_RETURN(result);
19297}
19298
19299/// Test if two variables are equals modulo CV qualifiers.
19300///
19301/// @param l the first array of the comparison.
19302///
19303/// @param r the second array of the comparison.
19304///
19305/// @return true iff @p l equals @p r or, if they are different, the
19306/// difference between the too is just a matter of CV qualifiers.
19307bool
19309{
19310 if (l == r)
19311 return true;
19312
19313 if (!l || !r)
19315
19318
19319 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
19320 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
19321
19322 if (this_subs.size() != other_subs.size())
19324
19325 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19326 for (i = this_subs.begin(), j = other_subs.begin();
19327 i != this_subs.end() && j != other_subs.end();
19328 ++i, ++j)
19329 if (**i != **j)
19331
19332 type_base *first_element_type =
19334 type_base *second_element_type =
19336
19337 if (*first_element_type != *second_element_type)
19339
19340 return true;
19341}
19342
19343/// Get the language of the array.
19344///
19345/// @return the language of the array.
19348{
19349 const std::vector<subrange_sptr>& subranges =
19350 get_subranges();
19351
19352 if (subranges.empty())
19353 return translation_unit::LANG_C11;
19354 return subranges.front()->get_language();
19355}
19356
19357bool
19359{
19360 const array_type_def* other =
19361 dynamic_cast<const array_type_def*>(&o);
19362 if (!other)
19363 return false;
19364 return try_canonical_compare(this, other);
19365}
19366
19367bool
19369{
19370 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19371 if (!other)
19372 return false;
19373 return *this == *other;
19374}
19375
19376/// Getter of the type of an array element.
19377///
19378/// @return the type of an array element.
19379const type_base_sptr
19381{return priv_->element_type_.lock();}
19382
19383/// Setter of the type of array element.
19384///
19385/// Beware that after using this function, one might want to
19386/// re-compute the canonical type of the array, if one has already
19387/// been computed.
19388///
19389/// The intended use of this method is to permit in-place adjustment
19390/// of the element type's qualifiers. In particular, the size of the
19391/// element type should not be changed.
19392///
19393/// @param element_type the new element type to set.
19394void
19395array_type_def::set_element_type(const type_base_sptr& element_type)
19396{
19397 priv_->element_type_ = element_type;
19398 update_size();
19400}
19401
19402/// Append subranges from the vector @param subs to the current
19403/// vector of subranges.
19404void
19405array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
19406{
19407
19408 for (const auto &sub : subs)
19409 priv_->subranges_.push_back(sub);
19410
19411 update_size();
19413}
19414
19415/// @return true if one of the sub-ranges of the array is infinite, or
19416/// if the array has no sub-range at all, also meaning that the size
19417/// of the array is infinite.
19418bool
19420{
19421 if (priv_->subranges_.empty())
19422 return true;
19423
19424 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
19425 priv_->subranges_.begin();
19426 i != priv_->subranges_.end();
19427 ++i)
19428 if ((*i)->is_non_finite())
19429 return true;
19430
19431 return false;
19432}
19433
19434int
19435array_type_def::get_dimension_count() const
19436{return priv_->subranges_.size();}
19437
19438/// Build and return the qualified name of the current instance of the
19439/// @ref array_type_def.
19440///
19441/// @param qn output parameter. Is set to the newly-built qualified
19442/// name of the current instance of @ref array_type_def.
19443///
19444/// @param internal set to true if the call is intended for an
19445/// internal use (for technical use inside the library itself), false
19446/// otherwise. If you don't know what this is for, then set it to
19447/// false.
19448void
19450{qn = get_qualified_name(internal);}
19451
19452/// Compute the qualified name of the array.
19453///
19454/// @param internal set to true if the call is intended for an
19455/// internal use (for technical use inside the library itself), false
19456/// otherwise. If you don't know what this is for, then set it to
19457/// false.
19458///
19459/// @return the resulting qualified name.
19460const interned_string&
19462{
19463 if (internal)
19464 {
19465 if (get_canonical_type())
19466 {
19467 if (priv_->internal_qualified_name_.empty())
19468 priv_->internal_qualified_name_ =
19469 array_declaration_name(this, /*variable_name=*/"",
19470 /*qualified=*/false,
19471 /*internal=*/true);
19472 return priv_->internal_qualified_name_;
19473 }
19474 else
19475 {
19476 priv_->temp_internal_qualified_name_ =
19477 array_declaration_name(this, /*variable_name=*/"",
19478 /*qualified*/false, /*internal*/true);
19479 return priv_->temp_internal_qualified_name_;
19480 }
19481 }
19482 else
19483 {
19484 if (get_canonical_type())
19485 {
19486 if (decl_base::peek_qualified_name().empty())
19487 set_qualified_name(array_declaration_name(this,
19488 /*variable_name=*/"",
19489 /*qualified=*/false,
19490 /*internal=*/false));
19492 }
19493 else
19494 {
19496 (array_declaration_name(this, /*variable_name=*/"",
19497 /*qualified=*/false,
19498 /*internal=*/false));
19500 }
19501 }
19502}
19503
19504/// This implements the ir_traversable_base::traverse pure virtual
19505/// function.
19506///
19507/// @param v the visitor used on the current instance.
19508///
19509/// @return true if the entire IR node tree got traversed, false
19510/// otherwise.
19511bool
19513{
19514 if (v.type_node_has_been_visited(this))
19515 return true;
19516
19517 if (visiting())
19518 return true;
19519
19520 if (v.visit_begin(this))
19521 {
19522 visiting(true);
19523 if (type_base_sptr t = get_element_type())
19524 t->traverse(v);
19525 visiting(false);
19526 }
19527
19528 bool result = v.visit_end(this);
19530 return result;
19531}
19532
19533const location&
19534array_type_def::get_location() const
19535{return decl_base::get_location();}
19536
19537/// Get the array's subranges
19538const std::vector<array_type_def::subrange_sptr>&
19540{return priv_->subranges_;}
19541
19542array_type_def::~array_type_def()
19543{}
19544
19545// </array_type_def definitions>
19546
19547// <enum_type_decl definitions>
19548
19549class enum_type_decl::priv
19550{
19551 type_base_sptr underlying_type_;
19552 enumerators enumerators_;
19553 mutable enumerators sorted_enumerators_;
19554
19555 friend class enum_type_decl;
19556
19557 priv();
19558
19559public:
19560 priv(type_base_sptr underlying_type,
19562 : underlying_type_(underlying_type),
19563 enumerators_(enumerators)
19564 {}
19565}; // end class enum_type_decl::priv
19566
19567/// Constructor.
19568///
19569/// @param name the name of the type declaration.
19570///
19571/// @param locus the source location where the type was defined.
19572///
19573/// @param underlying_type the underlying type of the enum.
19574///
19575/// @param enums the enumerators of this enum type.
19576///
19577/// @param linkage_name the linkage name of the enum.
19578///
19579/// @param vis the visibility of the enum type.
19580enum_type_decl::enum_type_decl(const string& name,
19581 const location& locus,
19582 type_base_sptr underlying_type,
19583 enumerators& enums,
19584 const string& linkage_name,
19585 visibility vis)
19586 : type_or_decl_base(underlying_type->get_environment(),
19587 ENUM_TYPE
19588 | ABSTRACT_TYPE_BASE
19589 | ABSTRACT_DECL_BASE),
19590 type_base(underlying_type->get_environment(),
19591 underlying_type->get_size_in_bits(),
19592 underlying_type->get_alignment_in_bits()),
19593 decl_base(underlying_type->get_environment(),
19594 name, locus, linkage_name, vis),
19595 priv_(new priv(underlying_type, enums))
19596{
19598 for (enumerators::iterator e = get_enumerators().begin();
19599 e != get_enumerators().end();
19600 ++e)
19601 e->set_enum_type(this);
19602}
19603
19604/// Return the underlying type of the enum.
19605type_base_sptr
19607{return priv_->underlying_type_;}
19608
19609/// @return the list of enumerators of the enum.
19612{return priv_->enumerators_;}
19613
19614/// @return the list of enumerators of the enum.
19617{return priv_->enumerators_;}
19618
19619/// Get the lexicographically sorted vector of enumerators.
19620///
19621/// @return the lexicographically sorted vector of enumerators.
19624{
19625 if (priv_->sorted_enumerators_.empty())
19626 {
19627 for (auto e = get_enumerators().rbegin();
19628 e != get_enumerators().rend();
19629 ++e)
19630 priv_->sorted_enumerators_.push_back(*e);
19631
19632 std::sort(priv_->sorted_enumerators_.begin(),
19633 priv_->sorted_enumerators_.end(),
19634 [](const enum_type_decl::enumerator& l,
19636 {
19637 if (l.get_name() == r.get_name())
19638 return l.get_value() < r.get_value();
19639 return (l.get_name() < r.get_name());
19640 });
19641 }
19642
19643 return priv_->sorted_enumerators_;
19644}
19645
19646/// Get the pretty representation of the current instance of @ref
19647/// enum_type_decl.
19648///
19649/// @param internal set to true if the call is intended to get a
19650/// representation of the decl (or type) for the purpose of canonical
19651/// type comparison. This is mainly used in the function
19652/// type_base::get_canonical_type_for().
19653///
19654/// In other words if the argument for this parameter is true then the
19655/// call is meant for internal use (for technical use inside the
19656/// library itself), false otherwise. If you don't know what this is
19657/// for, then set it to false.
19658///
19659/// @param qualified_name if true, names emitted in the pretty
19660/// representation are fully qualified.
19661///
19662/// @return the pretty representation of the enum type.
19663string
19665 bool qualified_name) const
19666{
19667 string r = "enum ";
19668
19669 if (internal && get_is_anonymous())
19670 r += get_type_name(this, qualified_name, /*internal=*/true);
19671 else if (get_is_anonymous())
19672 r += get_enum_flat_representation(*this, "",
19673 /*one_line=*/true,
19674 qualified_name);
19675 else
19677 qualified_name);
19678 return r;
19679}
19680
19681/// This implements the ir_traversable_base::traverse pure virtual
19682/// function.
19683///
19684/// @param v the visitor used on the current instance.
19685///
19686/// @return true if the entire IR node tree got traversed, false
19687/// otherwise.
19688bool
19690{
19691 if (v.type_node_has_been_visited(this))
19692 return true;
19693
19694 if (visiting())
19695 return true;
19696
19697 if (v.visit_begin(this))
19698 {
19699 visiting(true);
19700 if (type_base_sptr t = get_underlying_type())
19701 t->traverse(v);
19702 visiting(false);
19703 }
19704
19705 bool result = v.visit_end(this);
19707 return result;
19708}
19709
19710/// Destructor for the enum type declaration.
19712{}
19713
19714/// Test if two enums differ, but not by a name change.
19715///
19716/// @param l the first enum to consider.
19717///
19718/// @param r the second enum to consider.
19719///
19720/// @return true iff @p l differs from @p r by anything but a name
19721/// change.
19722bool
19724 const enum_type_decl& r,
19725 change_kind* k)
19726{
19727 bool result = false;
19729 {
19730 result = true;
19731 if (k)
19732 *k |= SUBTYPE_CHANGE_KIND;
19733 else
19734 return true;
19735 }
19736
19737 enum_type_decl::enumerators::const_iterator i, j;
19738 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
19739 i != l.get_enumerators().end() && j != r.get_enumerators().end();
19740 ++i, ++j)
19741 if (*i != *j)
19742 {
19743 result = true;
19744 if (k)
19745 {
19747 break;
19748 }
19749 else
19750 return true;
19751 }
19752
19753 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
19754 {
19755 result = true;
19756 if (k)
19758 else
19759 return true;
19760 }
19761
19762 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
19765 string n_l = l.get_name();
19766 string n_r = r.get_name();
19767 local_r.set_qualified_name(qn_l);
19768 local_r.set_name(n_l);
19769
19770 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
19771 {
19772 result = true;
19773 if (k)
19774 {
19775 if (!l.decl_base::operator==(r))
19777 if (!l.type_base::operator==(r))
19779 }
19780 else
19781 {
19782 local_r.set_name(n_r);
19783 local_r.set_qualified_name(qn_r);
19784 return true;
19785 }
19786 }
19787 local_r.set_qualified_name(qn_r);
19788 local_r.set_name(n_r);
19789
19790 return result;
19791}
19792
19793/// Test if a given enumerator is found present in an enum.
19794///
19795/// This is a subroutine of the equals function for enums.
19796///
19797/// @param enr the enumerator to consider.
19798///
19799/// @param enom the enum to consider.
19800///
19801/// @return true iff the enumerator @p enr is present in the enum @p
19802/// enom.
19803bool
19805 const enum_type_decl &enom)
19806{
19807 for (const auto &e : enom.get_enumerators())
19808 if (e == enr)
19809 return true;
19810 return false;
19811}
19812
19813/// Check if two enumerators values are equal.
19814///
19815/// This function doesn't check if the names of the enumerators are
19816/// equal or not.
19817///
19818/// @param enr the first enumerator to consider.
19819///
19820/// @param enl the second enumerator to consider.
19821///
19822/// @return true iff @p enr has the same value as @p enl.
19823static bool
19824enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
19825 const enum_type_decl::enumerator &enl)
19826{return enr.get_value() == enl.get_value();}
19827
19828/// Detect if a given enumerator value is present in an enum.
19829///
19830/// This function looks inside the enumerators of a given enum and
19831/// detect if the enum contains at least one enumerator or a given
19832/// value. The function also detects if the enumerator value we are
19833/// looking at is present in the enum with a different name. An
19834/// enumerator with the same value but with a different name is named
19835/// a "redundant enumerator". The function returns the set of
19836/// enumerators that are redundant with the value we are looking at.
19837///
19838/// @param enr the enumerator to consider.
19839///
19840/// @param enom the enum to consider.
19841///
19842/// @param redundant_enrs if the function returns true, then this
19843/// vector is filled with enumerators that are redundant with the
19844/// value of @p enr.
19845///
19846/// @return true iff the function detects that @p enom contains
19847/// enumerators with the same value as @p enr.
19848static bool
19849is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
19850 const enum_type_decl &enom,
19851 vector<enum_type_decl::enumerator>& redundant_enrs)
19852{
19853 bool found = false;
19854 for (const auto &e : enom.get_enumerators())
19855 if (enumerators_values_are_equal(e, enr))
19856 {
19857 found = true;
19858 if (e != enr)
19859 redundant_enrs.push_back(e);
19860 }
19861
19862 return found;
19863}
19864
19865/// Check if an enumerator value is redundant in a given enum.
19866///
19867/// Given an enumerator value, this function detects if an enum
19868/// contains at least one enumerator with the the same value but with
19869/// a different name.
19870///
19871/// @param enr the enumerator to consider.
19872///
19873/// @param enom the enum to consider.
19874///
19875/// @return true iff @p enr is a redundant enumerator in enom.
19876static bool
19877is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
19878 const enum_type_decl &enom)
19879{
19880 vector<enum_type_decl::enumerator> redundant_enrs;
19881 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
19882 {
19883 if (!redundant_enrs.empty())
19884 return true;
19885 }
19886 return false;
19887}
19888
19889/// Compares two instances of @ref enum_type_decl.
19890///
19891/// If the two intances are different, set a bitfield to give some
19892/// insight about the kind of differences there are.
19893///
19894/// @param l the first artifact of the comparison.
19895///
19896/// @param r the second artifact of the comparison.
19897///
19898/// @param k a pointer to a bitfield that gives information about the
19899/// kind of changes there are between @p l and @p r. This one is set
19900/// iff @p k is non-null and the function returns false.
19901///
19902/// Please note that setting k to a non-null value does have a
19903/// negative performance impact because even if @p l and @p r are not
19904/// equal, the function keeps up the comparison in order to determine
19905/// the different kinds of ways in which they are different.
19906///
19907/// @return true if @p l equals @p r, false otherwise.
19908bool
19910{
19911 bool result = true;
19912
19913 //
19914 // Look through decl-only-enum.
19915 //
19916
19917 const enum_type_decl *def1 =
19920 : &l;
19921
19922 const enum_type_decl *def2 =
19925 : &r;
19926
19927 if (!!def1 != !!def2)
19928 {
19929 // One enum is decl-only while the other is not.
19930 // So the two enums are different.
19931 result = false;
19932 if (k)
19933 *k |= SUBTYPE_CHANGE_KIND;
19934 else
19936 }
19937
19938 //
19939 // At this point, both enums have the same state of decl-only-ness.
19940 // So we can compare oranges to oranges.
19941 //
19942
19943 if (!def1)
19944 def1 = &l;
19945 if (!def2)
19946 def2 = &r;
19947
19948 if (def1->get_underlying_type() != def2->get_underlying_type())
19949 {
19950 result = false;
19951 if (k)
19952 *k |= SUBTYPE_CHANGE_KIND;
19953 else
19955 }
19956
19957 if (!(def1->decl_base::operator==(*def2)
19958 && def1->type_base::operator==(*def2)))
19959 {
19960 result = false;
19961 if (k)
19962 {
19963 if (!def1->decl_base::operator==(*def2))
19965 if (!def1->type_base::operator==(*def2))
19967 }
19968 else
19970 }
19971
19972 // Now compare the enumerators. Note that the order of declaration
19973 // of enumerators should not matter in the comparison.
19974 //
19975 // Also if an enumerator value is redundant, that shouldn't impact
19976 // the comparison.
19977 //
19978 // In that case, note that the two enums below are considered equal:
19979 //
19980 // enum foo
19981 // {
19982 // e0 = 0;
19983 // e1 = 1;
19984 // e2 = 2;
19985 // };
19986 //
19987 // enum foo
19988 // {
19989 // e0 = 0;
19990 // e1 = 1;
19991 // e2 = 2;
19992 // e_added = 1; // <-- this value is redundant with the value
19993 // // of the enumerator e1.
19994 // };
19995 //
19996 // Note however that in the case below, the enums are different.
19997 //
19998 // enum foo
19999 // {
20000 // e0 = 0;
20001 // e1 = 1;
20002 // };
20003 //
20004 // enum foo
20005 // {
20006 // e0 = 0;
20007 // e2 = 1; // <-- this enum value is present in the first version
20008 // // of foo, but is not redundant with any enumerator
20009 // // in the second version of of enum foo.
20010 // };
20011 //
20012 // These two enums are considered equal.
20013
20014 for(const auto &e : def1->get_enumerators())
20015 if (!is_enumerator_present_in_enum(e, *def2)
20016 && (!is_enumerator_value_redundant(e, *def2)
20017 || !is_enumerator_value_redundant(e, *def1)))
20018 {
20019 result = false;
20020 if (k)
20021 {
20023 break;
20024 }
20025 else
20027 }
20028
20029 for(const auto &e : def2->get_enumerators())
20030 if (!is_enumerator_present_in_enum(e, *def1)
20031 && (!is_enumerator_value_redundant(e, *def1)
20032 || !is_enumerator_value_redundant(e, *def2)))
20033 {
20034 result = false;
20035 if (k)
20036 {
20038 break;
20039 }
20040 else
20042 }
20043
20044 ABG_RETURN(result);
20045}
20046
20047/// Equality operator.
20048///
20049/// @param o the other enum to test against.
20050///
20051/// @return true iff @p o equals the current instance of enum type
20052/// decl.
20053bool
20055{
20056 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
20057 if (!op)
20058 return false;
20059 return try_canonical_compare(this, op);
20060}
20061
20062/// Equality operator.
20063///
20064/// @param o the other enum to test against.
20065///
20066/// @return true iff @p o is equals the current instance of enum type
20067/// decl.
20068bool
20070{
20071 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20072 if (!other)
20073 return false;
20074 return *this == *other;
20075}
20076
20077/// Equality operator for @ref enum_type_decl_sptr.
20078///
20079/// @param l the first operand to compare.
20080///
20081/// @param r the second operand to compare.
20082///
20083/// @return true iff @p l equals @p r.
20084bool
20086{
20087 if (!!l != !!r)
20088 return false;
20089 if (l.get() == r.get())
20090 return true;
20091 decl_base_sptr o = r;
20092 return *l == *o;
20093}
20094
20095/// Inequality operator for @ref enum_type_decl_sptr.
20096///
20097/// @param l the first operand to compare.
20098///
20099/// @param r the second operand to compare.
20100///
20101/// @return true iff @p l equals @p r.
20102bool
20104{return !operator==(l, r);}
20105
20106/// The type of the private data of an @ref
20107/// enum_type_decl::enumerator.
20108class enum_type_decl::enumerator::priv
20109{
20110 string name_;
20111 int64_t value_;
20112 string qualified_name_;
20113 enum_type_decl* enum_type_;
20114
20115 friend class enum_type_decl::enumerator;
20116
20117public:
20118
20119 priv()
20120 : enum_type_()
20121 {}
20122
20123 priv(const string& name,
20124 int64_t value,
20125 enum_type_decl* e = 0)
20126 : name_(name),
20127 value_(value),
20128 enum_type_(e)
20129 {}
20130}; // end class enum_type_def::enumerator::priv
20131
20132/// Default constructor of the @ref enum_type_decl::enumerator type.
20134 : priv_(new priv)
20135{}
20136
20137enum_type_decl::enumerator::~enumerator() = default;
20138
20139/// Constructor of the @ref enum_type_decl::enumerator type.
20140///
20141/// @param env the environment we are operating from.
20142///
20143/// @param name the name of the enumerator.
20144///
20145/// @param value the value of the enumerator.
20147 int64_t value)
20148 : priv_(new priv(name, value))
20149{}
20150
20151/// Copy constructor of the @ref enum_type_decl::enumerator type.
20152///
20153/// @param other enumerator to copy.
20155 : priv_(new priv(other.get_name(),
20156 other.get_value(),
20157 other.get_enum_type()))
20158{}
20159
20160/// Assignment operator of the @ref enum_type_decl::enumerator type.
20161///
20162/// @param o
20165{
20166 priv_->name_ = o.get_name();
20167 priv_->value_ = o.get_value();
20168 priv_->enum_type_ = o.get_enum_type();
20169 return *this;
20170}
20171
20172/// Equality operator
20173///
20174/// @param other the enumerator to compare to the current
20175/// instance of enum_type_decl::enumerator.
20176///
20177/// @return true if @p other equals the current instance of
20178/// enum_type_decl::enumerator.
20179bool
20181{
20182 bool names_equal = true;
20183 names_equal = (get_name() == other.get_name());
20184 return names_equal && (get_value() == other.get_value());
20185}
20186
20187/// Inequality operator.
20188///
20189/// @param other the other instance to compare against.
20190///
20191/// @return true iff @p other is different from the current instance.
20192bool
20194{return !operator==(other);}
20195
20196/// Getter for the name of the current instance of
20197/// enum_type_decl::enumerator.
20198///
20199/// @return a reference to the name of the current instance of
20200/// enum_type_decl::enumerator.
20201const string&
20203{return priv_->name_;}
20204
20205/// Getter for the qualified name of the current instance of
20206/// enum_type_decl::enumerator. The first invocation of the method
20207/// builds the qualified name, caches it and return a reference to the
20208/// cached qualified name. Subsequent invocations just return the
20209/// cached value.
20210///
20211/// @param internal set to true if the call is intended for an
20212/// internal use (for technical use inside the library itself), false
20213/// otherwise. If you don't know what this is for, then set it to
20214/// false.
20215///
20216/// @return the qualified name of the current instance of
20217/// enum_type_decl::enumerator.
20218const string&
20220{
20221 if (priv_->qualified_name_.empty())
20222 {
20223 priv_->qualified_name_ =
20224 get_enum_type()->get_qualified_name(internal)
20225 + "::"
20226 + get_name();
20227 }
20228 return priv_->qualified_name_;
20229}
20230
20231/// Setter for the name of @ref enum_type_decl::enumerator.
20232///
20233/// @param n the new name.
20234void
20236{priv_->name_ = n;}
20237
20238/// Getter for the value of @ref enum_type_decl::enumerator.
20239///
20240/// @return the value of the current instance of
20241/// enum_type_decl::enumerator.
20242int64_t
20244{return priv_->value_;}
20245
20246/// Setter for the value of @ref enum_type_decl::enumerator.
20247///
20248/// @param v the new value of the enum_type_decl::enumerator.
20249void
20251{priv_->value_= v;}
20252
20253/// Getter for the enum type that this enumerator is for.
20254///
20255/// @return the enum type that this enumerator is for.
20258{return priv_->enum_type_;}
20259
20260/// Setter for the enum type that this enumerator is for.
20261///
20262/// @param e the new enum type.
20263void
20265{priv_->enum_type_ = e;}
20266// </enum_type_decl definitions>
20267
20268// <typedef_decl definitions>
20269
20270/// Private data structure of the @ref typedef_decl.
20271struct typedef_decl::priv
20272{
20273 type_base_wptr underlying_type_;
20274
20275 priv(const type_base_sptr& t)
20276 : underlying_type_(t)
20277 {}
20278}; // end struct typedef_decl::priv
20279
20280/// Constructor of the typedef_decl type.
20281///
20282/// @param name the name of the typedef.
20283///
20284/// @param underlying_type the underlying type of the typedef.
20285///
20286/// @param locus the source location of the typedef declaration.
20287///
20288/// @param linkage_name the mangled name of the typedef.
20289///
20290/// @param vis the visibility of the typedef type.
20291typedef_decl::typedef_decl(const string& name,
20292 const type_base_sptr underlying_type,
20293 const location& locus,
20294 const string& linkage_name,
20295 visibility vis)
20296 : type_or_decl_base(underlying_type->get_environment(),
20297 TYPEDEF_TYPE
20298 | ABSTRACT_TYPE_BASE
20299 | ABSTRACT_DECL_BASE),
20300 type_base(underlying_type->get_environment(),
20301 underlying_type->get_size_in_bits(),
20302 underlying_type->get_alignment_in_bits()),
20303 decl_base(underlying_type->get_environment(),
20304 name, locus, linkage_name, vis),
20305 priv_(new priv(underlying_type))
20306{
20308}
20309
20310/// Constructor of the typedef_decl type.
20311///
20312/// @param name the name of the typedef.
20313///
20314/// @param env the environment of the current typedef.
20315///
20316/// @param locus the source location of the typedef declaration.
20317///
20318/// @param mangled_name the mangled name of the typedef.
20319///
20320/// @param vis the visibility of the typedef type.
20321typedef_decl::typedef_decl(const string& name,
20322 const environment& env,
20323 const location& locus,
20324 const string& mangled_name,
20325 visibility vis)
20326 : type_or_decl_base(env,
20327 TYPEDEF_TYPE
20328 | ABSTRACT_TYPE_BASE
20329 | ABSTRACT_DECL_BASE),
20330 type_base(env, /*size_in_bits=*/0,
20331 /*alignment_in_bits=*/0),
20332 decl_base(env, name, locus, mangled_name, vis),
20333 priv_(new priv(nullptr))
20334{
20336}
20337
20338/// Return the size of the typedef.
20339///
20340/// This function looks at the size of the underlying type and ensures
20341/// that it's the same as the size of the typedef.
20342///
20343/// @return the size of the typedef.
20344size_t
20346{
20347 if (!get_underlying_type())
20348 return 0;
20349 size_t s = get_underlying_type()->get_size_in_bits();
20350 if (s != type_base::get_size_in_bits())
20351 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
20353}
20354
20355/// Return the alignment of the typedef.
20356///
20357/// This function looks at the alignment of the underlying type and
20358/// ensures that it's the same as the alignment of the typedef.
20359///
20360/// @return the size of the typedef.
20361size_t
20363{
20364 if (!get_underlying_type())
20365 return 0;
20366 size_t s = get_underlying_type()->get_alignment_in_bits();
20368 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
20370}
20371
20372/// Compares two instances of @ref typedef_decl.
20373///
20374/// If the two intances are different, set a bitfield to give some
20375/// insight about the kind of differences there are.
20376///
20377/// @param l the first artifact of the comparison.
20378///
20379/// @param r the second artifact of the comparison.
20380///
20381/// @param k a pointer to a bitfield that gives information about the
20382/// kind of changes there are between @p l and @p r. This one is set
20383/// iff @p k is non-null and the function returns false.
20384///
20385/// Please note that setting k to a non-null value does have a
20386/// negative performance impact because even if @p l and @p r are not
20387/// equal, the function keeps up the comparison in order to determine
20388/// the different kinds of ways in which they are different.
20389///
20390/// @return true if @p l equals @p r, false otherwise.
20391bool
20393{
20394 bool result = true;
20395
20396 // No need to go further if the types have different names or
20397 // different size / alignment.
20398 if (!(l.decl_base::operator==(r)))
20399 {
20400 result = false;
20401 if (k)
20403 else
20405 }
20406
20408 {
20409 // Changes to the underlying type of a typedef are considered
20410 // local, a bit like for pointers.
20411 result = false;
20412 if (k)
20414 else
20416 }
20417
20418 ABG_RETURN(result);
20419}
20420
20421/// Equality operator
20422///
20423/// @param o the other typedef_decl to test against.
20424bool
20426{
20427 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
20428 if (!other)
20429 return false;
20430 return try_canonical_compare(this, other);
20431}
20432
20433/// Equality operator
20434///
20435/// @param o the other typedef_decl to test against.
20436///
20437/// @return true if the current instance of @ref typedef_decl equals
20438/// @p o.
20439bool
20441{
20442 const decl_base* other = dynamic_cast<const decl_base*>(&o);
20443 if (!other)
20444 return false;
20445 return *this == *other;
20446}
20447
20448/// Build a pretty representation for a typedef_decl.
20449///
20450/// @param internal set to true if the call is intended to get a
20451/// representation of the decl (or type) for the purpose of canonical
20452/// type comparison. This is mainly used in the function
20453/// type_base::get_canonical_type_for().
20454///
20455/// In other words if the argument for this parameter is true then the
20456/// call is meant for internal use (for technical use inside the
20457/// library itself), false otherwise. If you don't know what this is
20458/// for, then set it to false.
20459
20460/// @param qualified_name if true, names emitted in the pretty
20461/// representation are fully qualified.
20462///
20463/// @return a copy of the pretty representation of the current
20464/// instance of typedef_decl.
20465string
20467 bool qualified_name) const
20468{
20469
20470 string result = "typedef ";
20471 if (internal)
20472 result += get_name();
20473 else
20474 {
20475 if (qualified_name)
20476 result += get_qualified_name(internal);
20477 else
20478 result += get_name();
20479 }
20480
20481 return result;
20482}
20483
20484/// Getter of the underlying type of the typedef.
20485///
20486/// @return the underlying_type.
20487type_base_sptr
20489{return priv_->underlying_type_.lock();}
20490
20491/// Setter ofthe underlying type of the typedef.
20492///
20493/// @param t the new underlying type of the typedef.
20494void
20496{
20497 priv_->underlying_type_ = t;
20498 set_size_in_bits(t->get_size_in_bits());
20499 set_alignment_in_bits(t->get_alignment_in_bits());
20500}
20501
20502/// Implementation of the virtual "get_qualified_name" method.
20503///
20504/// @param qualified_name the resuling qualified name of the typedef type.
20505///
20506/// @param internal if true, then it means the qualified name is for
20507/// "internal" purposes, meaning mainly for type canonicalization
20508/// purposes.
20509void
20511 bool internal) const
20512{qualified_name = get_qualified_name(internal);}
20513
20514/// Implementation of the virtual "get_qualified_name" method.
20515///
20516/// @param internal if true, then it means the qualified name is for
20517/// "internal" purposes, meaning mainly for type canonicalization
20518/// purposes.
20519///
20520/// @return the qualified name.
20521const interned_string&
20523{
20524 // Note that the qualified name has been already set by
20525 // qualified_name_setter::do_update, which is invoked by
20526 // update_qualified_name. The latter is itself invoked whenever the
20527 // typedef is added to its scope, in scope_decl::add_member_decl.
20528 if (internal)
20529 return decl_base::priv_->internal_qualified_name_;
20530 else
20531 return decl_base::priv_->qualified_name_;
20532}
20533
20534/// This implements the ir_traversable_base::traverse pure virtual
20535/// function.
20536///
20537/// @param v the visitor used on the current instance.
20538///
20539/// @return true if the entire IR node tree got traversed, false
20540/// otherwise.
20541bool
20543{
20544 if (v.type_node_has_been_visited(this))
20545 return true;
20546
20547 if (visiting())
20548 return true;
20549
20550 if (v.visit_begin(this))
20551 {
20552 visiting(true);
20553 if (type_base_sptr t = get_underlying_type())
20554 t->traverse(v);
20555 visiting(false);
20556 }
20557
20558 bool result = v.visit_end(this);
20560 return result;
20561}
20562
20563typedef_decl::~typedef_decl()
20564{}
20565// </typedef_decl definitions>
20566
20567// <var_decl definitions>
20568
20569struct var_decl::priv
20570{
20571 type_base_wptr type_;
20572 type_base* naked_type_;
20573 decl_base::binding binding_;
20574 elf_symbol_sptr symbol_;
20575 interned_string id_;
20576
20577 priv()
20578 : naked_type_(),
20579 binding_(decl_base::BINDING_GLOBAL)
20580 {}
20581
20582 priv(type_base_sptr t,
20584 : type_(t),
20585 naked_type_(t.get()),
20586 binding_(b)
20587 {}
20588
20589 /// Setter of the type of the variable.
20590 ///
20591 /// @param t the new variable type.
20592 void
20593 set_type(type_base_sptr t)
20594 {
20595 type_ = t;
20596 naked_type_ = t.get();
20597 }
20598}; // end struct var_decl::priv
20599
20600/// Constructor of the @ref var_decl type.
20601///
20602/// @param name the name of the variable declaration
20603///
20604/// @param type the type of the variable declaration
20605///
20606/// @param locus the source location where the variable was defined.
20607///
20608/// @param linkage_name the linkage name of the variable.
20609///
20610/// @param vis the visibility of of the variable.
20611///
20612/// @param bind the binding kind of the variable.
20613var_decl::var_decl(const string& name,
20614 type_base_sptr type,
20615 const location& locus,
20616 const string& linkage_name,
20617 visibility vis,
20618 binding bind)
20619 : type_or_decl_base(type->get_environment(),
20620 VAR_DECL | ABSTRACT_DECL_BASE),
20621 decl_base(type->get_environment(), name, locus, linkage_name, vis),
20622 priv_(new priv(type, bind))
20623{
20625}
20626
20627/// Getter of the type of the variable.
20628///
20629/// @return the type of the variable.
20630const type_base_sptr
20632{return priv_->type_.lock();}
20633
20634/// Setter of the type of the variable.
20635///
20636/// @param the new type of the variable.
20637void
20638var_decl::set_type(type_base_sptr& t)
20639{priv_->set_type(t);}
20640
20641/// Getter of the type of the variable.
20642///
20643/// This getter returns a bare pointer, as opposed to a smart pointer.
20644/// It's to be used on performance sensitive code paths identified by
20645/// careful profiling.
20646///
20647/// @return the type of the variable, as a bare pointer.
20648const type_base*
20650{return priv_->naked_type_;}
20651
20652/// Getter of the binding of the variable.
20653///
20654/// @return the biding of the variable.
20657{return priv_->binding_;}
20658
20659/// Setter of the binding of the variable.
20660///
20661/// @param b the new binding value.
20662void
20664{priv_->binding_ = b;}
20665
20666/// Sets the underlying ELF symbol for the current variable.
20667///
20668/// And underlyin$g ELF symbol for the current variable might exist
20669/// only if the corpus that this variable originates from was
20670/// constructed from an ELF binary file.
20671///
20672/// Note that comparing two variables that have underlying ELF symbols
20673/// involves comparing their underlying elf symbols. The decl name
20674/// for the variable thus becomes irrelevant in the comparison.
20675///
20676/// @param sym the new ELF symbol for this variable decl.
20677void
20679{
20680 priv_->symbol_ = sym;
20681 // The variable id cache that depends on the symbol must be
20682 // invalidated because the symbol changed.
20683 priv_->id_ = get_environment().intern("");
20684}
20685
20686/// Gets the the underlying ELF symbol for the current variable,
20687/// that was set using var_decl::set_symbol(). Please read the
20688/// documentation for that member function for more information about
20689/// "underlying ELF symbols".
20690///
20691/// @return sym the underlying ELF symbol for this variable decl, if
20692/// one exists.
20693const elf_symbol_sptr&
20695{return priv_->symbol_;}
20696
20697/// Create a new var_decl that is a clone of the current one.
20698///
20699/// @return the cloned var_decl.
20702{
20704 get_type(),
20705 get_location(),
20708 get_binding()));
20709
20710 v->set_symbol(get_symbol());
20711
20712 if (is_member_decl(*this))
20713 {
20717 get_member_is_static(*this),
20718 get_data_member_offset(*this));
20719 }
20720 else
20722
20723 return v;
20724}
20725/// Setter of the scope of the current var_decl.
20726///
20727/// Note that the decl won't hold a reference on the scope. It's
20728/// rather the scope that holds a reference on its members.
20729///
20730/// @param scope the new scope.
20731void
20732var_decl::set_scope(scope_decl* scope)
20733{
20734 if (!get_context_rel())
20735 set_context_rel(new dm_context_rel(scope));
20736 else
20737 get_context_rel()->set_scope(scope);
20738}
20739
20740/// Compares two instances of @ref var_decl without taking their type
20741/// into account.
20742///
20743/// If the two intances are different modulo their type, set a
20744/// bitfield to give some insight about the kind of differences there
20745/// are.
20746///
20747/// @param l the first artifact of the comparison.
20748///
20749/// @param r the second artifact of the comparison.
20750///
20751/// @param k a pointer to a bitfield that gives information about the
20752/// kind of changes there are between @p l and @p r. This one is set
20753/// iff @p k is non-null and the function returns false.
20754///
20755/// Please note that setting k to a non-null value does have a
20756/// negative performance impact because even if @p l and @p r are not
20757/// equal, the function keeps up the comparison in order to determine
20758/// the different kinds of ways in which they are different.
20759///
20760/// @return true if @p l equals @p r, false otherwise.
20761bool
20763{
20764 bool result = true;
20765
20766 // If there are underlying elf symbols for these variables,
20767 // compare them. And then compare the other parts.
20768 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
20769 if (!!s0 != !!s1)
20770 {
20771 result = false;
20772 if (k)
20774 else
20776 }
20777 else if (s0 && s0 != s1)
20778 {
20779 result = false;
20780 if (k)
20782 else
20784 }
20785 bool symbols_are_equal = (s0 && s1 && result);
20786
20787 if (symbols_are_equal)
20788 {
20789 // The variables have underlying elf symbols that are equal, so
20790 // now, let's compare the decl_base part of the variables w/o
20791 // considering their decl names.
20792 const environment& env = l.get_environment();
20793 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
20794 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
20795 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
20796 bool decl_bases_different = !l.decl_base::operator==(r);
20797 const_cast<var_decl&>(l).set_qualified_name(n1);
20798 const_cast<var_decl&>(r).set_qualified_name(n2);
20799
20800 if (decl_bases_different)
20801 {
20802 result = false;
20803 if (k)
20805 else
20807 }
20808 }
20809 else
20810 if (!l.decl_base::operator==(r))
20811 {
20812 result = false;
20813 if (k)
20815 else
20817 }
20818
20819 const dm_context_rel* c0 =
20820 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
20821 const dm_context_rel* c1 =
20822 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
20823 ABG_ASSERT(c0 && c1);
20824
20825 if (*c0 != *c1)
20826 {
20827 result = false;
20828 if (k)
20830 else
20832 }
20833
20834 ABG_RETURN(result);
20835}
20836
20837/// Compares two instances of @ref var_decl.
20838///
20839/// If the two intances are different, set a bitfield to give some
20840/// insight about the kind of differences there are.
20841///
20842/// @param l the first artifact of the comparison.
20843///
20844/// @param r the second artifact of the comparison.
20845///
20846/// @param k a pointer to a bitfield that gives information about the
20847/// kind of changes there are between @p l and @p r. This one is set
20848/// iff @p k is non-null and the function returns false.
20849///
20850/// Please note that setting k to a non-null value does have a
20851/// negative performance impact because even if @p l and @p r are not
20852/// equal, the function keeps up the comparison in order to determine
20853/// the different kinds of ways in which they are different.
20854///
20855/// @return true if @p l equals @p r, false otherwise.
20856bool
20857equals(const var_decl& l, const var_decl& r, change_kind* k)
20858{
20859 bool result = true;
20860
20861 // First test types of variables. This should be fast because in
20862 // the general case, most types should be canonicalized.
20863 if (*l.get_naked_type() != *r.get_naked_type())
20864 {
20865 result = false;
20866 if (k)
20867 {
20869 r.get_naked_type()))
20870 *k |= (LOCAL_TYPE_CHANGE_KIND);
20871 else
20872 *k |= SUBTYPE_CHANGE_KIND;
20873 }
20874 else
20876 }
20877
20878 result &= var_equals_modulo_types(l, r, k);
20879
20880 ABG_RETURN(result);
20881}
20882
20883/// Comparison operator of @ref var_decl.
20884///
20885/// @param o the instance of @ref var_decl to compare against.
20886///
20887/// @return true iff the current instance of @ref var_decl equals @p o.
20888bool
20890{
20891 const var_decl* other = dynamic_cast<const var_decl*>(&o);
20892 if (!other)
20893 return false;
20894
20895 return equals(*this, *other, 0);
20896}
20897
20898/// Return an ID that tries to uniquely identify the variable inside a
20899/// program or a library.
20900///
20901/// So if the variable has an underlying elf symbol, the ID is the
20902/// concatenation of the symbol name and its version. Otherwise, the
20903/// ID is the linkage name if its non-null. Otherwise, it's the
20904/// pretty representation of the variable.
20905///
20906/// @return the ID.
20909{
20910 if (priv_->id_.empty())
20911 {
20912 string repr = get_name();
20913 string sym_str;
20914 if (elf_symbol_sptr s = get_symbol())
20915 sym_str = s->get_id_string();
20916 else if (!get_linkage_name().empty())
20917 sym_str = get_linkage_name();
20918
20919 const environment& env = get_type()->get_environment();
20920 priv_->id_ = env.intern(repr);
20921 if (!sym_str.empty())
20922 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
20923 }
20924 return priv_->id_;
20925}
20926
20927/// Return the hash value for the current instance.
20928///
20929/// @return the hash value.
20930size_t
20932{
20933 var_decl::hash hash_var;
20934 return hash_var(this);
20935}
20936
20937/// Get the qualified name of a given variable or data member.
20938///
20939///
20940/// Note that if the current instance of @ref var_decl is an anonymous
20941/// data member, then the qualified name is actually the flat
20942/// representation (the definition) of the type of the anonymous data
20943/// member. We chose the flat representation because otherwise, the
20944/// name of an *anonymous* data member is empty, by construction, e.g:
20945///
20946/// struct foo {
20947/// int a;
20948/// union {
20949/// char b;
20950/// char c;
20951/// }; // <---- this data member is anonymous.
20952/// int d;
20953/// }
20954///
20955/// The string returned for the anonymous member here is going to be:
20956///
20957/// "union {char b; char c}"
20958///
20959/// @param internal if true then this is for a purpose to the library,
20960/// otherwise, it's for being displayed to users.
20961///
20962/// @return the resulting qualified name.
20963const interned_string&
20965{
20966 if (is_anonymous_data_member(this)
20967 && decl_base::get_qualified_name().empty())
20968 {
20969 // Display the anonymous data member in a way that makes sense.
20970 string r = get_pretty_representation(internal);
20972 }
20973
20974 return decl_base::get_qualified_name(internal);
20975}
20976
20977/// Build and return the pretty representation of this variable.
20978///
20979/// @param internal set to true if the call is intended to get a
20980/// representation of the decl (or type) for the purpose of canonical
20981/// type comparison. This is mainly used in the function
20982/// type_base::get_canonical_type_for().
20983///
20984/// In other words if the argument for this parameter is true then the
20985/// call is meant for internal use (for technical use inside the
20986/// library itself), false otherwise. If you don't know what this is
20987/// for, then set it to false.
20988///
20989/// @param qualified_name if true, names emitted in the pretty
20990/// representation are fully qualified.
20991///
20992/// @return a copy of the pretty representation of this variable.
20993string
20994var_decl::get_pretty_representation(bool internal, bool qualified_name) const
20995{
20996 string result;
20997
20998 if (is_member_decl(this) && get_member_is_static(this))
20999 result = "static ";
21000
21001 // Detect if the current instance of var_decl is a member of
21002 // an anonymous class or union.
21003 bool member_of_anonymous_class = false;
21004 if (class_or_union* scope = is_at_class_scope(this))
21005 if (scope->get_is_anonymous())
21006 member_of_anonymous_class = true;
21007
21008 type_base_sptr type = get_type();
21009 if (is_array_type(type, /*look_through_qualifiers=*/true)
21010 || is_pointer_type(type, /*look_through_qualifiers=*/true)
21011 || is_reference_type(type, /*look_through_qualifiers=*/true)
21012 || is_ptr_to_mbr_type(type, /*look_through_qualifiers=*/true))
21013 {
21014 string name;
21015 if (member_of_anonymous_class || !qualified_name)
21016 name = get_name();
21017 else
21018 name = get_qualified_name(internal);
21019
21020 if (qualified_type_def_sptr q = is_qualified_type(type))
21021 {
21022 string quals_repr =
21023 get_string_representation_of_cv_quals(q->get_cv_quals());
21024 if (!quals_repr.empty())
21025 name = quals_repr + " " + name;
21026 type = peel_qualified_type(type);
21027 }
21028
21029 name = string(" ") + name;
21030 if (array_type_def_sptr t = is_array_type(type))
21031 result += array_declaration_name(t, name, qualified_name, internal);
21032 else if (pointer_type_def_sptr t = is_pointer_type(type))
21033 result += pointer_declaration_name(t, name, qualified_name, internal);
21034 else if (reference_type_def_sptr t = is_reference_type(type))
21035 result += pointer_declaration_name(t, name, qualified_name, internal);
21036 else if (ptr_to_mbr_type_sptr t = is_ptr_to_mbr_type(type))
21037 result += ptr_to_mbr_declaration_name(t, name,
21038 qualified_name,
21039 internal);
21040 }
21041 else
21042 {
21043 if (/*The current var_decl is to be used as an anonymous data
21044 member. */
21045 get_name().empty())
21046 {
21047 // Display the anonymous data member in a way that
21048 // makes sense.
21049 result +=
21052 "", /*one_line=*/true, internal);
21053 }
21054 else if (data_member_has_anonymous_type(this))
21055 {
21058 "", /*one_line=*/true, internal);
21059 result += " ";
21060 if (!internal
21061 && (member_of_anonymous_class || !qualified_name))
21062 // It doesn't make sense to name the member of an
21063 // anonymous class or union like:
21064 // "__anonymous__::data_member_name". So let's just use
21065 // its non-qualified name.
21066 result += get_name();
21067 else
21068 result += get_qualified_name(internal);
21069 }
21070 else
21071 {
21072 result +=
21074 + " ";
21075
21076 if (!internal
21077 && (member_of_anonymous_class || !qualified_name))
21078 // It doesn't make sense to name the member of an
21079 // anonymous class or union like:
21080 // "__anonymous__::data_member_name". So let's just use
21081 // its non-qualified name.
21082 result += get_name();
21083 else
21084 result += get_qualified_name(internal);
21085 }
21086 }
21087 return result;
21088}
21089
21090/// Get a name that is valid even for an anonymous data member.
21091///
21092/// If the current @ref var_decl is an anonymous data member, then
21093/// return its pretty representation. As of now, that pretty
21094/// representation is actually its flat representation as returned by
21095/// get_class_or_union_flat_representation().
21096///
21097/// Otherwise, just return the name of the current @ref var_decl.
21098///
21099/// @param qualified if true, return the qualified name. This doesn't
21100/// have an effet if the current @ref var_decl represents an anonymous
21101/// data member.
21102string
21104{
21105 string name;
21106 if (is_anonymous_data_member(this))
21107 // This function is used in the comparison engine to determine
21108 // which anonymous data member was deleted. So it's not involved
21109 // in type comparison or canonicalization. We don't want to use
21110 // the 'internal' version of the pretty presentation.
21111 name = get_pretty_representation(/*internal=*/false, qualified);
21112 else
21113 name = get_name();
21114
21115 return name;
21116}
21117
21118/// This implements the ir_traversable_base::traverse pure virtual
21119/// function.
21120///
21121/// @param v the visitor used on the current instance.
21122///
21123/// @return true if the entire IR node tree got traversed, false
21124/// otherwise.
21125bool
21127{
21128 if (visiting())
21129 return true;
21130
21131 if (v.visit_begin(this))
21132 {
21133 visiting(true);
21134 if (type_base_sptr t = get_type())
21135 t->traverse(v);
21136 visiting(false);
21137 }
21138 return v.visit_end(this);
21139}
21140
21141var_decl::~var_decl()
21142{}
21143
21144// </var_decl definitions>
21145
21146/// This function is automatically invoked whenever an instance of
21147/// this type is canonicalized.
21148///
21149/// It's an overload of the virtual type_base::on_canonical_type_set.
21150///
21151/// We put here what is thus meant to be executed only at the point of
21152/// type canonicalization.
21153void
21155{
21156 priv_->cached_name_.clear();
21157 priv_->internal_cached_name_.clear();
21158}
21159
21160/// The most straightforward constructor for the function_type class.
21161///
21162/// @param return_type the return type of the function type.
21163///
21164/// @param parms the list of parameters of the function type.
21165/// Stricto sensu, we just need a list of types; we are using a list
21166/// of parameters (where each parameter also carries the name of the
21167/// parameter and its source location) to try and provide better
21168/// diagnostics whenever it makes sense. If it appears that this
21169/// wasts too many resources, we can fall back to taking just a
21170/// vector of types here.
21171///
21172/// @param size_in_bits the size of this type, in bits.
21173///
21174/// @param alignment_in_bits the alignment of this type, in bits.
21175///
21176/// @param size_in_bits the size of this type.
21177function_type::function_type(type_base_sptr return_type,
21178 const parameters& parms,
21179 size_t size_in_bits,
21180 size_t alignment_in_bits)
21181 : type_or_decl_base(return_type->get_environment(),
21182 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21183 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21184 priv_(new priv(parms, return_type))
21185{
21187
21188 for (parameters::size_type i = 0, j = 1;
21189 i < priv_->parms_.size();
21190 ++i, ++j)
21191 {
21192 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21193 // If the first parameter is artificial, then it certainly
21194 // means that this is a member function, and the first
21195 // parameter is the implicit this pointer. In that case, set
21196 // the index of that implicit parameter to zero. Otherwise,
21197 // the index of the first parameter starts at one.
21198 j = 0;
21199 priv_->parms_[i]->set_index(j);
21200 }
21201}
21202
21203/// A constructor for a function_type that takes no parameters.
21204///
21205/// @param return_type the return type of this function_type.
21206///
21207/// @param size_in_bits the size of this type, in bits.
21208///
21209/// @param alignment_in_bits the alignment of this type, in bits.
21210function_type::function_type(type_base_sptr return_type,
21211 size_t size_in_bits, size_t alignment_in_bits)
21212 : type_or_decl_base(return_type->get_environment(),
21213 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21214 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
21215 priv_(new priv(return_type))
21216{
21218}
21219
21220/// A constructor for a function_type that takes no parameter and
21221/// that has no return_type yet. These missing parts can (and must)
21222/// be added later.
21223///
21224/// @param env the environment we are operating from.
21225///
21226/// @param size_in_bits the size of this type, in bits.
21227///
21228/// @param alignment_in_bits the alignment of this type, in bits.
21229function_type::function_type(const environment& env,
21230 size_t size_in_bits,
21231 size_t alignment_in_bits)
21232 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21233 type_base(env, size_in_bits, alignment_in_bits),
21234 priv_(new priv)
21235{
21237}
21238
21239/// Getter for the return type of the current instance of @ref
21240/// function_type.
21241///
21242/// @return the return type.
21243type_base_sptr
21245{return priv_->return_type_.lock();}
21246
21247/// Setter of the return type of the current instance of @ref
21248/// function_type.
21249///
21250/// @param t the new return type to set.
21251void
21253{priv_->return_type_ = t;}
21254
21255/// Getter for the set of parameters of the current intance of @ref
21256/// function_type.
21257///
21258/// @return the parameters of the current instance of @ref
21259/// function_type.
21262{return priv_->parms_;}
21263
21264/// Get the Ith parameter of the vector of parameters of the current
21265/// instance of @ref function_type.
21266///
21267/// Note that the first parameter is at index 0. That parameter is
21268/// the first parameter that comes after the possible implicit "this"
21269/// parameter, when the current instance @ref function_type is for a
21270/// member function. Otherwise, if the current instance of @ref
21271/// function_type is for a non-member function, the parameter at index
21272/// 0 is the first parameter of the function.
21273///
21274///
21275/// @param i the index of the parameter to return. If i is greater
21276/// than the index of the last parameter, then this function returns
21277/// an empty parameter (smart) pointer.
21278///
21279/// @return the @p i th parameter that is not implicit.
21282{
21283 parameter_sptr result;
21284 if (dynamic_cast<const method_type*>(this))
21285 {
21286 if (i + 1 < get_parameters().size())
21287 result = get_parameters()[i + 1];
21288 }
21289 else
21290 {
21291 if (i < get_parameters().size())
21292 result = get_parameters()[i];
21293 }
21294 return result;
21295}
21296
21297/// Setter for the parameters of the current instance of @ref
21298/// function_type.
21299///
21300/// @param p the new vector of parameters to set.
21301void
21303{
21304 priv_->parms_ = p;
21305 for (parameters::size_type i = 0, j = 1;
21306 i < priv_->parms_.size();
21307 ++i, ++j)
21308 {
21309 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21310 // If the first parameter is artificial, then it certainly
21311 // means that this is a member function, and the first
21312 // parameter is the implicit this pointer. In that case, set
21313 // the index of that implicit parameter to zero. Otherwise,
21314 // the index of the first parameter starts at one.
21315 j = 0;
21316 priv_->parms_[i]->set_index(j);
21317 }
21318}
21319
21320/// Append a new parameter to the vector of parameters of the current
21321/// instance of @ref function_type.
21322///
21323/// @param parm the parameter to append.
21324void
21326{
21327 parm->set_index(priv_->parms_.size());
21328 priv_->parms_.push_back(parm);
21329}
21330
21331/// Test if the current instance of @ref function_type is for a
21332/// variadic function.
21333///
21334/// A variadic function is a function that takes a variable number of
21335/// arguments.
21336///
21337/// @return true iff the current instance of @ref function_type is for
21338/// a variadic function.
21339bool
21341{
21342 return (!priv_->parms_.empty()
21343 && priv_->parms_.back()->get_variadic_marker());
21344}
21345
21346/// Compare two function types.
21347///
21348/// In case these function types are actually method types, this
21349/// function avoids comparing two parameters (of the function types)
21350/// if the types of the parameters are actually the types of the
21351/// classes of the method types. This prevents infinite recursion
21352/// during the comparison of two classes that are structurally
21353/// identical.
21354///
21355/// This is a subroutine of the equality operator of function_type.
21356///
21357/// @param lhs the first function type to consider
21358///
21359/// @param rhs the second function type to consider
21360///
21361/// @param k a pointer to a bitfield set by the function to give
21362/// information about the kind of changes carried by @p lhs and @p
21363/// rhs. It is set iff @p k is non-null and the function returns
21364/// false.
21365///
21366/// Please note that setting k to a non-null value does have a
21367/// negative performance impact because even if @p l and @p r are not
21368/// equal, the function keeps up the comparison in order to determine
21369/// the different kinds of ways in which they are different.
21370///
21371///@return true if lhs == rhs, false otherwise.
21372bool
21374{
21375#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
21376
21378
21379 {
21380 // First of all, let's see if these two function types haven't
21381 // already been compared. If so, and if the result of the
21382 // comparison has been cached, let's just re-use it, rather than
21383 // comparing them all over again.
21384 bool cached_result = false;
21385 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
21386 cached_result))
21387 ABG_RETURN(cached_result);
21388 }
21389
21391
21392 bool result = true;
21393
21394 if (!l.type_base::operator==(r))
21395 {
21396 result = false;
21397 if (k)
21399 else
21400 RETURN(result);
21401 }
21402
21403 class_or_union* l_class = 0, *r_class = 0;
21404 if (const method_type* m = dynamic_cast<const method_type*>(&l))
21405 l_class = m->get_class_type().get();
21406
21407 if (const method_type* m = dynamic_cast<const method_type*>(&r))
21408 r_class = m->get_class_type().get();
21409
21410 // Compare the names of the class of the method
21411
21412 if (!!l_class != !!r_class)
21413 {
21414 result = false;
21415 if (k)
21417 else
21418 RETURN(result);
21419 }
21420 else if (l_class
21421 && (l_class->get_qualified_name()
21422 != r_class->get_qualified_name()))
21423 {
21424 result = false;
21425 if (k)
21427 else
21428 RETURN(result);
21429 }
21430
21431 // Then compare the return type; Beware if it's t's a class type
21432 // that is the same as the method class name; we can recurse for
21433 // ever in that case.
21434
21435 decl_base* l_return_type_decl =
21437 decl_base* r_return_type_decl =
21439 bool compare_result_types = true;
21440 string l_rt_name = l_return_type_decl
21441 ? l_return_type_decl->get_qualified_name()
21442 : string();
21443 string r_rt_name = r_return_type_decl
21444 ? r_return_type_decl->get_qualified_name()
21445 : string();
21446
21447 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
21448 ||
21449 (r_class && (r_class->get_qualified_name() == r_rt_name)))
21450 compare_result_types = false;
21451
21452 if (compare_result_types)
21453 {
21454 // Let's not consider typedefs when comparing return types to
21455 // avoid spurious changes.
21456 //
21457 // TODO: We should also do this for parameter types, or rather,
21458 // we should teach the equality operators in the IR, at some
21459 // point, to peel typedefs off.
21461 !=
21463 {
21464 result = false;
21465 if (k)
21466 {
21468 r.get_return_type()))
21470 else
21471 *k |= SUBTYPE_CHANGE_KIND;
21472 }
21473 else
21474 RETURN(result);
21475 }
21476 }
21477 else
21478 if (l_rt_name != r_rt_name)
21479 {
21480 result = false;
21481 if (k)
21482 *k |= SUBTYPE_CHANGE_KIND;
21483 else
21484 RETURN(result);
21485 }
21486
21487 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
21488 for (i = l.get_first_parm(), j = r.get_first_parm();
21489 i != l.get_parameters().end() && j != r.get_parameters().end();
21490 ++i, ++j)
21491 {
21492 if (**i != **j)
21493 {
21494 result = false;
21495 if (k)
21496 {
21497 if (!types_have_similar_structure((*i)->get_type(),
21498 (*j)->get_type()))
21500 else
21501 *k |= SUBTYPE_CHANGE_KIND;
21502 }
21503 else
21504 RETURN(result);
21505 }
21506 }
21507
21508 if ((i != l.get_parameters().end()
21509 || j != r.get_parameters().end()))
21510 {
21511 result = false;
21512 if (k)
21514 else
21515 RETURN(result);
21516 }
21517
21518 RETURN(result);
21519#undef RETURN
21520}
21521
21522/// Get the first parameter of the function.
21523///
21524/// If the function is a non-static member function, the parameter
21525/// returned is the first one following the implicit 'this' parameter.
21526///
21527/// @return the first non implicit parameter of the function.
21528function_type::parameters::const_iterator
21530{
21531 if (get_parameters().empty())
21532 return get_parameters().end();
21533
21534 bool is_method = dynamic_cast<const method_type*>(this);
21535
21536 parameters::const_iterator i = get_parameters().begin();
21537
21538 if (is_method)
21539 ++i;
21540
21541 return i;
21542}
21543
21544/// Get the first parameter of the function.
21545///
21546/// Note that if the function is a non-static member function, the
21547/// parameter returned is the implicit 'this' parameter.
21548///
21549/// @return the first parameter of the function.
21550function_type::parameters::const_iterator
21552{return get_parameters().begin();}
21553
21554/// Get the name of the current @ref function_type.
21555///
21556/// The name is retrieved from a cache. If the cache is empty, this
21557/// function computes the name of the type, stores it in the cache and
21558/// returns it. Subsequent invocation of the function are going to
21559/// just hit the cache.
21560///
21561/// Note that if the type is *NOT* canonicalized then function type
21562/// name is never cached.
21563///
21564/// @param internal if true then it means the function type name is
21565/// going to be used for purposes that are internal to libabigail
21566/// itself. If you don't know what this is then you probably should
21567/// set this parameter to 'false'.
21568///
21569/// @return the name of the function type.
21570const interned_string&
21572{
21573 if (internal)
21574 {
21576 {
21577 if (priv_->internal_cached_name_.empty())
21578 priv_->internal_cached_name_ =
21579 get_function_type_name(this, /*internal=*/true);
21580 return priv_->internal_cached_name_;
21581 }
21582 else
21583 {
21584 if (priv_->temp_internal_cached_name_.empty())
21585 priv_->temp_internal_cached_name_ =
21586 get_function_type_name(this, /*internal=*/true);
21587 return priv_->temp_internal_cached_name_;
21588 }
21589 }
21590 else
21591 {
21593 {
21594 if (priv_->cached_name_.empty())
21595 priv_->cached_name_ =
21596 get_function_type_name(this, /*internal=*/false);
21597 return priv_->cached_name_;
21598 }
21599 else
21600 {
21601 priv_->cached_name_ =
21602 get_function_type_name(this, /*internal=*/false);
21603 return priv_->cached_name_;
21604 }
21605 }
21606}
21607
21608/// Equality operator for function_type.
21609///
21610/// @param o the other function_type to compare against.
21611///
21612/// @return true iff the two function_type are equal.
21613bool
21615{
21616 const function_type* o = dynamic_cast<const function_type*>(&other);
21617 if (!o)
21618 return false;
21619 return try_canonical_compare(this, o);
21620}
21621
21622/// Return a copy of the pretty representation of the current @ref
21623/// function_type.
21624///
21625/// @param internal set to true if the call is intended to get a
21626/// representation of the decl (or type) for the purpose of canonical
21627/// type comparison. This is mainly used in the function
21628/// type_base::get_canonical_type_for().
21629///
21630/// In other words if the argument for this parameter is true then the
21631/// call is meant for internal use (for technical use inside the
21632/// library itself), false otherwise. If you don't know what this is
21633/// for, then set it to false.
21634///
21635/// @return a copy of the pretty representation of the current @ref
21636/// function_type.
21637string
21639 bool /*qualified_name*/) const
21640{return ir::get_pretty_representation(this, internal);}
21641
21642/// Traverses an instance of @ref function_type, visiting all the
21643/// sub-types and decls that it might contain.
21644///
21645/// @param v the visitor that is used to visit every IR sub-node of
21646/// the current node.
21647///
21648/// @return true if either
21649/// - all the children nodes of the current IR node were traversed
21650/// and the calling code should keep going with the traversing.
21651/// - or the current IR node is already being traversed.
21652/// Otherwise, returning false means that the calling code should not
21653/// keep traversing the tree.
21654bool
21656{
21657 // TODO: should we allow the walker to avoid visiting function type
21658 // twice? I think that if we do, then ir_node_visitor needs an
21659 // option to specifically disallow this feature for function types.
21660
21661 if (visiting())
21662 return true;
21663
21664 if (v.visit_begin(this))
21665 {
21666 visiting(true);
21667 bool keep_going = true;
21668
21669 if (type_base_sptr t = get_return_type())
21670 {
21671 if (!t->traverse(v))
21672 keep_going = false;
21673 }
21674
21675 if (keep_going)
21676 for (parameters::const_iterator i = get_parameters().begin();
21677 i != get_parameters().end();
21678 ++i)
21679 if (type_base_sptr parm_type = (*i)->get_type())
21680 if (!parm_type->traverse(v))
21681 break;
21682
21683 visiting(false);
21684 }
21685 return v.visit_end(this);
21686}
21687
21688function_type::~function_type()
21689{}
21690// </function_type>
21691
21692// <method_type>
21693
21694struct method_type::priv
21695{
21696 class_or_union_wptr class_type_;
21697 bool is_const;
21698
21699 priv()
21700 : is_const()
21701 {}
21702}; // end struct method_type::priv
21703
21704/// Constructor for instances of method_type.
21705///
21706/// Instances of method_decl must be of type method_type.
21707///
21708/// @param return_type the type of the return value of the method.
21709///
21710/// @param class_type the base type of the method type. That is, the
21711/// type of the class the method belongs to.
21712///
21713/// @param p the vector of the parameters of the method.
21714///
21715/// @param is_const whether this method type is for a const method.
21716/// Note that const-ness is a property of the method *type* and of the
21717/// relationship between a method *declaration* and its scope.
21718///
21719/// @param size_in_bits the size of an instance of method_type,
21720/// expressed in bits.
21721///
21722/// @param alignment_in_bits the alignment of an instance of
21723/// method_type, expressed in bits.
21724method_type::method_type (type_base_sptr return_type,
21725 class_or_union_sptr class_type,
21726 const std::vector<function_decl::parameter_sptr>& p,
21727 bool is_const,
21728 size_t size_in_bits,
21729 size_t alignment_in_bits)
21730 : type_or_decl_base(class_type->get_environment(),
21731 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21732 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21733 function_type(return_type, p, size_in_bits, alignment_in_bits),
21734 priv_(new priv)
21735{
21737 set_class_type(class_type);
21738 set_is_const(is_const);
21739}
21740
21741/// Constructor of instances of method_type.
21742///
21743///Instances of method_decl must be of type method_type.
21744///
21745/// @param return_type the type of the return value of the method.
21746///
21747/// @param class_type the type of the class the method belongs to.
21748/// The actual (dynamic) type of class_type must be a pointer
21749/// class_type. We are setting it to pointer to type_base here to
21750/// help client code that is compiled without rtti and thus cannot
21751/// perform dynamic casts.
21752///
21753/// @param p the vector of the parameters of the method type.
21754///
21755/// @param is_const whether this method type is for a const method.
21756/// Note that const-ness is a property of the method *type* and of the
21757/// relationship between a method *declaration* and its scope.
21758///
21759/// @param size_in_bits the size of an instance of method_type,
21760/// expressed in bits.
21761///
21762/// @param alignment_in_bits the alignment of an instance of
21763/// method_type, expressed in bits.
21764method_type::method_type(type_base_sptr return_type,
21765 type_base_sptr class_type,
21766 const std::vector<function_decl::parameter_sptr>& p,
21767 bool is_const,
21768 size_t size_in_bits,
21769 size_t alignment_in_bits)
21770 : type_or_decl_base(class_type->get_environment(),
21771 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21772 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21773 function_type(return_type, p, size_in_bits, alignment_in_bits),
21774 priv_(new priv)
21775{
21777 set_class_type(is_class_type(class_type));
21778 set_is_const(is_const);
21779}
21780
21781/// Constructor of the qualified_type_def
21782///
21783/// @param env the environment we are operating from.
21784///
21785/// @param size_in_bits the size of the type, expressed in bits.
21786///
21787/// @param alignment_in_bits the alignment of the type, expressed in bits
21788method_type::method_type(const environment& env,
21789 size_t size_in_bits,
21790 size_t alignment_in_bits)
21791 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21792 type_base(env, size_in_bits, alignment_in_bits),
21793 function_type(env, size_in_bits, alignment_in_bits),
21794 priv_(new priv)
21795{
21797}
21798
21799/// Constructor of instances of method_type.
21800///
21801/// When constructed with this constructor, and instane of method_type
21802/// must set a return type using method_type::set_return_type
21803///
21804/// @param class_typ the base type of the method type. That is, the
21805/// type of the class (or union) the method belongs to.
21806///
21807/// @param size_in_bits the size of an instance of method_type,
21808/// expressed in bits.
21809///
21810/// @param alignment_in_bits the alignment of an instance of
21811/// method_type, expressed in bits.
21812method_type::method_type(class_or_union_sptr class_type,
21813 bool is_const,
21814 size_t size_in_bits,
21815 size_t alignment_in_bits)
21816 : type_or_decl_base(class_type->get_environment(),
21817 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21818 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21819 function_type(class_type->get_environment(),
21820 size_in_bits,
21821 alignment_in_bits),
21822 priv_(new priv)
21823{
21825 set_class_type(class_type);
21826 set_is_const(is_const);
21827}
21828
21829/// Get the class type this method belongs to.
21830///
21831/// @return the class type.
21832class_or_union_sptr
21834{return class_or_union_sptr(priv_->class_type_);}
21835
21836/// Sets the class type of the current instance of method_type.
21837///
21838/// The class type is the type of the class the method belongs to.
21839///
21840/// @param t the new class type to set.
21841void
21842method_type::set_class_type(const class_or_union_sptr& t)
21843{
21844 if (!t)
21845 return;
21846
21847 priv_->class_type_ = t;
21848}
21849
21850/// Return a copy of the pretty representation of the current @ref
21851/// method_type.
21852///
21853/// @param internal set to true if the call is intended to get a
21854/// representation of the decl (or type) for the purpose of canonical
21855/// type comparison. This is mainly used in the function
21856/// type_base::get_canonical_type_for().
21857///
21858/// In other words if the argument for this parameter is true then the
21859/// call is meant for internal use (for technical use inside the
21860/// library itself), false otherwise. If you don't know what this is
21861/// for, then set it to false.
21862///
21863/// @return a copy of the pretty representation of the current @ref
21864/// method_type.
21865string
21867 bool /*qualified_name*/) const
21868{return ir::get_pretty_representation(*this, internal);}
21869
21870/// Setter of the "is-const" property of @ref method_type.
21871///
21872/// @param the new value of the "is-const" property.
21873void
21875{priv_->is_const = f;}
21876
21877/// Getter of the "is-const" property of @ref method_type.
21878///
21879/// @return true iff the "is-const" property was set.
21880bool
21882{return priv_->is_const;}
21883
21884/// The destructor of method_type
21886{}
21887
21888// </method_type>
21889
21890// <function_decl definitions>
21891
21892struct function_decl::priv
21893{
21894 bool declared_inline_;
21895 decl_base::binding binding_;
21896 function_type_wptr type_;
21897 function_type* naked_type_;
21898 elf_symbol_sptr symbol_;
21899 interned_string id_;
21900
21901 priv()
21902 : declared_inline_(false),
21903 binding_(decl_base::BINDING_GLOBAL),
21904 naked_type_()
21905 {}
21906
21907 priv(function_type_sptr t,
21908 bool declared_inline,
21910 : declared_inline_(declared_inline),
21911 binding_(binding),
21912 type_(t),
21913 naked_type_(t.get())
21914 {}
21915
21916 priv(function_type_sptr t,
21917 bool declared_inline,
21920 : declared_inline_(declared_inline),
21921 binding_(binding),
21922 type_(t),
21923 naked_type_(t.get()),
21924 symbol_(s)
21925 {}
21926}; // end sruct function_decl::priv
21927
21928/// Constructor of the @ref function_decl.
21929///
21930/// @param name the name of the function.
21931///
21932/// @param function_type the type of the function.
21933///
21934/// @param declared_inline wether the function is declared inline.
21935///
21936/// @param locus the source location of the function.
21937///
21938/// @param mangled_name the linkage name of the function.
21939///
21940/// @param vis the visibility of the function.
21941///
21942/// @param bind the binding of the function.
21945 bool declared_inline,
21946 const location& locus,
21947 const string& mangled_name,
21948 visibility vis,
21949 binding bind)
21950 : type_or_decl_base(function_type->get_environment(),
21951 FUNCTION_DECL | ABSTRACT_DECL_BASE),
21952 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
21953 priv_(new priv(function_type, declared_inline, bind))
21954{
21956}
21957
21958/// Constructor of the function_decl type.
21959///
21960/// This flavour of constructor is for when the pointer to the
21961/// instance of function_type that the client code has is presented as
21962/// a pointer to type_base. In that case, this constructor saves the
21963/// client code from doing a dynamic_cast to get the function_type
21964/// pointer.
21965///
21966/// @param name the name of the function declaration.
21967///
21968/// @param fn_type the type of the function declaration. The dynamic
21969/// type of this parameter should be 'pointer to function_type'
21970///
21971/// @param declared_inline whether this function was declared inline
21972///
21973/// @param locus the source location of the function declaration.
21974///
21975/// @param linkage_name the mangled name of the function declaration.
21976///
21977/// @param vis the visibility of the function declaration.
21978///
21979/// @param bind the kind of the binding of the function
21980/// declaration.
21982 type_base_sptr fn_type,
21983 bool declared_inline,
21984 const location& locus,
21985 const string& linkage_name,
21986 visibility vis,
21987 binding bind)
21988 : type_or_decl_base(fn_type->get_environment(),
21989 FUNCTION_DECL | ABSTRACT_DECL_BASE),
21990 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
21991 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
21992 declared_inline,
21993 bind))
21994{
21996}
21997
21998/// Get the pretty representation of the current instance of @ref function_decl.
21999///
22000/// @param internal set to true if the call is intended to get a
22001/// representation of the decl (or type) for the purpose of canonical
22002/// type comparison. This is mainly used in the function
22003/// type_base::get_canonical_type_for().
22004///
22005/// In other words if the argument for this parameter is true then the
22006/// call is meant for internal use (for technical use inside the
22007/// library itself), false otherwise. If you don't know what this is
22008/// for, then set it to false.
22009///
22010/// @return the pretty representation for a function.
22011string
22013 bool qualified_name) const
22014{
22015 const method_decl* mem_fn =
22016 dynamic_cast<const method_decl*>(this);
22017
22018 string fn_prefix = mem_fn ? "method ": "function ";
22019 string result;
22020
22021 if (mem_fn
22022 && is_member_function(mem_fn)
22024 fn_prefix += "virtual ";
22025
22026 decl_base_sptr return_type;
22027 if ((mem_fn
22028 && is_member_function(mem_fn)
22029 && (get_member_function_is_dtor(*mem_fn)
22030 || get_member_function_is_ctor(*mem_fn))))
22031 /*cdtors do not have return types. */;
22032 else
22033 return_type = mem_fn
22034 ? get_type_declaration(mem_fn->get_type()->get_return_type())
22036
22037 result = get_pretty_representation_of_declarator(internal);
22038 if (return_type)
22039 {
22040 if (is_npaf_type(is_type(return_type))
22041 || !(is_pointer_to_function_type(is_type(return_type))
22042 || is_pointer_to_array_type(is_type(return_type))))
22043 result = get_type_name(is_type(return_type).get(), qualified_name,
22044 internal) + " " + result;
22045 else if (pointer_type_def_sptr p =
22047 result = add_outer_pointer_to_fn_type_expr(p, result,
22048 /*qualified=*/true,
22049 internal);
22050 else if(pointer_type_def_sptr p =
22051 is_pointer_to_array_type(is_type(return_type)))
22052 result = add_outer_pointer_to_array_type_expr(p, result,
22053 qualified_name,
22054 internal);
22055 else
22057 }
22058
22059 return fn_prefix + result;
22060}
22061
22062/// Compute and return the pretty representation for the part of the
22063/// function declaration that starts at the declarator. That is, the
22064/// return type and the other specifiers of the beginning of the
22065/// function's declaration ar omitted.
22066///
22067/// @param internal set to true if the call is intended to get a
22068/// representation of the decl (or type) for the purpose of canonical
22069/// type comparison. This is mainly used in the function
22070/// type_base::get_canonical_type_for().
22071///
22072/// In other words if the argument for this parameter is true then the
22073/// call is meant for internal use (for technical use inside the
22074/// library itself), false otherwise. If you don't know what this is
22075/// for, then set it to false.
22076///
22077/// @return the pretty representation for the part of the function
22078/// declaration that starts at the declarator.
22079string
22081{
22082 const method_decl* mem_fn =
22083 dynamic_cast<const method_decl*>(this);
22084
22085 string result;
22086
22087 if (mem_fn)
22088 {
22089 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
22090 + "::" + mem_fn->get_name();
22091 }
22092 else
22093 result += get_qualified_name();
22094
22095 std::ostringstream fn_parms;
22096 stream_pretty_representation_of_fn_parms(*get_type(),
22097 fn_parms,
22098 /*qualified=*/true,
22099 internal);
22100 result += fn_parms.str();
22101
22102 if (mem_fn
22103 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
22104 || is_method_type(mem_fn->get_type())->get_is_const()))
22105 result += " const";
22106
22107 return result;
22108}
22109
22110/// Getter for the first non-implicit parameter of a function decl.
22111///
22112/// If the function is a non-static member function, the parameter
22113/// returned is the first one following the implicit 'this' parameter.
22114///
22115/// @return the first non implicit parm.
22116function_decl::parameters::const_iterator
22118{
22119 if (get_parameters().empty())
22120 return get_parameters().end();
22121
22122 bool is_method = dynamic_cast<const method_decl*>(this);
22123
22124 parameters::const_iterator i = get_parameters().begin();
22125 if (is_method)
22126 ++i;
22127
22128 return i;
22129}
22130
22131/// Return the type of the current instance of @ref function_decl.
22132///
22133/// It's either a function_type or method_type.
22134/// @return the type of the current instance of @ref function_decl.
22135const shared_ptr<function_type>
22137{return priv_->type_.lock();}
22138
22139/// Fast getter of the type of the current instance of @ref function_decl.
22140///
22141/// Note that this function returns the underlying pointer managed by
22142/// the smart pointer returned by function_decl::get_type(). It's
22143/// faster than function_decl::get_type(). This getter is to be used
22144/// in code paths that are proven to be performance hot spots;
22145/// especially (for instance) when comparing function types. Those
22146/// are compared extremely frequently when libabigail is used to
22147/// handle huge binaries with a lot of functions.
22148///
22149/// @return the type of the current instance of @ref function_decl.
22150const function_type*
22152{return priv_->naked_type_;}
22153
22154void
22155function_decl::set_type(const function_type_sptr& fn_type)
22156{
22157 priv_->type_ = fn_type;
22158 priv_->naked_type_ = fn_type.get();
22159}
22160
22161/// This sets the underlying ELF symbol for the current function decl.
22162///
22163/// And underlyin$g ELF symbol for the current function decl might
22164/// exist only if the corpus that this function decl originates from
22165/// was constructed from an ELF binary file.
22166///
22167/// Note that comparing two function decls that have underlying ELF
22168/// symbols involves comparing their underlying elf symbols. The decl
22169/// name for the function thus becomes irrelevant in the comparison.
22170///
22171/// @param sym the new ELF symbol for this function decl.
22172void
22174{
22175 priv_->symbol_ = sym;
22176 // The function id cache that depends on the symbol must be
22177 // invalidated because the symbol changed.
22178 priv_->id_ = get_environment().intern("");
22179}
22180
22181/// Gets the the underlying ELF symbol for the current variable,
22182/// that was set using function_decl::set_symbol(). Please read the
22183/// documentation for that member function for more information about
22184/// "underlying ELF symbols".
22185///
22186/// @return sym the underlying ELF symbol for this function decl, if
22187/// one exists.
22188const elf_symbol_sptr&
22190{return priv_->symbol_;}
22191
22192bool
22193function_decl::is_declared_inline() const
22194{return priv_->declared_inline_;}
22195
22197function_decl::get_binding() const
22198{return priv_->binding_;}
22199
22200/// @return the return type of the current instance of function_decl.
22201const shared_ptr<type_base>
22203{return get_type()->get_return_type();}
22204
22205/// @return the parameters of the function.
22206const std::vector<shared_ptr<function_decl::parameter> >&
22208{return get_type()->get_parameters();}
22209
22210/// Append a parameter to the type of this function.
22211///
22212/// @param parm the parameter to append.
22213void
22214function_decl::append_parameter(shared_ptr<parameter> parm)
22215{get_type()->append_parameter(parm);}
22216
22217/// Append a vector of parameters to the type of this function.
22218///
22219/// @param parms the vector of parameters to append.
22220void
22221function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
22222{
22223 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
22224 i != parms.end();
22225 ++i)
22226 get_type()->append_parameter(*i);
22227}
22228
22229/// Create a new instance of function_decl that is a clone of the
22230/// current one.
22231///
22232/// @return the new clone.
22235{
22237 if (is_member_function(*this))
22238 {
22239 method_decl_sptr
22240 m(new method_decl(get_name(),
22241 get_type(),
22242 is_declared_inline(),
22243 get_location(),
22246 get_binding()));
22248 ABG_ASSERT(scope);
22252 get_member_is_static(*this),
22256 f = m;
22257 }
22258 else
22259 {
22260 f.reset(new function_decl(get_name(),
22261 get_type(),
22262 is_declared_inline(),
22263 get_location(),
22266 get_binding()));
22268 }
22269 f->set_symbol(get_symbol());
22270
22271 return f;
22272}
22273
22274/// Compares two instances of @ref function_decl.
22275///
22276/// If the two intances are different, set a bitfield to give some
22277/// insight about the kind of differences there are.
22278///
22279/// @param l the first artifact of the comparison.
22280///
22281/// @param r the second artifact of the comparison.
22282///
22283/// @param k a pointer to a bitfield that gives information about the
22284/// kind of changes there are between @p l and @p r. This one is set
22285/// iff @p k is non-null and the function returns false.
22286///
22287/// Please note that setting k to a non-null value does have a
22288/// negative performance impact because even if @p l and @p r are not
22289/// equal, the function keeps up the comparison in order to determine
22290/// the different kinds of ways in which they are different.
22291///
22292/// @return true if @p l equals @p r, false otherwise.
22293bool
22295{
22296 bool result = true;
22297
22298 // Compare function types
22299 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
22300 if (t0 == t1 || *t0 == *t1)
22301 ; // the types are equal, let's move on to compare the other
22302 // properties of the functions.
22303 else
22304 {
22305 result = false;
22306 if (k)
22307 {
22308 if (!types_have_similar_structure(t0, t1))
22310 else
22311 *k |= SUBTYPE_CHANGE_KIND;
22312 }
22313 else
22315 }
22316
22317 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
22318 if (!!s0 != !!s1)
22319 {
22320 result = false;
22321 if (k)
22323 else
22325 }
22326 else if (s0 && s0 != s1)
22327 {
22328 if (!elf_symbols_alias(s0, s1))
22329 {
22330 result = false;
22331 if (k)
22333 else
22335 }
22336 }
22337 bool symbols_are_equal = (s0 && s1 && result);
22338
22339 if (symbols_are_equal)
22340 {
22341 // The functions have underlying elf symbols that are equal,
22342 // so now, let's compare the decl_base part of the functions
22343 // w/o considering their decl names.
22344 interned_string n1 = l.get_name(), n2 = r.get_name();
22346 const_cast<function_decl&>(l).set_name("");
22347 const_cast<function_decl&>(l).set_linkage_name("");
22348 const_cast<function_decl&>(r).set_name("");
22349 const_cast<function_decl&>(r).set_linkage_name("");
22350
22351 bool decl_bases_different = !l.decl_base::operator==(r);
22352
22353 const_cast<function_decl&>(l).set_name(n1);
22354 const_cast<function_decl&>(l).set_linkage_name(ln1);
22355 const_cast<function_decl&>(r).set_name(n2);
22356 const_cast<function_decl&>(r).set_linkage_name(ln2);
22357
22358 if (decl_bases_different)
22359 {
22360 result = false;
22361 if (k)
22363 else
22365 }
22366 }
22367 else
22368 if (!l.decl_base::operator==(r))
22369 {
22370 result = false;
22371 if (k)
22373 else
22375 }
22376
22377 // Compare the remaining properties
22378 if (l.is_declared_inline() != r.is_declared_inline()
22379 || l.get_binding() != r.get_binding())
22380 {
22381 result = false;
22382 if (k)
22384 else
22386 }
22387
22389 {
22390 result = false;
22391 if (k)
22393 else
22395 }
22396
22398 {
22411 {
22412 result = false;
22413 if (k)
22415 else
22417 }
22418 }
22419
22420 ABG_RETURN(result);
22421}
22422
22423/// Comparison operator for @ref function_decl.
22424///
22425/// @param other the other instance of @ref function_decl to compare
22426/// against.
22427///
22428/// @return true iff the current instance of @ref function_decl equals
22429/// @p other.
22430bool
22432{
22433 const function_decl* o = dynamic_cast<const function_decl*>(&other);
22434 if (!o)
22435 return false;
22436 return equals(*this, *o, 0);
22437}
22438
22439/// Return true iff the function takes a variable number of
22440/// parameters.
22441///
22442/// @return true if the function taks a variable number
22443/// of parameters.
22444bool
22446{
22447 return (!get_parameters().empty()
22448 && get_parameters().back()->get_variadic_marker());
22449}
22450
22451/// The virtual implementation of 'get_hash' for a function_decl.
22452///
22453/// This allows decl_base::get_hash to work for function_decls.
22454///
22455/// @return the hash value for function decl.
22456size_t
22458{
22459 function_decl::hash hash_fn;
22460 return hash_fn(*this);
22461}
22462
22463/// Return an ID that tries to uniquely identify the function inside a
22464/// program or a library.
22465///
22466/// So if the function has an underlying elf symbol, the ID is the
22467/// concatenation of the symbol name and its version. Otherwise, the
22468/// ID is the linkage name if its non-null. Otherwise, it's the
22469/// pretty representation of the function.
22470///
22471/// @return the ID.
22474{
22475 if (priv_->id_.empty())
22476 {
22477 const environment& env = get_type()->get_environment();
22478 if (elf_symbol_sptr s = get_symbol())
22479 {
22480 string virtual_member_suffix;
22481 if (is_member_function(this))
22482 {
22483 method_decl* m = is_method_decl(this);
22484 ABG_ASSERT(m);
22486 {
22488 (m->get_type()->get_class_type(),
22489 /*look_through_decl_only=*/true))
22490 virtual_member_suffix += "/o";
22491 }
22492 }
22493 if (s->has_aliases())
22494 // The symbol has several aliases, so let's use a scheme
22495 // that allows all aliased functions to have different
22496 // IDs.
22497 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
22498 else
22499 // Let's use the full symbol name with its version as ID.
22500 priv_->id_ = env.intern(s->get_id_string());
22501
22502 if (!virtual_member_suffix.empty())
22503 priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
22504 }
22505 else if (!get_linkage_name().empty())
22506 priv_->id_= env.intern(get_linkage_name());
22507 else
22508 priv_->id_ = env.intern(get_pretty_representation());
22509 }
22510 return priv_->id_;
22511}
22512
22513/// Test if two function declarations are aliases.
22514///
22515/// Two functions declarations are aliases if their symbols are
22516/// aliases, in the ELF sense.
22517///
22518/// @param f1 the first function to consider.
22519///
22520/// @param f2 the second function to consider.
22521///
22522/// @return true iff @p f1 is an alias of @p f2
22523bool
22525{
22526 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
22527
22528 if (!s1 || !s2)
22529 return false;
22530
22531 return elf_symbols_alias(s1, s2);
22532}
22533
22534/// This implements the ir_traversable_base::traverse pure virtual
22535/// function.
22536///
22537/// @param v the visitor used on the current instance.
22538///
22539/// @return true if the entire IR node tree got traversed, false
22540/// otherwise.
22541bool
22543{
22544 if (visiting())
22545 return true;
22546
22547 if (v.visit_begin(this))
22548 {
22549 visiting(true);
22550 if (type_base_sptr t = get_type())
22551 t->traverse(v);
22552 visiting(false);
22553 }
22554 return v.visit_end(this);
22555}
22556
22557/// Destructor of the @ref function_decl type.
22559{delete priv_;}
22560
22561/// A deep comparison operator for a shared pointer to @ref function_decl
22562///
22563/// This function compares to shared pointers to @ref function_decl by
22564/// looking at the pointed-to instances of @ref function_dec
22565/// comparing them too. If the two pointed-to objects are equal then
22566/// this function returns true.
22567///
22568/// @param l the left-hand side argument of the equality operator.
22569///
22570/// @param r the right-hand side argument of the equality operator.
22571///
22572/// @return true iff @p l equals @p r.
22573bool
22575{
22576 if (l.get() == r.get())
22577 return true;
22578 if (!!l != !!r)
22579 return false;
22580
22581 return *l == *r;
22582}
22583
22584/// A deep inequality operator for smart pointers to functions.
22585///
22586/// @param l the left-hand side argument of the inequality operator.
22587///
22588/// @pram r the right-hand side argument of the inequality operator.
22589///
22590/// @return true iff @p is not equal to @p r.
22591bool
22593{return !operator==(l, r);}
22594
22595// <function_decl definitions>
22596
22597// <function_decl::parameter definitions>
22598
22599struct function_decl::parameter::priv
22600{
22601 type_base_wptr type_;
22602 unsigned index_;
22603 bool variadic_marker_;
22604
22605 priv()
22606 : index_(),
22607 variadic_marker_()
22608 {}
22609
22610 priv(type_base_sptr type,
22611 unsigned index,
22612 bool variadic_marker)
22613 : type_(type),
22614 index_(index),
22615 variadic_marker_(variadic_marker)
22616 {}
22617};// end struct function_decl::parameter::priv
22618
22619function_decl::parameter::parameter(const type_base_sptr type,
22620 unsigned index,
22621 const string& name,
22622 const location& loc,
22623 bool is_variadic)
22624 : type_or_decl_base(type->get_environment(),
22625 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22626 decl_base(type->get_environment(), name, loc),
22627 priv_(new priv(type, index, is_variadic))
22628{
22629 runtime_type_instance(this);
22630}
22631
22632function_decl::parameter::parameter(const type_base_sptr type,
22633 unsigned index,
22634 const string& name,
22635 const location& loc,
22636 bool is_variadic,
22637 bool is_artificial)
22638 : type_or_decl_base(type->get_environment(),
22639 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22640 decl_base(type->get_environment(), name, loc),
22641 priv_(new priv(type, index, is_variadic))
22642{
22643 runtime_type_instance(this);
22644 set_is_artificial(is_artificial);
22645}
22646
22647function_decl::parameter::parameter(const type_base_sptr type,
22648 const string& name,
22649 const location& loc,
22650 bool is_variadic,
22651 bool is_artificial)
22652 : type_or_decl_base(type->get_environment(),
22653 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22654 decl_base(type->get_environment(), name, loc),
22655 priv_(new priv(type, 0, is_variadic))
22656{
22657 runtime_type_instance(this);
22658 set_is_artificial(is_artificial);
22659}
22660
22661function_decl::parameter::parameter(const type_base_sptr type,
22662 unsigned index,
22663 bool variad)
22664 : type_or_decl_base(type->get_environment(),
22665 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
22666 decl_base(type->get_environment(), "", location()),
22667 priv_(new priv(type, index, variad))
22668{
22669 runtime_type_instance(this);
22670}
22671
22672function_decl::parameter::~parameter() = default;
22673
22674const type_base_sptr
22675function_decl::parameter::get_type()const
22676{return priv_->type_.lock();}
22677
22678/// @return a copy of the type name of the parameter.
22679interned_string
22681{
22682 const environment& env = get_environment();
22683
22684 type_base_sptr t = get_type();
22685 string str;
22686 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
22687 str = "...";
22688 else
22689 {
22690 ABG_ASSERT(t);
22692 }
22693 return env.intern(str);
22694}
22695
22696/// @return a copy of the pretty representation of the type of the
22697/// parameter.
22698const string
22700{
22701 type_base_sptr t = get_type();
22702 string str;
22703 if (get_variadic_marker()
22704 || get_environment().is_variadic_parameter_type(t))
22705 str = "...";
22706 else
22707 {
22708 ABG_ASSERT(t);
22710 }
22711 return str;
22712}
22713
22714/// Get a name uniquely identifying the parameter in the function.
22715///
22716///@return the unique parm name id.
22719{
22720 const environment& env = get_environment();
22721
22722
22723 std::ostringstream o;
22724 o << "parameter-" << get_index();
22725
22726 return env.intern(o.str());
22727}
22728
22729unsigned
22730function_decl::parameter::get_index() const
22731{return priv_->index_;}
22732
22733void
22734function_decl::parameter::set_index(unsigned i)
22735{priv_->index_ = i;}
22736
22737
22738bool
22739function_decl::parameter::get_variadic_marker() const
22740{return priv_->variadic_marker_;}
22741
22742/// Compares two instances of @ref function_decl::parameter.
22743///
22744/// If the two intances are different, set a bitfield to give some
22745/// insight about the kind of differences there are.
22746///
22747/// @param l the first artifact of the comparison.
22748///
22749/// @param r the second artifact of the comparison.
22750///
22751/// @param k a pointer to a bitfield that gives information about the
22752/// kind of changes there are between @p l and @p r. This one is set
22753/// iff @p k is non-null and the function returns false.
22754///
22755/// Please note that setting k to a non-null value does have a
22756/// negative performance impact because even if @p l and @p r are not
22757/// equal, the function keeps up the comparison in order to determine
22758/// the different kinds of ways in which they are different.
22759///
22760/// @return true if @p l equals @p r, false otherwise.
22761bool
22763 const function_decl::parameter& r,
22764 change_kind* k)
22765{
22766 bool result = true;
22767
22768 if ((l.get_variadic_marker() != r.get_variadic_marker())
22769 || (l.get_index() != r.get_index())
22770 || (!!l.get_type() != !!r.get_type()))
22771 {
22772 result = false;
22773 if (k)
22774 {
22775 if (l.get_index() != r.get_index())
22777 if (l.get_variadic_marker() != r.get_variadic_marker()
22778 || !!l.get_type() != !!r.get_type())
22780 }
22781 else
22783 }
22784
22785 type_base_sptr l_type = peel_typedef_type(l.get_type());
22786 type_base_sptr r_type = peel_typedef_type(r.get_type());
22787 if (l_type != r_type)
22788 {
22789 result = false;
22790 if (k)
22791 {
22792 if (!types_have_similar_structure(l_type, r_type))
22794 else
22795 *k |= SUBTYPE_CHANGE_KIND;
22796 }
22797 else
22799 }
22800
22801 ABG_RETURN(result);
22802}
22803
22804bool
22805function_decl::parameter::operator==(const parameter& o) const
22806{return equals(*this, o, 0);}
22807
22808bool
22809function_decl::parameter::operator==(const decl_base& o) const
22810{
22811 const function_decl::parameter* p =
22812 dynamic_cast<const function_decl::parameter*>(&o);
22813 if (!p)
22814 return false;
22815 return function_decl::parameter::operator==(*p);
22816}
22817
22818/// Non-member equality operator for @ref function_decl::parameter.
22819///
22820/// @param l the left-hand side of the equality operator
22821///
22822/// @param r the right-hand side of the equality operator
22823///
22824/// @return true iff @p l and @p r equals.
22825bool
22828{
22829 if (!!l != !!r)
22830 return false;
22831 if (!l)
22832 return true;
22833 return *l == *r;
22834}
22835
22836/// Non-member inequality operator for @ref function_decl::parameter.
22837///
22838/// @param l the left-hand side of the equality operator
22839///
22840/// @param r the right-hand side of the equality operator
22841///
22842/// @return true iff @p l and @p r different.
22843bool
22846{return !operator==(l, r);}
22847
22848/// Traverse the diff sub-tree under the current instance
22849/// function_decl.
22850///
22851/// @param v the visitor to invoke on each diff node of the sub-tree.
22852///
22853/// @return true if the traversing has to keep going on, false
22854/// otherwise.
22855bool
22857{
22858 if (visiting())
22859 return true;
22860
22861 if (v.visit_begin(this))
22862 {
22863 visiting(true);
22864 if (type_base_sptr t = get_type())
22865 t->traverse(v);
22866 visiting(false);
22867 }
22868 return v.visit_end(this);
22869}
22870
22871/// Get the hash of a decl. If the hash hasn't been computed yet,
22872/// compute it ans store its value; otherwise, just return the hash.
22873///
22874/// @return the hash of the decl.
22875size_t
22877{
22878 function_decl::parameter::hash hash_fn_parm;
22879 return hash_fn_parm(this);
22880}
22881
22882/// Compute the qualified name of the parameter.
22883///
22884/// @param internal set to true if the call is intended for an
22885/// internal use (for technical use inside the library itself), false
22886/// otherwise. If you don't know what this is for, then set it to
22887/// false.
22888///
22889/// @param qn the resulting qualified name.
22890void
22892 bool /*internal*/) const
22893{qualified_name = get_name();}
22894
22895/// Compute and return a copy of the pretty representation of the
22896/// current function parameter.
22897///
22898/// @param internal set to true if the call is intended to get a
22899/// representation of the decl (or type) for the purpose of canonical
22900/// type comparison. This is mainly used in the function
22901/// type_base::get_canonical_type_for().
22902///
22903/// In other words if the argument for this parameter is true then the
22904/// call is meant for internal use (for technical use inside the
22905/// library itself), false otherwise. If you don't know what this is
22906/// for, then set it to false.
22907///
22908/// @return a copy of the textual representation of the current
22909/// function parameter.
22910string
22912 bool qualified_name) const
22913{
22914 const environment& env = get_environment();
22915
22916 string type_repr;
22917 type_base_sptr t = get_type();
22918 if (!t)
22919 type_repr = "void";
22920 else if (env.is_variadic_parameter_type(t))
22921 type_repr = "...";
22922 else
22923 type_repr = ir::get_type_name(t, qualified_name, internal);
22924
22925 string result = type_repr;
22926 string parm_name = get_name_id();
22927
22928 if (!parm_name.empty())
22929 result += " " + parm_name;
22930
22931 return result;
22932}
22933
22934// </function_decl::parameter definitions>
22935
22936// <class_or_union definitions>
22937
22938/// A Constructor for instances of @ref class_or_union
22939///
22940/// @param env the environment we are operating from.
22941///
22942/// @param name the identifier of the class.
22943///
22944/// @param size_in_bits the size of an instance of @ref
22945/// class_or_union, expressed in bits
22946///
22947/// @param align_in_bits the alignment of an instance of @ref class_or_union,
22948/// expressed in bits.
22949///
22950/// @param locus the source location of declaration point this class.
22951///
22952/// @param vis the visibility of instances of @ref class_or_union.
22953///
22954/// @param mem_types the vector of member types of this instance of
22955/// @ref class_or_union.
22956///
22957/// @param data_members the vector of data members of this instance of
22958/// @ref class_or_union.
22959///
22960/// @param member_fns the vector of member functions of this instance
22961/// of @ref class_or_union.
22962class_or_union::class_or_union(const environment& env, const string& name,
22963 size_t size_in_bits, size_t align_in_bits,
22964 const location& locus, visibility vis,
22965 member_types& mem_types,
22967 member_functions& member_fns)
22968 : type_or_decl_base(env,
22969 ABSTRACT_TYPE_BASE
22970 | ABSTRACT_DECL_BASE
22971 | ABSTRACT_SCOPE_TYPE_DECL
22972 | ABSTRACT_SCOPE_DECL),
22973 decl_base(env, name, locus, name, vis),
22974 type_base(env, size_in_bits, align_in_bits),
22975 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
22976 priv_(new priv(data_members, member_fns))
22977{
22978 for (member_types::iterator i = mem_types.begin();
22979 i != mem_types.end();
22980 ++i)
22983
22984 for (data_members::iterator i = data_members.begin();
22985 i != data_members.end();
22986 ++i)
22987 if (!has_scope(*i))
22988 add_decl_to_scope(*i, this);
22989
22990 for (member_functions::iterator i = member_fns.begin();
22991 i != member_fns.end();
22992 ++i)
22993 if (!has_scope(static_pointer_cast<decl_base>(*i)))
22994 add_decl_to_scope(*i, this);
22995}
22996
22997/// A constructor for instances of @ref class_or_union.
22998///
22999/// @param env the environment we are operating from.
23000///
23001/// @param name the name of the class.
23002///
23003/// @param size_in_bits the size of an instance of @ref
23004/// class_or_union, expressed in bits
23005///
23006/// @param align_in_bits the alignment of an instance of @ref class_or_union,
23007/// expressed in bits.
23008///
23009/// @param locus the source location of declaration point this class.
23010///
23011/// @param vis the visibility of instances of @ref class_or_union.
23012class_or_union::class_or_union(const environment& env, const string& name,
23013 size_t size_in_bits, size_t align_in_bits,
23014 const location& locus, visibility vis)
23015 : type_or_decl_base(env,
23016 ABSTRACT_TYPE_BASE
23017 | ABSTRACT_DECL_BASE
23018 | ABSTRACT_SCOPE_TYPE_DECL
23019 | ABSTRACT_SCOPE_DECL),
23020 decl_base(env, name, locus, name, vis),
23021 type_base(env, size_in_bits, align_in_bits),
23022 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23023 priv_(new priv)
23024{}
23025
23026/// Constructor of the @ref class_or_union type.
23027///
23028/// @param env the @ref environment we are operating from.
23029///
23030/// @param name the name of the @ref class_or_union.
23031///
23032/// @param is_declaration_only a boolean saying whether the instance
23033/// represents a declaration only, or not.
23034class_or_union::class_or_union(const environment& env, const string& name,
23035 bool is_declaration_only)
23036 : type_or_decl_base(env,
23037 ABSTRACT_TYPE_BASE
23038 | ABSTRACT_DECL_BASE
23039 | ABSTRACT_SCOPE_TYPE_DECL
23040 | ABSTRACT_SCOPE_DECL),
23041 decl_base(env, name, location(), name),
23042 type_base(env, 0, 0),
23043 scope_type_decl(env, name, 0, 0, location()),
23044 priv_(new priv)
23045{
23046 set_is_declaration_only(is_declaration_only);
23047}
23048
23049/// This implements the ir_traversable_base::traverse pure virtual
23050/// function.
23051///
23052/// @param v the visitor used on the member nodes of the translation
23053/// unit during the traversal.
23054///
23055/// @return true if the entire IR node tree got traversed, false
23056/// otherwise.
23057bool
23059{
23060 if (v.type_node_has_been_visited(this))
23061 return true;
23062
23063 if (visiting())
23064 return true;
23065
23066 if (v.visit_begin(this))
23067 {
23068 visiting(true);
23069 bool stop = false;
23070
23071 if (!stop)
23072 for (data_members::const_iterator i = get_data_members().begin();
23073 i != get_data_members().end();
23074 ++i)
23075 if (!(*i)->traverse(v))
23076 {
23077 stop = true;
23078 break;
23079 }
23080
23081 if (!stop)
23082 for (member_functions::const_iterator i= get_member_functions().begin();
23083 i != get_member_functions().end();
23084 ++i)
23085 if (!(*i)->traverse(v))
23086 {
23087 stop = true;
23088 break;
23089 }
23090
23091 if (!stop)
23092 for (member_types::const_iterator i = get_member_types().begin();
23093 i != get_member_types().end();
23094 ++i)
23095 if (!(*i)->traverse(v))
23096 {
23097 stop = true;
23098 break;
23099 }
23100
23101 if (!stop)
23102 for (member_function_templates::const_iterator i =
23104 i != get_member_function_templates().end();
23105 ++i)
23106 if (!(*i)->traverse(v))
23107 {
23108 stop = true;
23109 break;
23110 }
23111
23112 if (!stop)
23113 for (member_class_templates::const_iterator i =
23115 i != get_member_class_templates().end();
23116 ++i)
23117 if (!(*i)->traverse(v))
23118 {
23119 stop = true;
23120 break;
23121 }
23122 visiting(false);
23123 }
23124
23125 bool result = v.visit_end(this);
23127 return result;
23128}
23129
23130/// Destrcutor of the @ref class_or_union type.
23132{delete priv_;}
23133
23134/// Add a member declaration to the current instance of class_or_union.
23135/// The member declaration can be either a member type, data member,
23136/// member function, or member template.
23137///
23138/// @param d the member declaration to add.
23139decl_base_sptr
23140class_or_union::add_member_decl(const decl_base_sptr& d)
23141{return insert_member_decl(d);}
23142
23143/// Remove a given decl from the current @ref class_or_union scope.
23144///
23145/// Note that only type declarations are supported by this method for
23146/// now. Support for the other kinds of declaration is left as an
23147/// exercise for the interested reader of the code.
23148///
23149/// @param decl the declaration to remove from this @ref
23150/// class_or_union scope.
23151void
23153{
23154 type_base_sptr t = is_type(decl);
23155
23156 // For now we want to support just removing types from classes. For
23157 // other kinds of IR node, we need more work.
23158 ABG_ASSERT(t);
23159
23161}
23162
23163/// Fixup the members of the type of an anonymous data member.
23164///
23165/// Walk all data members of (the type of) a given anonymous data
23166/// member and set a particular property of the relationship between
23167/// each data member and its containing type.
23168///
23169/// That property records the fact that the data member belongs to the
23170/// anonymous data member we consider.
23171///
23172/// In the future, if there are other properties of this relationship
23173/// to set in this manner, they ought to be added here.
23174///
23175/// @param anon_dm the anonymous data member to consider.
23176void
23178{
23179 class_or_union * anon_dm_type =
23181 if (!anon_dm_type)
23182 return;
23183
23184 for (class_or_union::data_members::const_iterator it =
23185 anon_dm_type->get_non_static_data_members().begin();
23186 it != anon_dm_type->get_non_static_data_members().end();
23187 ++it)
23188 {
23189 dm_context_rel *rel =
23190 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
23191 ABG_ASSERT(rel);
23192 rel->set_anonymous_data_member(anon_dm.get());
23193 }
23194}
23195
23196/// Getter of the alignment of the @ref class_or_union type.
23197///
23198/// If this @ref class_or_union is a declaration of a definition that
23199/// is elsewhere, then the size of the definition is returned.
23200///
23201/// @return the alignment of the @ref class_or_union type.
23202size_t
23204{
23208
23210}
23211
23212/// Setter of the alignment of the class type.
23213///
23214/// If this class is a declaration of a definition that is elsewhere,
23215/// then the new alignment is set to the definition.
23216///
23217/// @param s the new alignment.
23218void
23220{
23224 else
23226}
23227
23228/// Setter of the size of the @ref class_or_union type.
23229///
23230/// If this @ref class_or_union is a declaration of a definition that
23231/// is elsewhere, then the new size is set to the definition.
23232///
23233/// @param s the new size.
23234void
23236{
23240 else
23242}
23243
23244/// Getter of the size of the @ref class_or_union type.
23245///
23246/// If this @ref class_or_union is a declaration of a definition that
23247/// is elsewhere, then the size of the definition is returned.
23248///
23249/// @return the size of the @ref class_or_union type.
23250size_t
23252{
23256
23258}
23259
23260/// Get the number of anonymous member classes contained in this
23261/// class.
23262///
23263/// @return the number of anonymous member classes contained in this
23264/// class.
23265size_t
23267{
23268 int result = 0;
23269 for (member_types::const_iterator it = get_member_types().begin();
23270 it != get_member_types().end();
23271 ++it)
23272 if (class_decl_sptr t = is_class_type(*it))
23273 if (t->get_is_anonymous())
23274 ++result;
23275
23276 return result;
23277}
23278
23279/// Get the number of anonymous member unions contained in this class.
23280///
23281/// @return the number of anonymous member unions contained in this
23282/// class.
23283size_t
23285{
23286 int result = 0;
23287 for (member_types::const_iterator it = get_member_types().begin();
23288 it != get_member_types().end();
23289 ++it)
23290 if (union_decl_sptr t = is_union_type(*it))
23291 if (t->get_is_anonymous())
23292 ++result;
23293
23294 return result;
23295}
23296
23297/// Get the number of anonymous member enums contained in this class.
23298///
23299/// @return the number of anonymous member enums contained in this
23300/// class.
23301size_t
23303{
23304 int result = 0;
23305 for (member_types::const_iterator it = get_member_types().begin();
23306 it != get_member_types().end();
23307 ++it)
23308 if (enum_type_decl_sptr t = is_enum_type(*it))
23309 if (t->get_is_anonymous())
23310 ++result;
23311
23312 return result;
23313}
23314
23315/// Add a data member to the current instance of class_or_union.
23316///
23317/// @param v a var_decl to add as a data member. A proper
23318/// class_or_union::data_member is created from @p v and added to the
23319/// class_or_union. This var_decl should not have been already added
23320/// to a scope.
23321///
23322/// @param access the access specifier for the data member.
23323///
23324/// @param is_laid_out whether the data member was laid out. That is,
23325/// if its offset has been computed. In the pattern of a class
23326/// template for instance, this would be set to false.
23327///
23328/// @param is_static whether the data memer is static.
23329///
23330/// @param offset_in_bits if @p is_laid_out is true, this is the
23331/// offset of the data member, expressed (oh, surprise) in bits.
23332void
23334 bool is_laid_out, bool is_static,
23335 size_t offset_in_bits)
23336{
23337 ABG_ASSERT(!has_scope(v));
23338
23339 priv_->data_members_.push_back(v);
23341 set_data_member_is_laid_out(v, is_laid_out);
23342 set_data_member_offset(v, offset_in_bits);
23343 set_member_access_specifier(v, access);
23344 set_member_is_static(v, is_static);
23345
23346 if (!is_static)
23347 {
23348 // If this is a non-static variable, add it to the set of
23349 // non-static variables, if it's not already in there.
23350 bool is_already_in = false;
23351 for (data_members::const_iterator i =
23352 priv_->non_static_data_members_.begin();
23353 i != priv_->non_static_data_members_.end();
23354 ++i)
23355 if (*i == v)
23356 {
23357 is_already_in = true;
23358 break;
23359 }
23360 if (!is_already_in)
23361 priv_->non_static_data_members_.push_back(v);
23362 }
23363
23364 // If v is an anonymous data member, then fixup its data members.
23365 // For now, the only thing the fixup does is to make the data
23366 // members of the anonymous data member be aware of their containing
23367 // anonymous data member. That is helpful to compute the absolute
23368 // bit offset of each of the members of the anonymous data member.
23370}
23371
23372/// Get the data members of this @ref class_or_union.
23373///
23374/// @return a vector of the data members of this @ref class_or_union.
23377{return priv_->data_members_;}
23378
23379/// Find a data member of a given name in the current @ref class_or_union.
23380///
23381/// @param name the name of the data member to find in the current
23382/// @ref class_or_union.
23383///
23384/// @return a pointer to the @ref var_decl that represents the data
23385/// member to find inside the current @ref class_or_union.
23386const var_decl_sptr
23387class_or_union::find_data_member(const string& name) const
23388{
23389 for (data_members::const_iterator i = get_data_members().begin();
23390 i != get_data_members().end();
23391 ++i)
23392 if ((*i)->get_name() == name)
23393 return *i;
23394
23395 // We haven't found a data member with the name 'name'. Let's look
23396 // closer again, this time in our anonymous data members.
23397 for (data_members::const_iterator i = get_data_members().begin();
23398 i != get_data_members().end();
23399 ++i)
23401 {
23402 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
23403 ABG_ASSERT(type);
23404 if (var_decl_sptr data_member = type->find_data_member(name))
23405 return data_member;
23406 }
23407
23408 return var_decl_sptr();
23409}
23410
23411/// Find an anonymous data member in the class.
23412///
23413/// @param v the anonymous data member to find.
23414///
23415/// @return the anonymous data member found, or nil if none was found.
23416const var_decl_sptr
23418{
23419 if (!v->get_name().empty())
23420 return var_decl_sptr();
23421
23422 for (data_members::const_iterator it = get_non_static_data_members().begin();
23423 it != get_non_static_data_members().end();
23424 ++it)
23425 {
23426 if (is_anonymous_data_member(*it))
23427 if ((*it)->get_pretty_representation(/*internal=*/false, true)
23428 == v->get_pretty_representation(/*internal=*/false, true))
23429 return *it;
23430 }
23431
23432 return var_decl_sptr();
23433}
23434
23435/// Find a given data member.
23436///
23437/// This function takes a @ref var_decl as an argument. If it has a
23438/// non-empty name, then it tries to find a data member which has the
23439/// same name as the argument.
23440///
23441/// If it has an empty name, then the @ref var_decl is considered as
23442/// an anonymous data member. In that case, this function tries to
23443/// find an anonymous data member which type equals that of the @ref
23444/// var_decl argument.
23445///
23446/// @param v this carries either the name of the data member we need
23447/// to look for, or the type of the anonymous data member we are
23448/// looking for.
23449const var_decl_sptr
23451{
23452 if (!v)
23453 return var_decl_sptr();
23454
23455 if (v->get_name().empty())
23457
23458 return find_data_member(v->get_name());
23459}
23460
23461
23462/// Get the non-static data memebers of this @ref class_or_union.
23463///
23464/// @return a vector of the non-static data members of this @ref
23465/// class_or_union.
23468{return priv_->non_static_data_members_;}
23469
23470/// Add a member function.
23471///
23472/// @param f the new member function to add.
23473///
23474/// @param a the access specifier to use for the new member function.
23475///
23476/// @param is_static whether the new member function is static.
23477///
23478/// @param is_ctor whether the new member function is a constructor.
23479///
23480/// @param is_dtor whether the new member function is a destructor.
23481///
23482/// @param is_const whether the new member function is const.
23483void
23486 bool is_static, bool is_ctor,
23487 bool is_dtor, bool is_const)
23488{
23489 ABG_ASSERT(!has_scope(f));
23490
23492
23493 set_member_function_is_ctor(f, is_ctor);
23494 set_member_function_is_dtor(f, is_dtor);
23496 set_member_is_static(f, is_static);
23497 set_member_function_is_const(f, is_const);
23498
23499 priv_->member_functions_.push_back(f);
23500
23501 // Update the map of linkage name -> member functions. It's useful,
23502 // so that class_or_union::find_member_function() can function.
23503 if (!f->get_linkage_name().empty())
23504 priv_->mem_fns_map_[f->get_linkage_name()] = f;
23505}
23506
23507/// Get the member functions of this @ref class_or_union.
23508///
23509/// @return a vector of the member functions of this @ref
23510/// class_or_union.
23513{return priv_->member_functions_;}
23514
23515/// Find a method, using its linkage name as a key.
23516///
23517/// @param linkage_name the linkage name of the method to find.
23518///
23519/// @return the method found, or nil if none was found.
23520const method_decl*
23521class_or_union::find_member_function(const string& linkage_name) const
23522{
23523 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
23524}
23525
23526/// Find a method, using its linkage name as a key.
23527///
23528/// @param linkage_name the linkage name of the method to find.
23529///
23530/// @return the method found, or nil if none was found.
23532class_or_union::find_member_function(const string& linkage_name)
23533{
23534 string_mem_fn_sptr_map_type::const_iterator i =
23535 priv_->mem_fns_map_.find(linkage_name);
23536 if (i == priv_->mem_fns_map_.end())
23537 return 0;
23538 return i->second.get();
23539}
23540
23541/// Find a method, using its linkage name as a key.
23542///
23543/// @param linkage_name the linkage name of the method to find.
23544///
23545/// @return the method found, or nil if none was found.
23546method_decl_sptr
23548{
23549 string_mem_fn_sptr_map_type::const_iterator i =
23550 priv_->mem_fns_map_.find(linkage_name);
23551 if (i == priv_->mem_fns_map_.end())
23552 return 0;
23553 return i->second;
23554}
23555
23556/// Find a method (member function) using its signature (pretty
23557/// representation) as a key.
23558///
23559/// @param s the signature of the method.
23560///
23561/// @return the method found, or nil if none was found.
23562const method_decl*
23564{
23565 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
23566}
23567
23568/// Find a method (member function) using its signature (pretty
23569/// representation) as a key.
23570///
23571/// @param s the signature of the method.
23572///
23573/// @return the method found, or nil if none was found.
23576{
23577 string_mem_fn_ptr_map_type::const_iterator i =
23578 priv_->signature_2_mem_fn_map_.find(s);
23579 if (i == priv_->signature_2_mem_fn_map_.end())
23580 return 0;
23581 return i->second;
23582}
23583
23584/// Get the member function templates of this class.
23585///
23586/// @return a vector of the member function templates of this class.
23587const member_function_templates&
23589{return priv_->member_function_templates_;}
23590
23591/// Get the member class templates of this class.
23592///
23593/// @return a vector of the member class templates of this class.
23594const member_class_templates&
23596{return priv_->member_class_templates_;}
23597
23598/// Append a member function template to the @ref class_or_union.
23599///
23600/// @param m the member function template to append.
23601void
23602class_or_union::add_member_function_template(member_function_template_sptr m)
23603{
23604 decl_base* c = m->as_function_tdecl()->get_scope();
23605 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
23606 /// error message or something like a structured error.
23607 priv_->member_function_templates_.push_back(m);
23608 if (!c)
23609 scope_decl::add_member_decl(m->as_function_tdecl());
23610}
23611
23612/// Append a member class template to the @ref class_or_union.
23613///
23614/// @param m the member function template to append.
23615void
23617{
23618 decl_base* c = m->as_class_tdecl()->get_scope();
23619 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
23620 /// error message or something like a structured error.
23621 m->set_scope(this);
23622 priv_->member_class_templates_.push_back(m);
23623 if (!c)
23624 scope_decl::add_member_decl(m->as_class_tdecl());
23625}
23626
23627///@return true iff the current instance has no member.
23628bool
23630{
23631 return (get_member_types().empty()
23632 && priv_->data_members_.empty()
23633 && priv_->member_functions_.empty()
23634 && priv_->member_function_templates_.empty()
23635 && priv_->member_class_templates_.empty());
23636}
23637
23638/// Insert a data member to this @ref class_or_union type.
23639///
23640/// @param d the data member to insert.
23641///
23642/// @return the decl @p that got inserted.
23643decl_base_sptr
23645{
23646 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
23647 {
23648 add_data_member(v, public_access,
23649 /*is_laid_out=*/false,
23650 /*is_static=*/true,
23651 /*offset_in_bits=*/0);
23652 d = v;
23653 }
23654 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
23655 add_member_function(f, public_access,
23656 /*is_static=*/false,
23657 /*is_ctor=*/false,
23658 /*is_dtor=*/false,
23659 /*is_const=*/false);
23660 else if (member_function_template_sptr f =
23661 dynamic_pointer_cast<member_function_template>(d))
23663 else if (member_class_template_sptr c =
23664 dynamic_pointer_cast<member_class_template>(d))
23666 else
23668
23669 return d;
23670}
23671
23672/// Equality operator.
23673///
23674/// @param other the other @ref class_or_union to compare against.
23675///
23676/// @return true iff @p other equals the current @ref class_or_union.
23677bool
23679{
23680 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
23681 if (!op)
23682 return false;
23683
23684 // If this is a decl-only type (and thus with no canonical type),
23685 // use the canonical type of the definition, if any.
23686 const class_or_union *l = 0;
23688 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
23689 if (l == 0)
23690 l = this;
23691
23692 // Likewise for the other class.
23693 const class_or_union *r = 0;
23694 if (op->get_is_declaration_only())
23695 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
23696 if (r == 0)
23697 r = op;
23698
23699 return try_canonical_compare(l, r);
23700}
23701
23702/// Equality operator.
23703///
23704/// @param other the other @ref class_or_union to compare against.
23705///
23706/// @return true iff @p other equals the current @ref class_or_union.
23707bool
23709{
23710 const decl_base* o = dynamic_cast<const decl_base*>(&other);
23711 if (!o)
23712 return false;
23713 return *this == *o;
23714}
23715
23716/// Equality operator.
23717///
23718/// @param other the other @ref class_or_union to compare against.
23719///
23720/// @return true iff @p other equals the current @ref class_or_union.
23721bool
23723{
23724 const decl_base& o = other;
23726}
23727
23728/// Compares two instances of @ref class_or_union.
23729///
23730/// If the two intances are different, set a bitfield to give some
23731/// insight about the kind of differences there are.
23732///
23733/// @param l the first artifact of the comparison.
23734///
23735/// @param r the second artifact of the comparison.
23736///
23737/// @param k a pointer to a bitfield that gives information about the
23738/// kind of changes there are between @p l and @p r. This one is set
23739/// iff it's non-null and if the function returns false.
23740///
23741/// Please note that setting k to a non-null value does have a
23742/// negative performance impact because even if @p l and @p r are not
23743/// equal, the function keeps up the comparison in order to determine
23744/// the different kinds of ways in which they are different.
23745///
23746/// @return true if @p l equals @p r, false otherwise.
23747bool
23749{
23750 // if one of the classes is declaration-only, look through it to
23751 // get its definition.
23752 bool l_is_decl_only = l.get_is_declaration_only();
23753 bool r_is_decl_only = r.get_is_declaration_only();
23754 if (l_is_decl_only || r_is_decl_only)
23755 {
23756 const class_or_union* def1 = l_is_decl_only
23758 : &l;
23759
23760 const class_or_union* def2 = r_is_decl_only
23762 : &r;
23763
23764 if (!def1 || !def2)
23765 {
23766 if (!l.get_is_anonymous()
23767 && !r.get_is_anonymous()
23768 && l_is_decl_only && r_is_decl_only
23770 // The two decl-only classes differ from their size. A
23771 // true decl-only class should not have a size property to
23772 // begin with. This comes from a DWARF oddity and can
23773 // results in a false positive, so let's not consider that
23774 // change.
23775 return true;
23776
23778 || ((odr_is_relevant(l) && !def1)
23779 || (odr_is_relevant(r) && !def2)))
23782 {
23783 const interned_string& q1 = l.get_scoped_name();
23784 const interned_string& q2 = r.get_scoped_name();
23785 if (q1 == q2)
23786 // Not using RETURN(true) here, because that causes
23787 // performance issues. We don't need to do
23788 // l.priv_->unmark_as_being_compared({l,r}) here because
23789 // we haven't marked l or r as being compared yet, and
23790 // doing so has a peformance cost that shows up on
23791 // performance profiles for *big* libraries.
23792 return true;
23793 else
23794 {
23795 if (k)
23797 // Not using RETURN(true) here, because that causes
23798 // performance issues. We don't need to do
23799 // l.priv_->unmark_as_being_compared({l,r}) here because
23800 // we haven't marked l or r as being compared yet, and
23801 // doing so has a peformance cost that shows up on
23802 // performance profiles for *big* libraries.
23804 }
23805 }
23806 else // A decl-only class is considered different from a
23807 // class definition of the same name.
23808 {
23809 if (!!def1 != !!def2)
23810 {
23811 if (k)
23814 }
23815
23816 // both definitions are empty
23817 if (!(l.decl_base::operator==(r)
23818 && l.type_base::operator==(r)))
23819 {
23820 if (k)
23823 }
23824
23825 return true;
23826 }
23827 }
23828
23829 bool val = *def1 == *def2;
23830 if (!val)
23831 if (k)
23833 ABG_RETURN(val);
23834 }
23835
23836 // No need to go further if the classes have different names or
23837 // different size / alignment.
23838 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
23839 {
23840 if (k)
23843 }
23844
23845 if (types_defined_same_linux_kernel_corpus_public(l, r))
23846 return true;
23847
23848 //TODO: Maybe remove this (cycle detection and canonical type
23849 //propagation handling) from here and have it only in the equal
23850 //overload for class_decl and union_decl because this one ( the
23851 //equal overload for class_or_union) is just a sub-routine of these
23852 //two above.
23853#define RETURN(value) \
23854 return return_comparison_result(l, r, value, \
23855 /*propagate_canonical_type=*/false);
23856
23858
23860
23861 bool result = true;
23862
23863 //compare data_members
23864 {
23865 if (l.get_non_static_data_members().size()
23866 != r.get_non_static_data_members().size())
23867 {
23868 result = false;
23869 if (k)
23871 else
23872 RETURN(result);
23873 }
23874
23875 for (class_or_union::data_members::const_iterator
23876 d0 = l.get_non_static_data_members().begin(),
23877 d1 = r.get_non_static_data_members().begin();
23878 (d0 != l.get_non_static_data_members().end()
23879 && d1 != r.get_non_static_data_members().end());
23880 ++d0, ++d1)
23881 if (**d0 != **d1)
23882 {
23883 result = false;
23884 if (k)
23885 {
23886 // Report any representation change as being local.
23887 if (!types_have_similar_structure((*d0)->get_type(),
23888 (*d1)->get_type())
23889 || (*d0)->get_type() == (*d1)->get_type())
23891 else
23892 *k |= SUBTYPE_CHANGE_KIND;
23893 }
23894 else
23895 RETURN(result);
23896 }
23897 }
23898
23899 // Do not compare member functions. DWARF does not necessarily
23900 // all the member functions, be they virtual or not, in all
23901 // translation units. So we cannot have a clear view of them, per
23902 // class
23903
23904 // compare member function templates
23905 {
23906 if (l.get_member_function_templates().size()
23907 != r.get_member_function_templates().size())
23908 {
23909 result = false;
23910 if (k)
23912 else
23913 RETURN(result);
23914 }
23915
23916 for (member_function_templates::const_iterator
23917 fn_tmpl_it0 = l.get_member_function_templates().begin(),
23918 fn_tmpl_it1 = r.get_member_function_templates().begin();
23919 fn_tmpl_it0 != l.get_member_function_templates().end()
23920 && fn_tmpl_it1 != r.get_member_function_templates().end();
23921 ++fn_tmpl_it0, ++fn_tmpl_it1)
23922 if (**fn_tmpl_it0 != **fn_tmpl_it1)
23923 {
23924 result = false;
23925 if (k)
23926 {
23928 break;
23929 }
23930 else
23931 RETURN(result);
23932 }
23933 }
23934
23935 // compare member class templates
23936 {
23937 if (l.get_member_class_templates().size()
23938 != r.get_member_class_templates().size())
23939 {
23940 result = false;
23941 if (k)
23943 else
23944 RETURN(result);
23945 }
23946
23947 for (member_class_templates::const_iterator
23948 cl_tmpl_it0 = l.get_member_class_templates().begin(),
23949 cl_tmpl_it1 = r.get_member_class_templates().begin();
23950 cl_tmpl_it0 != l.get_member_class_templates().end()
23951 && cl_tmpl_it1 != r.get_member_class_templates().end();
23952 ++cl_tmpl_it0, ++cl_tmpl_it1)
23953 if (**cl_tmpl_it0 != **cl_tmpl_it1)
23954 {
23955 result = false;
23956 if (k)
23957 {
23959 break;
23960 }
23961 else
23962 RETURN(result);
23963 }
23964 }
23965
23966 RETURN(result);
23967#undef RETURN
23968}
23969
23970
23971/// Copy a method of a @ref class_or_union into a new @ref
23972/// class_or_union.
23973///
23974/// @param t the @ref class_or_union into which the method is to be copied.
23975///
23976/// @param method the method to copy into @p t.
23977///
23978/// @return the resulting newly copied method.
23979method_decl_sptr
23980copy_member_function(const class_or_union_sptr& t,
23981 const method_decl_sptr& method)
23982{return copy_member_function(t, method.get());}
23983
23984
23985/// Copy a method of a @ref class_or_union into a new @ref
23986/// class_or_union.
23987///
23988/// @param t the @ref class_or_union into which the method is to be copied.
23989///
23990/// @param method the method to copy into @p t.
23991///
23992/// @return the resulting newly copied method.
23993method_decl_sptr
23994copy_member_function(const class_or_union_sptr& t, const method_decl* method)
23995{
23996 ABG_ASSERT(t);
23997 ABG_ASSERT(method);
23998
23999 method_type_sptr old_type = method->get_type();
24000 ABG_ASSERT(old_type);
24001 method_type_sptr new_type(new method_type(old_type->get_return_type(),
24002 t,
24003 old_type->get_parameters(),
24004 old_type->get_is_const(),
24005 old_type->get_size_in_bits(),
24006 old_type->get_alignment_in_bits()));
24007 t->get_translation_unit()->bind_function_type_life_time(new_type);
24008
24009 method_decl_sptr
24010 new_method(new method_decl(method->get_name(),
24011 new_type,
24012 method->is_declared_inline(),
24013 method->get_location(),
24014 method->get_linkage_name(),
24015 method->get_visibility(),
24016 method->get_binding()));
24017 new_method->set_symbol(method->get_symbol());
24018
24019 if (class_decl_sptr class_type = is_class_type(t))
24020 class_type->add_member_function(new_method,
24024 get_member_is_static(*method),
24028 else
24029 t->add_member_function(new_method,
24031 get_member_is_static(*method),
24035 return new_method;
24036}
24037
24038// </class_or_union definitions>
24039
24040/// @defgroup OnTheFlyCanonicalization On-the-fly Canonicalization
24041/// @{
24042///
24043/// This optimization is also known as "canonical type propagation".
24044///
24045/// During the canonicalization of a type T (which doesn't yet have a
24046/// canonical type), T is compared structurally (member-wise) against
24047/// a type C which already has a canonical type. The comparison
24048/// expression is C == T.
24049///
24050/// During that structural comparison, if a subtype of C (which also
24051/// already has a canonical type) is structurally compared to a
24052/// subtype of T (which doesn't yet have a canonical type) and if they
24053/// are equal, then we can deduce that the canonical type of the
24054/// subtype of C is the canonical type of the subtype of C.
24055///
24056/// Thus, we can canonicalize the sub-type of the T, during the
24057/// canonicalization of T itself. That canonicalization of the
24058/// sub-type of T is what we call the "on-the-fly canonicalization".
24059/// It's on the fly because it happens during a comparison -- which
24060/// itself happens during the canonicalization of T.
24061///
24062/// For now this on-the-fly canonicalization only happens when
24063/// comparing @ref class_decl and @ref function_type.
24064///
24065/// Note however that there is a case when a type is *NOT* eligible to
24066/// this canonical type propagation optimization.
24067///
24068/// The reason why a type is deemed NON-eligible to the canonical type
24069/// propagation optimization is that it "depends" on recursively
24070/// present type. Let me explain.
24071///
24072/// Suppose we have a type T that has sub-types named ST0 and ST1.
24073/// Suppose ST1 itself has a sub-type that is T itself. In this case,
24074/// we say that T is a recursive type, because it has T (itself) as
24075/// one of its sub-types:
24076///
24077/// <PRE>
24078/// T
24079/// +-- ST0
24080/// |
24081/// +-- ST1
24082/// | +
24083/// | |
24084/// | +-- T
24085/// |
24086/// +-- ST2
24087/// </PRE>
24088///
24089/// ST1 is said to "depend" on T because it has T as a sub-type. But
24090/// because T is recursive, then ST1 is said to depend on a recursive
24091/// type. Notice however that ST0 does not depend on any recursive
24092/// type.
24093///
24094/// Now suppose we are comparing T to a type T' that has the same
24095/// structure with sub-types ST0', ST1' and ST2'. During the
24096/// comparison of ST1 against ST1', their sub-type T is compared
24097/// against T'. Because T (resp. T') is a recursive type that is
24098/// already being compared, the comparison of T against T' (as a
24099/// subtypes of ST1 and ST1') returns true, meaning they are
24100/// considered equal. This is done so that we don't enter an infinite
24101/// recursion.
24102///
24103/// That means ST1 is also deemed equal to ST1'. If we are in the
24104/// course of the canonicalization of T' and thus if T (as well as as
24105/// all of its sub-types) is already canonicalized, then the canonical
24106/// type propagation optimization will make us propagate the canonical
24107/// type of ST1 onto ST1'. So the canonical type of ST1' will be
24108/// equal to the canonical type of ST1 as a result of that
24109/// optmization.
24110///
24111/// But then, later down the road, when ST2 is compared against ST2',
24112/// let's suppose that we find out that they are different. Meaning
24113/// that ST2 != ST2'. This means that T != T', i.e, the
24114/// canonicalization of T' failed for now. But most importantly, it
24115/// means that the propagation of the canonical type of ST1 to ST1'
24116/// must now be invalidated. Meaning, ST1' must now be considered as
24117/// not having any canonical type.
24118///
24119/// In other words, during type canonicalization, if ST1' depends on a
24120/// recursive type T', its propagated canonical type must be
24121/// invalidated (set to nullptr) if T' appears to be different from T,
24122/// a.k.a, the canonicalization of T' temporarily failed.
24123///
24124/// This means that any sub-type that depends on recursive types and
24125/// that has been the target of the canonical type propagation
24126/// optimization must be tracked. If the dependant recursive type
24127/// fails its canonicalization, then the sub-type being compared must
24128/// have its propagated canonical type cleared. In other words, its
24129/// propagated canonical type must be cancelled.
24130///
24131/// @}
24132
24133
24134/// If on-the-fly canonicalization is turned on, then this function
24135/// sets the canonical type of its second parameter to the canonical
24136/// type of the first parameter.
24137///
24138/// @param lhs_type the type which canonical type to propagate.
24139///
24140/// @param rhs_type the type which canonical type to set.
24141static bool
24142maybe_propagate_canonical_type(const type_base& lhs_type,
24143 const type_base& rhs_type)
24144{
24145 const environment& env = lhs_type.get_environment();
24146#if WITH_DEBUG_TYPE_CANONICALIZATION
24147 if (!env.priv_->use_canonical_type_comparison_)
24148 return false;
24149#endif
24150
24152 if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
24153 if (!rhs_type.get_canonical_type())
24154 if (env.priv_->propagate_ct(lhs_type, rhs_type))
24155 return true;
24156 return false;
24157}
24158
24159// <class_decl definitions>
24160
24161static void
24162sort_virtual_member_functions(class_decl::member_functions& mem_fns);
24163
24164/// The private data for the class_decl type.
24165struct class_decl::priv
24166{
24167 base_specs bases_;
24168 unordered_map<string, base_spec_sptr> bases_map_;
24169 member_functions virtual_mem_fns_;
24170 virtual_mem_fn_map_type virtual_mem_fns_map_;
24171 bool is_struct_;
24172
24173 priv()
24174 : is_struct_(false)
24175 {}
24176
24177 priv(bool is_struct, class_decl::base_specs& bases)
24178 : bases_(bases),
24179 is_struct_(is_struct)
24180 {
24181 }
24182
24183 priv(bool is_struct)
24184 : is_struct_(is_struct)
24185 {}
24186};// end struct class_decl::priv
24187
24188/// A Constructor for instances of \ref class_decl
24189///
24190/// @param env the environment we are operating from.
24191///
24192/// @param name the identifier of the class.
24193///
24194/// @param size_in_bits the size of an instance of class_decl, expressed
24195/// in bits
24196///
24197/// @param align_in_bits the alignment of an instance of class_decl,
24198/// expressed in bits.
24199///
24200/// @param locus the source location of declaration point this class.
24201///
24202/// @param vis the visibility of instances of class_decl.
24203///
24204/// @param bases the vector of base classes for this instance of class_decl.
24205///
24206/// @param mbrs the vector of member types of this instance of
24207/// class_decl.
24208///
24209/// @param data_mbrs the vector of data members of this instance of
24210/// class_decl.
24211///
24212/// @param mbr_fns the vector of member functions of this instance of
24213/// class_decl.
24214class_decl::class_decl(const environment& env, const string& name,
24215 size_t size_in_bits, size_t align_in_bits,
24216 bool is_struct, const location& locus,
24217 visibility vis, base_specs& bases,
24218 member_types& mbr_types,
24219 data_members& data_mbrs,
24220 member_functions& mbr_fns)
24221 : type_or_decl_base(env,
24222 CLASS_TYPE
24223 | ABSTRACT_TYPE_BASE
24224 | ABSTRACT_DECL_BASE
24225 | ABSTRACT_SCOPE_TYPE_DECL
24226 | ABSTRACT_SCOPE_DECL),
24227 decl_base(env, name, locus, name, vis),
24228 type_base(env, size_in_bits, align_in_bits),
24229 class_or_union(env, name, size_in_bits, align_in_bits,
24230 locus, vis, mbr_types, data_mbrs, mbr_fns),
24231 priv_(new priv(is_struct, bases))
24232{
24234}
24235
24236/// A Constructor for instances of @ref class_decl
24237///
24238/// @param env the environment we are operating from.
24239///
24240/// @param name the identifier of the class.
24241///
24242/// @param size_in_bits the size of an instance of class_decl, expressed
24243/// in bits
24244///
24245/// @param align_in_bits the alignment of an instance of class_decl,
24246/// expressed in bits.
24247///
24248/// @param locus the source location of declaration point this class.
24249///
24250/// @param vis the visibility of instances of class_decl.
24251///
24252/// @param bases the vector of base classes for this instance of class_decl.
24253///
24254/// @param mbrs the vector of member types of this instance of
24255/// class_decl.
24256///
24257/// @param data_mbrs the vector of data members of this instance of
24258/// class_decl.
24259///
24260/// @param mbr_fns the vector of member functions of this instance of
24261/// class_decl.
24262///
24263/// @param is_anonymous whether the newly created instance is
24264/// anonymous.
24265class_decl::class_decl(const environment& env, const string& name,
24266 size_t size_in_bits, size_t align_in_bits,
24267 bool is_struct, const location& locus,
24268 visibility vis, base_specs& bases,
24269 member_types& mbr_types, data_members& data_mbrs,
24270 member_functions& mbr_fns, bool is_anonymous)
24271 : type_or_decl_base(env,
24272 CLASS_TYPE
24273 | ABSTRACT_TYPE_BASE
24274 | ABSTRACT_DECL_BASE
24275 | ABSTRACT_SCOPE_TYPE_DECL
24276 | ABSTRACT_SCOPE_DECL),
24277 decl_base(env, name, locus,
24278 // If the class is anonymous then by default it won't
24279 // have a linkage name. Also, the anonymous class does
24280 // have an internal-only unique name that is generally
24281 // not taken into account when comparing classes; such a
24282 // unique internal-only name, when used as a linkage
24283 // name might introduce spurious comparison false
24284 // negatives.
24285 /*linkage_name=*/is_anonymous ? string() : name,
24286 vis),
24287 type_base(env, size_in_bits, align_in_bits),
24288 class_or_union(env, name, size_in_bits, align_in_bits,
24289 locus, vis, mbr_types, data_mbrs, mbr_fns),
24290 priv_(new priv(is_struct, bases))
24291{
24293 set_is_anonymous(is_anonymous);
24294}
24295
24296/// A constructor for instances of class_decl.
24297///
24298/// @param env the environment we are operating from.
24299///
24300/// @param name the name of the class.
24301///
24302/// @param size_in_bits the size of an instance of class_decl, expressed
24303/// in bits
24304///
24305/// @param align_in_bits the alignment of an instance of class_decl,
24306/// expressed in bits.
24307///
24308/// @param locus the source location of declaration point this class.
24309///
24310/// @param vis the visibility of instances of class_decl.
24311class_decl::class_decl(const environment& env, const string& name,
24312 size_t size_in_bits, size_t align_in_bits,
24313 bool is_struct, const location& locus,
24314 visibility vis)
24315 : type_or_decl_base(env,
24316 CLASS_TYPE
24317 | ABSTRACT_TYPE_BASE
24318 | ABSTRACT_DECL_BASE
24319 | ABSTRACT_SCOPE_TYPE_DECL
24320 | ABSTRACT_SCOPE_DECL),
24321 decl_base(env, name, locus, name, vis),
24322 type_base(env, size_in_bits, align_in_bits),
24323 class_or_union(env, name, size_in_bits, align_in_bits,
24324 locus, vis),
24325 priv_(new priv(is_struct))
24326{
24328}
24329
24330/// A constructor for instances of @ref class_decl.
24331///
24332/// @param env the environment we are operating from.
24333///
24334/// @param name the name of the class.
24335///
24336/// @param size_in_bits the size of an instance of class_decl, expressed
24337/// in bits
24338///
24339/// @param align_in_bits the alignment of an instance of class_decl,
24340/// expressed in bits.
24341///
24342/// @param locus the source location of declaration point this class.
24343///
24344/// @param vis the visibility of instances of class_decl.
24345///
24346/// @param is_anonymous whether the newly created instance is
24347/// anonymous.
24348class_decl:: class_decl(const environment& env, const string& name,
24349 size_t size_in_bits, size_t align_in_bits,
24350 bool is_struct, const location& locus,
24351 visibility vis, bool is_anonymous)
24352 : type_or_decl_base(env,
24353 CLASS_TYPE
24354 | ABSTRACT_TYPE_BASE
24355 | ABSTRACT_DECL_BASE
24356 | ABSTRACT_SCOPE_TYPE_DECL
24357 | ABSTRACT_SCOPE_DECL),
24358 decl_base(env, name, locus,
24359 // If the class is anonymous then by default it won't
24360 // have a linkage name. Also, the anonymous class does
24361 // have an internal-only unique name that is generally
24362 // not taken into account when comparing classes; such a
24363 // unique internal-only name, when used as a linkage
24364 // name might introduce spurious comparison false
24365 // negatives.
24366 /*linkage_name=*/ is_anonymous ? string() : name,
24367 vis),
24368 type_base(env, size_in_bits, align_in_bits),
24369 class_or_union(env, name, size_in_bits, align_in_bits,
24370 locus, vis),
24371 priv_(new priv(is_struct))
24372{
24374 set_is_anonymous(is_anonymous);
24375}
24376
24377/// A constuctor for instances of class_decl that represent a
24378/// declaration without definition.
24379///
24380/// @param env the environment we are operating from.
24381///
24382/// @param name the name of the class.
24383///
24384/// @param is_declaration_only a boolean saying whether the instance
24385/// represents a declaration only, or not.
24386class_decl::class_decl(const environment& env, const string& name,
24387 bool is_struct, bool is_declaration_only)
24388 : type_or_decl_base(env,
24389 CLASS_TYPE
24390 | ABSTRACT_TYPE_BASE
24391 | ABSTRACT_DECL_BASE
24392 | ABSTRACT_SCOPE_TYPE_DECL
24393 | ABSTRACT_SCOPE_DECL),
24394 decl_base(env, name, location(), name),
24395 type_base(env, 0, 0),
24396 class_or_union(env, name, is_declaration_only),
24397 priv_(new priv(is_struct))
24398{
24400}
24401
24402/// This method is invoked automatically right after the current
24403/// instance of @ref class_decl has been canonicalized.
24404///
24405/// Currently, the only thing it does is to sort the virtual member
24406/// functions vector.
24407void
24409{
24411
24412 for (class_decl::virtual_mem_fn_map_type::iterator i =
24413 priv_->virtual_mem_fns_map_.begin();
24414 i != priv_->virtual_mem_fns_map_.end();
24415 ++i)
24416 sort_virtual_member_functions(i->second);
24417}
24418
24419/// Set the "is-struct" flag of the class.
24420///
24421/// @param f the new value of the flag.
24422void
24424{priv_->is_struct_ = f;}
24425
24426/// Test if the class is a struct.
24427///
24428/// @return true iff the class is a struct.
24429bool
24431{return priv_->is_struct_;}
24432
24433/// Add a base specifier to this class.
24434///
24435/// @param b the new base specifier.
24436void
24438{
24439 priv_->bases_.push_back(b);
24440 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
24441}
24442
24443/// Get the base specifiers for this class.
24444///
24445/// @return a vector of the base specifiers.
24448{return priv_->bases_;}
24449
24450/// Find a base class of a given qualified name for the current class.
24451///
24452/// @param qualified_name the qualified name of the base class to look for.
24453///
24454/// @return a pointer to the @ref class_decl that represents the base
24455/// class of name @p qualified_name, if found.
24457class_decl::find_base_class(const string& qualified_name) const
24458{
24459 unordered_map<string, base_spec_sptr>::iterator i =
24460 priv_->bases_map_.find(qualified_name);
24461
24462 if (i != priv_->bases_map_.end())
24463 return i->second->get_base_class();
24464
24465 return class_decl_sptr();
24466}
24467
24468/// Get the virtual member functions of this class.
24469///
24470/// @param return a vector of the virtual member functions of this
24471/// class.
24474{return priv_->virtual_mem_fns_;}
24475
24476/// Get the map that associates a virtual table offset to the virtual
24477/// member functions with that virtual table offset.
24478///
24479/// Usually, there should be a 1:1 mapping between a given vtable
24480/// offset and virtual member functions of that vtable offset. But
24481/// because of some implementation details, there can be several C++
24482/// destructor functions that are *generated* by compilers, for a
24483/// given destructor that is defined in the source code. If the
24484/// destructor is virtual then those generated functions have some
24485/// DWARF attributes in common with the constructor that the user
24486/// actually defined in its source code. Among those attributes are
24487/// the vtable offset of the destructor.
24488///
24489/// @return the map that associates a virtual table offset to the
24490/// virtual member functions with that virtual table offset.
24493{return priv_->virtual_mem_fns_map_;}
24494
24495/// Sort the virtual member functions by their virtual index.
24496void
24498{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
24499
24500/// Getter of the pretty representation of the current instance of
24501/// @ref class_decl.
24502///
24503/// @param internal set to true if the call is intended to get a
24504/// representation of the decl (or type) for the purpose of canonical
24505/// type comparison. This is mainly used in the function
24506/// type_base::get_canonical_type_for().
24507///
24508/// In other words if the argument for this parameter is true then the
24509/// call is meant for internal use (for technical use inside the
24510/// library itself), false otherwise. If you don't know what this is
24511/// for, then set it to false.
24512///
24513/// @param qualified_name if true, names emitted in the pretty
24514/// representation are fully qualified.
24515///
24516/// @return the pretty representaion for a class_decl.
24517string
24519 bool qualified_name) const
24520{
24521 string cl = "class ";
24522 if (!internal && is_struct())
24523 cl = "struct ";
24524
24525 // When computing the pretty representation for internal purposes,
24526 // if an anonymous class is named by a typedef, then consider that
24527 // it has a name, which is the typedef name.
24528 if (get_is_anonymous())
24529 {
24530 if (internal && !get_name().empty())
24531 return cl + get_type_name(this, qualified_name, /*internal=*/true);
24533 /*one_line=*/true,
24534 internal);
24535
24536 }
24537
24538 string result = cl;
24539 if (qualified_name)
24540 result += get_qualified_name(internal);
24541 else
24542 result += get_name();
24543
24544 return result;
24545}
24546
24547decl_base_sptr
24548class_decl::insert_member_decl(decl_base_sptr d)
24549{
24550 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24551 add_member_function(f, public_access,
24552 /*is_virtual=*/false,
24553 /*vtable_offset=*/0,
24554 /*is_static=*/false,
24555 /*is_ctor=*/false,
24556 /*is_dtor=*/false,
24557 /*is_const=*/false);
24558 else
24560
24561 return d;
24562}
24563
24564/// The private data structure of class_decl::base_spec.
24565struct class_decl::base_spec::priv
24566{
24567 class_decl_wptr base_class_;
24568 long offset_in_bits_;
24569 bool is_virtual_;
24570
24571 priv(const class_decl_sptr& cl,
24572 long offset_in_bits,
24573 bool is_virtual)
24574 : base_class_(cl),
24575 offset_in_bits_(offset_in_bits),
24576 is_virtual_(is_virtual)
24577 {}
24578};
24579
24580/// Constructor for base_spec instances.
24581///
24582/// @param base the base class to consider
24583///
24584/// @param a the access specifier of the base class.
24585///
24586/// @param offset_in_bits if positive or null, represents the offset
24587/// of the base in the layout of its containing type.. If negative,
24588/// means that the current base is not laid out in its containing type.
24589///
24590/// @param is_virtual if true, means that the current base class is
24591/// virtual in it's containing type.
24592class_decl::base_spec::base_spec(const class_decl_sptr& base,
24594 long offset_in_bits,
24595 bool is_virtual)
24596 : type_or_decl_base(base->get_environment(),
24597 ABSTRACT_DECL_BASE),
24598 decl_base(base->get_environment(), base->get_name(), base->get_location(),
24599 base->get_linkage_name(), base->get_visibility()),
24600 member_base(a),
24601 priv_(new priv(base, offset_in_bits, is_virtual))
24602{
24604 set_qualified_name(base->get_qualified_name());
24605}
24606
24607/// Get the base class referred to by the current base class
24608/// specifier.
24609///
24610/// @return the base class.
24613{return priv_->base_class_.lock();}
24614
24615/// Getter of the "is-virtual" proprerty of the base class specifier.
24616///
24617/// @return true iff this specifies a virtual base class.
24618bool
24620{return priv_->is_virtual_;}
24621
24622/// Getter of the offset of the base.
24623///
24624/// @return the offset of the base.
24625long
24627{return priv_->offset_in_bits_;}
24628
24629/// Calculate the hash value for a class_decl::base_spec.
24630///
24631/// @return the hash value.
24632size_t
24634{
24636 return h(*this);
24637}
24638
24639/// Traverses an instance of @ref class_decl::base_spec, visiting all
24640/// the sub-types and decls that it might contain.
24641///
24642/// @param v the visitor that is used to visit every IR sub-node of
24643/// the current node.
24644///
24645/// @return true if either
24646/// - all the children nodes of the current IR node were traversed
24647/// and the calling code should keep going with the traversing.
24648/// - or the current IR node is already being traversed.
24649/// Otherwise, returning false means that the calling code should not
24650/// keep traversing the tree.
24651bool
24653{
24654 if (visiting())
24655 return true;
24656
24657 if (v.visit_begin(this))
24658 {
24659 visiting(true);
24660 get_base_class()->traverse(v);
24661 visiting(false);
24662 }
24663
24664 return v.visit_end(this);
24665}
24666
24667/// Constructor for base_spec instances.
24668///
24669/// Note that this constructor is for clients that don't support RTTI
24670/// and that have a base class of type_base, but of dynamic type
24671/// class_decl.
24672///
24673/// @param base the base class to consider. Must be a pointer to an
24674/// instance of class_decl
24675///
24676/// @param a the access specifier of the base class.
24677///
24678/// @param offset_in_bits if positive or null, represents the offset
24679/// of the base in the layout of its containing type.. If negative,
24680/// means that the current base is not laid out in its containing type.
24681///
24682/// @param is_virtual if true, means that the current base class is
24683/// virtual in it's containing type.
24684class_decl::base_spec::base_spec(const type_base_sptr& base,
24686 long offset_in_bits,
24687 bool is_virtual)
24689 ABSTRACT_DECL_BASE),
24694 member_base(a),
24695 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
24696 offset_in_bits,
24697 is_virtual))
24698{
24700}
24701
24702class_decl::base_spec::~base_spec() = default;
24703
24704/// Compares two instances of @ref class_decl::base_spec.
24705///
24706/// If the two intances are different, set a bitfield to give some
24707/// insight about the kind of differences there are.
24708///
24709/// @param l the first artifact of the comparison.
24710///
24711/// @param r the second artifact of the comparison.
24712///
24713/// @param k a pointer to a bitfield that gives information about the
24714/// kind of changes there are between @p l and @p r. This one is set
24715/// iff @p k is non-null and the function returns false.
24716///
24717/// Please note that setting k to a non-null value does have a
24718/// negative performance impact because even if @p l and @p r are not
24719/// equal, the function keeps up the comparison in order to determine
24720/// the different kinds of ways in which they are different.
24721///
24722/// @return true if @p l equals @p r, false otherwise.
24723bool
24725 const class_decl::base_spec& r,
24726 change_kind* k)
24727{
24728 if (!l.member_base::operator==(r))
24729 {
24730 if (k)
24733 }
24734
24736}
24737
24738/// Comparison operator for @ref class_decl::base_spec.
24739///
24740/// @param other the instance of @ref class_decl::base_spec to compare
24741/// against.
24742///
24743/// @return true if the current instance of @ref class_decl::base_spec
24744/// equals @p other.
24745bool
24747{
24748 const class_decl::base_spec* o =
24749 dynamic_cast<const class_decl::base_spec*>(&other);
24750
24751 if (!o)
24752 return false;
24753
24754 return equals(*this, *o, 0);
24755}
24756
24757/// Comparison operator for @ref class_decl::base_spec.
24758///
24759/// @param other the instance of @ref class_decl::base_spec to compare
24760/// against.
24761///
24762/// @return true if the current instance of @ref class_decl::base_spec
24763/// equals @p other.
24764bool
24766{
24767 const class_decl::base_spec* o =
24768 dynamic_cast<const class_decl::base_spec*>(&other);
24769 if (!o)
24770 return false;
24771
24772 return operator==(static_cast<const decl_base&>(*o));
24773}
24774
24775mem_fn_context_rel::~mem_fn_context_rel()
24776{
24777}
24778
24779/// A constructor for instances of method_decl.
24780///
24781/// @param name the name of the method.
24782///
24783/// @param type the type of the method.
24784///
24785/// @param declared_inline whether the method was
24786/// declared inline or not.
24787///
24788/// @param locus the source location of the method.
24789///
24790/// @param linkage_name the mangled name of the method.
24791///
24792/// @param vis the visibility of the method.
24793///
24794/// @param bind the binding of the method.
24795method_decl::method_decl(const string& name,
24796 method_type_sptr type,
24797 bool declared_inline,
24798 const location& locus,
24799 const string& linkage_name,
24800 visibility vis,
24801 binding bind)
24803 METHOD_DECL
24804 | ABSTRACT_DECL_BASE
24805 |FUNCTION_DECL),
24806 decl_base(type->get_environment(), name, locus, linkage_name, vis),
24807 function_decl(name, static_pointer_cast<function_type>(type),
24808 declared_inline, locus, linkage_name, vis, bind)
24809{
24811 set_context_rel(new mem_fn_context_rel(0));
24812 set_member_function_is_const(*this, type->get_is_const());
24813}
24814
24815/// A constructor for instances of method_decl.
24816///
24817/// @param name the name of the method.
24818///
24819/// @param type the type of the method. Must be an instance of
24820/// method_type.
24821///
24822/// @param declared_inline whether the method was
24823/// declared inline or not.
24824///
24825/// @param locus the source location of the method.
24826///
24827/// @param linkage_name the mangled name of the method.
24828///
24829/// @param vis the visibility of the method.
24830///
24831/// @param bind the binding of the method.
24832method_decl::method_decl(const string& name,
24833 function_type_sptr type,
24834 bool declared_inline,
24835 const location& locus,
24836 const string& linkage_name,
24837 visibility vis,
24838 binding bind)
24839 : type_or_decl_base(type->get_environment(),
24840 METHOD_DECL
24841 | ABSTRACT_DECL_BASE
24842 | FUNCTION_DECL),
24843 decl_base(type->get_environment(), name, locus, linkage_name, vis),
24844 function_decl(name, static_pointer_cast<function_type>
24845 (dynamic_pointer_cast<method_type>(type)),
24846 declared_inline, locus, linkage_name, vis, bind)
24847{
24849 set_context_rel(new mem_fn_context_rel(0));
24850}
24851
24852/// A constructor for instances of method_decl.
24853///
24854/// @param name the name of the method.
24855///
24856/// @param type the type of the method. Must be an instance of
24857/// method_type.
24858///
24859/// @param declared_inline whether the method was
24860/// declared inline or not.
24861///
24862/// @param locus the source location of the method.
24863///
24864/// @param linkage_name the mangled name of the method.
24865///
24866/// @param vis the visibility of the method.
24867///
24868/// @param bind the binding of the method.
24869method_decl::method_decl(const string& name,
24870 type_base_sptr type,
24871 bool declared_inline,
24872 const location& locus,
24873 const string& linkage_name,
24874 visibility vis,
24875 binding bind)
24876 : type_or_decl_base(type->get_environment(),
24877 METHOD_DECL
24878 | ABSTRACT_DECL_BASE
24879 | FUNCTION_DECL),
24880 decl_base(type->get_environment(), name, locus, linkage_name, vis),
24881 function_decl(name, static_pointer_cast<function_type>
24882 (dynamic_pointer_cast<method_type>(type)),
24883 declared_inline, locus, linkage_name, vis, bind)
24884{
24886 set_context_rel(new mem_fn_context_rel(0));
24887}
24888
24889/// Set the linkage name of the method.
24890///
24891/// @param l the new linkage name of the method.
24892void
24894{
24895 string old_lname = get_linkage_name();
24897 // Update the linkage_name -> member function map of the containing
24898 // class declaration.
24899 if (!l.empty())
24900 {
24902 class_or_union_sptr cl = t->get_class_type();
24903 method_decl_sptr m(this, sptr_utils::noop_deleter());
24904 cl->priv_->mem_fns_map_[l] = m;
24905 if (!old_lname.empty() && l != old_lname)
24906 {
24907 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
24908 {
24909 ABG_ASSERT(m.get() == this);
24910 cl->priv_->mem_fns_map_.erase(old_lname);
24911 }
24912 }
24913 }
24914}
24915
24916method_decl::~method_decl()
24917{}
24918
24919const method_type_sptr
24921{
24922 method_type_sptr result;
24924 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
24925 return result;
24926}
24927
24928/// Set the containing class of a method_decl.
24929///
24930/// @param scope the new containing class_decl.
24931void
24932method_decl::set_scope(scope_decl* scope)
24933{
24934 if (!get_context_rel())
24935 set_context_rel(new mem_fn_context_rel(scope));
24936 else
24937 get_context_rel()->set_scope(scope);
24938}
24939
24940/// Equality operator for @ref method_decl_sptr.
24941///
24942/// This is a deep equality operator, as it compares the @ref
24943/// method_decl that is pointed-to by the smart pointer.
24944///
24945/// @param l the left-hand side argument of the equality operator.
24946///
24947/// @param r the righ-hand side argument of the equality operator.
24948///
24949/// @return true iff @p l equals @p r.
24950bool
24951operator==(const method_decl_sptr& l, const method_decl_sptr& r)
24952{
24953 if (l.get() == r.get())
24954 return true;
24955 if (!!l != !!r)
24956 return false;
24957
24958 return *l == *r;
24959}
24960
24961/// Inequality operator for @ref method_decl_sptr.
24962///
24963/// This is a deep equality operator, as it compares the @ref
24964/// method_decl that is pointed-to by the smart pointer.
24965///
24966/// @param l the left-hand side argument of the equality operator.
24967///
24968/// @param r the righ-hand side argument of the equality operator.
24969///
24970/// @return true iff @p l differs from @p r.
24971bool
24972operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
24973{return !operator==(l, r);}
24974
24975/// Test if a function_decl is actually a method_decl.
24976///
24977///@param d the @ref function_decl to consider.
24978///
24979/// @return the method_decl sub-object of @p d if inherits
24980/// a method_decl type.
24983{
24984 return dynamic_cast<method_decl*>
24985 (const_cast<type_or_decl_base*>(d));
24986}
24987
24988/// Test if a function_decl is actually a method_decl.
24989///
24990///@param d the @ref function_decl to consider.
24991///
24992/// @return the method_decl sub-object of @p d if inherits
24993/// a method_decl type.
24996{return is_method_decl(&d);}
24997
24998/// Test if a function_decl is actually a method_decl.
24999///
25000///@param d the @ref function_decl to consider.
25001///
25002/// @return the method_decl sub-object of @p d if inherits
25003/// a method_decl type.
25004method_decl_sptr
25006{return dynamic_pointer_cast<method_decl>(d);}
25007
25008/// A "less than" functor to sort a vector of instances of
25009/// method_decl that are virtual.
25010struct virtual_member_function_less_than
25011{
25012 /// The less than operator. First, it sorts the methods by their
25013 /// vtable index. If they have the same vtable index, it sorts them
25014 /// by the name of their ELF symbol. If they don't have elf
25015 /// symbols, it sorts them by considering their pretty
25016 /// representation.
25017 ///
25018 /// Note that this method expects virtual methods.
25019 ///
25020 /// @param f the first method to consider.
25021 ///
25022 /// @param s the second method to consider.
25023 ///
25024 /// @return true if method @p is less than method @s.
25025 bool
25026 operator()(const method_decl& f,
25027 const method_decl& s)
25028 {
25031
25032 ssize_t f_offset = get_member_function_vtable_offset(f);
25033 ssize_t s_offset = get_member_function_vtable_offset(s);
25034 if (f_offset != s_offset) return f_offset < s_offset;
25035
25036 string fn, sn;
25037 // Try the linkage names (important for destructors).
25038 fn = f.get_linkage_name();
25039 sn = s.get_linkage_name();
25040 if (fn != sn) return fn < sn;
25041
25042 // If the functions have symbols, then compare their symbol-id
25043 // string.
25044 elf_symbol_sptr f_sym = f.get_symbol();
25045 elf_symbol_sptr s_sym = s.get_symbol();
25046 if ((!f_sym) != (!s_sym)) return !f_sym;
25047 if (f_sym && s_sym)
25048 {
25049 fn = f_sym->get_id_string();
25050 sn = s_sym->get_id_string();
25051 if (fn != sn) return fn < sn;
25052 }
25053
25054 // None of the functions have symbols or linkage names that
25055 // distinguish them, so compare their pretty representation.
25058 if (fn != sn) return fn < sn;
25059
25060 /// If it's just the file paths that are different then sort them
25061 /// too.
25062 string fn_filepath, sn_filepath;
25063 unsigned line = 0, column = 0;
25064 location fn_loc = f.get_location(), sn_loc = s.get_location();
25065 if (fn_loc)
25066 fn_loc.expand(fn_filepath, line, column);
25067 if (sn_loc)
25068 sn_loc.expand(sn_filepath, line, column);
25069 return fn_filepath < sn_filepath;
25070 }
25071
25072 /// The less than operator. First, it sorts the methods by their
25073 /// vtable index. If they have the same vtable index, it sorts them
25074 /// by the name of their ELF symbol. If they don't have elf
25075 /// symbols, it sorts them by considering their pretty
25076 /// representation.
25077 ///
25078 /// Note that this method expects to take virtual methods.
25079 ///
25080 /// @param f the first method to consider.
25081 ///
25082 /// @param s the second method to consider.
25083 bool
25084 operator()(const method_decl_sptr f,
25085 const method_decl_sptr s)
25086 {return operator()(*f, *s);}
25087}; // end struct virtual_member_function_less_than
25088
25089/// Sort a vector of instances of virtual member functions.
25090///
25091/// @param mem_fns the vector of member functions to sort.
25092static void
25093sort_virtual_member_functions(class_decl::member_functions& mem_fns)
25094{
25095 virtual_member_function_less_than lt;
25096 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25097}
25098
25099/// Add a member function to the current instance of @ref class_or_union.
25100///
25101/// @param f a method_decl to add to the current class. This function
25102/// should not have been already added to a scope.
25103///
25104/// @param access the access specifier for the member function to add.
25105///
25106/// @param is_virtual if this is true then it means the function @p f
25107/// is a virtual function. That also means that the current instance
25108/// of @ref class_or_union is actually an instance of @ref class_decl.
25109///
25110/// @param vtable_offset the offset of the member function in the
25111/// virtual table. This parameter is taken into account only if @p
25112/// is_virtual is true.
25113///
25114/// @param is_static whether the member function is static.
25115///
25116/// @param is_ctor whether the member function is a constructor.
25117///
25118/// @param is_dtor whether the member function is a destructor.
25119///
25120/// @param is_const whether the member function is const.
25121void
25124 bool is_virtual,
25125 size_t vtable_offset,
25126 bool is_static, bool is_ctor,
25127 bool is_dtor, bool is_const)
25128{
25129 add_member_function(f, a, is_static, is_ctor,
25130 is_dtor, is_const);
25131
25132 if (class_decl* klass = is_class_type(this))
25133 {
25134 set_member_function_is_virtual(f, is_virtual);
25135 if (is_virtual)
25136 {
25137 set_member_function_vtable_offset(f, vtable_offset);
25138 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
25139 }
25140 }
25141}
25142
25143/// When a virtual member function has seen its virtualness set by
25144/// set_member_function_is_virtual(), this function ensures that the
25145/// member function is added to the specific vectors and maps of
25146/// virtual member function of its class.
25147///
25148/// @param method the method to fixup.
25149void
25150fixup_virtual_member_function(method_decl_sptr method)
25151{
25152 if (!method || !get_member_function_is_virtual(method))
25153 return;
25154
25155 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
25156
25157 class_decl::member_functions::const_iterator m;
25158 for (m = klass->priv_->virtual_mem_fns_.begin();
25159 m != klass->priv_->virtual_mem_fns_.end();
25160 ++m)
25161 if (m->get() == method.get()
25162 || (*m)->get_linkage_name() == method->get_linkage_name())
25163 break;
25164 if (m == klass->priv_->virtual_mem_fns_.end())
25165 klass->priv_->virtual_mem_fns_.push_back(method);
25166
25167 // Build or udpate the map that associates a vtable offset to the
25168 // number of virtual member functions that "point" to it.
25169 ssize_t voffset = get_member_function_vtable_offset(method);
25170 if (voffset == -1)
25171 return;
25172
25173 class_decl::virtual_mem_fn_map_type::iterator i =
25174 klass->priv_->virtual_mem_fns_map_.find(voffset);
25175 if (i == klass->priv_->virtual_mem_fns_map_.end())
25176 {
25177 class_decl::member_functions virtual_mem_fns_at_voffset;
25178 virtual_mem_fns_at_voffset.push_back(method);
25179 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
25180 }
25181 else
25182 {
25183 for (m = i->second.begin() ; m != i->second.end(); ++m)
25184 if (m->get() == method.get()
25185 || (*m)->get_linkage_name() == method->get_linkage_name())
25186 break;
25187 if (m == i->second.end())
25188 i->second.push_back(method);
25189 }
25190}
25191
25192/// Return true iff the class has no entity in its scope.
25193bool
25195{return priv_->bases_.empty() && has_no_member();}
25196
25197/// Test if the current instance of @ref class_decl has virtual member
25198/// functions.
25199///
25200/// @return true iff the current instance of @ref class_decl has
25201/// virtual member functions.
25202bool
25204{return !get_virtual_mem_fns().empty();}
25205
25206/// Test if the current instance of @ref class_decl has at least one
25207/// virtual base.
25208///
25209/// @return true iff the current instance of @ref class_decl has a
25210/// virtual member function.
25211bool
25213{
25214 for (base_specs::const_iterator b = get_base_specifiers().begin();
25215 b != get_base_specifiers().end();
25216 ++b)
25217 if ((*b)->get_is_virtual()
25218 || (*b)->get_base_class()->has_virtual_bases())
25219 return true;
25220
25221 return false;
25222}
25223
25224/// Test if the current instance has a vtable.
25225///
25226/// This is only valid for a C++ program.
25227///
25228/// Basically this function checks if the class has either virtual
25229/// functions, or virtual bases.
25230bool
25232{
25234 || has_virtual_bases())
25235 return true;
25236 return false;
25237}
25238
25239/// Get the highest vtable offset of all the virtual methods of the
25240/// class.
25241///
25242/// @return the highest vtable offset of all the virtual methods of
25243/// the class.
25244ssize_t
25246{
25247 ssize_t offset = -1;
25248 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
25249 get_virtual_mem_fns_map().begin();
25250 e != get_virtual_mem_fns_map().end();
25251 ++e)
25252 if (e->first > offset)
25253 offset = e->first;
25254
25255 return offset;
25256}
25257
25258/// Return the hash value for the current instance.
25259///
25260/// @return the hash value.
25261size_t
25263{
25264 class_decl::hash hash_class;
25265 return hash_class(this);
25266}
25267
25268/// Test if two methods are equal without taking their symbol or
25269/// linkage name into account.
25270///
25271/// @param f the first method.
25272///
25273/// @param s the second method.
25274///
25275/// @return true iff @p f equals @p s without taking their linkage
25276/// name or symbol into account.
25277static bool
25278methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
25279 const method_decl_sptr& s)
25280{
25281 method_decl_sptr first = f, second = s;
25282 elf_symbol_sptr saved_first_elf_symbol =
25283 first->get_symbol();
25284 elf_symbol_sptr saved_second_elf_symbol =
25285 second->get_symbol();
25286 interned_string saved_first_linkage_name =
25287 first->get_linkage_name();
25288 interned_string saved_second_linkage_name =
25289 second->get_linkage_name();
25290
25291 first->set_symbol(elf_symbol_sptr());
25292 first->set_linkage_name("");
25293 second->set_symbol(elf_symbol_sptr());
25294 second->set_linkage_name("");
25295
25296 bool equal = *first == *second;
25297
25298 first->set_symbol(saved_first_elf_symbol);
25299 first->set_linkage_name(saved_first_linkage_name);
25300 second->set_symbol(saved_second_elf_symbol);
25301 second->set_linkage_name(saved_second_linkage_name);
25302
25303 return equal;
25304}
25305
25306/// Test if a given method is equivalent to at least of other method
25307/// that is in a vector of methods.
25308///
25309/// Note that "equivalent" here means being equal without taking the
25310/// linkage name or the symbol of the methods into account.
25311///
25312/// This is a sub-routine of the 'equals' function that compares @ref
25313/// class_decl.
25314///
25315/// @param method the method to compare.
25316///
25317/// @param fns the vector of functions to compare @p method against.
25318///
25319/// @return true iff @p is equivalent to at least one method in @p
25320/// fns.
25321static bool
25322method_matches_at_least_one_in_vector(const method_decl_sptr& method,
25324{
25325 for (class_decl::member_functions::const_iterator i = fns.begin();
25326 i != fns.end();
25327 ++i)
25328 // Note that the comparison must be done in this order: method ==
25329 // *i This is to keep the consistency of the comparison. It's
25330 // important especially when doing type canonicalization. The
25331 // already canonicalize type is the left operand, and the type
25332 // being canonicalized is the right operand. This comes from the
25333 // code in type_base::get_canonical_type_for().
25334 if (methods_equal_modulo_elf_symbol(method, *i))
25335 return true;
25336
25337 return false;
25338}
25339
25340/// Cancel the canonical type that was propagated.
25341///
25342/// If we are in the process of comparing a type for the purpose of
25343/// canonicalization, and if that type has been the target of the
25344/// canonical type propagation optimization, then clear the propagated
25345/// canonical type. See @ref OnTheFlyCanonicalization for more about
25346/// the canonical type optimization
25347///
25348/// @param t the type to consider.
25349static bool
25350maybe_cancel_propagated_canonical_type(const class_or_union& t)
25351{
25352 const environment& env = t.get_environment();
25353 if (env.do_on_the_fly_canonicalization())
25354 if (is_type(&t)->priv_->canonical_type_propagated())
25355 {
25356 is_type(&t)->priv_->clear_propagated_canonical_type();
25357 env.priv_->remove_from_types_with_non_confirmed_propagated_ct(&t);
25358 return true;
25359 }
25360 return false;
25361}
25362
25363/// Compares two instances of @ref class_decl.
25364///
25365/// If the two intances are different, set a bitfield to give some
25366/// insight about the kind of differences there are.
25367///
25368/// @param l the first artifact of the comparison.
25369///
25370/// @param r the second artifact of the comparison.
25371///
25372/// @param k a pointer to a bitfield that gives information about the
25373/// kind of changes there are between @p l and @p r. This one is set
25374/// iff @p k is non-null and the function returns false.
25375///
25376/// Please note that setting k to a non-null value does have a
25377/// negative performance impact because even if @p l and @p r are not
25378/// equal, the function keeps up the comparison in order to determine
25379/// the different kinds of ways in which they are different.
25380///
25381/// @return true if @p l equals @p r, false otherwise.
25382bool
25384{
25385 {
25386 // First of all, let's see if these two types haven't already been
25387 // compared. If so, and if the result of the comparison has been
25388 // cached, let's just re-use it, rather than comparing them all
25389 // over again.
25390 bool result = false;
25391 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
25392 ABG_RETURN(result);
25393 }
25394
25395 // if one of the classes is declaration-only then we take a fast
25396 // path here.
25398 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
25399 static_cast<const class_or_union&>(r),
25400 k));
25401
25402 bool had_canonical_type = !!r.get_naked_canonical_type();
25403 bool result = true;
25404 if (!equals(static_cast<const class_or_union&>(l),
25405 static_cast<const class_or_union&>(r),
25406 k))
25407 {
25408 result = false;
25409 if (!k)
25410 ABG_RETURN(result);
25411 }
25412
25413 // If comparing the class_or_union 'part' of the type led to
25414 // canonical type propagation, then cancel that because it's too
25415 // early to do that at this point. We still need to compare bases
25416 // virtual members.
25417 if (!had_canonical_type)
25418 maybe_cancel_propagated_canonical_type(r);
25419
25421
25423
25424#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
25425
25426 // Compare bases.
25427 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
25428 {
25429 result = false;
25430 if (k)
25432 else
25433 RETURN(result);
25434 }
25435
25436 for (class_decl::base_specs::const_iterator
25437 b0 = l.get_base_specifiers().begin(),
25438 b1 = r.get_base_specifiers().begin();
25439 (b0 != l.get_base_specifiers().end()
25440 && b1 != r.get_base_specifiers().end());
25441 ++b0, ++b1)
25442 if (*b0 != *b1)
25443 {
25444 result = false;
25445 if (k)
25446 {
25447 if (!types_have_similar_structure((*b0)->get_base_class().get(),
25448 (*b1)->get_base_class().get()))
25450 else
25451 *k |= SUBTYPE_CHANGE_KIND;
25452 break;
25453 }
25454 RETURN(result);
25455 }
25456
25457 // Compare virtual member functions
25458
25459 // We look at the map that associates a given vtable offset to a
25460 // vector of virtual member functions that point to that offset.
25461 //
25462 // This is because there are cases where several functions can
25463 // point to the same virtual table offset.
25464 //
25465 // This is usually the case for virtual destructors. Even though
25466 // there can be only one virtual destructor declared in source
25467 // code, there are actually potentially up to three generated
25468 // functions for that destructor. Some of these generated
25469 // functions can be clones of other functions that are among those
25470 // generated ones. In any cases, they all have the same
25471 // properties, including the vtable offset property.
25472
25473 // So, there should be the same number of different vtable
25474 // offsets, the size of two maps must be equals.
25475 if (l.get_virtual_mem_fns_map().size()
25476 != r.get_virtual_mem_fns_map().size())
25477 {
25478 result = false;
25479 if (k)
25481 else
25482 RETURN(result);
25483 }
25484
25485 // Then, each virtual member function of a given vtable offset in
25486 // the first class type, must match an equivalent virtual member
25487 // function of a the same vtable offset in the second class type.
25488 //
25489 // By "match", I mean that the two virtual member function should
25490 // be equal if we don't take into account their symbol name or
25491 // their linkage name. This is because two destructor functions
25492 // clones (for instance) might have different linkage name, but
25493 // are still equivalent if their other properties are the same.
25494 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
25495 l.get_virtual_mem_fns_map().begin();
25496 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
25497 ++first_v_fn_entry)
25498 {
25499 unsigned voffset = first_v_fn_entry->first;
25500 const class_decl::member_functions& first_vfns =
25501 first_v_fn_entry->second;
25502
25503 const class_decl::virtual_mem_fn_map_type::const_iterator
25504 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
25505
25506 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
25507 {
25508 result = false;
25509 if (k)
25511 RETURN(result);
25512 }
25513
25514 const class_decl::member_functions& second_vfns =
25515 second_v_fn_entry->second;
25516
25517 bool matches = false;
25518 for (class_decl::member_functions::const_iterator i =
25519 first_vfns.begin();
25520 i != first_vfns.end();
25521 ++i)
25522 if (method_matches_at_least_one_in_vector(*i, second_vfns))
25523 {
25524 matches = true;
25525 break;
25526 }
25527
25528 if (!matches)
25529 {
25530 result = false;
25531 if (k)
25532 *k |= SUBTYPE_CHANGE_KIND;
25533 else
25534 RETURN(result);
25535 }
25536 }
25537
25538 RETURN(result);
25539#undef RETURN
25540}
25541
25542/// Copy a method of a class into a new class.
25543///
25544/// @param klass the class into which the method is to be copied.
25545///
25546/// @param method the method to copy into @p klass.
25547///
25548/// @return the resulting newly copied method.
25549method_decl_sptr
25550copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
25551{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
25552
25553/// Copy a method of a class into a new class.
25554///
25555/// @param klass the class into which the method is to be copied.
25556///
25557/// @param method the method to copy into @p klass.
25558///
25559/// @return the resulting newly copied method.
25560method_decl_sptr
25562{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
25563
25564/// Comparison operator for @ref class_decl.
25565///
25566/// @param other the instance of @ref class_decl to compare against.
25567///
25568/// @return true iff the current instance of @ref class_decl equals @p
25569/// other.
25570bool
25572{
25573 const class_decl* op = is_class_type(&other);
25574 if (!op)
25575 return false;
25576
25577 // If this is a decl-only type (and thus with no canonical type),
25578 // use the canonical type of the definition, if any.
25579 const class_decl *l = 0;
25581 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
25582 if (l == 0)
25583 l = this;
25584
25585 ABG_ASSERT(l);
25586
25587 // Likewise for the other type.
25588 const class_decl *r = 0;
25589 if (op->get_is_declaration_only())
25590 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
25591 if (r == 0)
25592 r = op;
25593
25594 ABG_ASSERT(r);
25595
25596 return try_canonical_compare(l, r);
25597}
25598
25599/// Equality operator for class_decl.
25600///
25601/// Re-uses the equality operator that takes a decl_base.
25602///
25603/// @param other the other class_decl to compare against.
25604///
25605/// @return true iff the current instance equals the other one.
25606bool
25608{
25609 const decl_base* o = is_decl(&other);
25610 if (!o)
25611 return false;
25612 return *this == *o;
25613}
25614
25615/// Equality operator for class_decl.
25616///
25617/// Re-uses the equality operator that takes a decl_base.
25618///
25619/// @param other the other class_decl to compare against.
25620///
25621/// @return true iff the current instance equals the other one.
25622bool
25624{
25625 const decl_base& o = other;
25626 return *this == o;
25627}
25628
25629/// Comparison operator for @ref class_decl.
25630///
25631/// @param other the instance of @ref class_decl to compare against.
25632///
25633/// @return true iff the current instance of @ref class_decl equals @p
25634/// other.
25635bool
25637{
25638 const decl_base& o = other;
25639 return *this == o;
25640}
25641
25642/// Turn equality of shared_ptr of class_decl into a deep equality;
25643/// that is, make it compare the pointed to objects too.
25644///
25645/// @param l the shared_ptr of class_decl on left-hand-side of the
25646/// equality.
25647///
25648/// @param r the shared_ptr of class_decl on right-hand-side of the
25649/// equality.
25650///
25651/// @return true if the class_decl pointed to by the shared_ptrs are
25652/// equal, false otherwise.
25653bool
25655{
25656 if (l.get() == r.get())
25657 return true;
25658 if (!!l != !!r)
25659 return false;
25660
25661 return *l == *r;
25662}
25663
25664/// Turn inequality of shared_ptr of class_decl into a deep equality;
25665/// that is, make it compare the pointed to objects too.
25666///
25667/// @param l the shared_ptr of class_decl on left-hand-side of the
25668/// equality.
25669///
25670/// @param r the shared_ptr of class_decl on right-hand-side of the
25671/// equality.
25672///
25673/// @return true if the class_decl pointed to by the shared_ptrs are
25674/// different, false otherwise.
25675bool
25677{return !operator==(l, r);}
25678
25679/// Turn equality of shared_ptr of class_or_union into a deep
25680/// equality; that is, make it compare the pointed to objects too.
25681///
25682/// @param l the left-hand-side operand of the operator
25683///
25684/// @param r the right-hand-side operand of the operator.
25685///
25686/// @return true iff @p l equals @p r.
25687bool
25688operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
25689{
25690 if (l.get() == r.get())
25691 return true;
25692 if (!!l != !!r)
25693 return false;
25694
25695 return *l == *r;
25696}
25697
25698/// Turn inequality of shared_ptr of class_or_union into a deep
25699/// equality; that is, make it compare the pointed to objects too.
25700///
25701/// @param l the left-hand-side operand of the operator
25702///
25703/// @param r the right-hand-side operand of the operator.
25704///
25705/// @return true iff @p l is different from @p r.
25706bool
25707operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
25708{return !operator==(l, r);}
25709
25710/// This implements the ir_traversable_base::traverse pure virtual
25711/// function.
25712///
25713/// @param v the visitor used on the current instance and on its
25714/// members.
25715///
25716/// @return true if the entire IR node tree got traversed, false
25717/// otherwise.
25718bool
25720{
25721 if (v.type_node_has_been_visited(this))
25722 return true;
25723
25724 if (visiting())
25725 return true;
25726
25727 if (v.visit_begin(this))
25728 {
25729 visiting(true);
25730 bool stop = false;
25731
25732 for (base_specs::const_iterator i = get_base_specifiers().begin();
25733 i != get_base_specifiers().end();
25734 ++i)
25735 {
25736 if (!(*i)->traverse(v))
25737 {
25738 stop = true;
25739 break;
25740 }
25741 }
25742
25743 if (!stop)
25744 for (data_members::const_iterator i = get_data_members().begin();
25745 i != get_data_members().end();
25746 ++i)
25747 if (!(*i)->traverse(v))
25748 {
25749 stop = true;
25750 break;
25751 }
25752
25753 if (!stop)
25754 for (member_functions::const_iterator i= get_member_functions().begin();
25755 i != get_member_functions().end();
25756 ++i)
25757 if (!(*i)->traverse(v))
25758 {
25759 stop = true;
25760 break;
25761 }
25762
25763 if (!stop)
25764 for (member_types::const_iterator i = get_member_types().begin();
25765 i != get_member_types().end();
25766 ++i)
25767 if (!(*i)->traverse(v))
25768 {
25769 stop = true;
25770 break;
25771 }
25772
25773 if (!stop)
25774 for (member_function_templates::const_iterator i =
25776 i != get_member_function_templates().end();
25777 ++i)
25778 if (!(*i)->traverse(v))
25779 {
25780 stop = true;
25781 break;
25782 }
25783
25784 if (!stop)
25785 for (member_class_templates::const_iterator i =
25787 i != get_member_class_templates().end();
25788 ++i)
25789 if (!(*i)->traverse(v))
25790 {
25791 stop = true;
25792 break;
25793 }
25794 visiting(false);
25795 }
25796
25797 bool result = v.visit_end(this);
25799 return result;
25800}
25801
25802/// Destructor of the @ref class_decl type.
25804{delete priv_;}
25805
25806context_rel::~context_rel()
25807{}
25808
25809bool
25810member_base::operator==(const member_base& o) const
25811{
25813 && get_is_static() == o.get_is_static());
25814}
25815
25816/// Equality operator for smart pointers to @ref
25817/// class_decl::base_specs.
25818///
25819/// This compares the pointed-to objects.
25820///
25821/// @param l the first instance to consider.
25822///
25823/// @param r the second instance to consider.
25824///
25825/// @return true iff @p l equals @p r.
25826bool
25829{
25830 if (l.get() == r.get())
25831 return true;
25832 if (!!l != !!r)
25833 return false;
25834
25835 return *l == static_cast<const decl_base&>(*r);
25836}
25837
25838/// Inequality operator for smart pointers to @ref
25839/// class_decl::base_specs.
25840///
25841/// This compares the pointed-to objects.
25842///
25843/// @param l the first instance to consider.
25844///
25845/// @param r the second instance to consider.
25846///
25847/// @return true iff @p l is different from @p r.
25848bool
25851{return !operator==(l, r);}
25852
25853/// Test if an ABI artifact is a class base specifier.
25854///
25855/// @param tod the ABI artifact to consider.
25856///
25857/// @return a pointer to the @ref class_decl::base_spec sub-object of
25858/// @p tod iff it's a class base specifier.
25861{
25862 return dynamic_cast<class_decl::base_spec*>
25863 (const_cast<type_or_decl_base*>(tod));
25864}
25865
25866/// Test if an ABI artifact is a class base specifier.
25867///
25868/// @param tod the ABI artifact to consider.
25869///
25870/// @return a pointer to the @ref class_decl::base_spec sub-object of
25871/// @p tod iff it's a class base specifier.
25874{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
25875
25876bool
25877member_function_template::operator==(const member_base& other) const
25878{
25879 try
25880 {
25881 const member_function_template& o =
25882 dynamic_cast<const member_function_template&>(other);
25883
25884 if (!(is_constructor() == o.is_constructor()
25885 && is_const() == o.is_const()
25886 && member_base::operator==(o)))
25887 return false;
25888
25889 if (function_tdecl_sptr ftdecl = as_function_tdecl())
25890 {
25891 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
25892 if (other_ftdecl)
25893 return ftdecl->function_tdecl::operator==(*other_ftdecl);
25894 }
25895 }
25896 catch(...)
25897 {}
25898 return false;
25899}
25900
25901/// Equality operator for smart pointers to @ref
25902/// member_function_template. This is compares the
25903/// pointed-to instances.
25904///
25905/// @param l the first instance to consider.
25906///
25907/// @param r the second instance to consider.
25908///
25909/// @return true iff @p l equals @p r.
25910bool
25911operator==(const member_function_template_sptr& l,
25912 const member_function_template_sptr& r)
25913{
25914 if (l.get() == r.get())
25915 return true;
25916 if (!!l != !!r)
25917 return false;
25918
25919 return *l == *r;
25920}
25921
25922/// Inequality operator for smart pointers to @ref
25923/// member_function_template. This is compares the pointed-to
25924/// instances.
25925///
25926/// @param l the first instance to consider.
25927///
25928/// @param r the second instance to consider.
25929///
25930/// @return true iff @p l equals @p r.
25931bool
25932operator!=(const member_function_template_sptr& l,
25933 const member_function_template_sptr& r)
25934{return !operator==(l, r);}
25935
25936/// This implements the ir_traversable_base::traverse pure virtual
25937/// function.
25938///
25939/// @param v the visitor used on the current instance and on its
25940/// underlying function template.
25941///
25942/// @return true if the entire IR node tree got traversed, false
25943/// otherwise.
25944bool
25946{
25947 if (visiting())
25948 return true;
25949
25950 if (v.visit_begin(this))
25951 {
25952 visiting(true);
25953 if (function_tdecl_sptr f = as_function_tdecl())
25954 f->traverse(v);
25955 visiting(false);
25956 }
25957 return v.visit_end(this);
25958}
25959
25960/// Equality operator of the the @ref member_class_template class.
25961///
25962/// @param other the other @ref member_class_template to compare against.
25963///
25964/// @return true iff the current instance equals @p other.
25965bool
25967{
25968 try
25969 {
25970 const member_class_template& o =
25971 dynamic_cast<const member_class_template&>(other);
25972
25973 if (!member_base::operator==(o))
25974 return false;
25975
25976 return as_class_tdecl()->class_tdecl::operator==(o);
25977 }
25978 catch(...)
25979 {return false;}
25980}
25981
25982/// Equality operator of the the @ref member_class_template class.
25983///
25984/// @param other the other @ref member_class_template to compare against.
25985///
25986/// @return true iff the current instance equals @p other.
25987bool
25989{
25990 if (!decl_base::operator==(other))
25991 return false;
25992 return as_class_tdecl()->class_tdecl::operator==(other);
25993}
25994
25995/// Comparison operator for the @ref member_class_template
25996/// type.
25997///
25998/// @param other the other instance of @ref
25999/// member_class_template to compare against.
26000///
26001/// @return true iff the two instances are equal.
26002bool
26004{
26005 const decl_base* o = dynamic_cast<const decl_base*>(&other);
26006 return *this == *o;
26007}
26008
26009/// Comparison operator for the @ref member_class_template
26010/// type.
26011///
26012/// @param l the first argument of the operator.
26013///
26014/// @param r the second argument of the operator.
26015///
26016/// @return true iff the two instances are equal.
26017bool
26018operator==(const member_class_template_sptr& l,
26019 const member_class_template_sptr& r)
26020{
26021 if (l.get() == r.get())
26022 return true;
26023 if (!!l != !!r)
26024 return false;
26025
26026 return *l == *r;
26027}
26028
26029/// Inequality operator for the @ref member_class_template
26030/// type.
26031///
26032/// @param l the first argument of the operator.
26033///
26034/// @param r the second argument of the operator.
26035///
26036/// @return true iff the two instances are equal.
26037bool
26038operator!=(const member_class_template_sptr& l,
26039 const member_class_template_sptr& r)
26040{return !operator==(l, r);}
26041
26042/// This implements the ir_traversable_base::traverse pure virtual
26043/// function.
26044///
26045/// @param v the visitor used on the current instance and on the class
26046/// pattern of the template.
26047///
26048/// @return true if the entire IR node tree got traversed, false
26049/// otherwise.
26050bool
26052{
26053 if (visiting())
26054 return true;
26055
26056 if (v.visit_begin(this))
26057 {
26058 visiting(true);
26059 if (class_tdecl_sptr t = as_class_tdecl())
26060 t->traverse(v);
26061 visiting(false);
26062 }
26063 return v.visit_end(this);
26064}
26065
26066/// Streaming operator for class_decl::access_specifier.
26067///
26068/// @param o the output stream to serialize the access specifier to.
26069///
26070/// @param a the access specifier to serialize.
26071///
26072/// @return the output stream.
26073std::ostream&
26074operator<<(std::ostream& o, access_specifier a)
26075{
26076 string r;
26077
26078 switch (a)
26079 {
26080 case no_access:
26081 r = "none";
26082 break;
26083 case private_access:
26084 r = "private";
26085 break;
26086 case protected_access:
26087 r = "protected";
26088 break;
26089 case public_access:
26090 r= "public";
26091 break;
26092 };
26093 o << r;
26094 return o;
26095}
26096
26097/// Sets the static-ness property of a class member.
26098///
26099/// @param d the class member to set the static-ness property for.
26100/// Note that this must be a class member otherwise the function
26101/// aborts the current process.
26102///
26103/// @param s this must be true if the member is to be static, false
26104/// otherwise.
26105void
26107{
26109
26111 ABG_ASSERT(c);
26112
26113 c->set_is_static(s);
26114
26115 scope_decl* scope = d.get_scope();
26116
26117 if (class_or_union* cl = is_class_or_union_type(scope))
26118 {
26119 if (var_decl* v = is_var_decl(&d))
26120 {
26121 if (s)
26122 // remove from the non-static data members
26123 for (class_decl::data_members::iterator i =
26124 cl->priv_->non_static_data_members_.begin();
26125 i != cl->priv_->non_static_data_members_.end();
26126 ++i)
26127 {
26128 if ((*i)->get_name() == v->get_name())
26129 {
26130 cl->priv_->non_static_data_members_.erase(i);
26131 break;
26132 }
26133 }
26134 else
26135 {
26136 bool is_already_in_non_static_data_members = false;
26137 for (class_or_union::data_members::iterator i =
26138 cl->priv_->non_static_data_members_.begin();
26139 i != cl->priv_->non_static_data_members_.end();
26140 ++i)
26141 {
26142 if ((*i)->get_name() == v->get_name())
26143 {
26144 is_already_in_non_static_data_members = true;
26145 break;
26146 }
26147 }
26148 if (!is_already_in_non_static_data_members)
26149 {
26150 var_decl_sptr var;
26151 // add to non-static data members.
26152 for (class_or_union::data_members::const_iterator i =
26153 cl->priv_->data_members_.begin();
26154 i != cl->priv_->data_members_.end();
26155 ++i)
26156 {
26157 if ((*i)->get_name() == v->get_name())
26158 {
26159 var = *i;
26160 break;
26161 }
26162 }
26163 ABG_ASSERT(var);
26164 cl->priv_->non_static_data_members_.push_back(var);
26165 }
26166 }
26167 }
26168 }
26169}
26170
26171/// Sets the static-ness property of a class member.
26172///
26173/// @param d the class member to set the static-ness property for.
26174/// Note that this must be a class member otherwise the function
26175/// aborts the current process.
26176///
26177/// @param s this must be true if the member is to be static, false
26178/// otherwise.
26179void
26180set_member_is_static(const decl_base_sptr& d, bool s)
26181{set_member_is_static(*d, s);}
26182
26183// </class_decl>
26184
26185// <union_decl>
26186
26187/// Constructor for the @ref union_decl type.
26188///
26189/// @param env the @ref environment we are operating from.
26190///
26191/// @param name the name of the union type.
26192///
26193/// @param size_in_bits the size of the union, in bits.
26194///
26195/// @param locus the location of the type.
26196///
26197/// @param vis the visibility of instances of @ref union_decl.
26198///
26199/// @param mbr_types the member types of the union.
26200///
26201/// @param data_mbrs the data members of the union.
26202///
26203/// @param member_fns the member functions of the union.
26204union_decl::union_decl(const environment& env, const string& name,
26205 size_t size_in_bits, const location& locus,
26206 visibility vis, member_types& mbr_types,
26207 data_members& data_mbrs, member_functions& member_fns)
26208 : type_or_decl_base(env,
26209 UNION_TYPE
26210 | ABSTRACT_TYPE_BASE
26211 | ABSTRACT_DECL_BASE),
26212 decl_base(env, name, locus, name, vis),
26213 type_base(env, size_in_bits, 0),
26214 class_or_union(env, name, size_in_bits, 0,
26215 locus, vis, mbr_types, data_mbrs, member_fns)
26216{
26218}
26219
26220/// Constructor for the @ref union_decl type.
26221///
26222/// @param env the @ref environment we are operating from.
26223///
26224/// @param name the name of the union type.
26225///
26226/// @param size_in_bits the size of the union, in bits.
26227///
26228/// @param locus the location of the type.
26229///
26230/// @param vis the visibility of instances of @ref union_decl.
26231///
26232/// @param mbr_types the member types of the union.
26233///
26234/// @param data_mbrs the data members of the union.
26235///
26236/// @param member_fns the member functions of the union.
26237///
26238/// @param is_anonymous whether the newly created instance is
26239/// anonymous.
26240union_decl::union_decl(const environment& env, const string& name,
26241 size_t size_in_bits, const location& locus,
26242 visibility vis, member_types& mbr_types,
26243 data_members& data_mbrs, member_functions& member_fns,
26244 bool is_anonymous)
26245 : type_or_decl_base(env,
26246 UNION_TYPE
26247 | ABSTRACT_TYPE_BASE
26248 | ABSTRACT_DECL_BASE),
26249 decl_base(env, name, locus,
26250 // If the class is anonymous then by default it won't
26251 // have a linkage name. Also, the anonymous class does
26252 // have an internal-only unique name that is generally
26253 // not taken into account when comparing classes; such a
26254 // unique internal-only name, when used as a linkage
26255 // name might introduce spurious comparison false
26256 // negatives.
26257 /*linkage_name=*/is_anonymous ? string() : name,
26258 vis),
26259 type_base(env, size_in_bits, 0),
26260 class_or_union(env, name, size_in_bits, 0,
26261 locus, vis, mbr_types, data_mbrs, member_fns)
26262{
26264 set_is_anonymous(is_anonymous);
26265}
26266
26267/// Constructor for the @ref union_decl type.
26268///
26269/// @param env the @ref environment we are operating from.
26270///
26271/// @param name the name of the union type.
26272///
26273/// @param size_in_bits the size of the union, in bits.
26274///
26275/// @param locus the location of the type.
26276///
26277/// @param vis the visibility of instances of @ref union_decl.
26278union_decl::union_decl(const environment& env, const string& name,
26279 size_t size_in_bits, const location& locus,
26280 visibility vis)
26281 : type_or_decl_base(env,
26282 UNION_TYPE
26283 | ABSTRACT_TYPE_BASE
26284 | ABSTRACT_DECL_BASE
26285 | ABSTRACT_SCOPE_TYPE_DECL
26286 | ABSTRACT_SCOPE_DECL),
26287 decl_base(env, name, locus, name, vis),
26288 type_base(env, size_in_bits, 0),
26289 class_or_union(env, name, size_in_bits,
26290 0, locus, vis)
26291{
26293}
26294
26295/// Constructor for the @ref union_decl type.
26296///
26297/// @param env the @ref environment we are operating from.
26298///
26299/// @param name the name of the union type.
26300///
26301/// @param size_in_bits the size of the union, in bits.
26302///
26303/// @param locus the location of the type.
26304///
26305/// @param vis the visibility of instances of @ref union_decl.
26306///
26307/// @param is_anonymous whether the newly created instance is
26308/// anonymous.
26309union_decl::union_decl(const environment& env, const string& name,
26310 size_t size_in_bits, const location& locus,
26311 visibility vis, bool is_anonymous)
26312 : type_or_decl_base(env,
26313 UNION_TYPE
26314 | ABSTRACT_TYPE_BASE
26315 | ABSTRACT_DECL_BASE
26316 | ABSTRACT_SCOPE_TYPE_DECL
26317 | ABSTRACT_SCOPE_DECL),
26318 decl_base(env, name, locus,
26319 // If the class is anonymous then by default it won't
26320 // have a linkage name. Also, the anonymous class does
26321 // have an internal-only unique name that is generally
26322 // not taken into account when comparing classes; such a
26323 // unique internal-only name, when used as a linkage
26324 // name might introduce spurious comparison false
26325 // negatives.
26326 /*linkage_name=*/is_anonymous ? string() : name,
26327 vis),
26328 type_base(env, size_in_bits, 0),
26329 class_or_union(env, name, size_in_bits,
26330 0, locus, vis)
26331{
26333 set_is_anonymous(is_anonymous);
26334}
26335
26336/// Constructor for the @ref union_decl type.
26337///
26338/// @param env the @ref environment we are operating from.
26339///
26340/// @param name the name of the union type.
26341///
26342/// @param is_declaration_only a boolean saying whether the instance
26343/// represents a declaration only, or not.
26344union_decl::union_decl(const environment& env,
26345 const string& name,
26346 bool is_declaration_only)
26347 : type_or_decl_base(env,
26348 UNION_TYPE
26349 | ABSTRACT_TYPE_BASE
26350 | ABSTRACT_DECL_BASE
26351 | ABSTRACT_SCOPE_TYPE_DECL
26352 | ABSTRACT_SCOPE_DECL),
26353 decl_base(env, name, location(), name),
26354 type_base(env, 0, 0),
26355 class_or_union(env, name, is_declaration_only)
26356{
26358}
26359
26360/// Getter of the pretty representation of the current instance of
26361/// @ref union_decl.
26362///
26363/// @param internal set to true if the call is intended to get a
26364/// representation of the decl (or type) for the purpose of canonical
26365/// type comparison. This is mainly used in the function
26366/// type_base::get_canonical_type_for().
26367///
26368/// In other words if the argument for this parameter is true then the
26369/// call is meant for internal use (for technical use inside the
26370/// library itself), false otherwise. If you don't know what this is
26371/// for, then set it to false.
26372///
26373/// @param qualified_name if true, names emitted in the pretty
26374/// representation are fully qualified.
26375///
26376/// @return the pretty representaion for a union_decl.
26377string
26379 bool qualified_name) const
26380{
26381 string repr;
26382 if (get_is_anonymous())
26383 {
26384 if (internal && !get_name().empty())
26385 repr = string("union ") +
26386 get_type_name(this, qualified_name, /*internal=*/true);
26387 else
26389 /*one_line=*/true,
26390 internal);
26391 }
26392 else
26393 {
26394 repr = "union ";
26395 if (qualified_name)
26396 repr += get_qualified_name(internal);
26397 else
26398 repr += get_name();
26399 }
26400
26401 return repr;
26402}
26403
26404/// Comparison operator for @ref union_decl.
26405///
26406/// @param other the instance of @ref union_decl to compare against.
26407///
26408/// @return true iff the current instance of @ref union_decl equals @p
26409/// other.
26410bool
26412{
26413 const union_decl* op = dynamic_cast<const union_decl*>(&other);
26414 if (!op)
26415 return false;
26416 return try_canonical_compare(this, op);
26417}
26418
26419/// Equality operator for union_decl.
26420///
26421/// Re-uses the equality operator that takes a decl_base.
26422///
26423/// @param other the other union_decl to compare against.
26424///
26425/// @return true iff the current instance equals the other one.
26426bool
26428{
26429 const decl_base *o = dynamic_cast<const decl_base*>(&other);
26430 if (!o)
26431 return false;
26432 return *this == *o;
26433}
26434
26435/// Equality operator for union_decl.
26436///
26437/// Re-uses the equality operator that takes a decl_base.
26438///
26439/// @param other the other union_decl to compare against.
26440///
26441/// @return true iff the current instance equals the other one.
26442bool
26444{
26445 const decl_base *o = dynamic_cast<const decl_base*>(&other);
26446 return *this == *o;
26447}
26448
26449/// Comparison operator for @ref union_decl.
26450///
26451/// @param other the instance of @ref union_decl to compare against.
26452///
26453/// @return true iff the current instance of @ref union_decl equals @p
26454/// other.
26455bool
26457{
26458 const decl_base& o = other;
26459 return *this == o;
26460}
26461
26462/// This implements the ir_traversable_base::traverse pure virtual
26463/// function.
26464///
26465/// @param v the visitor used on the current instance and on its
26466/// members.
26467///
26468/// @return true if the entire IR node tree got traversed, false
26469/// otherwise.
26470bool
26472{
26473 if (v.type_node_has_been_visited(this))
26474 return true;
26475
26476 if (visiting())
26477 return true;
26478
26479 if (v.visit_begin(this))
26480 {
26481 visiting(true);
26482 bool stop = false;
26483
26484 if (!stop)
26485 for (data_members::const_iterator i = get_data_members().begin();
26486 i != get_data_members().end();
26487 ++i)
26488 if (!(*i)->traverse(v))
26489 {
26490 stop = true;
26491 break;
26492 }
26493
26494 if (!stop)
26495 for (member_functions::const_iterator i= get_member_functions().begin();
26496 i != get_member_functions().end();
26497 ++i)
26498 if (!(*i)->traverse(v))
26499 {
26500 stop = true;
26501 break;
26502 }
26503
26504 if (!stop)
26505 for (member_types::const_iterator i = get_member_types().begin();
26506 i != get_member_types().end();
26507 ++i)
26508 if (!(*i)->traverse(v))
26509 {
26510 stop = true;
26511 break;
26512 }
26513
26514 if (!stop)
26515 for (member_function_templates::const_iterator i =
26517 i != get_member_function_templates().end();
26518 ++i)
26519 if (!(*i)->traverse(v))
26520 {
26521 stop = true;
26522 break;
26523 }
26524
26525 if (!stop)
26526 for (member_class_templates::const_iterator i =
26528 i != get_member_class_templates().end();
26529 ++i)
26530 if (!(*i)->traverse(v))
26531 {
26532 stop = true;
26533 break;
26534 }
26535 visiting(false);
26536 }
26537
26538 bool result = v.visit_end(this);
26540 return result;
26541}
26542
26543/// Destructor of the @ref union_decl type.
26545{}
26546
26547/// Compares two instances of @ref union_decl.
26548///
26549/// If the two intances are different, set a bitfield to give some
26550/// insight about the kind of differences there are.
26551///
26552/// @param l the first artifact of the comparison.
26553///
26554/// @param r the second artifact of the comparison.
26555///
26556/// @param k a pointer to a bitfield that gives information about the
26557/// kind of changes there are between @p l and @p r. This one is set
26558/// iff @p k is non-null and the function returns false.
26559///
26560/// Please note that setting k to a non-null value does have a
26561/// negative performance impact because even if @p l and @p r are not
26562/// equal, the function keeps up the comparison in order to determine
26563/// the different kinds of ways in which they are different.
26564///
26565/// @return true if @p l equals @p r, false otherwise.
26566bool
26568{
26569
26571
26572 {
26573 // First of all, let's see if these two types haven't already been
26574 // compared. If so, and if the result of the comparison has been
26575 // cached, let's just re-use it, rather than comparing them all
26576 // over again.
26577 bool result = false;
26578 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
26579 ABG_RETURN(result);
26580 }
26581
26582 bool result = equals(static_cast<const class_or_union&>(l),
26583 static_cast<const class_or_union&>(r),
26584 k);
26585
26587}
26588
26589/// Copy a method of a @ref union_decl into a new @ref
26590/// union_decl.
26591///
26592/// @param t the @ref union_decl into which the method is to be copied.
26593///
26594/// @param method the method to copy into @p t.
26595///
26596/// @return the resulting newly copied method.
26597method_decl_sptr
26598copy_member_function(const union_decl_sptr& union_type,
26599 const method_decl_sptr& f)
26600{return copy_member_function(union_type, f.get());}
26601
26602/// Copy a method of a @ref union_decl into a new @ref
26603/// union_decl.
26604///
26605/// @param t the @ref union_decl into which the method is to be copied.
26606///
26607/// @param method the method to copy into @p t.
26608///
26609/// @return the resulting newly copied method.
26610method_decl_sptr
26611copy_member_function(const union_decl_sptr& union_type,
26612 const method_decl* f)
26613{
26614 const class_or_union_sptr t = union_type;
26615 return copy_member_function(t, f);
26616}
26617
26618/// Turn equality of shared_ptr of union_decl into a deep equality;
26619/// that is, make it compare the pointed to objects too.
26620///
26621/// @param l the left-hand-side operand of the operator
26622///
26623/// @param r the right-hand-side operand of the operator.
26624///
26625/// @return true iff @p l equals @p r.
26626bool
26627operator==(const union_decl_sptr& l, const union_decl_sptr& r)
26628{
26629 if (l.get() == r.get())
26630 return true;
26631 if (!!l != !!r)
26632 return false;
26633
26634 return *l == *r;
26635}
26636
26637/// Turn inequality of shared_ptr of union_decl into a deep equality;
26638/// that is, make it compare the pointed to objects too.
26639///
26640/// @param l the left-hand-side operand of the operator
26641///
26642/// @param r the right-hand-side operand of the operator.
26643///
26644/// @return true iff @p l is different from @p r.
26645bool
26646operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
26647{return !operator==(l, r);}
26648// </union_decl>
26649
26650// <template_decl stuff>
26651
26652/// Data type of the private data of the @template_decl type.
26653class template_decl::priv
26654{
26655 friend class template_decl;
26656
26657 std::list<template_parameter_sptr> parms_;
26658public:
26659
26660 priv()
26661 {}
26662}; // end class template_decl::priv
26663
26664/// Add a new template parameter to the current instance of @ref
26665/// template_decl.
26666///
26667/// @param p the new template parameter to add.
26668void
26670{priv_->parms_.push_back(p);}
26671
26672/// Get the list of template parameters of the current instance of
26673/// @ref template_decl.
26674///
26675/// @return the list of template parameters.
26676const std::list<template_parameter_sptr>&
26678{return priv_->parms_;}
26679
26680/// Constructor.
26681///
26682/// @param env the environment we are operating from.
26683///
26684/// @param name the name of the template decl.
26685///
26686/// @param locus the source location where the template declaration is
26687/// defined.
26688///
26689/// @param vis the visibility of the template declaration.
26690template_decl::template_decl(const environment& env,
26691 const string& name,
26692 const location& locus,
26693 visibility vis)
26694 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
26695 decl_base(env, name, locus, /*mangled_name=*/"", vis),
26696 priv_(new priv)
26697{
26699}
26700
26701/// Destructor.
26703{}
26704
26705/// Equality operator.
26706///
26707/// @param o the other instance to compare against.
26708///
26709/// @return true iff @p equals the current instance.
26710bool
26712{
26713 const template_decl* other = dynamic_cast<const template_decl*>(&o);
26714 if (!other)
26715 return false;
26716 return *this == *other;
26717}
26718
26719/// Equality operator.
26720///
26721/// @param o the other instance to compare against.
26722///
26723/// @return true iff @p equals the current instance.
26724bool
26726{
26727 try
26728 {
26729 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
26730 for (t0 = get_template_parameters().begin(),
26731 t1 = o.get_template_parameters().begin();
26732 (t0 != get_template_parameters().end()
26733 && t1 != o.get_template_parameters().end());
26734 ++t0, ++t1)
26735 {
26736 if (**t0 != **t1)
26737 return false;
26738 }
26739
26740 if (t0 != get_template_parameters().end()
26741 || t1 != o.get_template_parameters().end())
26742 return false;
26743
26744 return true;
26745 }
26746 catch(...)
26747 {return false;}
26748}
26749
26750// </template_decl stuff>
26751
26752//<template_parameter>
26753
26754/// The type of the private data of the @ref template_parameter type.
26755class template_parameter::priv
26756{
26757 friend class template_parameter;
26758
26759 unsigned index_;
26760 template_decl_wptr template_decl_;
26761 mutable bool hashing_started_;
26762 mutable bool comparison_started_;
26763
26764 priv();
26765
26766public:
26767
26768 priv(unsigned index, template_decl_sptr enclosing_template_decl)
26769 : index_(index),
26770 template_decl_(enclosing_template_decl),
26771 hashing_started_(),
26772 comparison_started_()
26773 {}
26774}; // end class template_parameter::priv
26775
26776template_parameter::template_parameter(unsigned index,
26777 template_decl_sptr enclosing_template)
26778 : priv_(new priv(index, enclosing_template))
26779 {}
26780
26781unsigned
26782template_parameter::get_index() const
26783{return priv_->index_;}
26784
26786template_parameter::get_enclosing_template_decl() const
26787{return priv_->template_decl_.lock();}
26788
26789bool
26790template_parameter::get_hashing_has_started() const
26791{return priv_->hashing_started_;}
26792
26793void
26794template_parameter::set_hashing_has_started(bool f) const
26795{priv_->hashing_started_ = f;}
26796
26797bool
26798template_parameter::operator==(const template_parameter& o) const
26799{
26800 if (get_index() != o.get_index())
26801 return false;
26802
26803 if (priv_->comparison_started_)
26804 return true;
26805
26806 bool result = false;
26807
26808 // Avoid inifite loops due to the fact that comparison the enclosing
26809 // template decl might lead to comparing this very same template
26810 // parameter with another one ...
26811 priv_->comparison_started_ = true;
26812
26813 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
26814 ;
26815 else if (get_enclosing_template_decl()
26816 && (*get_enclosing_template_decl()
26817 != *o.get_enclosing_template_decl()))
26818 ;
26819 else
26820 result = true;
26821
26822 priv_->comparison_started_ = false;
26823
26824 return result;
26825}
26826
26827/// Inequality operator.
26828///
26829/// @param other the other instance to compare against.
26830///
26831/// @return true iff the other instance is different from the current
26832/// one.
26833bool
26835{return !operator==(other);}
26836
26837/// Destructor.
26839{}
26840
26841/// The type of the private data of the @ref type_tparameter type.
26842class type_tparameter::priv
26843{
26844 friend class type_tparameter;
26845}; // end class type_tparameter::priv
26846
26847/// Constructor of the @ref type_tparameter type.
26848///
26849/// @param index the index the type template parameter.
26850///
26851/// @param enclosing_tdecl the enclosing template declaration.
26852///
26853/// @param name the name of the template parameter.
26854///
26855/// @param locus the location of the declaration of this type template
26856/// parameter.
26857type_tparameter::type_tparameter(unsigned index,
26858 template_decl_sptr enclosing_tdecl,
26859 const string& name,
26860 const location& locus)
26861 : type_or_decl_base(enclosing_tdecl->get_environment(),
26862 ABSTRACT_DECL_BASE
26863 | ABSTRACT_TYPE_BASE
26864 | BASIC_TYPE),
26865 decl_base(enclosing_tdecl->get_environment(), name, locus),
26866 type_base(enclosing_tdecl->get_environment(), 0, 0),
26867 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
26868 template_parameter(index, enclosing_tdecl),
26869 priv_(new priv)
26870{
26872}
26873
26874/// Equality operator.
26875///
26876/// @param other the other template type parameter to compare against.
26877///
26878/// @return true iff @p other equals the current instance.
26879bool
26881{
26882 if (!type_decl::operator==(other))
26883 return false;
26884
26885 try
26886 {
26887 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26889 }
26890 catch (...)
26891 {return false;}
26892}
26893
26894/// Equality operator.
26895///
26896/// @param other the other template type parameter to compare against.
26897///
26898/// @return true iff @p other equals the current instance.
26899bool
26901{
26902 if (!type_decl::operator==(other))
26903 return false;
26904
26905 try
26906 {
26907 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26909 }
26910 catch (...)
26911 {return false;}
26912}
26913
26914/// Equality operator.
26915///
26916/// @param other the other template type parameter to compare against.
26917///
26918/// @return true iff @p other equals the current instance.
26919bool
26921{
26922 if (!decl_base::operator==(other))
26923 return false;
26924
26925 try
26926 {
26927 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26929 }
26930 catch (...)
26931 {return false;}
26932}
26933
26934/// Equality operator.
26935///
26936/// @param other the other template type parameter to compare against.
26937///
26938/// @return true iff @p other equals the current instance.
26939bool
26941{
26942 try
26943 {
26944 const type_base& o = dynamic_cast<const type_base&>(other);
26945 return *this == o;
26946 }
26947 catch(...)
26948 {return false;}
26949}
26950
26951/// Equality operator.
26952///
26953/// @param other the other template type parameter to compare against.
26954///
26955/// @return true iff @p other equals the current instance.
26956bool
26958{return *this == static_cast<const type_base&>(other);}
26959
26960type_tparameter::~type_tparameter()
26961{}
26962
26963/// The type of the private data of the @ref non_type_tparameter type.
26964class non_type_tparameter::priv
26965{
26966 friend class non_type_tparameter;
26967
26968 type_base_wptr type_;
26969
26970 priv();
26971
26972public:
26973
26974 priv(type_base_sptr type)
26975 : type_(type)
26976 {}
26977}; // end class non_type_tparameter::priv
26978
26979/// The constructor for the @ref non_type_tparameter type.
26980///
26981/// @param index the index of the template parameter.
26982///
26983/// @param enclosing_tdecl the enclosing template declaration that
26984/// holds this parameter parameter.
26985///
26986/// @param name the name of the template parameter.
26987///
26988/// @param type the type of the template parameter.
26989///
26990/// @param locus the location of the declaration of this template
26991/// parameter.
26992non_type_tparameter::non_type_tparameter(unsigned index,
26993 template_decl_sptr enclosing_tdecl,
26994 const string& name,
26995 type_base_sptr type,
26996 const location& locus)
26997 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
26998 decl_base(type->get_environment(), name, locus, ""),
26999 template_parameter(index, enclosing_tdecl),
27000 priv_(new priv(type))
27001{
27003}
27004
27005/// Getter for the type of the template parameter.
27006///
27007/// @return the type of the template parameter.
27008const type_base_sptr
27010{return priv_->type_.lock();}
27011
27012/// Get the hash value of the current instance.
27013///
27014/// @return the hash value.
27015size_t
27017{
27018 non_type_tparameter::hash hash_tparm;
27019 return hash_tparm(this);
27020}
27021
27022bool
27024{
27025 if (!decl_base::operator==(other))
27026 return false;
27027
27028 try
27029 {
27030 const non_type_tparameter& o =
27031 dynamic_cast<const non_type_tparameter&>(other);
27032 return (template_parameter::operator==(o)
27033 && get_type() == o.get_type());
27034 }
27035 catch(...)
27036 {return false;}
27037}
27038
27039bool
27041{
27042 try
27043 {
27044 const decl_base& o = dynamic_cast<const decl_base&>(other);
27045 return *this == o;
27046 }
27047 catch(...)
27048 {return false;}
27049}
27050
27051non_type_tparameter::~non_type_tparameter()
27052{}
27053
27054// <template_tparameter stuff>
27055
27056/// Type of the private data of the @ref template_tparameter type.
27057class template_tparameter::priv
27058{
27059}; //end class template_tparameter::priv
27060
27061/// Constructor for the @ref template_tparameter.
27062///
27063/// @param index the index of the template parameter.
27064///
27065/// @param enclosing_tdecl the enclosing template declaration.
27066///
27067/// @param name the name of the template parameter.
27068///
27069/// @param locus the location of the declaration of the template
27070/// parameter.
27071template_tparameter::template_tparameter(unsigned index,
27072 template_decl_sptr enclosing_tdecl,
27073 const string& name,
27074 const location& locus)
27075 : type_or_decl_base(enclosing_tdecl->get_environment(),
27076 ABSTRACT_DECL_BASE
27077 | ABSTRACT_TYPE_BASE
27078 | BASIC_TYPE),
27079 decl_base(enclosing_tdecl->get_environment(), name, locus),
27080 type_base(enclosing_tdecl->get_environment(), 0, 0),
27081 type_decl(enclosing_tdecl->get_environment(), name,
27082 0, 0, locus, name, VISIBILITY_DEFAULT),
27083 type_tparameter(index, enclosing_tdecl, name, locus),
27084 template_decl(enclosing_tdecl->get_environment(), name, locus),
27085 priv_(new priv)
27086{
27088}
27089
27090/// Equality operator.
27091///
27092/// @param other the other template parameter to compare against.
27093///
27094/// @return true iff @p other equals the current instance.
27095bool
27097{
27098 try
27099 {
27100 const template_tparameter& o =
27101 dynamic_cast<const template_tparameter&>(other);
27102 return (type_tparameter::operator==(o)
27104 }
27105 catch(...)
27106 {return false;}
27107}
27108
27109/// Equality operator.
27110///
27111/// @param other the other template parameter to compare against.
27112///
27113/// @return true iff @p other equals the current instance.
27114bool
27116{
27117 try
27118 {
27119 const template_tparameter& o =
27120 dynamic_cast<const template_tparameter&>(other);
27121 return (type_tparameter::operator==(o)
27123 }
27124 catch(...)
27125 {return false;}
27126}
27127
27128bool
27130{
27131 try
27132 {
27133 const template_tparameter& other =
27134 dynamic_cast<const template_tparameter&>(o);
27135 return *this == static_cast<const type_base&>(other);
27136 }
27137 catch(...)
27138 {return false;}
27139}
27140
27141bool
27143{
27144 try
27145 {
27146 const template_tparameter& other =
27147 dynamic_cast<const template_tparameter&>(o);
27148 return type_base::operator==(other);
27149 }
27150 catch(...)
27151 {return false;}
27152}
27153
27154template_tparameter::~template_tparameter()
27155{}
27156
27157// </template_tparameter stuff>
27158
27159// <type_composition stuff>
27160
27161/// The type of the private data of the @ref type_composition type.
27162class type_composition::priv
27163{
27164 friend class type_composition;
27165
27166 type_base_wptr type_;
27167
27168 // Forbid this.
27169 priv();
27170
27171public:
27172
27173 priv(type_base_wptr type)
27174 : type_(type)
27175 {}
27176}; //end class type_composition::priv
27177
27178/// Constructor for the @ref type_composition type.
27179///
27180/// @param index the index of the template type composition.
27181///
27182/// @param tdecl the enclosing template parameter that owns the
27183/// composition.
27184///
27185/// @param t the resulting type.
27186type_composition::type_composition(unsigned index,
27187 template_decl_sptr tdecl,
27188 type_base_sptr t)
27189 : type_or_decl_base(tdecl->get_environment(),
27190 ABSTRACT_DECL_BASE),
27191 decl_base(tdecl->get_environment(), "", location()),
27192 template_parameter(index, tdecl),
27193 priv_(new priv(t))
27194{
27196}
27197
27198/// Getter for the resulting composed type.
27199///
27200/// @return the composed type.
27201const type_base_sptr
27203{return priv_->type_.lock();}
27204
27205/// Setter for the resulting composed type.
27206///
27207/// @param t the composed type.
27208void
27210{priv_->type_ = t;}
27211
27212/// Get the hash value for the current instance.
27213///
27214/// @return the hash value.
27215size_t
27217{
27218 type_composition::hash hash_type_composition;
27219 return hash_type_composition(this);
27220}
27221
27222type_composition::~type_composition()
27223{}
27224
27225// </type_composition stuff>
27226
27227//</template_parameter stuff>
27228
27229// <function_template>
27230
27231class function_tdecl::priv
27232{
27233 friend class function_tdecl;
27234
27235 function_decl_sptr pattern_;
27236 binding binding_;
27237
27238 priv();
27239
27240public:
27241
27242 priv(function_decl_sptr pattern, binding bind)
27243 : pattern_(pattern), binding_(bind)
27244 {}
27245
27246 priv(binding bind)
27247 : binding_(bind)
27248 {}
27249}; // end class function_tdecl::priv
27250
27251/// Constructor for a function template declaration.
27252///
27253/// @param env the environment we are operating from.
27254///
27255/// @param locus the location of the declaration.
27256///
27257/// @param vis the visibility of the declaration. This is the
27258/// visibility the functions instantiated from this template are going
27259/// to have.
27260///
27261/// @param bind the binding of the declaration. This is the binding
27262/// the functions instantiated from this template are going to have.
27263function_tdecl::function_tdecl(const environment& env,
27264 const location& locus,
27265 visibility vis,
27266 binding bind)
27267 : type_or_decl_base(env,
27268 ABSTRACT_DECL_BASE
27269 | TEMPLATE_DECL
27270 | ABSTRACT_SCOPE_DECL),
27271 decl_base(env, "", locus, "", vis),
27272 template_decl(env, "", locus, vis),
27273 scope_decl(env, "", locus),
27274 priv_(new priv(bind))
27275{
27277}
27278
27279/// Constructor for a function template declaration.
27280///
27281/// @param pattern the pattern of the template.
27282///
27283/// @param locus the location of the declaration.
27284///
27285/// @param vis the visibility of the declaration. This is the
27286/// visibility the functions instantiated from this template are going
27287/// to have.
27288///
27289/// @param bind the binding of the declaration. This is the binding
27290/// the functions instantiated from this template are going to have.
27291function_tdecl::function_tdecl(function_decl_sptr pattern,
27292 const location& locus,
27293 visibility vis,
27294 binding bind)
27295 : type_or_decl_base(pattern->get_environment(),
27296 ABSTRACT_DECL_BASE
27297 | TEMPLATE_DECL
27298 | ABSTRACT_SCOPE_DECL),
27299 decl_base(pattern->get_environment(), pattern->get_name(), locus,
27300 pattern->get_name(), vis),
27301 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
27302 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
27303 priv_(new priv(pattern, bind))
27304{
27306}
27307
27308/// Set a new pattern to the function template.
27309///
27310/// @param p the new pattern.
27311void
27313{
27314 priv_->pattern_ = p;
27315 add_decl_to_scope(p, this);
27316 set_name(p->get_name());
27317}
27318
27319/// Get the pattern of the function template.
27320///
27321/// @return the pattern.
27324{return priv_->pattern_;}
27325
27326/// Get the binding of the function template.
27327///
27328/// @return the binding
27331{return priv_->binding_;}
27332
27333/// Comparison operator for the @ref function_tdecl type.
27334///
27335/// @param other the other instance of @ref function_tdecl to compare against.
27336///
27337/// @return true iff the two instance are equal.
27338bool
27340{
27341 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
27342 if (o)
27343 return *this == *o;
27344 return false;
27345}
27346
27347/// Comparison operator for the @ref function_tdecl type.
27348///
27349/// @param other the other instance of @ref function_tdecl to compare against.
27350///
27351/// @return true iff the two instance are equal.
27352bool
27354{
27355 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
27356 if (o)
27357 return *this == *o;
27358 return false;
27359}
27360
27361/// Comparison operator for the @ref function_tdecl type.
27362///
27363/// @param o the other instance of @ref function_tdecl to compare against.
27364///
27365/// @return true iff the two instance are equal.
27366bool
27368{
27369 if (!(get_binding() == o.get_binding()
27370 && template_decl::operator==(o)
27371 && scope_decl::operator==(o)
27372 && !!get_pattern() == !!o.get_pattern()))
27373 return false;
27374
27375 if (get_pattern())
27376 return (*get_pattern() == *o.get_pattern());
27377
27378 return true;
27379}
27380
27381/// This implements the ir_traversable_base::traverse pure virtual
27382/// function.
27383///
27384/// @param v the visitor used on the current instance and on the
27385/// function pattern of the template.
27386///
27387/// @return true if the entire IR node tree got traversed, false
27388/// otherwise.
27389bool
27391{
27392 if (visiting())
27393 return true;
27394
27395 if (!v.visit_begin(this))
27396 {
27397 visiting(true);
27398 if (get_pattern())
27399 get_pattern()->traverse(v);
27400 visiting(false);
27401 }
27402 return v.visit_end(this);
27403}
27404
27405function_tdecl::~function_tdecl()
27406{}
27407
27408// </function_template>
27409
27410// <class template>
27411
27412/// Type of the private data of the the @ref class_tdecl type.
27413class class_tdecl::priv
27414{
27415 friend class class_tdecl;
27416 class_decl_sptr pattern_;
27417
27418public:
27419
27420 priv()
27421 {}
27422
27423 priv(class_decl_sptr pattern)
27424 : pattern_(pattern)
27425 {}
27426}; // end class class_tdecl::priv
27427
27428/// Constructor for the @ref class_tdecl type.
27429///
27430/// @param env the environment we are operating from.
27431///
27432/// @param locus the location of the declaration of the class_tdecl
27433/// type.
27434///
27435/// @param vis the visibility of the instance of class instantiated
27436/// from this template.
27437class_tdecl::class_tdecl(const environment& env,
27438 const location& locus,
27439 visibility vis)
27440 : type_or_decl_base(env,
27441 ABSTRACT_DECL_BASE
27442 | TEMPLATE_DECL
27443 | ABSTRACT_SCOPE_DECL),
27444 decl_base(env, "", locus, "", vis),
27445 template_decl(env, "", locus, vis),
27446 scope_decl(env, "", locus),
27447 priv_(new priv)
27448{
27450}
27451
27452/// Constructor for the @ref class_tdecl type.
27453///
27454/// @param pattern The details of the class template. This must NOT be a
27455/// null pointer. If you really this to be null, please use the
27456/// constructor above instead.
27457///
27458/// @param locus the source location of the declaration of the type.
27459///
27460/// @param vis the visibility of the instances of class instantiated
27461/// from this template.
27462class_tdecl::class_tdecl(class_decl_sptr pattern,
27463 const location& locus,
27464 visibility vis)
27465 : type_or_decl_base(pattern->get_environment(),
27466 ABSTRACT_DECL_BASE
27467 | TEMPLATE_DECL
27468 | ABSTRACT_SCOPE_DECL),
27469 decl_base(pattern->get_environment(), pattern->get_name(),
27470 locus, pattern->get_name(), vis),
27471 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
27472 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
27473 priv_(new priv(pattern))
27474{
27476}
27477
27478/// Setter of the pattern of the template.
27479///
27480/// @param p the new template.
27481void
27483{
27484 priv_->pattern_ = p;
27485 add_decl_to_scope(p, this);
27486 set_name(p->get_name());
27487}
27488
27489/// Getter of the pattern of the template.
27490///
27491/// @return p the new template.
27494{return priv_->pattern_;}
27495
27496bool
27498{
27499 try
27500 {
27501 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
27502
27503 if (!(template_decl::operator==(o)
27504 && scope_decl::operator==(o)
27505 && !!get_pattern() == !!o.get_pattern()))
27506 return false;
27507
27508 if (!get_pattern() || !o.get_pattern())
27509 return true;
27510
27511 return get_pattern()->decl_base::operator==(*o.get_pattern());
27512 }
27513 catch(...) {}
27514 return false;
27515}
27516
27517bool
27519{
27520 try
27521 {
27522 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
27523 return *this == static_cast<const decl_base&>(o);
27524 }
27525 catch(...)
27526 {return false;}
27527}
27528
27529bool
27531{return *this == static_cast<const decl_base&>(o);}
27532
27533/// This implements the ir_traversable_base::traverse pure virtual
27534/// function.
27535///
27536/// @param v the visitor used on the current instance and on the class
27537/// pattern of the template.
27538///
27539/// @return true if the entire IR node tree got traversed, false
27540/// otherwise.
27541bool
27543{
27544 if (visiting())
27545 return true;
27546
27547 if (v.visit_begin(this))
27548 {
27549 visiting(true);
27550 if (class_decl_sptr pattern = get_pattern())
27551 pattern->traverse(v);
27552 visiting(false);
27553 }
27554 return v.visit_end(this);
27555}
27556
27557class_tdecl::~class_tdecl()
27558{}
27559
27560/// This visitor checks if a given type as non-canonicalized sub
27561/// types.
27562class non_canonicalized_subtype_detector : public ir::ir_node_visitor
27563{
27564 type_base* type_;
27565 type_base* has_non_canonical_type_;
27566
27567private:
27568 non_canonicalized_subtype_detector();
27569
27570public:
27571 non_canonicalized_subtype_detector(type_base* type)
27572 : type_(type),
27573 has_non_canonical_type_()
27574 {}
27575
27576 /// Return true if the visitor detected that there is a
27577 /// non-canonicalized sub-type.
27578 ///
27579 /// @return true if the visitor detected that there is a
27580 /// non-canonicalized sub-type.
27581 type_base*
27582 has_non_canonical_type() const
27583 {return has_non_canonical_type_;}
27584
27585 /// The intent of this visitor handler is to avoid looking into
27586 /// sub-types of member functions of the type we are traversing.
27587 bool
27588 visit_begin(function_decl* f)
27589 {
27590 // Do not look at sub-types of non-virtual member functions.
27591 if (is_member_function(f)
27593 return false;
27594 return true;
27595 }
27596
27597 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
27598 /// the 'has_non_canonical_type' flag. And in any case, when
27599 /// visiting a sub-type, do not visit its children nodes. So this
27600 /// function only goes to the level below the level of the top-most
27601 /// type.
27602 ///
27603 /// @return true if we are at the same level as the top-most type,
27604 /// otherwise return false.
27605 bool
27606 visit_begin(type_base* t)
27607 {
27608 if (t != type_)
27609 {
27610 if (!t->get_canonical_type())
27611 // We are looking a sub-type of 'type_' which has no
27612 // canonical type. So tada! we found one! Get out right
27613 // now with the trophy.
27614 has_non_canonical_type_ = t;
27615
27616 return false;
27617 }
27618 return true;
27619 }
27620
27621 /// When we are done visiting a sub-type, if it's been flagged as
27622 /// been non-canonicalized, then stop the traversing.
27623 ///
27624 /// Otherwise, keep going.
27625 ///
27626 /// @return false iff the sub-type that has been visited is
27627 /// non-canonicalized.
27628 bool
27629 visit_end(type_base* )
27630 {
27631 if (has_non_canonical_type_)
27632 return false;
27633 return true;
27634 }
27635}; //end class non_canonicalized_subtype_detector
27636
27637/// Test if a type has sub-types that are non-canonicalized.
27638///
27639/// @param t the type which sub-types to consider.
27640///
27641/// @return true if a type has sub-types that are non-canonicalized.
27642type_base*
27644{
27645 if (!t)
27646 return 0;
27647
27648 non_canonicalized_subtype_detector v(t.get());
27649 t->traverse(v);
27650 return v.has_non_canonical_type();
27651}
27652
27653/// Tests if the change of a given type effectively comes from just
27654/// its sub-types. That is, if the type has changed but its type name
27655/// hasn't changed, then the change of the type mostly likely is a
27656/// sub-type change.
27657///
27658/// @param t_v1 the first version of the type.
27659///
27660/// @param t_v2 the second version of the type.
27661///
27662/// @return true iff the type changed and the change is about its
27663/// sub-types.
27664bool
27665type_has_sub_type_changes(const type_base_sptr t_v1,
27666 const type_base_sptr t_v2)
27667{
27668 type_base_sptr t1 = strip_typedef(t_v1);
27669 type_base_sptr t2 = strip_typedef(t_v2);
27670
27671 string repr1 = get_pretty_representation(t1, /*internal=*/false),
27672 repr2 = get_pretty_representation(t2, /*internal=*/false);
27673 return (t1 != t2 && repr1 == repr2);
27674}
27675
27676/// Make sure that the life time of a given (smart pointer to a) type
27677/// is the same as the life time of the libabigail library.
27678///
27679/// @param t the type to consider.
27680void
27681keep_type_alive(type_base_sptr t)
27682{
27683 const environment& env = t->get_environment();
27684 env.priv_->extra_live_types_.push_back(t);
27685}
27686
27687/// Hash an ABI artifact that is either a type or a decl.
27688///
27689/// This function intends to provides the fastest possible hashing for
27690/// types and decls, while being completely correct.
27691///
27692/// Note that if the artifact is a type and if it has a canonical
27693/// type, the hash value is going to be the pointer value of the
27694/// canonical type. Otherwise, this function computes a hash value
27695/// for the type by recursively walking the type members. This last
27696/// code path is possibly *very* slow and should only be used when
27697/// only handful of types are going to be hashed.
27698///
27699/// If the artifact is a decl, then a combination of the hash of its
27700/// type and the hash of the other properties of the decl is computed.
27701///
27702/// @param tod the type or decl to hash.
27703///
27704/// @return the resulting hash value.
27705size_t
27707{
27708 size_t result = 0;
27709
27710 if (tod == 0)
27711 ;
27712 else if (const type_base* t = is_type(tod))
27713 result = hash_type(t);
27714 else if (const decl_base* d = is_decl(tod))
27715 {
27716 if (var_decl* v = is_var_decl(d))
27717 {
27718 ABG_ASSERT(v->get_type());
27719 size_t h = hash_type_or_decl(v->get_type());
27720 string repr = v->get_pretty_representation(/*internal=*/true);
27721 std::hash<string> hash_string;
27722 h = hashing::combine_hashes(h, hash_string(repr));
27723 result = h;
27724 }
27725 else if (function_decl* f = is_function_decl(d))
27726 {
27727 ABG_ASSERT(f->get_type());
27728 size_t h = hash_type_or_decl(f->get_type());
27729 string repr = f->get_pretty_representation(/*internal=*/true);
27730 std::hash<string> hash_string;
27731 h = hashing::combine_hashes(h, hash_string(repr));
27732 result = h;
27733 }
27735 {
27736 type_base_sptr parm_type = p->get_type();
27737 ABG_ASSERT(parm_type);
27738 std::hash<bool> hash_bool;
27739 std::hash<unsigned> hash_unsigned;
27740 size_t h = hash_type_or_decl(parm_type);
27741 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
27742 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
27743 result = h;
27744 }
27745 else if (class_decl::base_spec *bs = is_class_base_spec(d))
27746 {
27747 member_base::hash hash_member;
27748 std::hash<size_t> hash_size;
27749 std::hash<bool> hash_bool;
27750 type_base_sptr type = bs->get_base_class();
27751 size_t h = hash_type_or_decl(type);
27752 h = hashing::combine_hashes(h, hash_member(*bs));
27753 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
27754 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
27755 result = h;
27756 }
27757 else
27758 // This is a *really* *SLOW* path. If it shows up in a
27759 // performance profile, I bet it'd be a good idea to try to
27760 // avoid it altogether.
27761 result = d->get_hash();
27762 }
27763 else
27764 // We should never get here.
27765 abort();
27766 return result;
27767}
27768
27769/// Hash an ABI artifact that is either a type.
27770///
27771/// This function intends to provides the fastest possible hashing for
27772/// types while being completely correct.
27773///
27774/// Note that if the type artifact has a canonical type, the hash
27775/// value is going to be the pointer value of the canonical type.
27776/// Otherwise, this function computes a hash value for the type by
27777/// recursively walking the type members. This last code path is
27778/// possibly *very* slow and should only be used when only handful of
27779/// types are going to be hashed.
27780///
27781/// @param t the type or decl to hash.
27782///
27783/// @return the resulting hash value.
27784size_t
27786{return hash_as_canonical_type_or_constant(t);}
27787
27788/// Hash an ABI artifact that is either a type of a decl.
27789///
27790/// @param tod the ABI artifact to hash.
27791///
27792/// @return the hash value of the ABI artifact.
27793size_t
27795{return hash_type_or_decl(tod.get());}
27796
27797/// Test if a given type is allowed to be non canonicalized
27798///
27799/// This is a subroutine of hash_as_canonical_type_or_constant.
27800///
27801/// For now, the only types allowed to be non canonicalized in the
27802/// system are (typedefs & pointers to) decl-only class/union, the
27803/// void type and variadic parameter types.
27804///
27805/// @return true iff @p t is a one of the only types allowed to be
27806/// non-canonicalized in the system.
27807bool
27809{
27810 if (!t)
27811 return true;
27812
27813 return (// The IR nodes for the types below are unique across the
27814 // entire ABI corpus. Thus, no need to canonicalize them.
27815 // Maybe we could say otherwise and canonicalize them once
27816 // for all so that they can be removed from here.
27818
27819 // An IR node for the types below can be equal to several
27820 // other types (i.e, a decl-only type t equals a fully
27821 // defined type of the same name in ODR-supported
27822 // languages). Hence, they can't be given a canonical type.
27823 //
27824 // TODO: Maybe add a mode that would detect ODR violations
27825 // that would make a decl-only type co-exists with several
27826 // different definitions of the type in the ABI corpus.
27829 /*look_through_decl_only=*/true)
27831
27832}
27833
27834/// Test if a type is unique in the entire environment.
27835///
27836/// Examples of unique types are void, void* and variadic parameter
27837/// types.
27838///
27839/// @param t the type to test for.
27840///
27841/// @return true iff the type @p t is unique in the entire
27842/// environment.
27843bool
27844is_unique_type(const type_base_sptr& t)
27845{return is_unique_type(t.get());}
27846
27847/// Test if a type is unique in the entire environment.
27848///
27849/// Examples of unique types are void, void* and variadic parameter
27850/// types.
27851///
27852/// @param t the type to test for.
27853///
27854/// @return true iff the type @p t is unique in the entire
27855/// environment.
27856bool
27858{
27859 if (!t)
27860 return false;
27861
27862 const environment& env = t->get_environment();
27863 return (env.is_void_type(t)
27864 || env.is_void_pointer_type(t)
27865 || env.is_variadic_parameter_type(t));
27866}
27867
27868/// For a given type, return its exemplar type.
27869///
27870/// For a given type, its exemplar type is either its canonical type
27871/// or the canonical type of the definition type of a given
27872/// declaration-only type. If the neither of those two types exist,
27873/// then the exemplar type is the given type itself.
27874///
27875/// @param type the input to consider.
27876///
27877/// @return the exemplar type.
27878type_base*
27880{
27881 if (decl_base * decl = is_decl(type))
27882 {
27883 // Make sure we get the real definition of a decl-only type.
27884 decl = look_through_decl_only(decl);
27885 type = is_type(decl);
27886 ABG_ASSERT(type);
27887 }
27888 type_base *exemplar = type->get_naked_canonical_type();
27889 if (!exemplar)
27890 {
27891 // The type has no canonical type. Let's be sure that it's one
27892 // of those rare types that are allowed to be non canonicalized
27893 // in the system.
27894 exemplar = const_cast<type_base*>(type);
27896 }
27897 return exemplar;
27898}
27899
27900/// Test if a given type is allowed to be non canonicalized
27901///
27902/// This is a subroutine of hash_as_canonical_type_or_constant.
27903///
27904/// For now, the only types allowed to be non canonicalized in the
27905/// system are decl-only class/union and the void type.
27906///
27907/// @return true iff @p t is a one of the only types allowed to be
27908/// non-canonicalized in the system.
27909bool
27910is_non_canonicalized_type(const type_base_sptr& t)
27911{return is_non_canonicalized_type(t.get());}
27912
27913/// Hash a type by either returning the pointer value of its canonical
27914/// type or by returning a constant if the type doesn't have a
27915/// canonical type.
27916///
27917/// This is a subroutine of hash_type.
27918///
27919/// @param t the type to consider.
27920///
27921/// @return the hash value.
27922static size_t
27923hash_as_canonical_type_or_constant(const type_base *t)
27924{
27925 type_base *canonical_type = 0;
27926
27927 if (t)
27928 canonical_type = t->get_naked_canonical_type();
27929
27930 if (!canonical_type)
27931 {
27932 // If the type doesn't have a canonical type, maybe it's because
27933 // it's a declaration-only type? If that's the case, let's try
27934 // to get the canonical type of the definition of this
27935 // declaration.
27936 decl_base *decl = is_decl(t);
27937 if (decl
27938 && decl->get_is_declaration_only()
27940 {
27941 type_base *definition =
27943 ABG_ASSERT(definition);
27944 canonical_type = definition->get_naked_canonical_type();
27945 }
27946 }
27947
27948 if (canonical_type)
27949 return reinterpret_cast<size_t>(canonical_type);
27950
27951 // If we reached this point, it means we are seeing a
27952 // non-canonicalized type. It must be a decl-only class or a void
27953 // type, otherwise it means that for some weird reason, the type
27954 // hasn't been canonicalized. It should be!
27956
27957 return 0xDEADBABE;
27958}
27959
27960/// Test if the pretty representation of a given @ref function_decl is
27961/// lexicographically less then the pretty representation of another
27962/// @ref function_decl.
27963///
27964/// @param f the first @ref function_decl to consider for comparison.
27965///
27966/// @param s the second @ref function_decl to consider for comparison.
27967///
27968/// @return true iff the pretty representation of @p f is
27969/// lexicographically less than the pretty representation of @p s.
27970bool
27972{
27975
27976 if (fr != sr)
27977 return fr < sr;
27978
27979 fr = f.get_pretty_representation(/*internal=*/true),
27980 sr = s.get_pretty_representation(/*internal=*/true);
27981
27982 if (fr != sr)
27983 return fr < sr;
27984
27985 if (f.get_symbol())
27986 fr = f.get_symbol()->get_id_string();
27987 else if (!f.get_linkage_name().empty())
27988 fr = f.get_linkage_name();
27989
27990 if (s.get_symbol())
27991 sr = s.get_symbol()->get_id_string();
27992 else if (!s.get_linkage_name().empty())
27993 sr = s.get_linkage_name();
27994
27995 return fr < sr;
27996}
27997
27998/// Test if two types have similar structures, even though they are
27999/// (or can be) different.
28000///
28001/// const and volatile qualifiers are completely ignored.
28002///
28003/// typedef are resolved to their definitions; their names are ignored.
28004///
28005/// Two indirect types (pointers or references) have similar structure
28006/// if their underlying types are of the same kind and have the same
28007/// name. In the indirect types case, the size of the underlying type
28008/// does not matter.
28009///
28010/// Two direct types (i.e, non indirect) have a similar structure if
28011/// they have the same kind, name and size. Two class types have
28012/// similar structure if they have the same name, size, and if the
28013/// types of their data members have similar types.
28014///
28015/// @param first the first type to consider.
28016///
28017/// @param second the second type to consider.
28018///
28019/// @param indirect_type whether to do an indirect comparison
28020///
28021/// @return true iff @p first and @p second have similar structures.
28022bool
28023types_have_similar_structure(const type_base_sptr& first,
28024 const type_base_sptr& second,
28025 bool indirect_type)
28026{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
28027
28028/// Test if two types have similar structures, even though they are
28029/// (or can be) different.
28030///
28031/// const and volatile qualifiers are completely ignored.
28032///
28033/// typedef are resolved to their definitions; their names are ignored.
28034///
28035/// Two indirect types (pointers, references or arrays) have similar
28036/// structure if their underlying types are of the same kind and have
28037/// the same name. In the indirect types case, the size of the
28038/// underlying type does not matter.
28039///
28040/// Two direct types (i.e, non indirect) have a similar structure if
28041/// they have the same kind, name and size. Two class types have
28042/// similar structure if they have the same name, size, and if the
28043/// types of their data members have similar types.
28044///
28045/// @param first the first type to consider.
28046///
28047/// @param second the second type to consider.
28048///
28049/// @param indirect_type if true, then consider @p first and @p
28050/// second as being underlying types of indirect types. Meaning that
28051/// their size does not matter.
28052///
28053/// @return true iff @p first and @p second have similar structures.
28054bool
28056 const type_base* second,
28057 bool indirect_type)
28058{
28059 if (!!first != !!second)
28060 return false;
28061
28062 if (!first)
28063 return false;
28064
28065 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
28066 first = peel_qualified_or_typedef_type(first);
28067 second = peel_qualified_or_typedef_type(second);
28068
28069 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
28070 // various ty2 below cannot be null.
28071 if (typeid(*first) != typeid(*second))
28072 return false;
28073
28074 // Peel off matching pointers.
28075 if (const pointer_type_def* ty1 = is_pointer_type(first))
28076 {
28077 const pointer_type_def* ty2 = is_pointer_type(second);
28078 return types_have_similar_structure(ty1->get_pointed_to_type(),
28079 ty2->get_pointed_to_type(),
28080 /*indirect_type=*/true);
28081 }
28082
28083 // Peel off matching references.
28084 if (const reference_type_def* ty1 = is_reference_type(first))
28085 {
28086 const reference_type_def* ty2 = is_reference_type(second);
28087 if (ty1->is_lvalue() != ty2->is_lvalue())
28088 return false;
28089 return types_have_similar_structure(ty1->get_pointed_to_type(),
28090 ty2->get_pointed_to_type(),
28091 /*indirect_type=*/true);
28092 }
28093
28094 // Peel off matching pointer-to-member types.
28095 if (const ptr_to_mbr_type* ty1 = is_ptr_to_mbr_type(first))
28096 {
28097 const ptr_to_mbr_type* ty2 = is_ptr_to_mbr_type(second);
28098 return (types_have_similar_structure(ty1->get_member_type(),
28099 ty2->get_member_type(),
28100 /*indirect_type=*/true)
28101 && types_have_similar_structure(ty1->get_containing_type(),
28102 ty2->get_containing_type(),
28103 /*indirect_type=*/true));
28104 }
28105
28106 if (const type_decl* ty1 = is_type_decl(first))
28107 {
28108 const type_decl* ty2 = is_type_decl(second);
28109 if (!indirect_type)
28110 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28111 return false;
28112
28113 return ty1->get_name() == ty2->get_name();
28114 }
28115
28116 if (const enum_type_decl* ty1 = is_enum_type(first))
28117 {
28118 const enum_type_decl* ty2 = is_enum_type(second);
28119 if (!indirect_type)
28120 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
28121 return false;
28122
28123 return (get_name(ty1->get_underlying_type())
28124 == get_name(ty2->get_underlying_type()));
28125 }
28126
28127 if (const class_decl* ty1 = is_class_type(first))
28128 {
28129 const class_decl* ty2 = is_class_type(second);
28130 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28131 && ty1->get_name() != ty2->get_name())
28132 return false;
28133
28134 if (!indirect_type)
28135 {
28136 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
28137 || (ty1->get_non_static_data_members().size()
28138 != ty2->get_non_static_data_members().size()))
28139 return false;
28140
28141 for (class_or_union::data_members::const_iterator
28142 i = ty1->get_non_static_data_members().begin(),
28143 j = ty2->get_non_static_data_members().begin();
28144 (i != ty1->get_non_static_data_members().end()
28145 && j != ty2->get_non_static_data_members().end());
28146 ++i, ++j)
28147 {
28148 var_decl_sptr dm1 = *i;
28149 var_decl_sptr dm2 = *j;
28150 if (!types_have_similar_structure(dm1->get_type().get(),
28151 dm2->get_type().get(),
28152 indirect_type))
28153 return false;
28154 }
28155 }
28156
28157 return true;
28158 }
28159
28160 if (const union_decl* ty1 = is_union_type(first))
28161 {
28162 const union_decl* ty2 = is_union_type(second);
28163 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
28164 && ty1->get_name() != ty2->get_name())
28165 return false;
28166
28167 if (!indirect_type)
28168 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
28169
28170 return true;
28171 }
28172
28173 if (const array_type_def* ty1 = is_array_type(first))
28174 {
28175 const array_type_def* ty2 = is_array_type(second);
28176 // TODO: Handle int[5][2] vs int[2][5] better.
28177 if (!indirect_type)
28178 {
28179 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
28180 || ty1->get_dimension_count() != ty2->get_dimension_count())
28181 return false;
28182 }
28183
28184 if (!types_have_similar_structure(ty1->get_element_type(),
28185 ty2->get_element_type(),
28186 /*indirect_type=*/true))
28187 return false;
28188
28189 return true;
28190 }
28191
28192 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
28193 {
28195 if (ty1->get_upper_bound() != ty2->get_upper_bound()
28196 || ty1->get_lower_bound() != ty2->get_lower_bound()
28197 || ty1->get_language() != ty2->get_language()
28198 || !types_have_similar_structure(ty1->get_underlying_type(),
28199 ty2->get_underlying_type(),
28200 indirect_type))
28201 return false;
28202
28203 return true;
28204 }
28205
28206 if (const function_type* ty1 = is_function_type(first))
28207 {
28208 const function_type* ty2 = is_function_type(second);
28209 if (!types_have_similar_structure(ty1->get_return_type(),
28210 ty2->get_return_type(),
28211 indirect_type))
28212 return false;
28213
28214 if (ty1->get_parameters().size() != ty2->get_parameters().size())
28215 return false;
28216
28217 for (function_type::parameters::const_iterator
28218 i = ty1->get_parameters().begin(),
28219 j = ty2->get_parameters().begin();
28220 (i != ty1->get_parameters().end()
28221 && j != ty2->get_parameters().end());
28222 ++i, ++j)
28223 if (!types_have_similar_structure((*i)->get_type(),
28224 (*j)->get_type(),
28225 indirect_type))
28226 return false;
28227
28228 return true;
28229 }
28230
28231 // All kinds of type should have been handled at this point.
28233
28234 return false;
28235}
28236
28237/// Look for a data member of a given class, struct or union type and
28238/// return it.
28239///
28240/// The data member is designated by its name.
28241///
28242/// @param type the class, struct or union type to consider.
28243///
28244/// @param dm_name the name of the data member to lookup.
28245///
28246/// @return the data member iff it was found in @type or NULL if no
28247/// data member with that name was found.
28248const var_decl*
28250 const char* dm_name)
28251
28252{
28254 if (!cou)
28255 return 0;
28256
28257 return cou->find_data_member(dm_name).get();
28258}
28259
28260/// Look for a data member of a given class, struct or union type and
28261/// return it.
28262///
28263/// The data member is designated by its name.
28264///
28265/// @param type the class, struct or union type to consider.
28266///
28267/// @param dm the data member to lookup.
28268///
28269/// @return the data member iff it was found in @type or NULL if no
28270/// data member with that name was found.
28271const var_decl_sptr
28272lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
28273{
28274 class_or_union_sptr cou = is_class_or_union_type(type);
28275 if (!cou)
28276 return var_decl_sptr();
28277
28278 return cou->find_data_member(dm);
28279}
28280
28281/// Get the function parameter designated by its index.
28282///
28283/// Note that the first function parameter has index 0.
28284///
28285/// @param fun the function to consider.
28286///
28287/// @param parm_index the index of the function parameter to get.
28288///
28289/// @return the function parameter designated by its index, of NULL if
28290/// no function parameter with that index was found.
28293 unsigned parm_index)
28294{
28296 if (!fn)
28297 return 0;
28298
28299 const function_decl::parameters &parms = fn->get_type()->get_parameters();
28300 if (parms.size() <= parm_index)
28301 return 0;
28302
28303 return parms[parm_index].get();
28304}
28305
28306/// Build the internal name of the underlying type of an enum.
28307///
28308/// @param base_name the (unqualified) name of the enum the underlying
28309/// type is destined to.
28310///
28311/// @param is_anonymous true if the underlying type of the enum is to
28312/// be anonymous.
28313string
28315 bool is_anonymous,
28316 uint64_t size)
28317{
28318 std::ostringstream o;
28319
28320 if (is_anonymous)
28321 o << "unnamed-enum";
28322 else
28323 o << "enum-" << base_name;
28324
28325 o << "-underlying-type-" << size;
28326
28327 return o.str();
28328}
28329
28330/// Find the first data member of a class or union which name matches
28331/// a regular expression.
28332///
28333/// @param t the class or union to consider.
28334///
28335/// @param r the regular expression to consider.
28336///
28337/// @return the data member matched by @p r or nil if none was found.
28340 const regex::regex_t_sptr& r)
28341{
28342 for (auto data_member : t.get_data_members())
28343 {
28344 if (regex::match(r, data_member->get_name()))
28345 return data_member;
28346 }
28347
28348 return var_decl_sptr();
28349}
28350
28351/// Find the last data member of a class or union which name matches
28352/// a regular expression.
28353///
28354/// @param t the class or union to consider.
28355///
28356/// @param r the regular expression to consider.
28357///
28358/// @return the data member matched by @p r or nil if none was found.
28361 const regex::regex_t_sptr& regex)
28362{
28363 auto d = t.get_data_members().rbegin();
28364 auto e = t.get_data_members().rend();
28365 for (; d != e; ++d)
28366 {
28367 if (regex::match(regex, (*d)->get_name()))
28368 return *d;
28369 }
28370
28371 return var_decl_sptr();
28372}
28373
28374/// Emit the pretty representation of the parameters of a function
28375/// type.
28376///
28377/// @param fn_type the function type to consider.
28378///
28379/// @param o the output stream to emit the pretty representation to.
28380///
28381/// @param qualified if true, emit fully qualified names.
28382///
28383/// @param internal if true, then the result is to be used for the
28384/// purpose of type canonicalization.
28385static void
28386stream_pretty_representation_of_fn_parms(const function_type& fn_type,
28387 ostream& o, bool qualified,
28388 bool internal)
28389{
28390 o << "(";
28391 if (fn_type.get_parameters().empty())
28392 o << "void";
28393 else
28394 {
28395 type_base_sptr type;
28396 auto end = fn_type.get_parameters().end();
28397 auto first_parm = fn_type.get_first_non_implicit_parm();
28399 const environment& env = fn_type.get_environment();
28400 for (auto i = fn_type.get_first_non_implicit_parm(); i != end; ++i)
28401 {
28402 if (i != first_parm)
28403 o << ", ";
28404 parm = *i;
28405 type = parm->get_type();
28406 if (env.is_variadic_parameter_type(type))
28407 o << "...";
28408 else
28409 {
28410 if (internal)
28411 type = peel_typedef_type(type);
28412 o << get_type_name(type, qualified, internal);
28413 }
28414 }
28415 }
28416 o << ")";
28417}
28418
28419/// When constructing the name of a pointer to function type, add the
28420/// return type to the left of the existing type identifier, and the
28421/// parameters declarator to the right.
28422///
28423/// This function considers the name of the type as an expression.
28424///
28425/// The resulting type expr is going to be made of three parts:
28426/// left_expr inner_expr right_expr.
28427///
28428/// Suppose we want to build the type expression representing:
28429///
28430/// "an array of pointer to function taking a char parameter and
28431/// returning an int".
28432///
28433/// It's going to look like:
28434///
28435/// int(*a[])(char);
28436///
28437/// Suppose the caller of this function started to emit the inner
28438/// "a[]" part of the expression already. It thus calls this
28439/// function with that input "a[]" part. We consider that "a[]" as
28440/// the "type identifier".
28441///
28442/// So the inner_expr is going to be "(*a[])".
28443///
28444/// The left_expr part is "int". The right_expr part is "(char)".
28445///
28446/// In other words, this function adds the left_expr and right_expr to
28447/// the inner_expr. left_expr and right_expr are called "outer
28448/// pointer to function type expression".
28449///
28450/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28451/// array_declaration_name()
28452///
28453/// @param p the pointer to function type to consider.
28454///
28455/// @param input the type-id to use as the inner expression of the
28456/// overall pointer-to-function type expression
28457///
28458/// @param qualified if true then use qualified names in the resulting
28459/// type name.
28460///
28461/// @param internal if true then the resulting type name is going to
28462/// be used for type canonicalization purposes.
28463///
28464/// @return the name of the pointer to function type.
28465static string
28466add_outer_pointer_to_fn_type_expr(const type_base* p,
28467 const string& input,
28468 bool qualified, bool internal)
28469{
28470 if (!p)
28471 return "";
28472
28473 function_type_sptr pointed_to_fn;
28474 string star_or_ref;
28475
28476 if (const pointer_type_def* ptr = is_pointer_type(p))
28477 {
28478 pointed_to_fn = is_function_type(ptr->get_pointed_to_type());
28479 star_or_ref= "*";
28480 }
28481 else if (const reference_type_def* ref = is_reference_type(p))
28482 {
28483 star_or_ref = "&";
28484 pointed_to_fn = is_function_type(ref->get_pointed_to_type());
28485 }
28486
28487 if (!pointed_to_fn)
28488 return "";
28489
28490 std::ostringstream left, right, inner;
28491
28492 inner << "(" << star_or_ref << input << ")";
28493
28494 type_base_sptr type;
28495 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
28496 qualified, internal);
28497 type_base_sptr return_type =
28498 internal
28499 ? peel_typedef_type(pointed_to_fn->get_return_type())
28500 : pointed_to_fn->get_return_type();
28501
28502 string result;
28503
28504 if (is_npaf_type(return_type)
28505 || !(is_pointer_to_function_type(return_type)
28506 || is_pointer_to_array_type(return_type)))
28507 {
28508 if (return_type)
28509 left << get_type_name(return_type, qualified, internal);
28510 result = left.str() + " " + inner.str() + right.str();
28511 }
28512 else if (pointer_type_def_sptr p = is_pointer_to_function_type(return_type))
28513 {
28514 string inner_string = inner.str() + right.str();
28515 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
28516 qualified, internal);
28517 }
28518 else if (pointer_type_def_sptr p = is_pointer_to_array_type(return_type))
28519 {
28520 string inner_string = inner.str() + right.str();
28521 result = add_outer_pointer_to_array_type_expr(p, inner_string,
28522 qualified, internal);
28523 }
28524 else
28526
28527 return result;
28528}
28529
28530/// When constructing the name of a pointer to function type, add the
28531/// return type to the left of the existing type identifier, and the
28532/// parameters declarator to the right.
28533///
28534/// This function considers the name of the type as an expression.
28535///
28536/// The resulting type expr is going to be made of three parts:
28537/// left_expr inner_expr right_expr.
28538///
28539/// Suppose we want to build the type expression representing:
28540///
28541/// "an array of pointer to function taking a char parameter and
28542/// returning an int".
28543///
28544/// It's going to look like:
28545///
28546/// int(*a[])(char);
28547///
28548/// Suppose the caller of this function started to emit the inner
28549/// "a[]" part of the expression already. It thus calls this
28550/// function with that input "a[]" part. We consider that "a[]" as
28551/// the "type identifier".
28552///
28553/// So the inner_expr is going to be "(*a[])".
28554///
28555/// The left_expr part is "int". The right_expr part is "(char)".
28556///
28557/// In other words, this function adds the left_expr and right_expr to
28558/// the inner_expr. left_expr and right_expr are called "outer
28559/// pointer to function type expression".
28560///
28561/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28562/// array_declaration_name()
28563///
28564/// @param p the pointer to function type to consider.
28565///
28566/// @param input the type-id to use as the inner expression of the
28567/// overall pointer-to-function type expression
28568///
28569/// @param qualified if true then use qualified names in the resulting
28570/// type name.
28571///
28572/// @param internal if true then the resulting type name is going to
28573/// be used for type canonicalization purposes.
28574///
28575/// @return the name of the pointer to function type.
28576static string
28577add_outer_pointer_to_fn_type_expr(const type_base_sptr& p,
28578 const string& input,
28579 bool qualified, bool internal)
28580{return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
28581
28582/// When constructing the name of a pointer to array type, add the
28583/// array element type type to the left of the existing type
28584/// identifier, and the array declarator part to the right.
28585///
28586/// This function considers the name of the type as an expression.
28587///
28588/// The resulting type expr is going to be made of three parts:
28589/// left_expr inner_expr right_expr.
28590///
28591/// Suppose we want to build the type expression representing:
28592///
28593/// "a pointer to an array of int".
28594///
28595/// It's going to look like:
28596///
28597/// int(*foo)[];
28598///
28599/// Suppose the caller of this function started to emit the inner
28600/// "foo" part of the expression already. It thus calls this function
28601/// with that input "foo" part. We consider that "foo" as the "type
28602/// identifier".
28603///
28604/// So we are passed an input string that is "foo" and it's going to
28605/// be turned into the inner_expr part, which is going to be "(*foo)".
28606///
28607/// The left_expr part is "int". The right_expr part is "[]".
28608///
28609/// In other words, this function adds the left_expr and right_expr to
28610/// the inner_expr. left_expr and right_expr are called "outer
28611/// pointer to array type expression".
28612///
28613/// The model of this function was taken from the article "Reading C
28614/// type declaration", from Steve Friedl at
28615/// http://unixwiz.net/techtips/reading-cdecl.html.
28616///
28617/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28618/// array_declaration_name()
28619///
28620/// @param p the pointer to array type to consider.
28621///
28622/// @param input the type-id to start from as the inner part of the
28623/// final type name.
28624///
28625/// @param qualified if true then use qualified names in the resulting
28626/// type name.
28627///
28628/// @param internal if true then the resulting type name is going to
28629/// be used for type canonicalization purposes.
28630///
28631/// @return the name of the pointer to array type.
28632static string
28633add_outer_pointer_to_array_type_expr(const type_base* p,
28634 const string& input, bool qualified,
28635 bool internal)
28636{
28637 if (!p)
28638 return "";
28639
28640 string star_or_ref;
28641 type_base_sptr pointed_to_type;
28642
28643 if (const pointer_type_def *ptr = is_pointer_type(p))
28644 {
28645 pointed_to_type = ptr->get_pointed_to_type();
28646 star_or_ref = "*";
28647 }
28648 else if (const reference_type_def *ref = is_reference_type(p))
28649 {
28650 pointed_to_type = ref->get_pointed_to_type();
28651 star_or_ref = "&";
28652 }
28653
28654 array_type_def_sptr array = is_array_type(pointed_to_type);
28655 if (!array)
28656 return "";
28657
28658 std::ostringstream left, right, inner;
28659 inner << "(" << star_or_ref << input << ")";
28660 right << array->get_subrange_representation();
28661 string result;
28662
28663 type_base_sptr array_element_type = array->get_element_type();
28664
28665 if (is_npaf_type(array_element_type)
28666 || !(is_pointer_to_function_type(array_element_type)
28667 || is_pointer_to_array_type(array_element_type)))
28668 {
28669 left << get_type_name(array_element_type, qualified, internal);
28670 result = left.str() + inner.str() + right.str();
28671 }
28672 else if (pointer_type_def_sptr p =
28673 is_pointer_to_function_type(array_element_type))
28674 {
28675 string r = inner.str() + right.str();
28676 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
28677 }
28678 else if (pointer_type_def_sptr p =
28679 is_pointer_to_array_type(array_element_type))
28680 {
28681 string inner_string = inner.str() + right.str();
28682 result = add_outer_pointer_to_array_type_expr(p, inner_string,
28683 qualified, internal);
28684 }
28685 else
28687
28688 return result;
28689}
28690
28691/// When constructing the name of a pointer to array type, add the
28692/// array element type type to the left of the existing type
28693/// identifier, and the array declarator part to the right.
28694///
28695/// This function considers the name of the type as an expression.
28696///
28697/// The resulting type expr is going to be made of three parts:
28698/// left_expr inner_expr right_expr.
28699///
28700/// Suppose we want to build the type expression representing:
28701///
28702/// "a pointer to an array of int".
28703///
28704/// It's going to look like:
28705///
28706/// int(*foo)[];
28707///
28708/// Suppose the caller of this function started to emit the inner
28709/// "foo" part of the expression already. It thus calls this function
28710/// with that input "foo" part. We consider that "foo" as the "type
28711/// identifier".
28712///
28713/// So we are passed an input string that is "foo" and it's going to
28714/// be turned into the inner_expr part, which is going to be "(*foo)".
28715///
28716/// The left_expr part is "int". The right_expr part is "[]".
28717///
28718/// In other words, this function adds the left_expr and right_expr to
28719/// the inner_expr. left_expr and right_expr are called "outer
28720/// pointer to array type expression".
28721///
28722/// The model of this function was taken from the article "Reading C
28723/// type declaration", from Steve Friedl at
28724/// http://unixwiz.net/techtips/reading-cdecl.html.
28725///
28726/// This is a sub-routine of @ref pointer_declaration_name() and @ref
28727/// array_declaration_name()
28728///
28729/// @param p the pointer to array type to consider.
28730///
28731/// @param input the type-id to start from as the inner part of the
28732/// final type name.
28733///
28734/// @param qualified if true then use qualified names in the resulting
28735/// type name.
28736///
28737/// @param internal if true then the resulting type name is going to
28738/// be used for type canonicalization purposes.
28739///
28740/// @return the name of the pointer to array type.
28741static string
28742add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
28743 const string& input, bool qualified,
28744 bool internal)
28745{return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
28746 input, qualified, internal);}
28747
28748/// When constructing the name of a pointer to mebmer type, add the
28749/// return type to the left of the existing type identifier, and the
28750/// parameters declarator to the right.
28751///
28752/// This function considers the name of the type as an expression.
28753///
28754/// The resulting type expr is going to be made of three parts:
28755/// left_expr inner_expr right_expr.
28756///
28757/// Suppose we want to build the type expression representing:
28758///
28759/// "an array of pointer to member function (of a containing struct
28760/// X) taking a char parameter and returning an int".
28761///
28762/// It's going to look like:
28763///
28764/// int (X::* a[])(char);
28765///
28766/// Suppose the caller of this function started to emit the inner
28767/// "a[]" part of the expression already. It thus calls this
28768/// function with that input "a[]" part. We consider that "a[]" as
28769/// the "type identifier".
28770///
28771/// So the inner_expr is going to be "(X::* a[])".
28772///
28773/// The left_expr part is "int". The right_expr part is "(char)".
28774///
28775/// In other words, this function adds the left_expr and right_expr to
28776/// the inner_expr. left_expr and right_expr are called "outer
28777/// pointer to member type expression".
28778///
28779/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
28780///
28781/// @param p the pointer to member type to consider.
28782///
28783/// @param input the type-id to use as the inner expression of the
28784/// overall pointer-to-member type expression
28785///
28786/// @param qualified if true then use qualified names in the resulting
28787/// type name.
28788///
28789/// @param internal if true then the resulting type name is going to
28790/// be used for type canonicalization purposes.
28791///
28792/// @return the name of the pointer to member type.
28793static string
28794add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
28795 const string& input, bool qualified,
28796 bool internal)
28797{
28798 if (!p)
28799 return "";
28800
28801 std::ostringstream left, right, inner;
28802 string containing_type_name = get_type_name(p->get_containing_type(),
28803 qualified, internal);
28804 type_base_sptr mbr_type = p->get_member_type();
28805 string result;
28806 if (function_type_sptr fn_type = is_function_type(mbr_type))
28807 {
28808 inner << "(" << containing_type_name << "::*" << input << ")";
28809 stream_pretty_representation_of_fn_parms(*fn_type, right,
28810 qualified, internal);
28811 type_base_sptr return_type = fn_type->get_return_type();
28812 if (is_npaf_type(return_type)
28813 || !(is_pointer_to_function_type(return_type)
28814 || is_pointer_to_array_type(return_type)
28815 || is_pointer_to_ptr_to_mbr_type(return_type)
28816 || is_ptr_to_mbr_type(return_type)))
28817 {
28818 left << get_type_name(return_type, qualified, internal) << " ";;
28819 result = left.str() + inner.str() + right.str();
28820 }
28821 else if (pointer_type_def_sptr p = is_pointer_type(return_type))
28822 {
28823 string inner_str = inner.str() + right.str();
28824 result = pointer_declaration_name(p, inner_str, qualified, internal);
28825 }
28826 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(return_type))
28827 {
28828 string inner_str = inner.str() + right.str();
28829 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
28830 qualified, internal);
28831 }
28832 else
28834 }
28835 else if (ptr_to_mbr_type_sptr ptr_mbr_type = is_ptr_to_mbr_type(mbr_type))
28836 {
28837 inner << "(" << containing_type_name << "::*" << input << ")";
28838 stream_pretty_representation_of_fn_parms(*fn_type, right,
28839 qualified, internal);
28840 string inner_str = inner.str() + right.str();
28841 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
28842 qualified, internal);
28843 }
28844 else
28845 {
28846 left << get_type_name(p->get_member_type(), qualified, internal) << " ";
28847 inner << containing_type_name << "::*" << input;
28848 result = left.str()+ inner.str();
28849 }
28850
28851 return result;
28852}
28853
28854/// When constructing the name of a pointer to mebmer type, add the
28855/// return type to the left of the existing type identifier, and the
28856/// parameters declarator to the right.
28857///
28858/// This function considers the name of the type as an expression.
28859///
28860/// The resulting type expr is going to be made of three parts:
28861/// left_expr inner_expr right_expr.
28862///
28863/// Suppose we want to build the type expression representing:
28864///
28865/// "an array of pointer to member function (of a containing struct
28866/// X) taking a char parameter and returning an int".
28867///
28868/// It's going to look like:
28869///
28870/// int (X::* a[])(char);
28871///
28872/// Suppose the caller of this function started to emit the inner
28873/// "a[]" part of the expression already. It thus calls this
28874/// function with that input "a[]" part. We consider that "a[]" as
28875/// the "type identifier".
28876///
28877/// So the inner_expr is going to be "(X::* a[])".
28878///
28879/// The left_expr part is "int". The right_expr part is "(char)".
28880///
28881/// In other words, this function adds the left_expr and right_expr to
28882/// the inner_expr. left_expr and right_expr are called "outer
28883/// pointer to member type expression".
28884///
28885/// This is a sub-routine of @ref ptr_to_mbr_declaration_name().
28886///
28887/// @param p the pointer to member type to consider.
28888///
28889/// @param input the type-id to use as the inner expression of the
28890/// overall pointer-to-member type expression
28891///
28892/// @param qualified if true then use qualified names in the resulting
28893/// type name.
28894///
28895/// @param internal if true then the resulting type name is going to
28896/// be used for type canonicalization purposes.
28897///
28898/// @return the name of the pointer to member type.
28899static string
28900add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
28901 const string& input, bool qualified,
28902 bool internal)
28903{return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
28904
28905/// This adds the outer parts of a pointer to a pointer-to-member
28906/// expression.
28907///
28908/// Please read the comments of @ref add_outer_ptr_to_mbr_type_expr to
28909/// learn more about this function, which is similar.
28910///
28911/// This is a sub-routine of @ref pointer_declaration_name().
28912///
28913/// @param a pointer (or reference) to a pointer-to-member type.
28914///
28915/// @param input the inner type-id to add the outer parts to.
28916///
28917/// @param qualified if true then use qualified names in the resulting
28918/// type name.
28919///
28920/// @param internal if true then the resulting type name is going to
28921/// be used for type canonicalization purposes.
28922static string
28923add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
28924 const string& input, bool qualified,
28925 bool internal)
28926{
28927 if (!p)
28928 return "";
28929
28930 string star_or_ref;
28931 type_base_sptr pointed_to_type;
28932
28933 if (const pointer_type_def* ptr = is_pointer_type(p))
28934 {
28935 pointed_to_type = ptr->get_pointed_to_type();
28936 star_or_ref = "*";
28937 }
28938 else if (const reference_type_def* ref = is_reference_type(p))
28939 {
28940 pointed_to_type= ref->get_pointed_to_type();
28941 star_or_ref = "&";
28942 }
28943
28944 if (!pointed_to_type)
28945 return "";
28946
28947 ptr_to_mbr_type_sptr pointed_to_ptr_to_mbr =
28948 is_ptr_to_mbr_type(pointed_to_type);
28949 if (!pointed_to_ptr_to_mbr)
28950 return "";
28951
28952 std::ostringstream inner;
28953 inner << star_or_ref << input;
28954 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
28955 inner.str(),
28956 qualified, internal);
28957 return result;
28958}
28959
28960/// Emit the name of a pointer declaration.
28961///
28962/// @param the pointer to consider.
28963///
28964/// @param idname the name of the variable that has @p as a type or
28965/// the id of the type. If it's empty then the resulting name is
28966/// going to be the abstract name of the type.
28967///
28968/// @param qualified if true then the type name is going to be
28969/// fully qualified.
28970///
28971/// @param internal if true then the type name is going to be used for
28972/// type canonicalization purposes.
28973static interned_string
28974pointer_declaration_name(const type_base* ptr,
28975 const string& idname,
28976 bool qualified, bool internal)
28977{
28978 if (!ptr)
28979 return interned_string();
28980
28981 type_base_sptr pointed_to_type;
28982 string star_or_ref;
28983 if (const pointer_type_def* p = is_pointer_type(ptr))
28984 {
28985 pointed_to_type = p->get_pointed_to_type();
28986 star_or_ref = "*";
28987 }
28988 else if (const reference_type_def* p = is_reference_type(ptr))
28989 {
28990 pointed_to_type = p->get_pointed_to_type();
28991 star_or_ref = "&";
28992 }
28993
28994 if (!pointed_to_type)
28995 return interned_string();
28996
28997 string result;
28998 if (is_npaf_type(pointed_to_type)
28999 || !(is_function_type(pointed_to_type)
29000 || is_array_type(pointed_to_type)
29001 || is_ptr_to_mbr_type(pointed_to_type)))
29002 {
29003 result = get_type_name(pointed_to_type,
29004 qualified,
29005 internal)
29006 + star_or_ref;
29007
29008 if (!idname.empty())
29009 result += idname;
29010 }
29011 else
29012 {
29013 // derived type
29014 if (is_function_type(pointed_to_type))
29015 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
29016 qualified, internal);
29017 else if (is_array_type(pointed_to_type))
29018 result = add_outer_pointer_to_array_type_expr(ptr, idname,
29019 qualified, internal);
29020 else if (is_ptr_to_mbr_type(pointed_to_type))
29021 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
29022 qualified, internal);
29023 else
29025 }
29026 return ptr->get_environment().intern(result);
29027}
29028
29029
29030/// Emit the name of a pointer declaration.
29031///
29032/// @param the pointer to consider.
29033///
29034/// @param the name of the variable that has @p as a type. If it's
29035/// empty then the resulting name is going to be the abstract name of
29036/// the type.
29037///
29038/// @param qualified if true then the type name is going to be
29039/// fully qualified.
29040///
29041/// @param internal if true then the type name is going to be used for
29042/// type canonicalization purposes.
29043static interned_string
29044pointer_declaration_name(const type_base_sptr& ptr,
29045 const string& variable_name,
29046 bool qualified, bool internal)
29047{return pointer_declaration_name(ptr.get(), variable_name,
29048 qualified, internal);}
29049
29050/// Emit the name of a array declaration.
29051///
29052/// @param the array to consider.
29053///
29054/// @param the name of the variable that has @p as a type. If it's
29055/// empty then the resulting name is going to be the abstract name of
29056/// the type.
29057///
29058/// @param qualified if true then the type name is going to be
29059/// fully qualified.
29060///
29061/// @param internal if true then the type name is going to be used for
29062/// type canonicalization purposes.
29063static interned_string
29064array_declaration_name(const array_type_def* array,
29065 const string& variable_name,
29066 bool qualified, bool internal)
29067{
29068 if (!array)
29069 return interned_string();
29070
29071 type_base_sptr e_type = array->get_element_type();
29072 string e_type_repr =
29073 (e_type
29074 ? get_type_name(e_type, qualified, internal)
29075 : string("void"));
29076
29077 string result;
29078 if (is_ada_language(array->get_language()))
29079 {
29080 std::ostringstream o;
29081 if (!variable_name.empty())
29082 o << variable_name << " is ";
29083 o << "array ("
29084 << array->get_subrange_representation()
29085 << ") of " << e_type_repr;
29086 result = o.str();
29087 }
29088 else
29089 {
29090 if (is_npaf_type(e_type)
29091 || !(is_pointer_to_function_type(e_type)
29092 || is_pointer_to_array_type(e_type)
29094 || is_ptr_to_mbr_type(e_type)))
29095 {
29096 result = e_type_repr;
29097 if (!variable_name.empty())
29098 result += variable_name;
29099 result += array->get_subrange_representation();
29100 }
29101 else if (pointer_type_def_sptr p = is_pointer_type(e_type))
29102 {
29103 string s = variable_name + array->get_subrange_representation();
29104 result = pointer_declaration_name(p, s, qualified, internal);
29105 }
29106 else if (ptr_to_mbr_type_sptr p = is_ptr_to_mbr_type(e_type))
29107 {
29108 string s = variable_name + array->get_subrange_representation();
29109 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
29110 }
29111 else
29113 }
29114 return array->get_environment().intern(result);
29115}
29116
29117/// Emit the name of a array declaration.
29118///
29119/// @param the array to consider.
29120///
29121/// @param the name of the variable that has @p as a type. If it's
29122/// empty then the resulting name is going to be the abstract name of
29123/// the type.
29124///
29125/// @param qualified if true then the type name is going to be
29126/// fully qualified.
29127///
29128/// @param internal if true then the type name is going to be used for
29129/// type canonicalization purposes.
29130static interned_string
29131array_declaration_name(const array_type_def_sptr& array,
29132 const string& variable_name,
29133 bool qualified, bool internal)
29134{return array_declaration_name(array.get(), variable_name,
29135 qualified, internal);}
29136
29137/// Emit the name of a pointer-to-member declaration.
29138///
29139/// @param ptr the pointer-to-member to consider.
29140///
29141/// @param variable_name the name of the variable that has @p as a
29142/// type. If it's empty then the resulting name is going to be the
29143/// abstract name of the type.
29144///
29145/// @param qualified if true then the type name is going to be
29146/// fully qualified.
29147///
29148/// @param internal if true then the type name is going to be used for
29149/// type canonicalization purposes.
29150static interned_string
29151ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
29152 const string& variable_name,
29153 bool qualified, bool internal)
29154{
29155 if (!ptr)
29156 return interned_string();
29157
29158 string input = variable_name;
29159 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
29160 qualified, internal);
29161 return ptr->get_environment().intern(result);
29162}
29163
29164/// Emit the name of a pointer-to-member declaration.
29165///
29166/// @param ptr the pointer-to-member to consider.
29167///
29168/// @param variable_name the name of the variable that has @p as a
29169/// type. If it's empty then the resulting name is going to be the
29170/// abstract name of the type.
29171///
29172/// @param qualified if true then the type name is going to be
29173/// fully qualified.
29174///
29175/// @param internal if true then the type name is going to be used for
29176/// type canonicalization purposes.
29177static interned_string
29178ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
29179 const string& variable_name,
29180 bool qualified, bool internal)
29181{
29182 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
29183 qualified, internal);
29184}
29185
29186bool
29188{return true;}
29189
29190// <ir_node_visitor stuff>
29191
29192/// The private data structure of the ir_node_visitor type.
29193struct ir_node_visitor::priv
29194{
29195 pointer_set visited_ir_nodes;
29197
29198 priv()
29200 {}
29201}; // end struct ir_node_visitory::priv
29202
29203/// Default Constructor of the ir_node_visitor type.
29205 : priv_(new priv)
29206{}
29207
29208ir_node_visitor::~ir_node_visitor() = default;
29209
29210/// Set if the walker using this visitor is allowed to re-visit a type
29211/// node that was previously visited or not.
29212///
29213/// @param f if true, then the walker using this visitor is allowed to
29214/// re-visit a type node that was previously visited.
29215void
29217{priv_->allow_visiting_already_visited_type_node = f;}
29218
29219/// Get if the walker using this visitor is allowed to re-visit a type
29220/// node that was previously visited or not.
29221///
29222/// @return true iff the walker using this visitor is allowed to
29223/// re-visit a type node that was previously visited.
29224bool
29226{return priv_->allow_visiting_already_visited_type_node;}
29227
29228/// Mark a given type node as having been visited.
29229///
29230/// Note that for this function to work, the type node must have been
29231/// canonicalized. Otherwise the process is aborted.
29232///
29233/// @param p the type to mark as having been visited.
29234void
29236{
29238 return;
29239
29240 if (p == 0 || type_node_has_been_visited(p))
29241 return;
29242
29243 type_base* canonical_type = p->get_naked_canonical_type();
29244 ABG_ASSERT(canonical_type);
29245
29246 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
29247 priv_->visited_ir_nodes.insert(canonical_ptr_value);
29248}
29249
29250/// Un-mark all visited type nodes.
29251///
29252/// That is, no type node is going to be considered as having been
29253/// visited anymore.
29254///
29255/// In other words, after invoking this funciton,
29256/// ir_node_visitor::type_node_has_been_visited() is going to return
29257/// false on all type nodes.
29258void
29260{priv_->visited_ir_nodes.clear();}
29261
29262/// Test if a given type node has been marked as visited.
29263///
29264/// @param p the type node to consider.
29265///
29266/// @return true iff the type node @p p has been marked as visited by
29267/// the function ir_node_visitor::mark_type_node_as_visited.
29268bool
29270{
29272 return false;
29273
29274 if (p == 0)
29275 return false;
29276
29277 type_base *canonical_type = p->get_naked_canonical_type();
29278 ABG_ASSERT(canonical_type);
29279
29280 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
29281 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
29282 if (it == priv_->visited_ir_nodes.end())
29283 return false;
29284
29285 return true;
29286}
29287
29288bool
29289ir_node_visitor::visit_begin(decl_base*)
29290{return true;}
29291
29292bool
29293ir_node_visitor::visit_end(decl_base*)
29294{return true;}
29295
29296bool
29297ir_node_visitor::visit_begin(scope_decl*)
29298{return true;}
29299
29300bool
29301ir_node_visitor::visit_end(scope_decl*)
29302{return true;}
29303
29304bool
29305ir_node_visitor::visit_begin(type_base*)
29306{return true;}
29307
29308bool
29309ir_node_visitor::visit_end(type_base*)
29310{return true;}
29311
29312bool
29313ir_node_visitor::visit_begin(scope_type_decl* t)
29314{return visit_begin(static_cast<type_base*>(t));}
29315
29316bool
29317ir_node_visitor::visit_end(scope_type_decl* t)
29318{return visit_end(static_cast<type_base*>(t));}
29319
29320bool
29321ir_node_visitor::visit_begin(type_decl* t)
29322{return visit_begin(static_cast<type_base*>(t));}
29323
29324bool
29325ir_node_visitor::visit_end(type_decl* t)
29326{return visit_end(static_cast<type_base*>(t));}
29327
29328bool
29329ir_node_visitor::visit_begin(namespace_decl* d)
29330{return visit_begin(static_cast<decl_base*>(d));}
29331
29332bool
29333ir_node_visitor::visit_end(namespace_decl* d)
29334{return visit_end(static_cast<decl_base*>(d));}
29335
29336bool
29337ir_node_visitor::visit_begin(qualified_type_def* t)
29338{return visit_begin(static_cast<type_base*>(t));}
29339
29340bool
29341ir_node_visitor::visit_end(qualified_type_def* t)
29342{return visit_end(static_cast<type_base*>(t));}
29343
29344bool
29345ir_node_visitor::visit_begin(pointer_type_def* t)
29346{return visit_begin(static_cast<type_base*>(t));}
29347
29348bool
29349ir_node_visitor::visit_end(pointer_type_def* t)
29350{return visit_end(static_cast<type_base*>(t));}
29351
29352bool
29353ir_node_visitor::visit_begin(reference_type_def* t)
29354{return visit_begin(static_cast<type_base*>(t));}
29355
29356bool
29357ir_node_visitor::visit_end(reference_type_def* t)
29358{return visit_end(static_cast<type_base*>(t));}
29359
29360bool
29361ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
29362{return visit_begin(static_cast<type_base*>(t));}
29363
29364bool
29365ir_node_visitor::visit_end(ptr_to_mbr_type* t)
29366{return visit_end(static_cast<type_base*>(t));}
29367
29368bool
29369ir_node_visitor::visit_begin(array_type_def* t)
29370{return visit_begin(static_cast<type_base*>(t));}
29371
29372bool
29373ir_node_visitor::visit_end(array_type_def* t)
29374{return visit_end(static_cast<type_base*>(t));}
29375
29376bool
29377ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
29378{return visit_begin(static_cast<type_base*>(t));}
29379
29380bool
29381ir_node_visitor::visit_end(array_type_def::subrange_type* t)
29382{return visit_end(static_cast<type_base*>(t));}
29383
29384bool
29385ir_node_visitor::visit_begin(enum_type_decl* t)
29386{return visit_begin(static_cast<type_base*>(t));}
29387
29388bool
29389ir_node_visitor::visit_end(enum_type_decl* t)
29390{return visit_end(static_cast<type_base*>(t));}
29391
29392bool
29393ir_node_visitor::visit_begin(typedef_decl* t)
29394{return visit_begin(static_cast<type_base*>(t));}
29395
29396bool
29397ir_node_visitor::visit_end(typedef_decl* t)
29398{return visit_end(static_cast<type_base*>(t));}
29399
29400bool
29401ir_node_visitor::visit_begin(function_type* t)
29402{return visit_begin(static_cast<type_base*>(t));}
29403
29404bool
29405ir_node_visitor::visit_end(function_type* t)
29406{return visit_end(static_cast<type_base*>(t));}
29407
29408bool
29409ir_node_visitor::visit_begin(var_decl* d)
29410{return visit_begin(static_cast<decl_base*>(d));}
29411
29412bool
29413ir_node_visitor::visit_end(var_decl* d)
29414{return visit_end(static_cast<decl_base*>(d));}
29415
29416bool
29417ir_node_visitor::visit_begin(function_decl* d)
29418{return visit_begin(static_cast<decl_base*>(d));}
29419
29420bool
29421ir_node_visitor::visit_end(function_decl* d)
29422{return visit_end(static_cast<decl_base*>(d));}
29423
29424bool
29425ir_node_visitor::visit_begin(function_decl::parameter* d)
29426{return visit_begin(static_cast<decl_base*>(d));}
29427
29428bool
29429ir_node_visitor::visit_end(function_decl::parameter* d)
29430{return visit_end(static_cast<decl_base*>(d));}
29431
29432bool
29433ir_node_visitor::visit_begin(function_tdecl* d)
29434{return visit_begin(static_cast<decl_base*>(d));}
29435
29436bool
29437ir_node_visitor::visit_end(function_tdecl* d)
29438{return visit_end(static_cast<decl_base*>(d));}
29439
29440bool
29441ir_node_visitor::visit_begin(class_tdecl* d)
29442{return visit_begin(static_cast<decl_base*>(d));}
29443
29444bool
29445ir_node_visitor::visit_end(class_tdecl* d)
29446{return visit_end(static_cast<decl_base*>(d));}
29447
29448bool
29449ir_node_visitor::visit_begin(class_or_union* t)
29450{return visit_begin(static_cast<type_base*>(t));}
29451
29452bool
29453ir_node_visitor::visit_end(class_or_union* t)
29454{return visit_end(static_cast<type_base*>(t));}
29455
29456bool
29457ir_node_visitor::visit_begin(class_decl* t)
29458{return visit_begin(static_cast<type_base*>(t));}
29459
29460bool
29461ir_node_visitor::visit_end(class_decl* t)
29462{return visit_end(static_cast<type_base*>(t));}
29463
29464bool
29465ir_node_visitor::visit_begin(union_decl* t)
29466{return visit_begin(static_cast<type_base*>(t));}
29467
29468bool
29469ir_node_visitor::visit_end(union_decl* t)
29470{return visit_end(static_cast<type_base*>(t));}
29471
29472bool
29473ir_node_visitor::visit_begin(class_decl::base_spec* d)
29474{return visit_begin(static_cast<decl_base*>(d));}
29475
29476bool
29477ir_node_visitor::visit_end(class_decl::base_spec* d)
29478{return visit_end(static_cast<decl_base*>(d));}
29479
29480bool
29481ir_node_visitor::visit_begin(member_function_template* d)
29482{return visit_begin(static_cast<decl_base*>(d));}
29483
29484bool
29485ir_node_visitor::visit_end(member_function_template* d)
29486{return visit_end(static_cast<decl_base*>(d));}
29487
29488bool
29489ir_node_visitor::visit_begin(member_class_template* d)
29490{return visit_begin(static_cast<decl_base*>(d));}
29491
29492bool
29493ir_node_visitor::visit_end(member_class_template* d)
29494{return visit_end(static_cast<decl_base*>(d));}
29495
29496// </ir_node_visitor stuff>
29497
29498// <debugging facilities>
29499
29500/// Generate a different string at each invocation.
29501///
29502/// @return the resulting string.
29503static string
29504get_next_string()
29505{
29506 static __thread size_t counter;
29507 ++counter;
29508 std::ostringstream o;
29509 o << counter;
29510 return o.str();
29511}
29512
29513/// Convenience typedef for a hash map of pointer to function_decl and
29514/// string.
29515typedef unordered_map<const function_decl*, string,
29516 function_decl::hash,
29518
29519/// Return a string associated to a given function. Two functions
29520/// that compare equal would yield the same string, as far as this
29521/// routine is concerned. And two functions that are different would
29522/// yield different strings.
29523///
29524/// This is used to debug core diffing issues on functions. The
29525/// sequence of strings can be given to the 'testdiff2' program that
29526/// is in the tests/ directory of the source tree, to reproduce core
29527/// diffing issues on string and thus ease the debugging.
29528///
29529/// @param fn the function to generate a string for.
29530///
29531/// @param m the function_decl* <-> string map to be used by this
29532/// function to generate strings associated to a function.
29533///
29534/// @return the resulting string.
29535static const string&
29536fn_to_str(const function_decl* fn,
29538{
29539 fns_to_str_map_type::const_iterator i = m.find(fn);
29540 if (i != m.end())
29541 return i->second;
29542 string s = get_next_string();
29543 return m[fn]= s;
29544}
29545
29546/// Generate a sequence of string that matches a given sequence of
29547/// function. In the resulting sequence, each function is "uniquely
29548/// representated" by a string. For instance, if the same function "foo"
29549/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
29550/// we don't care about the actual string) would appear at index 1 and 3.
29551///
29552/// @param begin the beginning of the sequence of functions to consider.
29553///
29554/// @param end the end of the sequence of functions. This points to
29555/// one-passed-the-end of the actual sequence.
29556///
29557/// @param m the function_decl* <-> string map to be used by this
29558/// function to generate strings associated to a function.
29559///
29560/// @param o the output stream where to emit the generated list of
29561/// strings to.
29562static void
29563fns_to_str(vector<function_decl*>::const_iterator begin,
29564 vector<function_decl*>::const_iterator end,
29566 std::ostream& o)
29567{
29568 vector<function_decl*>::const_iterator i;
29569 for (i = begin; i != end; ++i)
29570 o << "'" << fn_to_str(*i, m) << "' ";
29571}
29572
29573/// For each sequence of functions given in argument, generate a
29574/// sequence of string that matches a given sequence of function. In
29575/// the resulting sequence, each function is "uniquely representated"
29576/// by a string. For instance, if the same function "foo" appears at
29577/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
29578/// care about the actual string) would appear at index 1 and 3.
29579///
29580/// @param a_begin the beginning of the sequence of functions to consider.
29581///
29582/// @param a_end the end of the sequence of functions. This points to
29583/// one-passed-the-end of the actual sequence.
29584///
29585/// @param b_begin the beginning of the second sequence of functions
29586/// to consider.
29587///
29588/// @param b_end the end of the second sequence of functions.
29589///
29590/// @param m the function_decl* <-> string map to be used by this
29591/// function to generate strings associated to a function.
29592///
29593/// @param o the output stream where to emit the generated list of
29594/// strings to.
29595static void
29596fns_to_str(vector<function_decl*>::const_iterator a_begin,
29597 vector<function_decl*>::const_iterator a_end,
29598 vector<function_decl*>::const_iterator b_begin,
29599 vector<function_decl*>::const_iterator b_end,
29601 std::ostream& o)
29602{
29603 fns_to_str(a_begin, a_end, m, o);
29604 o << "->|<- ";
29605 fns_to_str(b_begin, b_end, m, o);
29606 o << "\n";
29607}
29608
29609/// For each sequence of functions given in argument, generate a
29610/// sequence of string that matches a given sequence of function. In
29611/// the resulting sequence, each function is "uniquely representated"
29612/// by a string. For instance, if the same function "foo" appears at
29613/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
29614/// care about the actual string) would appear at index 1 and 3.
29615///
29616/// @param a_begin the beginning of the sequence of functions to consider.
29617///
29618/// @param a_end the end of the sequence of functions. This points to
29619/// one-passed-the-end of the actual sequence.
29620///
29621/// @param b_begin the beginning of the second sequence of functions
29622/// to consider.
29623///
29624/// @param b_end the end of the second sequence of functions.
29625///
29626/// @param o the output stream where to emit the generated list of
29627/// strings to.
29628void
29629fns_to_str(vector<function_decl*>::const_iterator a_begin,
29630 vector<function_decl*>::const_iterator a_end,
29631 vector<function_decl*>::const_iterator b_begin,
29632 vector<function_decl*>::const_iterator b_end,
29633 std::ostream& o)
29634{
29636 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
29637}
29638
29639// </debugging facilities>
29640
29641// </class template>
29642
29643}// end namespace ir
29644}//end namespace abigail
29645
29646namespace
29647{
29648
29649/// Update the qualified parent name, qualified name and scoped name
29650/// of a tree decl node.
29651///
29652/// @return true if the tree walking should continue, false otherwise.
29653///
29654/// @param d the tree node to take in account.
29655bool
29656qualified_name_setter::do_update(abigail::ir::decl_base* d)
29657{
29658 std::string parent_qualified_name;
29659 abigail::ir::scope_decl* parent = d->get_scope();
29660 if (parent)
29661 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
29662 else
29663 d->priv_->qualified_parent_name_ = abigail::interned_string();
29664
29665 const abigail::ir::environment& env = d->get_environment();
29666
29667 if (!d->priv_->qualified_parent_name_.empty())
29668 {
29669 if (d->get_name().empty())
29670 d->priv_->qualified_name_ = abigail::interned_string();
29671 else
29672 {
29673 d->priv_->qualified_name_ =
29674 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
29675 d->priv_->internal_qualified_name_ = env.intern(d->get_name());
29676 }
29677 }
29678
29679 if (d->priv_->scoped_name_.empty())
29680 {
29681 if (parent
29682 && !parent->get_is_anonymous()
29683 && !parent->get_name().empty())
29684 d->priv_->scoped_name_ =
29685 env.intern(parent->get_name() + "::" + d->get_name());
29686 else
29687 d->priv_->scoped_name_ =
29688 env.intern(d->get_name());
29689 }
29690
29691 if (!is_scope_decl(d))
29692 return false;
29693
29694 return true;
29695}
29696
29697/// This is called when we start visiting a decl node, during the
29698/// udpate of the qualified name of a given sub-tree.
29699///
29700/// @param d the decl node we are visiting.
29701///
29702/// @return true iff the traversal should keep going.
29703bool
29704qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
29705{return do_update(d);}
29706
29707/// This is called when we start visiting a type node, during the
29708/// udpate of the qualified name of a given sub-tree.
29709///
29710/// @param d the decl node we are visiting.
29711///
29712/// @return true iff the traversal should keep going.
29713bool
29714qualified_name_setter::visit_begin(abigail::ir::type_base* t)
29715{
29717 return do_update(d);
29718 return false;
29719}
29720}// 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:1695
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:18668
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:18636
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:18629
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition: abg-ir.cc:18643
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition: abg-ir.cc:18680
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition: abg-ir.cc:18651
bound_value()
Default constructor of the array_type_def::subrange_type::bound_value class.
Definition: abg-ir.cc:18601
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition: abg-ir.cc:18658
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:18844
bool is_non_finite() const
Test if the length of the subrange type is infinite.
Definition: abg-ir.cc:18871
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition: abg-ir.cc:18837
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:18813
string as_string() const
Return a string representation of the sub range.
Definition: abg-ir.cc:18893
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19082
bool operator!=(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:19021
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition: abg-ir.cc:18823
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:18805
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:18977
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition: abg-ir.cc:18830
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:19060
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition: abg-ir.cc:18916
uint64_t get_length() const
Getter of the length of the subrange type.
Definition: abg-ir.cc:18854
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition: abg-ir.cc:18886
The abstraction of an array type.
Definition: abg-ir.h:2519
virtual bool is_non_finite() const
Definition: abg-ir.cc:19419
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:19449
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition: abg-ir.cc:19380
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition: abg-ir.cc:19395
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:19512
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition: abg-ir.cc:19539
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:19358
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:19228
translation_unit::language get_language() const
Get the language of the array.
Definition: abg-ir.cc:19347
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition: abg-ir.cc:19405
Abstraction of a base specifier in a class declaration.
Definition: abg-ir.h:4425
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
Definition: abg-ir.cc:24612
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition: abg-ir.cc:24619
long get_offset_in_bits() const
Getter of the offset of the base.
Definition: abg-ir.cc:24626
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:24652
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Definition: abg-ir.cc:24746
virtual size_t get_hash() const
Calculate the hash value for a class_decl::base_spec.
Definition: abg-ir.cc:24633
Abstracts a class declaration.
Definition: abg-ir.h:4228
void is_struct(bool f)
Set the "is-struct" flag of the class.
Definition: abg-ir.cc:24423
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition: abg-ir.cc:25203
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:24492
bool is_struct() const
Test if the class is a struct.
Definition: abg-ir.cc:24430
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition: abg-ir.cc:24447
virtual ~class_decl()
Destructor of the class_decl type.
Definition: abg-ir.cc:25803
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:24408
bool has_vtable() const
Test if the current instance has a vtable.
Definition: abg-ir.cc:25231
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition: abg-ir.cc:25245
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition: abg-ir.cc:25212
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:25719
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition: abg-ir.h:4246
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
Definition: abg-ir.cc:24437
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition: abg-ir.cc:24473
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition: abg-ir.cc:24497
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition: abg-ir.cc:25383
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition: abg-ir.cc:25571
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition: abg-ir.cc:25194
virtual size_t get_hash() const
Return the hash value for the current instance.
Definition: abg-ir.cc:25262
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:24457
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition: abg-ir.h:4247
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:24518
The base type of class_decl and union_decl.
Definition: abg-ir.h:4026
virtual size_t get_num_anonymous_member_classes() const
Get the number of anonymous member classes contained in this class.
Definition: abg-ir.cc:23266
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:23484
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:23417
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition: abg-ir.cc:23512
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
Definition: abg-ir.cc:23152
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition: abg-ir.cc:23588
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition: abg-ir.cc:23251
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition: abg-ir.cc:23284
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
Definition: abg-ir.cc:23602
unordered_map< ssize_t, member_functions > virtual_mem_fn_map_type
Convenience typedef.
Definition: abg-ir.h:4058
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition: abg-ir.h:4057
const data_members & get_data_members() const
Get the data members of this class_or_union.
Definition: abg-ir.cc:23376
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:23333
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:23563
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:23547
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition: abg-ir.cc:23235
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
Definition: abg-ir.cc:23644
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:23140
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:23058
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition: abg-ir.cc:23616
const data_members & get_non_static_data_members() const
Get the non-static data memebers of this class_or_union.
Definition: abg-ir.cc:23467
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:23521
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:23177
vector< var_decl_sptr > data_members
Convenience typedef.
Definition: abg-ir.h:4056
virtual ~class_or_union()
Destrcutor of the class_or_union type.
Definition: abg-ir.cc:23131
bool has_no_member() const
Definition: abg-ir.cc:23629
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:23678
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26106
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition: abg-ir.cc:23203
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition: abg-ir.cc:23595
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition: abg-ir.cc:23219
vector< type_base_sptr > member_types
Convenience typedef.
Definition: abg-ir.h:4055
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
Definition: abg-ir.cc:23302
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:23387
Abstract a class template.
Definition: abg-ir.h:3829
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition: abg-ir.cc:27493
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
Definition: abg-ir.cc:27482
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:27542
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:27497
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:39
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
Definition: abg-corpus.cc:729
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
Definition: abg-corpus.cc:761
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:870
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
Definition: abg-corpus.cc:878
const environment & get_environment() const
Getter of the enviroment of the corpus.
Definition: abg-corpus.cc:684
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:15854
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:5196
virtual bool operator!=(const decl_base &) const
Inequality operator.
Definition: abg-ir.cc:5454
scope_decl * get_scope() const
Return the type containing the current decl, if any.
Definition: abg-ir.cc:5025
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
Definition: abg-ir.cc:4734
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:4818
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:5809
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
Definition: abg-ir.cc:5144
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
Definition: abg-ir.cc:5000
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:5180
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition: abg-ir.cc:5056
void clear_qualified_name()
Clear the qualified name of this decl.
Definition: abg-ir.cc:4727
void set_name(const string &n)
Setter for the name of the decl.
Definition: abg-ir.cc:4888
const location & get_location() const
Get the location of a given declaration.
Definition: abg-ir.cc:4838
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:4948
const interned_string & get_name() const
Getter for the name of the current decl.
Definition: abg-ir.cc:5044
virtual void set_scope(scope_decl *)
Setter of the scope of the current decl.
Definition: abg-ir.cc:5481
const interned_string & peek_qualified_name() const
Getter for the qualified name.
Definition: abg-ir.cc:4718
const context_rel * get_context_rel() const
Getter for the context relationship.
Definition: abg-ir.cc:4768
friend void set_member_function_is_virtual(function_decl &, bool)
Set the virtual-ness of a member function.
Definition: abg-ir.cc:6845
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Definition: abg-ir.cc:4901
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:8501
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
Definition: abg-ir.cc:5136
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:5164
friend void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5778
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
Definition: abg-ir.cc:4966
void set_location(const location &l)
Set the location for a given declaration.
Definition: abg-ir.cc:4876
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
Definition: abg-ir.cc:4911
void set_visibility(visibility v)
Setter for the visibility of the decl.
Definition: abg-ir.cc:5017
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4761
visibility get_visibility() const
Getter for the visibility of the decl.
Definition: abg-ir.cc:5010
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:5187
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:5470
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition: abg-ir.cc:5152
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition: abg-ir.cc:4993
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5749
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6807
virtual ~decl_base()
Destructor of the decl_base type.
Definition: abg-ir.cc:5458
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:5443
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:5037
bool get_is_anonymous_or_has_anonymous_parent() const
Definition: abg-ir.cc:4934
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
Definition: abg-ir.cc:4923
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:4810
friend bool equals(const decl_base &, const decl_base &, change_kind *)
Compares two instances of decl_base.
Definition: abg-ir.cc:5360
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:4787
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4747
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:5079
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:3249
void set_anonymous_data_member(var_decl *)
Set the containing anonymous data member of this data member context relationship....
Definition: abg-ir.cc:3259
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:3162
bool operator==(const version &o) const
Compares the current version against another one.
Definition: abg-ir.cc:3144
bool is_default() const
Getter for the 'is_default' property of the version.
Definition: abg-ir.cc:3124
const string & str() const
Getter for the version name.
Definition: abg-ir.cc:3110
bool operator!=(const version &o) const
Inequality operator.
Definition: abg-ir.cc:3153
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:2247
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:2570
elf_symbol_sptr get_next_common_instance() const
Get the next common instance of the current common symbol.
Definition: abg-ir.cc:2465
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:2302
void set_is_in_ksymtab(bool is_in_ksymtab)
Setter of the 'is-in-ksymtab' property.
Definition: abg-ir.cc:2226
bool has_aliases() const
Check if the current elf_symbol has an alias.
Definition: abg-ir.cc:2331
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:2263
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:2338
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:2591
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:2476
void add_alias(const elf_symbol_sptr &)
Add an alias to the current elf symbol.
Definition: abg-ir.cc:2355
void set_is_suppressed(bool is_suppressed)
Setter for the 'is-suppressed' property.
Definition: abg-ir.cc:2272
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:2401
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:2657
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:2233
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:2716
bool is_main_symbol() const
Tests whether this symbol is the main symbol.
Definition: abg-ir.cc:2316
void set_crc(const abg_compat::optional< uint32_t > &crc)
Setter of the 'crc' property.
Definition: abg-ir.cc:2240
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:2434
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:2450
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:2521
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:2548
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:2218
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:2254
elf_symbol_sptr get_next_alias() const
Get the next alias of the current symbol.
Definition: abg-ir.cc:2323
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:2702
The abstraction of an enumerator.
Definition: abg-ir.h:2835
enumerator()
Default constructor of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:20133
bool operator!=(const enumerator &other) const
Inequality operator.
Definition: abg-ir.cc:20193
void set_name(const string &n)
Setter for the name of enum_type_decl::enumerator.
Definition: abg-ir.cc:20235
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition: abg-ir.cc:20257
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition: abg-ir.cc:20202
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition: abg-ir.cc:20264
void set_value(int64_t v)
Setter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:20250
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:20219
int64_t get_value() const
Getter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:20243
bool operator==(const enumerator &other) const
Equality operator.
Definition: abg-ir.cc:20180
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:20164
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:19711
const enumerators & get_enumerators() const
Definition: abg-ir.cc:19611
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
Definition: abg-ir.cc:19623
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19689
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition: abg-ir.cc:19606
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:20054
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:19664
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:3746
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:3813
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:3893
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:3627
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:3845
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
Definition: abg-ir.cc:3678
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:3646
const config & get_config() const
Getter of the general configuration object.
Definition: abg-ir.cc:3883
environment()
Default constructor of the environment type.
Definition: abg-ir.cc:3274
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:4030
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition: abg-ir.cc:3690
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:4053
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:3665
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:3782
virtual ~environment()
Destructor for the environment type.
Definition: abg-ir.cc:3279
interned_string intern(const string &) const
Do intern a string.
Definition: abg-ir.cc:3876
bool do_on_the_fly_canonicalization() const
Getter for the "on-the-fly-canonicalization" flag.
Definition: abg-ir.cc:3713
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:3919
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Definition: abg-ir.cc:3287
Abstraction of a function parameter.
Definition: abg-ir.h:3283
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
Definition: abg-ir.cc:22891
interned_string get_type_name() const
Definition: abg-ir.cc:22680
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition: abg-ir.cc:22718
const string get_type_pretty_representation() const
Definition: abg-ir.cc:22699
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition: abg-ir.cc:22856
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:22876
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:22911
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:22080
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition: abg-ir.cc:22151
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:22542
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition: abg-ir.cc:22221
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition: abg-ir.cc:22445
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition: abg-ir.cc:22117
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition: abg-ir.cc:22136
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:21943
const type_base_sptr get_return_type() const
Definition: abg-ir.cc:22202
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition: abg-ir.cc:22234
const std::vector< parameter_sptr > & get_parameters() const
Definition: abg-ir.cc:22207
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition: abg-ir.cc:22214
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition: abg-ir.cc:22173
virtual ~function_decl()
Destructor of the function_decl type.
Definition: abg-ir.cc:22558
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:22189
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition: abg-ir.cc:22431
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:22457
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:22012
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:22473
Abstract a function template declaration.
Definition: abg-ir.h:3780
binding get_binding() const
Get the binding of the function template.
Definition: abg-ir.cc:27330
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
Definition: abg-ir.cc:27312
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition: abg-ir.cc:27323
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:27390
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition: abg-ir.cc:27339
Abstraction of a function type.
Definition: abg-ir.h:3387
shared_ptr< function_decl::parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3397
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:21655
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition: abg-ir.cc:21340
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:21551
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:21154
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition: abg-ir.cc:21614
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:21325
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition: abg-ir.cc:21302
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition: abg-ir.cc:21571
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:21281
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition: abg-ir.cc:21244
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition: abg-ir.cc:21252
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:21529
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition: abg-ir.cc:21261
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3399
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:21638
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:46
void set_modifiers(modifiers_type)
Setter of the modifiers bitmap of the integral_type.
Definition: abg-ir.cc:16320
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
Definition: abg-ir.cc:16343
base_type get_base_type() const
Getter of the base type of the integral_type.
Definition: abg-ir.cc:16306
modifiers_type
The modifiers of the base types above. Several modifiers can be combined for a given base type....
Definition: abg-ir-priv.h:80
@ LONG_LONG_MODIFIER
The "long long" modifier.
Definition: abg-ir-priv.h:91
@ LONG_MODIFIER
The "long" modifier.
Definition: abg-ir-priv.h:89
@ SIGNED_MODIFIER
The "signed" modifier.
Definition: abg-ir-priv.h:83
@ UNSIGNED_MODIFIER
The "unsigned" modier.
Definition: abg-ir-priv.h:85
@ SHORT_MODIFIER
The "short" modifier.
Definition: abg-ir-priv.h:87
bool operator==(const integral_type &) const
Equality operator for the integral_type.
Definition: abg-ir.cc:16330
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:54
@ WCHAR_T_BASE_TYPE
The "wchar_t" base type.
Definition: abg-ir-priv.h:70
@ CHAR32_T_BASE_TYPE
The "char32_t" base type.
Definition: abg-ir-priv.h:68
@ FLOAT_BASE_TYPE
The "float" base type.
Definition: abg-ir-priv.h:64
@ BOOL_BASE_TYPE
The "bool" base type in C++ or "_Bool" in C11.
Definition: abg-ir-priv.h:60
@ CHAR_BASE_TYPE
The "char" base type.
Definition: abg-ir-priv.h:58
@ CHAR16_T_BASE_TYPE
The "char16_t base type.
Definition: abg-ir-priv.h:66
@ INT_BASE_TYPE
The "int" base type.
Definition: abg-ir-priv.h:56
@ DOUBLE_BASE_TYPE
The "double" base type.
Definition: abg-ir-priv.h:62
modifiers_type get_modifiers() const
Getter of the modifiers bitmap of the integral_type.
Definition: abg-ir.cc:16313
integral_type()
Default constructor of the integral_type.
Definition: abg-ir.cc:16276
The base class for the visitor type hierarchy used for traversing a translation unit.
Definition: abg-ir.h:4952
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:29225
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition: abg-ir.cc:29269
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition: abg-ir.cc:29259
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition: abg-ir.cc:29204
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition: abg-ir.cc:29235
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:4553
bool is_constructor() const
Getter for the 'is-constructor' property.
Definition: abg-ir.h:4631
bool is_const() const
Getter for the 'is-const' property.
Definition: abg-ir.h:4666
size_t vtable_offset() const
Getter for the vtable offset property.
Definition: abg-ir.h:4611
bool is_destructor() const
Getter for the 'is-destructor' property.
Definition: abg-ir.h:4648
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition: abg-ir.h:3875
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition: abg-ir.h:3896
bool get_is_static() const
Definition: abg-ir.h:3908
Abstracts a member class template template.
Definition: abg-ir.h:4758
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
Definition: abg-ir.cc:25966
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26051
Abstract a member function template.
Definition: abg-ir.h:4703
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:25945
Abstraction of the declaration of a method.
Definition: abg-ir.h:3924
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
Definition: abg-ir.cc:6704
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
Definition: abg-ir.cc:24893
const method_type_sptr get_type() const
Definition: abg-ir.cc:24920
Abstracts the type of a class member function.
Definition: abg-ir.h:3483
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:21842
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition: abg-ir.cc:21874
virtual ~method_type()
The destructor of method_type.
Definition: abg-ir.cc:21885
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:21866
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition: abg-ir.cc:21833
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition: abg-ir.cc:21881
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:16921
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:16952
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition: abg-ir.cc:16855
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition: abg-ir.cc:16907
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:16893
Abstracts non type template parameters.
Definition: abg-ir.h:3657
const type_base_sptr get_type() const
Getter for the type of the template parameter.
Definition: abg-ir.cc:27009
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:27023
virtual size_t get_hash() const
Get the hash value of the current instance.
Definition: abg-ir.cc:27016
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:17586
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:17721
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:17517
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17815
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition: abg-ir.cc:17657
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition: abg-ir.cc:17701
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition: abg-ir.cc:17708
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:18450
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:18393
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
Definition: abg-ir.cc:18434
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:18501
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
Definition: abg-ir.cc:18384
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
Definition: abg-ir.cc:18526
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:17243
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition: abg-ir.cc:17368
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition: abg-ir.cc:17107
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:17356
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:17047
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition: abg-ir.cc:17347
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17316
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition: abg-ir.cc:17342
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition: abg-ir.cc:17361
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition: abg-ir.cc:17187
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition: abg-ir.cc:17024
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:18131
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:17909
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18253
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:18003
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition: abg-ir.cc:18073
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:18232
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:7988
void remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
Definition: abg-ir.cc:8191
void insert_member_type(type_base_sptr t, declarations::iterator before)
Insert a member type.
Definition: abg-ir.cc:8150
void add_member_type(type_base_sptr t)
Add a member type to the current instance of class_or_union.
Definition: abg-ir.cc:8166
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
Definition: abg-ir.cc:8006
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
Definition: abg-ir.cc:8041
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:8055
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:8471
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
Definition: abg-ir.cc:8125
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:8237
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:7924
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:8423
virtual void remove_member_decl(decl_base_sptr member)
Remove a declaration from the current scope.
Definition: abg-ir.cc:8262
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:8099
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:8136
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7948
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:7912
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
Definition: abg-ir.cc:8210
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:8501
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:8377
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7966
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
Definition: abg-ir.cc:8024
virtual size_t get_hash() const
Return the hash value for the current instance of scope_decl.
Definition: abg-ir.cc:8302
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:16814
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition: abg-ir.cc:16776
The base class of templates.
Definition: abg-ir.h:3539
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:26677
virtual ~template_decl()
Destructor.
Definition: abg-ir.cc:26702
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:26669
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:26711
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition: abg-ir.h:3574
virtual ~template_parameter()
Destructor.
Definition: abg-ir.cc:26838
bool operator!=(const template_parameter &) const
Inequality operator.
Definition: abg-ir.cc:26834
Abstracts a template template parameter.
Definition: abg-ir.h:3704
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:27096
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:15916
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition: abg-ir.cc:15899
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition: abg-ir.cc:15995
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:16021
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:15630
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition: abg-ir.cc:15988
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition: abg-ir.cc:15981
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition: abg-ir.cc:15971
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition: abg-ir.cc:16009
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition: abg-ir.cc:16002
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition: abg-ir.cc:15883
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition: abg-ir.h:3742
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition: abg-ir.cc:27202
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition: abg-ir.cc:27209
virtual size_t get_hash() const
Get the hash value for the current instance.
Definition: abg-ir.cc:27216
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:16608
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:16687
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:16546
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:16502
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:16667
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:4491
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:4305
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
Definition: abg-ir.cc:4294
location & get_artificial_location() const
Getter of the artificial location of the artifact.
Definition: abg-ir.cc:4451
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
Definition: abg-ir.cc:4458
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Definition: abg-ir.cc:4483
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
Definition: abg-ir.cc:4328
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:4317
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
Definition: abg-ir.cc:4516
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
Definition: abg-ir.cc:4348
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition: abg-ir.cc:10832
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:4383
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10481
bool hashing_started() const
Getter for the 'hashing_started' property.
Definition: abg-ir.cc:4401
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
Definition: abg-ir.cc:4433
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:4415
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
Definition: abg-ir.cc:10554
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Definition: abg-ir.cc:4508
Abstracts a type template parameter.
Definition: abg-ir.h:3620
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:26880
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:20510
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition: abg-ir.cc:20495
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition: abg-ir.cc:20345
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:20542
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition: abg-ir.cc:20488
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:20425
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition: abg-ir.cc:20362
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:20466
Abstracts a union type declaration.
Definition: abg-ir.h:4483
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26471
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition: abg-ir.cc:26411
virtual ~union_decl()
Destructor of the union_decl type.
Definition: abg-ir.cc:26544
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:26378
Abstracts a variable declaration.
Definition: abg-ir.h:3008
binding get_binding() const
Getter of the binding of the variable.
Definition: abg-ir.cc:20656
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition: abg-ir.cc:20638
void set_binding(binding b)
Setter of the binding of the variable.
Definition: abg-ir.cc:20663
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
Definition: abg-ir.cc:6365
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
Definition: abg-ir.cc:20701
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:20964
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:20649
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6510
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:20631
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:21126
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:21103
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition: abg-ir.cc:20678
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:20694
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition: abg-ir.cc:20889
virtual size_t get_hash() const
Return the hash value for the current instance.
Definition: abg-ir.cc:20931
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:20994
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:20908
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:11435
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
Definition: abg-fwd.h:232
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:11029
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:19723
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:13518
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:12616
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition: abg-ir.cc:27808
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Definition: abg-ir.cc:6620
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
Definition: abg-ir.cc:7381
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
Definition: abg-fwd.h:218
size_t hash_type(const type_base *t)
Hash an ABI artifact that is either a type.
Definition: abg-ir.cc:27785
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:11967
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:6015
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:6320
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:11295
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:8518
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:10448
class_decl_sptr is_class_type(const type_or_decl_base_sptr &d)
Test whether a type is a class.
Definition: abg-ir.cc:10850
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:11754
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:5809
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:11212
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:10090
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:10073
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition: abg-fwd.h:266
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:13952
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:13433
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:9045
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition: abg-ir.cc:22524
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:11194
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
Definition: abg-fwd.h:286
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:14356
weak_ptr< function_type > function_type_wptr
Convenience typedef for a weak pointer on a function_type.
Definition: abg-fwd.h:213
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:13846
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
Definition: abg-ir.cc:6845
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition: abg-ir.cc:6744
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:14001
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:13359
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:11389
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:10814
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
Definition: abg-corpus.cc:1645
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:11470
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:26627
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:25150
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:19308
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:13700
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
Definition: abg-ir.cc:7683
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:9678
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10541
scope_decl * is_scope_decl(decl_base *d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5679
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:13606
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition: abg-ir.cc:6038
bool is_template_parameter(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter.
Definition: abg-ir.cc:10415
bool is_anonymous_data_member(const var_decl &d)
Test if a var_decl is an anonymous data member.
Definition: abg-ir.cc:6140
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:10681
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:7290
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:25860
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
Definition: abg-ir.cc:5633
scope_decl * get_type_scope(const type_base_sptr &t)
Get the scope of a given type.
Definition: abg-ir.cc:8867
integral_type::modifiers_type operator~(integral_type::modifiers_type l)
Bitwise one's complement operator for integral_type::modifiers_type.
Definition: abg-ir.cc:16078
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:11873
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:13788
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
Definition: abg-ir.cc:6777
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:13243
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:9987
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
Definition: abg-ir.cc:27879
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:12958
location get_location(const decl_base_sptr &decl)
Get the location of a given declaration.
Definition: abg-ir.cc:8829
const typedef_decl * is_typedef(const type_or_decl_base *t)
Test whether a type is a typedef.
Definition: abg-ir.cc:10731
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
Definition: abg-ir.cc:8525
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:7454
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:10155
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
Definition: abg-ir.cc:7616
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:13731
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:28360
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:11369
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:5952
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:12978
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:11064
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:9710
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
Definition: abg-ir.cc:5713
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:6265
weak_ptr< class_decl > class_decl_wptr
Convenience typedef for a weak pointer on a class_decl.
Definition: abg-fwd.h:199
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:11993
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:10140
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:11123
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition: abg-ir.cc:10823
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:14929
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition: abg-fwd.h:241
method_type * is_method_type(type_or_decl_base *t)
Test whether a type is a method_type.
Definition: abg-ir.cc:11566
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:13268
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:13906
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:11007
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:14229
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:9332
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:13871
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:7403
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:14122
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:6224
type_decl * is_integral_type(const type_or_decl_base *t)
Test if a type is an integral type.
Definition: abg-ir.cc:10661
translation_unit * get_translation_unit(const shared_ptr< decl_base > decl)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:10277
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:6280
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition: abg-ir.cc:6648
const function_type * is_function_type(const type_or_decl_base *t)
Test whether a type is a function_type.
Definition: abg-ir.cc:11536
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
Definition: abg-ir.cc:7339
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:28023
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
Definition: abg-fwd.h:311
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:11616
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:11054
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:5976
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition: abg-fwd.h:190
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:7477
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:6704
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:8768
bool is_anonymous_type(const type_base_sptr &t)
Test if a given type is anonymous.
Definition: abg-ir.cc:10617
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:7032
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:2969
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:11736
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:11829
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:10643
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10521
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:11625
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:11516
scope_decl_sptr is_scope_decl(const decl_base_sptr &d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5689
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:8736
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5778
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition: abg-ir.cc:10701
type_base_sptr is_type(const type_or_decl_base_sptr &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10569
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
Definition: abg-ir.cc:6482
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
Definition: abg-ir.cc:9859
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition: abg-fwd.h:207
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
Definition: abg-fwd.h:164
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:15012
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:2841
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:7234
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:20762
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:13218
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:3607
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:7579
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:10532
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:11309
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
Definition: abg-corpus.cc:1631
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:3050
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:10764
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:10471
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:11596
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:13471
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:6733
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
Definition: abg-ir.cc:16261
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:7207
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:8544
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:3270
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:10773
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:27971
bool elf_symbols_alias(const elf_symbol &s1, const elf_symbol &s2)
Test if two symbols alias.
Definition: abg-ir.cc:2772
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:10384
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition: abg-fwd.h:253
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:236
const location & get_natural_or_artificial_location(const decl_base *decl)
Get the non-artificial (natural) location of a decl.
Definition: abg-ir.cc:10000
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:8805
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:27706
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:11797
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
Definition: abg-corpus.cc:1659
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:29517
bool is_template_decl(const decl_base_sptr &decl)
Tests whether a decl is a template.
Definition: abg-ir.cc:11896
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
Definition: abg-fwd.h:261
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:13565
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:3002
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:6156
namespace_decl * is_namespace(const decl_base *d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:11745
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:7540
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:11408
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition: abg-ir.cc:11902
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:27643
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:10458
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:13378
class_or_union * is_at_class_scope(const decl_base &decl)
Tests whether a given decl is at class scope.
Definition: abg-ir.cc:10364
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
Definition: abg-ir.cc:5360
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6510
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:12925
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:3027
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:12230
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
Definition: abg-ir.cc:15752
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:6676
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:9082
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
Definition: abg-fwd.h:223
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:14386
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:19804
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:9287
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:10782
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:10994
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:14176
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:6395
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
Definition: abg-ir.cc:6439
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:6534
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:28292
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:11717
string get_pretty_representation(const method_type_sptr method, bool internal)
Get the pretty representation of a method type.
Definition: abg-ir.cc:9534
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:10481
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:27681
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:24982
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition: abg-ir.cc:5698
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:9554
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:11886
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:8501
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:28314
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:10628
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5749
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition: abg-fwd.h:172
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:6333
const interned_string & get_node_name(var_decl_sptr node)
Gets the name of a var_decl node.
Definition: abg-ir.cc:12683
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:6897
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition: abg-ir.cc:6350
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:10651
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:10341
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6807
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:11137
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:9831
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:10246
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:6196
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
Definition: abg-ir.cc:8816
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:11177
weak_ptr< decl_base > decl_base_wptr
Convenience typedef for a weak pointer to a decl_base.
Definition: abg-fwd.h:178
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:9159
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:11768
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:11576
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:11103
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition: abg-ir.cc:10019
bool is_global_scope(const shared_ptr< scope_decl >scope)
Tests whether if a given scope is the global scope.
Definition: abg-ir.cc:10305
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:13826
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:7180
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:9112
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
Definition: abg-fwd.h:303
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:11852
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:8706
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:6496
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:11229
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition: abg-ir.cc:5847
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:28339
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition: abg-ir.cc:10174
bool is_at_global_scope(const decl_base *decl)
Tests whether a given declaration is at global scope.
Definition: abg-ir.cc:10332
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26106
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:11781
weak_ptr< template_decl > template_decl_wptr
Convenience typedef for a weak pointer to template_decl.
Definition: abg-fwd.h:306
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:28249
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:9224
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition: abg-fwd.h:158
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:8622
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
Definition: abg-ir.cc:7658
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:9801
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:14051
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
Definition: abg-fwd.h:281
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:11727
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:15086
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition: abg-ir.cc:27844
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:14823
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:8885
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:1673
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:7736
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:9196
decl_base_sptr is_decl(const type_or_decl_base_sptr &d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10510
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:9060
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
Definition: abg-ir.cc:10406
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10429
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:3060
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:27665
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:14294
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:10912
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:11546
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:11496
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:11249
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:8693
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:8782
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:23980
decl_base_sptr get_type_declaration(const type_base_sptr t)
Get the declaration for a given type.
Definition: abg-ir.cc:10192
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
Definition: abg-fwd.h:291
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:7426
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:15116
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:11161
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:13533
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition: abg-ir.cc:5651
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:5260
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:11506
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:11093
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:11353
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition: abg-ir.cc:6561
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:6591
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:11043
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:13663
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:11701
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:7851
The hashing functor for class_decl::base_spec.
Definition: abg-ir.h:4885
Hasher for the class_decl type.
Definition: abg-ir.h:4386
The private data of the environment type.
Definition: abg-ir-priv.h:389
A hashing functor fo instances and pointers of function_decl.
Definition: abg-ir.h:4851
A hashing functor for a function_decl::parameter.
Definition: abg-ir.h:3365
Equality functor for instances of function_decl.
Definition: abg-ir.h:4861
The hashing functor for function_type.
Definition: abg-ir.h:3470
The type of the private data of the function_type type.
Definition: abg-ir-priv.h:1538
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:29187
The hashing functor for member_base.
Definition: abg-ir.h:4892
Hasher for the non_type_tparameter type.
Definition: abg-ir.h:3692
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:143
Definition of the private data of type_base.
Definition: abg-ir-priv.h:179
Hasher for the type_composition type.
Definition: abg-ir.h:3769
A predicate for deep equality of instances of shared_ptr<type_base>
Definition: abg-ir.h:2086
A hashing functor for instances and pointers of var_decl.
Definition: abg-ir.h:4820
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.