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
224void
225push_composite_type_comparison_operands(const type_base& left,
226 const type_base& right);
227
228void
229pop_composite_type_comparison_operands(const type_base& left,
230 const type_base& right);
231
232bool
233mark_dependant_types_compared_until(const type_base &r);
234
235/// Push a pair of operands on the stack of operands of the current
236/// type comparison, during type canonicalization.
237///
238/// For more information on this, please look at the description of
239/// the environment::priv::right_type_comp_operands_ data member.
240///
241/// @param left the left-hand-side comparison operand to push.
242///
243/// @param right the right-hand-side comparison operand to push.
244void
246 const type_base& right)
247{
248 const environment& env = left.get_environment();
249 env.priv_->push_composite_type_comparison_operands(&left, &right);
250}
251
252/// Pop a pair of operands from the stack of operands to the current
253/// type comparison.
254///
255/// For more information on this, please look at the description of
256/// the environment::privright_type_comp_operands_ data member.
257///
258/// @param left the left-hand-side comparison operand we expect to
259/// pop from the top of the stack. If this doesn't match the
260/// operand found on the top of the stack, the function aborts.
261///
262/// @param right the right-hand-side comparison operand we expect to
263/// pop from the bottom of the stack. If this doesn't match the
264/// operand found on the top of the stack, the function aborts.
265void
267 const type_base& right)
268{
269 const environment& env = left.get_environment();
270 env.priv_->pop_composite_type_comparison_operands(&left, &right);
271}
272
273/// In the stack of the current types being compared (as part of type
274/// canonicalization), mark all the types that comes after a certain
275/// one as NOT being eligible to the canonical type propagation
276/// optimization.
277///
278/// For a starter, please read about the @ref
279/// OnTheFlyCanonicalization, aka, "canonical type propagation
280/// optimization".
281///
282/// To implement that optimization, we need, among other things to
283/// maintain stack of the types (and their sub-types) being
284/// currently compared as part of type canonicalization.
285///
286/// Note that we only consider the type that is the right-hand-side
287/// operand of the comparison because it's that one that is being
288/// canonicalized and thus, that is not yet canonicalized.
289///
290/// The reason why a type is deemed NON-eligible to the canonical
291/// type propagation optimization is that it "depends" on
292/// recursively present type. Let me explain.
293///
294/// Suppose we have a type T that has sub-types named ST0 and ST1.
295/// Suppose ST1 itself has a sub-type that is T itself. In this
296/// case, we say that T is a recursive type, because it has T
297/// (itself) as one of its sub-types:
298///
299/// T
300/// +-- ST0
301/// |
302/// +-- ST1
303/// +
304/// |
305/// +-- T
306///
307/// ST1 is said to "depend" on T because it has T as a sub-type.
308/// But because T is recursive, then ST1 is said to depend on a
309/// recursive type. Notice however that ST0 does not depend on any
310/// recursive type.
311///
312/// When we are at the point of comparing the sub-type T of ST1
313/// against its counterpart, the stack of the right-hand-side
314/// operands of the type canonicalization is going to look like
315/// this:
316///
317/// | T | ST1 |
318///
319/// We don't add the type T to the stack as we detect that T was
320/// already in there (recursive cycle).
321///
322/// So, this function will basically mark ST1 as being NON-eligible
323/// to being the target of canonical type propagation, by marking ST1
324/// as being dependant on T.
325///
326/// @param right the right-hand-side operand of the type comparison.
327///
328/// @return true iff the operation was successful.
329bool
331{
332 const environment& env = r.get_environment();
334 return env.priv_->mark_dependant_types_compared_until(&r);
335 return false;
336}
337
338/// @brief the location of a token represented in its simplest form.
339/// Instances of this type are to be stored in a sorted vector, so the
340/// type must have proper relational operators.
341class expanded_location
342{
343 string path_;
344 unsigned line_;
345 unsigned column_;
346
347 expanded_location();
348
349public:
350
351 friend class location_manager;
352
353 expanded_location(const string& path, unsigned line, unsigned column)
354 : path_(path), line_(line), column_(column)
355 {}
356
357 bool
358 operator==(const expanded_location& l) const
359 {
360 return (path_ == l.path_
361 && line_ == l.line_
362 && column_ && l.column_);
363 }
364
365 bool
366 operator<(const expanded_location& l) const
367 {
368 if (path_ < l.path_)
369 return true;
370 else if (path_ > l.path_)
371 return false;
372
373 if (line_ < l.line_)
374 return true;
375 else if (line_ > l.line_)
376 return false;
377
378 return column_ < l.column_;
379 }
380};
381
382/// Expand the location into a tripplet path, line and column number.
383///
384/// @param path the output parameter where this function sets the
385/// expanded path.
386///
387/// @param line the output parameter where this function sets the
388/// expanded line.
389///
390/// @param column the ouptut parameter where this function sets the
391/// expanded column.
392void
393location::expand(std::string& path, unsigned& line, unsigned& column) const
394{
395 if (!get_location_manager())
396 {
397 // We don't have a location manager maybe because this location
398 // was just freshly instanciated. We still want to be able to
399 // expand to default values.
400 path = "";
401 line = 0;
402 column = 0;
403 return;
404 }
405 get_location_manager()->expand_location(*this, path, line, column);
406}
407
408
409/// Expand the location into a string.
410///
411/// @return the string representing the location.
412string
414{
415 string path, result;
416 unsigned line = 0, column = 0;
417 expand(path, line, column);
418
419 std::ostringstream o;
420 o << path << ":" << line << ":" << column;
421 return o.str();
422}
423
424struct location_manager::priv
425{
426 /// This sorted vector contains the expanded locations of the tokens
427 /// coming from a given ABI Corpus. The index of a given expanded
428 /// location in the table gives us an integer that is used to build
429 /// instance of location types.
430 std::vector<expanded_location> locs;
431};
432
433location_manager::location_manager()
434 : priv_(new location_manager::priv)
435{}
436
437location_manager::~location_manager() = default;
438
439/// Insert the triplet representing a source locus into our internal
440/// vector of location triplet. Return an instance of location type,
441/// built from an integral type that represents the index of the
442/// source locus triplet into our source locus table.
443///
444/// @param file_path the file path of the source locus
445/// @param line the line number of the source location
446/// @param col the column number of the source location
447location
448location_manager::create_new_location(const std::string& file_path,
449 size_t line,
450 size_t col)
451{
452 expanded_location l(file_path, line, col);
453
454 // Just append the new expanded location to the end of the vector
455 // and return its index. Note that indexes start at 1.
456 priv_->locs.push_back(l);
457 return location(priv_->locs.size(), this);
458}
459
460/// Given an instance of location type, return the triplet
461/// {path,line,column} that represents the source locus. Note that
462/// the location must have been previously created from the function
463/// location_manager::create_new_location, otherwise this function yields
464/// unexpected results, including possibly a crash.
465///
466/// @param location the instance of location type to expand
467/// @param path the resulting path of the source locus
468/// @param line the resulting line of the source locus
469/// @param column the resulting colum of the source locus
470void
472 std::string& path,
473 unsigned& line,
474 unsigned& column) const
475{
476 if (location.value_ == 0)
477 return;
478 expanded_location &l = priv_->locs[location.value_ - 1];
479 path = l.path_;
480 line = l.line_;
481 column = l.column_;
482}
483
484typedef unordered_map<function_type_sptr,
485 bool,
487 type_shared_ptr_equal> fn_type_ptr_map;
488
489// <type_maps stuff>
490
491struct type_maps::priv
492{
493 mutable istring_type_base_wptrs_map_type basic_types_;
494 mutable istring_type_base_wptrs_map_type class_types_;
495 mutable istring_type_base_wptrs_map_type union_types_;
496 mutable istring_type_base_wptrs_map_type enum_types_;
497 mutable istring_type_base_wptrs_map_type typedef_types_;
498 mutable istring_type_base_wptrs_map_type qualified_types_;
499 mutable istring_type_base_wptrs_map_type pointer_types_;
500 mutable istring_type_base_wptrs_map_type reference_types_;
501 mutable istring_type_base_wptrs_map_type array_types_;
502 mutable istring_type_base_wptrs_map_type subrange_types_;
503 mutable istring_type_base_wptrs_map_type function_types_;
504 mutable vector<type_base_wptr> sorted_types_;
505}; // end struct type_maps::priv
506
507type_maps::type_maps()
508 : priv_(new priv)
509{}
510
511type_maps::~type_maps() = default;
512
513/// Test if the type_maps is empty.
514///
515/// @return true iff the type_maps is empty.
516bool
518{
519 return (basic_types().empty()
520 && class_types().empty()
521 && union_types().empty()
522 && enum_types().empty()
523 && typedef_types().empty()
525 && pointer_types().empty()
527 && array_types().empty()
528 && subrange_types().empty()
529 && function_types().empty());
530}
531
532/// Getter for the map that associates the name of a basic type to the
533/// vector instances of type_decl_sptr that represents that type.
536{return priv_->basic_types_;}
537
538/// Getter for the map that associates the name of a basic type to the
539/// vector of instances of @ref type_decl_sptr that represents that
540/// type.
543{return priv_->basic_types_;}
544
545/// Getter for the map that associates the name of a class type to the
546/// vector of instances of @ref class_decl_sptr that represents that
547/// type.
550{return priv_->class_types_;}
551
552/// Getter for the map that associates the name of a class type to the
553/// vector of instances of @ref class_decl_sptr that represents that
554/// type.
557{return priv_->class_types_;}
558
559/// Getter for the map that associates the name of a union type to the
560/// vector of instances of @ref union_decl_sptr that represents that
561/// type.
564{return priv_->union_types_;}
565
566/// Getter for the map that associates the name of a union type to the
567/// vector of instances of @ref union_decl_sptr that represents that
568/// type.
571{return priv_->union_types_;}
572
573/// Getter for the map that associates the name of an enum type to the
574/// vector of instances of @ref enum_type_decl_sptr that represents
575/// that type.
578{return priv_->enum_types_;}
579
580/// Getter for the map that associates the name of an enum type to the
581/// vector of instances of @ref enum_type_decl_sptr that represents
582/// that type.
585{return priv_->enum_types_;}
586
587/// Getter for the map that associates the name of a typedef to the
588/// vector of instances of @ref typedef_decl_sptr that represents tha
589/// type.
592{return priv_->typedef_types_;}
593
594/// Getter for the map that associates the name of a typedef to the
595/// vector of instances of @ref typedef_decl_sptr that represents tha
596/// type.
599{return priv_->typedef_types_;}
600
601/// Getter for the map that associates the name of a qualified type to
602/// the vector of instances of @ref qualified_type_def_sptr.
605{return priv_->qualified_types_;}
606
607/// Getter for the map that associates the name of a qualified type to
608/// the vector of instances of @ref qualified_type_def_sptr.
611{return priv_->qualified_types_;}
612
613/// Getter for the map that associates the name of a pointer type to
614/// the vector of instances of @ref pointer_type_def_sptr that
615/// represents that type.
618{return priv_->pointer_types_;}
619
620/// Getter for the map that associates the name of a pointer type to
621/// the vector of instances of @ref pointer_type_def_sptr that
622/// represents that type.
625{return priv_->pointer_types_;}
626
627/// Getter for the map that associates the name of a reference type to
628/// the vector of instances of @ref reference_type_def_sptr that
629/// represents that type.
632{return priv_->reference_types_;}
633
634/// Getter for the map that associates the name of a reference type to
635/// the vector of instances of @ref reference_type_def_sptr that
636/// represents that type.
639{return priv_->reference_types_;}
640
641/// Getter for the map that associates the name of an array type to
642/// the vector of instances of @ref array_type_def_sptr that
643/// represents that type.
646{return priv_->array_types_;}
647
648/// Getter for the map that associates the name of an array type to
649/// the vector of instances of @ref array_type_def_sptr that
650/// represents that type.
653{return priv_->array_types_;}
654
655/// Getter for the map that associates the name of a subrange type to
656/// the vector of instances of @ref array_type_def::subrange_sptr that
657/// represents that type.
660{return priv_->subrange_types_;}
661
662/// Getter for the map that associates the name of a subrange type to
663/// the vector of instances of @ref array_type_def::subrange_sptr that
664/// represents that type.
667{return priv_->subrange_types_;}
668
669/// Getter for the map that associates the name of a function type to
670/// the vector of instances of @ref function_type_sptr that represents
671/// that type.
674{return priv_->function_types_;}
675
676/// Getter for the map that associates the name of a function type to
677/// the vector of instances of @ref function_type_sptr that represents
678/// that type.
681{return priv_->function_types_;}
682
683/// A comparison functor to compare/sort types based on their pretty
684/// representations.
685struct type_name_comp
686{
687 /// Comparison operator for two instances of @ref type_base.
688 ///
689 /// This compares the two types by lexicographically comparing their
690 /// pretty representation.
691 ///
692 /// @param l the left-most type to compare.
693 ///
694 /// @param r the right-most type to compare.
695 ///
696 /// @return true iff @p l < @p r.
697 bool
698 operator()(type_base *l, type_base *r) const
699 {
700 if (l == 0 && r == 0)
701 return false;
702
703 string l_repr = get_pretty_representation(l);
704 string r_repr = get_pretty_representation(r);
705 return l_repr < r_repr;
706 }
707
708 /// Comparison operator for two instances of @ref type_base.
709 ///
710 /// This compares the two types by lexicographically comparing their
711 /// pretty representation.
712 ///
713 /// @param l the left-most type to compare.
714 ///
715 /// @param r the right-most type to compare.
716 ///
717 /// @return true iff @p l < @p r.
718 bool
719 operator()(const type_base_sptr &l, const type_base_sptr &r) const
720 {return operator()(l.get(), r.get());}
721
722 /// Comparison operator for two instances of @ref type_base.
723 ///
724 /// This compares the two types by lexicographically comparing their
725 /// pretty representation.
726 ///
727 /// @param l the left-most type to compare.
728 ///
729 /// @param r the right-most type to compare.
730 ///
731 /// @return true iff @p l < @p r.
732 bool
733 operator()(const type_base_wptr &l, const type_base_wptr &r) const
734 {return operator()(type_base_sptr(l), type_base_sptr(r));}
735}; // end struct type_name_comp
736
737#ifdef WITH_DEBUG_SELF_COMPARISON
738
739/// This is a function called when the ABG_RETURN* macros defined
740/// below return false.
741///
742/// The purpose of this function is to ease debugging. To know where
743/// the equality functions first compare non-equal, we can just set a
744/// breakpoint on this notify_equality_failed function and run the
745/// equality functions. Because all the equality functions use the
746/// ABG_RETURN* macros to return their values, this function is always
747/// called when any of those equality function return false.
748///
749/// @param l the first operand of the equality.
750///
751/// @param r the second operand of the equality.
752static void
753notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
754 const type_or_decl_base &r __attribute__((unused)))
755{}
756
757/// This is a function called when the ABG_RETURN* macros defined
758/// below return false.
759///
760/// The purpose of this function is to ease debugging. To know where
761/// the equality functions first compare non-equal, we can just set a
762/// breakpoint on this notify_equality_failed function and run the
763/// equality functions. Because all the equality functions use the
764/// ABG_RETURN* macros to return their values, this function is always
765/// called when any of those equality function return false.
766///
767/// @param l the first operand of the equality.
768///
769/// @param r the second operand of the equality.
770static void
771notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
772 const type_or_decl_base *r __attribute__((unused)))
773{}
774
775#define ABG_RETURN_EQUAL(l, r) \
776 do \
777 { \
778 if (l != r) \
779 notify_equality_failed(l, r); \
780 return (l == r); \
781 } \
782 while(false)
783
784
785#define ABG_RETURN_FALSE \
786 do \
787 { \
788 notify_equality_failed(l, r); \
789 return false; \
790 } while(false)
791
792#define ABG_RETURN(value) \
793 do \
794 { \
795 if (value == false) \
796 notify_equality_failed(l, r); \
797 return value; \
798 } while (false)
799
800#else // WITH_DEBUG_SELF_COMPARISON
801
802#define ABG_RETURN_FALSE return false
803#define ABG_RETURN(value) return (value)
804#define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
805#endif
806
807/// Compare two types by comparing their canonical types if present.
808///
809/// If the canonical types are not present (because the types have not
810/// yet been canonicalized, for instance) then the types are compared
811/// structurally.
812///
813/// @param l the first type to take into account in the comparison.
814///
815/// @param r the second type to take into account in the comparison.
816template<typename T>
817bool
818try_canonical_compare(const T *l, const T *r)
819{
820#if WITH_DEBUG_TYPE_CANONICALIZATION
821 // We are debugging the canonicalization of a type down the stack.
822 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
823 // type being canonicalized. We are at a point where we can compare
824 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
825 // have canonical types) or structural comparison.
826 //
827 // Because we are debugging the process of type canonicalization, we
828 // want to compare 'l' and 'r' canonically *AND* structurally. Both
829 // kinds of comparison should yield the same result, otherwise type
830 // canonicalization just failed for the subtype 'r' of the type
831 // being canonicalized.
832 //
833 // In concrete terms, this function is going to be called twice with
834 // the same pair {'l', 'r'} to compare: The first time with
835 // environment::priv_->use_canonical_type_comparison_ set to true,
836 // instructing us to compare them canonically, and the second time
837 // with that boolean set to false, instructing us to compare them
838 // structurally.
839 const environment&env = l->get_environment();
840 if (env.priv_->use_canonical_type_comparison_)
841 {
842 if (const type_base *lc = l->get_naked_canonical_type())
843 if (const type_base *rc = r->get_naked_canonical_type())
844 ABG_RETURN_EQUAL(lc, rc);
845 }
846 return equals(*l, *r, 0);
847#else
848 if (const type_base *lc = l->get_naked_canonical_type())
849 if (const type_base *rc = r->get_naked_canonical_type())
850 ABG_RETURN_EQUAL(lc, rc);
851 return equals(*l, *r, 0);
852#endif
853
854
855}
856
857/// Detect if a recursive comparison cycle is detected while
858/// structurally comparing two types (a.k.a member-wise comparison).
859///
860/// @param l the left-hand-side operand of the current comparison.
861///
862/// @param r the right-hand-side operand of the current comparison.
863///
864/// @return true iff a comparison cycle is detected.
865template<typename T>
866bool
868{
869 bool result = l.priv_->comparison_started(l, r);
870 return result ;
871}
872
873/// Detect if a recursive comparison cycle is detected while
874/// structurally comparing two @ref class_decl types.
875///
876/// @param l the left-hand-side operand of the current comparison.
877///
878/// @param r the right-hand-side operand of the current comparison.
879///
880/// @return true iff a comparison cycle is detected.
881template<>
882bool
884{
885 return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
886 static_cast<const class_or_union&>(r));
887}
888
889/// This macro is to be used while comparing composite types that
890/// might recursively refer to themselves. Comparing two such types
891/// might get us into a cyle.
892///
893/// Practically, if we detect that we are already into comparing 'l'
894/// and 'r'; then, this is a cycle.
895//
896/// To break the cycle, we assume the result of the comparison is true
897/// for now. Comparing the other sub-types of l & r will tell us later
898/// if l & r are actually different or not.
899///
900/// In the mean time, returning true from this macro should not be
901/// used to propagate the canonical type of 'l' onto 'r' as we don't
902/// know yet if l equals r. All the types that depend on l and r
903/// can't (and that are in the comparison stack currently) can't have
904/// their canonical type propagated either. So this macro disallows
905/// canonical type propagation for those types that depend on a
906/// recursively defined sub-type for now.
907///
908/// @param l the left-hand-side operand of the comparison.
909#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
910 do \
911 { \
912 if (is_comparison_cycle_detected(l, r)) \
913 { \
914 mark_dependant_types_compared_until(r); \
915 return true; \
916 } \
917 } \
918 while(false)
919
920
921/// Mark a pair of types as being compared.
922///
923/// This is helpful to later detect recursive cycles in the comparison
924/// stack.
925///
926/// @param l the left-hand-side operand of the comparison.
927///
928/// @parm r the right-hand-side operand of the comparison.
929template<typename T>
930void
932{
933 l.priv_->mark_as_being_compared(l, r);
935}
936
937/// Mark a pair of @ref class_decl types as being compared.
938///
939/// This is helpful to later detect recursive cycles in the comparison
940/// stack.
941///
942/// @param l the left-hand-side operand of the comparison.
943///
944/// @parm r the right-hand-side operand of the comparison.
945template<>
946void
948{
949 return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
950 static_cast<const class_or_union&>(r));
951}
952
953/// Mark a pair of types as being not compared anymore.
954///
955/// This is helpful to later detect recursive cycles in the comparison
956/// stack.
957///
958/// Note that the types must have been passed to
959/// mark_types_as_being_compared prior to calling this function.
960///
961/// @param l the left-hand-side operand of the comparison.
962///
963/// @parm r the right-hand-side operand of the comparison.
964template<typename T>
965void
967{
968 l.priv_->unmark_as_being_compared(l, r);
970}
971
972/// Mark a pair of @ref class_decl types as being not compared
973/// anymore.
974///
975/// This is helpful to later detect recursive cycles in the comparison
976/// stack.
977///
978/// Note that the types must have been passed to
979/// mark_types_as_being_compared prior to calling this function.
980///
981/// @param l the left-hand-side operand of the comparison.
982///
983/// @parm r the right-hand-side operand of the comparison.
984template<>
985void
987{
988 return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
989 static_cast<const class_or_union&>(r));
990}
991
992/// Return the result of the comparison of two (sub) types.
993///
994/// The function does the necessary book keeping before returning the
995/// result of the comparison of two (sub) types.
996///
997/// The book-keeping done is in the following
998/// areas:
999///
1000/// * Management of the Canonical Type Propagation optimization
1001/// * type comparison cycle detection
1002///
1003/// @param l the left-hand-side operand of the type comparison
1004///
1005/// @param r the right-hand-side operand of the type comparison
1006///
1007/// @param propagate_canonical_type if true, it means the function
1008/// performs the @ref OnTheFlyCanonicalization, aka, "canonical type
1009/// propagation optimization".
1010///
1011/// @param value the result of the comparison of @p l and @p r.
1012///
1013/// @return the value @p value.
1014template<typename T>
1015bool
1016return_comparison_result(T& l, T& r, bool value,
1017 bool propagate_canonical_type = true)
1018{
1019 if (propagate_canonical_type && (value == true))
1020 maybe_propagate_canonical_type(l, r);
1021
1023
1024 const environment& env = l.get_environment();
1026 // We are instructed to perform the "canonical type propagation"
1027 // optimization, making 'r' to possibly get the canonical type of
1028 // 'l' if it has one. This mostly means that we are currently
1029 // canonicalizing the type that contain the subtype provided in
1030 // the 'r' argument.
1031 {
1032 if (value == true
1033 && (is_type(&r)->priv_->depends_on_recursive_type()
1034 || env.priv_->is_recursive_type(&r))
1035 && is_type(&r)->priv_->canonical_type_propagated()
1036 && !is_type(&r)->priv_->propagated_canonical_type_confirmed()
1037 && !env.priv_->right_type_comp_operands_.empty())
1038 {
1039 // Track the object 'r' for which the propagated canonical
1040 // type might be re-initialized if the current comparison
1041 // eventually fails.
1042 env.priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
1043 }
1044 else if (value == true && env.priv_->right_type_comp_operands_.empty())
1045 {
1046 // The type provided in the 'r' argument is the type that is
1047 // being canonicalized; 'r' is not a mere subtype being
1048 // compared, it's the whole type being canonicalized. And
1049 // its canonicalization has just succeeded.
1050 //
1051 // Let's confirm the canonical type resulting from the
1052 // "canonical type propagation" optimization.
1053 env.priv_->confirm_ct_propagation(&r);
1054 }
1055 else if (value == true)
1056 // In any other case, we are not sure if propagated types
1057 // should be confirmed yet. So let's mark them as such.
1058 env.priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
1059 else if (value == false)
1060 {
1061 // The comparison of the current sub-type failed. So all
1062 // the with non-confirmed propagated types (those in
1063 // env.prix_->types_with_non_confirmed_propagated_ct_)
1064 // should see their tentatively propagated canonical type
1065 // cancelled.
1066 env.priv_->cancel_all_non_confirmed_propagated_canonical_types();
1067 }
1068 }
1069
1070 // If we reached this point with value == true and the stack of
1071 // types being compared is empty, then it means that the type pair
1072 // that was at the bottom of the stack is now fully compared.
1073 //
1074 // It follows that all types that were target of canonical type
1075 // propagation can now see their tentative canonical type be
1076 // confirmed for real.
1077 if (value == true
1078 && env.priv_->right_type_comp_operands_.empty()
1079 && !env.priv_->types_with_non_confirmed_propagated_ct_.empty())
1080 // So the comparison is completely done and there are some
1081 // types for which their propagated canonical type is sitll
1082 // considered not confirmed. As the comparison did yield true, we
1083 // shall now confirm the propagation for all those types.
1084 env.priv_->confirm_ct_propagation();
1085
1086#ifdef WITH_DEBUG_SELF_COMPARISON
1087 if (value == false && env.priv_->right_type_comp_operands_.empty())
1088 {
1089 for (const auto i : env.priv_->types_with_non_confirmed_propagated_ct_)
1090 {
1091 type_base *t = reinterpret_cast<type_base*>(i);
1092 env.priv_->check_abixml_canonical_type_propagation_during_self_comp(t);
1093 }
1094 }
1095#endif
1096
1097 ABG_RETURN(value);
1098}
1099
1100#define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1101 do \
1102 { \
1103 bool res = return_comparison_result(l, r, value); \
1104 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1105 return res; \
1106 } while (false)
1107
1108/// Cache the result of a comparison between too artifacts (l & r) and
1109/// return immediately.
1110///
1111/// @param value the value to cache.
1112#define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1113 do \
1114 { \
1115 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1116 return value; \
1117 } while (false)
1118
1119/// Getter of all types types sorted by their pretty representation.
1120///
1121/// @return a sorted vector of all types sorted by their pretty
1122/// representation.
1123const vector<type_base_wptr>&
1125{
1126 if (priv_->sorted_types_.empty())
1127 {
1128 istring_type_base_wptrs_map_type::const_iterator i;
1129 vector<type_base_wptr>::const_iterator j;
1130
1131 for (i = basic_types().begin(); i != basic_types().end(); ++i)
1132 for (j = i->second.begin(); j != i->second.end(); ++j)
1133 priv_->sorted_types_.push_back(*j);
1134
1135 for (i = class_types().begin(); i != class_types().end(); ++i)
1136 for (j = i->second.begin(); j != i->second.end(); ++j)
1137 priv_->sorted_types_.push_back(*j);
1138
1139 for (i = union_types().begin(); i != union_types().end(); ++i)
1140 for (j = i->second.begin(); j != i->second.end(); ++j)
1141 priv_->sorted_types_.push_back(*j);
1142
1143 for (i = enum_types().begin(); i != enum_types().end(); ++i)
1144 for (j = i->second.begin(); j != i->second.end(); ++j)
1145 priv_->sorted_types_.push_back(*j);
1146
1147 for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
1148 for (j = i->second.begin(); j != i->second.end(); ++j)
1149 priv_->sorted_types_.push_back(*j);
1150
1151 type_name_comp comp;
1152 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1153 }
1154
1155 return priv_->sorted_types_;
1156}
1157
1158// </type_maps stuff>
1159
1160// <translation_unit stuff>
1161
1162/// Constructor of translation_unit.
1163///
1164/// @param env the environment of this translation unit. Please note
1165/// that the life time of the environment must be greater than the
1166/// life time of the translation unit because the translation uses
1167/// resources that are allocated in the environment.
1168///
1169/// @param path the location of the translation unit.
1170///
1171/// @param address_size the size of addresses in the translation unit,
1172/// in bits.
1173translation_unit::translation_unit(const environment& env,
1174 const std::string& path,
1175 char address_size)
1176 : priv_(new priv(env))
1177{
1178 priv_->path_ = path;
1179 priv_->address_size_ = address_size;
1180}
1181
1182/// Getter of the the global scope of the translation unit.
1183///
1184/// @return the global scope of the current translation unit. If
1185/// there is not global scope allocated yet, this function creates one
1186/// and returns it.
1187const scope_decl_sptr&
1189{
1190 return const_cast<translation_unit*>(this)->get_global_scope();
1191}
1192
1193/// Getter of the the global scope of the translation unit.
1194///
1195/// @return the global scope of the current translation unit. If
1196/// there is not global scope allocated yet, this function creates one
1197/// and returns it.
1200{
1201 if (!priv_->global_scope_)
1202 {
1203 priv_->global_scope_.reset
1204 (new global_scope(const_cast<translation_unit*>(this)));
1205 priv_->global_scope_->set_translation_unit
1206 (const_cast<translation_unit*>(this));
1207 }
1208 return priv_->global_scope_;
1209}
1210
1211/// Getter of the types of the current @ref translation_unit.
1212///
1213/// @return the maps of the types of the translation unit.
1214const type_maps&
1216{return priv_->types_;}
1217
1218/// Getter of the types of the current @ref translation_unit.
1219///
1220/// @return the maps of the types of the translation unit.
1221type_maps&
1223{return priv_->types_;}
1224
1225/// Get the vector of function types that are used in the current
1226/// translation unit.
1227///
1228/// @return the vector of function types that are used in the current
1229/// translation unit.
1230const vector<function_type_sptr>&
1232{return priv_->live_fn_types_;}
1233
1234/// Getter of the environment of the current @ref translation_unit.
1235///
1236/// @return the translation unit of the current translation unit.
1237const environment&
1239{return priv_->env_;}
1240
1241/// Getter of the language of the source code of the translation unit.
1242///
1243/// @return the language of the source code.
1246{return priv_->language_;}
1247
1248/// Setter of the language of the source code of the translation unit.
1249///
1250/// @param l the new language.
1251void
1253{priv_->language_ = l;}
1254
1255
1256/// Get the path of the current translation unit.
1257///
1258/// This path is relative to the build directory of the translation
1259/// unit as returned by translation_unit::get_compilation_dir_path.
1260///
1261/// @return the relative path of the compilation unit associated to
1262/// the current instance of translation_unit.
1263//
1264const std::string&
1266{return priv_->path_;}
1267
1268/// Set the path associated to the current instance of
1269/// translation_unit.
1270///
1271/// This path is relative to the build directory of the translation
1272/// unit as returned by translation_unit::get_compilation_dir_path.
1273///
1274/// @param a_path the new relative path to set.
1275void
1276translation_unit::set_path(const string& a_path)
1277{priv_->path_ = a_path;}
1278
1279
1280/// Get the path of the directory that was 'current' when the
1281/// translation unit was compiled.
1282///
1283/// Note that the path returned by translation_unit::get_path is
1284/// relative to the path returned by this function.
1285///
1286/// @return the compilation directory for the current translation
1287/// unit.
1288const std::string&
1290{return priv_->comp_dir_path_;}
1291
1292/// Set the path of the directory that was 'current' when the
1293/// translation unit was compiled.
1294///
1295/// Note that the path returned by translation_unit::get_path is
1296/// relative to the path returned by this function.
1297///
1298/// @param the compilation directory for the current translation unit.
1299void
1301{priv_->comp_dir_path_ = d;}
1302
1303/// Get the concatenation of the build directory and the relative path
1304/// of the translation unit.
1305///
1306/// @return the absolute path of the translation unit.
1307const std::string&
1309{
1310 if (priv_->abs_path_.empty())
1311 {
1312 string path;
1313 if (!priv_->path_.empty())
1314 {
1315 if (!priv_->comp_dir_path_.empty())
1316 {
1317 path = priv_->comp_dir_path_;
1318 path += "/";
1319 }
1320 path += priv_->path_;
1321 }
1322 priv_->abs_path_ = path;
1323 }
1324
1325 return priv_->abs_path_;
1326}
1327
1328/// Set the corpus this translation unit is a member of.
1329///
1330/// Note that adding a translation unit to a @ref corpus automatically
1331/// triggers a call to this member function.
1332///
1333/// @param corpus the corpus.
1334void
1336{priv_->corp = c;}
1337
1338/// Get the corpus this translation unit is a member of.
1339///
1340/// @return the parent corpus, or nil if this doesn't belong to any
1341/// corpus yet.
1342corpus*
1344{return priv_->corp;}
1345
1346/// Get the corpus this translation unit is a member of.
1347///
1348/// @return the parent corpus, or nil if this doesn't belong to any
1349/// corpus yet.
1350const corpus*
1352{return const_cast<translation_unit*>(this)->get_corpus();}
1353
1354/// Getter of the location manager for the current translation unit.
1355///
1356/// @return a reference to the location manager for the current
1357/// translation unit.
1360{return priv_->loc_mgr_;}
1361
1362/// const Getter of the location manager.
1363///
1364/// @return a const reference to the location manager for the current
1365/// translation unit.
1366const location_manager&
1368{return priv_->loc_mgr_;}
1369
1370/// Tests whether if the current translation unit contains ABI
1371/// artifacts or not.
1372///
1373/// @return true iff the current translation unit is empty.
1374bool
1376{
1377 if (!priv_->global_scope_)
1378 return true;
1379 return get_global_scope()->is_empty();
1380}
1381
1382/// Getter of the address size in this translation unit.
1383///
1384/// @return the address size, in bits.
1385char
1387{return priv_->address_size_;}
1388
1389/// Setter of the address size in this translation unit.
1390///
1391/// @param a the new address size in bits.
1392void
1394{priv_->address_size_= a;}
1395
1396/// Getter of the 'is_constructed" flag. It says if the translation
1397/// unit is fully constructed or not.
1398///
1399/// This flag is important for cases when comparison might depend on
1400/// if the translation unit is fully built or not. For instance, when
1401/// reading types from DWARF, the virtual methods of a class are not
1402/// necessarily fully constructed until we have reached the end of the
1403/// translation unit. In that case, before we've reached the end of
1404/// the translation unit, we might not take virtual functions into
1405/// account when comparing classes.
1406///
1407/// @return true if the translation unit is constructed.
1408bool
1410{return priv_->is_constructed_;}
1411
1412/// Setter of the 'is_constructed" flag. It says if the translation
1413/// unit is fully constructed or not.
1414///
1415/// This flag is important for cases when comparison might depend on
1416/// if the translation unit is fully built or not. For instance, when
1417/// reading types from DWARF, the virtual methods of a class are not
1418/// necessarily fully constructed until we have reached the end of the
1419/// translation unit. In that case, before we've reached the end of
1420/// the translation unit, we might not take virtual functions into
1421/// account when comparing classes.
1422///
1423/// @param f true if the translation unit is constructed.
1424void
1426{priv_->is_constructed_ = f;}
1427
1428/// Compare the current translation unit against another one.
1429///
1430/// @param other the other tu to compare against.
1431///
1432/// @return true if the two translation units are equal, false
1433/// otherwise.
1434bool
1436{
1437 if (get_address_size() != other.get_address_size())
1438 return false;
1439
1440 return *get_global_scope() == *other.get_global_scope();
1441}
1442
1443/// Inequality operator.
1444///
1445/// @param o the instance of @ref translation_unit to compare the
1446/// current instance against.
1447///
1448/// @return true iff the current instance is different from @p o.
1449bool
1451{return ! operator==(o);}
1452
1453/// Ensure that the life time of a function type is bound to the life
1454/// time of the current translation unit.
1455///
1456/// @param ftype the function time which life time to bind to the life
1457/// time of the current instance of @ref translation_unit. That is,
1458/// it's onlyh when the translation unit is destroyed that the
1459/// function type can be destroyed to.
1460void
1462{
1463 const environment& env = get_environment();
1464
1465 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1466
1467 interned_string repr = get_type_name(ftype);
1468 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1469 push_back(ftype);
1470
1471 // The function type must be out of the same environment as its
1472 // translation unit.
1473 {
1474 const environment& e = ftype->get_environment();
1475 ABG_ASSERT(&env == &e);
1476 }
1477
1478 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1479 ABG_ASSERT(existing_tu == this);
1480 else
1481 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1482}
1483
1484/// This implements the ir_traversable_base::traverse virtual
1485/// function.
1486///
1487/// @param v the visitor used on the member nodes of the translation
1488/// unit during the traversal.
1489///
1490/// @return true if the entire type IR tree got traversed, false
1491/// otherwise.
1492bool
1494{return get_global_scope()->traverse(v);}
1495
1496translation_unit::~translation_unit()
1497{}
1498
1499/// Converts a translation_unit::language enumerator into a string.
1500///
1501/// @param l the language enumerator to translate.
1502///
1503/// @return the resulting string.
1504string
1506{
1507 switch (l)
1508 {
1509 case translation_unit::LANG_UNKNOWN:
1510 return "LANG_UNKNOWN";
1511 case translation_unit::LANG_Cobol74:
1512 return "LANG_Cobol74";
1513 case translation_unit::LANG_Cobol85:
1514 return "LANG_Cobol85";
1515 case translation_unit::LANG_C89:
1516 return "LANG_C89";
1517 case translation_unit::LANG_C99:
1518 return "LANG_C99";
1519 case translation_unit::LANG_C11:
1520 return "LANG_C11";
1521 case translation_unit::LANG_C:
1522 return "LANG_C";
1523 case translation_unit::LANG_C_plus_plus_11:
1524 return "LANG_C_plus_plus_11";
1525 case translation_unit::LANG_C_plus_plus_14:
1526 return "LANG_C_plus_plus_14";
1527 case translation_unit::LANG_C_plus_plus:
1528 return "LANG_C_plus_plus";
1529 case translation_unit::LANG_ObjC:
1530 return "LANG_ObjC";
1531 case translation_unit::LANG_ObjC_plus_plus:
1532 return "LANG_ObjC_plus_plus";
1533 case translation_unit::LANG_Fortran77:
1534 return "LANG_Fortran77";
1535 case translation_unit::LANG_Fortran90:
1536 return "LANG_Fortran90";
1537 case translation_unit::LANG_Fortran95:
1538 return "LANG_Fortran95";
1539 case translation_unit::LANG_Ada83:
1540 return "LANG_Ada83";
1541 case translation_unit::LANG_Ada95:
1542 return "LANG_Ada95";
1543 case translation_unit::LANG_Pascal83:
1544 return "LANG_Pascal83";
1545 case translation_unit::LANG_Modula2:
1546 return "LANG_Modula2";
1547 case translation_unit::LANG_Java:
1548 return "LANG_Java";
1549 case translation_unit::LANG_PLI:
1550 return "LANG_PLI";
1551 case translation_unit::LANG_UPC:
1552 return "LANG_UPC";
1553 case translation_unit::LANG_D:
1554 return "LANG_D";
1555 case translation_unit::LANG_Python:
1556 return "LANG_Python";
1557 case translation_unit::LANG_Go:
1558 return "LANG_Go";
1559 case translation_unit::LANG_Mips_Assembler:
1560 return "LANG_Mips_Assembler";
1561 default:
1562 return "LANG_UNKNOWN";
1563 }
1564
1565 return "LANG_UNKNOWN";
1566}
1567
1568/// Parse a string representing a language into a
1569/// translation_unit::language enumerator into a string.
1570///
1571/// @param l the string representing the language.
1572///
1573/// @return the resulting translation_unit::language enumerator.
1576{
1577 if (l == "LANG_Cobol74")
1578 return translation_unit::LANG_Cobol74;
1579 else if (l == "LANG_Cobol85")
1580 return translation_unit::LANG_Cobol85;
1581 else if (l == "LANG_C89")
1582 return translation_unit::LANG_C89;
1583 else if (l == "LANG_C99")
1584 return translation_unit::LANG_C99;
1585 else if (l == "LANG_C11")
1586 return translation_unit::LANG_C11;
1587 else if (l == "LANG_C")
1588 return translation_unit::LANG_C;
1589 else if (l == "LANG_C_plus_plus_11")
1590 return translation_unit::LANG_C_plus_plus_11;
1591 else if (l == "LANG_C_plus_plus_14")
1592 return translation_unit::LANG_C_plus_plus_14;
1593 else if (l == "LANG_C_plus_plus")
1594 return translation_unit::LANG_C_plus_plus;
1595 else if (l == "LANG_ObjC")
1596 return translation_unit::LANG_ObjC;
1597 else if (l == "LANG_ObjC_plus_plus")
1598 return translation_unit::LANG_ObjC_plus_plus;
1599 else if (l == "LANG_Fortran77")
1600 return translation_unit::LANG_Fortran77;
1601 else if (l == "LANG_Fortran90")
1602 return translation_unit::LANG_Fortran90;
1603 else if (l == "LANG_Fortran95")
1604 return translation_unit::LANG_Fortran95;
1605 else if (l == "LANG_Ada83")
1606 return translation_unit::LANG_Ada83;
1607 else if (l == "LANG_Ada95")
1608 return translation_unit::LANG_Ada95;
1609 else if (l == "LANG_Pascal83")
1610 return translation_unit::LANG_Pascal83;
1611 else if (l == "LANG_Modula2")
1612 return translation_unit::LANG_Modula2;
1613 else if (l == "LANG_Java")
1614 return translation_unit::LANG_Java;
1615 else if (l == "LANG_PLI")
1616 return translation_unit::LANG_PLI;
1617 else if (l == "LANG_UPC")
1618 return translation_unit::LANG_UPC;
1619 else if (l == "LANG_D")
1620 return translation_unit::LANG_D;
1621 else if (l == "LANG_Python")
1622 return translation_unit::LANG_Python;
1623 else if (l == "LANG_Go")
1624 return translation_unit::LANG_Go;
1625 else if (l == "LANG_Mips_Assembler")
1626 return translation_unit::LANG_Mips_Assembler;
1627
1628 return translation_unit::LANG_UNKNOWN;
1629}
1630
1631/// Test if a language enumerator designates the C language.
1632///
1633/// @param l the language enumerator to consider.
1634///
1635/// @return true iff @p l designates the C language.
1636bool
1638{
1639 return (l == translation_unit::LANG_C89
1640 || l == translation_unit::LANG_C99
1641 || l == translation_unit::LANG_C11
1642 || l == translation_unit::LANG_C);
1643}
1644
1645/// Test if a language enumerator designates the C++ language.
1646///
1647/// @param l the language enumerator to consider.
1648///
1649/// @return true iff @p l designates the C++ language.
1650bool
1652{
1653 return (l == translation_unit::LANG_C_plus_plus_03
1654 || l == translation_unit::LANG_C_plus_plus_11
1655 || l == translation_unit::LANG_C_plus_plus_14
1656 || l == translation_unit::LANG_C_plus_plus);
1657}
1658
1659/// Test if a language enumerator designates the Java language.
1660///
1661/// @param l the language enumerator to consider.
1662///
1663/// @return true iff @p l designates the Java language.
1664bool
1666{return l == translation_unit::LANG_Java;}
1667
1668/// Test if a language enumerator designates the Ada language.
1669///
1670/// @param l the language enumerator to consider.
1671///
1672/// @return true iff @p l designates the Ada language.
1673bool
1675{
1676 return (l == translation_unit::LANG_Ada83
1677 || l == translation_unit::LANG_Ada95);
1678}
1679
1680/// A deep comparison operator for pointers to translation units.
1681///
1682/// @param l the first translation unit to consider for the comparison.
1683///
1684/// @param r the second translation unit to consider for the comparison.
1685///
1686/// @return true if the two translation units are equal, false otherwise.
1687bool
1689{
1690 if (l.get() == r.get())
1691 return true;
1692
1693 if (!!l != !!r)
1694 return false;
1695
1696 return *l == *r;
1697}
1698
1699/// A deep inequality operator for pointers to translation units.
1700///
1701/// @param l the first translation unit to consider for the comparison.
1702///
1703/// @param r the second translation unit to consider for the comparison.
1704///
1705/// @return true iff the two translation units are different.
1706bool
1708{return !operator==(l, r);}
1709
1710// </translation_unit stuff>
1711
1712// <elf_symbol stuff>
1713struct elf_symbol::priv
1714{
1715 const environment& env_;
1716 size_t index_;
1717 size_t size_;
1718 string name_;
1719 elf_symbol::type type_;
1720 elf_symbol::binding binding_;
1721 elf_symbol::version version_;
1722 elf_symbol::visibility visibility_;
1723 bool is_defined_;
1724 // This flag below says if the symbol is a common elf symbol. In
1725 // relocatable files, a common symbol is a symbol defined in a
1726 // section of kind SHN_COMMON.
1727 //
1728 // Note that a symbol of kind STT_COMMON is also considered a common
1729 // symbol. Here is what the gABI says about STT_COMMON and
1730 // SHN_COMMON:
1731 //
1732 // Symbols with type STT_COMMON label uninitialized common
1733 // blocks. In relocatable objects, these symbols are not
1734 // allocated and must have the special section index SHN_COMMON
1735 // (see below). In shared objects and executables these symbols
1736 // must be allocated to some section in the defining object.
1737 //
1738 // In relocatable objects, symbols with type STT_COMMON are
1739 // treated just as other symbols with index SHN_COMMON. If the
1740 // link-editor allocates space for the SHN_COMMON symbol in an
1741 // output section of the object it is producing, it must
1742 // preserve the type of the output symbol as STT_COMMON.
1743 //
1744 // When the dynamic linker encounters a reference to a symbol
1745 // that resolves to a definition of type STT_COMMON, it may (but
1746 // is not required to) change its symbol resolution rules as
1747 // follows: instead of binding the reference to the first symbol
1748 // found with the given name, the dynamic linker searches for
1749 // the first symbol with that name with type other than
1750 // STT_COMMON. If no such symbol is found, it looks for the
1751 // STT_COMMON definition of that name that has the largest size.
1752 bool is_common_;
1753 bool is_in_ksymtab_;
1756 bool is_suppressed_;
1757 elf_symbol_wptr main_symbol_;
1758 elf_symbol_wptr next_alias_;
1759 elf_symbol_wptr next_common_instance_;
1760 string id_string_;
1761
1762 priv(const environment& e)
1763 : env_(e),
1764 index_(),
1765 size_(),
1766 type_(elf_symbol::NOTYPE_TYPE),
1767 binding_(elf_symbol::GLOBAL_BINDING),
1768 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1769 is_defined_(false),
1770 is_common_(false),
1771 is_in_ksymtab_(false),
1772 crc_(),
1773 namespace_(),
1774 is_suppressed_(false)
1775 {}
1776
1777 priv(const environment& e,
1778 size_t i,
1779 size_t s,
1780 const string& n,
1783 bool d,
1784 bool c,
1785 const elf_symbol::version& ve,
1787 bool is_in_ksymtab,
1790 bool is_suppressed)
1791 : env_(e),
1792 index_(i),
1793 size_(s),
1794 name_(n),
1795 type_(t),
1796 binding_(b),
1797 version_(ve),
1798 visibility_(vi),
1799 is_defined_(d),
1800 is_common_(c),
1801 is_in_ksymtab_(is_in_ksymtab),
1802 crc_(crc),
1803 namespace_(ns),
1804 is_suppressed_(is_suppressed)
1805 {
1806 if (!is_common_)
1807 is_common_ = type_ == COMMON_TYPE;
1808 }
1809}; // end struct elf_symbol::priv
1810
1811/// Constructor of the @ref elf_symbol type.
1812///
1813/// Note that this constructor is private, so client code cannot use
1814/// it to create instances of @ref elf_symbol. Rather, client code
1815/// should use the @ref elf_symbol::create() function to create
1816/// instances of @ref elf_symbol instead.
1817///
1818/// @param e the environment we are operating from.
1819///
1820/// @param i the index of the symbol in the (ELF) symbol table.
1821///
1822/// @param s the size of the symbol.
1823///
1824/// @param n the name of the symbol.
1825///
1826/// @param t the type of the symbol.
1827///
1828/// @param b the binding of the symbol.
1829///
1830/// @param d true if the symbol is defined, false otherwise.
1831///
1832/// @param c true if the symbol is a common symbol, false otherwise.
1833///
1834/// @param ve the version of the symbol.
1835///
1836/// @param vi the visibility of the symbol.
1837///
1838/// @param crc the CRC (modversions) value of Linux Kernel symbols
1839///
1840/// @param ns the namespace of Linux Kernel symbols, if any
1841elf_symbol::elf_symbol(const environment& e,
1842 size_t i,
1843 size_t s,
1844 const string& n,
1845 type t,
1846 binding b,
1847 bool d,
1848 bool c,
1849 const version& ve,
1850 visibility vi,
1851 bool is_in_ksymtab,
1854 bool is_suppressed)
1855 : priv_(new priv(e,
1856 i,
1857 s,
1858 n,
1859 t,
1860 b,
1861 d,
1862 c,
1863 ve,
1864 vi,
1865 is_in_ksymtab,
1866 crc,
1867 ns,
1868 is_suppressed))
1869{}
1870
1871/// Factory of instances of @ref elf_symbol.
1872///
1873/// This is the function to use to create instances of @ref elf_symbol.
1874///
1875/// @param e the environment we are operating from.
1876///
1877/// @param i the index of the symbol in the (ELF) symbol table.
1878///
1879/// @param s the size of the symbol.
1880///
1881/// @param n the name of the symbol.
1882///
1883/// @param t the type of the symbol.
1884///
1885/// @param b the binding of the symbol.
1886///
1887/// @param d true if the symbol is defined, false otherwise.
1888///
1889/// @param c true if the symbol is a common symbol.
1890///
1891/// @param ve the version of the symbol.
1892///
1893/// @param vi the visibility of the symbol.
1894///
1895/// @param crc the CRC (modversions) value of Linux Kernel symbols
1896///
1897/// @param ns the namespace of Linux Kernel symbols, if any
1898///
1899/// @return a (smart) pointer to a newly created instance of @ref
1900/// elf_symbol.
1903 size_t i,
1904 size_t s,
1905 const string& n,
1906 type t,
1907 binding b,
1908 bool d,
1909 bool c,
1910 const version& ve,
1911 visibility vi,
1912 bool is_in_ksymtab,
1915 bool is_suppressed)
1916{
1917 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
1918 is_in_ksymtab, crc, ns, is_suppressed));
1919 sym->priv_->main_symbol_ = sym;
1920 return sym;
1921}
1922
1923/// Test textual equality between two symbols.
1924///
1925/// Textual equality means that the aliases of the compared symbols
1926/// are not taken into account. Only the name, type, and version of
1927/// the symbols are compared.
1928///
1929/// @return true iff the two symbols are textually equal.
1930static bool
1931textually_equals(const elf_symbol&l,
1932 const elf_symbol&r)
1933{
1934 bool equals = (l.get_name() == r.get_name()
1935 && l.get_type() == r.get_type()
1936 && l.is_public() == r.is_public()
1937 && l.is_defined() == r.is_defined()
1939 && l.get_version() == r.get_version()
1940 && l.get_crc() == r.get_crc()
1941 && l.get_namespace() == r.get_namespace());
1942
1943 if (equals && l.is_variable())
1944 // These are variable symbols. Let's compare their symbol size.
1945 // The symbol size in this case is the size taken by the storage
1946 // of the variable. If that size changes, then it's an ABI
1947 // change.
1948 equals = l.get_size() == r.get_size();
1949
1950 return equals;
1951}
1952
1953/// Getter of the environment used by the current instance of @ref
1954/// elf_symbol.
1955///
1956/// @return the enviroment used by the current instance of @ref elf_symbol.
1957const environment&
1959{return priv_->env_;}
1960
1961/// Getter for the index
1962///
1963/// @return the index of the symbol.
1964size_t
1966{return priv_->index_;}
1967
1968/// Setter for the index.
1969///
1970/// @param s the new index.
1971void
1973{priv_->index_ = s;}
1974
1975/// Getter for the name of the @ref elf_symbol.
1976///
1977/// @return a reference to the name of the @ref symbol.
1978const string&
1980{return priv_->name_;}
1981
1982/// Setter for the name of the current intance of @ref elf_symbol.
1983///
1984/// @param n the new name.
1985void
1986elf_symbol::set_name(const string& n)
1987{
1988 priv_->name_ = n;
1989 priv_->id_string_.clear();
1990}
1991
1992/// Getter for the type of the current instance of @ref elf_symbol.
1993///
1994/// @return the type of the elf symbol.
1997{return priv_->type_;}
1998
1999/// Setter for the type of the current instance of @ref elf_symbol.
2000///
2001/// @param t the new symbol type.
2002void
2004{priv_->type_ = t;}
2005
2006/// Getter of the size of the symbol.
2007///
2008/// @return the size of the symbol, in bytes.
2009size_t
2011{return priv_->size_;}
2012
2013/// Setter of the size of the symbol.
2014///
2015/// @param size the new size of the symbol, in bytes.
2016void
2018{priv_->size_ = size;}
2019
2020/// Getter for the binding of the current instance of @ref elf_symbol.
2021///
2022/// @return the binding of the symbol.
2025{return priv_->binding_;}
2026
2027/// Setter for the binding of the current instance of @ref elf_symbol.
2028///
2029/// @param b the new binding.
2030void
2032{priv_->binding_ = b;}
2033
2034/// Getter for the version of the current instanc of @ref elf_symbol.
2035///
2036/// @return the version of the elf symbol.
2039{return priv_->version_;}
2040
2041/// Setter for the version of the current instance of @ref elf_symbol.
2042///
2043/// @param v the new version of the elf symbol.
2044void
2046{
2047 priv_->version_ = v;
2048 priv_->id_string_.clear();
2049}
2050
2051/// Setter of the visibility of the current instance of @ref
2052/// elf_symbol.
2053///
2054/// @param v the new visibility of the elf symbol.
2055void
2057{priv_->visibility_ = v;}
2058
2059/// Getter of the visibility of the current instance of @ref
2060/// elf_symbol.
2061///
2062/// @return the visibility of the elf symbol.
2065{return priv_->visibility_;}
2066
2067/// Test if the current instance of @ref elf_symbol is defined or not.
2068///
2069/// @return true if the current instance of @ref elf_symbol is
2070/// defined, false otherwise.
2071bool
2073{return priv_->is_defined_;}
2074
2075/// Sets a flag saying if the current instance of @ref elf_symbol is
2076/// defined
2077///
2078/// @param b the new value of the flag.
2079void
2081{priv_->is_defined_ = d;}
2082
2083/// Test if the current instance of @ref elf_symbol is public or not.
2084///
2085/// This tests if the symbol is defined, has default or protected
2086///visibility, and either:
2087/// - has global binding
2088/// - has weak binding
2089/// - or has a GNU_UNIQUE binding.
2090///
2091/// return true if the current instance of @ref elf_symbol is public,
2092/// false otherwise.
2093bool
2095{
2096 return (is_defined()
2097 && (get_binding() == GLOBAL_BINDING
2098 || get_binding() == WEAK_BINDING
2099 || get_binding() == GNU_UNIQUE_BINDING)
2100 && (get_visibility() == DEFAULT_VISIBILITY
2101 || get_visibility() == PROTECTED_VISIBILITY));
2102}
2103
2104/// Test if the current instance of @ref elf_symbol is a function
2105/// symbol or not.
2106///
2107/// @return true if the current instance of @ref elf_symbol is a
2108/// function symbol, false otherwise.
2109bool
2111{return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2112
2113/// Test if the current instance of @ref elf_symbol is a variable
2114/// symbol or not.
2115///
2116/// @return true if the current instance of @ref elf_symbol is a
2117/// variable symbol, false otherwise.
2118bool
2120{return get_type() == OBJECT_TYPE || get_type() == TLS_TYPE;}
2121
2122/// Getter of the 'is-in-ksymtab' property.
2123///
2124/// @return true iff the current symbol is in the Linux Kernel
2125/// specific 'ksymtab' symbol table.
2126bool
2128{return priv_->is_in_ksymtab_;}
2129
2130/// Setter of the 'is-in-ksymtab' property.
2131///
2132/// @param is_in_ksymtab this is true iff the current symbol is in the
2133/// Linux Kernel specific 'ksymtab' symbol table.
2134void
2136{priv_->is_in_ksymtab_ = is_in_ksymtab;}
2137
2138/// Getter of the 'crc' property.
2139///
2140/// @return the CRC (modversions) value for Linux Kernel symbols, if any
2143{return priv_->crc_;}
2144
2145/// Setter of the 'crc' property.
2146///
2147/// @param crc the new CRC (modversions) value for Linux Kernel symbols
2148void
2150{priv_->crc_ = crc;}
2151
2152/// Getter of the 'namespace' property.
2153///
2154/// @return the namespace for Linux Kernel symbols, if any
2157{return priv_->namespace_;}
2158
2159/// Setter of the 'namespace' property.
2160///
2161/// @param ns the new namespace for Linux Kernel symbols, if any
2162void
2164{priv_->namespace_ = ns;}
2165
2166/// Getter for the 'is-suppressed' property.
2167///
2168/// @return true iff the current symbol has been suppressed by a
2169/// suppression specification that was provided in the context that
2170/// led to the creation of the corpus this ELF symbol belongs to.
2171bool
2173{return priv_->is_suppressed_;}
2174
2175/// Setter for the 'is-suppressed' property.
2176///
2177/// @param true iff the current symbol has been suppressed by a
2178/// suppression specification that was provided in the context that
2179/// led to the creation of the corpus this ELF symbol belongs to.
2180void
2182{priv_->is_suppressed_ = is_suppressed;}
2183
2184/// @name Elf symbol aliases
2185///
2186/// An alias A for an elf symbol S is a symbol that is defined at the
2187/// same address as S. S is chained to A through the
2188/// elf_symbol::get_next_alias() method.
2189///
2190/// When there are several aliases to a symbol, the main symbol is the
2191/// the first symbol found in the symbol table for a given address.
2192///
2193/// The alias chain is circular. That means if S is the main symbol
2194/// and A is the alias, S is chained to A and A
2195/// is chained back to the main symbol S. The last alias in an alias
2196///chain is always chained to the main symbol.
2197///
2198/// Thus, when looping over the aliases of an elf_symbol A, detecting
2199/// an alias that is equal to the main symbol should logically be a
2200/// loop exit condition.
2201///
2202/// Accessing and adding aliases for instances of elf_symbol is done
2203/// through the member functions below.
2204
2205/// @{
2206
2207/// Get the main symbol of an alias chain.
2208///
2209///@return the main symbol.
2210const elf_symbol_sptr
2212{return priv_->main_symbol_.lock();}
2213
2214/// Get the main symbol of an alias chain.
2215///
2216///@return the main symbol.
2219{return priv_->main_symbol_.lock();}
2220
2221/// Tests whether this symbol is the main symbol.
2222///
2223/// @return true iff this symbol is the main symbol.
2224bool
2226{return get_main_symbol().get() == this;}
2227
2228/// Get the next alias of the current symbol.
2229///
2230///@return the alias, or NULL if there is no alias.
2233{return priv_->next_alias_.lock();}
2234
2235
2236/// Check if the current elf_symbol has an alias.
2237///
2238///@return true iff the current elf_symbol has an alias.
2239bool
2241{return bool(get_next_alias());}
2242
2243/// Get the number of aliases to this elf symbol
2244///
2245/// @return the number of aliases to this elf symbol.
2246int
2248{
2249 int result = 0;
2250
2252 a && a.get() != get_main_symbol().get();
2253 a = a->get_next_alias())
2254 ++result;
2255
2256 return result;
2257}
2258
2259/// Add an alias to the current elf symbol.
2260///
2261/// @param alias the new alias. Note that this elf_symbol should *NOT*
2262/// have aliases prior to the invocation of this function.
2263void
2265{
2266 if (!alias)
2267 return;
2268
2269 ABG_ASSERT(!alias->has_aliases());
2271
2272 if (has_aliases())
2273 {
2274 elf_symbol_sptr last_alias;
2276 a && !a->is_main_symbol();
2277 a = a->get_next_alias())
2278 {
2279 if (a->get_next_alias()->is_main_symbol())
2280 {
2281 ABG_ASSERT(last_alias == 0);
2282 last_alias = a;
2283 }
2284 }
2285 ABG_ASSERT(last_alias);
2286
2287 last_alias->priv_->next_alias_ = alias;
2288 }
2289 else
2290 priv_->next_alias_ = alias;
2291
2292 alias->priv_->next_alias_ = get_main_symbol();
2293 alias->priv_->main_symbol_ = get_main_symbol();
2294}
2295
2296/// Update the main symbol for a group of aliased symbols
2297///
2298/// If after the construction of the symbols (in order of discovery), the
2299/// actual main symbol can be identified (e.g. as the symbol that actually is
2300/// defined in the code), this method offers a way of updating the main symbol
2301/// through one of the aliased symbols.
2302///
2303/// For that, locate the new main symbol by name and update all references to
2304/// the main symbol among the group of aliased symbols.
2305///
2306/// @param name the name of the main symbol
2307///
2308/// @return the new main elf_symbol
2310elf_symbol::update_main_symbol(const std::string& name)
2311{
2313 if (!has_aliases() || get_name() == name)
2314 return get_main_symbol();
2315
2316 // find the new main symbol
2317 elf_symbol_sptr new_main;
2318 // we've already checked this; check the rest of the aliases
2319 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2320 a = a->get_next_alias())
2321 if (a->get_name() == name)
2322 {
2323 new_main = a;
2324 break;
2325 }
2326
2327 if (!new_main)
2328 return get_main_symbol();
2329
2330 // now update all main symbol references
2331 priv_->main_symbol_ = new_main;
2332 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2333 a = a->get_next_alias())
2334 a->priv_->main_symbol_ = new_main;
2335
2336 return new_main;
2337}
2338
2339/// Return true if the symbol is a common one.
2340///
2341/// @return true iff the symbol is common.
2342bool
2344{return priv_->is_common_;}
2345
2346/// Return true if this common common symbol has other common instances.
2347///
2348/// A common instance of a given common symbol is another common
2349/// symbol with the same name. Those exist in relocatable files. The
2350/// linker normally allocates all the instances into a common block in
2351/// the final output file.
2352///
2353/// Note that the current object must be a common symbol, otherwise,
2354/// this function aborts.
2355///
2356/// @return true iff the current common symbol has other common
2357/// instances.
2358bool
2360{
2362 return bool(get_next_common_instance());
2363}
2364
2365/// Get the next common instance of the current common symbol.
2366///
2367/// A common instance of a given common symbol is another common
2368/// symbol with the same name. Those exist in relocatable files. The
2369/// linker normally allocates all the instances into a common block in
2370/// the final output file.
2371///
2372/// @return the next common instance, or nil if there is not any.
2375{return priv_->next_common_instance_.lock();}
2376
2377/// Add a common instance to the current common elf symbol.
2378///
2379/// Note that this symbol must be the main symbol. Being the main
2380/// symbol means being the first common symbol to appear in the symbol
2381/// table.
2382///
2383/// @param common the other common instance to add.
2384void
2386{
2387 if (!common)
2388 return;
2389
2390 ABG_ASSERT(!common->has_other_common_instances());
2393
2395 {
2396 elf_symbol_sptr last_common_instance;
2398 c && (c.get() != get_main_symbol().get());
2399 c = c->get_next_common_instance())
2400 {
2401 if (c->get_next_common_instance().get() == get_main_symbol().get())
2402 {
2403 ABG_ASSERT(last_common_instance == 0);
2404 last_common_instance = c;
2405 }
2406 }
2407 ABG_ASSERT(last_common_instance);
2408
2409 last_common_instance->priv_->next_common_instance_ = common;
2410 }
2411 else
2412 priv_->next_common_instance_ = common;
2413
2414 common->priv_->next_common_instance_ = get_main_symbol();
2415 common->priv_->main_symbol_ = get_main_symbol();
2416}
2417
2418/// Get a string that is representative of a given elf_symbol.
2419///
2420/// If the symbol has a version, then the ID string is the
2421/// concatenation of the name of the symbol, the '@' character, and
2422/// the version of the symbol. If the version is the default version
2423/// of the symbol then the '@' character is replaced by a "@@" string.
2424///
2425/// Otherwise, if the symbol does not have any version, this function
2426/// returns the name of the symbol.
2427///
2428/// @return a the ID string.
2429const string&
2431{
2432 if (priv_->id_string_.empty())
2433 {
2434 string s = get_name ();
2435
2436 if (!get_version().is_empty())
2437 {
2438 if (get_version().is_default())
2439 s += "@@";
2440 else
2441 s += "@";
2442 s += get_version().str();
2443 }
2444 priv_->id_string_ = s;
2445 }
2446
2447 return priv_->id_string_;
2448}
2449
2450/// From the aliases of the current symbol, lookup one with a given name.
2451///
2452/// @param name the name of symbol alias we are looking for.
2453///
2454/// @return the symbol alias that has the name @p name, or nil if none
2455/// has been found.
2457elf_symbol::get_alias_from_name(const string& name) const
2458{
2459 if (name == get_name())
2460 return elf_symbol_sptr(priv_->main_symbol_);
2461
2463 a && a.get() != get_main_symbol().get();
2464 a = a->get_next_alias())
2465 if (a->get_name() == name)
2466 return a;
2467
2468 return elf_symbol_sptr();
2469}
2470
2471/// In the list of aliases of a given elf symbol, get the alias that
2472/// equals this current symbol.
2473///
2474/// @param other the elf symbol to get the potential aliases from.
2475///
2476/// @return the alias of @p other that texually equals the current
2477/// symbol, or nil if no alias textually equals the current symbol.
2480{
2481 for (elf_symbol_sptr a = other.get_next_alias();
2482 a && a.get() != a->get_main_symbol().get();
2483 a = a->get_next_alias())
2484 if (textually_equals(*this, *a))
2485 return a;
2486 return elf_symbol_sptr();
2487}
2488
2489/// Return a comma separated list of the id of the current symbol as
2490/// well as the id string of its aliases.
2491///
2492/// @param syms a map of all the symbols of the corpus the current
2493/// symbol belongs to.
2494///
2495/// @param include_symbol_itself if set to true, then the name of the
2496/// current symbol is included in the list of alias names that is emitted.
2497///
2498/// @return the string.
2499string
2501 bool include_symbol_itself) const
2502{
2503 string result;
2504
2505 if (include_symbol_itself)
2506 result = get_id_string();
2507
2508 vector<elf_symbol_sptr> aliases;
2509 compute_aliases_for_elf_symbol(*this, syms, aliases);
2510 if (!aliases.empty() && include_symbol_itself)
2511 result += ", ";
2512
2513 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2514 i != aliases.end();
2515 ++i)
2516 {
2517 if (i != aliases.begin())
2518 result += ", ";
2519 result += (*i)->get_id_string();
2520 }
2521 return result;
2522}
2523
2524/// Return a comma separated list of the id of the current symbol as
2525/// well as the id string of its aliases.
2526///
2527/// @param include_symbol_itself if set to true, then the name of the
2528/// current symbol is included in the list of alias names that is emitted.
2529///
2530/// @return the string.
2531string
2532elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2533{
2534 vector<elf_symbol_sptr> aliases;
2535 if (include_symbol_itself)
2536 aliases.push_back(get_main_symbol());
2537
2539 a && a.get() != get_main_symbol().get();
2540 a = a->get_next_alias())
2541 aliases.push_back(a);
2542
2543 string result;
2544 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2545 i != aliases.end();
2546 ++i)
2547 {
2548 if (i != aliases.begin())
2549 result += ", ";
2550 result += (*i)->get_id_string();
2551 }
2552
2553 return result;
2554}
2555
2556/// Given the ID of a symbol, get the name and the version of said
2557/// symbol.
2558///
2559/// @param id the symbol ID to consider.
2560///
2561/// @param name the symbol name extracted from the ID. This is set
2562/// only if the function returned true.
2563///
2564/// @param ver the symbol version extracted from the ID.
2565bool
2567 string& name,
2568 string& ver)
2569{
2570 name.clear(), ver.clear();
2571
2572 string::size_type i = id.find('@');
2573 if (i == string::npos)
2574 {
2575 name = id;
2576 return true;
2577 }
2578
2579 name = id.substr(0, i);
2580 ++i;
2581
2582 if (i >= id.size())
2583 return true;
2584
2585 string::size_type j = id.find('@', i);
2586 if (j == string::npos)
2587 j = i;
2588 else
2589 ++j;
2590
2591 if (j >= id.size())
2592 {
2593 ver = "";
2594 return true;
2595 }
2596
2597 ver = id.substr(j);
2598 return true;
2599}
2600
2601///@}
2602
2603/// Test if two main symbols are textually equal, or, if they have
2604/// aliases that are textually equal.
2605///
2606/// @param other the symbol to compare against.
2607///
2608/// @return true iff the current instance of elf symbol equals the @p
2609/// other.
2610bool
2612{
2613 bool are_equal = textually_equals(*this, other);
2614 if (!are_equal)
2615 are_equal = bool(get_alias_which_equals(other));
2616 return are_equal;
2617}
2618
2619/// Test if the current symbol aliases another one.
2620///
2621/// @param o the other symbol to test against.
2622///
2623/// @return true iff the current symbol aliases @p o.
2624bool
2626{
2627 if (*this == o)
2628 return true;
2629
2630 if (get_main_symbol() == o.get_main_symbol())
2631 return true;
2632
2634 a && !a->is_main_symbol();
2635 a = a->get_next_alias())
2636 {
2637 if (o == *a)
2638 return true;
2639 }
2640 return false;
2641}
2642
2643/// Equality operator for smart pointers to elf_symbol.
2644///
2645/// @param lhs the first elf symbol to consider.
2646///
2647/// @param rhs the second elf symbol to consider.
2648///
2649/// @return true iff @p lhs equals @p rhs.
2650bool
2652{
2653 if (!!lhs != !!rhs)
2654 return false;
2655
2656 if (!lhs)
2657 return true;
2658
2659 return *lhs == *rhs;
2660}
2661
2662/// Inequality operator for smart pointers to elf_symbol.
2663///
2664/// @param lhs the first elf symbol to consider.
2665///
2666/// @param rhs the second elf symbol to consider.
2667///
2668/// @return true iff @p lhs is different from @p rhs.
2669bool
2671{return !operator==(lhs, rhs);}
2672
2673/// Test if two symbols alias.
2674///
2675/// @param s1 the first symbol to consider.
2676///
2677/// @param s2 the second symbol to consider.
2678///
2679/// @return true if @p s1 aliases @p s2.
2680bool
2682{return s1.does_alias(s2) || s2.does_alias(s1);}
2683
2684void
2685compute_aliases_for_elf_symbol(const elf_symbol& sym,
2686 const string_elf_symbols_map_type& symtab,
2687 vector<elf_symbol_sptr>& aliases)
2688{
2689
2690 if (elf_symbol_sptr a = sym.get_next_alias())
2691 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2692 aliases.push_back(a);
2693 else
2694 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2695 i != symtab.end();
2696 ++i)
2697 for (elf_symbols::const_iterator j = i->second.begin();
2698 j != i->second.end();
2699 ++j)
2700 {
2701 if (**j == sym)
2702 for (elf_symbol_sptr s = (*j)->get_next_alias();
2703 s && !s->is_main_symbol();
2704 s = s->get_next_alias())
2705 aliases.push_back(s);
2706 else
2707 for (elf_symbol_sptr s = (*j)->get_next_alias();
2708 s && !s->is_main_symbol();
2709 s = s->get_next_alias())
2710 if (*s == sym)
2711 aliases.push_back(*j);
2712 }
2713}
2714
2715/// Test if two symbols alias.
2716///
2717/// @param s1 the first symbol to consider.
2718///
2719/// @param s2 the second symbol to consider.
2720///
2721/// @return true if @p s1 aliases @p s2.
2722bool
2724{
2725 if (!!s1 != !!s2)
2726 return false;
2727 if (s1 == s2)
2728 return true;
2729 return elf_symbols_alias(*s1, *s2);
2730}
2731
2732/// Test if two symbols alias.
2733///
2734/// @param s1 the first symbol to consider.
2735///
2736/// @param s2 the second symbol to consider.
2737///
2738/// @return true if @p s1 aliases @p s2.
2739bool
2741{return elf_symbols_alias(s1.get(), s2.get());}
2742
2743/// Serialize an instance of @ref symbol_type and stream it to a given
2744/// output stream.
2745///
2746/// @param o the output stream to serialize the symbole type to.
2747///
2748/// @param t the symbol type to serialize.
2749std::ostream&
2750operator<<(std::ostream& o, elf_symbol::type t)
2751{
2752 string repr;
2753
2754 switch (t)
2755 {
2756 case elf_symbol::NOTYPE_TYPE:
2757 repr = "unspecified symbol type";
2758 break;
2759 case elf_symbol::OBJECT_TYPE:
2760 repr = "variable symbol type";
2761 break;
2762 case elf_symbol::FUNC_TYPE:
2763 repr = "function symbol type";
2764 break;
2765 case elf_symbol::SECTION_TYPE:
2766 repr = "section symbol type";
2767 break;
2768 case elf_symbol::FILE_TYPE:
2769 repr = "file symbol type";
2770 break;
2771 case elf_symbol::COMMON_TYPE:
2772 repr = "common data object symbol type";
2773 break;
2774 case elf_symbol::TLS_TYPE:
2775 repr = "thread local data object symbol type";
2776 break;
2777 case elf_symbol::GNU_IFUNC_TYPE:
2778 repr = "indirect function symbol type";
2779 break;
2780 default:
2781 {
2782 std::ostringstream s;
2783 s << "unknown symbol type (" << (char)t << ')';
2784 repr = s.str();
2785 }
2786 break;
2787 }
2788
2789 o << repr;
2790 return o;
2791}
2792
2793/// Serialize an instance of @ref symbol_binding and stream it to a
2794/// given output stream.
2795///
2796/// @param o the output stream to serialize the symbole type to.
2797///
2798/// @param b the symbol binding to serialize.
2799std::ostream&
2800operator<<(std::ostream& o, elf_symbol::binding b)
2801{
2802 string repr;
2803
2804 switch (b)
2805 {
2806 case elf_symbol::LOCAL_BINDING:
2807 repr = "local binding";
2808 break;
2809 case elf_symbol::GLOBAL_BINDING:
2810 repr = "global binding";
2811 break;
2812 case elf_symbol::WEAK_BINDING:
2813 repr = "weak binding";
2814 break;
2815 case elf_symbol::GNU_UNIQUE_BINDING:
2816 repr = "GNU unique binding";
2817 break;
2818 default:
2819 {
2820 std::ostringstream s;
2821 s << "unknown binding (" << (unsigned char) b << ")";
2822 repr = s.str();
2823 }
2824 break;
2825 }
2826
2827 o << repr;
2828 return o;
2829}
2830
2831/// Serialize an instance of @ref elf_symbol::visibility and stream it
2832/// to a given output stream.
2833///
2834/// @param o the output stream to serialize the symbole type to.
2835///
2836/// @param v the symbol visibility to serialize.
2837std::ostream&
2838operator<<(std::ostream& o, elf_symbol::visibility v)
2839{
2840 string repr;
2841
2842 switch (v)
2843 {
2844 case elf_symbol::DEFAULT_VISIBILITY:
2845 repr = "default visibility";
2846 break;
2847 case elf_symbol::PROTECTED_VISIBILITY:
2848 repr = "protected visibility";
2849 break;
2850 case elf_symbol::HIDDEN_VISIBILITY:
2851 repr = "hidden visibility";
2852 break;
2853 case elf_symbol::INTERNAL_VISIBILITY:
2854 repr = "internal visibility";
2855 break;
2856 default:
2857 {
2858 std::ostringstream s;
2859 s << "unknown visibility (" << (unsigned char) v << ")";
2860 repr = s.str();
2861 }
2862 break;
2863 }
2864
2865 o << repr;
2866 return o;
2867}
2868
2869/// Convert a string representing a symbol type into an
2870/// elf_symbol::type.
2871///
2872///@param s the string to convert.
2873///
2874///@param t the resulting elf_symbol::type.
2875///
2876/// @return true iff the conversion completed successfully.
2877bool
2879{
2880 if (s == "no-type")
2881 t = elf_symbol::NOTYPE_TYPE;
2882 else if (s == "object-type")
2883 t = elf_symbol::OBJECT_TYPE;
2884 else if (s == "func-type")
2885 t = elf_symbol::FUNC_TYPE;
2886 else if (s == "section-type")
2887 t = elf_symbol::SECTION_TYPE;
2888 else if (s == "file-type")
2889 t = elf_symbol::FILE_TYPE;
2890 else if (s == "common-type")
2891 t = elf_symbol::COMMON_TYPE;
2892 else if (s == "tls-type")
2893 t = elf_symbol::TLS_TYPE;
2894 else if (s == "gnu-ifunc-type")
2895 t = elf_symbol::GNU_IFUNC_TYPE;
2896 else
2897 return false;
2898
2899 return true;
2900}
2901
2902/// Convert a string representing a an elf symbol binding into an
2903/// elf_symbol::binding.
2904///
2905/// @param s the string to convert.
2906///
2907/// @param b the resulting elf_symbol::binding.
2908///
2909/// @return true iff the conversion completed successfully.
2910bool
2912{
2913 if (s == "local-binding")
2914 b = elf_symbol::LOCAL_BINDING;
2915 else if (s == "global-binding")
2916 b = elf_symbol::GLOBAL_BINDING;
2917 else if (s == "weak-binding")
2918 b = elf_symbol::WEAK_BINDING;
2919 else if (s == "gnu-unique-binding")
2920 b = elf_symbol::GNU_UNIQUE_BINDING;
2921 else
2922 return false;
2923
2924 return true;
2925}
2926
2927/// Convert a string representing a an elf symbol visibility into an
2928/// elf_symbol::visibility.
2929///
2930/// @param s the string to convert.
2931///
2932/// @param b the resulting elf_symbol::visibility.
2933///
2934/// @return true iff the conversion completed successfully.
2935bool
2937{
2938 if (s == "default-visibility")
2939 v = elf_symbol::DEFAULT_VISIBILITY;
2940 else if (s == "protected-visibility")
2941 v = elf_symbol::PROTECTED_VISIBILITY;
2942 else if (s == "hidden-visibility")
2943 v = elf_symbol::HIDDEN_VISIBILITY;
2944 else if (s == "internal-visibility")
2945 v = elf_symbol::INTERNAL_VISIBILITY;
2946 else
2947 return false;
2948
2949 return true;
2950}
2951
2952/// Test if the type of an ELF symbol denotes a function symbol.
2953///
2954/// @param t the type of the ELF symbol.
2955///
2956/// @return true iff elf symbol type @p t denotes a function symbol
2957/// type.
2958bool
2960{return t == elf_symbol::FUNC_TYPE;}
2961
2962/// Test if the type of an ELF symbol denotes a function symbol.
2963///
2964/// @param t the type of the ELF symbol.
2965///
2966/// @return true iff elf symbol type @p t denotes a function symbol
2967/// type.
2968bool
2970{return t == elf_symbol::OBJECT_TYPE;}
2971
2972// <elf_symbol::version stuff>
2973
2974struct elf_symbol::version::priv
2975{
2976 string version_;
2977 bool is_default_;
2978
2979 priv()
2980 : is_default_(false)
2981 {}
2982
2983 priv(const string& v,
2984 bool d)
2985 : version_(v),
2986 is_default_(d)
2987 {}
2988}; // end struct elf_symbol::version::priv
2989
2990elf_symbol::version::version()
2991 : priv_(new priv)
2992{}
2993
2994/// @param v the name of the version.
2995///
2996/// @param is_default true if this is a default version.
2997elf_symbol::version::version(const string& v,
2998 bool is_default)
2999 : priv_(new priv(v, is_default))
3000{}
3001
3002elf_symbol::version::version(const elf_symbol::version& v)
3003 : priv_(new priv(v.str(), v.is_default()))
3004{
3005}
3006
3007elf_symbol::version::~version() = default;
3008
3009/// Cast the version_type into a string that is its name.
3010///
3011/// @return the name of the version.
3012elf_symbol::version::operator const string&() const
3013{return priv_->version_;}
3014
3015/// Getter for the version name.
3016///
3017/// @return the version name.
3018const string&
3020{return priv_->version_;}
3021
3022/// Setter for the version name.
3023///
3024/// @param s the version name.
3025void
3027{priv_->version_ = s;}
3028
3029/// Getter for the 'is_default' property of the version.
3030///
3031/// @return true iff this is a default version.
3032bool
3034{return priv_->is_default_;}
3035
3036/// Setter for the 'is_default' property of the version.
3037///
3038/// @param f true if this is the default version.
3039void
3041{priv_->is_default_ = f;}
3042
3043bool
3044elf_symbol::version::is_empty() const
3045{return str().empty();}
3046
3047/// Compares the current version against another one.
3048///
3049/// @param o the other version to compare the current one to.
3050///
3051/// @return true iff the current version equals @p o.
3052bool
3054{return str() == o.str();}
3055
3056/// Inequality operator.
3057///
3058/// @param o the version to compare against the current one.
3059///
3060/// @return true iff both versions are different.
3061bool
3063{return !operator==(o);}
3064
3065/// Assign a version to the current one.
3066///
3067/// @param o the other version to assign to this one.
3068///
3069/// @return a reference to the assigned version.
3072{
3073 str(o.str());
3074 is_default(o.is_default());
3075 return *this;
3076}
3077
3078// </elf_symbol::version stuff>
3079
3080// </elf_symbol stuff>
3081
3082// <class dm_context_rel stuff>
3083struct dm_context_rel::priv
3084{
3085 bool is_laid_out_;
3086 size_t offset_in_bits_;
3087 var_decl* anonymous_data_member_;
3088
3089 priv(bool is_static = false)
3090 : is_laid_out_(!is_static),
3091 offset_in_bits_(0),
3092 anonymous_data_member_()
3093 {}
3094
3095 priv(bool is_laid_out, size_t offset_in_bits)
3096 : is_laid_out_(is_laid_out),
3097 offset_in_bits_(offset_in_bits),
3098 anonymous_data_member_()
3099 {}
3100}; //end struct dm_context_rel::priv
3101
3102dm_context_rel::dm_context_rel()
3103 : context_rel(),
3104 priv_(new priv)
3105{}
3106
3107dm_context_rel::dm_context_rel(scope_decl* s,
3108 bool is_laid_out,
3109 size_t offset_in_bits,
3111 bool is_static)
3112 : context_rel(s, a, is_static),
3113 priv_(new priv(is_laid_out, offset_in_bits))
3114{}
3115
3116dm_context_rel::dm_context_rel(scope_decl* s)
3117 : context_rel(s),
3118 priv_(new priv())
3119{}
3120
3121bool
3122dm_context_rel::get_is_laid_out() const
3123{return priv_->is_laid_out_;}
3124
3125void
3126dm_context_rel::set_is_laid_out(bool f)
3127{priv_->is_laid_out_ = f;}
3128
3129size_t
3130dm_context_rel::get_offset_in_bits() const
3131{return priv_->offset_in_bits_;}
3132
3133void
3134dm_context_rel::set_offset_in_bits(size_t o)
3135{priv_->offset_in_bits_ = o;}
3136
3137bool
3138dm_context_rel::operator==(const dm_context_rel& o) const
3139{
3140 if (!context_rel::operator==(o))
3141 return false;
3142
3143 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3144 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3145}
3146
3147bool
3148dm_context_rel::operator!=(const dm_context_rel& o) const
3149{return !operator==(o);}
3150
3151/// Return a non-nil value if this data member context relationship
3152/// has an anonymous data member. That means, if the data member this
3153/// relation belongs to is part of an anonymous data member.
3154///
3155/// @return the containing anonymous data member of this data member
3156/// relationship. Nil if there is none.
3157const var_decl*
3159{return priv_->anonymous_data_member_;}
3160
3161/// Set the containing anonymous data member of this data member
3162/// context relationship. That means that the data member this
3163/// relation belongs to is part of an anonymous data member.
3164///
3165/// @param anon_dm the containing anonymous data member of this data
3166/// member relationship. Nil if there is none.
3167void
3169{priv_->anonymous_data_member_ = anon_dm;}
3170
3171dm_context_rel::~dm_context_rel()
3172{}
3173// </class dm_context_rel stuff>
3174
3175// <environment stuff>
3176
3177/// Convenience typedef for a map of interned_string -> bool.
3178typedef unordered_map<interned_string,
3180
3181
3182/// Default constructor of the @ref environment type.
3184 :priv_(new priv)
3185{}
3186
3187/// Destructor for the @ref environment type.
3189{}
3190
3191/// Getter the map of canonical types.
3192///
3193/// @return the map of canonical types. The key of the map is the
3194/// hash of the canonical type and its value if the canonical type.
3197{return priv_->canonical_types_;}
3198
3199/// Getter the map of canonical types.
3200///
3201/// @return the map of canonical types. The key of the map is the
3202/// hash of the canonical type and its value if the canonical type.
3205{return const_cast<environment*>(this)->get_canonical_types_map();}
3206
3207/// Helper to detect if a type is either a reference, a pointer, or a
3208/// qualified type.
3209static bool
3210is_ptr_ref_or_qual_type(const type_base *t)
3211{
3212 if (is_pointer_type(t)
3213 || is_reference_type(t)
3214 || is_qualified_type(t))
3215 return true;
3216 return false;
3217}
3218
3219/// Compare decls using their locations.
3220///
3221/// @param f the first decl to compare.
3222///
3223/// @param s the second decl to compare.
3224///
3225/// @return true if @p f compares less than @p s.
3226static bool
3227compare_using_locations(const decl_base *f,
3228 const decl_base *s)
3229{
3230 // If a decl has artificial location, then use that one over the
3231 // natural one.
3234
3235 ABG_ASSERT(fl.get_value() && sl.get_value());
3236 if (fl.get_is_artificial() == sl.get_is_artificial())
3237 {
3238 // The locations of the two artfifacts have the same
3239 // artificial-ness so they can be compared.
3240 string p1, p2;
3241 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3242 fl.expand(p1, l1, c1);
3243 sl.expand(p2, l2, c2);
3244 if (p1 != p2)
3245 return p1 < p2;
3246 if (l1 != l2)
3247 return l1 < l2;
3248 if (c1 != c2)
3249 return c1 < c2;
3250 }
3251
3252 return (get_pretty_representation(f, /*internal=*/false)
3253 < get_pretty_representation(s, /*internal=*/false));
3254}
3255
3256/// A functor to sort decls somewhat topologically. That is, types
3257/// are sorted in a way that makes the ones that are defined "first"
3258/// to come first.
3259///
3260/// The topological criteria is a lexicographic sort of the definition
3261/// location of the type. For types that have no location (or the
3262/// same location), it's their qualified name that is used for the
3263/// lexicographic sort.
3264struct decl_topo_comp
3265{
3266
3267 /// The "Less Than" comparison operator of this functor.
3268 ///
3269 /// @param f the first decl to be considered for the comparison.
3270 ///
3271 /// @param s the second decl to be considered for the comparison.
3272 ///
3273 /// @return true iff @p f is less than @p s.
3274 bool
3275 operator()(const decl_base *f,
3276 const decl_base *s)
3277 {
3278 if (!!f != !!s)
3279 return f && !s;
3280
3281 if (!f)
3282 return false;
3283
3284 // Unique types that are artificially created in the environment
3285 // don't have locations. They ought to be compared on the basis
3286 // of their pretty representation before we start looking at IR
3287 // nodes' locations down the road.
3289 return (get_pretty_representation(f, /*internal=*/false)
3290 < get_pretty_representation(s, /*internal=*/false));
3291
3292 // If both decls come from an abixml file, keep the order they
3293 // have from that abixml file.
3294 if ((!f->get_corpus() && !s->get_corpus())
3295 || (f->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
3296 && s->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN))
3297 return compare_using_locations(f, s);
3298
3299 // If a decl has artificial location, then use that one over the
3300 // natural one.
3301 location fl = get_artificial_or_natural_location(f);
3302 location sl = get_artificial_or_natural_location(s);
3303
3304 if (fl.get_value() && sl.get_value())
3305 return compare_using_locations(f, s);
3306 else if (!!fl != !!sl)
3307 // So one of the decls doesn't have location data.
3308 // The first decl is less than the second if it's the one not
3309 // having location data.
3310 return !fl && sl;
3311
3312 // We reach this point if location data is useless.
3313 if (f->get_is_anonymous()
3314 && s->get_is_anonymous()
3315 && (get_pretty_representation(f, /*internal=*/false)
3316 == get_pretty_representation(s, /*internal=*/false)))
3317 return f->get_name() < s->get_name();
3318
3319 return (get_pretty_representation(f, /*internal=*/false)
3320 < get_pretty_representation(s, /*internal=*/false));
3321 }
3322
3323 /// The "Less Than" comparison operator of this functor.
3324 ///
3325 /// @param f the first decl to be considered for the comparison.
3326 ///
3327 /// @param s the second decl to be considered for the comparison.
3328 ///
3329 /// @return true iff @p f is less than @p s.
3330 bool
3331 operator()(const decl_base_sptr &f,
3332 const decl_base_sptr &s)
3333 {return operator()(f.get(), s.get());}
3334
3335}; // end struct decl_topo_comp
3336
3337/// A functor to sort types somewhat topologically. That is, types
3338/// are sorted in a way that makes the ones that are defined "first"
3339/// to come first.
3340///
3341/// The topological criteria is a lexicographic sort of the definition
3342/// location of the type. For types that have no location, it's their
3343/// qualified name that is used for the lexicographic sort.
3344struct type_topo_comp
3345{
3346 /// Test if a decl has an artificial or natural location.
3347 ///
3348 /// @param d the decl to consider
3349 ///
3350 /// @return true iff @p d has a location.
3351 bool
3352 has_artificial_or_natural_location(const decl_base* d)
3354
3355 /// Test if a type has an artificial or natural location.
3356 ///
3357 /// @param t the type to consider
3358 ///
3359 /// @return true iff @p t has a location.
3360 bool
3361 has_artificial_or_natural_location(const type_base* t)
3362 {
3363 if (decl_base *d = is_decl(t))
3364 return has_artificial_or_natural_location(d);
3365 return false;
3366 }
3367
3368 /// The "Less Than" comparison operator of this functor.
3369 ///
3370 /// @param f the first type to be considered for the comparison.
3371 ///
3372 /// @param s the second type to be considered for the comparison.
3373 ///
3374 /// @return true iff @p f is less than @p s.
3375 bool
3376 operator()(const type_base_sptr &f,
3377 const type_base_sptr &s)
3378 {return operator()(f.get(), s.get());}
3379
3380 /// The "Less Than" comparison operator of this functor.
3381 ///
3382 /// @param f the first type to be considered for the comparison.
3383 ///
3384 /// @param s the second type to be considered for the comparison.
3385 ///
3386 /// @return true iff @p f is less than @p s.
3387 bool
3388 operator()(const type_base *f,
3389 const type_base *s)
3390 {
3391 // If both decls come from an abixml file, keep the order they
3392 // have from that abixml file.
3393 if ((!f->get_corpus() && !s->get_corpus())
3394 || (f->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
3395 && s->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN))
3396 return compare_using_locations(is_decl(f), is_decl(s));
3397
3398 bool f_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(f);
3399 bool s_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(s);
3400
3401 if (f_is_ptr_ref_or_qual != s_is_ptr_ref_or_qual)
3402 return !f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual;
3403
3404 if (f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual
3405 && !has_artificial_or_natural_location(f)
3406 && !has_artificial_or_natural_location(s))
3407 {
3408 string s1 = get_pretty_representation(f, /*internal=*/false);
3409 string s2 = get_pretty_representation(s, /*internal=*/false);
3410 if (s1 == s2)
3411 {
3412 if (qualified_type_def * q = is_qualified_type(f))
3413 {
3414 if (q->get_cv_quals() == qualified_type_def::CV_NONE)
3415 if (!is_qualified_type(s))
3416 // We are looking at two types that are the result of
3417 // an optimization that happens during the IR
3418 // construction. Namely, type f is a cv-qualified
3419 // type with no qualifier (no const, no volatile, no
3420 // nothing, we call it an empty-qualified type).
3421 // These are the result of an optimization which
3422 // removes "redundant qualifiers" from some types.
3423 // For instance, consider a "const reference". The
3424 // const there is redundant because a reference is
3425 // always const. So as a result of the optimizaton
3426 // that type is going to be transformed into an
3427 // empty-qualified reference. If we don't make that
3428 // optimization, then we risk having spurious change
3429 // reports down the road. But then, as a consequence
3430 // of that optimization, we need to sort the
3431 // empty-qualified type and its non-qualified variant
3432 // e.g, to ensure stability in the abixml output; both
3433 // types are logically equal, but here, we decide that
3434 // the empty-qualified one is topologically "less
3435 // than" the non-qualified counterpart.
3436 //
3437 // So here, type f is an empty-qualified type and type
3438 // s is its non-qualified variant. We decide that f
3439 // is topologically less than s.
3440 return true;
3441 }
3442 // Now let's peel off the pointer (or reference types) and
3443 // see if the ultimate underlying types have the same
3444 // textual representation; if not, use that as sorting
3445 // criterion.
3446 type_base *peeled_f =
3448 type_base *peeled_s =
3450
3451 s1 = get_pretty_representation(peeled_f, /*internal=*/false);
3452 s2 = get_pretty_representation(peeled_s, /*internal=*/false);
3453 if (s1 != s2)
3454 return s1 < s2;
3455
3456 // The underlying type of pointer/reference have the same
3457 // textual representation; let's try to peel of typedefs
3458 // as well and we'll consider sorting the result as decls.
3459 peeled_f = peel_typedef_pointer_or_reference_type(peeled_f, true);
3460 peeled_s = peel_typedef_pointer_or_reference_type(peeled_s, true);
3461
3462 s1 = get_pretty_representation(peeled_f, false);
3463 s2 = get_pretty_representation(peeled_s, false);
3464 if (s1 != s2)
3465 return s1 < s2;
3466 }
3467 }
3468
3469 string s1 = get_pretty_representation(f, false);
3470 string s2 = get_pretty_representation(s, false);
3471
3472 if (s1 != s2)
3473 return s1 < s2;
3474
3475 if (is_typedef(f) && is_typedef(s))
3476 {
3477 s1 = get_pretty_representation(is_typedef(f)->get_underlying_type(),
3478 false);
3479 s2 = get_pretty_representation(is_typedef(s)->get_underlying_type(),
3480 false);
3481 if (s1 != s2)
3482 return s1 < s2;
3483 }
3484
3485 type_base *peeled_f = peel_typedef_pointer_or_reference_type(f, true);
3486 type_base *peeled_s = peel_typedef_pointer_or_reference_type(s, true);
3487
3488 s1 = get_pretty_representation(peeled_f, false);
3489 s2 = get_pretty_representation(peeled_s, false);
3490
3491 if (s1 != s2)
3492 return s1 < s2;
3493
3494 decl_base *fd = is_decl(f);
3495 decl_base *sd = is_decl(s);
3496
3497 if (!!fd != !!sd)
3498 return fd && !sd;
3499
3500 // If the two types have no decls, how come we could not sort them
3501 // until now? Let's investigate.
3502 ABG_ASSERT(fd);
3503
3504 // From this point, fd and sd should be non-nil
3505 decl_topo_comp decl_comp;
3506 return decl_comp(fd, sd);
3507 }
3508}; //end struct type_topo_comp
3509
3510/// Sort types in a hopefully stable manner.
3511///
3512/// @param types a set of types with canonical types to sort.
3513///
3514/// @param result the resulting sorted vector.
3515void
3517 vector<type_base_sptr>& result)
3518{
3519 for (auto t: types)
3520 result.push_back(t);
3521
3522 type_topo_comp comp;
3523 std::stable_sort(result.begin(), result.end(), comp);
3524}
3525
3526/// Get the unique @ref type_decl that represents a "void" type for
3527/// the current environment. This node must be the only one
3528/// representing a void type in the system.
3529///
3530/// Note that upon first use of this IR node (by the relevant
3531/// front-end, for instance) it must be added to a scope using e.g,
3532/// the @ref add_decl_to_scope() function.
3533///
3534/// @return the @ref type_decl that represents a "void" type.
3535const type_base_sptr&
3537{
3538 if (!priv_->void_type_)
3539 priv_->void_type_.reset(new type_decl(*this,
3540 intern("void"),
3541 0, 0, location()));
3542 return priv_->void_type_;
3543}
3544
3545/// Getter of the "pointer-to-void" IR node that is shared across the
3546/// ABI corpus. This node must be the only one representing a void
3547/// pointer type in the system.
3548///
3549/// Note that upon first use of this IR node (by the relevant
3550/// front-end, for instance) it must be added to a scope using e.g,
3551/// the @ref add_decl_to_scope() function.
3552///
3553/// @return the "pointer-to-void" IR node.
3554const type_base_sptr&
3556{
3557 if (!priv_->void_pointer_type_)
3558 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3559 0, 0, location()));
3560 return priv_->void_pointer_type_;
3561}
3562
3563/// Get a @ref type_decl instance that represents a the type of a
3564/// variadic function parameter. This node must be the only one
3565/// representing a variadic parameter type in the system.
3566///
3567/// Note that upon first use of this IR node (by the relevant
3568/// front-end, for instance) it must be added to a scope using e.g,
3569/// the @ref add_decl_to_scope() function.
3570///
3571/// @return the Get a @ref type_decl instance that represents a the
3572/// type of a variadic function parameter.
3573const type_base_sptr&
3575{
3576 if (!priv_->variadic_marker_type_)
3577 priv_->variadic_marker_type_.
3579 0, 0, location()));
3580 return priv_->variadic_marker_type_;
3581}
3582
3583/// Getter of the name of the variadic parameter type.
3584///
3585/// @return the name of the variadic parameter type.
3586string&
3588{
3589 static string variadic_parameter_type_name = "variadic parameter type";
3590 return variadic_parameter_type_name;
3591}
3592
3593/// Test if the canonicalization of types created out of the current
3594/// environment is done.
3595///
3596/// @return true iff the canonicalization of types created out of the current
3597/// environment is done.
3598bool
3600{return priv_->canonicalization_is_done_;}
3601
3602/// Set a flag saying if the canonicalization of types created out of
3603/// the current environment is done or not.
3604///
3605/// Note that this function must only be called by internal code of
3606/// the library that creates ABI artifacts (e.g, read an abi corpus
3607/// from elf or from our own xml format and creates representations of
3608/// types out of it) and thus needs to canonicalize types to speed-up
3609/// further type comparison.
3610///
3611/// @param f the new value of the flag.
3612void
3614{priv_->canonicalization_is_done_ = f;}
3615
3616/// Getter for the "on-the-fly-canonicalization" flag.
3617///
3618/// @return true iff @ref OnTheFlyCanonicalization
3619/// "on-the-fly-canonicalization" is to be performed during
3620/// comparison.
3621bool
3623{return priv_->do_on_the_fly_canonicalization_;}
3624
3625/// Setter for the "on-the-fly-canonicalization" flag.
3626///
3627/// @param f If this is true then @ref OnTheFlyCanonicalization
3628/// "on-the-fly-canonicalization" is to be performed during
3629/// comparison.
3630void
3632{priv_->do_on_the_fly_canonicalization_ = f;}
3633
3634/// Getter of the "decl-only-class-equals-definition" flag.
3635///
3636/// Usually, a declaration-only class named 'struct foo' compares
3637/// equal to any class definition named "struct foo'. This is at
3638/// least true for C++.
3639///
3640/// In C, though, because there can be multiple definitions of 'struct
3641/// foo' in the binary, a declaration-only "struct foo" might be
3642/// considered to *NOT* resolve to any of the struct foo defined. In
3643/// that case, the declaration-only "struct foo" is considered
3644/// different from the definitions.
3645///
3646/// This flag controls the behaviour of the comparison of an
3647/// unresolved decl-only class against a definition of the same name.
3648///
3649/// If set to false, the the declaration equals the definition. If
3650/// set to false, then the decalration is considered different from
3651/// the declaration.
3652///
3653/// @return the value of the "decl-only-class-equals-definition" flag.
3654bool
3656{return priv_->decl_only_class_equals_definition_;}
3657
3658/// Setter of the "decl-only-class-equals-definition" flag.
3659///
3660/// Usually, a declaration-only class named 'struct foo' compares
3661/// equal to any class definition named "struct foo'. This is at
3662/// least true for C++.
3663///
3664/// In C, though, because there can be multiple definitions of 'struct
3665/// foo' in the binary, a declaration-only "struct foo" might be
3666/// considered to *NOT* resolve to any of the struct foo defined. In
3667/// that case, the declaration-only "struct foo" is considered
3668/// different from the definitions.
3669///
3670/// This flag controls the behaviour of the comparison of an
3671/// unresolved decl-only class against a definition of the same name.
3672///
3673/// If set to false, the the declaration equals the definition. If
3674/// set to false, then the decalration is considered different from
3675/// the declaration.
3676///
3677/// @param the new value of the "decl-only-class-equals-definition"
3678/// flag.
3679void
3681{priv_->decl_only_class_equals_definition_ = f;}
3682
3683/// Test if a given type is a void type as defined in the current
3684/// environment.
3685///
3686/// @param t the type to consider.
3687///
3688/// @return true iff @p t is a void type as defined in the current
3689/// environment.
3690bool
3691environment::is_void_type(const type_base_sptr& t) const
3692{
3693 if (!t)
3694 return false;
3695 return is_void_type(t.get());
3696}
3697
3698/// Test if a given type is a void type as defined in the current
3699/// environment.
3700///
3701/// @param t the type to consider.
3702///
3703/// @return true iff @p t is a void type as defined in the current
3704/// environment.
3705bool
3707{
3708 if (!t)
3709 return false;
3710 return (t == get_void_type().get()
3711 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3712}
3713
3714/// Test if a given type is the same as the void pointer type of the
3715/// environment.
3716///
3717/// @param t the IR type to test.
3718///
3719/// @return true iff @p t is the void pointer returned by
3720/// environment::get_void_pointer_type().
3721bool
3722environment::is_void_pointer_type(const type_base_sptr& t) const
3723{
3724 if (!t)
3725 return false;
3726
3727 return t.get() == get_void_pointer_type().get();
3728}
3729
3730/// Test if a given type is the same as the void pointer type of the
3731/// environment.
3732///
3733/// @param t the IR type to test.
3734///
3735/// @return true iff @p t is the void pointer returned by
3736/// environment::get_void_pointer_type().
3737bool
3739{
3740 if (!t)
3741 return false;
3742
3743 return t == get_void_pointer_type().get();
3744}
3745
3746/// Test if a type is a variadic parameter type as defined in the
3747/// current environment.
3748///
3749/// @param t the type to consider.
3750///
3751/// @return true iff @p t is a variadic parameter type as defined in
3752/// the current environment.
3753bool
3755{
3756 if (!t)
3757 return false;
3758 return t == get_variadic_parameter_type().get();
3759}
3760
3761/// Test if a type is a variadic parameter type as defined in the
3762/// current environment.
3763///
3764/// @param t the type to consider.
3765///
3766/// @return true iff @p t is a variadic parameter type as defined in
3767/// the current environment.
3768bool
3769environment::is_variadic_parameter_type(const type_base_sptr& t) const
3770{return is_variadic_parameter_type(t.get());}
3771
3772/// Do intern a string.
3773///
3774/// If a value of this string already exists in the interned string
3775/// pool of the current environment, then this function returns a new
3776/// interned_string pointing to that already existing string.
3777/// Otherwise, a new string is created, stored in the interned string
3778/// pool and a new interned_string instance is created to point to
3779/// that new intrerned string, and it's return.
3780///
3781/// @param s the value of the string to intern.
3782///
3783/// @return the interned string.
3785environment::intern(const string& s) const
3786{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3787
3788/// Getter of the general configuration object.
3789///
3790/// @return the configuration object.
3791const config&
3793{return priv_->config_;}
3794
3795/// Getter for a property that says if the user actually did set the
3796/// analyze_exported_interfaces_only() property. If not, it means
3797/// the default behaviour prevails.
3798///
3799/// @return tru iff the user did set the
3800/// analyze_exported_interfaces_only() property.
3801bool
3803{return priv_->analyze_exported_interfaces_only_.has_value();}
3804
3805/// Setter for the property that controls if we are to restrict the
3806/// analysis to the types that are only reachable from the exported
3807/// interfaces only, or if the set of types should be more broad than
3808/// that. Typically, we'd restrict the analysis to types reachable
3809/// from exported interfaces only (stricto sensu, that would really be
3810/// only the types that are part of the ABI of well designed
3811/// libraries) for performance reasons.
3812///
3813/// @param f the value of the flag.
3814void
3816{priv_->analyze_exported_interfaces_only_ = f;}
3817
3818/// Getter for the property that controls if we are to restrict the
3819/// analysis to the types that are only reachable from the exported
3820/// interfaces only, or if the set of types should be more broad than
3821/// that. Typically, we'd restrict the analysis to types reachable
3822/// from exported interfaces only (stricto sensu, that would really be
3823/// only the types that are part of the ABI of well designed
3824/// libraries) for performance reasons.
3825///
3826/// @param f the value of the flag.
3827bool
3829{return priv_->analyze_exported_interfaces_only_.value_or(false);}
3830
3831#ifdef WITH_DEBUG_SELF_COMPARISON
3832/// Setter of the corpus of the input corpus of the self comparison
3833/// that takes place when doing "abidw --debug-abidiff <binary>".
3834///
3835/// The first invocation of this function sets the first corpus of the
3836/// self comparison. The second invocation of this very same function
3837/// sets the second corpus of the self comparison. That second corpus
3838/// is supposed to come from the abixml serialization of the first
3839/// corpus.
3840///
3841/// @param c the corpus of the input binary or the corpus of the
3842/// abixml serialization of the initial binary input.
3843void
3844environment::set_self_comparison_debug_input(const corpus_sptr& c)
3845{
3846 self_comparison_debug_is_on(true);
3847 if (priv_->first_self_comparison_corpus_.expired())
3848 priv_->first_self_comparison_corpus_ = c;
3849 else if (priv_->second_self_comparison_corpus_.expired()
3850 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3851 priv_->second_self_comparison_corpus_ = c;
3852}
3853
3854/// Getter for the corpora of the input binary and the intermediate
3855/// abixml of the self comparison that takes place when doing
3856/// 'abidw --debug-abidiff <binary>'.
3857///
3858/// @param first_corpus output parameter that is set to the corpus of
3859/// the input corpus.
3860///
3861/// @param second_corpus output parameter that is set to the corpus of
3862/// the second corpus.
3863void
3864environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3865 corpus_sptr& second_corpus)
3866{
3867 first_corpus = priv_->first_self_comparison_corpus_.lock();
3868 second_corpus = priv_->second_self_comparison_corpus_.lock();
3869}
3870
3871/// Turn on/off the self comparison debug mode.
3872///
3873/// @param f true iff the self comparison debug mode is turned on.
3874void
3875environment::self_comparison_debug_is_on(bool f)
3876{priv_->self_comparison_debug_on_ = f;}
3877
3878/// Test if we are in the process of the 'self-comparison
3879/// debugging' as triggered by 'abidw --debug-abidiff' command.
3880///
3881/// @return true if self comparison debug is on.
3882bool
3883environment::self_comparison_debug_is_on() const
3884{return priv_->self_comparison_debug_on_;}
3885#endif
3886
3887#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3888/// Set the "type canonicalization debugging" mode, triggered by using
3889/// the command: "abidw --debug-tc".
3890///
3891/// @param flag if true then the type canonicalization debugging mode
3892/// is enabled.
3893void
3894environment::debug_type_canonicalization_is_on(bool flag)
3895{priv_->debug_type_canonicalization_ = flag;}
3896
3897/// Getter of the "type canonicalization debugging" mode, triggered by
3898/// using the command: "abidw --debug-tc".
3899///
3900/// @return true iff the type canonicalization debugging mode is
3901/// enabled.
3902bool
3903environment::debug_type_canonicalization_is_on() const
3904{return priv_->debug_type_canonicalization_;}
3905
3906/// Setter of the "DIE canonicalization debugging" mode, triggered by
3907/// using the command: "abidw --debug-dc".
3908///
3909/// @param flag true iff the DIE canonicalization debugging mode is
3910/// enabled.
3911void
3912environment::debug_die_canonicalization_is_on(bool flag)
3913{priv_->debug_die_canonicalization_ = flag;}
3914
3915/// Getter of the "DIE canonicalization debugging" mode, triggered by
3916/// using the command: "abidw --debug-dc".
3917///
3918/// @return true iff the DIE canonicalization debugging mode is
3919/// enabled.
3920bool
3921environment::debug_die_canonicalization_is_on() const
3922{return priv_->debug_die_canonicalization_;}
3923#endif // WITH_DEBUG_TYPE_CANONICALIZATION
3924
3925/// Get the vector of canonical types which have a given "string
3926/// representation".
3927///
3928/// @param 'name', the textual representation of the type as returned
3929/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3930/// /*qualified=*/true)
3931///
3932/// This is useful to for debugging purposes as it's handy to use from
3933/// inside a debugger like GDB.
3934///
3935/// @return a pointer to the vector of canonical types having the
3936/// representation @p name, or nullptr if no type with that
3937/// representation exists.
3938vector<type_base_sptr>*
3940{
3941 auto ti = get_canonical_types_map().find(name);
3942 if (ti == get_canonical_types_map().end())
3943 return nullptr;
3944 return &ti->second;
3945}
3946
3947/// Get a given canonical type which has a given "string
3948/// representation".
3949///
3950/// @param 'name', the textual representation of the type as returned
3951/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3952/// /*qualified=*/true).
3953///
3954/// @param index, the index of the type in the vector of types that
3955/// all have the same textual representation @p 'name'. That vector
3956/// is returned by the function environment::get_canonical_types().
3957///
3958/// @return the canonical type which has the representation @p name,
3959/// and which is at index @p index in the vector of canonical types
3960/// having that same textual representation.
3961type_base*
3962environment::get_canonical_type(const char* name, unsigned index)
3963{
3964 vector<type_base_sptr> *types = get_canonical_types(name);
3965 if (!types ||index >= types->size())
3966 return nullptr;
3967 return (*types)[index].get();
3968}
3969
3970#ifdef WITH_DEBUG_SELF_COMPARISON
3971/// Get the set of abixml type-id and the pointer value of the
3972/// (canonical) type it's associated to.
3973///
3974/// This is useful for debugging purposes, especially in the context
3975/// of the use of the command:
3976/// 'abidw --debug-abidiff <binary>'.
3977///
3978/// @return the set of abixml type-id and the pointer value of the
3979/// (canonical) type it's associated to.
3980const unordered_map<string, uintptr_t>&
3981environment::get_type_id_canonical_type_map() const
3982{return priv_->get_type_id_canonical_type_map();}
3983
3984/// Get the set of abixml type-id and the pointer value of the
3985/// (canonical) type it's associated to.
3986///
3987/// This is useful for debugging purposes, especially in the context
3988/// of the use of the command:
3989/// 'abidw --debug-abidiff <binary>'.
3990///
3991/// @return the set of abixml type-id and the pointer value of the
3992/// (canonical) type it's associated to.
3993unordered_map<string, uintptr_t>&
3994environment::get_type_id_canonical_type_map()
3995{return priv_->get_type_id_canonical_type_map();}
3996
3997/// Getter of the map that associates the values of type pointers to
3998/// their type-id strings.
3999///
4000/// Note that this map is populated at abixml reading time, (by
4001/// build_type()) when a given XML element representing a type is
4002/// read into a corresponding abigail::ir::type_base.
4003///
4004/// This is used only for the purpose of debugging the
4005/// self-comparison process. That is, when invoking "abidw
4006/// --debug-abidiff".
4007///
4008/// @return the map that associates the values of type pointers to
4009/// their type-id strings.
4010const unordered_map<uintptr_t, string>&
4011environment::get_pointer_type_id_map() const
4012{return priv_->get_pointer_type_id_map();}
4013
4014/// Getter of the map that associates the values of type pointers to
4015/// their type-id strings.
4016///
4017/// Note that this map is populated at abixml reading time, (by
4018/// build_type()) when a given XML element representing a type is
4019/// read into a corresponding abigail::ir::type_base.
4020///
4021/// This is used only for the purpose of debugging the
4022/// self-comparison process. That is, when invoking "abidw
4023/// --debug-abidiff".
4024///
4025/// @return the map that associates the values of type pointers to
4026/// their type-id strings.
4027unordered_map<uintptr_t, string>&
4028environment::get_pointer_type_id_map()
4029{return priv_->get_pointer_type_id_map();}
4030
4031/// Getter of the type-id that corresponds to the value of a pointer
4032/// to abigail::ir::type_base that was created from the abixml reader.
4033///
4034/// That value is retrieved from the map returned from
4035/// environment::get_pointer_type_id_map().
4036///
4037/// That map is populated at abixml reading time, (by build_type())
4038/// when a given XML element representing a type is read into a
4039/// corresponding abigail::ir::type_base.
4040///
4041/// This is used only for the purpose of debugging the
4042/// self-comparison process. That is, when invoking "abidw
4043/// --debug-abidiff".
4044///
4045/// @return the type-id strings that corresponds
4046string
4047environment::get_type_id_from_pointer(uintptr_t ptr) const
4048{return priv_->get_type_id_from_pointer(ptr);}
4049
4050/// Getter of the type-id that corresponds to the value of an
4051/// abigail::ir::type_base that was created from the abixml reader.
4052///
4053/// That value is retrieved from the map returned from
4054/// environment::get_pointer_type_id_map().
4055///
4056/// That map is populated at abixml reading time, (by build_type())
4057/// when a given XML element representing a type is read into a
4058/// corresponding abigail::ir::type_base.
4059///
4060/// This is used only for the purpose of debugging the
4061/// self-comparison process. That is, when invoking "abidw
4062/// --debug-abidiff".
4063///
4064/// @return the type-id strings that corresponds
4065string
4066environment::get_type_id_from_type(const type_base *t) const
4067{return priv_->get_type_id_from_type(t);}
4068
4069/// Getter of the canonical type of the artifact designated by a
4070/// type-id.
4071///
4072/// That type-id was generated by the abixml writer at the emitting
4073/// time of the abixml file. The corresponding canonical type was
4074/// stored in the map returned by
4075/// environment::get_type_id_canonical_type_map().
4076///
4077/// This is useful for debugging purposes, especially in the context
4078/// of the use of the command:
4079/// 'abidw --debug-abidiff <binary>'.
4080///
4081/// @return the set of abixml type-id and the pointer value of the
4082/// (canonical) type it's associated to.
4083uintptr_t
4084environment::get_canonical_type_from_type_id(const char* type_id) const
4085{return priv_->get_canonical_type_from_type_id(type_id);}
4086#endif
4087
4088// </environment stuff>
4089
4090// <type_or_decl_base stuff>
4091
4092/// The private data of @ref type_or_decl_base.
4093struct type_or_decl_base::priv
4094{
4095 // This holds the kind of dynamic type of particular instance.
4096 // Yes, this is part of the implementation of a "poor man" runtime
4097 // type identification. We are doing this because profiling shows
4098 // that using dynamic_cast in some places is really to slow and is
4099 // constituting a hotspot. This poor man's implementation made
4100 // things be much faster.
4101 enum type_or_decl_kind kind_;
4102 // This holds the runtime type instance pointer of particular
4103 // instance. In other words, this is the "this pointer" of the
4104 // dynamic type of a particular instance.
4105 void* rtti_;
4106 // This holds a pointer to either the type_base sub-object (if the
4107 // current instance is a type) or the decl_base sub-object (if the
4108 // current instance is a decl). This is used by the is_decl() and
4109 // is_type() functions, which also show up during profiling as
4110 // hotspots, due to their use of dynamic_cast.
4111 void* type_or_decl_ptr_;
4112 bool hashing_started_;
4113 const environment& env_;
4114 translation_unit* translation_unit_;
4115 // The location of an artifact as seen from its input by the
4116 // artifact reader. This might be different from the source
4117 // location advertised by the original emitter of the artifact
4118 // emitter.
4119 location artificial_location_;
4120 // Flags if the current ABI artifact is artificial (i.e, *NOT*
4121 // generated from the initial source code, but rather either
4122 // artificially by the compiler or by libabigail itself).
4123 bool is_artificial_;
4124
4125 /// Constructor of the type_or_decl_base::priv private type.
4126 ///
4127 /// @param e the environment in which the ABI artifact was created.
4128 ///
4129 /// @param k the identifier of the runtime type of the current
4130 /// instance of ABI artifact.
4131 priv(const environment& e,
4132 enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL)
4133 : kind_(k),
4134 rtti_(),
4135 type_or_decl_ptr_(),
4136 hashing_started_(),
4137 env_(e),
4138 translation_unit_(),
4139 is_artificial_()
4140 {}
4141
4143 kind() const
4144 {return kind_;}
4145
4146 void
4147 kind (enum type_or_decl_kind k)
4148 {kind_ |= k;}
4149}; // end struct type_or_decl_base::priv
4150
4151/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
4152/// bitmap type.
4156{
4157 return static_cast<type_or_decl_base::type_or_decl_kind>
4158 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4159}
4160
4161/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4162/// bitmap type.
4166{
4167 l = l | r;
4168 return l;
4169}
4170
4171/// bitwise "AND" operator for the
4172/// type_or_decl_base::type_or_decl_kind bitmap type.
4176{
4177 return static_cast<type_or_decl_base::type_or_decl_kind>
4178 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4179}
4180
4181/// bitwise "A&=" operator for the
4182/// type_or_decl_base::type_or_decl_kind bitmap type.
4186{
4187 l = l & r;
4188 return l;
4189}
4190
4191/// Constructor of @ref type_or_decl_base.
4192///
4193/// @param the environment the current ABI artifact is constructed
4194/// from.
4195///
4196/// @param k the runtime identifier bitmap of the type being built.
4197type_or_decl_base::type_or_decl_base(const environment& e,
4198 enum type_or_decl_kind k)
4199 :priv_(new priv(e, k))
4200{}
4201
4202/// The destructor of the @ref type_or_decl_base type.
4204{}
4205
4206/// Getter of the flag that says if the artefact is artificial.
4207///
4208/// Being artificial means it was not explicitely mentionned in the
4209/// source code, but was rather artificially created by the compiler
4210/// or libabigail.
4211///
4212/// @return true iff the declaration is artificial.
4213bool
4215{return priv_->is_artificial_;}
4216
4217/// Setter of the flag that says if the artefact is artificial.
4218///
4219/// Being artificial means the artefact was not explicitely
4220/// mentionned in the source code, but was rather artificially created
4221/// by the compiler or by libabigail.
4222///
4223/// @param f the new value of the flag that says if the artefact is
4224/// artificial.
4225void
4227{priv_->is_artificial_ = f;}
4228
4229/// Getter for the "kind" property of @ref type_or_decl_base type.
4230///
4231/// This property holds the identifier bitmap of the runtime type of
4232/// an ABI artifact.
4233///
4234/// @return the runtime type identifier bitmap of the current ABI
4235/// artifact.
4238{return priv_->kind();}
4239
4240/// Setter for the "kind" property of @ref type_or_decl_base type.
4241///
4242/// This property holds the identifier bitmap of the runtime type of
4243/// an ABI artifact.
4244///
4245/// @param the runtime type identifier bitmap of the current ABI
4246/// artifact.
4247void
4249{priv_->kind(k);}
4250
4251/// Getter of the pointer to the runtime type sub-object of the
4252/// current instance.
4253///
4254/// @return the pointer to the runtime type sub-object of the current
4255/// instance.
4256const void*
4258{return priv_->rtti_;}
4259
4260/// Getter of the pointer to the runtime type sub-object of the
4261/// current instance.
4262///
4263/// @return the pointer to the runtime type sub-object of the current
4264/// instance.
4265void*
4267{return priv_->rtti_;}
4268
4269/// Setter of the pointer to the runtime type sub-object of the
4270/// current instance.
4271///
4272/// @param i the new pointer to the runtime type sub-object of the
4273/// current instance.
4274void
4276{
4277 priv_->rtti_ = i;
4278 if (type_base* t = dynamic_cast<type_base*>(this))
4279 priv_->type_or_decl_ptr_ = t;
4280 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4281 priv_->type_or_decl_ptr_ = d;
4282}
4283
4284/// Getter of the pointer to either the type_base sub-object of the
4285/// current instance if it's a type, or to the decl_base sub-object of
4286/// the current instance if it's a decl.
4287///
4288/// @return the pointer to either the type_base sub-object of the
4289/// current instance if it's a type, or to the decl_base sub-object of
4290/// the current instance if it's a decl.
4291const void*
4293{return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
4294
4295/// Getter of the pointer to either the type_base sub-object of the
4296/// current instance if it's a type, or to the decl_base sub-object of
4297/// the current instance if it's a decl.
4298///
4299/// @return the pointer to either the type_base sub-object of the
4300/// current instance if it's a type, or to the decl_base sub-object of
4301/// the current instance if it's a decl.
4302void*
4304{return priv_->type_or_decl_ptr_;}
4305
4306/// Getter for the 'hashing_started' property.
4307///
4308/// @return the 'hashing_started' property.
4309bool
4311{return priv_->hashing_started_;}
4312
4313/// Setter for the 'hashing_started' property.
4314///
4315/// @param b the value to set the 'hashing_property' to.
4316void
4318{priv_->hashing_started_ = b;}
4319
4320/// Getter of the environment of the current ABI artifact.
4321///
4322/// @return the environment of the artifact.
4323const environment&
4325{return priv_->env_;}
4326
4327/// Setter of the artificial location of the artificat.
4328///
4329/// The artificial location is a location that was artificially
4330/// generated by libabigail, not generated by the original emitter of
4331/// the ABI meta-data. For instance, when reading an XML element from
4332/// an abixml file, the artificial location is the source location of
4333/// the XML element within the file, not the value of the
4334/// 'location'property that might be carried by the element.
4335///
4336/// Artificial locations might be useful to ensure that abixml emitted
4337/// by the abixml writer are sorted the same way as the input abixml
4338/// read by the reader.
4339///
4340/// @param l the new artificial location.
4341void
4343{priv_->artificial_location_ = l;}
4344
4345/// Getter of the artificial location of the artifact.
4346///
4347/// The artificial location is a location that was artificially
4348/// generated by libabigail, not generated by the original emitter of
4349/// the ABI meta-data. For instance, when reading an XML element from
4350/// an abixml file, the artificial location is the source location of
4351/// the XML element within the file, not the value of the
4352/// 'location'property that might be carried by the element.
4353///
4354/// Artificial locations might be useful to ensure that the abixml
4355/// emitted by the abixml writer is sorted the same way as the input
4356/// abixml read by the reader.
4357///
4358/// @return the new artificial location.
4359location&
4361{return priv_->artificial_location_;}
4362
4363/// Test if the current ABI artifact carries an artificial location.
4364///
4365/// @return true iff the current ABI artifact carries an artificial location.
4366bool
4368{
4369 return (priv_->artificial_location_
4370 && priv_->artificial_location_.get_is_artificial());
4371}
4372
4373/// Get the @ref corpus this ABI artifact belongs to.
4374///
4375/// @return the corpus this ABI artifact belongs to, or nil if it
4376/// belongs to none for now.
4377corpus*
4379{
4381 if (!tu)
4382 return 0;
4383 return tu->get_corpus();
4384}
4385
4386
4387/// Get the @ref corpus this ABI artifact belongs to.
4388///
4389/// @return the corpus this ABI artifact belongs to, or nil if it
4390/// belongs to none for now.
4391const corpus*
4393{return const_cast<type_or_decl_base*>(this)->get_corpus();}
4394
4395/// Set the @ref translation_unit this ABI artifact belongs to.
4396///
4397/// Note that adding an ABI artifact to a containining on should
4398/// invoke this member function.
4399void
4401{priv_->translation_unit_ = tu;}
4402
4403
4404/// Get the @ref translation_unit this ABI artifact belongs to.
4405///
4406/// @return the translation unit this ABI artifact belongs to, or nil
4407/// if belongs to none for now.
4410{return priv_->translation_unit_;}
4411
4412/// Get the @ref translation_unit this ABI artifact belongs to.
4413///
4414/// @return the translation unit this ABI artifact belongs to, or nil
4415/// if belongs to none for now.
4416const translation_unit*
4418{return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
4419
4420/// Traverse the the ABI artifact.
4421///
4422/// @param v the visitor used to traverse the sub-tree nodes of the
4423/// artifact.
4424bool
4426{return true;}
4427
4428/// Non-member equality operator for the @type_or_decl_base type.
4429///
4430/// @param lr the left-hand operand of the equality.
4431///
4432/// @param rr the right-hand operatnr of the equality.
4433///
4434/// @return true iff @p lr equals @p rr.
4435bool
4437{
4438 const type_or_decl_base* l = &lr;
4439 const type_or_decl_base* r = &rr;
4440
4441 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4442 *dr = dynamic_cast<const decl_base*>(r);
4443
4444 if (!!dl != !!dr)
4445 return false;
4446
4447 if (dl && dr)
4448 return *dl == *dr;
4449
4450 const type_base* tl = dynamic_cast<const type_base*>(l),
4451 *tr = dynamic_cast<const type_base*>(r);
4452
4453 if (!!tl != !!tr)
4454 return false;
4455
4456 if (tl && tr)
4457 return *tl == *tr;
4458
4459 return false;
4460}
4461
4462/// Non-member equality operator for the @type_or_decl_base type.
4463///
4464/// @param l the left-hand operand of the equality.
4465///
4466/// @param r the right-hand operatnr of the equality.
4467///
4468/// @return true iff @p l equals @p r.
4469bool
4471{
4472 if (!! l != !!r)
4473 return false;
4474
4475 if (!l)
4476 return true;
4477
4478 return *r == *l;
4479}
4480
4481/// Non-member inequality operator for the @type_or_decl_base type.
4482///
4483/// @param l the left-hand operand of the equality.
4484///
4485/// @param r the right-hand operator of the equality.
4486///
4487/// @return true iff @p l is different from @p r.
4488bool
4490{return !operator==(l, r);}
4491
4492// </type_or_decl_base stuff>
4493
4494// <Decl definition>
4495
4496struct decl_base::priv
4497{
4498 bool in_pub_sym_tab_;
4499 bool is_anonymous_;
4500 location location_;
4501 context_rel *context_;
4502 interned_string name_;
4503 interned_string qualified_parent_name_;
4504 // This temporary qualified name is the cache used for the qualified
4505 // name before the type associated to this decl (if applicable) is
4506 // canonicalized. Once the type is canonicalized, the cached use is
4507 // the data member qualified_parent_name_ above.
4508 interned_string temporary_qualified_name_;
4509 // This is the fully qualified name of the decl. It contains the
4510 // name of the decl and the qualified name of its scope. So if in
4511 // the parent scopes of the decl, there is one anonymous struct,
4512 // somewhere in the name, there is going to by an
4513 // __anonymous_struct__ string, even if the anonymous struct is not
4514 // the direct containing scope of this decl.
4515 interned_string qualified_name_;
4516 interned_string temporary_internal_qualified_name_;
4517 interned_string internal_qualified_name_;
4518 // Unline qualified_name_, scoped_name_ contains the name of the
4519 // decl and the name of its scope; not the qualified name of the
4520 // scope.
4521 interned_string scoped_name_;
4522 interned_string linkage_name_;
4523 visibility visibility_;
4524 decl_base_sptr declaration_;
4525 decl_base_wptr definition_of_declaration_;
4526 decl_base* naked_definition_of_declaration_;
4527 bool is_declaration_only_;
4528 typedef_decl_sptr naming_typedef_;
4529
4530 priv()
4531 : in_pub_sym_tab_(false),
4532 is_anonymous_(true),
4533 context_(),
4534 visibility_(VISIBILITY_DEFAULT),
4535 naked_definition_of_declaration_(),
4536 is_declaration_only_(false)
4537 {}
4538
4539 priv(interned_string name, interned_string linkage_name, visibility vis)
4540 : in_pub_sym_tab_(false),
4541 context_(),
4542 name_(name),
4543 qualified_name_(name),
4544 linkage_name_(linkage_name),
4545 visibility_(vis),
4546 naked_definition_of_declaration_(),
4547 is_declaration_only_(false)
4548 {
4549 is_anonymous_ = name_.empty();
4550 }
4551
4552 ~priv()
4553 {
4554 delete context_;
4555 }
4556};// end struct decl_base::priv
4557
4558/// Constructor for the @ref decl_base type.
4559///
4560/// @param e the environment the current @ref decl_base is being
4561/// created in.
4562///
4563/// @param name the name of the declaration.
4564///
4565/// @param locus the location where to find the declaration in the
4566/// source code.
4567///
4568/// @param linkage_name the linkage name of the declaration.
4569///
4570/// @param vis the visibility of the declaration.
4571decl_base::decl_base(const environment& e,
4572 const string& name,
4573 const location& locus,
4574 const string& linkage_name,
4575 visibility vis)
4576 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4577 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4578{
4579 set_location(locus);
4580}
4581
4582/// Constructor.
4583///
4584/// @param e the environment this instance of @ref decl_base is
4585/// created in.
4586///
4587/// @param name the name of the declaration being constructed.
4588///
4589/// @param locus the source location of the declaration being constructed.
4590///
4591/// @param linkage_name the linkage name of the declaration being
4592/// constructed.
4593///
4594/// @param vis the visibility of the declaration being constructed.
4595decl_base::decl_base(const environment& e,
4596 const interned_string& name,
4597 const location& locus,
4598 const interned_string& linkage_name,
4599 visibility vis)
4600 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4601 priv_(new priv(name, linkage_name, vis))
4602{
4603 set_location(locus);
4604}
4605
4606/// Constructor for the @ref decl_base type.
4607///
4608///@param environment the environment this instance of @ref decl_base
4609/// is being constructed in.
4610///
4611/// @param l the location where to find the declaration in the source
4612/// code.
4613decl_base::decl_base(const environment& e, const location& l)
4614 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4615 priv_(new priv())
4616{
4617 set_location(l);
4618}
4619
4620/// Getter for the qualified name.
4621///
4622/// Unlike decl_base::get_qualified_name() this doesn't try to update
4623/// the qualified name.
4624///
4625/// @return the qualified name.
4626const interned_string&
4628{return priv_->qualified_name_;}
4629
4630/// Clear the qualified name of this decl.
4631///
4632/// This is useful to ensure that the cache for the qualified name of
4633/// the decl is refreshed right after type canonicalization, for
4634/// instance.
4635void
4637{priv_->qualified_name_.clear();}
4638
4639/// Setter for the qualified name.
4640///
4641/// @param n the new qualified name.
4642void
4644{priv_->qualified_name_ = n;}
4645
4646/// Getter of the temporary qualified name of the current declaration.
4647///
4648/// This temporary qualified name is used as a qualified name cache by
4649/// the type for which this is the declaration (when applicable)
4650/// before the type is canonicalized. Once the type is canonicalized,
4651/// it's the result of decl_base::peek_qualified_name() that becomes
4652/// the qualified name cached.
4653///
4654/// @return the temporary qualified name.
4655const interned_string&
4657{return priv_->temporary_qualified_name_;}
4658
4659/// Setter for the temporary qualified name of the current
4660/// declaration.
4661///
4662///@param n the new temporary qualified name.
4663///
4664/// This temporary qualified name is used as a qualified name cache by
4665/// the type for which this is the declaration (when applicable)
4666/// before the type is canonicalized. Once the type is canonicalized,
4667/// it's the result of decl_base::peek_qualified_name() that becomes
4668/// the qualified name cached.
4669void
4671{priv_->temporary_qualified_name_ = n;}
4672
4673///Getter for the context relationship.
4674///
4675///@return the context relationship for the current decl_base.
4676const context_rel*
4678{return priv_->context_;}
4679
4680///Getter for the context relationship.
4681///
4682///@return the context relationship for the current decl_base.
4685{return priv_->context_;}
4686
4687void
4688decl_base::set_context_rel(context_rel *c)
4689{priv_->context_ = c;}
4690
4691/// Get the hash of a decl. If the hash hasn't been computed yet,
4692/// compute it ans store its value; otherwise, just return the hash.
4693///
4694/// @return the hash of the decl.
4695size_t
4697{
4698 size_t result = 0;
4699
4700 if (const type_base* t = dynamic_cast<const type_base*>(this))
4701 {
4703 result = hash(t);
4704 }
4705 else
4706 // If we reach this point, it mean we are missing a virtual
4707 // overload for decl_base::get_hash. Add it!
4708 abort();
4709
4710 return result;
4711}
4712
4713/// Test if the decl is defined in a ELF symbol table as a public
4714/// symbol.
4715///
4716/// @return true iff the decl is defined in a ELF symbol table as a
4717/// public symbol.
4718bool
4720{return priv_->in_pub_sym_tab_;}
4721
4722/// Set the flag saying if this decl is from a symbol that is in
4723/// a public symbols table, defined as public (global or weak).
4724///
4725/// @param f the new flag value.
4726void
4728{priv_->in_pub_sym_tab_ = f;}
4729
4730/// Get the location of a given declaration.
4731///
4732/// The location is an abstraction for the tripplet {file path,
4733/// line, column} that defines where the declaration appeared in the
4734/// source code.
4735///
4736/// To get the value of the tripplet {file path, line, column} from
4737/// the @ref location, you need to use the
4738/// location_manager::expand_location() method.
4739///
4740/// The instance of @ref location_manager that you want is
4741/// accessible from the instance of @ref translation_unit that the
4742/// current instance of @ref decl_base belongs to, via a call to
4743/// translation_unit::get_loc_mgr().
4744///
4745/// @return the location of the current instance of @ref decl_base.
4746const location&
4748{return priv_->location_;}
4749
4750/// Set the location for a given declaration.
4751///
4752/// The location is an abstraction for the tripplet {file path,
4753/// line, column} that defines where the declaration appeared in the
4754/// source code.
4755///
4756/// To create a location from a tripplet {file path, line, column},
4757/// you need to use the method @ref
4758/// location_manager::create_new_location().
4759///
4760/// Note that there can be two kinds of location. An artificial
4761/// location and a non-artificial one. The non-artificial location is
4762/// the one emitted by the original emitter of the ABI artifact, for
4763/// instance, if the ABI artifact comes from debug info, then the
4764/// source location that is present in the debug info represent a
4765/// non-artificial location. When looking at an abixml file on the
4766/// other hand, the value of the 'location' attribute of an XML
4767/// element describing an artifact is the non-artificial location.
4768/// The artificial location is the location (line number from the
4769/// beginning of the file) of the XML element within the abixml file.
4770///
4771/// So, if the location that is being set is artificial, note that the
4772/// type_or_decl_base::has_artificial_location() method of this decl will
4773/// subsequently return true and that artificial location will have to
4774/// be retrieved using type_or_decl_base::get_artificial_location().
4775/// If the location is non-artificial however,
4776/// type_or_decl_base::has_artificial_location() will subsequently
4777/// return false and the non-artificial location will have to be
4778/// retrieved using decl_base::get_location().
4779///
4780/// The instance of @ref location_manager that you want is
4781/// accessible from the instance of @ref translation_unit that the
4782/// current instance of @ref decl_base belongs to, via a call to
4783/// translation_unit::get_loc_mgr().
4784void
4786{
4787 if (l.get_is_artificial())
4789 else
4790 priv_->location_ = l;
4791}
4792
4793/// Setter for the name of the decl.
4794///
4795/// @param n the new name to set.
4796void
4797decl_base::set_name(const string& n)
4798{
4799 priv_->name_ = get_environment().intern(n);
4800 priv_->is_anonymous_ = n.empty();
4801}
4802
4803/// Test if the current declaration is anonymous.
4804///
4805/// Being anonymous means that the declaration was created without a
4806/// name. This can usually happen for enum or struct types.
4807///
4808/// @return true iff the type is anonymous.
4809bool
4811{return priv_->is_anonymous_;}
4812
4813/// Set the "is_anonymous" flag of the current declaration.
4814///
4815/// Being anonymous means that the declaration was created without a
4816/// name. This can usually happen for enum or struct types.
4817///
4818/// @param f the new value of the flag.
4819void
4821{priv_->is_anonymous_ = f;}
4822
4823
4824/// Get the "has_anonymous_parent" flag of the current declaration.
4825///
4826/// Having an anoymous parent means having a anonymous parent scope
4827/// (containing type or namespace) which is either direct or indirect.
4828///
4829/// @return true iff the current decl has a direct or indirect scope
4830/// which is anonymous.
4831bool
4833{
4834 scope_decl *scope = get_scope();
4835 if (!scope)
4836 return false;
4837 return scope->get_is_anonymous();
4838}
4839
4840/// @return the logical "OR" of decl_base::get_is_anonymous() and
4841/// decl_base::get_has_anonymous_parent().
4842bool
4845
4846/// Getter for the naming typedef of the current decl.
4847///
4848/// Consider the C idiom:
4849///
4850/// typedef struct {int member;} foo_type;
4851///
4852/// In that idiom, foo_type is the naming typedef of the anonymous
4853/// struct that is declared.
4854///
4855/// @return the naming typedef, if any. Otherwise, returns nil.
4858{return priv_->naming_typedef_;}
4859
4860/// Set the naming typedef of the current instance of @ref decl_base.
4861///
4862/// Consider the C idiom:
4863///
4864/// typedef struct {int member;} foo_type;
4865///
4866/// In that idiom, foo_type is the naming typedef of the anonymous
4867/// struct that is declared.
4868///
4869/// After completion of this function, the decl will not be considered
4870/// anonymous anymore. It's name is going to be the name of the
4871/// naming typedef.
4872///
4873/// @param typedef_type the new naming typedef.
4874void
4876{
4877 // A naming typedef is usually for an anonymous type.
4879 // Whe the typedef-named decl is saved into abixml, it's
4880 // not anonymous anymore. Its name is the typedef name.
4881 // So when we read it back, we must still be able to
4882 // apply the naming typedef to the decl.
4883 || t->get_name() == get_name());
4884 // Only non canonicalized types can be edited this way.
4885 ABG_ASSERT(is_type(this)
4886 && is_type(this)->get_naked_canonical_type() == nullptr);
4887
4888 priv_->naming_typedef_ = t;
4889 set_name(t->get_name());
4890 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4891 set_qualified_name(get_environment().intern(qualified_name));
4892 set_is_anonymous(false);
4893 // Now that the qualified type of the decl has changed, let's update
4894 // the qualified names of the member types of this decls.
4895 update_qualified_name(this);
4896}
4897
4898/// Getter for the mangled name.
4899///
4900/// @return the new mangled name.
4901const interned_string&
4903{return priv_->linkage_name_;}
4904
4905/// Setter for the linkage name.
4906///
4907/// @param m the new linkage name.
4908void
4910{
4911 const environment& env = get_environment();
4912 priv_->linkage_name_ = env.intern(m);
4913}
4914
4915/// Getter for the visibility of the decl.
4916///
4917/// @return the new visibility.
4920{return priv_->visibility_;}
4921
4922/// Setter for the visibility of the decl.
4923///
4924/// @param v the new visibility.
4925void
4927{priv_->visibility_ = v;}
4928
4929/// Return the type containing the current decl, if any.
4930///
4931/// @return the type that contains the current decl, or NULL if there
4932/// is none.
4935{
4936 if (priv_->context_)
4937 return priv_->context_->get_scope();
4938 return 0;
4939}
4940
4941/// Return a copy of the qualified name of the parent of the current
4942/// decl.
4943///
4944/// @return the newly-built qualified name of the of the current decl.
4945const interned_string&
4947{return priv_->qualified_parent_name_;}
4948
4949/// Getter for the name of the current decl.
4950///
4951/// @return the name of the current decl.
4952const interned_string&
4954{return priv_->name_;}
4955
4956/// Compute the qualified name of the decl.
4957///
4958/// @param qn the resulting qualified name.
4959///
4960/// @param internal set to true if the call is intended for an
4961/// internal use (for technical use inside the library itself), false
4962/// otherwise. If you don't know what this is for, then set it to
4963/// false.
4964void
4966{qn = get_qualified_name(internal);}
4967
4968/// Get the pretty representatin of the current declaration.
4969///
4970///
4971/// @param internal set to true if the call is intended to get a
4972/// representation of the decl (or type) for the purpose of canonical
4973/// type comparison. This is mainly used in the function
4974/// type_base::get_canonical_type_for().
4975///
4976/// In other words if the argument for this parameter is true then the
4977/// call is meant for internal use (for technical use inside the
4978/// library itself), false otherwise. If you don't know what this is
4979/// for, then set it to false.
4980///
4981/// @param qualified_name if true, names emitted in the pretty
4982/// representation are fully qualified.
4983///
4984/// @return the default pretty representation for a decl. This is
4985/// basically the fully qualified name of the decl optionally prefixed
4986/// with a meaningful string to add context for the user.
4987string
4989 bool qualified_name) const
4990{
4991 if (internal
4992 && get_is_anonymous()
4993 && has_generic_anonymous_internal_type_name(this))
4994 {
4995 // We are looking at an anonymous enum, union or class and we
4996 // want an *internal* pretty representation for it. All
4997 // anonymous types of this kind in the same namespace must have
4998 // the same internal representation for type canonicalization to
4999 // work properly.
5000 //
5001 // OK, in practise, we are certainly looking at an enum because
5002 // classes and unions should have their own overloaded virtual
5003 // member function for this.
5004 string name = get_generic_anonymous_internal_type_name(this);
5005 if (qualified_name && !get_qualified_parent_name().empty())
5006 name = get_qualified_parent_name() + "::" + name;
5007 return name;
5008 }
5009
5010 if (qualified_name)
5011 return get_qualified_name(internal);
5012 return get_name();
5013}
5014
5015/// Return the qualified name of the decl.
5016///
5017/// This is the fully qualified name of the decl. It's made of the
5018/// concatenation of the name of the decl with the qualified name of
5019/// its scope.
5020///
5021/// Note that the value returned by this function is computed by @ref
5022/// update_qualified_name when the decl is added to its scope.
5023///
5024/// @param internal set to true if the call is intended for an
5025/// internal use (for technical use inside the library itself), false
5026/// otherwise. If you don't know what this is for, then set it to
5027/// false.
5028///
5029/// @return the resulting qualified name.
5030const interned_string&
5031decl_base::get_qualified_name(bool /*internal*/) const
5032{return priv_->qualified_name_;}
5033
5034/// Return the scoped name of the decl.
5035///
5036/// This is made of the concatenation of the name of the decl with the
5037/// name of its scope. It doesn't contain the qualified name of its
5038/// scope, unlike what is returned by decl_base::get_qualified_name.
5039///
5040/// Note that the value returned by this function is computed by @ref
5041/// update_qualified_name when the decl is added to its scope.
5042///
5043/// @return the scoped name of the decl.
5044const interned_string&
5046{return priv_->scoped_name_;}
5047
5048/// If this @ref decl_base is a definition, get its earlier
5049/// declaration.
5050///
5051/// @return the earlier declaration of the class, if any.
5052const decl_base_sptr
5054{return priv_->declaration_;}
5055
5056/// set the earlier declaration of this @ref decl_base definition.
5057///
5058/// @param d the earlier declaration to set. Note that it's set only
5059/// if it's a pure declaration.
5060void
5062{
5063 if (d && d->get_is_declaration_only())
5064 priv_->declaration_ = d;
5065}
5066
5067
5068/// If this @ref decl_base is declaration-only, get its definition, if
5069/// any.
5070///
5071/// @return the definition of this decl-only @ref decl_base.
5072const decl_base_sptr
5074{return priv_->definition_of_declaration_.lock();}
5075
5076/// If this @ref decl_base is declaration-only, get its definition,
5077/// if any.
5078///
5079/// Note that this function doesn't return a smart pointer, but rather
5080/// the underlying pointer managed by the smart pointer. So it's as
5081/// fast as possible. This getter is to be used in code paths that
5082/// are proven to be performance hot spots; especially, when comparing
5083/// sensitive types like enums, classes or unions. Those are compared
5084/// extremely frequently and thus, their access to the definition of
5085/// declaration must be fast.
5086///
5087/// @return the definition of the declaration.
5088const decl_base*
5090{return priv_->naked_definition_of_declaration_;}
5091
5092/// Test if a @ref decl_base is a declaration-only decl.
5093///
5094/// @return true iff the current @ref decl_base is declaration-only.
5095bool
5097{return priv_->is_declaration_only_;}
5098
5099/// Set a flag saying if the @ref enum_type_decl is a declaration-only
5100/// @ref enum_type_decl.
5101///
5102/// @param f true if the @ref enum_type_decl is a declaration-only
5103/// @ref enum_type_decl.
5104void
5106{
5107 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
5108
5109 priv_->is_declaration_only_ = f;
5110
5111 if (update_types_lookup_map)
5112 if (scope_decl* s = get_scope())
5113 {
5114 scope_decl::declarations::iterator i;
5115 if (s->find_iterator_for_member(this, i))
5117 else
5119 }
5120}
5121
5124{
5125 return static_cast<change_kind>(static_cast<unsigned>(l)
5126 | static_cast<unsigned>(r));
5127}
5128
5131{
5132 return static_cast<change_kind>(static_cast<unsigned>(l)
5133 & static_cast<unsigned>(r));
5134}
5135
5138{
5139 l = l | r;
5140 return l;
5141}
5142
5145{
5146 l = l & r;
5147 return l;
5148}
5149
5150/// Compare the properties that belong to the "is-a-member-relation"
5151/// of a decl.
5152///
5153/// For instance, access specifiers are part of the
5154/// "is-a-member-relation" of a decl.
5155///
5156/// This comparison however doesn't take decl names into account. So
5157/// typedefs for instance are decls that we want to compare with this
5158/// function.
5159///
5160/// This function is a sub-routine of the more general 'equals'
5161/// overload for instances of decl_base.
5162///
5163/// @param l the left-hand side operand of the comparison.
5164///
5165/// @param r the right-hand side operand of the comparison.
5166///
5167/// @return true iff @p l compare equals, as a member decl, to @p r.
5168bool
5170 const decl_base& r,
5171 change_kind* k)
5172{
5173 bool result = true;
5174 if (is_member_decl(l) && is_member_decl(r))
5175 {
5176 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
5177 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
5178
5179 access_specifier la = no_access, ra = no_access;
5180 bool member_types_or_functions =
5181 ((is_type(l) && is_type(r))
5182 || (is_function_decl(l) && is_function_decl(r)));
5183
5184 if (member_types_or_functions)
5185 {
5186 // Access specifiers on member types in DWARF is not
5187 // reliable; in the same DSO, the same struct can be either
5188 // a class or a struct, and the access specifiers of its
5189 // member types are not necessarily given, so they
5190 // effectively can be considered differently, again, in the
5191 // same DSO. So, here, let's avoid considering those!
5192 // during comparison.
5193 la = r1->get_access_specifier();
5194 ra = r2->get_access_specifier();
5195 r1->set_access_specifier(no_access);
5196 r2->set_access_specifier(no_access);
5197 }
5198
5199 bool rels_are_different = *r1 != *r2;
5200
5201 if (member_types_or_functions)
5202 {
5203 // restore the access specifiers.
5204 r1->set_access_specifier(la);
5205 r2->set_access_specifier(ra);
5206 }
5207
5208 if (rels_are_different)
5209 {
5210 result = false;
5211 if (k)
5213 }
5214 }
5215 ABG_RETURN(result);
5216}
5217
5218/// Get the name of a decl for the purpose of comparing two decl
5219/// names.
5220///
5221/// This is a sub-routine of the 'equal' overload for decl_base.
5222///
5223/// This function takes into account the fact that all anonymous names
5224/// shall have the same name for the purpose of comparison.
5225///
5226/// For decls that are part of an anonymous scope, only the
5227/// non-qualified name should be taken into account.
5228static interned_string
5229get_decl_name_for_comparison(const decl_base &d)
5230{
5231 if (has_generic_anonymous_internal_type_name(&d)
5232 && d.get_is_anonymous())
5233 {
5234 // The decl is anonymous. It should have the same name ass the
5235 // other anymous types of the same kind.
5236 string r;
5237 r += get_generic_anonymous_internal_type_name(&d);
5238 return d.get_environment().intern(r);
5239 }
5240
5243 ? d.get_name()
5244 : d.get_qualified_name(/*internal=*/true);
5245 return n;
5246}
5247
5248/// Compares two instances of @ref decl_base.
5249///
5250/// If the two intances are different, set a bitfield to give some
5251/// insight about the kind of differences there are.
5252///
5253/// @param l the first artifact of the comparison.
5254///
5255/// @param r the second artifact of the comparison.
5256///
5257/// @param k a pointer to a bitfield that gives information about the
5258/// kind of changes there are between @p l and @p r. This one is set
5259/// iff it's non-null and if the function returns false.
5260///
5261/// Please note that setting k to a non-null value does have a
5262/// negative performance impact because even if @p l and @p r are not
5263/// equal, the function keeps up the comparison in order to determine
5264/// the different kinds of ways in which they are different.
5265///
5266/// @return true if @p l equals @p r, false otherwise.
5267bool
5268equals(const decl_base& l, const decl_base& r, change_kind* k)
5269{
5270 bool result = true;
5271 const interned_string &l_linkage_name = l.get_linkage_name();
5272 const interned_string &r_linkage_name = r.get_linkage_name();
5273 if (!l_linkage_name.empty() && !r_linkage_name.empty())
5274 {
5275 if (l_linkage_name != r_linkage_name)
5276 {
5277 // Linkage names are different. That usually means the two
5278 // decls are different, unless we are looking at two
5279 // function declarations which have two different symbols
5280 // that are aliases of each other.
5281 const function_decl *f1 = is_function_decl(&l),
5282 *f2 = is_function_decl(&r);
5283 if (f1 && f2 && function_decls_alias(*f1, *f2))
5284 ;// The two functions are aliases, so they are not
5285 // different.
5286 else
5287 {
5288 result = false;
5289 if (k)
5291 else
5293 }
5294 }
5295 }
5296
5297 // This is the qualified name of the decls that we want to compare.
5298 // We want to use the "internal" version of the qualified name as
5299 // that one is stable even for anonymous decls.
5300 interned_string ln = get_decl_name_for_comparison(l);
5301 interned_string rn = get_decl_name_for_comparison(r);
5302
5303 /// If both of the current decls have an anonymous scope then let's
5304 /// compare their name component by component by properly handling
5305 /// anonymous scopes. That's the slow path.
5306 ///
5307 /// Otherwise, let's just compare their name, the obvious way.
5308 /// That's the fast path because in that case the names are
5309 /// interned_string and comparing them is much faster.
5310 bool decls_are_same = (ln == rn);
5311 if (!decls_are_same
5312 && l.get_is_anonymous()
5314 && r.get_is_anonymous()
5316 // Both decls are anonymous and their scope are *NOT* anonymous.
5317 // So we consider the decls to have equivalent names (both
5318 // anonymous, remember). We are still in the fast path here.
5319 decls_are_same = true;
5320
5321 if (!decls_are_same
5324 // This is the slow path as we are comparing the decl qualified
5325 // names component by component, properly handling anonymous
5326 // scopes.
5327 decls_are_same = tools_utils::decl_names_equal(ln, rn);
5328
5329 if (!decls_are_same)
5330 {
5331 result = false;
5332 if (k)
5334 else
5336 }
5337
5338 result &= maybe_compare_as_member_decls(l, r, k);
5339
5340 ABG_RETURN(result);
5341}
5342
5343/// Return true iff the two decls have the same name.
5344///
5345/// This function doesn't test if the scopes of the the two decls are
5346/// equal.
5347///
5348/// Note that this virtual function is to be implemented by classes
5349/// that extend the \p decl_base class.
5350bool
5352{return equals(*this, other, 0);}
5353
5354/// Inequality operator.
5355///
5356/// @param other to other instance of @ref decl_base to compare the
5357/// current instance to.
5358///
5359/// @return true iff the current instance of @ref decl_base is
5360/// different from @p other.
5361bool
5363{return !operator==(other);}
5364
5365/// Destructor of the @ref decl_base type.
5367{delete priv_;}
5368
5369/// This implements the ir_traversable_base::traverse pure virtual
5370/// function.
5371///
5372/// @param v the visitor used on the member nodes of the translation
5373/// unit during the traversal.
5374///
5375/// @return true if the entire IR node tree got traversed, false
5376/// otherwise.
5377bool
5379{
5380 // Do nothing in the base class.
5381 return true;
5382}
5383
5384/// Setter of the scope of the current decl.
5385///
5386/// Note that the decl won't hold a reference on the scope. It's
5387/// rather the scope that holds a reference on its members.
5388void
5390{
5391 if (!priv_->context_)
5392 priv_->context_ = new context_rel(scope);
5393 else
5394 priv_->context_->set_scope(scope);
5395}
5396
5397// </decl_base definition>
5398
5399/// Streaming operator for the decl_base::visibility.
5400///
5401/// @param o the output stream to serialize the visibility to.
5402///
5403/// @param v the visibility to serialize.
5404///
5405/// @return the output stream.
5406std::ostream&
5407operator<<(std::ostream& o, decl_base::visibility v)
5408{
5409 string r;
5410 switch (v)
5411 {
5412 case decl_base::VISIBILITY_NONE:
5413 r = "none";
5414 break;
5415 case decl_base::VISIBILITY_DEFAULT:
5416 r = "default";
5417 break;
5418 case decl_base::VISIBILITY_PROTECTED:
5419 r = "protected";
5420 break;
5421 case decl_base::VISIBILITY_HIDDEN:
5422 r = "hidden";
5423 break;
5424 case decl_base::VISIBILITY_INTERNAL:
5425 r = "internal";
5426 break;
5427 }
5428 return o;
5429}
5430
5431/// Streaming operator for decl_base::binding.
5432///
5433/// @param o the output stream to serialize the visibility to.
5434///
5435/// @param b the binding to serialize.
5436///
5437/// @return the output stream.
5438std::ostream&
5439operator<<(std::ostream& o, decl_base::binding b)
5440{
5441 string r;
5442 switch (b)
5443 {
5444 case decl_base::BINDING_NONE:
5445 r = "none";
5446 break;
5447 case decl_base::BINDING_LOCAL:
5448 r = "local";
5449 break;
5450 case decl_base::BINDING_GLOBAL:
5451 r = "global";
5452 break;
5453 case decl_base::BINDING_WEAK:
5454 r = "weak";
5455 break;
5456 }
5457 o << r;
5458 return o;
5459}
5460
5461/// Turn equality of shared_ptr of decl_base into a deep equality;
5462/// that is, make it compare the pointed to objects, not just the
5463/// pointers.
5464///
5465/// @param l the shared_ptr of decl_base on left-hand-side of the
5466/// equality.
5467///
5468/// @param r the shared_ptr of decl_base on right-hand-side of the
5469/// equality.
5470///
5471/// @return true if the decl_base pointed to by the shared_ptrs are
5472/// equal, false otherwise.
5473bool
5474operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5475{
5476 if (l.get() == r.get())
5477 return true;
5478 if (!!l != !!r)
5479 return false;
5480
5481 return *l == *r;
5482}
5483
5484/// Inequality operator of shared_ptr of @ref decl_base.
5485///
5486/// This is a deep equality operator, that is, it compares the
5487/// pointed-to objects, rather than just the pointers.
5488///
5489/// @param l the left-hand-side operand.
5490///
5491/// @param r the right-hand-side operand.
5492///
5493/// @return true iff @p l is different from @p r.
5494bool
5495operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5496{return !operator==(l, r);}
5497
5498/// Turn equality of shared_ptr of type_base into a deep equality;
5499/// that is, make it compare the pointed to objects too.
5500///
5501/// @param l the shared_ptr of type_base on left-hand-side of the
5502/// equality.
5503///
5504/// @param r the shared_ptr of type_base on right-hand-side of the
5505/// equality.
5506///
5507/// @return true if the type_base pointed to by the shared_ptrs are
5508/// equal, false otherwise.
5509bool
5510operator==(const type_base_sptr& l, const type_base_sptr& r)
5511{
5512 if (l.get() == r.get())
5513 return true;
5514 if (!!l != !!r)
5515 return false;
5516
5517 return *l == *r;
5518}
5519
5520/// Turn inequality of shared_ptr of type_base into a deep equality;
5521/// that is, make it compare the pointed to objects..
5522///
5523/// @param l the shared_ptr of type_base on left-hand-side of the
5524/// equality.
5525///
5526/// @param r the shared_ptr of type_base on right-hand-side of the
5527/// equality.
5528///
5529/// @return true iff the type_base pointed to by the shared_ptrs are
5530/// different.
5531bool
5532operator!=(const type_base_sptr& l, const type_base_sptr& r)
5533{return !operator==(l, r);}
5534
5535/// Tests if a declaration has got a scope.
5536///
5537/// @param d the declaration to consider.
5538///
5539/// @return true if the declaration has got a scope, false otherwise.
5540bool
5542{return (d.get_scope());}
5543
5544/// Tests if a declaration has got a scope.
5545///
5546/// @param d the declaration to consider.
5547///
5548/// @return true if the declaration has got a scope, false otherwise.
5549bool
5550has_scope(const decl_base_sptr d)
5551{return has_scope(*d.get());}
5552
5553/// Tests if a declaration is a class member.
5554///
5555/// @param d the declaration to consider.
5556///
5557/// @return true if @p d is a class member, false otherwise.
5558bool
5559is_member_decl(const decl_base_sptr d)
5560{return is_at_class_scope(d) || is_method_decl(d);}
5561
5562/// Tests if a declaration is a class member.
5563///
5564/// @param d the declaration to consider.
5565///
5566/// @return true if @p d is a class member, false otherwise.
5567bool
5569{return is_at_class_scope(d) || is_method_decl(d);}
5570
5571/// Tests if a declaration is a class member.
5572///
5573/// @param d the declaration to consider.
5574///
5575/// @return true if @p d is a class member, false otherwise.
5576bool
5578{return is_at_class_scope(d) || is_method_decl(d);}
5579
5580/// Test if a declaration is a @ref scope_decl.
5581///
5582/// @param d the declaration to take in account.
5583///
5584/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5585/// if d is a @ref scope_decl.
5588{return dynamic_cast<scope_decl*>(d);}
5589
5590/// Test if a declaration is a @ref scope_decl.
5591///
5592/// @param d the declaration to take in account.
5593///
5594/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5595/// if d is a @ref scope_decl.
5597is_scope_decl(const decl_base_sptr& d)
5598{return dynamic_pointer_cast<scope_decl>(d);}
5599
5600/// Tests if a type is a class member.
5601///
5602/// @param t the type to consider.
5603///
5604/// @return true if @p t is a class member type, false otherwise.
5605bool
5606is_member_type(const type_base_sptr& t)
5607{
5608 decl_base_sptr d = get_type_declaration(t);
5609 return is_member_decl(d);
5610}
5611
5612/// Test if a type is user-defined.
5613///
5614/// A type is considered user-defined if it's a
5615/// struct/class/union/enum that is *NOT* artificial.
5616///
5617/// @param t the type to consider.
5618///
5619/// @return true iff the type @p t is user-defined.
5620bool
5622{
5623 if (t == 0)
5624 return false;
5625
5627 decl_base *d = is_decl(t);
5628
5630 && d && !d->get_is_artificial())
5631 return true;
5632
5633 return false;
5634}
5635
5636/// Test if a type is user-defined.
5637///
5638/// A type is considered user-defined if it's a
5639/// struct/class/union/enum.
5640///
5641///
5642/// @param t the type to consider.
5643///
5644/// @return true iff the type @p t is user-defined.
5645bool
5646is_user_defined_type(const type_base_sptr& t)
5647{return is_user_defined_type(t.get());}
5648
5649/// Gets the access specifier for a class member.
5650///
5651/// @param d the declaration of the class member to consider. Note
5652/// that this must be a class member otherwise the function aborts the
5653/// current process.
5654///
5655/// @return the access specifier for the class member @p d.
5658{
5660
5661 const context_rel* c = d.get_context_rel();
5662 ABG_ASSERT(c);
5663
5664 return c->get_access_specifier();
5665}
5666
5667/// Gets the access specifier for a class member.
5668///
5669/// @param d the declaration of the class member to consider. Note
5670/// that this must be a class member otherwise the function aborts the
5671/// current process.
5672///
5673/// @return the access specifier for the class member @p d.
5675get_member_access_specifier(const decl_base_sptr& d)
5676{return get_member_access_specifier(*d);}
5677
5678/// Sets the access specifier for a class member.
5679///
5680/// @param d the class member to set the access specifier for. Note
5681/// that this must be a class member otherwise the function aborts the
5682/// current process.
5683///
5684/// @param a the new access specifier to set the class member to.
5685void
5688{
5690
5692 ABG_ASSERT(c);
5693
5694 c->set_access_specifier(a);
5695}
5696
5697/// Sets the access specifier for a class member.
5698///
5699/// @param d the class member to set the access specifier for. Note
5700/// that this must be a class member otherwise the function aborts the
5701/// current process.
5702///
5703/// @param a the new access specifier to set the class member to.
5704void
5705set_member_access_specifier(const decl_base_sptr& d,
5708
5709/// Gets a flag saying if a class member is static or not.
5710///
5711/// @param d the declaration for the class member to consider. Note
5712/// that this must be a class member otherwise the function aborts the
5713/// current process.
5714///
5715/// @return true if the class member @p d is static, false otherwise.
5716bool
5718{
5720
5721 const context_rel* c = d.get_context_rel();
5722 ABG_ASSERT(c);
5723
5724 return c->get_is_static();
5725}
5726
5727/// Gets a flag saying if a class member is static or not.
5728///
5729/// @param d the declaration for the class member to consider. Note
5730/// that this must be a class member otherwise the function aborts the
5731/// current process.
5732///
5733/// @return true if the class member @p d is static, false otherwise.
5734bool
5736{return get_member_is_static(*d);}
5737
5738/// Gets a flag saying if a class member is static or not.
5739///
5740/// @param d the declaration for the class member to consider. Note
5741/// that this must be a class member otherwise the function aborts the
5742/// current process.
5743///
5744/// @return true if the class member @p d is static, false otherwise.
5745bool
5746get_member_is_static(const decl_base_sptr& d)
5747{return get_member_is_static(*d);}
5748
5749/// Test if a var_decl is a data member.
5750///
5751/// @param v the var_decl to consider.
5752///
5753/// @return true if @p v is data member, false otherwise.
5754bool
5756{return is_at_class_scope(v);}
5757
5758/// Test if a var_decl is a data member.
5759///
5760/// @param v the var_decl to consider.
5761///
5762/// @return true if @p v is data member, false otherwise.
5763bool
5765{return is_data_member(*v);}
5766
5767/// Test if a var_decl is a data member.
5768///
5769/// @param v the var_decl to consider.
5770///
5771/// @return true if @p v is data member, false otherwise.
5772bool
5774{return is_at_class_scope(d);}
5775
5776/// Test if a decl is a data member.
5777///
5778/// @param d the decl to consider.
5779///
5780/// @return a pointer to the data member iff @p d is a data member, or
5781/// a null pointer.
5783is_data_member(const decl_base_sptr& d)
5784{
5785 if (var_decl_sptr v = is_var_decl(d))
5786 {
5787 if (is_data_member(v))
5788 return v;
5789 }
5790 return var_decl_sptr();
5791}
5792
5793/// Test if a decl is a data member.
5794///
5795/// @param d the decl to consider.
5796///
5797/// @return a pointer to the data member iff @p d is a data member, or
5798/// a null pointer.
5801{
5802 if (var_decl_sptr v = is_var_decl(d))
5803 {
5804 if (is_data_member(v))
5805 return v;
5806 }
5807 return var_decl_sptr();
5808}
5809
5810/// Test if a decl is a data member.
5811///
5812/// @param d the decl to consider.
5813///
5814/// @return a pointer to the data member iff @p d is a data member, or
5815/// a null pointer.
5816var_decl*
5818{
5819 if (var_decl *v = is_var_decl(d))
5820 if (is_data_member(v))
5821 return v;
5822 return 0;
5823}
5824
5825/// Test if a decl is a data member.
5826///
5827/// @param d the decl to consider.
5828///
5829/// @return a pointer to the data member iff @p d is a data member, or
5830/// a null pointer.
5831var_decl*
5833{
5834 if (var_decl *v = is_var_decl(d))
5835 if (is_data_member(v))
5836 return v;
5837 return 0;
5838}
5839
5840/// Get the first non-anonymous data member of a given anonymous data
5841/// member.
5842///
5843/// E.g:
5844///
5845/// struct S
5846/// {
5847/// union // <-- for this anonymous data member, the function
5848/// // returns a.
5849/// {
5850/// int a;
5851/// charb;
5852/// };
5853/// };
5854///
5855/// @return anon_dm the anonymous data member to consider.
5856///
5857/// @return the first non-anonymous data member of @p anon_dm. If no
5858/// data member was found then this function returns @p anon_dm.
5859const var_decl_sptr
5861{
5862 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5863 return anon_dm;
5864
5865 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5866 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5867
5868 if (is_anonymous_data_member(first))
5870
5871 return first;
5872}
5873
5874/// In the context of a given class or union, this function returns
5875/// the data member that is located after a given data member.
5876///
5877/// @param klass the class or union to consider.
5878///
5879/// @param the data member to consider.
5880///
5881/// @return the data member that is located right after @p
5882/// data_member.
5883const var_decl_sptr
5885 const var_decl_sptr &data_member)
5886{
5887 if (!klass ||!data_member)
5888 return var_decl_sptr();
5889
5890 for (class_or_union::data_members::const_iterator it =
5891 klass->get_non_static_data_members().begin();
5892 it != klass->get_non_static_data_members().end();
5893 ++it)
5894 if (**it == *data_member)
5895 {
5896 ++it;
5897 if (it != klass->get_non_static_data_members().end())
5899 break;
5900 }
5901
5902 return var_decl_sptr();
5903}
5904
5905/// In the context of a given class or union, this function returns
5906/// the data member that is located after a given data member.
5907///
5908/// @param klass the class or union to consider.
5909///
5910/// @param the data member to consider.
5911///
5912/// @return the data member that is located right after @p
5913/// data_member.
5914const var_decl_sptr
5915get_next_data_member(const class_or_union_sptr& klass,
5916 const var_decl_sptr &data_member)
5917{return get_next_data_member(klass.get(), data_member);}
5918
5919/// Get the last data member of a class type.
5920///
5921/// @param klass the class type to consider.
5924{return klass.get_non_static_data_members().back();}
5925
5926/// Get the last data member of a class type.
5927///
5928/// @param klass the class type to consider.
5931{return get_last_data_member(*klass);}
5932
5933/// Get the last data member of a class type.
5934///
5935/// @param klass the class type to consider.
5937get_last_data_member(const class_or_union_sptr &klass)
5938{return get_last_data_member(klass.get());}
5939
5940/// Test if a decl is an anonymous data member.
5941///
5942/// @param d the decl to consider.
5943///
5944/// @return true iff @p d is an anonymous data member.
5945bool
5947{return is_anonymous_data_member(&d);}
5948
5949/// Test if a decl is an anonymous data member.
5950///
5951/// @param d the decl to consider.
5952///
5953/// @return the var_decl representing the data member iff @p d is an
5954/// anonymous data member.
5955const var_decl*
5957{
5958 if (const var_decl* v = is_data_member(d))
5959 {
5961 return v;
5962 }
5963 return 0;
5964}
5965
5966/// Test if a decl is an anonymous data member.
5967///
5968/// @param d the decl to consider.
5969///
5970/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5971/// it's an anonymous data member. Otherwise returns a nil pointer.
5972const var_decl*
5974{
5975 if (const var_decl* v = is_data_member(d))
5976 {
5978 return v;
5979 }
5980 return 0;
5981}
5982
5983/// Test if a decl is an anonymous data member.
5984///
5985/// @param d the decl to consider.
5986///
5987/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5988/// it's an anonymous data member. Otherwise returns a nil pointer.
5991{
5992 if (var_decl_sptr v = is_data_member(d))
5993 {
5995 return v;
5996 }
5997 return var_decl_sptr();
5998}
5999
6000/// Test if a decl is an anonymous data member.
6001///
6002/// @param d the decl to consider.
6003///
6004/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6005/// it's an anonymous data member. Otherwise returns a nil pointer.
6007is_anonymous_data_member(const decl_base_sptr& d)
6008{
6009 if (var_decl_sptr v = is_data_member(d))
6010 return is_anonymous_data_member(v);
6011 return var_decl_sptr();
6012}
6013
6014/// Test if a @ref var_decl is an anonymous data member.
6015///
6016/// @param d the @ref var_decl to consider.
6017///
6018/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6019/// it's an anonymous data member. Otherwise returns a nil pointer.
6022{
6023 if (is_anonymous_data_member(d.get()))
6024 return d;
6025 return var_decl_sptr();
6026}
6027
6028/// Test if a @ref var_decl is an anonymous data member.
6029///
6030/// @param d the @ref var_decl to consider.
6031///
6032/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6033/// it's an anonymous data member. Otherwise returns a nil pointer.
6034const var_decl*
6036{
6037 if (d && is_anonymous_data_member(*d))
6038 return d;
6039 return 0;
6040}
6041
6042/// Test if a @ref var_decl is an anonymous data member.
6043///
6044/// @param d the @ref var_decl to consider.
6045///
6046/// @return true iff @p d is an anonymous data member.
6047bool
6049{
6050 return (is_data_member(d)
6051 && d.get_is_anonymous()
6052 && d.get_name().empty()
6054}
6055
6056/// Get the @ref class_or_union type of a given anonymous data member.
6057///
6058/// @param d the anonymous data member to consider.
6059///
6060/// @return the @ref class_or_union type of the anonymous data member
6061/// @p d.
6064{
6065 if ((d = is_anonymous_data_member(d)))
6066 return is_class_or_union_type(d->get_type().get());
6067 return 0;
6068}
6069
6070/// Get the @ref class_or_union type of a given anonymous data member.
6071///
6072/// @param d the anonymous data member to consider.
6073///
6074/// @return the @ref class_or_union type of the anonymous data member
6075/// @p d.
6076class_or_union_sptr
6078{
6080 return is_class_or_union_type(d.get_type());
6081 return class_or_union_sptr();
6082}
6083
6084/// Test if a data member has annonymous type or not.
6085///
6086/// @param d the data member to consider.
6087///
6088/// @return the anonymous class or union type iff @p turns out to have
6089/// an anonymous type. Otherwise, returns nil.
6090const class_or_union_sptr
6092{
6093 if (is_data_member(d))
6094 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
6095 if (cou->get_is_anonymous())
6096 return cou;
6097
6098 return class_or_union_sptr();
6099}
6100
6101/// Test if a data member has annonymous type or not.
6102///
6103/// @param d the data member to consider.
6104///
6105/// @return the anonymous class or union type iff @p turns out to have
6106/// an anonymous type. Otherwise, returns nil.
6107const class_or_union_sptr
6109{
6110 if (d)
6112 return class_or_union_sptr();
6113}
6114
6115/// Test if a data member has annonymous type or not.
6116///
6117/// @param d the data member to consider.
6118///
6119/// @return the anonymous class or union type iff @p turns out to have
6120/// an anonymous type. Otherwise, returns nil.
6121const class_or_union_sptr
6123{return data_member_has_anonymous_type(d.get());}
6124
6125/// Get the @ref class_or_union type of a given anonymous data member.
6126///
6127/// @param d the anonymous data member to consider.
6128///
6129/// @return the @ref class_or_union type of the anonymous data member
6130/// @p d.
6131class_or_union_sptr
6133{
6135 return is_class_or_union_type(v->get_type());
6136 return class_or_union_sptr();
6137}
6138
6139/// Test if a given anonymous data member exists in a class or union.
6140///
6141/// @param anon_dm the anonymous data member to consider.
6142///
6143/// @param clazz the class to consider.
6144///
6145/// @return true iff @p anon_dm exists in the @clazz.
6146bool
6148 const class_or_union& clazz)
6149{
6150 if (!anon_dm.get_is_anonymous()
6151 || !is_class_or_union_type(anon_dm.get_type()))
6152 return false;
6153
6154 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
6155 ABG_ASSERT(cl);
6156
6157 // Look for the presence of each data member of anon_dm in clazz.
6158 //
6159 // If one data member of anon_dm is not present in clazz, then the
6160 // data member anon_dm is considered to not exist in clazz.
6161 for (auto anon_dm_m : cl->get_non_static_data_members())
6162 {
6163 // If the data member anon_dm_m is not an anonymous data member,
6164 // it's easy to look for it.
6165 if (!is_anonymous_data_member(anon_dm_m))
6166 {
6167 if (!clazz.find_data_member(anon_dm_m->get_name()))
6168 return false;
6169 }
6170 // If anon_dm_m is itself an anonymous data member then recurse
6171 else
6172 {
6173 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
6174 return false;
6175 }
6176 }
6177
6178 return true;
6179}
6180
6181/// Test if a given decl is anonymous or has a naming typedef.
6182///
6183/// @param d the decl to consider.
6184///
6185/// @return true iff @p d is anonymous or has a naming typedef.
6186bool
6188{
6189 if (d.get_is_anonymous() || d.get_naming_typedef())
6190 return true;
6191 return false;
6192}
6193
6194/// Set the offset of a data member into its containing class.
6195///
6196/// @param m the data member to consider.
6197///
6198/// @param o the offset, in bits.
6199void
6201{
6203
6204 dm_context_rel* ctxt_rel =
6205 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6206 ABG_ASSERT(ctxt_rel);
6207
6208 ctxt_rel->set_offset_in_bits(o);
6209}
6210
6211/// Get the offset of a data member.
6212///
6213/// @param m the data member to consider.
6214///
6215/// @return the offset (in bits) of @p m in its containing class.
6216uint64_t
6218{
6220 const dm_context_rel* ctxt_rel =
6221 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6222 ABG_ASSERT(ctxt_rel);
6223 return ctxt_rel->get_offset_in_bits();
6224}
6225
6226/// Get the offset of a data member.
6227///
6228/// @param m the data member to consider.
6229///
6230/// @return the offset (in bits) of @p m in its containing class.
6231uint64_t
6233{return get_data_member_offset(*m);}
6234
6235/// Get the offset of a data member.
6236///
6237/// @param m the data member to consider.
6238///
6239/// @return the offset (in bits) of @p m in its containing class.
6240uint64_t
6241get_data_member_offset(const decl_base_sptr d)
6242{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6243
6244/// Get the offset of the non-static data member that comes after a
6245/// given one.
6246///
6247/// If there is no data member after after the one given to this
6248/// function (maybe because the given one is the last data member of
6249/// the class type) then the function return false.
6250///
6251/// @param klass the class to consider.
6252///
6253/// @param dm the data member before the one we want to retrieve.
6254///
6255/// @param offset out parameter. This parameter is set by the
6256/// function to the offset of the data member that comes right after
6257/// the data member @p dm, iff the function returns true.
6258///
6259/// @return true iff the data member coming right after @p dm was
6260/// found.
6261bool
6263 const var_decl_sptr& dm,
6264 uint64_t& offset)
6265{
6266 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6267 if (!next_dm)
6268 return false;
6269 offset = get_data_member_offset(next_dm);
6270 return true;
6271}
6272
6273/// Get the offset of the non-static data member that comes after a
6274/// given one.
6275///
6276/// If there is no data member after after the one given to this
6277/// function (maybe because the given one is the last data member of
6278/// the class type) then the function return false.
6279///
6280/// @param klass the class to consider.
6281///
6282/// @param dm the data member before the one we want to retrieve.
6283///
6284/// @param offset out parameter. This parameter is set by the
6285/// function to the offset of the data member that comes right after
6286/// the data member @p dm, iff the function returns true.
6287///
6288/// @return true iff the data member coming right after @p dm was
6289/// found.
6290bool
6291get_next_data_member_offset(const class_or_union_sptr& klass,
6292 const var_decl_sptr& dm,
6293 uint64_t& offset)
6294{return get_next_data_member_offset(klass.get(), dm, offset);}
6295
6296/// Get the absolute offset of a data member.
6297///
6298/// If the data member is part of an anonymous data member then this
6299/// returns the absolute offset -- relative to the beginning of the
6300/// containing class of the anonymous data member.
6301///
6302/// @param m the data member to consider.
6303///
6304/// @return the aboslute offset of the data member @p m.
6305uint64_t
6307{
6309 const dm_context_rel* ctxt_rel =
6310 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6311 ABG_ASSERT(ctxt_rel);
6312
6313 const var_decl *containing_anonymous_data_member =
6314 ctxt_rel->get_anonymous_data_member();
6315
6316 uint64_t containing_anonymous_data_member_offset = 0;
6317 if (containing_anonymous_data_member)
6318 containing_anonymous_data_member_offset =
6319 get_absolute_data_member_offset(*containing_anonymous_data_member);
6320
6321 return (ctxt_rel->get_offset_in_bits()
6322 +
6323 containing_anonymous_data_member_offset);
6324}
6325
6326/// Get the absolute offset of a data member.
6327///
6328/// If the data member is part of an anonymous data member then this
6329/// returns the absolute offset -- relative to the beginning of the
6330/// containing class of the anonymous data member.
6331///
6332/// @param m the data member to consider.
6333///
6334/// @return the aboslute offset of the data member @p m.
6335uint64_t
6337{
6338 if (!m)
6339 return 0;
6341}
6342
6343/// Get the size of a given variable.
6344///
6345/// @param v the variable to consider.
6346///
6347/// @return the size of variable @p v.
6348uint64_t
6350{
6351 type_base_sptr t = v->get_type();
6352 ABG_ASSERT(t);
6353
6354 return t->get_size_in_bits();
6355}
6356
6357/// Set a flag saying if a data member is laid out.
6358///
6359/// @param m the data member to consider.
6360///
6361/// @param l true if @p m is to be considered as laid out.
6362void
6364{
6366 dm_context_rel* ctxt_rel =
6367 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6368 ctxt_rel->set_is_laid_out(l);
6369}
6370
6371/// Test whether a data member is laid out.
6372///
6373/// @param m the data member to consider.
6374///
6375/// @return true if @p m is laid out, false otherwise.
6376bool
6378{
6380 const dm_context_rel* ctxt_rel =
6381 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6382
6383 return ctxt_rel->get_is_laid_out();
6384}
6385
6386/// Test whether a data member is laid out.
6387///
6388/// @param m the data member to consider.
6389///
6390/// @return true if @p m is laid out, false otherwise.
6391bool
6393{return get_data_member_is_laid_out(*m);}
6394
6395/// Test whether a function_decl is a member function.
6396///
6397/// @param f the function_decl to test.
6398///
6399/// @return true if @p f is a member function, false otherwise.
6400bool
6402{return is_member_decl(f);}
6403
6404/// Test whether a function_decl is a member function.
6405///
6406/// @param f the function_decl to test.
6407///
6408/// @return true if @p f is a member function, false otherwise.
6409bool
6411{return is_member_decl(*f);}
6412
6413/// Test whether a function_decl is a member function.
6414///
6415/// @param f the function_decl to test.
6416///
6417/// @return true if @p f is a member function, false otherwise.
6418bool
6420{return is_member_decl(*f);}
6421
6422/// Test whether a member function is a constructor.
6423///
6424/// @param f the member function to test.
6425///
6426/// @return true if @p f is a constructor, false otherwise.
6427bool
6429{
6431
6432 const method_decl* m = is_method_decl(&f);
6433 ABG_ASSERT(m);
6434
6435 const mem_fn_context_rel* ctxt =
6436 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6437
6438 return ctxt->is_constructor();
6439}
6440
6441/// Test whether a member function is a constructor.
6442///
6443/// @param f the member function to test.
6444///
6445/// @return true if @p f is a constructor, false otherwise.
6446bool
6448{return get_member_function_is_ctor(*f);}
6449
6450
6451/// Setter for the is_ctor property of the member function.
6452///
6453/// @param f the member function to set.
6454///
6455/// @param f the new boolean value of the is_ctor property. Is true
6456/// if @p f is a constructor, false otherwise.
6457void
6459{
6461
6462 method_decl* m = is_method_decl(&f);
6463 ABG_ASSERT(m);
6464
6465 mem_fn_context_rel* ctxt =
6466 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6467
6468 ctxt->is_constructor(c);
6469}
6470
6471/// Setter for the is_ctor property of the member function.
6472///
6473/// @param f the member function to set.
6474///
6475/// @param f the new boolean value of the is_ctor property. Is true
6476/// if @p f is a constructor, false otherwise.
6477void
6480
6481/// Test whether a member function is a destructor.
6482///
6483/// @param f the function to test.
6484///
6485/// @return true if @p f is a destructor, false otherwise.
6486bool
6488{
6490
6491 const method_decl* m = is_method_decl(&f);
6492 ABG_ASSERT(m);
6493
6494 const mem_fn_context_rel* ctxt =
6495 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6496
6497 return ctxt->is_destructor();
6498}
6499
6500/// Test whether a member function is a destructor.
6501///
6502/// @param f the function to test.
6503///
6504/// @return true if @p f is a destructor, false otherwise.
6505bool
6507{return get_member_function_is_dtor(*f);}
6508
6509/// Set the destructor-ness property of a member function.
6510///
6511/// @param f the function to set.
6512///
6513/// @param d true if @p f is a destructor, false otherwise.
6514void
6516{
6518
6519 method_decl* m = is_method_decl(&f);
6520 ABG_ASSERT(m);
6521
6522 mem_fn_context_rel* ctxt =
6523 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6524
6525 ctxt->is_destructor(d);
6526}
6527
6528/// Set the destructor-ness property of a member function.
6529///
6530/// @param f the function to set.
6531///
6532/// @param d true if @p f is a destructor, false otherwise.
6533void
6536
6537/// Test whether a member function is const.
6538///
6539/// @param f the function to test.
6540///
6541/// @return true if @p f is const, false otherwise.
6542bool
6544{
6546
6547 const method_decl* m = is_method_decl(&f);
6548 ABG_ASSERT(m);
6549
6550 const mem_fn_context_rel* ctxt =
6551 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6552
6553 return ctxt->is_const();
6554}
6555
6556/// Test whether a member function is const.
6557///
6558/// @param f the function to test.
6559///
6560/// @return true if @p f is const, false otherwise.
6561bool
6563{return get_member_function_is_const(*f);}
6564
6565/// set the const-ness property of a member function.
6566///
6567/// @param f the function to set.
6568///
6569/// @param is_const the new value of the const-ness property of @p f
6570void
6572{
6574
6575 method_decl* m = is_method_decl(&f);
6576 ABG_ASSERT(m);
6577
6578 mem_fn_context_rel* ctxt =
6579 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6580
6581 ctxt->is_const(is_const);
6582}
6583
6584/// set the const-ness property of a member function.
6585///
6586/// @param f the function to set.
6587///
6588/// @param is_const the new value of the const-ness property of @p f
6589void
6591{set_member_function_is_const(*f, is_const);}
6592
6593/// Test if a virtual member function has a vtable offset set.
6594///
6595/// @param f the virtual member function to consider.
6596///
6597/// @return true iff the virtual member function has its vtable offset
6598/// set, i.e, if the vtable offset of @p is different from -1.
6599bool
6601{return get_member_function_vtable_offset(f) != -1;}
6602
6603/// Get the vtable offset of a member function.
6604///
6605/// @param f the member function to consider.
6606///
6607/// @return the vtable offset of @p f. Note that a vtable offset of
6608/// value -1 means that the member function does *NOT* yet have a
6609/// vtable offset associated to it.
6610ssize_t
6612{
6614
6615 const method_decl* m =
6616 dynamic_cast<const method_decl*>(&f);
6617 ABG_ASSERT(m);
6618
6619 const mem_fn_context_rel* ctxt =
6620 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6621
6622 return ctxt->vtable_offset();
6623}
6624
6625/// Get the vtable offset of a member function.
6626///
6627/// @param f the member function to consider.
6628///
6629/// @return the vtable offset of @p f. Note that a vtable offset of
6630/// value -1 means that the member function does *NOT* yet have a
6631/// vtable offset associated to it.
6632ssize_t
6635
6636/// Set the vtable offset of a member function.
6637///
6638/// @param f the member function to consider.
6639///
6640/// @param s the new vtable offset. Please note that a vtable offset
6641/// of value -1 means that the virtual member function does not (yet)
6642/// have any vtable offset associated to it.
6643void
6645{
6647
6648 method_decl* m = is_method_decl(&f);
6649 ABG_ASSERT(m);
6650
6651 mem_fn_context_rel* ctxt =
6652 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6653
6654 ctxt->vtable_offset(s);
6655}
6656
6657/// Get the vtable offset of a member function.
6658///
6659/// @param f the member function to consider.
6660///
6661/// @param s the new vtable offset. Please note that a vtable offset
6662/// of value -1 means that the virtual member function does not (yet)
6663/// have any vtable offset associated to it.
6664void
6666{return set_member_function_vtable_offset(*f, s);}
6667
6668/// Test if a given member function is virtual.
6669///
6670/// @param mem_fn the member function to consider.
6671///
6672/// @return true iff a @p mem_fn is virtual.
6673bool
6675{
6677
6678 const method_decl* m =
6679 dynamic_cast<const method_decl*>(&f);
6680 ABG_ASSERT(m);
6681
6682 const mem_fn_context_rel* ctxt =
6683 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6684
6685 return ctxt->is_virtual();
6686}
6687
6688/// Test if a given member function is virtual.
6689///
6690/// @param mem_fn the member function to consider.
6691///
6692/// @return true iff a @p mem_fn is virtual.
6693bool
6695{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6696
6697/// Test if a given member function is virtual.
6698///
6699/// @param mem_fn the member function to consider.
6700///
6701/// @return true iff a @p mem_fn is virtual.
6702bool
6704{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6705
6706/// Set the virtual-ness of a member function.
6707///
6708/// @param f the member function to consider.
6709///
6710/// @param is_virtual set to true if the function is virtual.
6711void
6713{
6715
6716 method_decl* m = is_method_decl(&f);
6717 ABG_ASSERT(m);
6718
6719 mem_fn_context_rel* ctxt =
6720 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6721
6722 ctxt->is_virtual(is_virtual);
6723}
6724
6725/// Set the virtual-ness of a member function.
6726///
6727/// @param f the member function to consider.
6728///
6729/// @param is_virtual set to true if the function is virtual.
6730void
6732{
6733 if (fn)
6734 {
6735 set_member_function_is_virtual(*fn, is_virtual);
6737 (dynamic_pointer_cast<method_decl>(fn));
6738 }
6739}
6740
6741/// Recursively returns the the underlying type of a typedef. The
6742/// return type should not be a typedef of anything anymore.
6743///
6744///
6745/// Also recursively strip typedefs from the sub-types of the type
6746/// given in arguments.
6747///
6748/// Note that this function builds types in which typedefs are
6749/// stripped off. Usually, types are held by their scope, so their
6750/// life time is bound to the life time of their scope. But as this
6751/// function cannot really insert the built type into it's scope, it
6752/// must ensure that the newly built type stays live long enough.
6753///
6754/// So, if the newly built type has a canonical type, this function
6755/// returns the canonical type. Otherwise, this function ensure that
6756/// the newly built type has a life time that is the same as the life
6757/// time of the entire libabigail library.
6758///
6759/// @param type the type to strip the typedefs from.
6760///
6761/// @return the resulting type stripped from its typedefs, or just
6762/// return @p type if it has no typedef in any of its sub-types.
6763type_base_sptr
6764strip_typedef(const type_base_sptr type)
6765{
6766 if (!type)
6767 return type;
6768
6769 // If type is a class type then do not try to strip typedefs from it.
6770 // And if it has no canonical type (which can mean that it's a
6771 // declaration-only class), then, make sure its live for ever and
6772 // return it.
6773 if (class_decl_sptr cl = is_class_type(type))
6774 {
6775 if (!cl->get_canonical_type())
6776 keep_type_alive(type);
6777 return type;
6778 }
6779
6780 const environment& env = type->get_environment();
6781 type_base_sptr t = type;
6782
6783 if (const typedef_decl_sptr ty = is_typedef(t))
6784 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6785 else if (const reference_type_def_sptr ty = is_reference_type(t))
6786 {
6787 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6788 env));
6789 ABG_ASSERT(p);
6790 t.reset(new reference_type_def(p,
6791 ty->is_lvalue(),
6792 ty->get_size_in_bits(),
6793 ty->get_alignment_in_bits(),
6794 ty->get_location()));
6795 }
6796 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6797 {
6798 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6799 env));
6800 ABG_ASSERT(p);
6801 t.reset(new pointer_type_def(p,
6802 ty->get_size_in_bits(),
6803 ty->get_alignment_in_bits(),
6804 ty->get_location()));
6805 }
6806 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6807 {
6808 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6809 env));
6810 ABG_ASSERT(p);
6811 t.reset(new qualified_type_def(p,
6812 ty->get_cv_quals(),
6813 ty->get_location()));
6814 }
6815 else if (const array_type_def_sptr ty = is_array_type(t))
6816 {
6817 type_base_sptr p = strip_typedef(ty->get_element_type());
6818 ABG_ASSERT(p);
6819 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6820 }
6821 else if (const method_type_sptr ty = is_method_type(t))
6822 {
6824 for (function_decl::parameters::const_iterator i =
6825 ty->get_parameters().begin();
6826 i != ty->get_parameters().end();
6827 ++i)
6828 {
6830 type_base_sptr typ = strip_typedef(p->get_type());
6831 ABG_ASSERT(typ);
6833 (new function_decl::parameter(typ,
6834 p->get_index(),
6835 p->get_name(),
6836 p->get_location(),
6837 p->get_variadic_marker(),
6838 p->get_is_artificial()));
6839 parm.push_back(stripped);
6840 }
6841 type_base_sptr p = strip_typedef(ty->get_return_type());
6842 ABG_ASSERT(!!p == !!ty->get_return_type());
6843 t.reset(new method_type(p, ty->get_class_type(),
6844 parm, ty->get_is_const(),
6845 ty->get_size_in_bits(),
6846 ty->get_alignment_in_bits()));
6847 }
6848 else if (const function_type_sptr ty = is_function_type(t))
6849 {
6851 for (function_decl::parameters::const_iterator i =
6852 ty->get_parameters().begin();
6853 i != ty->get_parameters().end();
6854 ++i)
6855 {
6857 type_base_sptr typ = strip_typedef(p->get_type());
6858 ABG_ASSERT(typ);
6860 (new function_decl::parameter(typ,
6861 p->get_index(),
6862 p->get_name(),
6863 p->get_location(),
6864 p->get_variadic_marker(),
6865 p->get_is_artificial()));
6866 parm.push_back(stripped);
6867 }
6868 type_base_sptr p = strip_typedef(ty->get_return_type());
6869 ABG_ASSERT(!!p == !!ty->get_return_type());
6870 t.reset(new function_type(p, parm,
6871 ty->get_size_in_bits(),
6872 ty->get_alignment_in_bits()));
6873 }
6874
6875 if (!t->get_translation_unit())
6876 t->set_translation_unit(type->get_translation_unit());
6877
6878 if (!(type->get_canonical_type() && canonicalize(t)))
6879 keep_type_alive(t);
6880
6881 return t->get_canonical_type() ? t->get_canonical_type() : t;
6882}
6883
6884/// Strip qualification from a qualified type, when it makes sense.
6885///
6886/// DWARF constructs "const reference". This is redundant because a
6887/// reference is always const. It also constructs the useless "const
6888/// void" type. The issue is these redundant types then leak into the
6889/// IR and make for bad diagnostics.
6890///
6891/// This function thus strips the const qualifier from the type in
6892/// that case. It might contain code to strip other cases like this
6893/// in the future.
6894///
6895/// @param t the type to strip const qualification from.
6896///
6897/// @return the stripped type or just return @p t.
6898decl_base_sptr
6899strip_useless_const_qualification(const qualified_type_def_sptr t)
6900{
6901 if (!t)
6902 return t;
6903
6904 decl_base_sptr result = t;
6905 type_base_sptr u = t->get_underlying_type();
6906 const environment& env = t->get_environment();
6907
6908 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6909 && (is_reference_type(u)))
6910 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6911 && env.is_void_type(u))
6912 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6913 // Let's strip the const qualifier because a reference is always
6914 // 'const' and a const void doesn't make sense. They will just
6915 // lead to spurious changes later down the pipeline, that we'll
6916 // have to deal with by doing painful and error-prone editing of
6917 // the diff IR. Dropping that useless and inconsistent artefact
6918 // right here seems to be a good way to go.
6919 result = is_decl(u);
6920
6921 return result;
6922}
6923
6924/// Merge redundant qualifiers from a tree of qualified types.
6925///
6926/// Suppose a tree of qualified types leads to:
6927///
6928/// const virtual const restrict const int;
6929///
6930/// Suppose the IR tree of qualified types ressembles (with C meaning
6931/// const, V meaning virtual and R meaning restrict):
6932///
6933/// [C|V]-->[C|R] -->[C] --> [int].
6934///
6935/// This function walks the IR and remove the redundant CV qualifiers
6936/// so the IR becomes:
6937///
6938/// [C|V] --> [R] --> [] -->[int].
6939///
6940/// Note that the empty qualified type (noted []) represents a
6941/// qualified type with no qualifier. It's rare, but it can exist.
6942/// I've put it here just for the sake of example.
6943///
6944/// The resulting IR thus represents the (merged) type:
6945///
6946/// const virtual restrict int.
6947///
6948/// This function is a sub-routine of the overload @ref
6949/// strip_useless_const_qualification which doesn't return any value.
6950///
6951/// @param t the qualified type to consider.
6952///
6953/// @param redundant_quals the (redundant) qualifiers to be removed
6954/// from the qualifiers of the underlying types of @p t.
6955///
6956/// @return the underlying type of @p t which might have had its
6957/// redundant qualifiers removed.
6958static qualified_type_def_sptr
6959strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
6960 qualified_type_def::CV redundant_quals)
6961{
6962 if (!t)
6963 return t;
6964
6965 // We must NOT edit canonicalized types.
6966 ABG_ASSERT(!t->get_canonical_type());
6967
6968 qualified_type_def_sptr underlying_qualified_type =
6969 is_qualified_type(t->get_underlying_type());
6970
6971 // Let's build 'currated qualifiers' that are the qualifiers of the
6972 // current type from which redundant qualifiers are removed.
6973 qualified_type_def::CV currated_quals = t->get_cv_quals();
6974
6975 // Remove the redundant qualifiers from these currated qualifiers
6976 currated_quals &= ~redundant_quals;
6977 t->set_cv_quals(currated_quals);
6978
6979 // The redundant qualifiers, moving forward, is now the union of the
6980 // previous set of redundant qualifiers and the currated qualifiers.
6981 redundant_quals |= currated_quals;
6982
6983 qualified_type_def_sptr result = t;
6984 if (underlying_qualified_type)
6985 // Now remove the redundant qualifiers from the qualified types
6986 // potentially carried by the underlying type.
6987 result =
6988 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
6989 redundant_quals);
6990
6991 return result;
6992}
6993
6994/// Merge redundant qualifiers from a tree of qualified types.
6995///
6996/// Suppose a tree of qualified types leads to:
6997///
6998/// const virtual const restrict const int;
6999///
7000/// Suppose the IR tree of qualified types ressembles (with C meaning
7001/// const, V meaning virtual and R meaning restrict):
7002///
7003/// [C|V]-->[C|R] -->[C] --> [int].
7004///
7005/// This function walks the IR and remove the redundant CV qualifiers
7006/// so the IR becomes:
7007///
7008/// [C|V] --> [R] --> [] -->[int].
7009///
7010/// Note that the empty qualified type (noted []) represents a
7011/// qualified type with no qualifier. It's rare, but it can exist.
7012/// I've put it here just for the sake of example.
7013///
7014/// The resulting IR thus represents the (merged) type:
7015///
7016/// const virtual restrict int.
7017///
7018/// @param t the qualified type to consider. The IR below the
7019/// argument to this parameter will be edited to remove redundant
7020/// qualifiers where applicable.
7021void
7022strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
7023{
7024 if (!t)
7025 return;
7026
7027 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
7028 strip_redundant_quals_from_underyling_types(t, redundant_quals);
7029}
7030
7031/// Return the leaf underlying type node of a @ref typedef_decl node.
7032///
7033/// If the underlying type of a @ref typedef_decl node is itself a
7034/// @ref typedef_decl node, then recursively look at the underlying
7035/// type nodes to get the first one that is not a a @ref typedef_decl
7036/// node. This is what a leaf underlying type node means.
7037///
7038/// Otherwise, if the underlying type node of @ref typedef_decl is
7039/// *NOT* a @ref typedef_decl node, then just return the underlying
7040/// type node.
7041///
7042/// And if the type node considered is not a @ref typedef_decl node,
7043/// then just return it.
7044///
7045/// @return the leaf underlying type node of a @p type.
7046type_base_sptr
7047peel_typedef_type(const type_base_sptr& type)
7048{
7049 typedef_decl_sptr t = is_typedef(type);
7050 if (!t)
7051 return type;
7052
7053 if (is_typedef(t->get_underlying_type()))
7054 return peel_typedef_type(t->get_underlying_type());
7055 return t->get_underlying_type();
7056}
7057
7058/// Return the leaf underlying type node of a @ref typedef_decl node.
7059///
7060/// If the underlying type of a @ref typedef_decl node is itself a
7061/// @ref typedef_decl node, then recursively look at the underlying
7062/// type nodes to get the first one that is not a a @ref typedef_decl
7063/// node. This is what a leaf underlying type node means.
7064///
7065/// Otherwise, if the underlying type node of @ref typedef_decl is
7066/// *NOT* a @ref typedef_decl node, then just return the underlying
7067/// type node.
7068///
7069/// And if the type node considered is not a @ref typedef_decl node,
7070/// then just return it.
7071///
7072/// @return the leaf underlying type node of a @p type.
7073const type_base*
7075{
7076 const typedef_decl* t = is_typedef(type);
7077 if (!t)
7078 return type;
7079
7080 return peel_typedef_type(t->get_underlying_type()).get();
7081}
7082
7083/// Return the leaf pointed-to type node of a @ref pointer_type_def
7084/// node.
7085///
7086/// If the pointed-to type of a @ref pointer_type_def node is itself a
7087/// @ref pointer_type_def node, then recursively look at the
7088/// pointed-to type nodes to get the first one that is not a a @ref
7089/// pointer_type_def node. This is what a leaf pointed-to type node
7090/// means.
7091///
7092/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7093/// *NOT* a @ref pointer_type_def node, then just return the
7094/// pointed-to type node.
7095///
7096/// And if the type node considered is not a @ref pointer_type_def
7097/// node, then just return it.
7098///
7099/// @return the leaf pointed-to type node of a @p type.
7100type_base_sptr
7101peel_pointer_type(const type_base_sptr& type)
7102{
7104 if (!t)
7105 return type;
7106
7107 if (is_pointer_type(t->get_pointed_to_type()))
7108 return peel_pointer_type(t->get_pointed_to_type());
7109 return t->get_pointed_to_type();
7110}
7111
7112/// Return the leaf pointed-to type node of a @ref pointer_type_def
7113/// node.
7114///
7115/// If the pointed-to type of a @ref pointer_type_def node is itself a
7116/// @ref pointer_type_def node, then recursively look at the
7117/// pointed-to type nodes to get the first one that is not a a @ref
7118/// pointer_type_def node. This is what a leaf pointed-to type node
7119/// means.
7120///
7121/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7122/// *NOT* a @ref pointer_type_def node, then just return the
7123/// pointed-to type node.
7124///
7125/// And if the type node considered is not a @ref pointer_type_def
7126/// node, then just return it.
7127///
7128/// @return the leaf pointed-to type node of a @p type.
7129const type_base*
7131{
7132 const pointer_type_def* t = is_pointer_type(type);
7133 if (!t)
7134 return type;
7135
7136 return peel_pointer_type(t->get_pointed_to_type()).get();
7137}
7138
7139/// Return the leaf pointed-to type node of a @ref reference_type_def
7140/// node.
7141///
7142/// If the pointed-to type of a @ref reference_type_def node is itself
7143/// a @ref reference_type_def node, then recursively look at the
7144/// pointed-to type nodes to get the first one that is not a a @ref
7145/// reference_type_def node. This is what a leaf pointed-to type node
7146/// means.
7147///
7148/// Otherwise, if the pointed-to type node of @ref reference_type_def
7149/// is *NOT* a @ref reference_type_def node, then just return the
7150/// pointed-to type node.
7151///
7152/// And if the type node considered is not a @ref reference_type_def
7153/// node, then just return it.
7154///
7155/// @return the leaf pointed-to type node of a @p type.
7156type_base_sptr
7157peel_reference_type(const type_base_sptr& type)
7158{
7160 if (!t)
7161 return type;
7162
7163 if (is_reference_type(t->get_pointed_to_type()))
7164 return peel_reference_type(t->get_pointed_to_type());
7165 return t->get_pointed_to_type();
7166}
7167
7168/// Return the leaf pointed-to type node of a @ref reference_type_def
7169/// node.
7170///
7171/// If the pointed-to type of a @ref reference_type_def node is itself
7172/// a @ref reference_type_def node, then recursively look at the
7173/// pointed-to type nodes to get the first one that is not a a @ref
7174/// reference_type_def node. This is what a leaf pointed-to type node
7175/// means.
7176///
7177/// Otherwise, if the pointed-to type node of @ref reference_type_def
7178/// is *NOT* a @ref reference_type_def node, then just return the
7179/// pointed-to type node.
7180///
7181/// And if the type node considered is not a @ref reference_type_def
7182/// node, then just return it.
7183///
7184/// @return the leaf pointed-to type node of a @p type.
7185const type_base*
7187{
7188 const reference_type_def* t = is_reference_type(type);
7189 if (!t)
7190 return type;
7191
7192 return peel_reference_type(t->get_pointed_to_type()).get();
7193}
7194
7195/// Return the leaf element type of an array.
7196///
7197/// If the element type is itself an array, then recursively return
7198/// the element type of that array itself.
7199///
7200/// @param type the array type to consider. If this is not an array
7201/// type, this type is returned by the function.
7202///
7203/// @return the leaf element type of the array @p type, or, if it's
7204/// not an array type, then just return @p.
7205const type_base_sptr
7206peel_array_type(const type_base_sptr& type)
7207{
7208 const array_type_def_sptr t = is_array_type(type);
7209 if (!t)
7210 return type;
7211
7212 return peel_array_type(t->get_element_type());
7213}
7214
7215/// Return the leaf element type of an array.
7216///
7217/// If the element type is itself an array, then recursively return
7218/// the element type of that array itself.
7219///
7220/// @param type the array type to consider. If this is not an array
7221/// type, this type is returned by the function.
7222///
7223/// @return the leaf element type of the array @p type, or, if it's
7224/// not an array type, then just return @p.
7225const type_base*
7227{
7228 const array_type_def* t = is_array_type(type);
7229 if (!t)
7230 return type;
7231
7232 return peel_array_type(t->get_element_type()).get();
7233}
7234
7235/// Return the leaf underlying type of a qualified type.
7236///
7237/// If the underlying type is itself a qualified type, then
7238/// recursively return the first underlying type of that qualified
7239/// type to return the first underlying type that is not a qualified type.
7240///
7241/// If the underlying type is NOT a qualified type, then just return
7242/// that underlying type.
7243///
7244/// @param type the qualified type to consider.
7245///
7246/// @return the leaf underlying type.
7247const type_base*
7249{
7250 const qualified_type_def* t = is_qualified_type(type);
7251 if (!t)
7252 return type;
7253
7254 return peel_qualified_type(t->get_underlying_type().get());
7255}
7256
7257/// Return the leaf underlying type of a qualified type.
7258///
7259/// If the underlying type is itself a qualified type, then
7260/// recursively return the first underlying type of that qualified
7261/// type to return the first underlying type that is not a qualified type.
7262///
7263/// If the underlying type is NOT a qualified type, then just return
7264/// that underlying type.
7265///
7266/// @param type the qualified type to consider.
7267///
7268/// @return the leaf underlying type.
7269const type_base_sptr
7270peel_qualified_type(const type_base_sptr& type)
7271{
7272 const qualified_type_def_sptr t = is_qualified_type(type);
7273 if (!t)
7274 return type;
7275
7276 return peel_qualified_type(t->get_underlying_type());
7277}
7278
7279/// Return the leaf underlying type of a qualified or typedef type.
7280///
7281/// If the underlying type is itself a qualified or typedef type, then
7282/// recursively return the first underlying type of that qualified or
7283/// typedef type to return the first underlying type that is not a
7284/// qualified or typedef type.
7285///
7286/// If the underlying type is NOT a qualified nor a typedef type, then
7287/// just return that underlying type.
7288///
7289/// @param type the qualified or typedef type to consider.
7290///
7291/// @return the leaf underlying type.
7292type_base*
7294{
7295 while (is_typedef(type) || is_qualified_type(type))
7296 {
7297 if (const typedef_decl* t = is_typedef(type))
7298 type = peel_typedef_type(t);
7299
7300 if (const qualified_type_def* t = is_qualified_type(type))
7301 type = peel_qualified_type(t);
7302 }
7303
7304 return const_cast<type_base*>(type);
7305}
7306
7307/// Return the leaf underlying type of a qualified or typedef type.
7308///
7309/// If the underlying type is itself a qualified or typedef type, then
7310/// recursively return the first underlying type of that qualified or
7311/// typedef type to return the first underlying type that is not a
7312/// qualified or typedef type.
7313///
7314/// If the underlying type is NOT a qualified nor a typedef type, then
7315/// just return that underlying type.
7316///
7317/// @param type the qualified or typedef type to consider.
7318///
7319/// @return the leaf underlying type.
7320type_base_sptr
7321peel_qualified_or_typedef_type(const type_base_sptr &t)
7322{
7323 type_base_sptr type = t;
7324 while (is_typedef(type) || is_qualified_type(type))
7325 {
7326 if (typedef_decl_sptr t = is_typedef(type))
7327 type = peel_typedef_type(t);
7328
7329 if (qualified_type_def_sptr t = is_qualified_type(type))
7330 type = peel_qualified_type(t);
7331 }
7332
7333 return type;
7334}
7335
7336/// Return the leaf underlying or pointed-to type node of a @ref
7337/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7338/// or @ref array_type_def node.
7339///
7340/// @param type the type to peel.
7341///
7342/// @return the leaf underlying or pointed-to type node of @p type.
7343type_base_sptr
7345{
7346 type_base_sptr typ = type;
7347 while (is_typedef(typ)
7348 || is_pointer_type(typ)
7349 || is_reference_type(typ)
7350 || is_array_type(typ))
7351 {
7352 if (typedef_decl_sptr t = is_typedef(typ))
7353 typ = peel_typedef_type(t);
7354
7356 typ = peel_pointer_type(t);
7357
7359 typ = peel_reference_type(t);
7360
7361 if (const array_type_def_sptr t = is_array_type(typ))
7362 typ = peel_array_type(t);
7363 }
7364
7365 return typ;
7366}
7367
7368/// Return the leaf underlying or pointed-to type node of a @ref
7369/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7370/// node.
7371///
7372/// @param type the type to peel.
7373///
7374/// @return the leaf underlying or pointed-to type node of @p type.
7375type_base*
7377{
7378 while (is_typedef(type)
7379 || is_pointer_type(type)
7380 || is_reference_type(type)
7381 || is_array_type(type))
7382 {
7383 if (const typedef_decl* t = is_typedef(type))
7384 type = peel_typedef_type(t);
7385
7386 if (const pointer_type_def* t = is_pointer_type(type))
7387 type = peel_pointer_type(t);
7388
7389 if (const reference_type_def* t = is_reference_type(type))
7390 type = peel_reference_type(t);
7391
7392 if (const array_type_def* t = is_array_type(type))
7393 type = peel_array_type(t);
7394 }
7395
7396 return const_cast<type_base*>(type);
7397}
7398
7399/// Return the leaf underlying or pointed-to type node of a @ref
7400/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7401/// node.
7402///
7403/// @param type the type to peel.
7404///
7405/// @return the leaf underlying or pointed-to type node of @p type.
7406type_base*
7408 bool peel_qual_type)
7409{
7410 while (is_typedef(type)
7411 || is_pointer_type(type)
7412 || is_reference_type(type)
7413 || is_array_type(type)
7414 || (peel_qual_type && is_qualified_type(type)))
7415 {
7416 if (const typedef_decl* t = is_typedef(type))
7417 type = peel_typedef_type(t);
7418
7419 if (const pointer_type_def* t = is_pointer_type(type))
7420 type = peel_pointer_type(t);
7421
7422 if (const reference_type_def* t = is_reference_type(type))
7423 type = peel_reference_type(t);
7424
7425 if (const array_type_def* t = is_array_type(type))
7426 type = peel_array_type(t);
7427
7428 if (peel_qual_type)
7429 if (const qualified_type_def* t = is_qualified_type(type))
7430 type = peel_qualified_type(t);
7431 }
7432
7433 return const_cast<type_base*>(type);
7434}
7435
7436/// Return the leaf underlying or pointed-to type node of a, @ref
7437/// pointer_type_def, @ref reference_type_def or @ref
7438/// qualified_type_def type node.
7439///
7440/// @param type the type to peel.
7441///
7442/// @param peel_qualified_type if true, also peel qualified types.
7443///
7444/// @return the leaf underlying or pointed-to type node of @p type.
7445type_base*
7447 bool peel_qual_type)
7448{
7449 while (is_pointer_type(type)
7450 || is_reference_type(type)
7451 || is_array_type(type)
7452 || (peel_qual_type && is_qualified_type(type)))
7453 {
7454 if (const pointer_type_def* t = is_pointer_type(type))
7455 type = peel_pointer_type(t);
7456
7457 if (const reference_type_def* t = is_reference_type(type))
7458 type = peel_reference_type(t);
7459
7460 if (const array_type_def* t = is_array_type(type))
7461 type = peel_array_type(t);
7462
7463 if (peel_qual_type)
7464 if (const qualified_type_def* t = is_qualified_type(type))
7465 type = peel_qualified_type(t);
7466 }
7467
7468 return const_cast<type_base*>(type);
7469}
7470
7471/// Clone an array type.
7472///
7473/// Note that the element type of the new array is shared witht the
7474/// old one.
7475///
7476/// @param array the array type to clone.
7477///
7478/// @return a newly built array type. Note that it needs to be added
7479/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7480/// bound to the one of that scope. Otherwise, its lifetime is bound
7481/// to the lifetime of its containing shared pointer.
7484{
7485 vector<array_type_def::subrange_sptr> subranges;
7486
7487 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7488 array->get_subranges().begin();
7489 i != array->get_subranges().end();
7490 ++i)
7491 {
7493 (new array_type_def::subrange_type(array->get_environment(),
7494 (*i)->get_name(),
7495 (*i)->get_lower_bound(),
7496 (*i)->get_upper_bound(),
7497 (*i)->get_underlying_type(),
7498 (*i)->get_location(),
7499 (*i)->get_language()));
7500 subrange->is_infinite((*i)->is_infinite());
7501 if (scope_decl *scope = (*i)->get_scope())
7502 add_decl_to_scope(subrange, scope);
7503 subranges.push_back(subrange);
7504 }
7505
7506 array_type_def_sptr result
7507 (new array_type_def(array->get_element_type(),
7508 subranges, array->get_location()));
7509
7510 return result;
7511}
7512
7513/// Clone a typedef type.
7514///
7515/// Note that the underlying type of the newly constructed typedef is
7516/// shared with the old one.
7517///
7518/// @param t the typedef to clone.
7519///
7520/// @return the newly constructed typedef. Note that it needs to be
7521/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7522/// to be bound to the one of that scope. Otherwise, its lifetime is
7523/// bound to the lifetime of its containing shared pointer.
7526{
7527 if (!t)
7528 return t;
7529
7530 typedef_decl_sptr result
7531 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7532 t->get_location(), t->get_linkage_name(),
7533 t->get_visibility()));
7534 return result;
7535}
7536
7537/// Clone a qualifiend type.
7538///
7539/// Note that underlying type of the newly constructed qualified type
7540/// is shared with the old one.
7541///
7542/// @param t the qualified type to clone.
7543///
7544/// @return the newly constructed qualified type. Note that it needs
7545/// to be added to a scope (e.g, using add_decl_to_scope) for its
7546/// lifetime to be bound to the one of that scope. Otherwise, its
7547/// lifetime is bound to the lifetime of its containing shared
7548/// pointer.
7549qualified_type_def_sptr
7550clone_qualified_type(const qualified_type_def_sptr& t)
7551{
7552 if (!t)
7553 return t;
7554
7555 qualified_type_def_sptr result
7556 (new qualified_type_def(t->get_underlying_type(),
7557 t->get_cv_quals(), t->get_location()));
7558
7559 return result;
7560}
7561
7562/// Clone a typedef, an array or a qualified tree.
7563///
7564/// @param type the typedef, array or qualified tree to clone. any
7565/// order.
7566///
7567/// @return the cloned type, or NULL if @type was neither a typedef,
7568/// array nor a qualified type.
7569static type_base_sptr
7570clone_typedef_array_qualified_type(type_base_sptr type)
7571{
7572 if (!type)
7573 return type;
7574
7575 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7576 type_base_sptr result;
7577
7578 if (typedef_decl_sptr t = is_typedef(type))
7579 result = clone_typedef(is_typedef(t));
7580 else if (qualified_type_def_sptr t = is_qualified_type(type))
7581 result = clone_qualified_type(t);
7582 else if (array_type_def_sptr t = is_array_type(type))
7583 result = clone_array(t);
7584 else
7585 return type_base_sptr();
7586
7587 if (scope)
7588 add_decl_to_scope(is_decl(result), scope);
7589
7590 return result;
7591}
7592
7593/// Clone a type tree made of an array or a typedef of array.
7594///
7595/// Note that this can be a tree which root node is a typedef an which
7596/// sub-tree can be any arbitrary combination of typedef, qualified
7597/// type and arrays.
7598///
7599/// @param t the array or typedef of qualified array to consider.
7600///
7601/// @return a clone of @p t.
7602type_base_sptr
7603clone_array_tree(const type_base_sptr t)
7604{
7606
7607 scope_decl* scope = is_decl(t)->get_scope();
7608 type_base_sptr result = clone_typedef_array_qualified_type(t);
7609 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7610
7611 type_base_sptr subtree;
7612 if (typedef_decl_sptr type = is_typedef(result))
7613 {
7614 type_base_sptr s =
7615 clone_typedef_array_qualified_type(type->get_underlying_type());
7616 if (s)
7617 {
7618 subtree = s;
7619 type->set_underlying_type(subtree);
7620 }
7621 }
7622 else if (array_type_def_sptr type = is_array_type(result))
7623 {
7624 type_base_sptr s =
7625 clone_typedef_array_qualified_type(type->get_element_type());
7626 if (s)
7627 {
7628 subtree = s;
7629 type->set_element_type(subtree);
7630 }
7631 }
7632 add_decl_to_scope(is_decl(subtree), scope);
7633
7634 for (;;)
7635 {
7636 if (typedef_decl_sptr t = is_typedef(subtree))
7637 {
7638 type_base_sptr s =
7639 clone_typedef_array_qualified_type(t->get_underlying_type());
7640 if (s)
7641 {
7642 scope_decl* scope =
7643 is_decl(t->get_underlying_type())->get_scope();
7644 ABG_ASSERT(scope);
7645 add_decl_to_scope(is_decl(s), scope);
7646 t->set_underlying_type (s);
7647 subtree = s;
7648 }
7649 else
7650 break;
7651 }
7652 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7653 {
7654 type_base_sptr s =
7655 clone_typedef_array_qualified_type(t->get_underlying_type());
7656 if (s)
7657 {
7658 scope_decl* scope =
7659 is_decl(t->get_underlying_type())->get_scope();
7660 ABG_ASSERT(scope);
7661 add_decl_to_scope(is_decl(s), scope);
7662 t->set_underlying_type(s);
7663 subtree = s;
7664 }
7665 else
7666 break;
7667 }
7668 else if (array_type_def_sptr t = is_array_type(subtree))
7669 {
7670 type_base_sptr e = t->get_element_type();
7671 if (is_typedef(e) || is_qualified_type(e))
7672 {
7673 type_base_sptr s =
7674 clone_typedef_array_qualified_type(e);
7675 if (s)
7676 {
7677 scope_decl* scope = is_decl(e)->get_scope();
7678 ABG_ASSERT(scope);
7679 add_decl_to_scope(is_decl(s), scope);
7680 t->set_element_type(s);
7681 }
7682 else
7683 break;
7684 }
7685 break;
7686 }
7687 else
7688 break;
7689 }
7690 return result;
7691}
7692
7693/// Update the qualified name of a given sub-tree.
7694///
7695/// @param d the sub-tree for which to update the qualified name.
7696static void
7697update_qualified_name(decl_base * d)
7698{
7699 ::qualified_name_setter setter;
7700 d->traverse(setter);
7701}
7702
7703/// Update the qualified name of a given sub-tree.
7704///
7705/// @param d the sub-tree for which to update the qualified name.
7706static void
7707update_qualified_name(decl_base_sptr d)
7708{return update_qualified_name(d.get());}
7709
7710// <scope_decl stuff>
7711
7712/// Hash a type by returning the pointer value of its canonical type.
7713///
7714/// @param l the type to hash.
7715///
7716/// @return the the pointer value of the canonical type of @p l.
7717size_t
7718canonical_type_hash::operator()(const type_base_sptr& l) const
7719{return operator()(l.get());}
7720
7721/// Hash a (canonical) type by returning its pointer value
7722///
7723/// @param l the canonical type to hash.
7724///
7725/// @return the pointer value of the canonical type of @p l.
7726size_t
7728{return reinterpret_cast<size_t>(l);}
7729
7730struct scope_decl::priv
7731{
7732 declarations members_;
7733 declarations sorted_members_;
7734 type_base_sptrs_type member_types_;
7735 type_base_sptrs_type sorted_member_types_;
7736 scopes member_scopes_;
7737 canonical_type_sptr_set_type canonical_types_;
7738 type_base_sptrs_type sorted_canonical_types_;
7739}; // end struct scope_decl::priv
7740
7741/// Constructor of the @ref scope_decl type.
7742///
7743/// @param the environment to use for the new instance.
7744///
7745/// @param the name of the scope decl.
7746///
7747/// @param locus the source location where the scope_decl is defined.
7748///
7749/// @param vis the visibility of the declaration.
7750scope_decl::scope_decl(const environment& env,
7751 const string& name,
7752 const location& locus,
7753 visibility vis)
7754 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7755 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7756 priv_(new priv)
7757{}
7758
7759/// Constructor of the @ref scope_decl type.
7760///
7761/// @param the environment to use for the new instance.
7762///
7763/// @param l the source location where the scope_decl is defined.
7764///
7765/// @param vis the visibility of the declaration.
7766scope_decl::scope_decl(const environment& env, location& l)
7767 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7768 decl_base(env, "", l),
7769 priv_(new priv)
7770{}
7771
7772/// @eturn the set of canonical types of the the current scope.
7775{return priv_->canonical_types_;}
7776
7777/// @eturn the set of canonical types of the the current scope.
7780{return const_cast<scope_decl*>(this)->get_canonical_types();}
7781
7782/// Return a vector of sorted canonical types of the current scope.
7783///
7784/// The types are sorted "almost topologically". That means, they are
7785/// sorted using the lexicographic order of the string representing
7786/// the location their definition point. If a type doesn't have a
7787/// location, then its pretty representation is used.
7788///
7789/// @return a vector of sorted canonical types of the current scope.
7792{
7793 if (priv_->sorted_canonical_types_.empty())
7794 {
7795 for (canonical_type_sptr_set_type::const_iterator e =
7796 get_canonical_types().begin();
7797 e != get_canonical_types().end();
7798 ++e)
7799 priv_->sorted_canonical_types_.push_back(*e);
7800
7801 type_topo_comp comp;
7802 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7803 priv_->sorted_canonical_types_.end(),
7804 comp);
7805 }
7806 return priv_->sorted_canonical_types_;
7807}
7808
7809/// Getter for the member declarations carried by the current @ref
7810/// scope_decl.
7811///
7812/// @return the member declarations carried by the current @ref
7813/// scope_decl.
7816{return priv_->members_;}
7817
7818/// Getter for the member declarations carried by the current @ref
7819/// scope_decl.
7820///
7821/// @return the member declarations carried by the current @ref
7822/// scope_decl.
7825{return priv_->members_;}
7826
7827/// Getter for the sorted member declarations carried by the current
7828/// @ref scope_decl.
7829///
7830/// @return the sorted member declarations carried by the current @ref
7831/// scope_decl. The declarations are sorted topologically.
7834{
7835 decl_topo_comp comp;
7836 if (priv_->sorted_members_.empty())
7837 {
7838 for (declarations::const_iterator i = get_member_decls().begin();
7839 i != get_member_decls().end();
7840 ++i)
7841 priv_->sorted_members_.push_back(*i);
7842
7843 std::stable_sort(priv_->sorted_members_.begin(),
7844 priv_->sorted_members_.end(),
7845 comp);
7846 }
7847 return priv_->sorted_members_;
7848}
7849
7850/// Getter for the number of anonymous classes contained in this
7851/// scope.
7852///
7853/// @return the number of anonymous classes contained in this scope.
7854size_t
7856{
7857 int result = 0;
7858 for (declarations::const_iterator it = get_member_decls().begin();
7859 it != get_member_decls().end();
7860 ++it)
7861 if (class_decl_sptr t = is_class_type(*it))
7862 if (t->get_is_anonymous())
7863 ++result;
7864
7865 return result;
7866}
7867
7868/// Getter for the number of anonymous unions contained in this
7869/// scope.
7870///
7871/// @return the number of anonymous unions contained in this scope.
7872size_t
7874{
7875 int result = 0;
7876 for (declarations::const_iterator it = get_member_decls().begin();
7877 it != get_member_decls().end();
7878 ++it)
7879 if (union_decl_sptr t = is_union_type(*it))
7880 if (t->get_is_anonymous())
7881 ++result;
7882
7883 return result;
7884}
7885
7886/// Getter for the number of anonymous enums contained in this
7887/// scope.
7888///
7889/// @return the number of anonymous enums contained in this scope.
7890size_t
7892{
7893 int result = 0;
7894 for (declarations::const_iterator it = get_member_decls().begin();
7895 it != get_member_decls().end();
7896 ++it)
7897 if (enum_type_decl_sptr t = is_enum_type(*it))
7898 if (t->get_is_anonymous())
7899 ++result;
7900
7901 return result;
7902}
7903
7904/// Getter for the scopes carried by the current scope.
7905///
7906/// @return the scopes carried by the current scope.
7909{return priv_->member_scopes_;}
7910
7911/// Getter for the scopes carried by the current scope.
7912///
7913/// @return the scopes carried by the current scope.
7914const scope_decl::scopes&
7916{return priv_->member_scopes_;}
7917
7918/// Test if the current scope is empty.
7919///
7920/// @return true iff the current scope is empty.
7921bool
7923{
7924 return (get_member_decls().empty()
7925 && get_canonical_types().empty());
7926}
7927
7928/// Add a member decl to this scope. Note that user code should not
7929/// use this, but rather use add_decl_to_scope.
7930///
7931/// Note that this function updates the qualified name of the member
7932/// decl that is added. It also sets the scope of the member. Thus,
7933/// it ABG_ASSERTs that member should not have its scope set, prior to
7934/// calling this function.
7935///
7936/// @param member the new member decl to add to this scope.
7937decl_base_sptr
7938scope_decl::add_member_decl(const decl_base_sptr& member)
7939{
7940 ABG_ASSERT(!has_scope(member));
7941
7942 member->set_scope(this);
7943 priv_->members_.push_back(member);
7944 if (is_type(member))
7945 priv_->member_types_.push_back(is_type(member));
7946
7947 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
7948 priv_->member_scopes_.push_back(m);
7949
7950 update_qualified_name(member);
7951
7953 {
7954 if (translation_unit* existing_tu = member->get_translation_unit())
7955 ABG_ASSERT(tu == existing_tu);
7956 else
7957 member->set_translation_unit(tu);
7958 }
7959
7961
7962 return member;
7963}
7964
7965/// Get the member types of this @ref scope_decl.
7966///
7967/// @return a vector of the member types of this ref class_or_union.
7970{return priv_->member_types_;}
7971
7972/// Find a member type of a given name, inside the current @ref
7973/// scope_decl.
7974///
7975/// @param name the name of the member type to look for.
7976///
7977/// @return a pointer to the @ref type_base that represents the member
7978/// type of name @p name, for the current scope.
7979type_base_sptr
7980scope_decl::find_member_type(const string& name) const
7981{
7982 for (auto t : get_member_types())
7983 if (get_type_name(t, /*qualified*/false) == name)
7984 return t;
7985 return type_base_sptr();
7986}
7987
7988/// Insert a member type.
7989///
7990/// @param t the type to insert in the @ref scope_decl type.
7991///
7992/// @param an iterator right before which @p t has to be inserted.
7993void
7995 declarations::iterator before)
7996{
7997 decl_base_sptr d = get_type_declaration(t);
7998 ABG_ASSERT(d);
7999 ABG_ASSERT(!has_scope(d));
8000
8001 priv_->member_types_.push_back(t);
8002 insert_member_decl(d, before);
8003}
8004
8005/// Add a member type to the current instance of class_or_union.
8006///
8007/// @param t the member type to add. It must not have been added to a
8008/// scope, otherwise this will violate an ABG_ASSERTion.
8009void
8012
8013/// Add a member type to the current instance of class_or_union.
8014///
8015/// @param t the type to be added as a member type to the current
8016/// instance of class_or_union. An instance of class_or_union::member_type
8017/// will be created out of @p t and and added to the the class.
8018///
8019/// @param a the access specifier for the member type to be created.
8020type_base_sptr
8022{
8023 decl_base_sptr d = get_type_declaration(t);
8024 ABG_ASSERT(d);
8026 add_member_type(t);
8028 return t;
8029}
8030
8031/// Remove a member type from the current @ref class_or_union scope.
8032///
8033/// @param t the type to remove.
8034void
8036{
8037 for (auto i = priv_->member_types_.begin();
8038 i != priv_->member_types_.end();
8039 ++i)
8040 {
8041 if (*((*i)) == *t)
8042 {
8043 priv_->member_types_.erase(i);
8044 return;
8045 }
8046 }
8047}
8048
8049/// Get the sorted member types of this @ref scope_decl
8050///
8051/// @return a vector of the sorted member types of this ref
8052/// class_or_union.
8055{
8056 if (priv_->sorted_member_types_.empty())
8057 {
8058 for (auto t : get_member_types())
8059 priv_->sorted_member_types_.push_back(t);
8060
8061 type_topo_comp comp;
8062 std::stable_sort(priv_->sorted_member_types_.begin(),
8063 priv_->sorted_member_types_.end(),
8064 comp);
8065 }
8066 return priv_->sorted_member_types_;
8067}
8068
8069/// Insert a member decl to this scope, right before an element
8070/// pointed to by a given iterator. Note that user code should not
8071/// use this, but rather use insert_decl_into_scope.
8072///
8073/// Note that this function updates the qualified name of the inserted
8074/// member.
8075///
8076/// @param member the new member decl to add to this scope.
8077///
8078/// @param before an interator pointing to the element before which
8079/// the new member should be inserted.
8080decl_base_sptr
8082 declarations::iterator before)
8083{
8084 ABG_ASSERT(!member->get_scope());
8085
8086 member->set_scope(this);
8087 priv_->members_.insert(before, member);
8088
8089 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8090 priv_-> member_scopes_.push_back(m);
8091
8092 update_qualified_name(member);
8093
8095 {
8096 if (translation_unit* existing_tu = member->get_translation_unit())
8097 ABG_ASSERT(tu == existing_tu);
8098 else
8099 member->set_translation_unit(tu);
8100 }
8101
8103
8104 return member;
8105}
8106
8107/// Remove a declaration from the current scope.
8108///
8109/// @param member the declaration to remove from the scope.
8110void
8112{
8113 for (declarations::iterator i = priv_->members_.begin();
8114 i != priv_->members_.end();
8115 ++i)
8116 {
8117 if (**i == *member)
8118 {
8119 priv_->members_.erase(i);
8120 // Do not access i after this point as it's invalided by the
8121 // erase call.
8122 break;
8123 }
8124 }
8125
8126 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8127 if (scope)
8128 {
8129 for (scopes::iterator i = priv_->member_scopes_.begin();
8130 i != priv_->member_scopes_.end();
8131 ++i)
8132 {
8133 if (**i == *member)
8134 {
8135 priv_->member_scopes_.erase(i);
8136 break;
8137 }
8138 }
8139 }
8140}
8141
8142/// Return the hash value for the current instance of scope_decl.
8143///
8144/// This method can trigger the computing of the hash value, if need be.
8145///
8146/// @return the hash value.
8147size_t
8149{
8150 scope_decl::hash hash_scope;
8151 return hash_scope(this);
8152}
8153
8154/// Compares two instances of @ref scope_decl.
8155///
8156/// If the two intances are different, set a bitfield to give some
8157/// insight about the kind of differences there are.
8158///
8159/// @param l the first artifact of the comparison.
8160///
8161/// @param r the second artifact of the comparison.
8162///
8163/// @param k a pointer to a bitfield that gives information about the
8164/// kind of changes there are between @p l and @p r. This one is set
8165/// iff @p k is non-null and the function returns false.
8166///
8167/// Please note that setting k to a non-null value does have a
8168/// negative performance impact because even if @p l and @p r are not
8169/// equal, the function keeps up the comparison in order to determine
8170/// the different kinds of ways in which they are different.
8171///
8172/// @return true if @p l equals @p r, false otherwise.
8173bool
8175{
8176 bool result = true;
8177
8178 if (!l.decl_base::operator==(r))
8179 {
8180 result = false;
8181 if (k)
8183 else
8185 }
8186
8187 scope_decl::declarations::const_iterator i, j;
8188 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8189 i != l.get_member_decls().end() && j != r.get_member_decls().end();
8190 ++i, ++j)
8191 {
8192 if (**i != **j)
8193 {
8194 result = false;
8195 if (k)
8196 {
8197 *k |= SUBTYPE_CHANGE_KIND;
8198 break;
8199 }
8200 else
8202 }
8203 }
8204
8205 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8206 {
8207 result = false;
8208 if (k)
8210 else
8212 }
8213
8214 ABG_RETURN(result);
8215}
8216
8217/// Return true iff both scopes have the same names and have the same
8218/// member decls.
8219///
8220/// This function doesn't check for equality of the scopes of its
8221/// arguments.
8222bool
8224{
8225 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8226 if (!other)
8227 return false;
8228
8229 return equals(*this, *other, 0);
8230}
8231
8232/// Equality operator for @ref scope_decl_sptr.
8233///
8234/// @param l the left hand side operand of the equality operator.
8235///
8236/// @pram r the right hand side operand of the equalify operator.
8237///
8238/// @return true iff @p l equals @p r.
8239bool
8241{
8242 if (!!l != !!r)
8243 return false;
8244 if (l.get() == r.get())
8245 return true;
8246 return *l == *r;
8247}
8248
8249/// Inequality operator for @ref scope_decl_sptr.
8250///
8251/// @param l the left hand side operand of the equality operator.
8252///
8253/// @pram r the right hand side operand of the equalify operator.
8254///
8255/// @return true iff @p l equals @p r.
8256bool
8258{return !operator==(l, r);}
8259
8260/// Find a member of the current scope and return an iterator on it.
8261///
8262/// @param decl the scope member to find.
8263///
8264/// @param i the iterator to set to the member @p decl. This is set
8265/// iff the function returns true.
8266///
8267/// @return true if the member decl was found, false otherwise.
8268bool
8270 declarations::iterator& i)
8271{
8272 if (!decl)
8273 return false;
8274
8275 if (get_member_decls().empty())
8276 {
8277 i = get_member_decls().end();
8278 return false;
8279 }
8280
8281 for (declarations::iterator it = get_member_decls().begin();
8282 it != get_member_decls().end();
8283 ++it)
8284 {
8285 if ((*it).get() == decl)
8286 {
8287 i = it;
8288 return true;
8289 }
8290 }
8291
8292 return false;
8293}
8294
8295/// Find a member of the current scope and return an iterator on it.
8296///
8297/// @param decl the scope member to find.
8298///
8299/// @param i the iterator to set to the member @p decl. This is set
8300/// iff the function returns true.
8301///
8302/// @return true if the member decl was found, false otherwise.
8303bool
8305 declarations::iterator& i)
8306{return find_iterator_for_member(decl.get(), i);}
8307
8308/// This implements the ir_traversable_base::traverse pure virtual
8309/// function.
8310///
8311/// @param v the visitor used on the current instance of scope_decl
8312/// and on its member nodes.
8313///
8314/// @return true if the traversal of the tree should continue, false
8315/// otherwise.
8316bool
8318{
8319 if (visiting())
8320 return true;
8321
8322 if (v.visit_begin(this))
8323 {
8324 visiting(true);
8325 for (scope_decl::declarations::const_iterator i =
8326 get_member_decls().begin();
8327 i != get_member_decls ().end();
8328 ++i)
8329 if (!(*i)->traverse(v))
8330 break;
8331 visiting(false);
8332 }
8333 return v.visit_end(this);
8334}
8335
8336scope_decl::~scope_decl()
8337{}
8338
8339/// Appends a declaration to a given scope, if the declaration
8340/// doesn't already belong to one and if the declaration is not for a
8341/// type that is supposed to be unique.
8342///
8343/// @param decl the declaration to add to the scope
8344///
8345/// @param scope the scope to append the declaration to
8346decl_base_sptr
8347add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8348{
8349 ABG_ASSERT(scope);
8350
8351 if (scope && decl && !decl->get_scope())
8352 decl = scope->add_member_decl(decl);
8353
8354 return decl;
8355}
8356
8357/// Appends a declaration to a given scope, if the declaration doesn't
8358/// already belong to a scope.
8359///
8360/// @param decl the declaration to add append to the scope
8361///
8362/// @param scope the scope to append the decl to
8363decl_base_sptr
8364add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8365{return add_decl_to_scope(decl, scope.get());}
8366
8367/// Remove a given decl from its scope
8368///
8369/// @param decl the decl to remove from its scope.
8370void
8371remove_decl_from_scope(decl_base_sptr decl)
8372{
8373 if (!decl)
8374 return;
8375
8376 scope_decl* scope = decl->get_scope();
8377 scope->remove_member_decl(decl);
8378 decl->set_scope(0);
8379}
8380
8381/// Inserts a declaration into a given scope, before a given IR child
8382/// node of the scope.
8383///
8384/// @param decl the declaration to insert into the scope.
8385///
8386/// @param before an iterator pointing to the child IR node before
8387/// which to insert the declaration.
8388///
8389/// @param scope the scope into which to insert the declaration.
8390decl_base_sptr
8391insert_decl_into_scope(decl_base_sptr decl,
8392 scope_decl::declarations::iterator before,
8393 scope_decl* scope)
8394{
8395 if (scope && decl && !decl->get_scope())
8396 {
8397 decl_base_sptr d = scope->insert_member_decl(decl, before);
8398 decl = d;
8399 }
8400 return decl;
8401}
8402
8403/// Inserts a declaration into a given scope, before a given IR child
8404/// node of the scope.
8405///
8406/// @param decl the declaration to insert into the scope.
8407///
8408/// @param before an iterator pointing to the child IR node before
8409/// which to insert the declaration.
8410///
8411/// @param scope the scope into which to insert the declaration.
8412decl_base_sptr
8413insert_decl_into_scope(decl_base_sptr decl,
8414 scope_decl::declarations::iterator before,
8415 scope_decl_sptr scope)
8416{return insert_decl_into_scope(decl, before, scope.get());}
8417
8418/// Constructor of the @ref global_scope type.
8419///
8420/// @param tu the translation unit the scope belongs to.
8421global_scope::global_scope(translation_unit *tu)
8422 : type_or_decl_base(tu->get_environment(),
8423 GLOBAL_SCOPE_DECL
8424 | ABSTRACT_DECL_BASE
8425 | ABSTRACT_SCOPE_DECL),
8426 decl_base(tu->get_environment(), "", location()),
8427 scope_decl(tu->get_environment(), "", location()),
8428 translation_unit_(tu)
8429{
8430 runtime_type_instance(this);
8431}
8432
8433/// return the global scope as seen by a given declaration.
8434///
8435/// @param decl the declaration to consider.
8436///
8437/// @return the global scope of the decl, or a null pointer if the
8438/// decl is not yet added to a translation_unit.
8439const global_scope*
8441{
8442 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8443 return s;
8444
8445 scope_decl* scope = decl.get_scope();
8446 while (scope && !dynamic_cast<global_scope*>(scope))
8447 scope = scope->get_scope();
8448
8449 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8450}
8451
8452/// return the global scope as seen by a given declaration.
8453///
8454/// @param decl the declaration to consider.
8455///
8456/// @return the global scope of the decl, or a null pointer if the
8457/// decl is not yet added to a translation_unit.
8458const global_scope*
8460{return get_global_scope(*decl);}
8461
8462/// Return the global scope as seen by a given declaration.
8463///
8464/// @param decl the declaration to consider.
8465///
8466/// @return the global scope of the decl, or a null pointer if the
8467/// decl is not yet added to a translation_unit.
8468const global_scope*
8469get_global_scope(const shared_ptr<decl_base> decl)
8470{return get_global_scope(decl.get());}
8471
8472/// Return the a scope S containing a given declaration and that is
8473/// right under a given scope P.
8474///
8475/// Note that @p scope must come before @p decl in topological
8476/// order.
8477///
8478/// @param decl the decl for which to find a scope.
8479///
8480/// @param scope the scope under which the resulting scope must be.
8481///
8482/// @return the resulting scope.
8483const scope_decl*
8485 const scope_decl* scope)
8486{
8487 if (!decl)
8488 return 0;
8489
8490 if (scope == 0)
8491 return get_global_scope(decl);
8492
8493 // Handle the case where decl is a scope itself.
8494 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8495 if (!s)
8496 s = decl->get_scope();
8497
8498 if (is_global_scope(s))
8499 return scope;
8500
8501 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8502 // same. The caller needs to be prepared to deal with this case.
8503 if (s == scope)
8504 return s;
8505
8506 while (s && !is_global_scope(s) && s->get_scope() != scope)
8507 s = s->get_scope();
8508
8509 if (!s || is_global_scope(s))
8510 // SCOPE must come before decl in topological order, but I don't
8511 // know how to ensure that ...
8512 return scope;
8513 ABG_ASSERT(s);
8514
8515 return s;
8516}
8517
8518/// Return the a scope S containing a given declaration and that is
8519/// right under a given scope P.
8520///
8521/// @param decl the decl for which to find a scope.
8522///
8523/// @param scope the scope under which the resulting scope must be.
8524///
8525/// @return the resulting scope.
8526const scope_decl*
8527get_top_most_scope_under(const decl_base_sptr decl,
8528 const scope_decl* scope)
8529{return get_top_most_scope_under(decl.get(), scope);}
8530
8531/// Return the a scope S containing a given declaration and that is
8532/// right under a given scope P.
8533///
8534/// @param decl the decl for which to find a scope.
8535///
8536/// @param scope the scope under which the resulting scope must be.
8537///
8538/// @return the resulting scope.
8539const scope_decl*
8540get_top_most_scope_under(const decl_base_sptr decl,
8541 const scope_decl_sptr scope)
8542{return get_top_most_scope_under(decl, scope.get());}
8543
8544// </scope_decl stuff>
8545
8546
8547/// Get the string representation of a CV qualifier bitmap.
8548///
8549/// @param cv_quals the bitmap of CV qualifiers to consider.
8550///
8551/// @return the string representation.
8552string
8554{
8555 string repr;
8556 if (cv_quals & qualified_type_def::CV_RESTRICT)
8557 repr = "restrict";
8558 if (cv_quals & qualified_type_def::CV_CONST)
8559 {
8560 if (!repr.empty())
8561 repr += ' ';
8562 repr += "const";
8563 }
8564 if (cv_quals & qualified_type_def::CV_VOLATILE)
8565 {
8566 if (!repr.empty())
8567 repr += ' ';
8568 repr += "volatile";
8569 }
8570 return repr;
8571}
8572
8573/// Build and return a copy of the name of an ABI artifact that is
8574/// either a type or a decl.
8575///
8576/// @param tod the ABI artifact to get the name for.
8577///
8578/// @param qualified if yes, return the qualified name of @p tod;
8579/// otherwise, return the non-qualified name;
8580///
8581/// @return the name of @p tod.
8582string
8583get_name(const type_or_decl_base *tod, bool qualified)
8584{
8585 string result;
8586
8587 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8588
8589 if (type_base* t = dynamic_cast<type_base*>(a))
8590 result = get_type_name(t, qualified);
8591 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8592 {
8593 if (qualified)
8594 result = d->get_qualified_name();
8595 else
8596 result = d->get_name();
8597 }
8598 else
8599 // We should never reach this point.
8600 abort();
8601
8602 return result;
8603}
8604
8605/// Build and return a copy of the name of an ABI artifact that is
8606/// either a type of a decl.
8607///
8608/// @param tod the ABI artifact to get the name for.
8609///
8610/// @param qualified if yes, return the qualified name of @p tod;
8611/// otherwise, return the non-qualified name;
8612///
8613/// @return the name of @p tod.
8614string
8615get_name(const type_or_decl_base_sptr& tod, bool qualified)
8616{return get_name(tod.get(), qualified);}
8617
8618/// Build and return a qualified name from a name and its scope.
8619///
8620/// The name is supposed to be for an entity that is part of the
8621/// scope.
8622///
8623/// @param the scope to consider.
8624///
8625/// @param name of the name to consider.
8626///
8627/// @return a copy of the string that represents the qualified name.
8628string
8629build_qualified_name(const scope_decl* scope, const string& name)
8630{
8631 if (name.empty())
8632 return "";
8633
8634 string qualified_name;
8635 if (scope)
8636 qualified_name = scope->get_qualified_name();
8637
8638 if (qualified_name.empty())
8639 qualified_name = name;
8640 else
8641 qualified_name = qualified_name + "::" + name;
8642
8643 return qualified_name;
8644}
8645
8646/// Build and return the qualified name of a type in its scope.
8647///
8648/// @param scope the scope of the type to consider.
8649///
8650/// @param type the type to consider.
8651string
8652build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8653{return build_qualified_name(scope, get_name((type)));}
8654
8655// </scope_decl stuff>
8656
8657/// Get the location of the declaration of a given type.
8658///
8659/// @param type the type to consider.
8660///
8661/// @return the location of the declaration of type @p type.
8663get_location(const type_base_sptr& type)
8664{
8665 if (decl_base_sptr decl = get_type_declaration(type))
8666 return get_location(decl);
8667 return location();
8668}
8669
8670/// Get the location of a given declaration.
8671///
8672/// @param decl the declaration to consider.
8673///
8674/// @return the location of the declaration @p decl.
8676get_location(const decl_base_sptr& decl)
8677{
8678 location loc = decl->get_location();
8679 if (!loc)
8680 {
8681 if (class_or_union_sptr c = is_class_or_union_type(decl))
8682 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8683 {
8684 c = is_class_or_union_type(c->get_definition_of_declaration());
8685 loc = c->get_location();
8686 }
8687 }
8688 return loc;
8689}
8690
8691/// Get the scope of a given type.
8692///
8693/// @param t the type to consider.
8694///
8695/// @return the scope of type @p t or 0 if the type has no scope yet.
8698{
8699 if (!t)
8700 return 0;
8701
8703 if (d)
8704 return d->get_scope();
8705 return 0;
8706}
8707
8708/// Get the scope of a given type.
8709///
8710/// @param t the type to consider.
8711///
8712/// @return the scope of type @p t or 0 if the type has no scope yet.
8714get_type_scope(const type_base_sptr& t)
8715{return get_type_scope(t.get());}
8716
8717/// Get the name of a given type and return a copy of it.
8718///
8719/// @param t the type to consider.
8720///
8721/// @param qualified if true then return the qualified name of the
8722/// type.
8723///
8724/// @param internal set to true if the call is intended for an
8725/// internal use (for technical use inside the library itself), false
8726/// otherwise. If you don't know what this is for, then set it to
8727/// false.
8728///
8729/// @return a copy of the type name if the type has a name, or the
8730/// empty string if it does not.
8732get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8733{return get_type_name(t.get(), qualified, internal);}
8734
8735/// Return true iff a decl is for a type type that has a generic
8736/// anonymous internal type name.
8737///
8738/// @param d the decl to considier.
8739///
8740/// @return true iff @p d is for a type type that has a generic
8741/// anonymous internal type name.
8742static bool
8743has_generic_anonymous_internal_type_name(const decl_base *d)
8744{
8745 return (is_class_or_union_type(d)
8746 || is_enum_type(d)
8747 || is_subrange_type(d));
8748}
8749
8750/// Return the generic internal name of an anonymous type.
8751///
8752/// For internal purposes, we want to define a generic name for all
8753/// anonymous types of a certain kind. For instance, all anonymous
8754/// structs will be have a generic name of "__anonymous_struct__", all
8755/// anonymous unions will have a generic name of
8756/// "__anonymous_union__", etc.
8757///
8758/// That generic name can be used as a hash to put all anonymous types
8759/// of a certain kind in the same hash table bucket, for instance.
8760static interned_string
8761get_generic_anonymous_internal_type_name(const decl_base *d)
8762{
8763 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8764
8765 const environment&env = d->get_environment();
8766
8767 interned_string result;
8768 if (is_class_type(d))
8769 result =
8771 else if (is_union_type(d))
8772 result =
8774 else if (is_enum_type(d))
8775 result =
8777 else if (is_subrange_type(d))
8778 result =
8780 else
8782
8783 return result;
8784}
8785
8786/// Get the internal name for a given integral type.
8787///
8788/// All integral types that have the modifiers 'short, long or long
8789/// long' have the same internal name. This is so that they can all
8790/// have the same canonical type if they are of the same size.
8791/// Otherwise, 'long int' and 'long long int' would have different
8792/// canonical types even though they are equivalent from an ABI point
8793/// of view.
8794///
8795/// @param t the integral type to consider
8796///
8797/// @return the internal name for @p t if it's an integral type, or
8798/// the empty string if @p t is not an integral type.
8799static string
8800get_internal_integral_type_name(const type_base* t)
8801{
8802 string name;
8803 type_decl *type = is_integral_type(t);
8804
8805 if (!type)
8806 return name;
8807
8808 integral_type int_type;
8809 if (parse_integral_type(type->get_name(), int_type))
8810 name = int_type.to_string(/*internal=*/true);
8811
8812 return name;
8813}
8814
8815/// Get the name of a given type and return a copy of it.
8816///
8817/// @param t the type to consider.
8818///
8819/// @param qualified if true then return the qualified name of the
8820/// type.
8821///
8822/// @param internal set to true if the call is intended for an
8823/// internal use (for technical use inside the library itself), false
8824/// otherwise. If you don't know what this is for, then set it to
8825/// false.
8826///
8827/// @return a copy of the type name if the type has a name, or the
8828/// empty string if it does not.
8829interned_string
8830get_type_name(const type_base* t, bool qualified, bool internal)
8831{
8832 const decl_base* d = dynamic_cast<const decl_base*>(t);
8833 if (!d)
8834 {
8835 const function_type* fn_type = is_function_type(t);
8836 ABG_ASSERT(fn_type);
8837 return fn_type->get_cached_name(internal);
8838 }
8839
8840 // All anonymous types of a given kind get to have the same internal
8841 // name for internal purpose. This to allow them to be compared
8842 // among themselves during type canonicalization.
8843 if (internal)
8844 {
8845 if (d->get_is_anonymous())
8846 {
8847 string r;
8848 r += get_generic_anonymous_internal_type_name(d);
8849 return t->get_environment().intern(r);
8850 }
8851
8852 if (qualified)
8853 return d->get_qualified_name(internal);
8854
8855 const environment&env = d->get_environment();
8856 return env.intern(get_internal_integral_type_name(t));
8857 }
8858
8859 if (qualified)
8860 return d->get_qualified_name(internal);
8861 return d->get_name();
8862}
8863
8864/// Get the name of a given type and return a copy of it.
8865///
8866/// @param t the type to consider.
8867///
8868/// @param qualified if true then return the qualified name of the
8869/// type.
8870///
8871/// @param internal set to true if the call is intended for an
8872/// internal use (for technical use inside the library itself), false
8873/// otherwise. If you don't know what this is for, then set it to
8874/// false.
8875///
8876/// @return a copy of the type name if the type has a name, or the
8877/// empty string if it does not.
8879get_type_name(const type_base& t, bool qualified, bool internal)
8880{return get_type_name(&t, qualified, internal);}
8881
8882/// Get the name of the pointer to a given type.
8883///
8884/// @param pointed_to_type the pointed-to-type to consider.
8885///
8886/// @param qualified this is true if the resulting name should be of a
8887/// pointer to a *fully-qualified* pointed-to-type.
8888///
8889/// @param internal true if the name is for libabigail-internal
8890/// purposes.
8891///
8892/// @return the name (string representation) of the pointer.
8895 bool qualified, bool internal)
8896{
8897 const environment& env = pointed_to_type.get_environment();
8898 string tn = get_type_name(pointed_to_type, qualified, internal);
8899 tn = tn + "*";
8900
8901 return env.intern(tn);
8902}
8903
8904/// Get the name of the reference to a given type.
8905///
8906/// @param pointed_to_type the pointed-to-type to consider.
8907///
8908/// @param qualified this is true if the resulting name should be of a
8909/// reference to a *fully-qualified* pointed-to-type.
8910///
8911/// @param internal true if the name is for libabigail-internal
8912/// purposes.
8913///
8914/// @return the name (string representation) of the reference.
8917 bool lvalue_reference,
8918 bool qualified, bool internal)
8919{
8920 const environment& env = pointed_to_type.get_environment();
8921
8922 string name = get_type_name(pointed_to_type, qualified, internal);
8923 if (lvalue_reference)
8924 name = name + "&";
8925 else
8926 name = name + "&&";
8927
8928 return env.intern(name);
8929}
8930
8931/// Get the name of a qualified type, given the underlying type and
8932/// its qualifiers.
8933///
8934/// @param underlying_type the underlying type to consider.
8935///
8936/// @param quals the CV qualifiers of the name.
8937///
8938/// @param qualified true if we should consider the fully qualified
8939/// name of @p underlying_type.
8940///
8941/// @param internal true if the result is to be used for
8942/// libabigail-internal purposes.
8943///
8944/// @return the name (string representation) of the qualified type.
8946get_name_of_qualified_type(const type_base_sptr& underlying_type,
8948 bool qualified, bool internal)
8949{
8950 const environment& env = underlying_type->get_environment();
8951
8952 string quals_repr = get_string_representation_of_cv_quals(quals);
8953 string name = get_type_name(underlying_type, qualified, internal);
8954
8955 if (quals_repr.empty() && internal)
8956 // We are asked to return the internal name, that might be used
8957 // for type canonicalization. For that canonicalization, we need
8958 // to make a difference between a no-op qualified type which
8959 // underlying type is foo (the qualified type is named "none
8960 // foo"), and the name of foo, which is just "foo".
8961 //
8962 // Please remember that this has to be kept in sync with what is
8963 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
8964 // change this code here, please change that code there too.
8965 quals_repr = "";
8966
8967 if (!quals_repr.empty())
8968 {
8969 if (is_pointer_type(peel_qualified_type(underlying_type))
8970 || is_reference_type(peel_qualified_type(underlying_type)))
8971 {
8972 name += " ";
8973 name += quals_repr;
8974 }
8975 else
8976 name = quals_repr + " " + name;
8977 }
8978
8979 return env.intern(name);
8980}
8981
8982/// Get the name of a given function type and return a copy of it.
8983///
8984/// @param fn_type the function type to consider.
8985///
8986/// @param internal set to true if the call is intended for an
8987/// internal use (for technical use inside the library itself), false
8988/// otherwise. If you don't know what this is for, then set it to
8989/// false.
8990///
8991/// @return a copy of the function type name
8994 bool internal)
8995{return get_function_type_name(fn_type.get(), internal);}
8996
8997/// Get the name of a given function type and return a copy of it.
8998///
8999/// @param fn_type the function type to consider.
9000///
9001/// @param internal set to true if the call is intended for an
9002/// internal use (for technical use inside the library itself), false
9003/// otherwise. If you don't know what this is for, then set it to
9004/// false.
9005///
9006/// @return a copy of the function type name
9009 bool internal)
9010{
9011 ABG_ASSERT(fn_type);
9012
9013 if (const method_type* method = is_method_type(fn_type))
9014 return get_method_type_name(method, internal);
9015
9016 return get_function_type_name(*fn_type, internal);
9017}
9018
9019/// Get the name of a given function type and return a copy of it.
9020///
9021/// @param fn_type the function type to consider.
9022///
9023/// @param internal set to true if the call is intended for an
9024/// internal use (for technical use inside the library itself), false
9025/// otherwise. If you don't know what this is for, then set it to
9026/// false.
9027///
9028/// @return a copy of the function type name
9031 bool internal)
9032{
9033 std::ostringstream o;
9034 // When the function name is used for internal purposes (e.g, for
9035 // canonicalization), we want its representation to stay the same,
9036 // regardless of typedefs. So let's strip typedefs from the return
9037 // type.
9038 type_base_sptr return_type =
9039 internal
9041 : fn_type.get_return_type();
9042 const environment& env = fn_type.get_environment();
9043
9044 o << get_pretty_representation(return_type, internal);
9045
9046 o << " (";
9047 type_base_sptr type;
9048 for (function_type::parameters::const_iterator i =
9049 fn_type.get_parameters().begin();
9050 i != fn_type.get_parameters().end();
9051 ++i)
9052 {
9053 if (i != fn_type.get_parameters().begin())
9054 o << ", ";
9055 type = (*i)->get_type();
9056 if (internal)
9057 type = peel_typedef_type(type);
9058 o << get_pretty_representation(type, internal);
9059 }
9060 o <<")";
9061
9062 return env.intern(o.str());
9063}
9064
9065/// Get the ID of a function, or, if the ID can designate several
9066/// different functions, get its pretty representation.
9067///
9068/// @param fn the function to consider
9069///
9070/// @return the function ID of pretty representation of @p fn.
9073{
9074 ABG_ASSERT(fn);
9075
9076 interned_string result = fn->get_environment().intern(fn->get_id());
9077
9078 if (corpus *c = fn->get_corpus())
9079 {
9081 c->get_exported_decls_builder();
9082 if (b->fn_id_maps_to_several_fns(fn))
9083 result = fn->get_environment().intern(fn->get_pretty_representation());
9084 }
9085
9086 return result;
9087}
9088
9089/// Get the name of a given method type and return a copy of it.
9090///
9091/// @param fn_type the function type to consider.
9092///
9093/// @param internal set to true if the call is intended for an
9094/// internal use (for technical use inside the library itself), false
9095/// otherwise. If you don't know what this is for, then set it to
9096/// false.
9097///
9098/// @return a copy of the function type name
9101 bool internal)
9102{return get_method_type_name(fn_type.get(), internal);}
9103
9104/// Get the name of a given method type and return a copy of it.
9105///
9106/// @param fn_type the function type to consider.
9107///
9108/// @param internal set to true if the call is intended for an
9109/// internal use (for technical use inside the library itself), false
9110/// otherwise. If you don't know what this is for, then set it to
9111/// false.
9112///
9113/// @return a copy of the function type name
9116 bool internal)
9117{
9118 if (fn_type)
9119 return get_method_type_name(*fn_type, internal);
9120
9121 return interned_string();
9122}
9123
9124/// Get the name of a given method type and return a copy of it.
9125///
9126/// @param fn_type the function type to consider.
9127///
9128/// @param internal set to true if the call is intended for an
9129/// internal use (for technical use inside the library itself), false
9130/// otherwise. If you don't know what this is for, then set it to
9131/// false.
9132///
9133/// @return a copy of the function type name
9136 bool internal)
9137{
9138 std::ostringstream o;
9139 // When the function name is used for internal purposes (e.g, for
9140 // canonicalization), we want its representation to stay the same,
9141 // regardless of typedefs. So let's strip typedefs from the return
9142 // type.
9143 type_base_sptr return_type =
9144 internal
9146 : fn_type.get_return_type();
9147 const environment& env = fn_type.get_environment();
9148
9149 if (return_type)
9150 o << return_type->get_cached_pretty_representation(internal);
9151 else
9152 // There are still some abixml files out there in which "void"
9153 // can be expressed as an empty type.
9154 o << "void";
9155
9156 class_or_union_sptr class_type = fn_type.get_class_type();
9157 ABG_ASSERT(class_type);
9158
9159 o << " (" << class_type->get_qualified_name(internal) << "::*)"
9160 << " (";
9161
9162 type_base_sptr type;
9163 for (function_type::parameters::const_iterator i =
9164 fn_type.get_parameters().begin();
9165 i != fn_type.get_parameters().end();
9166 ++i)
9167 {
9168 if (i != fn_type.get_parameters().begin())
9169 o << ", ";
9170 type = (*i)->get_type();
9171 if (internal)
9172 type = peel_typedef_type(type);
9173 if (*i)
9174 o << type->get_cached_pretty_representation(internal);
9175 else
9176 // There are still some abixml files out there in which "void"
9177 // can be expressed as an empty type.
9178 o << "void";
9179 }
9180 o <<")";
9181
9182 return env.intern(o.str());
9183}
9184
9185/// Build and return a copy of the pretty representation of an ABI
9186/// artifact that could be either a type of a decl.
9187///
9188/// param tod the ABI artifact to consider.
9189///
9190/// @param internal set to true if the call is intended for an
9191/// internal use (for technical use inside the library itself), false
9192/// otherwise. If you don't know what this is for, then set it to
9193/// false.
9194///
9195/// @return a copy of the pretty representation of an ABI artifact
9196/// that could be either a type of a decl.
9197string
9199{
9200 string result;
9201
9202 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9203 result = get_pretty_representation(t, internal);
9204 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9205 result = get_pretty_representation(d, internal);
9206 else
9207 // We should never reach this point
9208 abort();
9209
9210 return result;
9211}
9212
9213/// Build and return a copy of the pretty representation of an ABI
9214/// artifact that could be either a type of a decl.
9215///
9216/// param tod the ABI artifact to consider.
9217///
9218/// @param internal set to true if the call is intended for an
9219/// internal use (for technical use inside the library itself), false
9220/// otherwise. If you don't know what this is for, then set it to
9221/// false.
9222///
9223/// @return a copy of the pretty representation of an ABI artifact
9224/// that could be either a type of a decl.
9225string
9227{return get_pretty_representation(tod.get(), internal);}
9228
9229/// Get a copy of the pretty representation of a decl.
9230///
9231/// @param d the decl to consider.
9232///
9233/// @param internal set to true if the call is intended for an
9234/// internal use (for technical use inside the library itself), false
9235/// otherwise. If you don't know what this is for, then set it to
9236/// false.
9237///
9238/// @return the pretty representation of the decl.
9239string
9240get_pretty_representation(const decl_base* d, bool internal)
9241{
9242 if (!d)
9243 return "";
9244 return d->get_pretty_representation(internal);
9245}
9246
9247/// Get a copy of the pretty representation of a type.
9248///
9249/// @param d the type to consider.
9250///
9251/// @param internal set to true if the call is intended for an
9252/// internal use (for technical use inside the library itself), false
9253/// otherwise. If you don't know what this is for, then set it to
9254/// false.
9255///
9256/// @return the pretty representation of the type.
9257string
9258get_pretty_representation(const type_base* t, bool internal)
9259{
9260 if (!t)
9261 return "void";
9262 if (const function_type* fn_type = is_function_type(t))
9263 return get_pretty_representation(fn_type, internal);
9264
9265 const decl_base* d = get_type_declaration(t);
9266 ABG_ASSERT(d);
9267 return get_pretty_representation(d, internal);
9268}
9269
9270/// Get a copy of the pretty representation of a decl.
9271///
9272/// @param d the decl to consider.
9273///
9274/// @param internal set to true if the call is intended for an
9275/// internal use (for technical use inside the library itself), false
9276/// otherwise. If you don't know what this is for, then set it to
9277/// false.
9278///
9279/// @return the pretty representation of the decl.
9280string
9281get_pretty_representation(const decl_base_sptr& d, bool internal)
9282{return get_pretty_representation(d.get(), internal);}
9283
9284/// Get a copy of the pretty representation of a type.
9285///
9286/// @param d the type to consider.
9287///
9288/// @param internal set to true if the call is intended for an
9289/// internal use (for technical use inside the library itself), false
9290/// otherwise. If you don't know what this is for, then set it to
9291/// false.
9292///
9293/// @return the pretty representation of the type.
9294string
9295get_pretty_representation(const type_base_sptr& t, bool internal)
9296{return get_pretty_representation(t.get(), internal);}
9297
9298/// Get the pretty representation of a function type.
9299///
9300/// @param fn_type the function type to consider.
9301///
9302/// @param internal set to true if the call is intended for an
9303/// internal use (for technical use inside the library itself), false
9304/// otherwise. If you don't know what this is for, then set it to
9305/// false.
9306///
9307/// @return the string represenation of the function type.
9308string
9310 bool internal)
9311{return get_pretty_representation(fn_type.get(), internal);}
9312
9313/// Get the pretty representation of a function type.
9314///
9315/// @param fn_type the function type to consider.
9316///
9317/// @param internal set to true if the call is intended for an
9318/// internal use (for technical use inside the library itself), false
9319/// otherwise. If you don't know what this is for, then set it to
9320/// false.
9321///
9322/// @return the string represenation of the function type.
9323string
9324get_pretty_representation(const function_type* fn_type, bool internal)
9325{
9326 if (!fn_type)
9327 return "void";
9328
9329 if (const method_type* method = is_method_type(fn_type))
9330 return get_pretty_representation(method, internal);
9331
9332 return get_pretty_representation(*fn_type, internal);
9333}
9334
9335/// Get the pretty representation of a function type.
9336///
9337/// @param fn_type the function type to consider.
9338///
9339/// @param internal set to true if the call is intended for an
9340/// internal use (for technical use inside the library itself), false
9341/// otherwise. If you don't know what this is for, then set it to
9342/// false.
9343///
9344/// @return the string represenation of the function type.
9345string
9346get_pretty_representation(const function_type& fn_type, bool internal)
9347{
9348 std::ostringstream o;
9349 o << "function type " << get_function_type_name(fn_type, internal);
9350 return o.str();
9351}
9352
9353/// Get the pretty representation of a method type.
9354///
9355/// @param method the method type to consider.
9356///
9357/// @param internal set to true if the call is intended for an
9358/// internal use (for technical use inside the library itself), false
9359/// otherwise. If you don't know what this is for, then set it to
9360/// false.
9361///
9362/// @return the string represenation of the method type.
9363string
9364get_pretty_representation(const method_type& method, bool internal)
9365{
9366 std::ostringstream o;
9367 o << "method type " << get_method_type_name(method, internal);
9368 return o.str();
9369}
9370
9371/// Get the pretty representation of a method type.
9372///
9373/// @param method the method type to consider.
9374///
9375/// @param internal set to true if the call is intended for an
9376/// internal use (for technical use inside the library itself), false
9377/// otherwise. If you don't know what this is for, then set it to
9378/// false.
9379///
9380/// @return the string represenation of the method type.
9381string
9382get_pretty_representation(const method_type* method, bool internal)
9383{
9384 if (!method)
9385 return "void";
9386 return get_pretty_representation(*method, internal);
9387}
9388
9389/// Get the pretty representation of a method type.
9390///
9391/// @param method the method type to consider.
9392///
9393/// @param internal set to true if the call is intended for an
9394/// internal use (for technical use inside the library itself), false
9395/// otherwise. If you don't know what this is for, then set it to
9396/// false.
9397///
9398/// @return the string represenation of the method type.
9399string
9401{return get_pretty_representation(method.get(), internal);}
9402
9403/// Get the flat representation of an instance of @ref class_or_union
9404/// type.
9405///
9406/// The flat representation of a given @ref class_or_union type is the
9407/// actual definition of the type, for instance:
9408///
9409/// struct foo {int a; char b;}
9410///
9411///@param cou the instance of @ref class_or_union to consider.
9412///
9413///@param indent the identation spaces to use in the representation.
9414///
9415///@param one_line if true, then the flat representation stands on one
9416///line. Otherwise, it stands on multiple lines.
9417///
9418///@return the resulting flat representation.
9419string
9421 const string& indent,
9422 bool one_line,
9423 bool internal,
9424 bool qualified_names)
9425{
9426 string repr;
9427 string local_indent = " ";
9428
9429 if (class_decl* clazz = is_class_type(&cou))
9430 {
9431 repr = indent;
9432 if (!internal && clazz->is_struct())
9433 repr += "struct";
9434 else
9435 repr += "class";
9436 }
9437 else if (is_union_type(cou))
9438 repr = indent + "union";
9439 else
9440 return "";
9441
9442 repr += " ";
9443
9444 string name = cou.get_qualified_name();
9445
9446 if (!cou.get_is_anonymous())
9447 repr += name;
9448
9449 repr += "{";
9450
9451 if (!one_line)
9452 repr += "\n";
9453
9454 string real_indent;
9456 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9457 dm != dmems.end();
9458 ++dm)
9459 {
9460 if (dm != dmems.begin())
9461 {
9462 if (one_line)
9463 real_indent = " ";
9464 else
9465 real_indent = "\n" + indent + local_indent;
9466 }
9467
9469 repr +=
9472 real_indent, one_line, internal, qualified_names);
9473 else
9474 {
9475 if (one_line)
9476 {
9477 if (dm != dmems.begin())
9478 repr += real_indent;
9479 repr += (*dm)->get_pretty_representation(internal,
9480 qualified_names);
9481 }
9482 else
9483 repr +=
9484 real_indent+ (*dm)->get_pretty_representation(internal,
9485 qualified_names);
9486 }
9487 repr += ";";
9488 }
9489
9490 if (one_line)
9491 repr += "}";
9492 else
9493 repr += indent + "}";
9494
9495 return repr;
9496}
9497
9498/// Get the flat representation of an instance of @ref class_or_union
9499/// type.
9500///
9501/// The flat representation of a given @ref class_or_union type is the
9502/// actual definition of the type, for instance:
9503///
9504/// struct foo {int a; char b;}
9505///
9506///@param cou the instance of @ref class_or_union to consider.
9507///
9508///@param indent the identation spaces to use in the representation.
9509///
9510///@param one_line if true, then the flat representation stands on one
9511///line. Otherwise, it stands on multiple lines.
9512///
9513///@return the resulting flat representation.
9514string
9516 const string& indent,
9517 bool one_line,
9518 bool internal,
9519 bool qualified_names)
9520{
9521 if (cou)
9522 return get_class_or_union_flat_representation(*cou, indent, one_line,
9523 internal, qualified_names);
9524 return "";
9525}
9526
9527/// Get the flat representation of an instance of @ref class_or_union
9528/// type.
9529///
9530/// The flat representation of a given @ref class_or_union type is the
9531/// actual definition of the type, for instance:
9532///
9533/// struct foo {int a; char b;}
9534///
9535///@param cou the instance of @ref class_or_union to consider.
9536///
9537///@param indent the identation spaces to use in the representation.
9538///
9539///@param one_line if true, then the flat representation stands on one
9540///line. Otherwise, it stands on multiple lines.
9541///
9542///@return the resulting flat representation.
9543string
9544get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9545 const string& indent,
9546 bool one_line,
9547 bool internal,
9548 bool qualified_names)
9550 indent,
9551 one_line,
9552 internal,
9553 qualified_names);}
9554
9555/// Get the textual representation of a type for debugging purposes.
9556///
9557/// If the type is a class/union, this shows the data members, virtual
9558/// member functions, size, pointer value of its canonical type, etc.
9559/// Otherwise, this just shows the name of the artifact as returned by
9560/// type_or_decl_base:get_pretty_representation().
9561///
9562/// @param artifact the artifact to show a debugging representation of.
9563///
9564/// @return a debugging string representation of @p artifact.
9565string
9567{
9568 if (!artifact)
9569 return string("");
9570
9571 class_or_union * c = is_class_or_union_type(artifact);
9572 if (c)
9573 {
9574 class_decl *clazz = is_class_type(c);
9575 string name = c->get_qualified_name();
9576 std::ostringstream o;
9577 if (clazz)
9578 {
9579 if (clazz->is_struct())
9580 o << "struct ";
9581 else
9582 o << "class ";
9583 }
9584 else if (is_union_type(c))
9585 o << "union ";
9586 o << name;
9587
9588 if (clazz)
9589 {
9590 if (!clazz->get_base_specifiers().empty())
9591 o << " :" << std::endl;
9592 for (auto &b : clazz->get_base_specifiers())
9593 {
9594 o << " ";
9595 if (b->get_is_virtual())
9596 o << "virtual ";
9597 o << b->get_base_class()->get_qualified_name()
9598 << std::endl;
9599 }
9600 }
9601 o << std::endl
9602 << "{"
9603 << " // size in bits: " << c->get_size_in_bits() << "\n"
9604 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9605 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9606 << " // translation unit: " << c->get_translation_unit()->get_absolute_path() << std::endl
9607 << " // @: " << std::hex << is_type(c)
9608 << ", @canonical: " << c->get_canonical_type().get() << std::dec
9609 << "\n\n";
9610
9611 for (auto m : c->get_data_members())
9612 {
9613 type_base_sptr t = m->get_type();
9615
9616 o << " "
9617 << m->get_pretty_representation(/*internal=*/false,
9618 /*qualified=*/false)
9619 << ";";
9620
9621 if (t && t->get_canonical_type())
9622 o << " // uses canonical type '@"
9623 << std::hex << t->get_canonical_type().get() << std::dec;
9624
9625 o << "'" << std::endl;
9626 }
9627
9628 if (clazz && clazz->has_vtable())
9629 {
9630 o << " // virtual member functions\n\n";
9631 for (auto f : clazz->get_virtual_mem_fns())
9632 o << " " << f->get_pretty_representation(/*internal=*/false,
9633 /*qualified=*/false)
9634 << ";" << std::endl;
9635 }
9636
9637 o << "};" << std::endl;
9638
9639 return o.str();
9640 }
9641 else if (const enum_type_decl* e = is_enum_type(artifact))
9642 {
9643 string name = e->get_qualified_name();
9644 std::ostringstream o;
9645 o << "union " << name
9646 << " : "
9647 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9648 true)
9649 << "\n"
9650 << "{\n"
9651 << " // size in bits: " << e->get_size_in_bits() << "\n"
9652 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9653 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9654 << " // translation unit: "
9655 << e->get_translation_unit()->get_absolute_path() << "\n"
9656 << " // @: " << std::hex << is_type(e)
9657 << ", @canonical: " << e->get_canonical_type().get() << std::dec
9658 << "\n\n";
9659
9660 for (const auto &enom : e->get_enumerators())
9661 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9662
9663 o << "};\n";
9664
9665 return o.str();
9666 }
9667 return artifact->get_pretty_representation(/*internal=*/true,
9668 /*qualified=*/true);
9669}
9670
9671/// Get a given data member, referred to by its name, of a class type.
9672///
9673/// @param clazz the class to consider.
9674///
9675/// @param member_name name of the data member to get.
9676///
9677/// @return the resulting data member or nullptr if none was found.
9679get_data_member(class_or_union *clazz, const char* member_name)
9680{
9681 if (!clazz)
9682 return var_decl_sptr();
9683 return clazz->find_data_member(member_name);
9684}
9685
9686/// Get a given data member, referred to by its name, of a class type.
9687///
9688/// @param clazz the class to consider.
9689///
9690/// @param member_name name of the data member to get.
9691///
9692/// @return the resulting data member or nullptr if none was found.
9694get_data_member(type_base *clazz, const char* member_name)
9695{return get_data_member(is_class_or_union_type(clazz), member_name);}
9696
9697/// Get the non-artificial (natural) location of a decl.
9698///
9699/// If the decl doesn't have a natural location then return its
9700/// artificial one.
9701///
9702/// @param decl the decl to consider.
9703///
9704/// @return the natural location @p decl if it has one; otherwise,
9705/// return its artificial one.
9706const location&
9708{
9709 ABG_ASSERT(decl);
9710
9711 if (decl->get_location())
9712 return decl->get_location();
9713 return decl->get_artificial_location();
9714}
9715
9716/// Get the artificial location of a decl.
9717///
9718/// If the decl doesn't have an artificial location then return its
9719/// natural one.
9720///
9721/// @param decl the decl to consider.
9722///
9723/// @return the artificial location @p decl if it has one; otherwise,
9724/// return its natural one.
9725const location&
9727{
9728 ABG_ASSERT(decl);
9729
9730 if (decl->has_artificial_location())
9731 return decl->get_artificial_location();
9732 return decl->get_location();
9733}
9734
9735/// Emit a textual representation of an artifact to std error stream
9736/// for debugging purposes.
9737///
9738/// This is useful to invoke from within a command line debugger like
9739/// GDB to help make sense of a given ABI artifact.
9740///
9741/// @param artifact the ABI artifact to emit the debugging
9742/// representation for.
9743///
9744/// @return the artifact @p artifact.
9746debug(const type_or_decl_base* artifact)
9747{
9748 std::cerr << get_debug_representation(artifact) << std::endl;
9749 return const_cast<type_or_decl_base*>(artifact);
9750}
9751
9752/// Emit a textual representation of an artifact to std error stream
9753/// for debugging purposes.
9754///
9755/// This is useful to invoke from within a command line debugger like
9756/// GDB to help make sense of a given ABI artifact.
9757///
9758/// @param artifact the ABI artifact to emit the debugging
9759/// representation for.
9760///
9761/// @return the artifact @p artifact.
9762type_base*
9763debug(const type_base* artifact)
9764{
9765 debug(static_cast<const type_or_decl_base*>(artifact));
9766 return const_cast<type_base*>(artifact);
9767}
9768
9769/// Emit a textual representation of an artifact to std error stream
9770/// for debugging purposes.
9771///
9772/// This is useful to invoke from within a command line debugger like
9773/// GDB to help make sense of a given ABI artifact.
9774///
9775/// @param artifact the ABI artifact to emit the debugging
9776/// representation for.
9777///
9778/// @return the artifact @p artifact.
9779decl_base*
9780debug(const decl_base* artifact)
9781{
9782 debug(static_cast<const type_or_decl_base*>(artifact));
9783 return const_cast<decl_base*>(artifact);
9784}
9785
9786/// Test if two ABI artifacts are equal.
9787///
9788/// This can be useful when used from the command line of a debugger
9789/// like GDB.
9790///
9791/// @param l the first ABI artifact to consider in the comparison.
9792///
9793/// @param r the second ABI artifact to consider in the comparison.
9794///
9795/// @return true iff @p l equals @p r.
9796bool
9798{
9799 if (!!l != !!r)
9800 return false;
9801 if (!l && !r)
9802 return true;
9803
9804 return (*l == *r);
9805}
9806
9807/// Emit a trace of a comparison operand stack.
9808///
9809/// @param vect the operand stack to emit the trace for.
9810///
9811/// @param o the output stream to emit the trace to.
9812static void
9813debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
9814{
9815 for (auto t : vect)
9816 {
9817 o << "|" << t->get_pretty_representation()
9818 << "@" << std::hex << t << std::dec;
9819 }
9820 if (!vect.empty())
9821 o << "|";
9822}
9823
9824/// Construct a trace of the two comparison operand stacks.
9825///
9826/// @param the environment in which the comparison operand stacks are.
9827///
9828/// @return a string representing the trace.
9829static string
9830print_comp_stack(const environment& env)
9831{
9832 std::ostringstream o;
9833 o << "left-operands: ";
9834 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
9835 o << "\n" << "right-operands: ";
9836 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
9837 o << "\n";
9838 return o.str();
9839}
9840
9841/// Emit a trace of the two comparison operands stack on the standard
9842/// error stream.
9843///
9844/// @param env the environment the comparison operands stack belong
9845/// to.
9846void
9848{
9849 std::cerr << print_comp_stack(env);
9850 std::cerr << std::endl;
9851}
9852
9853/// By looking at the language of the TU a given ABI artifact belongs
9854/// to, test if the ONE Definition Rule should apply.
9855///
9856/// To date, it applies to c++, java and ada.
9857///
9858/// @param artifact the ABI artifact to consider.
9859///
9860/// @return true iff the One Definition Rule should apply.
9861bool
9863{
9865 artifact.get_translation_unit()->get_language();
9866
9868 || is_java_language(l)
9869 || is_ada_language(l))
9870 return true;
9871
9872 return false;
9873}
9874
9875/// Get the declaration for a given type.
9876///
9877/// @param t the type to consider.
9878///
9879/// @return the declaration for the type to return.
9880const decl_base*
9882{return dynamic_cast<const decl_base*>(t);}
9883
9884/// Get the declaration for a given type.
9885///
9886/// @param t the type to consider.
9887///
9888/// @return the declaration for the type to return.
9889decl_base*
9891{return dynamic_cast<decl_base*>(t);}
9892
9893/// Get the declaration for a given type.
9894///
9895/// @param t the type to consider.
9896///
9897/// @return the declaration for the type to return.
9898decl_base_sptr
9899get_type_declaration(const type_base_sptr t)
9900{return dynamic_pointer_cast<decl_base>(t);}
9901
9902/// Test if two types are equal modulo a typedef.
9903///
9904/// Type A and B are compatible if
9905///
9906/// - A and B are equal
9907/// - or if one type is a typedef of the other one.
9908///
9909/// @param type1 the first type to consider.
9910///
9911/// @param type2 the second type to consider.
9912///
9913/// @return true iff @p type1 and @p type2 are compatible.
9914bool
9915types_are_compatible(const type_base_sptr type1,
9916 const type_base_sptr type2)
9917{
9918 if (!type1 || !type2)
9919 return false;
9920
9921 if (type1 == type2)
9922 return true;
9923
9924 // Normally we should strip typedefs entirely, but this is
9925 // potentially costly, especially on binaries with huge changesets
9926 // like the Linux Kernel. So we just get the leaf types for now.
9927 //
9928 // Maybe there should be an option by which users accepts to pay the
9929 // CPU usage toll in exchange for finer filtering?
9930
9931 // type_base_sptr t1 = strip_typedef(type1);
9932 // type_base_sptr t2 = strip_typedef(type2);
9933
9934 type_base_sptr t1 = peel_typedef_type(type1);
9935 type_base_sptr t2 = peel_typedef_type(type2);
9936
9937 return t1 == t2;
9938}
9939
9940/// Test if two types are equal modulo a typedef.
9941///
9942/// Type A and B are compatible if
9943///
9944/// - A and B are equal
9945/// - or if one type is a typedef of the other one.
9946///
9947/// @param type1 the declaration of the first type to consider.
9948///
9949/// @param type2 the declaration of the second type to consider.
9950///
9951/// @return true iff @p type1 and @p type2 are compatible.
9952bool
9953types_are_compatible(const decl_base_sptr d1,
9954 const decl_base_sptr d2)
9955{return types_are_compatible(is_type(d1), is_type(d2));}
9956
9957/// Return the translation unit a declaration belongs to.
9958///
9959/// @param decl the declaration to consider.
9960///
9961/// @return the resulting translation unit, or null if the decl is not
9962/// yet added to a translation unit.
9965{return const_cast<translation_unit*>(decl.get_translation_unit());}
9966
9967/// Return the translation unit a declaration belongs to.
9968///
9969/// @param decl the declaration to consider.
9970///
9971/// @return the resulting translation unit, or null if the decl is not
9972/// yet added to a translation unit.
9975{return decl ? get_translation_unit(*decl) : 0;}
9976
9977/// Return the translation unit a declaration belongs to.
9978///
9979/// @param decl the declaration to consider.
9980///
9981/// @return the resulting translation unit, or null if the decl is not
9982/// yet added to a translation unit.
9984get_translation_unit(const shared_ptr<decl_base> decl)
9985{return get_translation_unit(decl.get());}
9986
9987/// Tests whether if a given scope is the global scope.
9988///
9989/// @param scope the scope to consider.
9990///
9991/// @return true iff the current scope is the global one.
9992bool
9994{return !!dynamic_cast<const global_scope*>(&scope);}
9995
9996/// Tests whether if a given scope is the global scope.
9997///
9998/// @param scope the scope to consider.
9999///
10000/// @return the @ref global_scope* representing the scope @p scope or
10001/// 0 if @p scope is not a global scope.
10002const global_scope*
10004{return dynamic_cast<const global_scope*>(scope);}
10005
10006/// Tests whether if a given scope is the global scope.
10007///
10008/// @param scope the scope to consider.
10009///
10010/// @return true iff the current scope is the global one.
10011bool
10012is_global_scope(const shared_ptr<scope_decl>scope)
10013{return is_global_scope(scope.get());}
10014
10015/// Tests whether a given declaration is at global scope.
10016///
10017/// @param decl the decl to consider.
10018///
10019/// @return true iff decl is at global scope.
10020bool
10022{return (is_global_scope(decl.get_scope()));}
10023
10024/// Tests whether a given declaration is at global scope.
10025///
10026/// @param decl the decl to consider.
10027///
10028/// @return true iff decl is at global scope.
10029bool
10030is_at_global_scope(const decl_base_sptr decl)
10031{return (decl && is_global_scope(decl->get_scope()));}
10032
10033/// Tests whether a given declaration is at global scope.
10034///
10035/// @param decl the decl to consider.
10036///
10037/// @return true iff decl is at global scope.
10038bool
10040{return is_at_global_scope(*decl);}
10041
10042/// Tests whether a given decl is at class scope.
10043///
10044/// @param decl the decl to consider.
10045///
10046/// @return true iff decl is at class scope.
10048is_at_class_scope(const decl_base_sptr decl)
10049{return is_at_class_scope(decl.get());}
10050
10051/// Tests whether a given decl is at class scope.
10052///
10053/// @param decl the decl to consider.
10054///
10055/// @return true iff decl is at class scope.
10058{
10059 if (!decl)
10060 return 0;
10061
10062 return is_at_class_scope(*decl);
10063}
10064
10065/// Tests whether a given decl is at class scope.
10066///
10067/// @param decl the decl to consider.
10068///
10069/// @return true iff decl is at class scope.
10072{
10073 scope_decl* scope = decl.get_scope();
10074 if (class_or_union* cl = is_class_type(scope))
10075 return cl;
10076 if (class_or_union* cl = is_union_type(scope))
10077 return cl;
10078 return 0;
10079}
10080
10081/// Find a data member inside an anonymous data member.
10082///
10083/// An anonymous data member has a type which is a class or union.
10084/// This function looks for a data member inside the type of that
10085/// anonymous data member.
10086///
10087/// @param anon_dm the anonymous data member to consider.
10088///
10089/// @param name the name of the data member to look for.
10092 const string& name)
10093{
10094 const class_or_union* containing_class_or_union =
10096
10097 if (!containing_class_or_union)
10098 return var_decl_sptr();
10099
10100 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10101 return result;
10102}
10103
10104/// Tests whether a given decl is at template scope.
10105///
10106/// Note that only template parameters , types that are compositions,
10107/// and template patterns (function or class) can be at template scope.
10108///
10109/// @param decl the decl to consider.
10110///
10111/// @return true iff the decl is at template scope.
10112bool
10113is_at_template_scope(const shared_ptr<decl_base> decl)
10114{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10115
10116/// Tests whether a decl is a template parameter.
10117///
10118/// @param decl the decl to consider.
10119///
10120/// @return true iff decl is a template parameter.
10121bool
10122is_template_parameter(const shared_ptr<decl_base> decl)
10123{
10124 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10125 || dynamic_pointer_cast<non_type_tparameter>(decl)
10126 || dynamic_pointer_cast<template_tparameter>(decl)));
10127}
10128
10129/// Test whether a declaration is a @ref function_decl.
10130///
10131/// @param d the declaration to test for.
10132///
10133/// @return a shared pointer to @ref function_decl if @p d is a @ref
10134/// function_decl. Otherwise, a nil shared pointer.
10137{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10138
10139/// Test whether a declaration is a @ref function_decl.
10140///
10141/// @param d the declaration to test for.
10142///
10143/// @return true if @p d is a function_decl.
10144bool
10146{return is_function_decl(&d);}
10147
10148/// Test whether a declaration is a @ref function_decl.
10149///
10150/// @param d the declaration to test for.
10151///
10152/// @return a shared pointer to @ref function_decl if @p d is a @ref
10153/// function_decl. Otherwise, a nil shared pointer.
10156{return dynamic_pointer_cast<function_decl>(d);}
10157
10158/// Test whether a declaration is a @ref function_decl.
10159///
10160/// @param d the declaration to test for.
10161///
10162/// @return a pointer to @ref function_decl if @p d is a @ref
10163/// function_decl. Otherwise, a nil shared pointer.
10166{
10167 return dynamic_cast<function_decl::parameter*>
10168 (const_cast<type_or_decl_base*>(tod));
10169}
10170
10171/// Test whether an ABI artifact is a @ref function_decl.
10172///
10173/// @param tod the declaration to test for.
10174///
10175/// @return a pointer to @ref function_decl if @p d is a @ref
10176/// function_decl. Otherwise, a nil shared pointer.
10179{return dynamic_pointer_cast<function_decl::parameter>(tod);}
10180
10181/// Test if an ABI artifact is a declaration.
10182///
10183/// @param d the artifact to consider.
10184///
10185/// @param return the declaration sub-object of @p d if it's a
10186/// declaration, or NULL if it is not.
10187decl_base*
10189{
10190 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10191 {
10192 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10193 // The artifact is a decl-only (like a function or a
10194 // variable). That is, it's not a type that also has a
10195 // declaration. In this case, we are in the fast path and we
10196 // have a pointer to the decl sub-object handy. Just return
10197 // it ...
10198 return reinterpret_cast<decl_base*>
10199 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10200
10201 // ... Otherwise, we are in the slow path, which is that the
10202 // artifact is a type which has a declaration. In that case,
10203 // let's use the slow dynamic_cast because we don't have the
10204 // pointer to the decl sub-object handily present.
10205 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10206 }
10207 return 0;
10208}
10209
10210/// Test if an ABI artifact is a declaration.
10211///
10212/// @param d the artifact to consider.
10213///
10214/// @param return the declaration sub-object of @p d if it's a
10215/// declaration, or NULL if it is not.
10216decl_base_sptr
10218{return dynamic_pointer_cast<decl_base>(d);}
10219
10220/// Test if an ABI artifact is a declaration.
10221///
10222/// This is done using a slow path that uses dynamic_cast.
10223///
10224/// @param d the artifact to consider.
10225///
10226/// @param return the declaration sub-object of @p d if it's a
10227decl_base*
10229{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10230
10231/// Test if an ABI artifact is a declaration.
10232///
10233/// This is done using a slow path that uses dynamic_cast.
10234///
10235/// @param d the artifact to consider.
10236///
10237/// @param return the declaration sub-object of @p d if it's a
10238decl_base_sptr
10240{return dynamic_pointer_cast<decl_base>(t);}
10241
10242/// Test whether a declaration is a type.
10243///
10244/// @param d the IR artefact to test for.
10245///
10246/// @return true if the artifact is a type, false otherwise.
10247bool
10249{
10250 if (dynamic_cast<const type_base*>(&tod))
10251 return true;
10252 return false;
10253}
10254
10255/// Test whether a declaration is a type.
10256///
10257/// @param d the IR artefact to test for.
10258///
10259/// @return true if the artifact is a type, false otherwise.
10260type_base*
10262{
10263 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10264 return reinterpret_cast<type_base*>
10265 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10266
10267 return 0;
10268}
10269
10270/// Test whether a declaration is a type.
10271///
10272/// @param d the IR artefact to test for.
10273///
10274/// @return true if the artifact is a type, false otherwise.
10275type_base_sptr
10277{return dynamic_pointer_cast<type_base>(tod);}
10278
10279/// Test whether a declaration is a type.
10280///
10281/// @param d the declaration to test for.
10282///
10283/// @return true if the declaration is a type, false otherwise.
10284
10285/// Test if a given type is anonymous.
10286///
10287/// Note that this function considers that an anonymous class that is
10288/// named by a typedef is not anonymous anymore. This is the C idiom:
10289///
10290/// typedef struct {int member;} s_type;
10291///
10292/// The typedef s_type becomes the name of the originally anonymous
10293/// struct.
10294///
10295/// @param t the type to consider.
10296///
10297/// @return true iff @p t is anonymous.
10298bool
10300{
10301 const decl_base* d = get_type_declaration(t);
10302 if (d)
10303 if (d->get_is_anonymous())
10304 {
10306 {
10307 // An anonymous class that is named by a typedef is not
10308 // considered anonymous anymore.
10309 if (!cou->get_naming_typedef())
10310 return true;
10311 }
10312 else
10313 return true;
10314 }
10315 return false;
10316}
10317
10318/// Test if a given type is anonymous.
10319///
10320/// @param t the type to consider.
10321///
10322/// @return true iff @p t is anonymous.
10323bool
10324is_anonymous_type(const type_base_sptr& t)
10325{return is_anonymous_type(t.get());}
10326
10327/// Test whether a type is a type_decl (a builtin type).
10328///
10329/// @return the type_decl* for @t if it's type_decl, otherwise, return
10330/// nil.
10331const type_decl*
10333{return dynamic_cast<const type_decl*>(t);}
10334
10335/// Test whether a type is a type_decl (a builtin type).
10336///
10337/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10338/// return nil.
10341{return dynamic_pointer_cast<type_decl>(t);}
10342
10343/// Test if a type is an integral type.
10344///
10345/// @param t the type to test.
10346///
10347/// @return the integral type @p t can be converted to, or nil if @p
10348/// is not an integral type.
10349type_decl*
10351{
10352 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10353 if (!type)
10354 return nullptr;
10355
10356 integral_type int_type;
10357 if (!parse_integral_type(type->get_name(), int_type))
10358 return nullptr;
10359
10360 return type;
10361}
10362
10363/// Test if a type is an integral type.
10364///
10365/// @param t the type to test.
10366///
10367/// @return the integral type @p t can be converted to, or nil if @p
10368/// is not an integral type.
10371{
10372 const type_decl_sptr type = is_type_decl(t);
10373 if (!type)
10374 return type_decl_sptr();
10375
10376 integral_type int_type;
10377 if (!parse_integral_type(type->get_name(), int_type))
10378 return type_decl_sptr();
10379
10380 return type;
10381}
10382
10383/// Test whether a type is a typedef.
10384///
10385/// @param t the type to test for.
10386///
10387/// @return the typedef declaration of the @p t, or NULL if it's not a
10388/// typedef.
10391{return dynamic_pointer_cast<typedef_decl>(t);}
10392
10393/// Test whether a type is a typedef.
10394///
10395/// @param t the declaration of the type to test for.
10396///
10397/// @return the typedef declaration of the @p t, or NULL if it's not a
10398/// typedef.
10399const typedef_decl*
10401{return dynamic_cast<const typedef_decl*>(t);}
10402
10403/// Test whether a type is a typedef.
10404///
10405/// @param t the declaration of the type to test for.
10406///
10407/// @return the typedef declaration of the @p t, or NULL if it's not a
10408/// typedef.
10411{return dynamic_cast<typedef_decl*>(t);}
10412
10413/// Test whether a type is a typedef.
10414///
10415/// @param t the declaration of the type to test for.
10416///
10417/// @return the typedef declaration of the @p t, or NULL if it's not a
10418/// typedef.
10419const typedef_decl*
10421{return dynamic_cast<const typedef_decl*>(t);}
10422/// Test if a type is an enum. This function looks through typedefs.
10423///
10424/// @parm t the type to consider.
10425///
10426/// @return the enum_decl if @p t is an @ref enum_decl or null
10427/// otherwise.
10429is_compatible_with_enum_type(const type_base_sptr& t)
10430{
10431 if (!t)
10432 return enum_type_decl_sptr();
10433
10434 // Normally we should strip typedefs entirely, but this is
10435 // potentially costly, especially on binaries with huge changesets
10436 // like the Linux Kernel. So we just get the leaf types for now.
10437 //
10438 // Maybe there should be an option by which users accepts to pay the
10439 // CPU usage toll in exchange for finer filtering?
10440
10441 // type_base_sptr ty = strip_typedef(t);
10442 type_base_sptr ty = peel_typedef_type(t);;
10443 return is_enum_type(ty);
10444}
10445
10446/// Test if a type is an enum. This function looks through typedefs.
10447///
10448/// @parm t the type to consider.
10449///
10450/// @return the enum_decl if @p t is an @ref enum_decl or null
10451/// otherwise.
10453is_compatible_with_enum_type(const decl_base_sptr& t)
10455
10456/// Test if a decl is an enum_type_decl
10457///
10458/// @param d the decl to test for.
10459///
10460/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
10461const enum_type_decl*
10463{return dynamic_cast<const enum_type_decl*>(d);}
10464
10465/// Test if a decl is an enum_type_decl
10466///
10467/// @param d the decl to test for.
10468///
10469/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
10472{return dynamic_pointer_cast<enum_type_decl>(d);}
10473
10474/// Test if a type is a class. This function looks through typedefs.
10475///
10476/// @parm t the type to consider.
10477///
10478/// @return the class_decl if @p t is a class_decl or null otherwise.
10480is_compatible_with_class_type(const type_base_sptr& t)
10481{
10482 if (!t)
10483 return class_decl_sptr();
10484
10485 // Normally we should strip typedefs entirely, but this is
10486 // potentially costly, especially on binaries with huge changesets
10487 // like the Linux Kernel. So we just get the leaf types for now.
10488 //
10489 // Maybe there should be an option by which users accepts to pay the
10490 // CPU usage toll in exchange for finer filtering?
10491
10492 // type_base_sptr ty = strip_typedef(t);
10493 type_base_sptr ty = peel_typedef_type(t);
10494 return is_class_type(ty);
10495}
10496
10497/// Test if a type is a class. This function looks through typedefs.
10498///
10499/// @parm t the type to consider.
10500///
10501/// @return the class_decl if @p t is a class_decl or null otherwise.
10503is_compatible_with_class_type(const decl_base_sptr& t)
10505
10506/// Test whether a type is a class.
10507///
10508/// @parm t the type to consider.
10509///
10510/// @return true iff @p t is a class_decl.
10511bool
10513{return is_class_type(&t);}
10514
10515/// Test whether a type is a class.
10516///
10517/// @parm t the type to consider.
10518///
10519/// @return the class_decl if @p t is a class_decl or null otherwise.
10522{
10523 if (!t)
10524 return 0;
10525
10526 if (t->kind() & type_or_decl_base::CLASS_TYPE)
10527 return reinterpret_cast<class_decl*>
10528 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10529
10530 return 0;
10531}
10532
10533/// Test whether a type is a class.
10534///
10535/// @parm t the type to consider.
10536///
10537/// @return the class_decl if @p t is a class_decl or null otherwise.
10540{return dynamic_pointer_cast<class_decl>(d);}
10541
10542
10543/// Test wheter a type is a declaration-only class.
10544///
10545/// @param t the type to considier.
10546///
10547/// @param look_through_decl_only if true, then look through the
10548/// decl-only class to see if it actually has a class definition in
10549/// the same ABI corpus.
10550///
10551/// @return true iff @p t is a declaration-only class.
10552bool
10555{
10556 if (class_or_union *klass = is_class_or_union_type(t))
10557 {
10559 klass = look_through_decl_only_class(klass);
10560 return klass->get_is_declaration_only();
10561 }
10562 return false;
10563}
10564
10565/// Test wheter a type is a declaration-only class.
10566///
10567/// @param t the type to considier.
10568///
10569/// @param look_through_decl_only if true, then look through the
10570/// decl-only class to see if it actually has a class definition in
10571/// the same ABI corpus.
10572///
10573/// @return true iff @p t is a declaration-only class.
10574bool
10575is_declaration_only_class_type(const type_base_sptr& t,
10578
10579/// Test if a type is a @ref class_or_union.
10580///
10581/// @param t the type to consider.
10582///
10583/// @return the @ref class_or_union is @p is a @ref class_or_union, or
10584/// nil otherwise.
10587{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
10588
10589/// Test if a type is a @ref class_or_union.
10590///
10591/// @param t the type to consider.
10592///
10593/// @return the @ref class_or_union is @p is a @ref class_or_union, or
10594/// nil otherwise.
10595shared_ptr<class_or_union>
10596is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
10597{return dynamic_pointer_cast<class_or_union>(t);}
10598
10599/// Test if a type is a @ref union_decl.
10600///
10601/// @param t the type to consider.
10602///
10603/// @return true iff @p t is a union_decl.
10604bool
10606{return is_union_type(&t);}
10607
10608/// Test if a type is a @ref union_decl.
10609///
10610/// @param t the type to consider.
10611///
10612/// @return the @ref union_decl is @p is a @ref union_decl, or nil
10613/// otherwise.
10616{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
10617
10618/// Test if a type is a @ref union_decl.
10619///
10620/// @param t the type to consider.
10621///
10622/// @return the @ref union_decl is @p is a @ref union_decl, or nil
10623/// otherwise.
10624union_decl_sptr
10625is_union_type(const shared_ptr<type_or_decl_base>& t)
10626{return dynamic_pointer_cast<union_decl>(t);}
10627
10628/// Test whether a type is a pointer_type_def.
10629///
10630/// @param t the type to test.
10631///
10632/// @return the @ref pointer_type_def_sptr if @p t is a
10633/// pointer_type_def, null otherwise.
10636{
10637 if (!t)
10638 return 0;
10639
10640 if (t->kind() & type_or_decl_base::POINTER_TYPE)
10641 return reinterpret_cast<pointer_type_def*>
10642 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10643
10644 return 0;
10645}
10646
10647/// Test whether a type is a pointer_type_def.
10648///
10649/// @param t the type to test.
10650///
10651/// @return the @ref pointer_type_def_sptr if @p t is a
10652/// pointer_type_def, null otherwise.
10653const pointer_type_def*
10655{
10656 return is_pointer_type(const_cast<type_or_decl_base*>(t));
10657}
10658
10659/// Test whether a type is a pointer_type_def.
10660///
10661/// @param t the type to test.
10662///
10663/// @return the @ref pointer_type_def_sptr if @p t is a
10664/// pointer_type_def, null otherwise.
10667{return dynamic_pointer_cast<pointer_type_def>(t);}
10668
10669/// Test if a type is a pointer to a decl-only class/union.
10670///
10671/// @param t the type to consider.
10672///
10673/// @return true iff @p t is a pointer to a decl-only class/union.
10674bool
10676{
10677 const pointer_type_def* ptr = is_pointer_type(t);
10678 if (!ptr)
10679 return false;
10680
10681 const type_base* type = peel_pointer_type(ptr);
10682
10683 type = peel_typedef_type(type);
10684
10686 /*look_through_decl_only=*/true))
10687 return true;
10688
10689 return false;
10690}
10691
10692/// Test if a type is a reference to a decl-only class/union.
10693///
10694/// @param t the type to consider.
10695///
10696/// @return true iff @p t is a reference to a decl-only class/union.
10697bool
10699{
10700 const reference_type_def* ref = is_reference_type(t);
10701 if (!ref)
10702 return false;
10703
10704 const type_base* type = peel_reference_type(ref);
10705
10706 type = peel_typedef_type(type);
10707
10709 /*look_through_decl_only=*/true))
10710 return true;
10711
10712 return false;
10713}
10714
10715/// Test if a type is a typedef to a decl-only class/union.
10716///
10717/// @param t the type to consider.
10718///
10719/// @return true iff @p t is a typedef to a decl-only class/union.
10720bool
10722{
10723 const typedef_decl* typdef = is_typedef(t);
10724 if (!typdef)
10725 return false;
10726
10727 const type_base* type = peel_typedef_type(typdef);
10729 /*look_through_decl_only=*/true))
10730 return true;
10731
10732 return false;
10733}
10734
10735/// Test whether a type is a reference_type_def.
10736///
10737/// @param t the type to test.
10738///
10739/// @return the @ref reference_type_def_sptr if @p t is a
10740/// reference_type_def, null otherwise.
10743{return dynamic_cast<reference_type_def*>(t);}
10744
10745/// Test whether a type is a reference_type_def.
10746///
10747/// @param t the type to test.
10748///
10749/// @return the @ref reference_type_def_sptr if @p t is a
10750/// reference_type_def, null otherwise.
10751const reference_type_def*
10753{return dynamic_cast<const reference_type_def*>(t);}
10754
10755/// Test whether a type is a reference_type_def.
10756///
10757/// @param t the type to test.
10758///
10759/// @return the @ref reference_type_def_sptr if @p t is a
10760/// reference_type_def, null otherwise.
10763{return dynamic_pointer_cast<reference_type_def>(t);}
10764
10765/// Test if a type is equivalent to a pointer to void type.
10766///
10767/// Note that this looks trough typedefs or CV qualifiers to look for
10768/// the void pointer.
10769///
10770/// @param type the type to consider.
10771///
10772/// @return the actual void pointer if @p is eqivalent to a void
10773/// pointer or NULL if it's not.
10774const type_base*
10776{
10777 type = peel_qualified_or_typedef_type(type);
10778
10779 const pointer_type_def * t = is_pointer_type(type);
10780 if (!t)
10781 return 0;
10782
10783 // Look through typedefs in the pointed-to type as well.
10784 type_base * ty = t->get_pointed_to_type().get();
10786 if (ty && ty->get_environment().is_void_type(ty))
10787 return ty;
10788
10789 return 0;
10790}
10791
10792/// Test if a type is equivalent to a pointer to void type.
10793///
10794/// Note that this looks trough typedefs or CV qualifiers to look for
10795/// the void pointer.
10796///
10797/// @param type the type to consider.
10798///
10799/// @return the actual void pointer if @p is eqivalent to a void
10800/// pointer or NULL if it's not.
10801const type_base*
10803{return is_void_pointer_type_equivalent(&type);}
10804
10805/// Test if a type is a pointer to void type.
10806///
10807/// @param type the type to consider.
10808///
10809/// @return the actual void pointer if @p is a void pointer or NULL if
10810/// it's not.
10811const type_base*
10813{
10814 if (!t)
10815 return nullptr;
10816
10817 if (t->get_environment().get_void_pointer_type().get() == t)
10818 return t;
10819
10820 const pointer_type_def* ptr = is_pointer_type(t);
10821 if (!ptr)
10822 return nullptr;
10823
10825 return t;
10826
10827 return nullptr;
10828}
10829
10830/// Test if a type is a pointer to void type.
10831///
10832/// @param type the type to consider.
10833///
10834/// @return the actual void pointer if @p is a void pointer or NULL if
10835/// it's not.
10836const type_base_sptr
10837is_void_pointer_type(const type_base_sptr& t)
10838{
10839 type_base_sptr nil;
10840 if (!t)
10841 return nil;
10842
10843 if (t->get_environment().get_void_pointer_type().get() == t.get())
10844 return t;
10845
10846 pointer_type_def* ptr = is_pointer_type(t.get());
10847 if (!ptr)
10848 return nil;
10849
10850 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
10851 return t;
10852
10853 return nil;
10854}
10855
10856/// Test whether a type is a reference_type_def.
10857///
10858/// @param t the type to test.
10859///
10860/// @return the @ref reference_type_def_sptr if @p t is a
10861/// reference_type_def, null otherwise.
10864{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
10865
10866/// Test whether a type is a qualified_type_def.
10867///
10868/// @param t the type to test.
10869///
10870/// @return the @ref qualified_type_def_sptr if @p t is a
10871/// qualified_type_def, null otherwise.
10872qualified_type_def_sptr
10874{return dynamic_pointer_cast<qualified_type_def>(t);}
10875
10876/// Test whether a type is a function_type.
10877///
10878/// @param t the type to test.
10879///
10880/// @return the @ref function_type_sptr if @p t is a
10881/// function_type, null otherwise.
10884{return dynamic_pointer_cast<function_type>(t);}
10885
10886/// Test whether a type is a function_type.
10887///
10888/// @param t the type to test.
10889///
10890/// @return the @ref function_type_sptr if @p t is a
10891/// function_type, null otherwise.
10894{return dynamic_cast<function_type*>(t);}
10895
10896/// Test whether a type is a function_type.
10897///
10898/// @param t the type to test.
10899///
10900/// @return the @ref function_type_sptr if @p t is a
10901/// function_type, null otherwise.
10902const function_type*
10904{return dynamic_cast<const function_type*>(t);}
10905
10906/// Test whether a type is a method_type.
10907///
10908/// @param t the type to test.
10909///
10910/// @return the @ref method_type_sptr if @p t is a
10911/// method_type, null otherwise.
10914{return dynamic_pointer_cast<method_type>(t);}
10915
10916/// Test whether a type is a method_type.
10917///
10918/// @param t the type to test.
10919///
10920/// @return the @ref method_type_sptr if @p t is a
10921/// method_type, null otherwise.
10922const method_type*
10924{return dynamic_cast<const method_type*>(t);}
10925
10926/// Test whether a type is a method_type.
10927///
10928/// @param t the type to test.
10929///
10930/// @return the @ref method_type_sptr if @p t is a
10931/// method_type, null otherwise.
10934{return dynamic_cast<method_type*>(t);}
10935
10936/// If a class (or union) is a decl-only class, get its definition.
10937/// Otherwise, just return the initial class.
10938///
10939/// @param the_class the class (or union) to consider.
10940///
10941/// @return either the definition of the class, or the class itself.
10945
10946/// If a class (or union) is a decl-only class, get its definition.
10947/// Otherwise, just return the initial class.
10948///
10949/// @param the_class the class (or union) to consider.
10950///
10951/// @return either the definition of the class, or the class itself.
10952class_or_union_sptr
10955
10956/// If a class (or union) is a decl-only class, get its definition.
10957/// Otherwise, just return the initial class.
10958///
10959/// @param klass the class (or union) to consider.
10960///
10961/// @return either the definition of the class, or the class itself.
10962class_or_union_sptr
10963look_through_decl_only_class(class_or_union_sptr klass)
10965
10966/// If an enum is a decl-only enum, get its definition.
10967/// Otherwise, just return the initial enum.
10968///
10969/// @param the_enum the enum to consider.
10970///
10971/// @return either the definition of the enum, or the enum itself.
10974{return is_enum_type(look_through_decl_only(the_enum));}
10975
10976/// If an enum is a decl-only enum, get its definition.
10977/// Otherwise, just return the initial enum.
10978///
10979/// @param enom the enum to consider.
10980///
10981/// @return either the definition of the enum, or the enum itself.
10984{return is_enum_type(look_through_decl_only(enom));}
10985
10986/// If a decl is decl-only get its definition. Otherwise, just return nil.
10987///
10988/// @param d the decl to consider.
10989///
10990/// @return either the definition of the decl, or nil.
10991decl_base_sptr
10993{
10994 decl_base_sptr decl;
10997
10998 if (!decl)
10999 return decl;
11000
11001 while (decl->get_is_declaration_only()
11002 && decl->get_definition_of_declaration())
11003 decl = decl->get_definition_of_declaration();
11004
11005 return decl;
11006}
11007
11008/// If a decl is decl-only enum, get its definition. Otherwise, just
11009/// return the initial decl.
11010///
11011/// @param d the decl to consider.
11012///
11013/// @return either the definition of the enum, or the decl itself.
11014decl_base*
11016{
11017 if (!d)
11018 return d;
11019
11020 decl_base* result = look_through_decl_only(*d).get();
11021 if (!result)
11022 result = d;
11023
11024 return result;
11025}
11026
11027/// If a decl is decl-only get its definition. Otherwise, just return nil.
11028///
11029/// @param d the decl to consider.
11030///
11031/// @return either the definition of the decl, or nil.
11032decl_base_sptr
11033look_through_decl_only(const decl_base_sptr& d)
11034{
11035 if (!d)
11036 return d;
11037
11038 decl_base_sptr result = look_through_decl_only(*d);
11039 if (!result)
11040 result = d;
11041
11042 return result;
11043}
11044
11045/// If a type is is decl-only, then get its definition. Otherwise,
11046/// just return the initial type.
11047///
11048/// @param d the decl to consider.
11049///
11050/// @return either the definition of the decl, or the initial type.
11051type_base*
11053{
11054 decl_base* d = is_decl(t);
11055 if (!d)
11056 return t;
11058 return is_type(d);
11059}
11060
11061/// If a type is is decl-only, then get its definition. Otherwise,
11062/// just return the initial type.
11063///
11064/// @param d the decl to consider.
11065///
11066/// @return either the definition of the decl, or the initial type.
11067type_base_sptr
11068look_through_decl_only(const type_base_sptr& t)
11069{
11070 decl_base_sptr d = is_decl(t);
11071 if (!d)
11072 return t;
11074 return is_type(d);
11075}
11076
11077/// Tests if a declaration is a variable declaration.
11078///
11079/// @param decl the decl to test.
11080///
11081/// @return the var_decl_sptr iff decl is a variable declaration; nil
11082/// otherwise.
11083var_decl*
11085{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
11086
11087/// Tests if a declaration is a variable declaration.
11088///
11089/// @param decl the decl to test.
11090///
11091/// @return the var_decl_sptr iff decl is a variable declaration; nil
11092/// otherwise.
11095{return dynamic_pointer_cast<var_decl>(decl);}
11096
11097/// Tests if a declaration is a namespace declaration.
11098///
11099/// @param d the decalration to consider.
11100///
11101/// @return the namespace declaration if @p d is a namespace.
11103is_namespace(const decl_base_sptr& d)
11104{return dynamic_pointer_cast<namespace_decl>(d);}
11105
11106/// Tests if a declaration is a namespace declaration.
11107///
11108/// @param d the decalration to consider.
11109///
11110/// @return the namespace declaration if @p d is a namespace.
11113{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
11114
11115/// Tests whether a decl is a template parameter composition type.
11116///
11117/// @param decl the declaration to consider.
11118///
11119/// @return true iff decl is a template parameter composition type.
11120bool
11121is_template_parm_composition_type(const shared_ptr<decl_base> decl)
11122{
11123 return (decl
11124 && is_at_template_scope(decl)
11125 && is_type(decl)
11126 && !is_template_parameter(decl));
11127}
11128
11129/// Test whether a decl is the pattern of a function template.
11130///
11131/// @param decl the decl to consider.
11132///
11133/// @return true iff decl is the pattern of a function template.
11134bool
11135is_function_template_pattern(const shared_ptr<decl_base> decl)
11136{
11137 return (decl
11138 && dynamic_pointer_cast<function_decl>(decl)
11139 && dynamic_cast<template_decl*>(decl->get_scope()));
11140}
11141
11142/// Test if a type is an array_type_def.
11143///
11144/// @param type the type to consider.
11145///
11146/// @return true iff @p type is an array_type_def.
11149{return dynamic_cast<array_type_def*>(const_cast<type_or_decl_base*>(type));}
11150
11151/// Test if a type is an array_type_def.
11152///
11153/// @param type the type to consider.
11154///
11155/// @return true iff @p type is an array_type_def.
11158{return dynamic_pointer_cast<array_type_def>(type);}
11159
11160/// Tests if the element of a given array is a qualified type.
11161///
11162/// @param array the array type to consider.
11163///
11164/// @return the qualified element of the array iff it's a qualified
11165/// type. Otherwise, return a nil object.
11166qualified_type_def_sptr
11168{
11169 if (!array)
11170 return qualified_type_def_sptr();
11171
11172 return is_qualified_type(array->get_element_type());
11173}
11174
11175/// Test if an array type is an array to a qualified element type.
11176///
11177/// @param type the array type to consider.
11178///
11179/// @return true the array @p type iff it's an array to a qualified
11180/// element type.
11182is_array_of_qualified_element(const type_base_sptr& type)
11183{
11184 if (array_type_def_sptr array = is_array_type(type))
11186 return array;
11187
11188 return array_type_def_sptr();
11189}
11190
11191/// Test if a type is a typedef of an array.
11192///
11193/// Note that the function looks through qualified and typedefs types
11194/// of the underlying type of the current typedef. In other words, if
11195/// we are looking at a typedef of a CV-qualified array, or at a
11196/// typedef of a CV-qualified typedef of an array, this function will
11197/// still return TRUE.
11198///
11199/// @param t the type to consider.
11200///
11201/// @return true if t is a typedef which underlying type is an array.
11202/// That array might be either cv-qualified array or a typedef'ed
11203/// array, or a combination of both.
11205is_typedef_of_array(const type_base_sptr& t)
11206{
11207 array_type_def_sptr result;
11208
11209 if (typedef_decl_sptr typdef = is_typedef(t))
11210 {
11211 type_base_sptr u =
11212 peel_qualified_or_typedef_type(typdef->get_underlying_type());
11213 result = is_array_type(u);
11214 }
11215
11216 return result;
11217}
11218
11219/// Test if a type is an array_type_def::subrange_type.
11220///
11221/// @param type the type to consider.
11222///
11223/// @return the array_type_def::subrange_type which @p type is a type
11224/// of, or nil if it's not of that type.
11225array_type_def::subrange_type*
11227{
11228 return dynamic_cast<array_type_def::subrange_type*>
11229 (const_cast<type_or_decl_base*>(type));
11230}
11231
11232/// Test if a type is an array_type_def::subrange_type.
11233///
11234/// @param type the type to consider.
11235///
11236/// @return the array_type_def::subrange_type which @p type is a type
11237/// of, or nil if it's not of that type.
11240{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
11241
11242/// Tests whether a decl is a template.
11243///
11244/// @param decl the decl to consider.
11245///
11246/// @return true iff decl is a function template, class template, or
11247/// template template parameter.
11248bool
11249is_template_decl(const decl_base_sptr& decl)
11250{return decl && dynamic_pointer_cast<template_decl>(decl);}
11251
11252/// This enum describe the kind of entity to lookup, while using the
11253/// lookup API.
11255{
11256 LOOKUP_ENTITY_TYPE,
11257 LOOKUP_ENTITY_VAR,
11258};
11259
11260/// Find the first relevant delimiter (the "::" string) in a fully
11261/// qualified C++ type name, starting from a given position. The
11262/// delimiter returned separates a type name from the name of its
11263/// context.
11264///
11265/// This is supposed to work correctly on names in cases like this:
11266///
11267/// foo<ns1::name1, ns2::name2>
11268///
11269/// In that case when called with with parameter @p begin set to 0, no
11270/// delimiter is returned, because the type name in this case is:
11271/// 'foo<ns1::name1, ns2::name2>'.
11272///
11273/// But in this case:
11274///
11275/// foo<p1, bar::name>::some_type
11276///
11277/// The "::" returned is the one right before 'some_type'.
11278///
11279/// @param fqn the fully qualified name of the type to consider.
11280///
11281/// @param begin the position from which to look for the delimiter.
11282///
11283/// @param delim_pos out parameter. Is set to the position of the
11284/// delimiter iff the function returned true.
11285///
11286/// @return true iff the function found and returned the delimiter.
11287static bool
11288find_next_delim_in_cplus_type(const string& fqn,
11289 size_t begin,
11290 size_t& delim_pos)
11291{
11292 int angle_count = 0;
11293 bool found = false;
11294 size_t i = begin;
11295 for (; i < fqn.size(); ++i)
11296 {
11297 if (fqn[i] == '<')
11298 ++angle_count;
11299 else if (fqn[i] == '>')
11300 --angle_count;
11301 else if (i + 1 < fqn.size()
11302 && !angle_count
11303 && fqn[i] == ':'
11304 && fqn[i+1] == ':')
11305 {
11306 delim_pos = i;
11307 found = true;
11308 break;
11309 }
11310 }
11311 return found;
11312}
11313
11314/// Decompose a fully qualified name into the list of its components.
11315///
11316/// @param fqn the fully qualified name to decompose.
11317///
11318/// @param comps the resulting list of component to fill.
11319void
11320fqn_to_components(const string& fqn,
11321 list<string>& comps)
11322{
11323 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
11324 do
11325 {
11326 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
11327 comp_end = fqn_size;
11328
11329 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
11330 comps.push_back(comp);
11331
11332 comp_begin = comp_end + 2;
11333 if (comp_begin >= fqn_size)
11334 break;
11335 } while (true);
11336}
11337
11338/// Turn a set of qualified name components (that name a type) into a
11339/// qualified name string.
11340///
11341/// @param comps the name components
11342///
11343/// @return the resulting string, which would be the qualified name of
11344/// a type.
11345string
11346components_to_type_name(const list<string>& comps)
11347{
11348 string result;
11349 for (list<string>::const_iterator c = comps.begin();
11350 c != comps.end();
11351 ++c)
11352 if (c == comps.begin())
11353 result = *c;
11354 else
11355 result += "::" + *c;
11356 return result;
11357}
11358
11359/// This predicate returns true if a given container iterator points
11360/// to the last element of the container, false otherwise.
11361///
11362/// @tparam T the type of the container of the iterator.
11363///
11364/// @param container the container the iterator points into.
11365///
11366/// @param i the iterator to consider.
11367///
11368/// @return true iff the iterator points to the last element of @p
11369/// container.
11370template<typename T>
11371static bool
11372iterator_is_last(T& container,
11373 typename T::const_iterator i)
11374{
11375 typename T::const_iterator next = i;
11376 ++next;
11377 return (next == container.end());
11378}
11379
11380//--------------------------------
11381// <type and decls lookup stuff>
11382// ------------------------------
11383
11384/// Lookup all the type*s* that have a given fully qualified name.
11385///
11386/// @param type_name the fully qualified name of the type to
11387/// lookup.
11388///
11389/// @param type_map the map to look into.
11390///
11391/// @return the vector containing the types named @p type_name. If
11392/// the lookup didn't yield any type, then this function returns nil.
11393static const type_base_wptrs_type*
11394lookup_types_in_map(const interned_string& type_name,
11395 const istring_type_base_wptrs_map_type& type_map)
11396{
11397 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
11398 if (i != type_map.end())
11399 return &i->second;
11400 return 0;
11401}
11402
11403/// Lookup a type (with a given name) in a map that associates a type
11404/// name to a type. If there are several types with a given name,
11405/// then try to return the first one that is not decl-only.
11406/// Otherwise, return the last of such types, that is, the last one
11407/// that got registered.
11408///
11409/// @tparam TypeKind the type of the type this function is supposed to
11410/// return.
11411///
11412/// @param type_name the name of the type to lookup.
11413///
11414/// @param type_map the map in which to look.
11415///
11416/// @return a shared_ptr to the type found. If no type was found or
11417/// if the type found was not of type @p TypeKind then the function
11418/// returns nil.
11419template <class TypeKind>
11420static shared_ptr<TypeKind>
11421lookup_type_in_map(const interned_string& type_name,
11422 const istring_type_base_wptrs_map_type& type_map)
11423{
11424 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
11425 if (i != type_map.end())
11426 {
11427 // Walk the types that have the name "type_name" and return the
11428 // first one that is not declaration-only ...
11429 for (auto j : i->second)
11430 {
11431 type_base_sptr t(j);
11432 decl_base_sptr d = is_decl(t);
11433 if (d && !d->get_is_declaration_only())
11434 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
11435 }
11436 // ... or return the last type with the name "type_name" that
11437 // was recorded. It's likely to be declaration-only if we
11438 // reached this point.
11439 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
11440 }
11441 return shared_ptr<TypeKind>();
11442}
11443
11444/// Lookup a basic type from a translation unit.
11445///
11446/// This is done by looking the type up in the type map that is
11447/// maintained in the translation unit. So this is as fast as
11448/// possible.
11449///
11450/// @param type_name the name of the basic type to look for.
11451///
11452/// @param tu the translation unit to look into.
11453///
11454/// @return the basic type found or nil if no basic type was found.
11457{
11458 return lookup_type_in_map<type_decl>(type_name,
11459 tu.get_types().basic_types());
11460}
11461
11462/// Lookup a basic type from a translation unit.
11463///
11464/// This is done by looking the type up in the type map that is
11465/// maintained in the translation unit. So this is as fast as
11466/// possible.
11467///
11468/// @param type_name the name of the basic type to look for.
11469///
11470/// @param tu the translation unit to look into.
11471///
11472/// @return the basic type found or nil if no basic type was found.
11474lookup_basic_type(const string& type_name, const translation_unit& tu)
11475{
11476 const environment& env = tu.get_environment();
11477
11478 interned_string s = env.intern(type_name);
11479 return lookup_basic_type(s, tu);
11480}
11481
11482/// Lookup a class type from a translation unit.
11483///
11484/// This is done by looking the type up in the type map that is
11485/// maintained in the translation unit. So this is as fast as
11486/// possible.
11487///
11488/// @param fqn the fully qualified name of the class type node to look
11489/// up.
11490///
11491/// @param tu the translation unit to perform lookup from.
11492///
11493/// @return the declaration of the class type IR node found, NULL
11494/// otherwise.
11496lookup_class_type(const string& fqn, const translation_unit& tu)
11497{
11498 const environment& env = tu.get_environment();
11499 interned_string s = env.intern(fqn);
11500 return lookup_class_type(s, tu);
11501}
11502
11503/// Lookup a class type from a translation unit.
11504///
11505/// This is done by looking the type up in the type map that is
11506/// maintained in the translation unit. So this is as fast as
11507/// possible.
11508///
11509/// @param type_name the name of the class type to look for.
11510///
11511/// @param tu the translation unit to look into.
11512///
11513/// @return the class type found or nil if no class type was found.
11516{
11517 return lookup_type_in_map<class_decl>(type_name,
11518 tu.get_types().class_types());
11519}
11520
11521/// Lookup a union type from a translation unit.
11522///
11523/// This is done by looking the type up in the type map that is
11524/// maintained in the translation unit. So this is as fast as
11525/// possible.
11526///
11527/// @param type_name the name of the union type to look for.
11528///
11529/// @param tu the translation unit to look into.
11530///
11531/// @return the union type found or nil if no union type was found.
11532union_decl_sptr
11534{
11535 return lookup_type_in_map<union_decl>(type_name,
11536 tu.get_types().union_types());
11537}
11538
11539/// Lookup a union type from a translation unit.
11540///
11541/// This is done by looking the type up in the type map that is
11542/// maintained in the translation unit. So this is as fast as
11543/// possible.
11544///
11545/// @param fqn the fully qualified name of the type to lookup.
11546///
11547/// @param tu the translation unit to look into.
11548///
11549/// @return the union type found or nil if no union type was found.
11550union_decl_sptr
11551lookup_union_type(const string& fqn, const translation_unit& tu)
11552{
11553 const environment& env = tu.get_environment();
11554 interned_string s = env.intern(fqn);
11555 return lookup_union_type(s, tu);
11556}
11557
11558/// Lookup a union type in a given corpus, from its location.
11559///
11560/// @param loc the location of the union type to look for.
11561///
11562/// @param corp the corpus to look it from.
11563///
11564/// @return the resulting union_decl.
11565union_decl_sptr
11567{
11570 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
11571
11572 return result;
11573}
11574
11575/// Lookup a union type in a given corpus, from its location.
11576///
11577/// @param loc the location of the union type to look for.
11578///
11579/// @param corp the corpus to look it from.
11580///
11581/// @return the resulting union_decl.
11582union_decl_sptr
11583lookup_union_type_per_location(const string& loc, const corpus& corp)
11584{
11585 const environment& env = corp.get_environment();
11586 return lookup_union_type_per_location(env.intern(loc), corp);
11587}
11588
11589/// Lookup an enum type from a translation unit.
11590///
11591/// This is done by looking the type up in the type map that is
11592/// maintained in the translation unit. So this is as fast as
11593/// possible.
11594///
11595/// @param type_name the name of the enum type to look for.
11596///
11597/// @param tu the translation unit to look into.
11598///
11599/// @return the enum type found or nil if no enum type was found.
11602{
11603 return lookup_type_in_map<enum_type_decl>(type_name,
11604 tu.get_types().enum_types());
11605}
11606
11607/// Lookup an enum type from a translation unit.
11608///
11609/// This is done by looking the type up in the type map that is
11610/// maintained in the translation unit. So this is as fast as
11611/// possible.
11612///
11613/// @param type_name the name of the enum type to look for.
11614///
11615/// @param tu the translation unit to look into.
11616///
11617/// @return the enum type found or nil if no enum type was found.
11619lookup_enum_type(const string& type_name, const translation_unit& tu)
11620{
11621 const environment& env = tu.get_environment();
11622 interned_string s = env.intern(type_name);
11623 return lookup_enum_type(s, tu);
11624}
11625
11626/// Lookup a typedef type from a translation unit.
11627///
11628/// This is done by looking the type up in the type map that is
11629/// maintained in the translation unit. So this is as fast as
11630/// possible.
11631///
11632/// @param type_name the name of the typedef type to look for.
11633///
11634/// @param tu the translation unit to look into.
11635///
11636/// @return the typedef type found or nil if no typedef type was
11637/// found.
11640 const translation_unit& tu)
11641{
11642 return lookup_type_in_map<typedef_decl>(type_name,
11643 tu.get_types().typedef_types());
11644}
11645
11646/// Lookup a typedef type from a translation unit.
11647///
11648/// This is done by looking the type up in the type map that is
11649/// maintained in the translation unit. So this is as fast as
11650/// possible.
11651///
11652/// @param type_name the name of the typedef type to look for.
11653///
11654/// @param tu the translation unit to look into.
11655///
11656/// @return the typedef type found or nil if no typedef type was
11657/// found.
11659lookup_typedef_type(const string& type_name, const translation_unit& tu)
11660{
11661 const environment& env = tu.get_environment();
11662 interned_string s = env.intern(type_name);
11663 return lookup_typedef_type(s, tu);
11664}
11665
11666/// Lookup a qualified type from a translation unit.
11667///
11668/// This is done by looking the type up in the type map that is
11669/// maintained in the translation unit. So this is as fast as
11670/// possible.
11671///
11672/// @param type_name the name of the qualified type to look for.
11673///
11674/// @param tu the translation unit to look into.
11675///
11676/// @return the qualified type found or nil if no qualified type was
11677/// found.
11678qualified_type_def_sptr
11680 const translation_unit& tu)
11681{
11682 const type_maps& m = tu.get_types();
11683 return lookup_type_in_map<qualified_type_def>(type_name,
11684 m.qualified_types());
11685}
11686
11687/// Lookup a qualified type from a translation unit.
11688///
11689/// This is done by looking the type up in the type map that is
11690/// maintained in the translation unit. So this is as fast as
11691/// possible.
11692///
11693/// @param underlying_type the underying type of the qualified type to
11694/// look up.
11695///
11696/// @param quals the CV-qualifiers of the qualified type to look for.
11697///
11698/// @param tu the translation unit to look into.
11699///
11700/// @return the qualified type found or nil if no qualified type was
11701/// found.
11702qualified_type_def_sptr
11703lookup_qualified_type(const type_base_sptr& underlying_type,
11705 const translation_unit& tu)
11706{
11707 interned_string type_name = get_name_of_qualified_type(underlying_type,
11708 quals);
11709 return lookup_qualified_type(type_name, tu);
11710}
11711
11712/// Lookup a pointer type from a translation unit.
11713///
11714/// This is done by looking the type up in the type map that is
11715/// maintained in the translation unit. So this is as fast as
11716/// possible.
11717///
11718/// @param type_name the name of the pointer type to look for.
11719///
11720/// @param tu the translation unit to look into.
11721///
11722/// @return the pointer type found or nil if no pointer type was
11723/// found.
11726 const translation_unit& tu)
11727{
11728 const type_maps& m = tu.get_types();
11729 return lookup_type_in_map<pointer_type_def>(type_name,
11730 m.pointer_types());
11731}
11732
11733/// Lookup a pointer type from a translation unit.
11734///
11735/// This is done by looking the type up in the type map that is
11736/// maintained in the translation unit. So this is as fast as
11737/// possible.
11738///
11739/// @param type_name the name of the pointer type to look for.
11740///
11741/// @param tu the translation unit to look into.
11742///
11743/// @return the pointer type found or nil if no pointer type was
11744/// found.
11746lookup_pointer_type(const string& type_name, const translation_unit& tu)
11747{
11748 const environment& env = tu.get_environment();
11749 interned_string s = env.intern(type_name);
11750 return lookup_pointer_type(s, tu);
11751}
11752
11753/// Lookup a pointer type from a translation unit.
11754///
11755/// This is done by looking the type up in the type map that is
11756/// maintained in the translation unit. So this is as fast as
11757/// possible.
11758///
11759/// @param pointed_to_type the pointed-to-type of the pointer to look for.
11760///
11761/// @param tu the translation unit to look into.
11762///
11763/// @return the pointer type found or nil if no pointer type was
11764/// found.
11766lookup_pointer_type(const type_base_sptr& pointed_to_type,
11767 const translation_unit& tu)
11768{
11769 type_base_sptr t = look_through_decl_only(pointed_to_type);
11771 return lookup_pointer_type(type_name, tu);
11772}
11773
11774/// Lookup a reference type from a translation unit.
11775///
11776/// This is done by looking the type up in the type map that is
11777/// maintained in the translation unit. So this is as fast as
11778/// possible.
11779///
11780/// @param type_name the name of the reference type to look for.
11781///
11782/// @param tu the translation unit to look into.
11783///
11784/// @return the reference type found or nil if no reference type was
11785/// found.
11788 const translation_unit& tu)
11789{
11790 const type_maps& m = tu.get_types();
11791 return lookup_type_in_map<reference_type_def>(type_name,
11792 m.reference_types());
11793}
11794
11795/// Lookup a reference type from a translation unit.
11796///
11797/// This is done by looking the type up in the type map that is
11798/// maintained in the translation unit. So this is as fast as
11799/// possible.
11800///
11801/// @param pointed_to_type the pointed-to-type of the reference to
11802/// look up.
11803///
11804/// @param tu the translation unit to look into.
11805///
11806/// @return the reference type found or nil if no reference type was
11807/// found.
11809lookup_reference_type(const type_base_sptr& pointed_to_type,
11810 bool lvalue_reference,
11811 const translation_unit& tu)
11812{
11813 interned_string type_name =
11815 lvalue_reference);
11816 return lookup_reference_type(type_name, tu);
11817}
11818
11819/// Lookup an array type from a translation unit.
11820///
11821/// This is done by looking the type up in the type map that is
11822/// maintained in the translation unit. So this is as fast as
11823/// possible.
11824///
11825/// @param type_name the name of the array type to look for.
11826///
11827/// @param tu the translation unit to look into.
11828///
11829/// @return the array type found or nil if no array type was found.
11832 const translation_unit& tu)
11833{
11834 const type_maps& m = tu.get_types();
11835 return lookup_type_in_map<array_type_def>(type_name,
11836 m.array_types());
11837}
11838
11839/// Lookup a function type from a translation unit.
11840///
11841/// This is done by looking the type up in the type map that is
11842/// maintained in the translation unit. So this is as fast as
11843/// possible.
11844///
11845/// @param type_name the name of the type to lookup.
11846///
11847/// @param tu the translation unit to look into.
11848///
11849/// @return the function type found, or NULL of none was found.
11852 const translation_unit& tu)
11853{
11854 const type_maps& m = tu.get_types();
11855 return lookup_type_in_map<function_type>(type_name,
11856 m.function_types());
11857}
11858
11859/// Lookup a function type from a translation unit.
11860///
11861/// This walks all the function types held by the translation unit and
11862/// compare their sub-type *names*. If the names match then return
11863/// the function type found in the translation unit.
11864///
11865/// @param t the function type to look for.
11866///
11867/// @param tu the translation unit to look into.
11868///
11869/// @return the function type found, or NULL of none was found.
11872 const translation_unit& tu)
11873{
11874 interned_string type_name = get_type_name(t);
11875 return lookup_function_type(type_name, tu);
11876}
11877
11878/// Lookup a function type from a translation unit.
11879///
11880/// This is done by looking the type up in the type map that is
11881/// maintained in the translation unit. So this is as fast as
11882/// possible.
11883///
11884/// @param t the function type to look for.
11885///
11886/// @param tu the translation unit to look into.
11887///
11888/// @return the function type found, or NULL of none was found.
11891 const translation_unit& tu)
11892{return lookup_function_type(*t, tu);}
11893
11894/// Lookup a type in a translation unit.
11895///
11896/// @param fqn the fully qualified name of the type to lookup.
11897///
11898/// @param tu the translation unit to consider.
11899///
11900/// @return the declaration of the type if found, NULL otherwise.
11901const type_base_sptr
11903 const translation_unit& tu)
11904{
11905 type_base_sptr result;
11906 ((result = lookup_typedef_type(fqn, tu))
11907 || (result = lookup_class_type(fqn, tu))
11908 || (result = lookup_union_type(fqn, tu))
11909 || (result = lookup_enum_type(fqn, tu))
11910 || (result = lookup_qualified_type(fqn, tu))
11911 || (result = lookup_pointer_type(fqn, tu))
11912 || (result = lookup_reference_type(fqn, tu))
11913 || (result = lookup_array_type(fqn, tu))
11914 || (result = lookup_function_type(fqn, tu))
11915 || (result = lookup_basic_type(fqn, tu)));
11916
11917 return result;
11918}
11919
11920/// Lookup a type in a translation unit, starting from the global
11921/// namespace.
11922///
11923/// @param fqn the fully qualified name of the type to lookup.
11924///
11925/// @param tu the translation unit to consider.
11926///
11927/// @return the declaration of the type if found, NULL otherwise.
11928type_base_sptr
11929lookup_type(const string& fqn, const translation_unit& tu)
11930{
11931 const environment&env = tu.get_environment();
11932 interned_string ifqn = env.intern(fqn);
11933 return lookup_type(ifqn, tu);
11934}
11935
11936/// Lookup a type from a translation unit.
11937///
11938/// @param fqn the components of the fully qualified name of the node
11939/// to look up.
11940///
11941/// @param tu the translation unit to perform lookup from.
11942///
11943/// @return the declaration of the IR node found, NULL otherwise.
11944const type_base_sptr
11945lookup_type(const type_base_sptr type,
11946 const translation_unit& tu)
11947{
11948 interned_string type_name = get_type_name(type);
11949 return lookup_type(type_name, tu);
11950}
11951
11952/// Lookup a type in a scope.
11953///
11954/// This is really slow as it walks the member types of the scope in
11955/// sequence to find the type with a given name.
11956///
11957/// If possible, users should prefer looking up types from the
11958/// enclosing translation unit or even ABI corpus because both the
11959/// translation unit and the corpus have a map of type, indexed by
11960/// their name. Looking up a type from those maps is thus much
11961/// faster.
11962///
11963/// @param fqn the fully qualified name of the type to lookup.
11964///
11965/// @param skope the scope to look into.
11966///
11967/// @return the declaration of the type if found, NULL otherwise.
11968const type_base_sptr
11969lookup_type_in_scope(const string& fqn,
11970 const scope_decl_sptr& skope)
11971{
11972 list<string> comps;
11973 fqn_to_components(fqn, comps);
11974 return lookup_type_in_scope(comps, skope);
11975}
11976
11977/// Lookup a @ref var_decl in a scope.
11978///
11979/// @param fqn the fuly qualified name of the @var_decl to lookup.
11980///
11981/// @param skope the scope to look into.
11982///
11983/// @return the declaration of the @ref var_decl if found, NULL
11984/// otherwise.
11985const decl_base_sptr
11987 const scope_decl_sptr& skope)
11988{
11989 list<string> comps;
11990 fqn_to_components(fqn, comps);
11991 return lookup_var_decl_in_scope(comps, skope);
11992}
11993
11994/// A generic function (template) to get the name of a node, whatever
11995/// node it is. This has to be specialized for the kind of node we
11996/// want.
11997///
11998/// Note that a node is a member of a scope.
11999///
12000/// @tparam NodeKind the kind of node to consider.
12001///
12002/// @param node the node to get the name from.
12003///
12004/// @return the name of the node.
12005template<typename NodeKind>
12006static const interned_string&
12007get_node_name(shared_ptr<NodeKind> node);
12008
12009/// Gets the name of a class_decl node.
12010///
12011/// @param node the decl_base node to get the name from.
12012///
12013/// @return the name of the node.
12014template<>
12015const interned_string&
12017{return node->get_name();}
12018
12019/// Gets the name of a type_base node.
12020///
12021/// @param node the type_base node to get the name from.
12022///
12023/// @return the name of the node.
12024template<>
12025const interned_string&
12026get_node_name(type_base_sptr node)
12027{return get_type_declaration(node)->get_name();}
12028
12029/// Gets the name of a var_decl node.
12030///
12031/// @param node the var_decl node to get the name from.
12032///
12033/// @return the name of the node.
12034template<>
12035const interned_string&
12037{return node->get_name();}
12038
12039/// Generic function to get the declaration of a given node, whatever
12040/// it is. There has to be specializations for the kind of the nodes
12041/// we want to support.
12042///
12043/// @tparam NodeKind the type of the node we are looking at.
12044///
12045/// @return the declaration.
12046template<typename NodeKind>
12047static decl_base_sptr
12048convert_node_to_decl(shared_ptr<NodeKind> node);
12049
12050/// Lookup a node in a given scope.
12051///
12052/// @tparam the type of the node to lookup.
12053///
12054/// @param fqn the components of the fully qualified name of the node
12055/// to lookup.
12056///
12057/// @param skope the scope to look into.
12058///
12059/// @return the declaration of the looked up node, or NULL if it
12060/// wasn't found.
12061template<typename NodeKind>
12062static const type_or_decl_base_sptr
12063lookup_node_in_scope(const list<string>& fqn,
12064 const scope_decl_sptr& skope)
12065{
12066 type_or_decl_base_sptr resulting_decl;
12067 shared_ptr<NodeKind> node;
12068 bool it_is_last = false;
12069 scope_decl_sptr cur_scope = skope, new_scope, scope;
12070
12071 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
12072 {
12073 new_scope.reset();
12074 it_is_last = iterator_is_last(fqn, c);
12075 for (scope_decl::declarations::const_iterator m =
12076 cur_scope->get_member_decls().begin();
12077 m != cur_scope->get_member_decls().end();
12078 ++m)
12079 {
12080 if (!it_is_last)
12081 {
12082 // looking for a scope
12083 scope = dynamic_pointer_cast<scope_decl>(*m);
12084 if (scope && scope->get_name() == *c)
12085 {
12086 new_scope = scope;
12087 break;
12088 }
12089 }
12090 else
12091 {
12092 //looking for a final type.
12093 node = dynamic_pointer_cast<NodeKind>(*m);
12094 if (node && get_node_name(node) == *c)
12095 {
12096 if (class_decl_sptr cl =
12097 dynamic_pointer_cast<class_decl>(node))
12098 if (cl->get_is_declaration_only()
12099 && !cl->get_definition_of_declaration())
12100 continue;
12101 resulting_decl = node;
12102 break;
12103 }
12104 }
12105 }
12106 if (!new_scope && !resulting_decl)
12107 return decl_base_sptr();
12108 cur_scope = new_scope;
12109 }
12110 ABG_ASSERT(resulting_decl);
12111 return resulting_decl;
12112}
12113
12114/// lookup a type in a scope.
12115///
12116///
12117/// This is really slow as it walks the member types of the scope in
12118/// sequence to find the type with a given name.
12119///
12120/// If possible, users should prefer looking up types from the
12121/// enclosing translation unit or even ABI corpus because both the
12122/// translation unit and the corpus have a map of type, indexed by
12123/// their name. Looking up a type from those maps is thus much
12124/// faster.
12125///
12126/// @param comps the components of the fully qualified name of the
12127/// type to lookup.
12128///
12129/// @param skope the scope to look into.
12130///
12131/// @return the declaration of the type found.
12132const type_base_sptr
12133lookup_type_in_scope(const list<string>& comps,
12134 const scope_decl_sptr& scope)
12135{return is_type(lookup_node_in_scope<type_base>(comps, scope));}
12136
12137/// lookup a type in a scope.
12138///
12139/// This is really slow as it walks the member types of the scope in
12140/// sequence to find the type with a given name.
12141///
12142/// If possible, users should prefer looking up types from the
12143/// enclosing translation unit or even ABI corpus because both the
12144/// translation unit and the corpus have a map of type, indexed by
12145/// their name. Looking up a type from those maps is thus much
12146/// faster.
12147///
12148/// @param type the type to look for.
12149///
12150/// @param access_path a vector of scopes the path of scopes to follow
12151/// before reaching the scope into which to look for @p type. Note
12152/// that the deepest scope (the one immediately containing @p type) is
12153/// at index 0 of this vector, and the top-most scope is the last
12154/// element of the vector.
12155///
12156/// @param scope the top-most scope into which to look for @p type.
12157///
12158/// @return the scope found in @p scope, or NULL if it wasn't found.
12159static const type_base_sptr
12161 const vector<scope_decl*>& access_path,
12162 const scope_decl* scope)
12163{
12164 vector<scope_decl*> a = access_path;
12165 type_base_sptr result;
12166
12167 scope_decl* first_scope = 0;
12168 if (!a.empty())
12169 {
12170 first_scope = a.back();
12171 ABG_ASSERT(first_scope->get_name() == scope->get_name());
12172 a.pop_back();
12173 }
12174
12175 if (a.empty())
12176 {
12177 interned_string n = get_type_name(type, false);
12178 for (scope_decl::declarations::const_iterator i =
12179 scope->get_member_decls().begin();
12180 i != scope->get_member_decls().end();
12181 ++i)
12182 if (is_type(*i) && (*i)->get_name() == n)
12183 {
12184 result = is_type(*i);
12185 break;
12186 }
12187 }
12188 else
12189 {
12190 first_scope = a.back();
12191 interned_string scope_name, cur_scope_name = first_scope->get_name();
12192 for (scope_decl::scopes::const_iterator i =
12193 scope->get_member_scopes().begin();
12194 i != scope->get_member_scopes().end();
12195 ++i)
12196 {
12197 scope_name = (*i)->get_name();
12198 if (scope_name == cur_scope_name)
12199 {
12200 result = lookup_type_in_scope(type, a, (*i).get());
12201 break;
12202 }
12203 }
12204 }
12205 return result;
12206}
12207
12208/// lookup a type in a scope.
12209///
12210/// This is really slow as it walks the member types of the scope in
12211/// sequence to find the type with a given name.
12212///
12213/// If possible, users should prefer looking up types from the
12214/// enclosing translation unit or even ABI corpus because both the
12215/// translation unit and the corpus have a map of type, indexed by
12216/// their name. Looking up a type from those maps is thus much
12217/// faster.
12218///
12219/// @param type the type to look for.
12220///
12221/// @param scope the top-most scope into which to look for @p type.
12222///
12223/// @return the scope found in @p scope, or NULL if it wasn't found.
12224static const type_base_sptr
12225lookup_type_in_scope(const type_base_sptr type,
12226 const scope_decl* scope)
12227{
12228 if (!type || is_function_type(type))
12229 return type_base_sptr();
12230
12231 decl_base_sptr type_decl = get_type_declaration(type);
12232 ABG_ASSERT(type_decl);
12233 vector<scope_decl*> access_path;
12234 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
12235 {
12236 access_path.push_back(s);
12237 if (is_global_scope(s))
12238 break;
12239 }
12240 return lookup_type_in_scope(*type, access_path, scope);
12241}
12242
12243/// Lookup a type from a translation unit by walking the scopes of the
12244/// translation unit in sequence and looking into them.
12245///
12246/// This is really slow as it walks the member types of the scopes in
12247/// sequence to find the type with a given name.
12248///
12249/// If possible, users should prefer looking up types from the
12250/// translation unit or even ABI corpus in a more direct way, by using
12251/// the lookup_type() functins.
12252///
12253///
12254/// This is because both the translation unit and the corpus have a
12255/// map of types, indexed by their name. Looking up a type from those
12256/// maps is thus much faster. @param fqn the components of the fully
12257/// qualified name of the node to look up.
12258///
12259/// @param tu the translation unit to perform lookup from.
12260///
12261/// @return the declaration of the IR node found, NULL otherwise.
12262const type_base_sptr
12263lookup_type_through_scopes(const type_base_sptr type,
12264 const translation_unit& tu)
12265{
12266 if (function_type_sptr fn_type = is_function_type(type))
12267 return lookup_function_type(fn_type, tu);
12268 return lookup_type_in_scope(type, tu.get_global_scope().get());
12269}
12270
12271/// lookup a var_decl in a scope.
12272///
12273/// @param comps the components of the fully qualified name of the
12274/// var_decl to lookup.
12275///
12276/// @param skope the scope to look into.
12277const decl_base_sptr
12278lookup_var_decl_in_scope(const std::list<string>& comps,
12279 const scope_decl_sptr& skope)
12280{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
12281
12282/// Lookup an IR node from a translation unit.
12283///
12284/// @tparam NodeKind the type of the IR node to lookup from the
12285/// translation unit.
12286///
12287/// @param fqn the components of the fully qualified name of the node
12288/// to look up.
12289///
12290/// @param tu the translation unit to perform lookup from.
12291///
12292/// @return the declaration of the IR node found, NULL otherwise.
12293template<typename NodeKind>
12294static const type_or_decl_base_sptr
12295lookup_node_in_translation_unit(const list<string>& fqn,
12296 const translation_unit& tu)
12297{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
12298
12299/// Lookup a type from a translation unit by walking its scopes in
12300/// sequence and by looking into them.
12301///
12302/// This is much slower than using the lookup_type() function.
12303///
12304/// @param fqn the components of the fully qualified name of the node
12305/// to look up.
12306///
12307/// @param tu the translation unit to perform lookup from.
12308///
12309/// @return the declaration of the IR node found, NULL otherwise.
12310type_base_sptr
12311lookup_type_through_scopes(const list<string>& fqn,
12312 const translation_unit& tu)
12313{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
12314
12315
12316/// Lookup a class type from a translation unit by walking its scopes
12317/// in sequence and by looking into them.
12318///
12319/// This is much slower than using the lookup_class_type() function
12320/// because it walks all the scopes of the translation unit in
12321/// sequence and lookup the types to find one that has a given name.
12322///
12323/// @param fqn the components of the fully qualified name of the class
12324/// type node to look up.
12325///
12326/// @param tu the translation unit to perform lookup from.
12327///
12328/// @return the declaration of the class type IR node found, NULL
12329/// otherwise.
12331lookup_class_type_through_scopes(const list<string>& fqn,
12332 const translation_unit& tu)
12333{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
12334
12335/// Lookup a basic type from all the translation units of a given
12336/// corpus.
12337///
12338/// @param fqn the components of the fully qualified name of the basic
12339/// type node to look up.
12340///
12341/// @param tu the translation unit to perform lookup from.
12342///
12343/// @return the declaration of the basic type IR node found, NULL
12344/// otherwise.
12345static type_decl_sptr
12346lookup_basic_type_through_translation_units(const interned_string& type_name,
12347 const corpus& abi_corpus)
12348{
12349 type_decl_sptr result;
12350
12351 for (translation_units::const_iterator tu =
12352 abi_corpus.get_translation_units().begin();
12353 tu != abi_corpus.get_translation_units().end();
12354 ++tu)
12355 if ((result = lookup_basic_type(type_name, **tu)))
12356 break;
12357
12358 return result;
12359}
12360
12361/// Lookup a union type from all the translation units of a given
12362/// corpus.
12363///
12364/// @param fqn the components of the fully qualified name of the union
12365/// type node to look up.
12366///
12367/// @param tu the translation unit to perform lookup from.
12368///
12369/// @return the declaration of the union type IR node found, NULL
12370/// otherwise.
12371static union_decl_sptr
12372lookup_union_type_through_translation_units(const interned_string& type_name,
12373 const corpus & abi_corpus)
12374{
12375 union_decl_sptr result;
12376
12377 for (translation_units::const_iterator tu =
12378 abi_corpus.get_translation_units().begin();
12379 tu != abi_corpus.get_translation_units().end();
12380 ++tu)
12381 if ((result = lookup_union_type(type_name, **tu)))
12382 break;
12383
12384 return result;
12385}
12386
12387/// Lookup an enum type from all the translation units of a given
12388/// corpus.
12389///
12390/// @param fqn the components of the fully qualified name of the enum
12391/// type node to look up.
12392///
12393/// @param tu the translation unit to perform lookup from.
12394///
12395/// @return the declaration of the enum type IR node found, NULL
12396/// otherwise.
12398lookup_enum_type_through_translation_units(const interned_string& type_name,
12399 const corpus & abi_corpus)
12400{
12401 enum_type_decl_sptr result;
12402
12403 for (translation_units::const_iterator tu =
12404 abi_corpus.get_translation_units().begin();
12405 tu != abi_corpus.get_translation_units().end();
12406 ++tu)
12407 if ((result = lookup_enum_type(type_name, **tu)))
12408 break;
12409
12410 return result;
12411}
12412
12413/// Lookup a typedef type definition in all the translation units of a
12414/// given ABI corpus.
12415///
12416/// @param @param qn the fully qualified name of the typedef type to lookup.
12417///
12418/// @param abi_corpus the ABI corpus which to look the type up in.
12419///
12420/// @return the type definition if any was found, or a NULL pointer.
12421static typedef_decl_sptr
12422lookup_typedef_type_through_translation_units(const interned_string& type_name,
12423 const corpus & abi_corpus)
12424{
12425 typedef_decl_sptr result;
12426
12427 for (translation_units::const_iterator tu =
12428 abi_corpus.get_translation_units().begin();
12429 tu != abi_corpus.get_translation_units().end();
12430 ++tu)
12431 if ((result = lookup_typedef_type(type_name, **tu)))
12432 break;
12433
12434 return result;
12435}
12436
12437/// Lookup a qualified type definition in all the translation units of a
12438/// given ABI corpus.
12439///
12440/// @param @param qn the fully qualified name of the qualified type to
12441/// lookup.
12442///
12443/// @param abi_corpus the ABI corpus which to look the type up in.
12444///
12445/// @return the type definition if any was found, or a NULL pointer.
12446static qualified_type_def_sptr
12447lookup_qualified_type_through_translation_units(const interned_string& t_name,
12448 const corpus & abi_corpus)
12449{
12450 qualified_type_def_sptr result;
12451
12452 for (translation_units::const_iterator tu =
12453 abi_corpus.get_translation_units().begin();
12454 tu != abi_corpus.get_translation_units().end();
12455 ++tu)
12456 if ((result = lookup_qualified_type(t_name, **tu)))
12457 break;
12458
12459 return result;
12460}
12461
12462/// Lookup a pointer type definition in all the translation units of a
12463/// given ABI corpus.
12464///
12465/// @param @param qn the fully qualified name of the pointer type to
12466/// lookup.
12467///
12468/// @param abi_corpus the ABI corpus which to look the type up in.
12469///
12470/// @return the type definition if any was found, or a NULL pointer.
12472lookup_pointer_type_through_translation_units(const interned_string& type_name,
12473 const corpus & abi_corpus)
12474{
12475 pointer_type_def_sptr result;
12476
12477 for (translation_units::const_iterator tu =
12478 abi_corpus.get_translation_units().begin();
12479 tu != abi_corpus.get_translation_units().end();
12480 ++tu)
12481 if ((result = lookup_pointer_type(type_name, **tu)))
12482 break;
12483
12484 return result;
12485}
12486
12487/// Lookup a reference type definition in all the translation units of a
12488/// given ABI corpus.
12489///
12490/// @param @param qn the fully qualified name of the reference type to
12491/// lookup.
12492///
12493/// @param abi_corpus the ABI corpus which to look the type up in.
12494///
12495/// @return the type definition if any was found, or a NULL pointer.
12497lookup_reference_type_through_translation_units(const interned_string& t_name,
12498 const corpus & abi_corpus)
12499{
12501
12502 for (translation_units::const_iterator tu =
12503 abi_corpus.get_translation_units().begin();
12504 tu != abi_corpus.get_translation_units().end();
12505 ++tu)
12506 if ((result = lookup_reference_type(t_name, **tu)))
12507 break;
12508
12509 return result;
12510}
12511
12512/// Lookup a array type definition in all the translation units of a
12513/// given ABI corpus.
12514///
12515/// @param @param qn the fully qualified name of the array type to
12516/// lookup.
12517///
12518/// @param abi_corpus the ABI corpus which to look the type up in.
12519///
12520/// @return the type definition if any was found, or a NULL pointer.
12522lookup_array_type_through_translation_units(const interned_string& type_name,
12523 const corpus & abi_corpus)
12524{
12525 array_type_def_sptr result;
12526
12527 for (translation_units::const_iterator tu =
12528 abi_corpus.get_translation_units().begin();
12529 tu != abi_corpus.get_translation_units().end();
12530 ++tu)
12531 if ((result = lookup_array_type(type_name, **tu)))
12532 break;
12533
12534 return result;
12535}
12536
12537/// Lookup a function type definition in all the translation units of
12538/// a given ABI corpus.
12539///
12540/// @param @param qn the fully qualified name of the function type to
12541/// lookup.
12542///
12543/// @param abi_corpus the ABI corpus which to look the type up in.
12544///
12545/// @return the type definition if any was found, or a NULL pointer.
12546static function_type_sptr
12547lookup_function_type_through_translation_units(const interned_string& type_name,
12548 const corpus & abi_corpus)
12549{
12550 function_type_sptr result;
12551
12552 for (translation_units::const_iterator tu =
12553 abi_corpus.get_translation_units().begin();
12554 tu != abi_corpus.get_translation_units().end();
12555 ++tu)
12556 if ((result = lookup_function_type(type_name, **tu)))
12557 break;
12558
12559 return result;
12560}
12561
12562/// Lookup a type definition in all the translation units of a given
12563/// ABI corpus.
12564///
12565/// @param @param qn the fully qualified name of the type to lookup.
12566///
12567/// @param abi_corpus the ABI corpus which to look the type up in.
12568///
12569/// @return the type definition if any was found, or a NULL pointer.
12570type_base_sptr
12572 const corpus& abi_corpus)
12573{
12574 type_base_sptr result;
12575
12576 for (translation_units::const_iterator tu =
12577 abi_corpus.get_translation_units().begin();
12578 tu != abi_corpus.get_translation_units().end();
12579 ++tu)
12580 if ((result = lookup_type(qn, **tu)))
12581 break;
12582
12583 return result;
12584}
12585
12586/// Lookup a type from a given translation unit present in a give corpus.
12587///
12588/// @param type_name the name of the type to look for.
12589///
12590/// @parm tu_path the path of the translation unit to consider.
12591///
12592/// @param corp the corpus to consider.
12593///
12594/// @return the resulting type, if any.
12595type_base_sptr
12597 const string& tu_path,
12598 const corpus& corp)
12599{
12600 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
12601 if (i == corp.priv_->path_tu_map.end())
12602 return type_base_sptr();
12603
12604 translation_unit_sptr tu = i->second;
12605 ABG_ASSERT(tu);
12606
12607 type_base_sptr t = lookup_type(type_name, *tu);
12608 return t;
12609}
12610
12611/// Look into an ABI corpus for a function type.
12612///
12613/// @param fn_type the function type to be looked for in the ABI
12614/// corpus.
12615///
12616/// @param corpus the ABI corpus into which to look for the function
12617/// type.
12618///
12619/// @return the function type found in the corpus.
12622 const corpus& corpus)
12623{
12624 ABG_ASSERT(fn_t);
12625
12626 function_type_sptr result;
12627
12628 if ((result = lookup_function_type(fn_t, corpus)))
12629 return result;
12630
12631 for (translation_units::const_iterator i =
12632 corpus.get_translation_units().begin();
12633 i != corpus.get_translation_units().end();
12634 ++i)
12636 **i)))
12637 return result;
12638
12639 return result;
12640}
12641
12642/// Look into a given corpus to find a type which has the same
12643/// qualified name as a giventype.
12644///
12645/// If the per-corpus type map is non-empty (because the corpus allows
12646/// the One Definition Rule) then the type islooked up in that
12647/// per-corpus type map. Otherwise, the type is looked-up in each
12648/// translation unit.
12649///
12650/// @param t the type which has the same qualified name as the type we
12651/// are looking for.
12652///
12653/// @param corp the ABI corpus to look into for the type.
12655lookup_basic_type(const type_decl& t, const corpus& corp)
12656{return lookup_basic_type(t.get_name(), corp);}
12657
12658/// Look into a given corpus to find a basic type which has a given
12659/// qualified name.
12660///
12661/// If the per-corpus type map is non-empty (because the corpus allows
12662/// the One Definition Rule) then the type islooked up in that
12663/// per-corpus type map. Otherwise, the type is looked-up in each
12664/// translation unit.
12665///
12666/// @param qualified_name the qualified name of the basic type to look
12667/// for.
12668///
12669/// @param corp the corpus to look into.
12671lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
12672{
12674 type_decl_sptr result;
12675
12676 if (!m.empty())
12677 result = lookup_type_in_map<type_decl>(qualified_name, m);
12678 else
12679 result = lookup_basic_type_through_translation_units(qualified_name, corp);
12680
12681 return result;
12682}
12683
12684/// Lookup a @ref type_decl type from a given corpus, by its location.
12685///
12686/// @param loc the location to consider.
12687///
12688/// @param corp the corpus to consider.
12689///
12690/// @return the resulting basic type, if any.
12693 const corpus &corp)
12694{
12697 type_decl_sptr result;
12698
12699 result = lookup_type_in_map<type_decl>(loc, m);
12700
12701 return result;
12702}
12703
12704/// Lookup a @ref type_decl type from a given corpus, by its location.
12705///
12706/// @param loc the location to consider.
12707///
12708/// @param corp the corpus to consider.
12709///
12710/// @return the resulting basic type, if any.
12712lookup_basic_type_per_location(const string &loc, const corpus &corp)
12713{
12714 const environment& env = corp.get_environment();
12715 return lookup_basic_type_per_location(env.intern(loc), corp);
12716}
12717
12718/// Look into a given corpus to find a basic type which has a given
12719/// qualified name.
12720///
12721/// If the per-corpus type map is non-empty (because the corpus allows
12722/// the One Definition Rule) then the type islooked up in that
12723/// per-corpus type map. Otherwise, the type is looked-up in each
12724/// translation unit.
12725///
12726/// @param qualified_name the qualified name of the basic type to look
12727/// for.
12728///
12729/// @param corp the corpus to look into.
12731lookup_basic_type(const string& qualified_name, const corpus& corp)
12732{
12733 return lookup_basic_type(corp.get_environment().intern(qualified_name),
12734 corp);
12735}
12736
12737/// Look into a given corpus to find a class type which has the same
12738/// qualified name as a given type.
12739///
12740/// If the per-corpus type map is non-empty (because the corpus allows
12741/// the One Definition Rule) then the type islooked up in that
12742/// per-corpus type map. Otherwise, the type is looked-up in each
12743/// translation unit.
12744///
12745/// @param t the class decl type which has the same qualified name as
12746/// the type we are looking for.
12747///
12748/// @param corp the corpus to look into.
12751{
12753 return lookup_class_type(s, corp);
12754}
12755
12756/// Look into a given corpus to find a class type which has a given
12757/// qualified name.
12758///
12759/// If the per-corpus type map is non-empty (because the corpus allows
12760/// the One Definition Rule) then the type islooked up in that
12761/// per-corpus type map. Otherwise, the type is looked-up in each
12762/// translation unit.
12763///
12764/// @param qualified_name the qualified name of the type to look for.
12765///
12766/// @param corp the corpus to look into.
12768lookup_class_type(const string& qualified_name, const corpus& corp)
12769{
12770 interned_string s = corp.get_environment().intern(qualified_name);
12771 return lookup_class_type(s, corp);
12772}
12773
12774/// Look into a given corpus to find a class type which has a given
12775/// qualified name.
12776///
12777/// If the per-corpus type map is non-empty (because the corpus allows
12778/// the One Definition Rule) then the type islooked up in that
12779/// per-corpus type map. Otherwise, the type is looked-up in each
12780/// translation unit.
12781///
12782/// @param qualified_name the qualified name of the type to look for.
12783///
12784/// @param corp the corpus to look into.
12786lookup_class_type(const interned_string& qualified_name, const corpus& corp)
12787{
12789
12790 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
12791
12792 return result;
12793}
12794
12795/// Look into a given corpus to find the class type*s* that have a
12796/// given qualified name.
12797///
12798/// @param qualified_name the qualified name of the type to look for.
12799///
12800/// @param corp the corpus to look into.
12801///
12802/// @return the vector of class types named @p qualified_name.
12804lookup_class_types(const interned_string& qualified_name, const corpus& corp)
12805{
12807
12808 return lookup_types_in_map(qualified_name, m);
12809}
12810
12811/// Look into a given corpus to find the class type*s* that have a
12812/// given qualified name and that are declaration-only.
12813///
12814/// @param qualified_name the qualified name of the type to look for.
12815///
12816/// @param corp the corpus to look into.
12817///
12818/// @param result the vector of decl-only class types named @p
12819/// qualified_name. This is populated iff the function returns true.
12820///
12821/// @return true iff @p result was populated with the decl-only
12822/// classes named @p qualified_name.
12823bool
12825 const corpus& corp,
12826 type_base_wptrs_type& result)
12827{
12829
12830 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
12831 if (!v)
12832 return false;
12833
12834 for (auto type : *v)
12835 {
12836 type_base_sptr t(type);
12838 if (c->get_is_declaration_only()
12839 && !c->get_definition_of_declaration())
12840 result.push_back(type);
12841 }
12842
12843 return !result.empty();
12844}
12845
12846/// Look into a given corpus to find the union type*s* that have a
12847/// given qualified name.
12848///
12849/// @param qualified_name the qualified name of the type to look for.
12850///
12851/// @param corp the corpus to look into.
12852///
12853/// @return the vector of union types named @p qualified_name.
12855lookup_union_types(const interned_string& qualified_name, const corpus& corp)
12856{
12858
12859 return lookup_types_in_map(qualified_name, m);
12860}
12861
12862/// Look into a given corpus to find the class type*s* that have a
12863/// given qualified name.
12864///
12865/// @param qualified_name the qualified name of the type to look for.
12866///
12867/// @param corp the corpus to look into.
12868///
12869/// @return the vector of class types which name is @p qualified_name.
12871lookup_class_types(const string& qualified_name, const corpus& corp)
12872{
12873 interned_string s = corp.get_environment().intern(qualified_name);
12874 return lookup_class_types(s, corp);
12875}
12876
12877/// Look into a given corpus to find the union types that have a given
12878/// qualified name.
12879///
12880/// @param qualified_name the qualified name of the type to look for.
12881///
12882/// @param corp the corpus to look into.
12883///
12884/// @return the vector of union types which name is @p qualified_name.
12886lookup_union_types(const string& qualified_name, const corpus& corp)
12887{
12888 interned_string s = corp.get_environment().intern(qualified_name);
12889 return lookup_union_types(s, corp);
12890}
12891
12892/// Look up a @ref class_decl from a given corpus by its location.
12893///
12894/// @param loc the location to consider.
12895///
12896/// @param corp the corpus to consider.
12897///
12898/// @return the resulting class decl, if any.
12901 const corpus& corp)
12902{
12905 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
12906
12907 return result;
12908}
12909
12910/// Look up a @ref class_decl from a given corpus by its location.
12911///
12912/// @param loc the location to consider.
12913///
12914/// @param corp the corpus to consider.
12915///
12916/// @return the resulting class decl, if any.
12918lookup_class_type_per_location(const string &loc, const corpus &corp)
12919{
12920 const environment& env = corp.get_environment();
12921 return lookup_class_type_per_location(env.intern(loc), corp);
12922}
12923
12924/// Look into a given corpus to find a union type which has a given
12925/// qualified name.
12926///
12927/// If the per-corpus type map is non-empty (because the corpus allows
12928/// the One Definition Rule) then the type islooked up in that
12929/// per-corpus type map. Otherwise, the type is looked-up in each
12930/// translation unit.
12931///
12932/// @param qualified_name the qualified name of the type to look for.
12933///
12934/// @param corp the corpus to look into.
12935union_decl_sptr
12936lookup_union_type(const interned_string& type_name, const corpus& corp)
12937{
12939
12940 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
12941 if (!result)
12942 result = lookup_union_type_through_translation_units(type_name, corp);
12943
12944 return result;
12945}
12946
12947/// Look into a given corpus to find a union type which has a given
12948/// qualified name.
12949///
12950/// If the per-corpus type map is non-empty (because the corpus allows
12951/// the One Definition Rule) then the type islooked up in that
12952/// per-corpus type map. Otherwise, the type is looked-up in each
12953/// translation unit.
12954///
12955/// @param qualified_name the qualified name of the type to look for.
12956///
12957/// @param corp the corpus to look into.
12958union_decl_sptr
12959lookup_union_type(const string& type_name, const corpus& corp)
12960{
12961 interned_string s = corp.get_environment().intern(type_name);
12962 return lookup_union_type(s, corp);
12963}
12964
12965/// Look into a given corpus to find an enum type which has the same
12966/// qualified name as a given enum type.
12967///
12968/// If the per-corpus type map is non-empty (because the corpus allows
12969/// the One Definition Rule) then the type islooked up in that
12970/// per-corpus type map. Otherwise, the type is looked-up in each
12971/// translation unit.
12972///
12973/// @param t the enum type which has the same qualified name as the
12974/// type we are looking for.
12975///
12976/// @param corp the corpus to look into.
12979{
12981 return lookup_enum_type(s, corp);
12982}
12983
12984/// Look into a given corpus to find an enum type which has a given
12985/// qualified name.
12986///
12987/// If the per-corpus type map is non-empty (because the corpus allows
12988/// the One Definition Rule) then the type islooked up in that
12989/// per-corpus type map. Otherwise, the type is looked-up in each
12990/// translation unit.
12991///
12992/// @param qualified_name the qualified name of the enum type to look
12993/// for.
12994///
12995/// @param corp the corpus to look into.
12997lookup_enum_type(const string& qualified_name, const corpus& corp)
12998{
12999 interned_string s = corp.get_environment().intern(qualified_name);
13000 return lookup_enum_type(s, corp);
13001}
13002
13003/// Look into a given corpus to find an enum type which has a given
13004/// qualified name.
13005///
13006/// If the per-corpus type map is non-empty (because the corpus allows
13007/// the One Definition Rule) then the type islooked up in that
13008/// per-corpus type map. Otherwise, the type is looked-up in each
13009/// translation unit.
13010///
13011/// @param qualified_name the qualified name of the enum type to look
13012/// for.
13013///
13014/// @param corp the corpus to look into.
13016lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
13017{
13019
13020 enum_type_decl_sptr result =
13021 lookup_type_in_map<enum_type_decl>(qualified_name, m);
13022 if (!result)
13023 result = lookup_enum_type_through_translation_units(qualified_name, corp);
13024
13025 return result;
13026}
13027
13028/// Look into a given corpus to find the enum type*s* that have a
13029/// given qualified name.
13030///
13031/// @param qualified_name the qualified name of the type to look for.
13032///
13033/// @param corp the corpus to look into.
13034///
13035/// @return the vector of enum types that which name is @p qualified_name.
13037lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
13038{
13040
13041 return lookup_types_in_map(qualified_name, m);
13042}
13043
13044/// Look into a given corpus to find the enum type*s* that have a
13045/// given qualified name.
13046///
13047/// @param qualified_name the qualified name of the type to look for.
13048///
13049/// @param corp the corpus to look into.
13050///
13051/// @return the vector of enum types that which name is @p qualified_name.
13053lookup_enum_types(const string& qualified_name, const corpus& corp)
13054{
13055 interned_string s = corp.get_environment().intern(qualified_name);
13056 return lookup_enum_types(s, corp);
13057}
13058
13059/// Look up an @ref enum_type_decl from a given corpus, by its location.
13060///
13061/// @param loc the location to consider.
13062///
13063/// @param corp the corpus to look the type from.
13064///
13065/// @return the resulting enum type, if any.
13068{
13071 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
13072
13073 return result;
13074}
13075
13076/// Look up an @ref enum_type_decl from a given corpus, by its location.
13077///
13078/// @param loc the location to consider.
13079///
13080/// @param corp the corpus to look the type from.
13081///
13082/// @return the resulting enum type, if any.
13084lookup_enum_type_per_location(const string &loc, const corpus &corp)
13085{
13086 const environment& env = corp.get_environment();
13087 return lookup_enum_type_per_location(env.intern(loc), corp);
13088}
13089
13090/// Look into a given corpus to find a typedef type which has the
13091/// same qualified name as a given typedef type.
13092///
13093/// If the per-corpus type map is non-empty (because the corpus allows
13094/// the One Definition Rule) then the type islooked up in that
13095/// per-corpus type map. Otherwise, the type is looked-up in each
13096/// translation unit.
13097///
13098/// @param t the typedef type which has the same qualified name as the
13099/// typedef type we are looking for.
13100///
13101/// @param corp the corpus to look into.
13104{
13106 return lookup_typedef_type(s, corp);
13107}
13108
13109/// Look into a given corpus to find a typedef type which has the
13110/// same qualified name as a given typedef type.
13111///
13112/// If the per-corpus type map is non-empty (because the corpus allows
13113/// the One Definition Rule) then the type islooked up in that
13114/// per-corpus type map. Otherwise, the type is looked-up in each
13115/// translation unit.
13116///
13117/// @param t the typedef type which has the same qualified name as the
13118/// typedef type we are looking for.
13119///
13120/// @param corp the corpus to look into.
13122lookup_typedef_type(const string& qualified_name, const corpus& corp)
13123{
13124 interned_string s = corp.get_environment().intern(qualified_name);
13125 return lookup_typedef_type(s, corp);
13126}
13127
13128/// Look into a given corpus to find a typedef type which has a
13129/// given qualified name.
13130///
13131/// If the per-corpus type map is non-empty (because the corpus allows
13132/// the One Definition Rule) then the type islooked up in that
13133/// per-corpus type map. Otherwise, the type is looked-up in each
13134/// translation unit.
13135///
13136/// @param qualified_name the qualified name of the typedef type to
13137/// look for.
13138///
13139/// @param corp the corpus to look into.
13141lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
13142{
13144
13145 typedef_decl_sptr result =
13146 lookup_type_in_map<typedef_decl>(qualified_name, m);
13147 if (!result)
13148 result = lookup_typedef_type_through_translation_units(qualified_name,
13149 corp);
13150
13151 return result;
13152}
13153
13154/// Lookup a @ref typedef_decl from a corpus, by its location.
13155///
13156/// @param loc the location to consider.
13157///
13158/// @param corp the corpus to consider.
13159///
13160/// @return the typedef_decl found, if any.
13163{
13166 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
13167
13168 return result;
13169}
13170
13171/// Lookup a @ref typedef_decl from a corpus, by its location.
13172///
13173/// @param loc the location to consider.
13174///
13175/// @param corp the corpus to consider.
13176///
13177/// @return the typedef_decl found, if any.
13179lookup_typedef_type_per_location(const string &loc, const corpus &corp)
13180{
13181 const environment& env = corp.get_environment();
13182 return lookup_typedef_type_per_location(env.intern(loc), corp);
13183}
13184
13185/// Look into a corpus to find a class, union or typedef type which
13186/// has a given qualified name.
13187///
13188/// If the per-corpus type map is non-empty (because the corpus allows
13189/// the One Definition Rule) then the type islooked up in that
13190/// per-corpus type map. Otherwise, the type is looked-up in each
13191/// translation unit.
13192///
13193/// @param qualified_name the name of the type to find.
13194///
13195/// @param corp the corpus to look into.
13196///
13197/// @return the typedef or class type found.
13198type_base_sptr
13199lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
13200{
13201 type_base_sptr result = lookup_class_type(qualified_name, corp);
13202 if (!result)
13203 result = lookup_union_type(qualified_name, corp);
13204
13205 if (!result)
13206 result = lookup_typedef_type(qualified_name, corp);
13207 return result;
13208}
13209
13210/// Look into a corpus to find a class, typedef or enum type which has
13211/// a given qualified name.
13212///
13213/// If the per-corpus type map is non-empty (because the corpus allows
13214/// the One Definition Rule) then the type islooked up in that
13215/// per-corpus type map. Otherwise, the type is looked-up in each
13216/// translation unit.
13217///
13218/// @param qualified_name the qualified name of the type to look for.
13219///
13220/// @param corp the corpus to look into.
13221///
13222/// @return the typedef, class or enum type found.
13223type_base_sptr
13224lookup_class_typedef_or_enum_type(const string& qualified_name,
13225 const corpus& corp)
13226{
13227 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
13228 if (!result)
13229 result = lookup_enum_type(qualified_name, corp);
13230
13231 return result;
13232}
13233
13234/// Look into a given corpus to find a qualified type which has the
13235/// same qualified name as a given type.
13236///
13237/// @param t the type which has the same qualified name as the
13238/// qualified type we are looking for.
13239///
13240/// @param corp the corpus to look into.
13241///
13242/// @return the qualified type found.
13243qualified_type_def_sptr
13245{
13247 return lookup_qualified_type(s, corp);
13248}
13249
13250/// Look into a given corpus to find a qualified type which has a
13251/// given qualified name.
13252///
13253/// @param qualified_name the qualified name of the type to look for.
13254///
13255/// @param corp the corpus to look into.
13256///
13257/// @return the type found.
13258qualified_type_def_sptr
13259lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
13260{
13262 corp.get_types().qualified_types();
13263
13264 qualified_type_def_sptr result =
13265 lookup_type_in_map<qualified_type_def>(qualified_name, m);
13266
13267 if (!result)
13268 result = lookup_qualified_type_through_translation_units(qualified_name,
13269 corp);
13270
13271 return result;
13272}
13273
13274/// Look into a given corpus to find a pointer type which has the same
13275/// qualified name as a given pointer type.
13276///
13277/// @param t the pointer type which has the same qualified name as the
13278/// type we are looking for.
13279///
13280/// @param corp the corpus to look into.
13281///
13282/// @return the pointer type found.
13285{
13287 return lookup_pointer_type(s, corp);
13288}
13289
13290/// Look into a given corpus to find a pointer type which has a given
13291/// qualified name.
13292///
13293/// If the per-corpus type map is non-empty (because the corpus allows
13294/// the One Definition Rule) then the type islooked up in that
13295/// per-corpus type map. Otherwise, the type is looked-up in each
13296/// translation unit.
13297///
13298/// @param qualified_name the qualified name of the pointer type to
13299/// look for.
13300///
13301/// @param corp the corpus to look into.
13302///
13303/// @return the pointer type found.
13305lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
13306{
13308
13309 pointer_type_def_sptr result =
13310 lookup_type_in_map<pointer_type_def>(qualified_name, m);
13311 if (!result)
13312 result = lookup_pointer_type_through_translation_units(qualified_name,
13313 corp);
13314
13315 return result;
13316}
13317
13318/// Look into a given corpus to find a reference type which has the
13319/// same qualified name as a given reference type.
13320///
13321/// If the per-corpus type map is non-empty (because the corpus allows
13322/// the One Definition Rule) then the type islooked up in that
13323/// per-corpus type map. Otherwise, the type is looked-up in each
13324/// translation unit.
13325///
13326/// @param t the reference type which has the same qualified name as
13327/// the reference type we are looking for.
13328///
13329/// @param corp the corpus to look into.
13330///
13331/// @return the reference type found.
13334{
13336 return lookup_reference_type(s, corp);
13337}
13338
13339/// Look into a given corpus to find a reference type which has a
13340/// given qualified name.
13341///
13342/// If the per-corpus type map is non-empty (because the corpus allows
13343/// the One Definition Rule) then the type islooked up in that
13344/// per-corpus type map. Otherwise, the type is looked-up in each
13345/// translation unit.
13346///
13347/// @param qualified_name the qualified name of the reference type to
13348/// look for.
13349///
13350/// @param corp the corpus to look into.
13351///
13352/// @return the reference type found.
13354lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
13355{
13357 corp.get_types().reference_types();
13358
13360 lookup_type_in_map<reference_type_def>(qualified_name, m);
13361 if (!result)
13362 result = lookup_reference_type_through_translation_units(qualified_name,
13363 corp);
13364
13365 return result;
13366}
13367
13368/// Look into a given corpus to find an array type which has a given
13369/// qualified name.
13370///
13371/// If the per-corpus type map is non-empty (because the corpus allows
13372/// the One Definition Rule) then the type islooked up in that
13373/// per-corpus type map. Otherwise, the type is looked-up in each
13374/// translation unit.
13375///
13376/// @param qualified_name the qualified name of the array type to look
13377/// for.
13378///
13379/// @param corp the corpus to look into.
13380///
13381/// @return the array type found.
13384{
13386 return lookup_array_type(s, corp);
13387}
13388
13389/// Look into a given corpus to find an array type which has the same
13390/// qualified name as a given array type.
13391///
13392/// If the per-corpus type map is non-empty (because the corpus allows
13393/// the One Definition Rule) then the type islooked up in that
13394/// per-corpus type map. Otherwise, the type is looked-up in each
13395/// translation unit.
13396///
13397/// @param t the type which has the same qualified name as the type we
13398/// are looking for.
13399///
13400/// @param corp the corpus to look into.
13401///
13402/// @return the type found.
13404lookup_array_type(const interned_string& qualified_name, const corpus& corp)
13405{
13407
13408 array_type_def_sptr result =
13409 lookup_type_in_map<array_type_def>(qualified_name, m);
13410 if (!result)
13411 result = lookup_array_type_through_translation_units(qualified_name, corp);
13412
13413 return result;
13414}
13415
13416/// Look into a given corpus to find a function type which has the same
13417/// qualified name as a given function type.
13418///
13419/// If the per-corpus type map is non-empty (because the corpus allows
13420/// the One Definition Rule) then the type islooked up in that
13421/// per-corpus type map. Otherwise, the type is looked-up in each
13422/// translation unit.
13423///
13424/// @param t the function type which has the same qualified name as
13425/// the function type we are looking for.
13426///
13427/// @param corp the corpus to look into.
13428///
13429/// @return the function type found.
13432{
13433 interned_string type_name = get_type_name(t);
13434 return lookup_function_type(type_name, corp);
13435}
13436
13437/// Look into a given corpus to find a function type which has the same
13438/// qualified name as a given function type.
13439///
13440/// If the per-corpus type map is non-empty (because the corpus allows
13441/// the One Definition Rule) then the type islooked up in that
13442/// per-corpus type map. Otherwise, the type is looked-up in each
13443/// translation unit.
13444///
13445/// @param t the function type which has the same qualified name as
13446/// the function type we are looking for.
13447///
13448/// @param corp the corpus to look into.
13449///
13450/// @return the function type found.
13453 const corpus& corpus)
13454{
13455 if (fn_t)
13456 return lookup_function_type(*fn_t, corpus);
13457 return function_type_sptr();
13458}
13459
13460/// Look into a given corpus to find a function type which has a given
13461/// qualified name.
13462///
13463/// If the per-corpus type map is non-empty (because the corpus allows
13464/// the One Definition Rule) then the type islooked up in that
13465/// per-corpus type map. Otherwise, the type is looked-up in each
13466/// translation unit.
13467///
13468/// @param qualified_name the qualified name of the function type to
13469/// look for.
13470///
13471/// @param corp the corpus to look into.
13472///
13473/// @return the function type found.
13475lookup_function_type(const interned_string& qualified_name, const corpus& corp)
13476{
13478
13479 function_type_sptr result =
13480 lookup_type_in_map<function_type>(qualified_name, m);
13481 if (!result)
13482 result = lookup_function_type_through_translation_units(qualified_name,
13483 corp);
13484
13485 return result;
13486}
13487
13488/// Look into a given corpus to find a type which has a given
13489/// qualified name.
13490///
13491/// If the per-corpus type map is non-empty (because the corpus allows
13492/// the One Definition Rule) then the type islooked up in that
13493/// per-corpus type map. Otherwise, the type is looked-up in each
13494/// translation unit.
13495///
13496/// @param qualified_name the qualified name of the function type to
13497/// look for.
13498///
13499/// @param corp the corpus to look into.
13500///
13501/// @return the function type found.
13502type_base_sptr
13503lookup_type(const interned_string& n, const corpus& corp)
13504{
13505 type_base_sptr result;
13506
13507 ((result = lookup_basic_type(n, corp))
13508 || (result = lookup_class_type(n, corp))
13509 || (result = lookup_union_type(n, corp))
13510 || (result = lookup_enum_type(n, corp))
13511 || (result = lookup_typedef_type(n, corp))
13512 || (result = lookup_qualified_type(n, corp))
13513 || (result = lookup_pointer_type(n, corp))
13514 || (result = lookup_reference_type(n, corp))
13515 || (result = lookup_array_type(n, corp))
13516 || (result= lookup_function_type(n, corp)));
13517
13518 return result;
13519}
13520
13521/// Lookup a type from a corpus, by its location.
13522///
13523/// @param loc the location to consider.
13524///
13525/// @param corp the corpus to look the type from.
13526///
13527/// @return the resulting type, if any found.
13528type_base_sptr
13530{
13531 // TODO: finish this.
13532
13533 //TODO: when we fully support types indexed by their location, this
13534 //function should return a vector of types because at each location,
13535 //there can be several types that are defined (yay, C and C++,
13536 //*sigh*).
13537
13538 type_base_sptr result;
13539 ((result = lookup_basic_type_per_location(loc, corp))
13540 || (result = lookup_class_type_per_location(loc, corp))
13541 || (result = lookup_union_type_per_location(loc, corp))
13542 || (result = lookup_enum_type_per_location(loc, corp))
13543 || (result = lookup_typedef_type_per_location(loc, corp)));
13544
13545 return result;
13546}
13547
13548/// Look into a given corpus to find a type
13549///
13550/// If the per-corpus type map is non-empty (because the corpus allows
13551/// the One Definition Rule) then the type islooked up in that
13552/// per-corpus type map. Otherwise, the type is looked-up in each
13553/// translation unit.
13554///
13555/// @param qualified_name the qualified name of the function type to
13556/// look for.
13557///
13558/// @param corp the corpus to look into.
13559///
13560/// @return the function type found.
13561type_base_sptr
13562lookup_type(const type_base&t, const corpus& corp)
13563{
13565 return lookup_type(n, corp);
13566}
13567
13568/// Look into a given corpus to find a type
13569///
13570/// If the per-corpus type map is non-empty (because the corpus allows
13571/// the One Definition Rule) then the type islooked up in that
13572/// per-corpus type map. Otherwise, the type is looked-up in each
13573/// translation unit.
13574///
13575/// @param qualified_name the qualified name of the function type to
13576/// look for.
13577///
13578/// @param corp the corpus to look into.
13579///
13580/// @return the function type found.
13581type_base_sptr
13582lookup_type(const type_base_sptr&t, const corpus& corp)
13583{
13584 if (t)
13585 return lookup_type(*t, corp);
13586 return type_base_sptr();
13587}
13588
13589/// Update the map that associates a fully qualified name of a given
13590/// type to that type.
13591///
13592///
13593/// @param type the type we are considering.
13594///
13595/// @param types_map the map to update. It's a map that assciates a
13596/// fully qualified name of a type to the type itself.
13597///
13598/// @param use_type_name_as_key if true, use the name of the type as
13599/// the key to look it up later. If false, then use the location of
13600/// the type as a key to look it up later.
13601///
13602/// @return true iff the type was added to the map.
13603template<typename TypeKind>
13604bool
13605maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
13607 bool use_type_name_as_key = true)
13608{
13610
13611 if (use_type_name_as_key)
13612 s = get_type_name(type);
13613 else if (location l = type->get_location())
13614 {
13615 string str = l.expand();
13616 s = type->get_environment().intern(str);
13617 }
13618
13619 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
13620 bool result = false;
13621
13622 if (i == types_map.end())
13623 {
13624 types_map[s].push_back(type);
13625 result = true;
13626 }
13627 else
13628 i->second.push_back(type);
13629
13630 return result;
13631}
13632
13633/// This is the specialization for type @ref class_decl of the
13634/// function template:
13635///
13636/// maybe_update_types_lookup_map<T>(scope_decl*,
13637/// const shared_ptr<T>&,
13638/// istring_type_base_wptrs_map_type&)
13639///
13640/// @param class_type the type to consider.
13641///
13642/// @param types_map the type map to update.
13643///
13644/// @return true iff the type was added to the map.
13645template<>
13646bool
13649 bool use_type_name_as_key)
13650{
13651 class_decl_sptr type = class_type;
13652
13653 bool update_qname_map = true;
13654 if (type->get_is_declaration_only())
13655 {
13656 // Let's try to look through decl-only classes to get their
13657 // definition. But if the class doesn't have a definition then
13658 // we'll keep it.
13659 if (class_decl_sptr def =
13660 is_class_type(class_type->get_definition_of_declaration()))
13661 type = def;
13662 }
13663
13664 if (!update_qname_map)
13665 return false;
13666
13668 if (use_type_name_as_key)
13669 {
13670 string qname = type->get_qualified_name();
13671 s = type->get_environment().intern(qname);
13672 }
13673 else if (location l = type->get_location())
13674 {
13675 string str = l.expand();
13676 s = type->get_environment().intern(str);
13677 }
13678
13679 bool result = false;
13680 istring_type_base_wptrs_map_type::iterator i = map.find(s);
13681 if (i == map.end())
13682 {
13683 map[s].push_back(type);
13684 result = true;
13685 }
13686 else
13687 i->second.push_back(type);
13688
13689 return result;
13690}
13691
13692/// This is the specialization for type @ref function_type of the
13693/// function template:
13694///
13695/// maybe_update_types_lookup_map<T>(scope_decl*,
13696/// const shared_ptr<T>&,
13697/// istring_type_base_wptrs_map_type&)
13698///
13699/// @param scope the scope of the type to consider.
13700///
13701/// @param class_type the type to consider.
13702///
13703/// @param types_map the type map to update.
13704///
13705/// @return true iff the type was added to the map.
13706template<>
13707bool
13709(const function_type_sptr& type,
13711 bool /*use_type_name_as_key*/)
13712{
13713 bool result = false;
13715 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
13716 if (i == types_map.end())
13717 {
13718 types_map[s].push_back(type);
13719 result = true;
13720 }
13721 else
13722 i->second.push_back(type);
13723
13724 return result;
13725}
13726
13727/// Update the map that associates the fully qualified name of a basic
13728/// type with the type itself.
13729///
13730/// The per-translation unit type map is updated if no type with this
13731/// name was already existing in that map.
13732///
13733/// If no type with this name did already exist in the per-corpus type
13734/// map, then that per-corpus type map is updated. Otherwise, that
13735/// type is erased from that per-corpus map.
13736///
13737/// @param basic_type the basic type to consider.
13738void
13740{
13741 if (translation_unit *tu = basic_type->get_translation_unit())
13742 maybe_update_types_lookup_map<type_decl>
13743 (basic_type, tu->get_types().basic_types());
13744
13745 if (corpus *type_corpus = basic_type->get_corpus())
13746 {
13747 maybe_update_types_lookup_map<type_decl>
13748 (basic_type,
13749 type_corpus->priv_->get_types().basic_types());
13750
13751 maybe_update_types_lookup_map<type_decl>
13752 (basic_type,
13753 type_corpus->get_type_per_loc_map().basic_types(),
13754 /*use_type_name_as_key*/false);
13755
13756 if (corpus *group = type_corpus->get_group())
13757 {
13758 maybe_update_types_lookup_map<type_decl>
13759 (basic_type,
13760 group->priv_->get_types().basic_types());
13761
13762 maybe_update_types_lookup_map<type_decl>
13763 (basic_type,
13764 group->get_type_per_loc_map().basic_types(),
13765 /*use_type_name_as_key*/false);
13766 }
13767 }
13768
13769}
13770
13771/// Update the map that associates the fully qualified name of a class
13772/// type with the type itself.
13773///
13774/// The per-translation unit type map is updated if no type with this
13775/// name was already existing in that map.
13776///
13777/// If no type with this name did already exist in the per-corpus type
13778/// map, then that per-corpus type map is updated. Otherwise, that
13779/// type is erased from that per-corpus map.
13780///
13781/// @param class_type the class type to consider.
13782void
13784{
13785 if (translation_unit *tu = class_type->get_translation_unit())
13787 (class_type, tu->get_types().class_types());
13788
13789 if (corpus *type_corpus = class_type->get_corpus())
13790 {
13792 (class_type,
13793 type_corpus->priv_->get_types().class_types());
13794
13796 (class_type,
13797 type_corpus->get_type_per_loc_map().class_types(),
13798 /*use_type_name_as_key*/false);
13799
13800 if (corpus *group = type_corpus->get_group())
13801 {
13803 (class_type,
13804 group->priv_->get_types().class_types());
13805
13807 (class_type,
13808 group->get_type_per_loc_map().class_types(),
13809 /*use_type_name_as_key*/false);
13810 }
13811 }
13812}
13813
13814/// Update the map that associates the fully qualified name of a union
13815/// type with the type itself.
13816///
13817/// The per-translation unit type map is updated if no type with this
13818/// name was already existing in that map.
13819///
13820/// If no type with this name did already exist in the per-corpus type
13821/// map, then that per-corpus type map is updated. Otherwise, that
13822/// type is erased from that per-corpus map.
13823///
13824/// @param union_type the union type to consider.
13825void
13826maybe_update_types_lookup_map(const union_decl_sptr& union_type)
13827{
13828 if (translation_unit *tu = union_type->get_translation_unit())
13829 maybe_update_types_lookup_map<union_decl>
13830 (union_type, tu->get_types().union_types());
13831
13832 if (corpus *type_corpus = union_type->get_corpus())
13833 {
13834 maybe_update_types_lookup_map<union_decl>
13835 (union_type,
13836 type_corpus->priv_->get_types().union_types());
13837
13838 maybe_update_types_lookup_map<union_decl>
13839 (union_type,
13840 type_corpus->get_type_per_loc_map().union_types(),
13841 /*use_type_name_as_key*/false);
13842
13843 if (corpus *group = type_corpus->get_group())
13844 {
13845 maybe_update_types_lookup_map<union_decl>
13846 (union_type,
13847 group->priv_->get_types().union_types());
13848
13849 maybe_update_types_lookup_map<union_decl>
13850 (union_type,
13851 group->get_type_per_loc_map().union_types(),
13852 /*use_type_name_as_key*/false);
13853 }
13854 }
13855}
13856
13857/// Update the map that associates the fully qualified name of an enum
13858/// type with the type itself.
13859///
13860/// The per-translation unit type map is updated if no type with this
13861/// name was already existing in that map.
13862///
13863/// If no type with this name did already exist in the per-corpus type
13864/// map, then that per-corpus type map is updated. Otherwise, that
13865/// type is erased from that per-corpus map.
13866///
13867/// @param enum_type the type to consider.
13868void
13870{
13871 if (translation_unit *tu = enum_type->get_translation_unit())
13872 maybe_update_types_lookup_map<enum_type_decl>
13873 (enum_type, tu->get_types().enum_types());
13874
13875 if (corpus *type_corpus = enum_type->get_corpus())
13876 {
13877 maybe_update_types_lookup_map<enum_type_decl>
13878 (enum_type,
13879 type_corpus->priv_->get_types().enum_types());
13880
13881 maybe_update_types_lookup_map<enum_type_decl>
13882 (enum_type,
13883 type_corpus->get_type_per_loc_map().enum_types(),
13884 /*use_type_name_as_key*/false);
13885
13886 if (corpus *group = type_corpus->get_group())
13887 {
13888 maybe_update_types_lookup_map<enum_type_decl>
13889 (enum_type,
13890 group->priv_->get_types().enum_types());
13891
13892 maybe_update_types_lookup_map<enum_type_decl>
13893 (enum_type,
13894 group->get_type_per_loc_map().enum_types(),
13895 /*use_type_name_as_key*/false);
13896 }
13897 }
13898
13899}
13900
13901/// Update the map that associates the fully qualified name of a
13902/// typedef type with the type itself.
13903///
13904/// The per-translation unit type map is updated if no type with this
13905/// name was already existing in that map.
13906///
13907/// If no type with this name did already exist in the per-corpus type
13908/// map, then that per-corpus type map is updated. Otherwise, that
13909/// type is erased from that per-corpus map.
13910///
13911/// @param typedef_type the type to consider.
13912void
13914{
13915 if (translation_unit *tu = typedef_type->get_translation_unit())
13916 maybe_update_types_lookup_map<typedef_decl>
13917 (typedef_type, tu->get_types().typedef_types());
13918
13919 if (corpus *type_corpus = typedef_type->get_corpus())
13920 {
13921 maybe_update_types_lookup_map<typedef_decl>
13922 (typedef_type,
13923 type_corpus->priv_->get_types().typedef_types());
13924
13925 maybe_update_types_lookup_map<typedef_decl>
13926 (typedef_type,
13927 type_corpus->get_type_per_loc_map().typedef_types(),
13928 /*use_type_name_as_key*/false);
13929
13930 if (corpus *group = type_corpus->get_group())
13931 {
13932 maybe_update_types_lookup_map<typedef_decl>
13933 (typedef_type,
13934 group->priv_->get_types().typedef_types());
13935
13936 maybe_update_types_lookup_map<typedef_decl>
13937 (typedef_type,
13938 group->get_type_per_loc_map().typedef_types(),
13939 /*use_type_name_as_key*/false);
13940 }
13941 }
13942}
13943
13944/// Update the map that associates the fully qualified name of a
13945/// qualified type with the type itself.
13946///
13947/// The per-translation unit type map is updated if no type with this
13948/// name was already existing in that map.
13949///
13950/// If no type with this name did already exist in the per-corpus type
13951/// map, then that per-corpus type map is updated. Otherwise, that
13952/// type is erased from that per-corpus map.
13953///
13954/// @param qualified_type the type to consider.
13955void
13956maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
13957{
13958 if (translation_unit *tu = qualified_type->get_translation_unit())
13959 maybe_update_types_lookup_map<qualified_type_def>
13960 (qualified_type, tu->get_types().qualified_types());
13961
13962 if (corpus *type_corpus = qualified_type->get_corpus())
13963 {
13964 maybe_update_types_lookup_map<qualified_type_def>
13965 (qualified_type,
13966 type_corpus->priv_->get_types().qualified_types());
13967
13968 if (corpus *group = type_corpus->get_group())
13969 {
13970 maybe_update_types_lookup_map<qualified_type_def>
13971 (qualified_type,
13972 group->priv_->get_types().qualified_types());
13973 }
13974 }
13975}
13976
13977/// Update the map that associates the fully qualified name of a
13978/// pointer type with the type itself.
13979///
13980/// The per-translation unit type map is updated if no type with this
13981/// name was already existing in that map.
13982///
13983/// If no type with this name did already exist in the per-corpus type
13984/// map, then that per-corpus type map is updated. Otherwise, that
13985/// type is erased from that per-corpus map.
13986///
13987/// @param pointer_type the type to consider.
13988void
13990{
13991 if (translation_unit *tu = pointer_type->get_translation_unit())
13992 maybe_update_types_lookup_map<pointer_type_def>
13993 (pointer_type, tu->get_types().pointer_types());
13994
13995 if (corpus *type_corpus = pointer_type->get_corpus())
13996 {
13997 maybe_update_types_lookup_map<pointer_type_def>
13998 (pointer_type,
13999 type_corpus->priv_->get_types().pointer_types());
14000
14001 if (corpus *group = type_corpus->get_group())
14002 {
14003 maybe_update_types_lookup_map<pointer_type_def>
14004 (pointer_type,
14005 group->priv_->get_types().pointer_types());
14006 }
14007 }
14008}
14009
14010/// Update the map that associates the fully qualified name of a
14011/// reference type with the type itself.
14012///
14013/// The per-translation unit type map is updated if no type with this
14014/// name was already existing in that map.
14015///
14016/// If no type with this name did already exist in the per-corpus type
14017/// map, then that per-corpus type map is updated. Otherwise, that
14018/// type is erased from that per-corpus map.
14019///
14020/// @param reference_type the type to consider.
14021void
14023{
14024 if (translation_unit *tu = reference_type->get_translation_unit())
14025 maybe_update_types_lookup_map<reference_type_def>
14026 (reference_type, tu->get_types().reference_types());
14027
14028 if (corpus *type_corpus = reference_type->get_corpus())
14029 {
14030 maybe_update_types_lookup_map<reference_type_def>
14031 (reference_type,
14032 type_corpus->priv_->get_types().reference_types());
14033
14034 if (corpus *group = type_corpus->get_group())
14035 {
14036 maybe_update_types_lookup_map<reference_type_def>
14037 (reference_type,
14038 group->priv_->get_types().reference_types());
14039 }
14040 }
14041}
14042
14043/// Update the map that associates the fully qualified name of a type
14044/// with the type itself.
14045///
14046/// The per-translation unit type map is updated if no type with this
14047/// name was already existing in that map.
14048///
14049/// If no type with this name did already exist in the per-corpus type
14050/// map, then that per-corpus type map is updated. Otherwise, that
14051/// type is erased from that per-corpus map.
14052///
14053/// @param array_type the type to consider.
14054void
14056{
14057 if (translation_unit *tu = array_type->get_translation_unit())
14058 maybe_update_types_lookup_map<array_type_def>
14059 (array_type, tu->get_types().array_types());
14060
14061 if (corpus *type_corpus = array_type->get_corpus())
14062 {
14063 maybe_update_types_lookup_map<array_type_def>
14064 (array_type,
14065 type_corpus->priv_->get_types().array_types());
14066
14067 maybe_update_types_lookup_map<array_type_def>
14068 (array_type,
14069 type_corpus->get_type_per_loc_map().array_types(),
14070 /*use_type_name_as_key*/false);
14071
14072 if (corpus *group = type_corpus->get_group())
14073 {
14074 maybe_update_types_lookup_map<array_type_def>
14075 (array_type,
14076 group->priv_->get_types().array_types());
14077
14078 maybe_update_types_lookup_map<array_type_def>
14079 (array_type,
14080 group->get_type_per_loc_map().array_types(),
14081 /*use_type_name_as_key*/false);
14082 }
14083 }
14084}
14085
14086/// Update the map that associates the fully qualified name of a type
14087/// with the type itself.
14088///
14089/// The per-translation unit type map is updated if no type with this
14090/// name was already existing in that map.
14091///
14092/// If no type with this name did already exist in the per-corpus type
14093/// map, then that per-corpus type map is updated. Otherwise, that
14094/// type is erased from that per-corpus map.
14095///
14096/// @param subrange_type the type to consider.
14097void
14099(const array_type_def::subrange_sptr& subrange_type)
14100{
14101 if (translation_unit *tu = subrange_type->get_translation_unit())
14102 maybe_update_types_lookup_map<array_type_def::subrange_type>
14103 (subrange_type, tu->get_types().subrange_types());
14104
14105 if (corpus *type_corpus = subrange_type->get_corpus())
14106 {
14107 maybe_update_types_lookup_map<array_type_def::subrange_type>
14108 (subrange_type,
14109 type_corpus->priv_->get_types().subrange_types());
14110
14111 maybe_update_types_lookup_map<array_type_def::subrange_type>
14112 (subrange_type,
14113 type_corpus->get_type_per_loc_map().subrange_types(),
14114 /*use_type_name_as_key*/false);
14115
14116 if (corpus *group = subrange_type->get_corpus())
14117 {
14118 maybe_update_types_lookup_map<array_type_def::subrange_type>
14119 (subrange_type,
14120 group->priv_->get_types().subrange_types());
14121
14122 maybe_update_types_lookup_map<array_type_def::subrange_type>
14123 (subrange_type,
14124 group->get_type_per_loc_map().subrange_types(),
14125 /*use_type_name_as_key*/false);
14126 }
14127 }
14128}
14129
14130/// Update the map that associates the fully qualified name of a
14131/// function type with the type itself.
14132///
14133/// The per-translation unit type map is updated if no type with this
14134/// name was already existing in that map.
14135///
14136/// If no type with this name did already exist in the per-corpus type
14137/// map, then that per-corpus type map is updated. Otherwise, that
14138/// type is erased from that per-corpus map.
14139///
14140/// @param scope the scope of the function type.
14141/// @param fn_type the type to consider.
14142void
14144{
14145 if (translation_unit *tu = fn_type->get_translation_unit())
14147 (fn_type, tu->get_types().function_types());
14148
14149 if (corpus *type_corpus = fn_type->get_corpus())
14150 {
14152 (fn_type,
14153 type_corpus->priv_->get_types().function_types());
14154
14155 if (corpus *group = fn_type->get_corpus())
14156 {
14158 (fn_type,
14159 group->priv_->get_types().function_types());
14160 }
14161 }
14162}
14163
14164/// Update the map that associates the fully qualified name of a type
14165/// declaration with the type itself.
14166///
14167/// The per-translation unit type map is updated if no type with this
14168/// name was already existing in that map.
14169///
14170/// If no type with this name did already exist in the per-corpus type
14171/// map, then that per-corpus type map is updated. Otherwise, that
14172/// type is erased from that per-corpus map.
14173///
14174/// @param decl the declaration of the type to consider.
14175void
14176maybe_update_types_lookup_map(const decl_base_sptr& decl)
14177{
14178 if (!is_type(decl))
14179 return;
14180
14181 if (type_decl_sptr basic_type = is_type_decl(decl))
14183 else if (class_decl_sptr class_type = is_class_type(decl))
14185 else if (union_decl_sptr union_type = is_union_type(decl))
14187 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
14189 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
14190 maybe_update_types_lookup_map(typedef_type);
14191 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
14192 maybe_update_types_lookup_map(qualified_type);
14193 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
14194 maybe_update_types_lookup_map(pointer_type);
14195 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
14196 maybe_update_types_lookup_map(reference_type);
14197 else if (array_type_def_sptr array_type = is_array_type(decl))
14199 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
14200 maybe_update_types_lookup_map(subrange_type);
14201 else
14203}
14204
14205/// Update the map that associates the fully qualified name of a type
14206/// with the type itself.
14207///
14208/// The per-translation unit type map is updated if no type with this
14209/// name was already existing in that map.
14210///
14211/// If no type with this name did already exist in the per-corpus type
14212/// map, then that per-corpus type map is updated. Otherwise, that
14213/// type is erased from that per-corpus map.
14214///
14215/// @param type the type to consider.
14216void
14217maybe_update_types_lookup_map(const type_base_sptr& type)
14218{
14219 if (decl_base_sptr decl = get_type_declaration(type))
14221 else
14223}
14224
14225//--------------------------------
14226// </type and decls lookup stuff>
14227// ------------------------------
14228
14229/// In a translation unit, lookup a given type or synthesize it if
14230/// it's a qualified type.
14231///
14232/// So this function first looks the type up in the translation unit.
14233/// If it's found, then OK, it's returned. Otherwise, if it's a
14234/// qualified, reference or pointer or function type (a composite
14235/// type), lookup the underlying type, synthesize the type we want
14236/// from it and return it.
14237///
14238/// If the underlying types is not not found, then give up and return
14239/// nil.
14240///
14241/// @return the type that was found or the synthesized type.
14242type_base_sptr
14243synthesize_type_from_translation_unit(const type_base_sptr& type,
14244 translation_unit& tu)
14245{
14246 type_base_sptr result;
14247
14248 result = lookup_type(type, tu);
14249
14250 if (!result)
14251 {
14252 if (qualified_type_def_sptr qual = is_qualified_type(type))
14253 {
14254 type_base_sptr underlying_type =
14255 synthesize_type_from_translation_unit(qual->get_underlying_type(),
14256 tu);
14257 if (underlying_type)
14258 {
14259 result.reset(new qualified_type_def(underlying_type,
14260 qual->get_cv_quals(),
14261 qual->get_location()));
14262 }
14263 }
14264 else if (pointer_type_def_sptr p = is_pointer_type(type))
14265 {
14266 type_base_sptr pointed_to_type =
14267 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
14268 tu);
14269 if (pointed_to_type)
14270 {
14271 result.reset(new pointer_type_def(pointed_to_type,
14272 p->get_size_in_bits(),
14273 p->get_alignment_in_bits(),
14274 p->get_location()));
14275 }
14276 }
14277 else if (reference_type_def_sptr r = is_reference_type(type))
14278 {
14279 type_base_sptr pointed_to_type =
14280 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
14281 if (pointed_to_type)
14282 {
14283 result.reset(new reference_type_def(pointed_to_type,
14284 r->is_lvalue(),
14285 r->get_size_in_bits(),
14286 r->get_alignment_in_bits(),
14287 r->get_location()));
14288 }
14289 }
14290 else if (function_type_sptr f = is_function_type(type))
14292
14293 if (result)
14294 {
14296 canonicalize(result);
14297 }
14298 }
14299
14300 if (result)
14301 tu.priv_->synthesized_types_.push_back(result);
14302
14303 return result;
14304}
14305
14306/// In a translation unit, lookup the sub-types that make up a given
14307/// function type and if the sub-types are all found, synthesize and
14308/// return a function_type with them.
14309///
14310/// This function is like lookup_function_type_in_translation_unit()
14311/// execept that it constructs the function type from the sub-types
14312/// found in the translation, rather than just looking for the
14313/// function types held by the translation unit. This can be useful
14314/// if the translation unit doesnt hold the function type we are
14315/// looking for (i.e, lookup_function_type_in_translation_unit()
14316/// returned NULL) but we still want to see if the sub-types of the
14317/// function types are present in the translation unit.
14318///
14319/// @param fn_type the function type to consider.
14320///
14321/// @param tu the translation unit to look into.
14322///
14323/// @return the resulting synthesized function type if all its
14324/// sub-types have been found, NULL otherwise.
14327 translation_unit& tu)
14328{
14330
14331 const environment& env = tu.get_environment();
14332
14333 type_base_sptr return_type = fn_type.get_return_type();
14334 type_base_sptr result_return_type;
14335 if (!return_type || env.is_void_type(return_type))
14336 result_return_type = env.get_void_type();
14337 else
14338 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
14339 if (!result_return_type)
14340 return nil;
14341
14343 type_base_sptr parm_type;
14345 for (function_type::parameters::const_iterator i =
14346 fn_type.get_parameters().begin();
14347 i != fn_type.get_parameters().end();
14348 ++i)
14349 {
14350 type_base_sptr t = (*i)->get_type();
14351 parm_type = synthesize_type_from_translation_unit(t, tu);
14352 if (!parm_type)
14353 return nil;
14354 parm.reset(new function_decl::parameter(parm_type,
14355 (*i)->get_index(),
14356 (*i)->get_name(),
14357 (*i)->get_location(),
14358 (*i)->get_variadic_marker(),
14359 (*i)->get_is_artificial()));
14360 parms.push_back(parm);
14361 }
14362
14363 class_or_union_sptr class_type;
14364 const method_type* method = is_method_type(&fn_type);
14365 if (method)
14366 {
14367 class_type = is_class_or_union_type
14369 ABG_ASSERT(class_type);
14370 }
14371
14372 function_type_sptr result_fn_type;
14373
14374 if (class_type)
14375 result_fn_type.reset(new method_type(result_return_type,
14376 class_type,
14377 parms,
14378 method->get_is_const(),
14379 fn_type.get_size_in_bits(),
14380 fn_type.get_alignment_in_bits()));
14381 else
14382 result_fn_type.reset(new function_type(result_return_type,
14383 parms,
14384 fn_type.get_size_in_bits(),
14385 fn_type.get_alignment_in_bits()));
14386
14387 tu.priv_->synthesized_types_.push_back(result_fn_type);
14388 tu.bind_function_type_life_time(result_fn_type);
14389
14390 canonicalize(result_fn_type);
14391 return result_fn_type;
14392}
14393
14394/// Demangle a C++ mangled name and return the resulting string
14395///
14396/// @param mangled_name the C++ mangled name to demangle.
14397///
14398/// @return the resulting mangled name.
14399string
14400demangle_cplus_mangled_name(const string& mangled_name)
14401{
14402 if (mangled_name.empty())
14403 return "";
14404
14405 size_t l = 0;
14406 int status = 0;
14407 char * str = abi::__cxa_demangle(mangled_name.c_str(),
14408 NULL, &l, &status);
14409 string demangled_name = mangled_name;
14410 if (str)
14411 {
14412 ABG_ASSERT(status == 0);
14413 demangled_name = str;
14414 free(str);
14415 str = 0;
14416 }
14417 return demangled_name;
14418}
14419
14420/// Return either the type given in parameter if it's non-null, or the
14421/// void type.
14422///
14423/// @param t the type to consider.
14424///
14425/// @param env the environment to use. If NULL, just abort the
14426/// process.
14427///
14428/// @return either @p t if it is non-null, or the void type.
14429type_base_sptr
14430type_or_void(const type_base_sptr t, const environment& env)
14431{
14432 type_base_sptr r;
14433
14434 if (t)
14435 r = t;
14436 else
14437 r = type_base_sptr(env.get_void_type());
14438
14439 return r;
14440}
14441
14442global_scope::~global_scope()
14443{
14444}
14445
14446static bool
14447maybe_propagate_canonical_type(const type_base& lhs_type,
14448 const type_base& rhs_type);
14449
14450/// Test if two types are eligible to the "Linux Kernel Fast Type
14451/// Comparison Optimization", a.k.a LKFTCO.
14452///
14453/// Two types T1 and T2 (who are presumably of the same name and kind)
14454/// are eligible to the LKFTCO if they fulfill the following criteria/
14455///
14456/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
14457/// either class, union or enums.
14458///
14459/// 2/ They are defined in the same translation unit.
14460///
14461/// @param t1 the first type to consider.
14462///
14463/// @param t2 the second type to consider.
14464///
14465/// @return true iff t1 and t2 are eligible to the LKFTCO.
14466static bool
14467types_defined_same_linux_kernel_corpus_public(const type_base& t1,
14468 const type_base& t2)
14469{
14470 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
14471 string t1_file_path, t2_file_path;
14472
14473 /// If the t1 (and t2) are classes/unions/enums from the same linux
14474 /// kernel corpus, let's move on. Otherwise bail out.
14475 if (!(t1_corpus && t2_corpus
14476 && t1_corpus == t2_corpus
14477 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
14478 && (is_class_or_union_type(&t1)
14479 || is_enum_type(&t1))))
14480 return false;
14481
14482 class_or_union *c1 = 0, *c2 = 0;
14483 c1 = is_class_or_union_type(&t1);
14484 c2 = is_class_or_union_type(&t2);
14485
14486 // Two anonymous class types with no naming typedefs cannot be
14487 // eligible to this optimization.
14488 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
14489 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
14490 return false;
14491
14492 // Two anonymous classes with naming typedefs should have the same
14493 // typedef name.
14494 if (c1
14495 && c2
14496 && c1->get_is_anonymous() && c1->get_naming_typedef()
14497 && c2->get_is_anonymous() && c2->get_naming_typedef())
14498 if (c1->get_naming_typedef()->get_name()
14499 != c2->get_naming_typedef()->get_name())
14500 return false;
14501
14502 // Two anonymous enum types cannot be eligible to this optimization.
14503 if (const enum_type_decl *e1 = is_enum_type(&t1))
14504 if (const enum_type_decl *e2 = is_enum_type(&t2))
14505 if (e1->get_is_anonymous() || e2->get_is_anonymous())
14506 return false;
14507
14508 // Look through declaration-only types. That is, get the associated
14509 // definition type.
14512
14513 if (c1 && c2)
14514 {
14515 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
14516 {
14517 if (c1->get_environment().decl_only_class_equals_definition())
14518 // At least one of classes/union is declaration-only.
14519 // Because we are in a context in which a declaration-only
14520 // class/union is equal to all definitions of that
14521 // class/union, we can assume that the two types are
14522 // equal.
14523 return true;
14524 }
14525 }
14526
14527 if (t1.get_size_in_bits() != t2.get_size_in_bits())
14528 return false;
14529
14530 // Look at the file names of the locations of t1 and t2. If they
14531 // are equal, then t1 and t2 are defined in the same file.
14532 {
14533 location l;
14534
14535 if (c1)
14536 l = c1->get_location();
14537 else
14538 l = dynamic_cast<const decl_base&>(t1).get_location();
14539
14540 unsigned line = 0, col = 0;
14541 if (l)
14542 l.expand(t1_file_path, line, col);
14543 if (c2)
14544 l = c2->get_location();
14545 else
14546 l = dynamic_cast<const decl_base&>(t2).get_location();
14547 if (l)
14548 l.expand(t2_file_path, line, col);
14549 }
14550
14551 if (t1_file_path.empty() || t2_file_path.empty())
14552 return false;
14553
14554 if (t1_file_path == t2_file_path)
14555 return true;
14556
14557 return false;
14558}
14559
14560
14561/// Compare a type T against a canonical type.
14562///
14563/// This function is called during the canonicalization process of the
14564/// type T. T is called the "candidate type" because it's in the
14565/// process of being canonicalized. Meaning, it's going to be
14566/// compared to a canonical type C. If T equals C, then the canonical
14567/// type of T is C.
14568///
14569/// The purpose of this function is to allow the debugging of the
14570/// canonicalization of T, if that debugging is activated by
14571/// configuring the libabigail package with
14572/// --enable-debug-type-canonicalization and by running "abidw
14573/// --debug-tc". In that case, T is going to be compared to C twice:
14574/// once with canonical equality and once with structural equality.
14575/// The two comparisons must be equal. Otherwise, the
14576/// canonicalization process is said to be faulty and this function
14577/// aborts.
14578///
14579/// This is a sub-routine of type_base::get_canonical_type_for.
14580///
14581/// @param canonical_type the canonical type to compare the candidate
14582/// type against.
14583///
14584/// @param candidate_type the candidate type to compare against the
14585/// canonical type.
14586///
14587/// @return true iff @p canonical_type equals @p candidate_type.
14588///
14589static bool
14590compare_types_during_canonicalization(const type_base& canonical_type,
14591 const type_base& candidate_type)
14592{
14593#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
14594 const environment& env = canonical_type.get_environment();
14595 if (env.debug_type_canonicalization_is_on())
14596 {
14597 bool canonical_equality = false, structural_equality = false;
14598 env.priv_->use_canonical_type_comparison_ = false;
14599 structural_equality = canonical_type == candidate_type;
14600 env.priv_->use_canonical_type_comparison_ = true;
14601 canonical_equality = canonical_type == candidate_type;
14602 if (canonical_equality != structural_equality)
14603 {
14604 std::cerr << "structural & canonical equality different for type: "
14605 << canonical_type.get_pretty_representation(true, true)
14606 << std::endl;
14608 }
14609 return structural_equality;
14610 }
14611#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
14612 return canonical_type == candidate_type;
14613}
14614
14615/// Compare a canonical type against a candidate canonical type.
14616///
14617/// This is ultimately a sub-routine of the
14618/// type_base::get_canonical_type_for().
14619///
14620/// The goal of this function is to ease debugging because it can be
14621/// called from within type_base::get_canonical_type_for() from the
14622/// prompt of the debugger (with some breakpoint appropriately set) to
14623/// debug the comparison that happens during type canonicalization,
14624/// between a candidate type being canonicalized, and an existing
14625/// canonical type that is registered in the system, in as returned by
14626/// environment::get_canonical_types()
14627///
14628/// @param canonical_type the canonical type to consider.
14629///
14630/// @param candidate_type the candidate type that is being
14631/// canonicalized, and thus compared to @p canonical_type.
14632///
14633/// @return true iff @p canonical_type compares equal to @p
14634/// candidate_type.
14635static bool
14636compare_canonical_type_against_candidate(const type_base& canonical_type,
14637 const type_base& candidate_type)
14638{
14639 environment& env = const_cast<environment&>(canonical_type.get_environment());
14640
14641 // Before the "*it == it" comparison below is done, let's
14642 // perform on-the-fly-canonicalization. For C types, let's
14643 // consider that an unresolved struct declaration 'struct S'
14644 // is different from a definition 'struct S'. This is
14645 // because normally, at this point all the declarations of
14646 // struct S that are compatible with the definition of
14647 // struct S have already been resolved to that definition,
14648 // during the DWARF parsing. The remaining unresolved
14649 // declaration are thus considered different. With this
14650 // setup we can properly handle cases of two *different*
14651 // struct S being defined in the same binary (in different
14652 // translation units), and a third struct S being only
14653 // declared as an opaque type in a third translation unit of
14654 // its own, with no definition in there. In that case, the
14655 // declaration-only struct S should be left alone and not
14656 // resolved to any of the two definitions of struct S.
14657 bool saved_decl_only_class_equals_definition =
14658 env.decl_only_class_equals_definition();
14659 env.do_on_the_fly_canonicalization(true);
14660 // Compare types by considering that decl-only classes don't
14661 // equal their definition.
14662 env.decl_only_class_equals_definition(false);
14663 env.priv_->allow_type_comparison_results_caching(true);
14664 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
14665 candidate_type)
14666 || compare_types_during_canonicalization(canonical_type,
14667 candidate_type));
14668 // Restore the state of the on-the-fly-canonicalization and
14669 // the decl-only-class-being-equal-to-a-matching-definition
14670 // flags.
14671 env.priv_->clear_type_comparison_results_cache();
14672 env.priv_->allow_type_comparison_results_caching(false);
14673 env.do_on_the_fly_canonicalization(false);
14674 env.decl_only_class_equals_definition
14675 (saved_decl_only_class_equals_definition);
14676 return equal;
14677}
14678
14679/// Compare a canonical type against a candidate canonical type.
14680///
14681/// This is ultimately a sub-routine of the
14682/// type_base::get_canonical_type_for().
14683///
14684/// The goal of this function is to ease debugging because it can be
14685/// called from within type_base::get_canonical_type_for() from the
14686/// prompt of the debugger (with some breakpoint appropriately set) to
14687/// debug the comparison that happens during type canonicalization,
14688/// between a candidate type being canonicalized, and an existing
14689/// canonical type that is registered in the system, in as returned by
14690/// environment::get_canonical_types()
14691///
14692/// @param canonical_type the canonical type to consider.
14693///
14694/// @param candidate_type the candidate type that is being
14695/// canonicalized, and thus compared to @p canonical_type.
14696///
14697/// @return true iff @p canonical_type compares equal to @p
14698/// candidate_type.
14699static bool
14700compare_canonical_type_against_candidate(const type_base* canonical_type,
14701 const type_base* candidate_type)
14702{
14703 return compare_canonical_type_against_candidate(*canonical_type,
14704 *candidate_type);
14705}
14706
14707/// Compare a canonical type against a candidate canonical type.
14708///
14709/// This is ultimately a sub-routine of the
14710/// type_base::get_canonical_type_for().
14711///
14712/// The goal of this function is to ease debugging because it can be
14713/// called from within type_base::get_canonical_type_for() from the
14714/// prompt of the debugger (with some breakpoint appropriately set) to
14715/// debug the comparison that happens during type canonicalization,
14716/// between a candidate type being canonicalized, and an existing
14717/// canonical type that is registered in the system, in as returned by
14718/// environment::get_canonical_types()
14719///
14720/// @param canonical_type the canonical type to consider.
14721///
14722/// @param candidate_type the candidate type that is being
14723/// canonicalized, and thus compared to @p canonical_type.
14724///
14725/// @return true iff @p canonical_type compares equal to @p
14726/// candidate_type.
14727static bool
14728compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
14729 const type_base_sptr& candidate_type)
14730{
14731 return compare_canonical_type_against_candidate(canonical_type.get(),
14732 candidate_type.get());
14733}
14734
14735/// Compute the canonical type for a given instance of @ref type_base.
14736///
14737/// Consider two types T and T'. The canonical type of T, denoted
14738/// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
14739/// otherwise, to compare two types, one just needs to compare their
14740/// canonical types using pointer equality. That makes type
14741/// comparison faster than the structural comparison performed by the
14742/// abigail::ir::equals() overloads.
14743///
14744/// If there is not yet any canonical type for @p t, then @p t is its
14745/// own canonical type. Otherwise, this function returns the
14746/// canonical type of @p t which is the canonical type that has the
14747/// same hash value as @p t and that structurally equals @p t. Note
14748/// that after invoking this function, the life time of the returned
14749/// canonical time is then equals to the life time of the current
14750/// process.
14751///
14752/// @param t a smart pointer to instance of @ref type_base we want to
14753/// compute a canonical type for.
14754///
14755/// @return the canonical type for the current instance of @ref
14756/// type_base.
14757type_base_sptr
14758type_base::get_canonical_type_for(type_base_sptr t)
14759{
14760 if (!t)
14761 return t;
14762
14763 environment& env = const_cast<environment&>(t->get_environment());
14764
14766 // This type should not be canonicalized!
14767 return type_base_sptr();
14768
14769 if (is_decl(t))
14771
14772 // Look through decl-only types (classes, unions and enums)
14773 bool decl_only_class_equals_definition =
14774 (odr_is_relevant(*t) || env.decl_only_class_equals_definition());
14775
14776 class_or_union_sptr class_or_union = is_class_or_union_type(t);
14777
14778 // In the context of types from C++ or languages where we assume the
14779 // "One Definition Rule", we assume that a declaration-only
14780 // non-anonymous class equals all fully defined classes of the same
14781 // name.
14782 //
14783 // Otherwise, all classes, including declaration-only classes are
14784 // canonicalized and only canonical comparison is going to be used
14785 // in the system.
14786 if (decl_only_class_equals_definition)
14787 if (class_or_union)
14788 if (class_or_union->get_is_declaration_only())
14789 return type_base_sptr();
14790
14791 class_decl_sptr is_class = is_class_type(t);
14792 if (t->get_canonical_type())
14793 return t->get_canonical_type();
14794
14795 // For classes and union, ensure that an anonymous class doesn't
14796 // have a linkage name. If it does in the future, then me must be
14797 // mindful that the linkage name respects the type identity
14798 // constraints which states that "if two linkage names are different
14799 // then the two types are different".
14800 ABG_ASSERT(!class_or_union
14801 || !class_or_union->get_is_anonymous()
14802 || class_or_union->get_linkage_name().empty());
14803
14804 // We want the pretty representation of the type, but for an
14805 // internal use, not for a user-facing purpose.
14806 //
14807 // If two classe types Foo are declared, one as a class and the
14808 // other as a struct, but are otherwise equivalent, we want their
14809 // pretty representation to be the same. Hence the 'internal'
14810 // argument of ir::get_pretty_representation() is set to true here.
14811 // So in this case, the pretty representation of Foo is going to be
14812 // "class Foo", regardless of its struct-ness. This also applies to
14813 // composite types which would have "class Foo" as a sub-type.
14814 string repr = t->get_cached_pretty_representation(/*internal=*/true);
14815
14816 // If 't' already has a canonical type 'inside' its corpus
14817 // (t_corpus), then this variable is going to contain that canonical
14818 // type.
14819 type_base_sptr canonical_type_present_in_corpus;
14821 env.get_canonical_types_map();
14822
14823 type_base_sptr result;
14824 environment::canonical_types_map_type::iterator i = types.find(repr);
14825 if (i == types.end())
14826 {
14827 vector<type_base_sptr> v;
14828 v.push_back(t);
14829 types[repr] = v;
14830 result = t;
14831 }
14832 else
14833 {
14834 vector<type_base_sptr> &v = i->second;
14835 // Let's compare 't' structurally (i.e, compare its sub-types
14836 // recursively) against the canonical types of the system. If it
14837 // equals a given canonical type C, then it means C is the
14838 // canonical type of 't'. Otherwise, if 't' is different from
14839 // all the canonical types of the system, then it means 't' is a
14840 // canonical type itself.
14841 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
14842 it != v.rend();
14843 ++it)
14844 {
14845 bool equal = compare_canonical_type_against_candidate(*it, t);
14846 if (equal)
14847 {
14848 result = *it;
14849 break;
14850 }
14851 }
14852#ifdef WITH_DEBUG_SELF_COMPARISON
14853 if (env.self_comparison_debug_is_on())
14854 {
14855 // So we are debugging the canonicalization process,
14856 // possibly via the use of 'abidw --debug-abidiff <binary>'.
14857 corpus_sptr corp1, corp2;
14858 env.get_self_comparison_debug_inputs(corp1, corp2);
14859 if (corp1 && corp2 && t->get_corpus() == corp2.get())
14860 {
14861 // If 't' comes from the second corpus, then it *must*
14862 // be equal to its matching canonical type coming from
14863 // the first corpus because the second corpus is the
14864 // abixml representation of the first corpus. In other
14865 // words, all types coming from the second corpus must
14866 // have canonical types coming from the first corpus.
14867 if (result)
14868 {
14869 if (!env.priv_->
14870 check_canonical_type_from_abixml_during_self_comp(t,
14871 result))
14872 {
14873 // The canonical type of the type re-read from abixml
14874 // type doesn't match the canonical type that was
14875 // initially serialized down.
14876 uintptr_t should_have_canonical_type = 0;
14877 string type_id = env.get_type_id_from_type(t.get());
14878 if (type_id.empty())
14879 type_id = "type-id-<not-found>";
14880 else
14881 should_have_canonical_type =
14882 env.get_canonical_type_from_type_id(type_id.c_str());
14883 std::cerr << "error: wrong canonical type for '"
14884 << repr
14885 << "' / type: @"
14886 << std::hex
14887 << t.get()
14888 << "/ canon: @"
14889 << result.get()
14890 << ", type-id: '"
14891 << type_id
14892 << "'. Should have had canonical type: "
14893 << std::hex
14894 << should_have_canonical_type
14895 << std::endl;
14896 }
14897 }
14898 else //!result
14899 {
14900 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
14901 string type_id = env.get_type_id_from_pointer(ptr_val);
14902 if (type_id.empty())
14903 type_id = "type-id-<not-found>";
14904 // We are in the case where 't' is different from all
14905 // the canonical types of the same name that come from
14906 // the first corpus.
14907 //
14908 // If 't' indeed comes from the second corpus then this
14909 // clearly is a canonicalization failure.
14910 //
14911 // There was a problem either during the serialization
14912 // of 't' into abixml, or during the de-serialization
14913 // from abixml into abigail::ir. Further debugging is
14914 // needed to determine what that root cause problem is.
14915 //
14916 // Note that the first canonicalization problem of this
14917 // kind must be fixed before looking at the subsequent
14918 // ones, because the later might well just be
14919 // consequences of the former.
14920 std::cerr << "error: wrong induced canonical type for '"
14921 << repr
14922 << "' from second corpus"
14923 << ", ptr: " << std::hex << t.get()
14924 << " type-id: " << type_id
14925 << std::endl;
14926 }
14927 }
14928 }
14929#endif //WITH_DEBUG_SELF_COMPARISON
14930
14931 if (!result)
14932 {
14933 v.push_back(t);
14934 result = t;
14935 }
14936 }
14937
14938 return result;
14939}
14940
14941/// This method is invoked automatically right after the current
14942/// instance of @ref class_decl has been canonicalized.
14943void
14945{}
14946
14947/// This is a subroutine of the canonicalize() function.
14948///
14949/// When the canonical type C of type T has just been computed, there
14950/// can be cases where T has member functions that C doesn't have.
14951///
14952/// This is possible because non virtual member functions are not
14953/// taken in account when comparing two types.
14954///
14955/// In that case, this function updates C so that it contains the
14956/// member functions.
14957///
14958/// There can also be cases where C has a method M which is not linked
14959/// to any underlying symbol, whereas in T, M is to link to an
14960/// underlying symbol. In that case, this function updates M in C so
14961/// that it's linked to the same underlying symbol as for M in T.
14962static void
14963maybe_adjust_canonical_type(const type_base_sptr& canonical,
14964 const type_base_sptr& type)
14965{
14966 if (!canonical
14967 // If 'type' is *NOT* a newly canonicalized type ...
14968 || type->get_naked_canonical_type()
14969 // ... or if 'type' is it's own canonical type, then get out.
14970 || type.get() == canonical.get())
14971 return;
14972
14973 if (class_decl_sptr cl = is_class_type(type))
14974 {
14975 class_decl_sptr canonical_class = is_class_type(canonical);
14976
14977 if (canonical_class)
14978 {
14979 // Set symbols of member functions that might be missing
14980 // theirs.
14981 for (class_decl::member_functions::const_iterator i =
14982 cl->get_member_functions().begin();
14983 i != cl->get_member_functions().end();
14984 ++i)
14985 if ((*i)->get_symbol())
14986 {
14987 if (method_decl *m = canonical_class->
14988 find_member_function((*i)->get_linkage_name()))
14989 {
14990 elf_symbol_sptr s1 = (*i)->get_symbol();
14991 if (s1 && !m->get_symbol())
14992 // Method 'm' in the canonical type is not
14993 // linked to the underlying symbol of '*i'.
14994 // Let's link it now. have th
14995 m->set_symbol(s1);
14996 }
14997 else
14998 // There is a member function defined and publicly
14999 // exported in the other class, and the canonical
15000 // class doesn't have that member function. Let's
15001 // copy that member function to the canonical class
15002 // then.
15003 copy_member_function (canonical_class, *i);
15004 }
15005 }
15006 }
15007
15008 // If an artificial function type equals a non-artfificial one in
15009 // the system, then the canonical type of both should be deemed
15010 // non-artificial. This is important because only non-artificial
15011 // canonical function types are emitted out into abixml, so if don't
15012 // do this we risk missing to emit some function types.
15013 if (is_function_type(type))
15014 if (type->get_is_artificial() != canonical->get_is_artificial())
15015 canonical->set_is_artificial(false);
15016}
15017
15018/// Compute the canonical type of a given type.
15019///
15020/// It means that after invoking this function, comparing the intance
15021/// instance @ref type_base and another one (on which
15022/// type_base::enable_canonical_equality() would have been invoked as
15023/// well) is performed by just comparing the pointer values of the
15024/// canonical types of both types. That equality comparison is
15025/// supposedly faster than structural comparison of the types.
15026///
15027/// @param t a smart pointer to the instance of @ref type_base for
15028/// which to compute the canonical type. After this call,
15029/// t->get_canonical_type() will return the newly computed canonical
15030/// type.
15031///
15032/// @return the canonical type computed for @p t.
15033type_base_sptr
15034canonicalize(type_base_sptr t)
15035{
15036 if (!t)
15037 return t;
15038
15039 if (t->get_canonical_type())
15040 return t->get_canonical_type();
15041
15042 type_base_sptr canonical = type_base::get_canonical_type_for(t);
15043 maybe_adjust_canonical_type(canonical, t);
15044
15045 t->priv_->canonical_type = canonical;
15046 t->priv_->naked_canonical_type = canonical.get();
15047
15048 // So this type is now canonicalized.
15049 //
15050 // It means that:
15051 //
15052 // 1/ Either the canonical type was not propagated during the
15053 // comparison of another type that was being canonicalized
15054 //
15055 // 2/ Or the canonical type has been propagated during the
15056 // comparison of another type that was being canonicalized and
15057 // that propagated canonical type has been confirmed, because
15058 // it was depending on a recursive type which comparison
15059 // succeeded.
15060 ABG_ASSERT(!t->priv_->canonical_type_propagated()
15061 || t->priv_->propagated_canonical_type_confirmed());
15062
15063 if (class_decl_sptr cl = is_class_type(t))
15064 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
15065 if ((canonical = d->get_canonical_type()))
15066 {
15067 d->priv_->canonical_type = canonical;
15068 d->priv_->naked_canonical_type = canonical.get();
15069 }
15070
15071 if (canonical)
15072 {
15073 if (decl_base_sptr d = is_decl_slow(canonical))
15074 {
15075 scope_decl *scope = d->get_scope();
15076 // Add the canonical type to the set of canonical types
15077 // belonging to its scope.
15078 if (scope)
15079 {
15080 if (is_type(scope))
15081 // The scope in question is itself a type (e.g, a class
15082 // or union). Let's call that type ST. We want to add
15083 // 'canonical' to the set of canonical types belonging
15084 // to ST.
15085 if (type_base_sptr c = is_type(scope)->get_canonical_type())
15086 // We want to add 'canonical' to set of canonical
15087 // types belonging to the canonical type of ST. That
15088 // way, just looking at the canonical type of ST is
15089 // enough to get the types that belong to the scope of
15090 // the class of equivalence of ST.
15091 scope = is_scope_decl(is_decl(c)).get();
15092 scope->get_canonical_types().insert(canonical);
15093 }
15094 // else, if the type doesn't have a scope, it's not meant to be
15095 // emitted. This can be the case for the result of the
15096 // function strip_typedef, for instance.
15097 }
15098
15099#ifdef WITH_DEBUG_CT_PROPAGATION
15100 // Update the book-keeping of the set of the types which
15101 // propagated canonical type has been cleared.
15102 //
15103 // If this type 't' which has just been canonicalized was
15104 // previously in the set of types which propagated canonical
15105 // type has been cleared, then remove it from that set because
15106 // its canonical type is now computed and definitely set.
15107 const environment& env = t->get_environment();
15108 env.priv_->erase_type_with_cleared_propagated_canonical_type(t.get());
15109#endif
15110 }
15111
15112 t->on_canonical_type_set();
15113 return canonical;
15114}
15115
15116/// Set the definition of this declaration-only @ref decl_base.
15117///
15118/// @param d the new definition to set.
15119void
15121{
15123 priv_->definition_of_declaration_ = d;
15124 if (type_base *t = is_type(this))
15125 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
15126 t->priv_->canonical_type = canonical_type;
15127
15128 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
15129}
15130
15131/// The constructor of @ref type_base.
15132///
15133/// @param s the size of the type, in bits.
15134///
15135/// @param a the alignment of the type, in bits.
15136type_base::type_base(const environment& e, size_t s, size_t a)
15137 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
15138 priv_(new priv(s, a))
15139{}
15140
15141/// Getter of the canonical type of the current instance of @ref
15142/// type_base.
15143///
15144/// @return a smart pointer to the canonical type of the current
15145/// intance of @ref type_base, or an empty smart pointer if the
15146/// current instance of @ref type_base doesn't have any canonical
15147/// type.
15148type_base_sptr
15150{return priv_->canonical_type.lock();}
15151
15152/// Getter of the canonical type pointer.
15153///
15154/// Note that this function doesn't return a smart pointer, but rather
15155/// the underlying pointer managed by the smart pointer. So it's as
15156/// fast as possible. This getter is to be used in code paths that
15157/// are proven to be performance hot spots; especially, when comparing
15158/// sensitive types like class, function, pointers and reference
15159/// types. Those are compared extremely frequently and thus, their
15160/// accessing the canonical type must be fast.
15161///
15162/// @return the canonical type pointer, not managed by a smart
15163/// pointer.
15164type_base*
15166{return priv_->naked_canonical_type;}
15167
15168/// Get the pretty representation of the current type.
15169///
15170/// The pretty representation is retrieved from a cache. If the cache
15171/// is empty, this function computes the pretty representation, put it
15172/// in the cache and returns it.
15173///
15174/// Note that if the type is *NOT* canonicalized, the pretty
15175/// representation is never cached.
15176///
15177/// @param internal if true, then the pretty representation is to be
15178/// used for purpuses that are internal to the libabigail library
15179/// itself. If you don't know what this means, then you probably
15180/// should set this parameter to "false".
15181const interned_string&
15183{
15184 if (internal)
15185 {
15186 if (!get_naked_canonical_type() || priv_->internal_cached_repr_.empty())
15187 {
15188 string r = ir::get_pretty_representation(this, internal);
15189 priv_->internal_cached_repr_ = get_environment().intern(r);
15190 }
15191 return priv_->internal_cached_repr_;
15192 }
15193
15194 if (!get_naked_canonical_type() || priv_->cached_repr_.empty())
15195 {
15196 string r = ir::get_pretty_representation(this, internal);
15197 priv_->cached_repr_ = get_environment().intern(r);
15198 }
15199
15200 return priv_->cached_repr_;
15201}
15202
15203/// Compares two instances of @ref type_base.
15204///
15205/// If the two intances are different, set a bitfield to give some
15206/// insight about the kind of differences there are.
15207///
15208/// @param l the first artifact of the comparison.
15209///
15210/// @param r the second artifact of the comparison.
15211///
15212/// @param k a pointer to a bitfield that gives information about the
15213/// kind of changes there are between @p l and @p r. This one is set
15214/// iff @p is non-null and if the function returns false.
15215///
15216/// Please note that setting k to a non-null value does have a
15217/// negative performance impact because even if @p l and @p r are not
15218/// equal, the function keeps up the comparison in order to determine
15219/// the different kinds of ways in which they are different.
15220///
15221/// @return true if @p l equals @p r, false otherwise.
15222bool
15223equals(const type_base& l, const type_base& r, change_kind* k)
15224{
15225 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
15227 if (!result)
15228 if (k)
15230 ABG_RETURN(result);
15231}
15232
15233/// Return true iff both type declarations are equal.
15234///
15235/// Note that this doesn't test if the scopes of both types are equal.
15236bool
15238{return equals(*this, other, 0);}
15239
15240/// Inequality operator.
15241///
15242///@param other the instance of @ref type_base to compare the current
15243/// instance against.
15244///
15245/// @return true iff the current instance is different from @p other.
15246bool
15248{return !operator==(other);}
15249
15250/// Setter for the size of the type.
15251///
15252/// @param s the new size -- in bits.
15253void
15255{priv_->size_in_bits = s;}
15256
15257/// Getter for the size of the type.
15258///
15259/// @return the size in bits of the type.
15260size_t
15262{return priv_->size_in_bits;}
15263
15264/// Setter for the alignment of the type.
15265///
15266/// @param a the new alignment -- in bits.
15267void
15269{priv_->alignment_in_bits = a;}
15270
15271/// Getter for the alignment of the type.
15272///
15273/// @return the alignment of the type in bits.
15274size_t
15276{return priv_->alignment_in_bits;}
15277
15278/// Default implementation of traversal for types. This function does
15279/// nothing. It must be implemented by every single new type that is
15280/// written.
15281///
15282/// Please look at e.g, class_decl::traverse() for an example of how
15283/// to implement this.
15284///
15285/// @param v the visitor used to visit the type.
15286bool
15288{
15289 if (v.type_node_has_been_visited(this))
15290 return true;
15291
15292 v.visit_begin(this);
15293 bool result = v.visit_end(this);
15295
15296 return result;
15297}
15298
15299type_base::~type_base()
15300{delete priv_;}
15301
15302// </type_base definitions>
15303
15304// <integral_type definitions>
15305
15306/// Bitwise OR operator for integral_type::modifiers_type.
15307///
15308/// @param l the left-hand side operand.
15309///
15310/// @param r the right-hand side operand.
15311///
15312/// @return the result of the bitwise OR.
15315{
15316 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
15317 |
15318 static_cast<unsigned>(r));
15319}
15320
15321/// Bitwise AND operator for integral_type::modifiers_type.
15322///
15323/// @param l the left-hand side operand.
15324///
15325/// @param r the right-hand side operand.
15326///
15327/// @return the result of the bitwise AND.
15330{
15331 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
15332 &
15333 static_cast<unsigned>(r));
15334}
15335
15336/// Bitwise one's complement operator for integral_type::modifiers_type.
15337///
15338/// @param l the left-hand side operand.
15339///
15340/// @param r the right-hand side operand.
15341///
15342/// @return the result of the bitwise one's complement operator.
15345{
15346 return static_cast<integral_type::modifiers_type>(~static_cast<unsigned>(l));
15347}
15348
15349/// Bitwise |= operator for integral_type::modifiers_type.
15350///
15351/// @param l the left-hand side operand.
15352///
15353/// @param r the right-hand side operand.
15354///
15355/// @return the result of the bitwise |=.
15358{
15359 l = l | r;
15360 return l;
15361}
15362
15363/// Bitwise &= operator for integral_type::modifiers_type.
15364///
15365/// @param l the left-hand side operand.
15366///
15367/// @param r the right-hand side operand.
15368///
15369/// @return the result of the bitwise &=.
15372{
15373 l = l & r;
15374 return l;
15375}
15376
15377/// Parse a word containing one integral type modifier.
15378///
15379/// A word is considered to be a string of characters that doesn't
15380/// contain any white space.
15381///
15382/// @param word the word to parse. It is considered to be a string of
15383/// characters that doesn't contain any white space.
15384///
15385/// @param modifiers out parameter. It's set by this function to the
15386/// parsed modifier iff the function returned true.
15387///
15388/// @return true iff @word was successfully parsed.
15389static bool
15390parse_integral_type_modifier(const string& word,
15392{
15393 if (word == "signed")
15394 modifiers |= integral_type::SIGNED_MODIFIER;
15395 else if (word == "unsigned")
15397 else if (word == "short")
15398 modifiers |= integral_type::SHORT_MODIFIER;
15399 else if (word == "long")
15400 modifiers |= integral_type::LONG_MODIFIER;
15401 else if (word == "long long")
15403 else
15404 return false;
15405
15406 return true;
15407}
15408
15409/// Parse a base type of an integral type from a string.
15410///
15411/// @param type_name the type name to parse.
15412///
15413/// @param base out parameter. This is set to the resulting base type
15414/// parsed, iff the function returned true.
15415///
15416/// @return true iff the function could successfully parse the base
15417/// type.
15418static bool
15419parse_base_integral_type(const string& type_name,
15421{
15422 if (type_name == "int")
15424 else if (type_name == "char")
15426 else if (type_name == "bool" || type_name == "_Bool")
15428 else if (type_name == "double")
15430 else if (type_name =="float")
15432 else if (type_name == "char16_t")
15434 else if (type_name == "char32_t")
15436 else if (type_name == "wchar_t")
15438 else
15439 return false;
15440
15441 return true;
15442}
15443
15444/// Parse an integral type from a string.
15445///
15446/// @param type_name the string containing the integral type to parse.
15447///
15448/// @param base out parameter. Is set by this function to the base
15449/// type of the integral type, iff the function returned true.
15450///
15451/// @param modifiers out parameter If set by this function to the
15452/// modifier of the integral type, iff the function returned true.
15453///
15454/// @return true iff the function could parse an integral type from @p
15455/// type_name.
15456static bool
15457parse_integral_type(const string& type_name,
15460{
15461 string input = type_name;
15462 string::size_type len = input.length();
15463 string::size_type cur_pos = 0, prev_pos = 0;
15464 string cur_word, prev_word;
15465 bool ok = false;
15466
15467 while (cur_pos < len)
15468 {
15469 if (cur_pos < len && isspace(input[cur_pos]))
15470 do
15471 ++cur_pos;
15472 while (cur_pos < len && isspace(input[cur_pos]));
15473
15474 prev_pos = cur_pos;
15475 cur_pos = input.find(' ', prev_pos);
15476 prev_word = cur_word;
15477 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
15478
15479 if (cur_pos < len
15480 && cur_word == "long"
15481 && prev_word != "long")
15482 {
15483 if (cur_pos < len && isspace(input[cur_pos]))
15484 do
15485 ++cur_pos;
15486 while (cur_pos < len && isspace(input[cur_pos]));
15487 prev_pos = cur_pos;
15488
15489 cur_pos = input.find(' ', prev_pos);
15490 string saved_prev_word = prev_word;
15491 prev_word = cur_word;
15492 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
15493 if (cur_word == "long")
15494 cur_word = "long long";
15495 else
15496 {
15497 cur_pos = prev_pos;
15498 cur_word = prev_word;
15499 prev_word = saved_prev_word;
15500 }
15501 }
15502
15503 if (!parse_integral_type_modifier(cur_word, modifiers))
15504 {
15505 if (!parse_base_integral_type(cur_word, base))
15506 return false;
15507 else
15508 ok = true;
15509 }
15510 else
15511 ok = true;
15512 }
15513
15514 return ok;
15515}
15516
15517/// Parse an integral type from a string.
15518///
15519/// @param str the string containing the integral type to parse.
15520///
15521///@param type the resulting @ref integral_type. Is set to the result
15522///of the parse, iff the function returns true.
15523///
15524/// @return true iff the function could parse an integral type from @p
15525/// str.
15526bool
15527parse_integral_type(const string& str, integral_type& type)
15528{
15530 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
15531
15532 if (!parse_integral_type(str, base_type, modifiers))
15533 return false;
15534
15535 // So this is an integral type.
15536 integral_type int_type(base_type, modifiers);
15537 type = int_type;
15538 return true;
15539}
15540
15541/// Default constructor of the @ref integral_type.
15543 : base_(INT_BASE_TYPE),
15544 modifiers_(NO_MODIFIER)
15545{}
15546
15547/// Constructor of the @ref integral_type.
15548///
15549/// @param b the base type of the integral type.
15550///
15551/// @param m the modifiers of the integral type.
15553 : base_(b), modifiers_(m)
15554{}
15555
15556/// Constructor of the @ref integral_type.
15557///
15558/// @param the name of the integral type to parse to initialize the
15559/// current instance of @ref integral_type.
15560integral_type::integral_type(const string& type_name)
15561 : base_(INT_BASE_TYPE),
15562 modifiers_(NO_MODIFIER)
15563{
15564 bool could_parse = parse_integral_type(type_name, base_, modifiers_);
15565 ABG_ASSERT(could_parse);
15566}
15567
15568/// Getter of the base type of the @ref integral_type.
15569///
15570/// @return the base type of the @ref integral_type.
15573{return base_;}
15574
15575/// Getter of the modifiers bitmap of the @ref integral_type.
15576///
15577/// @return the modifiers bitmap of the @ref integral_type.
15580{return modifiers_;}
15581
15582/// Setter of the modifiers bitmap of the @ref integral_type.
15583///
15584/// @param m the new modifiers.
15585void
15587{modifiers_ = m;}
15588
15589/// Equality operator for the @ref integral_type.
15590///
15591/// @param other the other integral type to compare against.
15592///
15593/// @return true iff @p other equals the current instance of @ref
15594/// integral_type.
15595bool
15597{return base_ == other.base_ && modifiers_ == other.modifiers_;}
15598
15599/// Return the string representation of the current instance of @ref
15600/// integral_type.
15601///
15602/// @param internal if true the string representation is to be used
15603/// for internal purposes. In general, it means it's for type
15604/// canonicalization purposes.
15605///
15606/// @return the string representation of the current instance of @ref
15607/// integral_type.
15608string
15609integral_type::to_string(bool internal) const
15610{
15611 string result;
15612
15613 // Look at modifiers ...
15614 if (modifiers_ & SIGNED_MODIFIER)
15615 result += "signed ";
15616 if (modifiers_ & UNSIGNED_MODIFIER)
15617 result += "unsigned ";
15618 if (!internal)
15619 {
15620 // For canonicalization purposes, we won't emit the "short, long, or
15621 // long long" modifiers. This is because on some platforms, "long
15622 // int" and "long long int" might have the same size. In those
15623 // cases, we want the two types to be equivalent if they have the
15624 // same size. If they don't have the same internal string
15625 // representation, they'd automatically have different canonical
15626 // types and thus be canonically different.
15627 if (modifiers_ & SHORT_MODIFIER)
15628 result += "short ";
15629 if (modifiers_ & LONG_MODIFIER)
15630 result += "long ";
15631 if (modifiers_ & LONG_LONG_MODIFIER)
15632 result += "long long ";
15633 }
15634
15635 // ... and look at base types.
15636 if (base_ == INT_BASE_TYPE)
15637 result += "int";
15638 else if (base_ == CHAR_BASE_TYPE)
15639 result += "char";
15640 else if (base_ == BOOL_BASE_TYPE)
15641 result += "bool";
15642 else if (base_ == DOUBLE_BASE_TYPE)
15643 result += "double";
15644 else if (base_ == FLOAT_BASE_TYPE)
15645 result += "float";
15646 else if (base_ == CHAR16_T_BASE_TYPE)
15647 result += "char16_t";
15648 else if (base_ == CHAR32_T_BASE_TYPE)
15649 result += "char32_t";
15650 else if (base_ == WCHAR_T_BASE_TYPE)
15651 result += "wchar_t";
15652
15653 return result;
15654}
15655
15656/// Convert the current instance of @ref integral_type into its string
15657/// representation.
15658///
15659/// @return the string representation of the current instance of @ref
15660/// integral_type.
15661integral_type::operator string() const
15662{return to_string();}
15663
15664// </integral_type definitions>
15665
15666//<type_decl definitions>
15667
15668/// Constructor.
15669///
15670/// @param env the environment we are operating from.
15671///
15672/// @param name the name of the type declaration.
15673///
15674/// @param size_in_bits the size of the current type_decl, in bits.
15675///
15676/// @param alignment_in_bits the alignment of the current typ, in
15677/// bits.
15678///
15679/// @param locus the source location of the current type declaration.
15680///
15681/// @param linkage_name the linkage_name of the current type declaration.
15682///
15683/// @param vis the visibility of the type declaration.
15684type_decl::type_decl(const environment& env,
15685 const string& name,
15686 size_t size_in_bits,
15687 size_t alignment_in_bits,
15688 const location& locus,
15689 const string& linkage_name,
15690 visibility vis)
15691
15692 : type_or_decl_base(env,
15693 BASIC_TYPE
15694 | ABSTRACT_TYPE_BASE
15695 | ABSTRACT_DECL_BASE),
15696 decl_base(env, name, locus, linkage_name, vis),
15697 type_base(env, size_in_bits, alignment_in_bits)
15698{
15700
15702 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
15703 integral_type int_type(base_type, modifiers);
15704 if (parse_integral_type(name, int_type))
15705 {
15706 // Convert the integral_type into its canonical string
15707 // representation.
15708 string integral_type_name = int_type;
15709
15710 // Set the name of this type_decl to the canonical string
15711 // representation above
15712 set_name(integral_type_name);
15714
15715 if (!get_linkage_name().empty())
15716 set_linkage_name(integral_type_name);
15717 }
15718}
15719
15720/// Compares two instances of @ref type_decl.
15721///
15722/// If the two intances are different, set a bitfield to give some
15723/// insight about the kind of differences there are.
15724///
15725/// @param l the first artifact of the comparison.
15726///
15727/// @param r the second artifact of the comparison.
15728///
15729/// @param k a pointer to a bitfield that gives information about the
15730/// kind of changes there are between @p l and @p r. This one is set
15731/// iff @p k is non-null and the function returns false.
15732///
15733/// Please note that setting k to a non-null value does have a
15734/// negative performance impact because even if @p l and @p r are not
15735/// equal, the function keeps up the comparison in order to determine
15736/// the different kinds of ways in which they are different.
15737///
15738/// @return true if @p l equals @p r, false otherwise.
15739bool
15740equals(const type_decl& l, const type_decl& r, change_kind* k)
15741{
15742 bool result = false;
15743
15744 // Consider the types as decls to compare their decls-related
15745 // properties.
15746 result = equals(static_cast<const decl_base&>(l),
15747 static_cast<const decl_base&>(r),
15748 k);
15749 if (!k && !result)
15751
15752 // Now consider the types a "types' to compare their size-related
15753 // properties.
15754 result &= equals(static_cast<const type_base&>(l),
15755 static_cast<const type_base&>(r),
15756 k);
15757 ABG_RETURN(result);
15758}
15759
15760/// Return true if both types equals.
15761///
15762/// This operator re-uses the overload that takes a decl_base.
15763///
15764/// Note that this does not check the scopes of any of the types.
15765///
15766/// @param o the other type_decl to check agains.
15767bool
15769{
15770 const decl_base* other = dynamic_cast<const decl_base*>(&o);
15771 if (!other)
15772 return false;
15773 return *this == *other;
15774}
15775
15776/// Return true if both types equals.
15777///
15778/// Note that this does not check the scopes of any of the types.
15779///
15780/// @param o the other type_decl to check against.
15781bool
15783{
15784 const type_decl* other = dynamic_cast<const type_decl*>(&o);
15785 if (!other)
15786 return false;
15787 return try_canonical_compare(this, other);
15788}
15789
15790/// Return true if both types equals.
15791///
15792/// Note that this does not check the scopes of any of the types.
15793///
15794/// @param o the other type_decl to check against.
15795///
15796/// @return true iff the current isntance equals @p o
15797bool
15799{
15800 const decl_base& other = o;
15801 return *this == other;
15802}
15803
15804/// Return true if both types equals.
15805///
15806/// Note that this does not check the scopes of any of the types.
15807///
15808/// @param o the other type_decl to check against.
15809///
15810/// @return true iff the current isntance equals @p o
15811bool
15813{return !operator==(o);}
15814
15815/// Return true if both types equals.
15816///
15817/// Note that this does not check the scopes of any of the types.
15818///
15819/// @param o the other type_decl to check against.
15820///
15821/// @return true iff the current isntance equals @p o
15822bool
15824{return !operator==(o);}
15825
15826/// Inequality operator.
15827///
15828/// @param o the other type to compare against.
15829///
15830/// @return true iff the current instance is different from @p o.
15831bool
15833{return !operator==(o);}
15834
15835/// Equality operator for @ref type_decl_sptr.
15836///
15837/// @param l the first operand to compare.
15838///
15839/// @param r the second operand to compare.
15840///
15841/// @return true iff @p l equals @p r.
15842bool
15844{
15845 if (!!l != !!r)
15846 return false;
15847 if (l.get() == r.get())
15848 return true;
15849 return *l == *r;
15850}
15851
15852/// Inequality operator for @ref type_decl_sptr.
15853///
15854/// @param l the first operand to compare.
15855///
15856/// @param r the second operand to compare.
15857///
15858/// @return true iff @p l is different from @p r.
15859bool
15861{return !operator==(l, r);}
15862
15863/// Implementation for the virtual qualified name builder for @ref
15864/// type_decl.
15865///
15866/// @param qualified_name the output parameter to hold the resulting
15867/// qualified name.
15868///
15869/// @param internal set to true if the call is intended for an
15870/// internal use (for technical use inside the library itself), false
15871/// otherwise. If you don't know what this is for, then set it to
15872/// false.
15873void
15875 bool internal) const
15876{qualified_name = get_qualified_name(internal);}
15877
15878/// Implementation for the virtual qualified name builder for @ref
15879/// type_decl.
15880///
15881/// @param qualified_name the output parameter to hold the resulting
15882/// qualified name.
15883///
15884/// @param internal set to true if the call is intended for an
15885/// internal use (for technical use inside the library itself), false
15886/// otherwise. If you don't know what this is for, then set it to
15887/// false.
15888const interned_string&
15890{
15891 const environment& env = get_environment();
15892
15893
15894 if (internal)
15895 if (is_integral_type(this))
15896 {
15898 {
15899 if (decl_base::priv_->internal_qualified_name_.empty())
15900 decl_base::priv_->internal_qualified_name_ =
15901 env.intern(get_internal_integral_type_name(this));
15902 return decl_base::priv_->internal_qualified_name_;
15903 }
15904 else
15905 {
15906 decl_base::priv_->temporary_internal_qualified_name_ =
15907 env.intern(get_internal_integral_type_name(this));
15908 return decl_base::priv_->temporary_internal_qualified_name_;
15909 }
15910 }
15911
15912 return decl_base::get_qualified_name(/*internal=*/false);
15913}
15914
15915/// Get the pretty representation of the current instance of @ref
15916/// type_decl.
15917///
15918/// @param internal set to true if the call is intended to get a
15919/// representation of the decl (or type) for the purpose of canonical
15920/// type comparison. This is mainly used in the function
15921/// type_base::get_canonical_type_for().
15922///
15923/// In other words if the argument for this parameter is true then the
15924/// call is meant for internal use (for technical use inside the
15925/// library itself), false otherwise. If you don't know what this is
15926/// for, then set it to false.
15927///
15928/// @param qualified_name if true, names emitted in the pretty
15929/// representation are fully qualified.
15930///
15931/// @return the pretty representatin of the @ref type_decl.
15932string
15934 bool qualified_name) const
15935{
15936 if (internal)
15937 if (is_integral_type(this))
15938 return get_internal_integral_type_name(this);
15939
15940 if (qualified_name)
15941 return get_qualified_name(internal);
15942 return get_name();
15943}
15944
15945/// This implements the ir_traversable_base::traverse pure virtual
15946/// function.
15947///
15948/// @param v the visitor used on the current instance.
15949///
15950/// @return true if the entire IR node tree got traversed, false
15951/// otherwise.
15952bool
15954{
15955 if (v.type_node_has_been_visited(this))
15956 return true;
15957
15958 v.visit_begin(this);
15959 bool result = v.visit_end(this);
15961
15962 return result;
15963}
15964
15965type_decl::~type_decl()
15966{}
15967//</type_decl definitions>
15968
15969// <scope_type_decl definitions>
15970
15971/// Constructor.
15972///
15973/// @param env the environment we are operating from.
15974///
15975/// @param name the name of the type.
15976///
15977/// @param size_in_bits the size of the type, in bits.
15978///
15979/// @param alignment_in_bits the alignment of the type, in bits.
15980///
15981/// @param locus the source location where the type is defined.
15982///
15983/// @param vis the visibility of the type.
15984scope_type_decl::scope_type_decl(const environment& env,
15985 const string& name,
15986 size_t size_in_bits,
15987 size_t alignment_in_bits,
15988 const location& locus,
15989 visibility vis)
15990 : type_or_decl_base(env,
15991 ABSTRACT_SCOPE_TYPE_DECL
15992 | ABSTRACT_TYPE_BASE
15993 | ABSTRACT_DECL_BASE),
15994 decl_base(env, name, locus, "", vis),
15995 type_base(env, size_in_bits, alignment_in_bits),
15996 scope_decl(env, name, locus)
15997{}
15998
15999/// Compares two instances of @ref scope_type_decl.
16000///
16001/// If the two intances are different, set a bitfield to give some
16002/// insight about the kind of differences there are.
16003///
16004/// @param l the first artifact of the comparison.
16005///
16006/// @param r the second artifact of the comparison.
16007///
16008/// @param k a pointer to a bitfield that gives information about the
16009/// kind of changes there are between @p l and @p r. This one is set
16010/// iff @p k is non-null and the function returns false.
16011///
16012/// Please note that setting k to a non-null value does have a
16013/// negative performance impact because even if @p l and @p r are not
16014/// equal, the function keeps up the comparison in order to determine
16015/// the different kinds of ways in which they are different.
16016///
16017/// @return true if @p l equals @p r, false otherwise.
16018bool
16020{
16021 bool result = equals(static_cast<const scope_decl&>(l),
16022 static_cast<const scope_decl&>(r),
16023 k);
16024
16025 if (!k && !result)
16027
16028 result &= equals(static_cast<const type_base&>(l),
16029 static_cast<const type_base&>(r),
16030 k);
16031
16032 ABG_RETURN(result);
16033}
16034
16035/// Equality operator between two scope_type_decl.
16036///
16037/// Note that this function does not consider the scope of the scope
16038/// types themselves.
16039///
16040/// @return true iff both scope types are equal.
16041bool
16043{
16044 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
16045 if (!other)
16046 return false;
16047 return try_canonical_compare(this, other);
16048}
16049
16050/// Equality operator between two scope_type_decl.
16051///
16052/// This re-uses the equality operator that takes a decl_base.
16053///
16054/// @param o the other scope_type_decl to compare against.
16055///
16056/// @return true iff both scope types are equal.
16057bool
16059{
16060 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16061 if (!other)
16062 return false;
16063
16064 return *this == *other;
16065}
16066
16067/// Traverses an instance of @ref scope_type_decl, visiting all the
16068/// sub-types and decls that it might contain.
16069///
16070/// @param v the visitor that is used to visit every IR sub-node of
16071/// the current node.
16072///
16073/// @return true if either
16074/// - all the children nodes of the current IR node were traversed
16075/// and the calling code should keep going with the traversing.
16076/// - or the current IR node is already being traversed.
16077/// Otherwise, returning false means that the calling code should not
16078/// keep traversing the tree.
16079bool
16081{
16082 if (visiting())
16083 return true;
16084
16085 if (v.type_node_has_been_visited(this))
16086 return true;
16087
16088 if (v.visit_begin(this))
16089 {
16090 visiting(true);
16091 for (scope_decl::declarations::const_iterator i =
16092 get_member_decls().begin();
16093 i != get_member_decls ().end();
16094 ++i)
16095 if (!(*i)->traverse(v))
16096 break;
16097 visiting(false);
16098 }
16099
16100 bool result = v.visit_end(this);
16102
16103 return result;
16104}
16105
16106scope_type_decl::~scope_type_decl()
16107{}
16108// </scope_type_decl definitions>
16109
16110// <namespace_decl>
16111
16112/// Constructor.
16113///
16114/// @param the environment we are operatin from.
16115///
16116/// @param name the name of the namespace.
16117///
16118/// @param locus the source location where the namespace is defined.
16119///
16120/// @param vis the visibility of the namespace.
16122 const string& name,
16123 const location& locus,
16124 visibility vis)
16125 // We need to call the constructor of decl_base directly here
16126 // because it is virtually inherited by scope_decl. Note that we
16127 // just implicitely call the default constructor for scope_decl
16128 // here, as what we really want is to initialize the decl_base
16129 // subobject. Wow, virtual inheritance is useful, but setting it
16130 // up is ugly.
16131 : type_or_decl_base(env,
16132 NAMESPACE_DECL
16133 | ABSTRACT_DECL_BASE
16134 | ABSTRACT_SCOPE_DECL),
16135 decl_base(env, name, locus, "", vis),
16136 scope_decl(env, name, locus)
16137{
16139}
16140
16141/// Build and return a copy of the pretty representation of the
16142/// namespace.
16143///
16144/// @param internal set to true if the call is intended to get a
16145/// representation of the decl (or type) for the purpose of canonical
16146/// type comparison. This is mainly used in the function
16147/// type_base::get_canonical_type_for().
16148///
16149/// In other words if the argument for this parameter is true then the
16150/// call is meant for internal use (for technical use inside the
16151/// library itself), false otherwise. If you don't know what this is
16152/// for, then set it to false.
16153///
16154/// @param qualified_name if true, names emitted in the pretty
16155/// representation are fully qualified.
16156///
16157/// @return a copy of the pretty representation of the namespace.
16158string
16160 bool qualified_name) const
16161{
16162 string r =
16163 "namespace " + scope_decl::get_pretty_representation(internal,
16164 qualified_name);
16165 return r;
16166}
16167
16168/// Return true iff both namespaces and their members are equal.
16169///
16170/// Note that this function does not check if the scope of these
16171/// namespaces are equal.
16172bool
16174{
16175 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
16176 if (!other)
16177 return false;
16178 return scope_decl::operator==(*other);
16179}
16180
16181/// Test if the current namespace_decl is empty or contains empty
16182/// namespaces itself.
16183///
16184/// @return true iff the current namespace_decl is empty or contains
16185/// empty itself.
16186bool
16188{
16189 if (is_empty())
16190 return true;
16191
16192 for (declarations::const_iterator i = get_member_decls().begin();
16193 i != get_member_decls().end();
16194 ++i)
16195 {
16196 if (!is_namespace(*i))
16197 return false;
16198
16200 ABG_ASSERT(ns);
16201
16202 if (!ns->is_empty_or_has_empty_sub_namespaces())
16203 return false;
16204 }
16205
16206 return true;
16207}
16208
16209/// This implements the ir_traversable_base::traverse pure virtual
16210/// function.
16211///
16212/// @param v the visitor used on the current instance and on its
16213/// member nodes.
16214///
16215/// @return true if the entire IR node tree got traversed, false
16216/// otherwise.
16217bool
16219{
16220 if (visiting())
16221 return true;
16222
16223 if (v.visit_begin(this))
16224 {
16225 visiting(true);
16226 scope_decl::declarations::const_iterator i;
16227 for (i = get_member_decls().begin();
16228 i != get_member_decls ().end();
16229 ++i)
16230 {
16232 dynamic_pointer_cast<ir_traversable_base>(*i);
16233 if (t)
16234 if (!t->traverse (v))
16235 break;
16236 }
16237 visiting(false);
16238 }
16239 return v.visit_end(this);
16240}
16241
16242namespace_decl::~namespace_decl()
16243{
16244}
16245
16246// </namespace_decl>
16247
16248// <qualified_type_def>
16249
16250/// Type of the private data of qualified_type_def.
16251class qualified_type_def::priv
16252{
16253 friend class qualified_type_def;
16254
16255 qualified_type_def::CV cv_quals_;
16256 // Before the type is canonicalized, this is used as a temporary
16257 // internal name.
16258 interned_string temporary_internal_name_;
16259 // Once the type is canonicalized, this is used as the internal
16260 // name.
16261 interned_string internal_name_;
16262 weak_ptr<type_base> underlying_type_;
16263
16264 priv()
16265 : cv_quals_(CV_NONE)
16266 {}
16267
16268 priv(qualified_type_def::CV quals,
16269 type_base_sptr t)
16270 : cv_quals_(quals),
16271 underlying_type_(t)
16272 {}
16273
16274 priv(qualified_type_def::CV quals)
16275 : cv_quals_(quals)
16276 {}
16277};// end class qualified_type_def::priv
16278
16279/// Build the name of the current instance of qualified type.
16280///
16281/// @param fully_qualified if true, build a fully qualified name.
16282///
16283/// @param internal set to true if the call is intended for an
16284/// internal use (for technical use inside the library itself), false
16285/// otherwise. If you don't know what this is for, then set it to
16286/// false.
16287///
16288/// @return a copy of the newly-built name.
16289string
16290qualified_type_def::build_name(bool fully_qualified, bool internal) const
16291{
16292 type_base_sptr t = get_underlying_type();
16293 if (!t)
16294 // The qualified type might temporarily have no underlying type,
16295 // especially during the construction of the type, while the
16296 // underlying type is not yet constructed. In that case, let's do
16297 // like if the underlying type is the 'void' type.
16299
16301 fully_qualified,
16302 internal);
16303}
16304
16305/// This function is automatically invoked whenever an instance of
16306/// this type is canonicalized.
16307///
16308/// It's an overload of the virtual type_base::on_canonical_type_set.
16309///
16310/// We put here what is thus meant to be executed only at the point of
16311/// type canonicalization.
16312void
16315
16316/// Constructor of the qualified_type_def
16317///
16318/// @param type the underlying type
16319///
16320/// @param quals a bitfield representing the const/volatile qualifiers
16321///
16322/// @param locus the location of the qualified type definition
16323qualified_type_def::qualified_type_def(type_base_sptr type,
16324 CV quals,
16325 const location& locus)
16326 : type_or_decl_base(type->get_environment(),
16327 QUALIFIED_TYPE
16328 | ABSTRACT_TYPE_BASE
16329 | ABSTRACT_DECL_BASE),
16330 type_base(type->get_environment(), type->get_size_in_bits(),
16331 type->get_alignment_in_bits()),
16332 decl_base(type->get_environment(), "", locus, "",
16333 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
16334 priv_(new priv(quals, type))
16335{
16337 interned_string name = type->get_environment().intern(build_name(false));
16338 set_name(name);
16339}
16340
16341/// Constructor of the qualified_type_def
16342///
16343/// @param env the environment of the type.
16344///
16345/// @param quals a bitfield representing the const/volatile qualifiers
16346///
16347/// @param locus the location of the qualified type definition
16348qualified_type_def::qualified_type_def(const environment& env,
16349 CV quals,
16350 const location& locus)
16351 : type_or_decl_base(env,
16352 QUALIFIED_TYPE
16353 | ABSTRACT_TYPE_BASE
16354 | ABSTRACT_DECL_BASE),
16355 type_base(env, /*size_in_bits=*/0,
16356 /*alignment_in_bits=*/0),
16357 decl_base(env, "", locus, ""),
16358 priv_(new priv(quals))
16359{
16361 // We don't yet have an underlying type. So for naming purpose,
16362 // let's temporarily pretend the underlying type is 'void'.
16363 interned_string name = env.intern("void");
16364 set_name(name);
16365}
16366
16367/// Get the size of the qualified type def.
16368///
16369/// This is an overload for type_base::get_size_in_bits().
16370///
16371/// @return the size of the qualified type.
16372size_t
16374{
16375 size_t s = 0;
16376 if (type_base_sptr ut = get_underlying_type())
16377 {
16378 // We do have the underlying type properly set, so let's make
16379 // the size of the qualified type match the size of its
16380 // underlying type.
16381 s = ut->get_size_in_bits();
16382 if (s != type_base::get_size_in_bits())
16383 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
16384 }
16386}
16387
16388/// Compares two instances of @ref qualified_type_def.
16389///
16390/// If the two intances are different, set a bitfield to give some
16391/// insight about the kind of differences there are.
16392///
16393/// @param l the first artifact of the comparison.
16394///
16395/// @param r the second artifact of the comparison.
16396///
16397/// @param k a pointer to a bitfield that gives information about the
16398/// kind of changes there are between @p l and @p r. This one is set
16399/// iff @p k is non-null and the function returns false.
16400///
16401/// Please note that setting k to a non-null value does have a
16402/// negative performance impact because even if @p l and @p r are not
16403/// equal, the function keeps up the comparison in order to determine
16404/// the different kinds of ways in which they are different.
16405///
16406/// @return true if @p l equals @p r, false otherwise.
16407bool
16409{
16410 bool result = true;
16411 if (l.get_cv_quals() != r.get_cv_quals())
16412 {
16413 result = false;
16414 if (k)
16416 else
16418 }
16419
16421 {
16422 result = false;
16423 if (k)
16424 {
16426 r.get_underlying_type().get()))
16427 // Underlying type changes in which the structure of the
16428 // type changed are considered local changes to the
16429 // qualified type.
16431 else
16432 *k |= SUBTYPE_CHANGE_KIND;
16433 }
16434 else
16435 // okay strictly speaking this is not necessary, but I am
16436 // putting it here to maintenance; that is, so that adding
16437 // subsequent clauses needed to compare two qualified types
16438 // later still works.
16440 }
16441
16442 ABG_RETURN(result);
16443}
16444
16445/// Equality operator for qualified types.
16446///
16447/// Note that this function does not check for equality of the scopes.
16448///
16449///@param o the other qualified type to compare against.
16450///
16451/// @return true iff both qualified types are equal.
16452bool
16454{
16455 const qualified_type_def* other =
16456 dynamic_cast<const qualified_type_def*>(&o);
16457 if (!other)
16458 return false;
16459 return try_canonical_compare(this, other);
16460}
16461
16462/// Equality operator for qualified types.
16463///
16464/// Note that this function does not check for equality of the scopes.
16465/// Also, this re-uses the equality operator above that takes a
16466/// decl_base.
16467///
16468///@param o the other qualified type to compare against.
16469///
16470/// @return true iff both qualified types are equal.
16471bool
16473{
16474 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16475 if (!other)
16476 return false;
16477 return *this == *other;
16478}
16479
16480/// Equality operator for qualified types.
16481///
16482/// Note that this function does not check for equality of the scopes.
16483/// Also, this re-uses the equality operator above that takes a
16484/// decl_base.
16485///
16486///@param o the other qualified type to compare against.
16487///
16488/// @return true iff both qualified types are equal.
16489bool
16491{
16492 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16493 if (!other)
16494 return false;
16495 return *this == *other;
16496}
16497
16498/// Implementation for the virtual qualified name builder for @ref
16499/// qualified_type_def.
16500///
16501/// @param qualified_name the output parameter to hold the resulting
16502/// qualified name.
16503///
16504/// @param internal set to true if the call is intended for an
16505/// internal use (for technical use inside the library itself), false
16506/// otherwise. If you don't know what this is for, then set it to
16507/// false.
16508void
16510 bool internal) const
16511{qualified_name = get_qualified_name(internal);}
16512
16513/// Implementation of the virtual qualified name builder/getter.
16514///
16515/// @param internal set to true if the call is intended for an
16516/// internal use (for technical use inside the library itself), false
16517/// otherwise. If you don't know what this is for, then set it to
16518/// false.
16519///
16520/// @return the resulting qualified name.
16521const interned_string&
16523{
16524 const environment& env = get_environment();
16525
16526
16527 if (!get_canonical_type())
16528 {
16529 // The type hasn't been canonicalized yet. We want to return a
16530 // temporary name that is not cached because the structure of
16531 // this type (and so its name) can change until its
16532 // canonicalized.
16533 if (internal)
16534 {
16535 // We are asked to return a temporary *internal* name.
16536 // Lets compute it and return a reference to where it's
16537 // stored.
16538 priv_->temporary_internal_name_ =
16539 env.intern(build_name(true, /*internal=*/true));
16540 return priv_->temporary_internal_name_;
16541 }
16542 else
16543 {
16544 // We are asked to return a temporary non-internal name.
16546 (env.intern(build_name(true, /*internal=*/false)));
16548 }
16549 }
16550 else
16551 {
16552 // The type has already been canonicalized. We want to return
16553 // the definitive name and cache it.
16554 if (internal)
16555 {
16556 if (priv_->internal_name_.empty())
16557 priv_->internal_name_ =
16558 env.intern(build_name(/*qualified=*/true,
16559 /*internal=*/true));
16560 return priv_->internal_name_;
16561 }
16562 else
16563 {
16564 if (peek_qualified_name().empty())
16566 (env.intern(build_name(/*qualified=*/true,
16567 /*internal=*/false)));
16568 return peek_qualified_name();
16569 }
16570 }
16571}
16572
16573/// This implements the ir_traversable_base::traverse pure virtual
16574/// function.
16575///
16576/// @param v the visitor used on the current instance.
16577///
16578/// @return true if the entire IR node tree got traversed, false
16579/// otherwise.
16580bool
16582{
16583 if (v.type_node_has_been_visited(this))
16584 return true;
16585
16586 if (visiting())
16587 return true;
16588
16589 if (v.visit_begin(this))
16590 {
16591 visiting(true);
16592 if (type_base_sptr t = get_underlying_type())
16593 t->traverse(v);
16594 visiting(false);
16595 }
16596 bool result = v.visit_end(this);
16598 return result;
16599}
16600
16601qualified_type_def::~qualified_type_def()
16602{
16603}
16604
16605/// Getter of the const/volatile qualifier bit field
16608{return priv_->cv_quals_;}
16609
16610/// Setter of the const/value qualifiers bit field
16611void
16613{priv_->cv_quals_ = cv_quals;}
16614
16615/// Compute and return the string prefix or suffix representing the
16616/// qualifiers hold by the current instance of @ref
16617/// qualified_type_def.
16618///
16619/// @return the newly-built cv string.
16620string
16622{return get_string_representation_of_cv_quals(priv_->cv_quals_);}
16623
16624/// Getter of the underlying type
16625type_base_sptr
16627{return priv_->underlying_type_.lock();}
16628
16629/// Setter of the underlying type.
16630///
16631/// @param t the new underlying type.
16632void
16634{
16635 ABG_ASSERT(t);
16636 priv_->underlying_type_ = t;
16637 // Now we need to update other properties that depend on the new underlying type.
16638 set_size_in_bits(t->get_size_in_bits());
16639 set_alignment_in_bits(t->get_alignment_in_bits());
16641 set_name(name);
16642 if (scope_decl* s = get_scope())
16643 {
16644 // Now that the name has been updated, we need to update the
16645 // lookup maps accordingly.
16646 scope_decl::declarations::iterator i;
16647 if (s->find_iterator_for_member(this, i))
16649 else
16651 }
16652}
16653
16654/// Non-member equality operator for @ref qualified_type_def
16655///
16656/// @param l the left-hand side of the equality operator
16657///
16658/// @param r the right-hand side of the equality operator
16659///
16660/// @return true iff @p l and @p r equals.
16661bool
16662operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
16663{
16664 if (l.get() == r.get())
16665 return true;
16666 if (!!l != !!r)
16667 return false;
16668
16669 return *l == *r;
16670}
16671
16672/// Non-member inequality operator for @ref qualified_type_def
16673///
16674/// @param l the left-hand side of the equality operator
16675///
16676/// @param r the right-hand side of the equality operator
16677///
16678/// @return true iff @p l and @p r equals.
16679bool
16680operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
16681{return ! operator==(l, r);}
16682
16683/// Overloaded bitwise OR operator for cv qualifiers.
16686{
16687 return static_cast<qualified_type_def::CV>
16688 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
16689}
16690
16691/// Overloaded bitwise |= operator for cv qualifiers.
16694{
16695 l = l | r;
16696 return l;
16697}
16698
16699/// Overloaded bitwise &= operator for cv qualifiers.
16702{
16703 l = l & r;
16704 return l;
16705}
16706
16707/// Overloaded bitwise AND operator for CV qualifiers.
16710{
16711 return static_cast<qualified_type_def::CV>
16712 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
16713}
16714
16715/// Overloaded bitwise inverting operator for CV qualifiers.
16718{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
16719
16720/// Streaming operator for qualified_type_decl::CV
16721///
16722/// @param o the output stream to serialize the cv qualifier to.
16723///
16724/// @param cv the cv qualifier to serialize.
16725///
16726/// @return the output stream used.
16727std::ostream&
16728operator<<(std::ostream& o, qualified_type_def::CV cv)
16729{
16730 string str;
16731
16732 switch (cv)
16733 {
16734 case qualified_type_def::CV_NONE:
16735 str = "none";
16736 break;
16737 case qualified_type_def::CV_CONST:
16738 str = "const";
16739 break;
16740 case qualified_type_def::CV_VOLATILE:
16741 str = "volatile";
16742 break;
16743 case qualified_type_def::CV_RESTRICT:
16744 str = "restrict";
16745 break;
16746 }
16747
16748 o << str;
16749 return o;
16750}
16751
16752// </qualified_type_def>
16753
16754//<pointer_type_def definitions>
16755
16756/// Private data structure of the @ref pointer_type_def.
16757struct pointer_type_def::priv
16758{
16759 type_base_wptr pointed_to_type_;
16760 type_base* naked_pointed_to_type_;
16761 interned_string internal_qualified_name_;
16762 interned_string temp_internal_qualified_name_;
16763
16764 priv(const type_base_sptr& t)
16765 : pointed_to_type_(type_or_void(t, t->get_environment())),
16766 naked_pointed_to_type_(t.get())
16767 {}
16768
16769 priv()
16770 : naked_pointed_to_type_()
16771 {}
16772}; //end struct pointer_type_def
16773
16774/// This function is automatically invoked whenever an instance of
16775/// this type is canonicalized.
16776///
16777/// It's an overload of the virtual type_base::on_canonical_type_set.
16778///
16779/// We put here what is thus meant to be executed only at the point of
16780/// type canonicalization.
16781void
16784
16785
16786///Constructor of @ref pointer_type_def.
16787///
16788/// @param pointed_to the pointed-to type.
16789///
16790/// @param size_in_bits the size of the type, in bits.
16791///
16792/// @param align_in_bits the alignment of the type, in bits.
16793///
16794/// @param locus the source location where the type was defined.
16795pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
16796 size_t size_in_bits,
16797 size_t align_in_bits,
16798 const location& locus)
16799 : type_or_decl_base(pointed_to->get_environment(),
16800 POINTER_TYPE
16801 | ABSTRACT_TYPE_BASE
16802 | ABSTRACT_DECL_BASE),
16803 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
16804 decl_base(pointed_to->get_environment(), "", locus, ""),
16805 priv_(new priv(pointed_to))
16806{
16808 try
16809 {
16810 ABG_ASSERT(pointed_to);
16811 const environment& env = pointed_to->get_environment();
16812 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
16813 string name = (pto ? pto->get_name() : string("void")) + "*";
16814 set_name(env.intern(name));
16815 if (pto)
16816 set_visibility(pto->get_visibility());
16817 }
16818 catch (...)
16819 {}
16820}
16821
16822///Constructor of @ref pointer_type_def.
16823///
16824/// @param env the environment of the type.
16825///
16826/// @param size_in_bits the size of the type, in bits.
16827///
16828/// @param align_in_bits the alignment of the type, in bits.
16829///
16830/// @param locus the source location where the type was defined.
16831pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
16832 size_t alignment_in_bits,
16833 const location& locus)
16834 : type_or_decl_base(env,
16835 POINTER_TYPE
16836 | ABSTRACT_TYPE_BASE
16837 | ABSTRACT_DECL_BASE),
16838 type_base(env, size_in_bits, alignment_in_bits),
16839 decl_base(env, "", locus, ""),
16840 priv_(new priv())
16841{
16843 string name = string("void") + "*";
16844 set_name(env.intern(name));
16845}
16846
16847/// Set the pointed-to type of the pointer.
16848///
16849/// @param t the new pointed-to type.
16850void
16852{
16853 ABG_ASSERT(t);
16854 priv_->pointed_to_type_ = t;
16855 priv_->naked_pointed_to_type_ = t.get();
16856
16857 try
16858 {
16859 const environment& env = t->get_environment();
16860 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
16861 string name = (pto ? pto->get_name() : string("void")) + "*";
16862 set_name(env.intern(name));
16863 if (pto)
16864 set_visibility(pto->get_visibility());
16865 }
16866 catch (...)
16867 {}
16868}
16869
16870/// Compares two instances of @ref pointer_type_def.
16871///
16872/// If the two intances are different, set a bitfield to give some
16873/// insight about the kind of differences there are.
16874///
16875/// @param l the first artifact of the comparison.
16876///
16877/// @param r the second artifact of the comparison.
16878///
16879/// @param k a pointer to a bitfield that gives information about the
16880/// kind of changes there are between @p l and @p r. This one is set
16881/// iff @p k is non-null and the function returns false.
16882///
16883/// Please note that setting k to a non-null value does have a
16884/// negative performance impact because even if @p l and @p r are not
16885/// equal, the function keeps up the comparison in order to determine
16886/// the different kinds of ways in which they are different.
16887///
16888/// @return true if @p l equals @p r, false otherwise.
16889bool
16891{
16892 // In C and C++ languages, a pointer to void equals all other
16893 // pointers.
16894 if (l.get_translation_unit()
16900 return true;
16901
16902 bool result = l.get_pointed_to_type() == r.get_pointed_to_type();
16903 if (!result)
16904 if (k)
16905 {
16906 if (!types_have_similar_structure(&l, &r))
16907 // pointed-to type changes in which the structure of the
16908 // type changed are considered local changes to the pointer
16909 // type.
16911 *k |= SUBTYPE_CHANGE_KIND;
16912 }
16913
16914 ABG_RETURN(result);
16915}
16916
16917/// Return true iff both instances of pointer_type_def are equal.
16918///
16919/// Note that this function does not check for the scopes of the this
16920/// types.
16921bool
16923{
16924 const pointer_type_def* other = is_pointer_type(&o);
16925 if (!other)
16926 return false;
16927 return try_canonical_compare(this, other);
16928}
16929
16930/// Return true iff both instances of pointer_type_def are equal.
16931///
16932/// Note that this function does not check for the scopes of the
16933/// types.
16934///
16935/// @param other the other type to compare against.
16936///
16937/// @return true iff @p other equals the current instance.
16938bool
16940{
16941 const decl_base* o = is_decl(&other);
16942 if (!o)
16943 return false;
16944 return *this == *o;
16945}
16946
16947/// Return true iff both instances of pointer_type_def are equal.
16948///
16949/// Note that this function does not check for the scopes of the
16950/// types.
16951///
16952/// @param other the other type to compare against.
16953///
16954/// @return true iff @p other equals the current instance.
16955bool
16957{
16958 const decl_base& o = other;
16959 return *this == o;
16960}
16961
16962/// Getter of the pointed-to type.
16963///
16964/// @return the pointed-to type.
16965const type_base_sptr
16967{return priv_->pointed_to_type_.lock();}
16968
16969/// Getter of a naked pointer to the pointed-to type.
16970///
16971/// @return a naked pointed to the pointed-to type.
16972type_base*
16974{return priv_->naked_pointed_to_type_;}
16975
16976/// Build and return the qualified name of the current instance of
16977/// @ref pointer_type_def.
16978///
16979/// @param qn output parameter. The resulting qualified name.
16980///
16981/// @param internal set to true if the call is intended for an
16982/// internal use (for technical use inside the library itself), false
16983/// otherwise. If you don't know what this is for, then set it to
16984/// false.
16985void
16987{qn = get_qualified_name(internal);}
16988
16989/// Build, cache and return the qualified name of the current instance
16990/// of @ref pointer_type_def. Subsequent invocations of this function
16991/// return the cached value.
16992///
16993/// Note that this function should work even if the underlying type is
16994/// momentarily empty.
16995///
16996/// @param internal set to true if the call is intended for an
16997/// internal use (for technical use inside the library itself), false
16998/// otherwise. If you don't know what this is for, then set it to
16999/// false.
17000///
17001/// @return the resulting qualified name.
17002const interned_string&
17004{
17005 type_base* pointed_to_type = get_naked_pointed_to_type();
17006 pointed_to_type = look_through_decl_only(pointed_to_type);
17007
17008 if (internal)
17009 {
17010 if (get_canonical_type())
17011 {
17012 if (priv_->internal_qualified_name_.empty())
17013 if (pointed_to_type)
17014 priv_->internal_qualified_name_ =
17015 get_name_of_pointer_to_type(*pointed_to_type,
17016 /*qualified_name=*/true,
17017 /*internal=*/true);
17018 return priv_->internal_qualified_name_;
17019 }
17020 else
17021 {
17022 // As the type hasn't yet been canonicalized, its structure
17023 // (and so its name) can change. So let's invalidate the
17024 // cache where we store its name at each invocation of this
17025 // function.
17026 if (pointed_to_type)
17027 priv_->temp_internal_qualified_name_ =
17028 get_name_of_pointer_to_type(*pointed_to_type,
17029 /*qualified_name=*/true,
17030 /*internal=*/true);
17031 return priv_->temp_internal_qualified_name_;
17032 }
17033 }
17034 else
17035 {
17037 {
17038 if (decl_base::peek_qualified_name().empty())
17040 (get_name_of_pointer_to_type(*pointed_to_type,
17041 /*qualified_name=*/true,
17042 /*internal=*/false));
17044 }
17045 else
17046 {
17047 // As the type hasn't yet been canonicalized, its structure
17048 // (and so its name) can change. So let's invalidate the
17049 // cache where we store its name at each invocation of this
17050 // function.
17051 if (pointed_to_type)
17053 (get_name_of_pointer_to_type(*pointed_to_type,
17054 /*qualified_name=*/true,
17055 /*internal=*/false));
17057 }
17058 }
17059}
17060
17061/// This implements the ir_traversable_base::traverse pure virtual
17062/// function.
17063///
17064/// @param v the visitor used on the current instance.
17065///
17066/// @return true if the entire IR node tree got traversed, false
17067/// otherwise.
17068bool
17070{
17071 if (v.type_node_has_been_visited(this))
17072 return true;
17073
17074 if (visiting())
17075 return true;
17076
17077 if (v.visit_begin(this))
17078 {
17079 visiting(true);
17080 if (type_base_sptr t = get_pointed_to_type())
17081 t->traverse(v);
17082 visiting(false);
17083 }
17084
17085 bool result = v.visit_end(this);
17087 return result;
17088}
17089
17090pointer_type_def::~pointer_type_def()
17091{}
17092
17093/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
17094/// equality; that is, make it compare the pointed to objects too.
17095///
17096/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
17097/// of the equality.
17098///
17099/// @param r the shared_ptr of @ref pointer_type_def on
17100/// right-hand-side of the equality.
17101///
17102/// @return true if the @ref pointer_type_def pointed to by the
17103/// shared_ptrs are equal, false otherwise.
17104bool
17106{
17107 if (l.get() == r.get())
17108 return true;
17109 if (!!l != !!r)
17110 return false;
17111
17112 return *l == *r;
17113}
17114
17115/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
17116/// equality; that is, make it compare the pointed to objects too.
17117///
17118/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
17119/// of the equality.
17120///
17121/// @param r the shared_ptr of @ref pointer_type_def on
17122/// right-hand-side of the equality.
17123///
17124/// @return true iff the @ref pointer_type_def pointed to by the
17125/// shared_ptrs are different.
17126bool
17128{return !operator==(l, r);}
17129
17130// </pointer_type_def definitions>
17131
17132// <reference_type_def definitions>
17133
17134/// This function is automatically invoked whenever an instance of
17135/// this type is canonicalized.
17136///
17137/// It's an overload of the virtual type_base::on_canonical_type_set.
17138///
17139/// We put here what is thus meant to be executed only at the point of
17140/// type canonicalization.
17141void
17144
17145/// Constructor of the reference_type_def type.
17146///
17147/// @param pointed_to the pointed to type.
17148///
17149/// @param lvalue wether the reference is an lvalue reference. If
17150/// false, the reference is an rvalue one.
17151///
17152/// @param size_in_bits the size of the type, in bits.
17153///
17154/// @param align_in_bits the alignment of the type, in bits.
17155///
17156/// @param locus the source location of the type.
17157reference_type_def::reference_type_def(const type_base_sptr pointed_to,
17158 bool lvalue,
17159 size_t size_in_bits,
17160 size_t align_in_bits,
17161 const location& locus)
17162 : type_or_decl_base(pointed_to->get_environment(),
17163 REFERENCE_TYPE
17164 | ABSTRACT_TYPE_BASE
17165 | ABSTRACT_DECL_BASE),
17166 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17167 decl_base(pointed_to->get_environment(), "", locus, ""),
17168 is_lvalue_(lvalue)
17169{
17171
17172 try
17173 {
17174 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
17175 string name;
17176 if (pto)
17177 {
17178 set_visibility(pto->get_visibility());
17179 name = string(pto->get_name()) + "&";
17180 }
17181 else
17182 name = string(get_type_name(is_function_type(pointed_to),
17183 /*qualified_name=*/true)) + "&";
17184
17185 if (!is_lvalue())
17186 name += "&";
17187 const environment& env = pointed_to->get_environment();
17188 set_name(env.intern(name));
17189
17190 pointed_to_type_ =
17191 type_base_wptr(type_or_void(pointed_to,
17192 pointed_to->get_environment()));
17193 }
17194 catch (...)
17195 {}
17196}
17197
17198/// Constructor of the reference_type_def type.
17199///
17200/// This one creates a type that has no pointed-to type, temporarily.
17201/// This is useful for cases where the underlying type is not yet
17202/// available. It can be set later using
17203/// reference_type_def::set_pointed_to_type().
17204///
17205/// @param env the environment of the type.
17206///
17207/// @param lvalue wether the reference is an lvalue reference. If
17208/// false, the reference is an rvalue one.
17209///
17210/// @param size_in_bits the size of the type, in bits.
17211///
17212/// @param align_in_bits the alignment of the type, in bits.
17213///
17214/// @param locus the source location of the type.
17215reference_type_def::reference_type_def(const environment& env, bool lvalue,
17216 size_t size_in_bits,
17217 size_t alignment_in_bits,
17218 const location& locus)
17219 : type_or_decl_base(env,
17220 REFERENCE_TYPE
17221 | ABSTRACT_TYPE_BASE
17222 | ABSTRACT_DECL_BASE),
17223 type_base(env, size_in_bits, alignment_in_bits),
17224 decl_base(env, "", locus, ""),
17225 is_lvalue_(lvalue)
17226{
17228 string name = "void&";
17229 if (!is_lvalue())
17230 name += "&";
17231
17232 set_name(env.intern(name));
17233 pointed_to_type_ = type_base_wptr(env.get_void_type());
17234}
17235
17236/// Setter of the pointed_to type of the current reference type.
17237///
17238/// @param pointed_to the new pointed to type.
17239void
17240reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
17241{
17242 ABG_ASSERT(pointed_to_type);
17243 pointed_to_type_ = pointed_to_type;
17244
17245 decl_base_sptr pto;
17246 try
17247 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
17248 catch (...)
17249 {}
17250
17251 if (pto)
17252 {
17253 set_visibility(pto->get_visibility());
17254 string name = string(pto->get_name()) + "&";
17255 if (!is_lvalue())
17256 name += "&";
17257 const environment& env = pto->get_environment();
17258 set_name(env.intern(name));
17259 }
17260}
17261
17262/// Compares two instances of @ref reference_type_def.
17263///
17264/// If the two intances are different, set a bitfield to give some
17265/// insight about the kind of differences there are.
17266///
17267/// @param l the first artifact of the comparison.
17268///
17269/// @param r the second artifact of the comparison.
17270///
17271/// @param k a pointer to a bitfield that gives information about the
17272/// kind of changes there are between @p l and @p r. This one is set
17273/// iff @p k is non-null and the function returns false.
17274///
17275/// Please note that setting k to a non-null value does have a
17276/// negative performance impact because even if @p l and @p r are not
17277/// equal, the function keeps up the comparison in order to determine
17278/// the different kinds of ways in which they are different.
17279///
17280/// @return true if @p l equals @p r, false otherwise.
17281bool
17283{
17284 if (l.is_lvalue() != r.is_lvalue())
17285 {
17286 if (k)
17289 }
17290
17291 // Compare the pointed-to-types modulo the typedefs they might have
17292 bool result = (l.get_pointed_to_type() == r.get_pointed_to_type());
17293 if (!result)
17294 if (k)
17295 {
17296 if (!types_have_similar_structure(&l, &r))
17298 *k |= SUBTYPE_CHANGE_KIND;
17299 }
17300 ABG_RETURN(result);
17301}
17302
17303/// Equality operator of the @ref reference_type_def type.
17304///
17305/// @param o the other instance of @ref reference_type_def to compare
17306/// against.
17307///
17308/// @return true iff the two instances are equal.
17309bool
17311{
17312 const reference_type_def* other =
17313 dynamic_cast<const reference_type_def*>(&o);
17314 if (!other)
17315 return false;
17316 return try_canonical_compare(this, other);
17317}
17318
17319/// Equality operator of the @ref reference_type_def type.
17320///
17321/// @param o the other instance of @ref reference_type_def to compare
17322/// against.
17323///
17324/// @return true iff the two instances are equal.
17325bool
17327{
17328 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17329 if (!other)
17330 return false;
17331 return *this == *other;
17332}
17333
17334/// Equality operator of the @ref reference_type_def type.
17335///
17336/// @param o the other instance of @ref reference_type_def to compare
17337/// against.
17338///
17339/// @return true iff the two instances are equal.
17340bool
17342{
17343 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17344 if (!other)
17345 return false;
17346 return *this == *other;
17347}
17348
17349type_base_sptr
17350reference_type_def::get_pointed_to_type() const
17351{return pointed_to_type_.lock();}
17352
17353bool
17354reference_type_def::is_lvalue() const
17355{return is_lvalue_;}
17356
17357/// Build and return the qualified name of the current instance of the
17358/// @ref reference_type_def.
17359///
17360/// @param qn output parameter. Is set to the newly-built qualified
17361/// name of the current instance of @ref reference_type_def.
17362///
17363/// @param internal set to true if the call is intended for an
17364/// internal use (for technical use inside the library itself), false
17365/// otherwise. If you don't know what this is for, then set it to
17366/// false.
17367void
17369{qn = get_qualified_name(internal);}
17370
17371/// Build, cache and return the qualified name of the current instance
17372/// of the @ref reference_type_def. Subsequent invocations of this
17373/// function return the cached value.
17374///
17375/// @param internal set to true if the call is intended for an
17376/// internal use (for technical use inside the library itself), false
17377/// otherwise. If you don't know what this is for, then set it to
17378/// false.
17379///
17380/// @return the newly-built qualified name of the current instance of
17381/// @ref reference_type_def.
17382const interned_string&
17384{
17385 if (peek_qualified_name().empty()
17386 || !get_canonical_type())
17388 (*look_through_decl_only(get_pointed_to_type()),
17389 is_lvalue(),
17390 /*qualified_name=*/true,
17391 internal));
17392 return peek_qualified_name();
17393}
17394
17395/// Get the pretty representation of the current instance of @ref
17396/// reference_type_def.
17397///
17398/// @param internal set to true if the call is intended to get a
17399/// representation of the decl (or type) for the purpose of canonical
17400/// type comparison. This is mainly used in the function
17401/// type_base::get_canonical_type_for().
17402///
17403/// In other words if the argument for this parameter is true then the
17404/// call is meant for internal use (for technical use inside the
17405/// library itself), false otherwise. If you don't know what this is
17406/// for, then set it to false.
17407///
17408/// @param qualified_name if true, names emitted in the pretty
17409/// representation are fully qualified.
17410///
17411/// @return the pretty representatin of the @ref reference_type_def.
17412string
17414 bool qualified_name) const
17415{
17416 string result =
17418 (get_pointed_to_type()),
17419 is_lvalue(),
17420 qualified_name,
17421 internal);
17422
17423 return result;
17424}
17425
17426/// This implements the ir_traversable_base::traverse pure virtual
17427/// function.
17428///
17429/// @param v the visitor used on the current instance.
17430///
17431/// @return true if the entire IR node tree got traversed, false
17432/// otherwise.
17433bool
17435{
17436 if (v.type_node_has_been_visited(this))
17437 return true;
17438
17439 if (visiting())
17440 return true;
17441
17442 if (v.visit_begin(this))
17443 {
17444 visiting(true);
17445 if (type_base_sptr t = get_pointed_to_type())
17446 t->traverse(v);
17447 visiting(false);
17448 }
17449
17450 bool result = v.visit_end(this);
17452 return result;
17453}
17454
17455reference_type_def::~reference_type_def()
17456{}
17457
17458/// Turn equality of shared_ptr of @ref reference_type_def into a deep
17459/// equality; that is, make it compare the pointed to objects too.
17460///
17461/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
17462/// of the equality.
17463///
17464/// @param r the shared_ptr of @ref reference_type_def on
17465/// right-hand-side of the equality.
17466///
17467/// @return true if the @ref reference_type_def pointed to by the
17468/// shared_ptrs are equal, false otherwise.
17469bool
17471{
17472 if (l.get() == r.get())
17473 return true;
17474 if (!!l != !!r)
17475 return false;
17476
17477 return *l == *r;
17478}
17479
17480/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
17481/// equality; that is, make it compare the pointed to objects too.
17482///
17483/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
17484/// of the equality.
17485///
17486/// @param r the shared_ptr of @ref reference_type_def on
17487/// right-hand-side of the equality.
17488///
17489/// @return true iff the @ref reference_type_def pointed to by the
17490/// shared_ptrs are different.
17491bool
17493{return !operator==(l, r);}
17494
17495// </reference_type_def definitions>
17496
17497// <array_type_def definitions>
17498
17499// <array_type_def::subrange_type>
17500array_type_def::subrange_type::~subrange_type() = default;
17501
17502// <array_type_def::subrante_type::bound_value>
17503
17504/// Default constructor of the @ref
17505/// array_type_def::subrange_type::bound_value class.
17506///
17507/// Constructs an unsigned bound_value of value zero.
17509 : s_(UNSIGNED_SIGNEDNESS)
17510{
17511 v_.unsigned_ = 0;
17512}
17513
17514/// Initialize an unsigned bound_value with a given value.
17515///
17516/// @param v the initial bound value.
17518 : s_(UNSIGNED_SIGNEDNESS)
17519{
17520 v_.unsigned_ = v;
17521}
17522
17523/// Initialize a signed bound_value with a given value.
17524///
17525/// @param v the initial bound value.
17527 : s_(SIGNED_SIGNEDNESS)
17528{
17529 v_.signed_ = v;
17530}
17531
17532/// Getter of the signedness (unsigned VS signed) of the bound value.
17533///
17534/// @return the signedness of the bound value.
17535enum array_type_def::subrange_type::bound_value::signedness
17537{return s_;}
17538
17539/// Setter of the signedness (unsigned VS signed) of the bound value.
17540///
17541/// @param s the new signedness of the bound value.
17542void
17544{ s_ = s;}
17545
17546/// Getter of the bound value as a signed value.
17547///
17548/// @return the bound value as signed.
17549int64_t
17551{return v_.signed_;
17552}
17553
17554/// Getter of the bound value as an unsigned value.
17555///
17556/// @return the bound value as unsigned.
17557uint64_t
17559{return v_.unsigned_;}
17560
17561/// Setter of the bound value as unsigned.
17562///
17563/// @param v the new unsigned value.
17564void
17566{
17567 s_ = UNSIGNED_SIGNEDNESS;
17568 v_.unsigned_ = v;
17569}
17570
17571/// Setter of the bound value as signed.
17572///
17573/// @param v the new signed value.
17574void
17576{
17577 s_ = SIGNED_SIGNEDNESS;
17578 v_.signed_ = v;
17579}
17580
17581/// Equality operator of the bound value.
17582///
17583/// @param v the other bound value to compare with.
17584///
17585/// @return true iff the current bound value equals @p v.
17586bool
17588{
17589 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
17590}
17591
17592// </array_type_def::subrante_type::bound_value>
17593
17594struct array_type_def::subrange_type::priv
17595{
17596 bound_value lower_bound_;
17597 bound_value upper_bound_;
17598 type_base_wptr underlying_type_;
17600 bool infinite_;
17601
17602 priv(bound_value ub,
17603 translation_unit::language l = translation_unit::LANG_C11)
17604 : upper_bound_(ub), language_(l), infinite_(false)
17605 {}
17606
17607 priv(bound_value lb, bound_value ub,
17608 translation_unit::language l = translation_unit::LANG_C11)
17609 : lower_bound_(lb), upper_bound_(ub),
17610 language_(l), infinite_(false)
17611 {}
17612
17613 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
17614 translation_unit::language l = translation_unit::LANG_C11)
17615 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
17616 language_(l), infinite_(false)
17617 {}
17618};
17619
17620/// Constructor of an array_type_def::subrange_type type.
17621///
17622/// @param env the environment this type was created from.
17623///
17624/// @param name the name of the subrange type.
17625///
17626/// @param lower_bound the lower bound of the array. This is
17627/// generally zero (at least for C and C++).
17628///
17629/// @param upper_bound the upper bound of the array.
17630///
17631/// @param underlying_type the underlying type of the subrange type.
17632///
17633/// @param loc the source location where the type is defined.
17634array_type_def::subrange_type::subrange_type(const environment& env,
17635 const string& name,
17636 bound_value lower_bound,
17637 bound_value upper_bound,
17638 const type_base_sptr& utype,
17639 const location& loc,
17641 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
17642 type_base(env,
17643 upper_bound.get_unsigned_value()
17644 - lower_bound.get_unsigned_value(),
17645 0),
17646 decl_base(env, name, loc, ""),
17647 priv_(new priv(lower_bound, upper_bound, utype, l))
17648{
17650}
17651
17652/// Constructor of the array_type_def::subrange_type type.
17653///
17654/// @param env the environment this type is being created in.
17655///
17656/// @param name the name of the subrange type.
17657///
17658/// @param lower_bound the lower bound of the array. This is
17659/// generally zero (at least for C and C++).
17660///
17661/// @param upper_bound the upper bound of the array.
17662///
17663/// @param loc the source location where the type is defined.
17664///
17665/// @param l the language that generated this subrange.
17666array_type_def::subrange_type::subrange_type(const environment& env,
17667 const string& name,
17668 bound_value lower_bound,
17669 bound_value upper_bound,
17670 const location& loc,
17672 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
17673 type_base(env,
17674 upper_bound.get_unsigned_value()
17675 - lower_bound.get_unsigned_value(), 0),
17676 decl_base(env, name, loc, ""),
17677 priv_(new priv(lower_bound, upper_bound, l))
17678{
17680}
17681
17682/// Constructor of the array_type_def::subrange_type type.
17683///
17684/// @param env the environment this type is being created from.
17685///
17686/// @param name of the name of type.
17687///
17688/// @param upper_bound the upper bound of the array. The lower bound
17689/// is considered to be zero.
17690///
17691/// @param loc the source location of the type.
17692///
17693/// @param the language that generated this type.
17694array_type_def::subrange_type::subrange_type(const environment& env,
17695 const string& name,
17696 bound_value upper_bound,
17697 const location& loc,
17699 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
17700 type_base(env, upper_bound.get_unsigned_value(), 0),
17701 decl_base(env, name, loc, ""),
17702 priv_(new priv(upper_bound, l))
17703{
17705}
17706
17707/// Getter of the underlying type of the subrange, that is, the type
17708/// that defines the range.
17709///
17710/// @return the underlying type.
17711type_base_sptr
17713{return priv_->underlying_type_.lock();}
17714
17715/// Setter of the underlying type of the subrange, that is, the type
17716/// that defines the range.
17717///
17718/// @param u the new underlying type.
17719void
17721{
17722 ABG_ASSERT(priv_->underlying_type_.expired());
17723 priv_->underlying_type_ = u;
17724}
17725
17726/// Getter of the upper bound of the subrange type.
17727///
17728/// @return the upper bound of the subrange type.
17729int64_t
17731{return priv_->upper_bound_.get_signed_value();}
17732
17733/// Getter of the lower bound of the subrange type.
17734///
17735/// @return the lower bound of the subrange type.
17736int64_t
17738{return priv_->lower_bound_.get_signed_value();}
17739
17740/// Setter of the upper bound of the subrange type.
17741///
17742/// @param ub the new value of the upper bound.
17743void
17745{priv_->upper_bound_ = ub;}
17746
17747/// Setter of the lower bound.
17748///
17749/// @param lb the new value of the lower bound.
17750void
17752{priv_->lower_bound_ = lb;}
17753
17754/// Getter of the length of the subrange type.
17755///
17756/// Note that a length of zero means the array has an infinite (or
17757/// rather a non-known) size.
17758///
17759/// @return the length of the subrange type.
17760uint64_t
17762{
17763 if (is_infinite())
17764 return 0;
17765
17766 // A subrange can have an upper bound that is lower than its lower
17767 // bound. This is possible in Ada for instance. In that case, the
17768 // length of the subrange is considered to be zero.
17769 if (get_upper_bound() >= get_lower_bound())
17770 return get_upper_bound() - get_lower_bound() + 1;
17771 return 0;
17772}
17773
17774/// Test if the length of the subrange type is infinite.
17775///
17776/// @return true iff the length of the subrange type is infinite.
17777bool
17779{return priv_->infinite_;}
17780
17781/// Set the infinite-ness status of the subrange type.
17782///
17783/// @param f true iff the length of the subrange type should be set to
17784/// being infinite.
17785void
17787{priv_->infinite_ = f;}
17788
17789/// Getter of the language that generated this type.
17790///
17791/// @return the language of this type.
17794{return priv_->language_;}
17795
17796/// Return a string representation of the sub range.
17797///
17798/// @return the string representation of the sub range.
17799string
17801{
17802 std::ostringstream o;
17803
17805 {
17806 type_base_sptr underlying_type = get_underlying_type();
17807 if (underlying_type)
17808 o << ir::get_pretty_representation(underlying_type, false) << " ";
17809 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
17810 }
17811 else if (is_infinite())
17812 o << "[]";
17813 else
17814 o << "[" << get_length() << "]";
17815
17816 return o.str();
17817}
17818
17819/// Return a string representation of a vector of subranges
17820///
17821/// @return the string representation of a vector of sub ranges.
17822string
17824{
17825 if (v.empty())
17826 return "[]";
17827
17828 string r;
17829 for (vector<subrange_sptr>::const_iterator i = v.begin();
17830 i != v.end();
17831 ++i)
17832 r += (*i)->as_string();
17833
17834 return r;
17835}
17836
17837/// Compares two isntances of @ref array_type_def::subrange_type.
17838///
17839/// If the two intances are different, set a bitfield to give some
17840/// insight about the kind of differences there are.
17841///
17842/// @param l the first artifact of the comparison.
17843///
17844/// @param r the second artifact of the comparison.
17845///
17846/// @param k a pointer to a bitfield that gives information about the
17847/// kind of changes there are between @p l and @p r. This one is set
17848/// iff @p k is non-null and the function returns false.
17849///
17850/// Please note that setting k to a non-null value does have a
17851/// negative performance impact because even if @p l and @p r are not
17852/// equal, the function keeps up the comparison in order to determine
17853/// the different kinds of ways in which they are different.
17854///
17855/// @return true if @p l equals @p r, false otherwise.
17856bool
17859 change_kind* k)
17860{
17861 bool result = true;
17862
17863 if (l.get_lower_bound() != r.get_lower_bound()
17864 || l.get_upper_bound() != r.get_upper_bound()
17865 || l.get_name() != r.get_name())
17866 {
17867 result = false;
17868 if (k)
17870 else
17871 ABG_RETURN(result);
17872 }
17873
17874 ABG_RETURN(result);
17875}
17876
17877/// Equality operator.
17878///
17879/// @param o the other subrange to test against.
17880///
17881/// @return true iff @p o equals the current instance of
17882/// array_type_def::subrange_type.
17883bool
17885{
17886 const subrange_type* other =
17887 dynamic_cast<const subrange_type*>(&o);
17888 if (!other)
17889 return false;
17890 return try_canonical_compare(this, other);
17891}
17892
17893/// Equality operator.
17894///
17895/// @param o the other subrange to test against.
17896///
17897/// @return true iff @p o equals the current instance of
17898/// array_type_def::subrange_type.
17899bool
17901{
17902 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17903 if (!other)
17904 return false;
17905 return *this == *other;
17906}
17907
17908/// Equality operator.
17909///
17910/// @param o the other subrange to test against.
17911///
17912/// @return true iff @p o equals the current instance of
17913/// array_type_def::subrange_type.
17914bool
17916{
17917 const type_base &t = o;
17918 return operator==(t);
17919}
17920
17921/// Equality operator.
17922///
17923/// @param o the other subrange to test against.
17924///
17925/// @return true iff @p o equals the current instance of
17926/// array_type_def::subrange_type.
17927bool
17929{return !operator==(o);}
17930
17931/// Equality operator.
17932///
17933/// @param o the other subrange to test against.
17934///
17935/// @return true iff @p o equals the current instance of
17936/// array_type_def::subrange_type.
17937bool
17939{return !operator==(o);}
17940
17941/// Inequality operator.
17942///
17943/// @param o the other subrange to test against.
17944///
17945/// @return true iff @p o is different from the current instance of
17946/// array_type_def::subrange_type.
17947bool
17949{return !operator==(o);}
17950
17951/// Build a pretty representation for an
17952/// array_type_def::subrange_type.
17953///
17954/// @param internal set to true if the call is intended to get a
17955/// representation of the decl (or type) for the purpose of canonical
17956/// type comparison. This is mainly used in the function
17957/// type_base::get_canonical_type_for().
17958///
17959/// In other words if the argument for this parameter is true then the
17960/// call is meant for internal use (for technical use inside the
17961/// library itself), false otherwise. If you don't know what this is
17962/// for, then set it to false.
17963///
17964/// @return a copy of the pretty representation of the current
17965/// instance of typedef_decl.
17966string
17968{
17969 string name = get_name();
17970 string repr;
17971
17972 if (name.empty())
17973 repr += "<anonymous range>";
17974 else
17975 repr += "<range " + get_name() + ">";
17976 repr += as_string();
17977
17978 return repr;
17979}
17980
17981/// This implements the ir_traversable_base::traverse pure virtual
17982/// function.
17983///
17984/// @param v the visitor used on the current instance.
17985///
17986/// @return true if the entire IR node tree got traversed, false
17987/// otherwise.
17988bool
17990{
17991 if (v.type_node_has_been_visited(this))
17992 return true;
17993
17994 if (v.visit_begin(this))
17995 {
17996 visiting(true);
17997 if (type_base_sptr u = get_underlying_type())
17998 u->traverse(v);
17999 visiting(false);
18000 }
18001
18002 bool result = v.visit_end(this);
18004 return result;
18005}
18006
18007// </array_type_def::subrange_type>
18008
18009struct array_type_def::priv
18010{
18011 type_base_wptr element_type_;
18012 subranges_type subranges_;
18013 interned_string temp_internal_qualified_name_;
18014 interned_string internal_qualified_name_;
18015
18016 priv(type_base_sptr t)
18017 : element_type_(t)
18018 {}
18019
18020 priv(type_base_sptr t, subranges_type subs)
18021 : element_type_(t), subranges_(subs)
18022 {}
18023
18024 priv()
18025 {}
18026};
18027
18028/// Constructor for the type array_type_def
18029///
18030/// Note how the constructor expects a vector of subrange
18031/// objects. Parsing of the array information always entails
18032/// parsing the subrange info as well, thus the class subrange_type
18033/// is defined inside class array_type_def and also parsed
18034/// simultaneously.
18035///
18036/// @param e_type the type of the elements contained in the array
18037///
18038/// @param subs a vector of the array's subranges(dimensions)
18039///
18040/// @param locus the source location of the array type definition.
18041array_type_def::array_type_def(const type_base_sptr e_type,
18042 const std::vector<subrange_sptr>& subs,
18043 const location& locus)
18045 ARRAY_TYPE
18046 | ABSTRACT_TYPE_BASE
18047 | ABSTRACT_DECL_BASE),
18048 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
18049 decl_base(e_type->get_environment(), locus),
18050 priv_(new priv(e_type))
18051{
18053 append_subranges(subs);
18054}
18055
18056/// Constructor for the type array_type_def
18057///
18058/// This constructor builds a temporary array that has no element type
18059/// associated. Later when the element type is available, it be set
18060/// with the array_type_def::set_element_type() member function.
18061///
18062/// Note how the constructor expects a vector of subrange
18063/// objects. Parsing of the array information always entails
18064/// parsing the subrange info as well, thus the class subrange_type
18065/// is defined inside class array_type_def and also parsed
18066/// simultaneously.
18067///
18068/// @param env the environment of the array type.
18069///
18070/// @param subs a vector of the array's subranges(dimensions)
18071///
18072/// @param locus the source location of the array type definition.
18073array_type_def::array_type_def(const environment& env,
18074 const std::vector<subrange_sptr>& subs,
18075 const location& locus)
18076 : type_or_decl_base(env,
18077 ARRAY_TYPE
18078 | ABSTRACT_TYPE_BASE
18079 | ABSTRACT_DECL_BASE),
18080 type_base(env, 0, 0),
18081 decl_base(env, locus),
18082 priv_(new priv)
18083{
18085 append_subranges(subs);
18086}
18087
18088/// Update the size of the array.
18089///
18090/// This function computes the size of the array and sets it using
18091/// type_base::set_size_in_bits().
18092void
18093array_type_def::update_size()
18094{
18095 type_base_sptr e = priv_->element_type_.lock();
18096 if (e)
18097 {
18098 size_t s = e->get_size_in_bits();
18099 if (s)
18100 {
18101 for (const auto &sub : get_subranges())
18102 s *= sub->get_length();
18104 }
18105 set_alignment_in_bits(e->get_alignment_in_bits());
18106 }
18107}
18108
18109string
18110array_type_def::get_subrange_representation() const
18111{
18113 return r;
18114}
18115
18116/// Get the string representation of an @ref array_type_def.
18117///
18118/// @param a the array type to consider.
18119///
18120/// @param internal set to true if the call is intended for an
18121/// internal use (for technical use inside the library itself), false
18122/// otherwise. If you don't know what this is for, then set it to
18123/// false.
18124static string
18125get_type_representation(const array_type_def& a, bool internal)
18126{
18127 type_base_sptr e_type = a.get_element_type();
18128 decl_base_sptr d = get_type_declaration(e_type);
18129 string r;
18130
18131 if (is_ada_language(a.get_language()))
18132 {
18133 std::ostringstream o;
18134 o << "array ("
18135 << a.get_subrange_representation()
18136 << ") of "
18137 << e_type ? e_type->get_pretty_representation(internal):string("void");
18138 }
18139 else
18140 {
18141 if (internal)
18142 r = (e_type
18143 ? get_type_name(e_type,
18144 /*qualified=*/true,
18145 /*internal=*/true)
18146 : string("void"))
18147 + a.get_subrange_representation();
18148 else
18149 r = (e_type
18150 ? get_type_name(e_type, /*qualified=*/true, /*internal=*/false)
18151 : string("void"))
18152 + a.get_subrange_representation();
18153 }
18154
18155 return r;
18156}
18157
18158/// Get the pretty representation of the current instance of @ref
18159/// array_type_def.
18160///
18161/// @param internal set to true if the call is intended to get a
18162/// representation of the decl (or type) for the purpose of canonical
18163/// type comparison. This is mainly used in the function
18164/// type_base::get_canonical_type_for().
18165///
18166/// In other words if the argument for this parameter is true then the
18167/// call is meant for internal use (for technical use inside the
18168/// library itself), false otherwise. If you don't know what this is
18169/// for, then set it to false.
18170/// @param internal set to true if the call is intended for an
18171/// internal use (for technical use inside the library itself), false
18172/// otherwise. If you don't know what this is for, then set it to
18173/// false.
18174///
18175/// @return the pretty representation of the ABI artifact.
18176string
18178 bool /*qualified_name*/) const
18179{return get_type_representation(*this, internal);}
18180
18181/// Compares two instances of @ref array_type_def.
18182///
18183/// If the two intances are different, set a bitfield to give some
18184/// insight about the kind of differences there are.
18185///
18186/// @param l the first artifact of the comparison.
18187///
18188/// @param r the second artifact of the comparison.
18189///
18190/// @param k a pointer to a bitfield that gives information about the
18191/// kind of changes there are between @p l and @p r. This one is set
18192/// iff @p k is non-null and the function returns false.
18193///
18194/// Please note that setting k to a non-null value does have a
18195/// negative performance impact because even if @p l and @p r are not
18196/// equal, the function keeps up the comparison in order to determine
18197/// the different kinds of ways in which they are different.
18198///
18199/// @return true if @p l equals @p r, false otherwise.
18200bool
18202{
18203 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
18204 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
18205
18206 bool result = true;
18207 if (this_subs.size() != other_subs.size())
18208 {
18209 result = false;
18210 if (k)
18212 else
18214 }
18215
18216 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
18217 for (i = this_subs.begin(), j = other_subs.begin();
18218 i != this_subs.end() && j != other_subs.end();
18219 ++i, ++j)
18220 if (**i != **j)
18221 {
18222 result = false;
18223 if (k)
18224 {
18226 break;
18227 }
18228 else
18230 }
18231
18232 // Compare the element types modulo the typedefs they might have
18233 if (l.get_element_type() != r.get_element_type())
18234 {
18235 result = false;
18236 if (k)
18237 *k |= SUBTYPE_CHANGE_KIND;
18238 else
18240 }
18241
18242 ABG_RETURN(result);
18243}
18244
18245/// Test if two variables are equals modulo CV qualifiers.
18246///
18247/// @param l the first array of the comparison.
18248///
18249/// @param r the second array of the comparison.
18250///
18251/// @return true iff @p l equals @p r or, if they are different, the
18252/// difference between the too is just a matter of CV qualifiers.
18253bool
18255{
18256 if (l == r)
18257 return true;
18258
18259 if (!l || !r)
18261
18264
18265 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
18266 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
18267
18268 if (this_subs.size() != other_subs.size())
18270
18271 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
18272 for (i = this_subs.begin(), j = other_subs.begin();
18273 i != this_subs.end() && j != other_subs.end();
18274 ++i, ++j)
18275 if (**i != **j)
18277
18278 type_base *first_element_type =
18280 type_base *second_element_type =
18282
18283 if (*first_element_type != *second_element_type)
18285
18286 return true;
18287}
18288
18289/// Get the language of the array.
18290///
18291/// @return the language of the array.
18294{
18295 const std::vector<subrange_sptr>& subranges =
18296 get_subranges();
18297
18298 if (subranges.empty())
18299 return translation_unit::LANG_C11;
18300 return subranges.front()->get_language();
18301}
18302
18303bool
18305{
18306 const array_type_def* other =
18307 dynamic_cast<const array_type_def*>(&o);
18308 if (!other)
18309 return false;
18310 return try_canonical_compare(this, other);
18311}
18312
18313bool
18315{
18316 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18317 if (!other)
18318 return false;
18319 return *this == *other;
18320}
18321
18322/// Getter of the type of an array element.
18323///
18324/// @return the type of an array element.
18325const type_base_sptr
18327{return priv_->element_type_.lock();}
18328
18329/// Setter of the type of array element.
18330///
18331/// Beware that after using this function, one might want to
18332/// re-compute the canonical type of the array, if one has already
18333/// been computed.
18334///
18335/// The intended use of this method is to permit in-place adjustment
18336/// of the element type's qualifiers. In particular, the size of the
18337/// element type should not be changed.
18338///
18339/// @param element_type the new element type to set.
18340void
18341array_type_def::set_element_type(const type_base_sptr& element_type)
18342{
18343 priv_->element_type_ = element_type;
18344 update_size();
18346}
18347
18348/// Append subranges from the vector @param subs to the current
18349/// vector of subranges.
18350void
18351array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
18352{
18353
18354 for (const auto &sub : subs)
18355 priv_->subranges_.push_back(sub);
18356
18357 update_size();
18359}
18360
18361/// @return true if one of the sub-ranges of the array is infinite, or
18362/// if the array has no sub-range at all, also meaning that the size
18363/// of the array is infinite.
18364bool
18366{
18367 if (priv_->subranges_.empty())
18368 return true;
18369
18370 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
18371 priv_->subranges_.begin();
18372 i != priv_->subranges_.end();
18373 ++i)
18374 if ((*i)->is_infinite())
18375 return true;
18376
18377 return false;
18378}
18379
18380int
18381array_type_def::get_dimension_count() const
18382{return priv_->subranges_.size();}
18383
18384/// Build and return the qualified name of the current instance of the
18385/// @ref array_type_def.
18386///
18387/// @param qn output parameter. Is set to the newly-built qualified
18388/// name of the current instance of @ref array_type_def.
18389///
18390/// @param internal set to true if the call is intended for an
18391/// internal use (for technical use inside the library itself), false
18392/// otherwise. If you don't know what this is for, then set it to
18393/// false.
18394void
18396{qn = get_qualified_name(internal);}
18397
18398/// Compute the qualified name of the array.
18399///
18400/// @param internal set to true if the call is intended for an
18401/// internal use (for technical use inside the library itself), false
18402/// otherwise. If you don't know what this is for, then set it to
18403/// false.
18404///
18405/// @return the resulting qualified name.
18406const interned_string&
18408{
18409 const environment& env = get_environment();
18410
18411
18412 if (internal)
18413 {
18414 if (get_canonical_type())
18415 {
18416 if (priv_->internal_qualified_name_.empty())
18417 priv_->internal_qualified_name_ =
18418 env.intern(get_type_representation(*this, /*internal=*/true));
18419 return priv_->internal_qualified_name_;
18420 }
18421 else
18422 {
18423 priv_->temp_internal_qualified_name_ =
18424 env.intern(get_type_representation(*this, /*internal=*/true));
18425 return priv_->temp_internal_qualified_name_;
18426 }
18427 }
18428 else
18429 {
18430 if (get_canonical_type())
18431 {
18432 if (decl_base::peek_qualified_name().empty())
18433 set_qualified_name(env.intern(get_type_representation
18434 (*this, /*internal=*/false)));
18436 }
18437 else
18438 {
18439 set_temporary_qualified_name(env.intern(get_type_representation
18440 (*this,
18441 /*internal=*/false)));
18443 }
18444 }
18445}
18446
18447/// This implements the ir_traversable_base::traverse pure virtual
18448/// function.
18449///
18450/// @param v the visitor used on the current instance.
18451///
18452/// @return true if the entire IR node tree got traversed, false
18453/// otherwise.
18454bool
18456{
18457 if (v.type_node_has_been_visited(this))
18458 return true;
18459
18460 if (visiting())
18461 return true;
18462
18463 if (v.visit_begin(this))
18464 {
18465 visiting(true);
18466 if (type_base_sptr t = get_element_type())
18467 t->traverse(v);
18468 visiting(false);
18469 }
18470
18471 bool result = v.visit_end(this);
18473 return result;
18474}
18475
18476const location&
18477array_type_def::get_location() const
18478{return decl_base::get_location();}
18479
18480/// Get the array's subranges
18481const std::vector<array_type_def::subrange_sptr>&
18483{return priv_->subranges_;}
18484
18485array_type_def::~array_type_def()
18486{}
18487
18488// </array_type_def definitions>
18489
18490// <enum_type_decl definitions>
18491
18492class enum_type_decl::priv
18493{
18494 type_base_sptr underlying_type_;
18495 enumerators enumerators_;
18496
18497 friend class enum_type_decl;
18498
18499 priv();
18500
18501public:
18502 priv(type_base_sptr underlying_type,
18504 : underlying_type_(underlying_type),
18505 enumerators_(enumerators)
18506 {}
18507}; // end class enum_type_decl::priv
18508
18509/// Constructor.
18510///
18511/// @param name the name of the type declaration.
18512///
18513/// @param locus the source location where the type was defined.
18514///
18515/// @param underlying_type the underlying type of the enum.
18516///
18517/// @param enums the enumerators of this enum type.
18518///
18519/// @param linkage_name the linkage name of the enum.
18520///
18521/// @param vis the visibility of the enum type.
18522enum_type_decl::enum_type_decl(const string& name,
18523 const location& locus,
18524 type_base_sptr underlying_type,
18525 enumerators& enums,
18526 const string& linkage_name,
18527 visibility vis)
18528 : type_or_decl_base(underlying_type->get_environment(),
18529 ENUM_TYPE
18530 | ABSTRACT_TYPE_BASE
18531 | ABSTRACT_DECL_BASE),
18532 type_base(underlying_type->get_environment(),
18533 underlying_type->get_size_in_bits(),
18534 underlying_type->get_alignment_in_bits()),
18535 decl_base(underlying_type->get_environment(),
18536 name, locus, linkage_name, vis),
18537 priv_(new priv(underlying_type, enums))
18538{
18540 for (enumerators::iterator e = get_enumerators().begin();
18541 e != get_enumerators().end();
18542 ++e)
18543 e->set_enum_type(this);
18544}
18545
18546/// Return the underlying type of the enum.
18547type_base_sptr
18549{return priv_->underlying_type_;}
18550
18551/// @return the list of enumerators of the enum.
18554{return priv_->enumerators_;}
18555
18556/// @return the list of enumerators of the enum.
18559{return priv_->enumerators_;}
18560
18561/// Get the pretty representation of the current instance of @ref
18562/// enum_type_decl.
18563///
18564/// @param internal set to true if the call is intended to get a
18565/// representation of the decl (or type) for the purpose of canonical
18566/// type comparison. This is mainly used in the function
18567/// type_base::get_canonical_type_for().
18568///
18569/// In other words if the argument for this parameter is true then the
18570/// call is meant for internal use (for technical use inside the
18571/// library itself), false otherwise. If you don't know what this is
18572/// for, then set it to false.
18573///
18574/// @param qualified_name if true, names emitted in the pretty
18575/// representation are fully qualified.
18576///
18577/// @return the pretty representation of the enum type.
18578string
18580 bool qualified_name) const
18581{
18582 string r = "enum ";
18583
18584 if (internal && get_is_anonymous())
18585 r += get_type_name(this, qualified_name, /*internal=*/true);
18586 else
18588 qualified_name);
18589 return r;
18590}
18591
18592/// This implements the ir_traversable_base::traverse pure virtual
18593/// function.
18594///
18595/// @param v the visitor used on the current instance.
18596///
18597/// @return true if the entire IR node tree got traversed, false
18598/// otherwise.
18599bool
18601{
18602 if (v.type_node_has_been_visited(this))
18603 return true;
18604
18605 if (visiting())
18606 return true;
18607
18608 if (v.visit_begin(this))
18609 {
18610 visiting(true);
18611 if (type_base_sptr t = get_underlying_type())
18612 t->traverse(v);
18613 visiting(false);
18614 }
18615
18616 bool result = v.visit_end(this);
18618 return result;
18619}
18620
18621/// Destructor for the enum type declaration.
18623{}
18624
18625/// Test if two enums differ, but not by a name change.
18626///
18627/// @param l the first enum to consider.
18628///
18629/// @param r the second enum to consider.
18630///
18631/// @return true iff @p l differs from @p r by anything but a name
18632/// change.
18633bool
18635 const enum_type_decl& r,
18636 change_kind* k)
18637{
18638 bool result = false;
18640 {
18641 result = true;
18642 if (k)
18643 *k |= SUBTYPE_CHANGE_KIND;
18644 else
18645 return true;
18646 }
18647
18648 enum_type_decl::enumerators::const_iterator i, j;
18649 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
18650 i != l.get_enumerators().end() && j != r.get_enumerators().end();
18651 ++i, ++j)
18652 if (*i != *j)
18653 {
18654 result = true;
18655 if (k)
18656 {
18658 break;
18659 }
18660 else
18661 return true;
18662 }
18663
18664 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
18665 {
18666 result = true;
18667 if (k)
18669 else
18670 return true;
18671 }
18672
18673 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
18676 string n_l = l.get_name();
18677 string n_r = r.get_name();
18678 local_r.set_qualified_name(qn_l);
18679 local_r.set_name(n_l);
18680
18681 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
18682 {
18683 result = true;
18684 if (k)
18685 {
18686 if (!l.decl_base::operator==(r))
18688 if (!l.type_base::operator==(r))
18690 }
18691 else
18692 {
18693 local_r.set_name(n_r);
18694 local_r.set_qualified_name(qn_r);
18695 return true;
18696 }
18697 }
18698 local_r.set_qualified_name(qn_r);
18699 local_r.set_name(n_r);
18700
18701 return result;
18702}
18703
18704/// Test if a given enumerator is found present in an enum.
18705///
18706/// This is a subroutine of the equals function for enums.
18707///
18708/// @param enr the enumerator to consider.
18709///
18710/// @param enom the enum to consider.
18711///
18712/// @return true iff the enumerator @p enr is present in the enum @p
18713/// enom.
18714static bool
18715is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr,
18716 const enum_type_decl &enom)
18717{
18718 for (const auto &e : enom.get_enumerators())
18719 if (e == enr)
18720 return true;
18721 return false;
18722}
18723
18724/// Check if two enumerators values are equal.
18725///
18726/// This function doesn't check if the names of the enumerators are
18727/// equal or not.
18728///
18729/// @param enr the first enumerator to consider.
18730///
18731/// @param enl the second enumerator to consider.
18732///
18733/// @return true iff @p enr has the same value as @p enl.
18734static bool
18735enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
18736 const enum_type_decl::enumerator &enl)
18737{return enr.get_value() == enl.get_value();}
18738
18739/// Detect if a given enumerator value is present in an enum.
18740///
18741/// This function looks inside the enumerators of a given enum and
18742/// detect if the enum contains at least one enumerator or a given
18743/// value. The function also detects if the enumerator value we are
18744/// looking at is present in the enum with a different name. An
18745/// enumerator with the same value but with a different name is named
18746/// a "redundant enumerator". The function returns the set of
18747/// enumerators that are redundant with the value we are looking at.
18748///
18749/// @param enr the enumerator to consider.
18750///
18751/// @param enom the enum to consider.
18752///
18753/// @param redundant_enrs if the function returns true, then this
18754/// vector is filled with enumerators that are redundant with the
18755/// value of @p enr.
18756///
18757/// @return true iff the function detects that @p enom contains
18758/// enumerators with the same value as @p enr.
18759static bool
18760is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
18761 const enum_type_decl &enom,
18762 vector<enum_type_decl::enumerator>& redundant_enrs)
18763{
18764 bool found = false;
18765 for (const auto &e : enom.get_enumerators())
18766 if (enumerators_values_are_equal(e, enr))
18767 {
18768 found = true;
18769 if (e != enr)
18770 redundant_enrs.push_back(e);
18771 }
18772
18773 return found;
18774}
18775
18776/// Check if an enumerator value is redundant in a given enum.
18777///
18778/// Given an enumerator value, this function detects if an enum
18779/// contains at least one enumerator with the the same value but with
18780/// a different name.
18781///
18782/// @param enr the enumerator to consider.
18783///
18784/// @param enom the enum to consider.
18785///
18786/// @return true iff @p enr is a redundant enumerator in enom.
18787static bool
18788is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
18789 const enum_type_decl &enom)
18790{
18791 vector<enum_type_decl::enumerator> redundant_enrs;
18792 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
18793 {
18794 if (!redundant_enrs.empty())
18795 return true;
18796 }
18797 return false;
18798}
18799
18800/// Compares two instances of @ref enum_type_decl.
18801///
18802/// If the two intances are different, set a bitfield to give some
18803/// insight about the kind of differences there are.
18804///
18805/// @param l the first artifact of the comparison.
18806///
18807/// @param r the second artifact of the comparison.
18808///
18809/// @param k a pointer to a bitfield that gives information about the
18810/// kind of changes there are between @p l and @p r. This one is set
18811/// iff @p k is non-null and the function returns false.
18812///
18813/// Please note that setting k to a non-null value does have a
18814/// negative performance impact because even if @p l and @p r are not
18815/// equal, the function keeps up the comparison in order to determine
18816/// the different kinds of ways in which they are different.
18817///
18818/// @return true if @p l equals @p r, false otherwise.
18819bool
18821{
18822 bool result = true;
18823
18824 //
18825 // Look through decl-only-enum.
18826 //
18827
18828 const enum_type_decl *def1 =
18831 : &l;
18832
18833 const enum_type_decl *def2 =
18836 : &r;
18837
18838 if (!!def1 != !!def2)
18839 {
18840 // One enum is decl-only while the other is not.
18841 // So the two enums are different.
18842 result = false;
18843 if (k)
18844 *k |= SUBTYPE_CHANGE_KIND;
18845 else
18847 }
18848
18849 //
18850 // At this point, both enums have the same state of decl-only-ness.
18851 // So we can compare oranges to oranges.
18852 //
18853
18854 if (!def1)
18855 def1 = &l;
18856 if (!def2)
18857 def2 = &r;
18858
18859 if (def1->get_underlying_type() != def2->get_underlying_type())
18860 {
18861 result = false;
18862 if (k)
18863 *k |= SUBTYPE_CHANGE_KIND;
18864 else
18866 }
18867
18868 if (!(def1->decl_base::operator==(*def2)
18869 && def1->type_base::operator==(*def2)))
18870 {
18871 result = false;
18872 if (k)
18873 {
18874 if (!def1->decl_base::operator==(*def2))
18876 if (!def1->type_base::operator==(*def2))
18878 }
18879 else
18881 }
18882
18883 // Now compare the enumerators. Note that the order of declaration
18884 // of enumerators should not matter in the comparison.
18885 //
18886 // Also if an enumerator value is redundant, that shouldn't impact
18887 // the comparison.
18888 //
18889 // In that case, note that the two enums below are considered equal:
18890 //
18891 // enum foo
18892 // {
18893 // e0 = 0;
18894 // e1 = 1;
18895 // e2 = 2;
18896 // };
18897 //
18898 // enum foo
18899 // {
18900 // e0 = 0;
18901 // e1 = 1;
18902 // e2 = 2;
18903 // e_added = 1; // <-- this value is redundant with the value
18904 // // of the enumerator e1.
18905 // };
18906 //
18907 // Note however that in the case below, the enums are different.
18908 //
18909 // enum foo
18910 // {
18911 // e0 = 0;
18912 // e1 = 1;
18913 // };
18914 //
18915 // enum foo
18916 // {
18917 // e0 = 0;
18918 // e2 = 1; // <-- this enum value is present in the first version
18919 // // of foo, but is not redundant with any enumerator
18920 // // in the second version of of enum foo.
18921 // };
18922 //
18923 // These two enums are considered equal.
18924
18925 for(const auto &e : def1->get_enumerators())
18926 if (!is_enumerator_present_in_enum(e, *def2)
18927 && (!is_enumerator_value_redundant(e, *def2)
18928 || !is_enumerator_value_redundant(e, *def1)))
18929 {
18930 result = false;
18931 if (k)
18932 {
18934 break;
18935 }
18936 else
18938 }
18939
18940 for(const auto &e : def2->get_enumerators())
18941 if (!is_enumerator_present_in_enum(e, *def1)
18942 && (!is_enumerator_value_redundant(e, *def1)
18943 || !is_enumerator_value_redundant(e, *def2)))
18944 {
18945 result = false;
18946 if (k)
18947 {
18949 break;
18950 }
18951 else
18953 }
18954
18955 ABG_RETURN(result);
18956}
18957
18958/// Equality operator.
18959///
18960/// @param o the other enum to test against.
18961///
18962/// @return true iff @p o equals the current instance of enum type
18963/// decl.
18964bool
18966{
18967 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
18968 if (!op)
18969 return false;
18970 return try_canonical_compare(this, op);
18971}
18972
18973/// Equality operator.
18974///
18975/// @param o the other enum to test against.
18976///
18977/// @return true iff @p o is equals the current instance of enum type
18978/// decl.
18979bool
18981{
18982 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18983 if (!other)
18984 return false;
18985 return *this == *other;
18986}
18987
18988/// Equality operator for @ref enum_type_decl_sptr.
18989///
18990/// @param l the first operand to compare.
18991///
18992/// @param r the second operand to compare.
18993///
18994/// @return true iff @p l equals @p r.
18995bool
18997{
18998 if (!!l != !!r)
18999 return false;
19000 if (l.get() == r.get())
19001 return true;
19002 decl_base_sptr o = r;
19003 return *l == *o;
19004}
19005
19006/// Inequality operator for @ref enum_type_decl_sptr.
19007///
19008/// @param l the first operand to compare.
19009///
19010/// @param r the second operand to compare.
19011///
19012/// @return true iff @p l equals @p r.
19013bool
19015{return !operator==(l, r);}
19016
19017/// The type of the private data of an @ref
19018/// enum_type_decl::enumerator.
19019class enum_type_decl::enumerator::priv
19020{
19021 string name_;
19022 int64_t value_;
19023 string qualified_name_;
19024 enum_type_decl* enum_type_;
19025
19026 friend class enum_type_decl::enumerator;
19027
19028public:
19029
19030 priv()
19031 : enum_type_()
19032 {}
19033
19034 priv(const string& name,
19035 int64_t value,
19036 enum_type_decl* e = 0)
19037 : name_(name),
19038 value_(value),
19039 enum_type_(e)
19040 {}
19041}; // end class enum_type_def::enumerator::priv
19042
19043/// Default constructor of the @ref enum_type_decl::enumerator type.
19045 : priv_(new priv)
19046{}
19047
19048enum_type_decl::enumerator::~enumerator() = default;
19049
19050/// Constructor of the @ref enum_type_decl::enumerator type.
19051///
19052/// @param env the environment we are operating from.
19053///
19054/// @param name the name of the enumerator.
19055///
19056/// @param value the value of the enumerator.
19058 int64_t value)
19059 : priv_(new priv(name, value))
19060{}
19061
19062/// Copy constructor of the @ref enum_type_decl::enumerator type.
19063///
19064/// @param other enumerator to copy.
19066 : priv_(new priv(other.get_name(),
19067 other.get_value(),
19068 other.get_enum_type()))
19069{}
19070
19071/// Assignment operator of the @ref enum_type_decl::enumerator type.
19072///
19073/// @param o
19076{
19077 priv_->name_ = o.get_name();
19078 priv_->value_ = o.get_value();
19079 priv_->enum_type_ = o.get_enum_type();
19080 return *this;
19081}
19082
19083/// Equality operator
19084///
19085/// @param other the enumerator to compare to the current
19086/// instance of enum_type_decl::enumerator.
19087///
19088/// @return true if @p other equals the current instance of
19089/// enum_type_decl::enumerator.
19090bool
19092{
19093 bool names_equal = true;
19094 names_equal = (get_name() == other.get_name());
19095 return names_equal && (get_value() == other.get_value());
19096}
19097
19098/// Inequality operator.
19099///
19100/// @param other the other instance to compare against.
19101///
19102/// @return true iff @p other is different from the current instance.
19103bool
19105{return !operator==(other);}
19106
19107/// Getter for the name of the current instance of
19108/// enum_type_decl::enumerator.
19109///
19110/// @return a reference to the name of the current instance of
19111/// enum_type_decl::enumerator.
19112const string&
19114{return priv_->name_;}
19115
19116/// Getter for the qualified name of the current instance of
19117/// enum_type_decl::enumerator. The first invocation of the method
19118/// builds the qualified name, caches it and return a reference to the
19119/// cached qualified name. Subsequent invocations just return the
19120/// cached value.
19121///
19122/// @param internal set to true if the call is intended for an
19123/// internal use (for technical use inside the library itself), false
19124/// otherwise. If you don't know what this is for, then set it to
19125/// false.
19126///
19127/// @return the qualified name of the current instance of
19128/// enum_type_decl::enumerator.
19129const string&
19131{
19132 if (priv_->qualified_name_.empty())
19133 {
19134 priv_->qualified_name_ =
19135 get_enum_type()->get_qualified_name(internal)
19136 + "::"
19137 + get_name();
19138 }
19139 return priv_->qualified_name_;
19140}
19141
19142/// Setter for the name of @ref enum_type_decl::enumerator.
19143///
19144/// @param n the new name.
19145void
19147{priv_->name_ = n;}
19148
19149/// Getter for the value of @ref enum_type_decl::enumerator.
19150///
19151/// @return the value of the current instance of
19152/// enum_type_decl::enumerator.
19153int64_t
19155{return priv_->value_;}
19156
19157/// Setter for the value of @ref enum_type_decl::enumerator.
19158///
19159/// @param v the new value of the enum_type_decl::enumerator.
19160void
19162{priv_->value_= v;}
19163
19164/// Getter for the enum type that this enumerator is for.
19165///
19166/// @return the enum type that this enumerator is for.
19169{return priv_->enum_type_;}
19170
19171/// Setter for the enum type that this enumerator is for.
19172///
19173/// @param e the new enum type.
19174void
19176{priv_->enum_type_ = e;}
19177// </enum_type_decl definitions>
19178
19179// <typedef_decl definitions>
19180
19181/// Private data structure of the @ref typedef_decl.
19182struct typedef_decl::priv
19183{
19184 type_base_wptr underlying_type_;
19185 string internal_qualified_name_;
19186 string temp_internal_qualified_name_;
19187
19188 priv(const type_base_sptr& t)
19189 : underlying_type_(t)
19190 {}
19191}; // end struct typedef_decl::priv
19192
19193/// Constructor of the typedef_decl type.
19194///
19195/// @param name the name of the typedef.
19196///
19197/// @param underlying_type the underlying type of the typedef.
19198///
19199/// @param locus the source location of the typedef declaration.
19200///
19201/// @param linkage_name the mangled name of the typedef.
19202///
19203/// @param vis the visibility of the typedef type.
19204typedef_decl::typedef_decl(const string& name,
19205 const type_base_sptr underlying_type,
19206 const location& locus,
19207 const string& linkage_name,
19208 visibility vis)
19209 : type_or_decl_base(underlying_type->get_environment(),
19210 TYPEDEF_TYPE
19211 | ABSTRACT_TYPE_BASE
19212 | ABSTRACT_DECL_BASE),
19213 type_base(underlying_type->get_environment(),
19214 underlying_type->get_size_in_bits(),
19215 underlying_type->get_alignment_in_bits()),
19216 decl_base(underlying_type->get_environment(),
19217 name, locus, linkage_name, vis),
19218 priv_(new priv(underlying_type))
19219{
19221}
19222
19223/// Constructor of the typedef_decl type.
19224///
19225/// @param name the name of the typedef.
19226///
19227/// @param env the environment of the current typedef.
19228///
19229/// @param locus the source location of the typedef declaration.
19230///
19231/// @param mangled_name the mangled name of the typedef.
19232///
19233/// @param vis the visibility of the typedef type.
19234typedef_decl::typedef_decl(const string& name,
19235 const environment& env,
19236 const location& locus,
19237 const string& mangled_name,
19238 visibility vis)
19239 : type_or_decl_base(env,
19240 TYPEDEF_TYPE
19241 | ABSTRACT_TYPE_BASE
19242 | ABSTRACT_DECL_BASE),
19243 type_base(env, /*size_in_bits=*/0,
19244 /*alignment_in_bits=*/0),
19245 decl_base(env, name, locus, mangled_name, vis),
19246 priv_(new priv(nullptr))
19247{
19249}
19250
19251/// Return the size of the typedef.
19252///
19253/// This function looks at the size of the underlying type and ensures
19254/// that it's the same as the size of the typedef.
19255///
19256/// @return the size of the typedef.
19257size_t
19259{
19260 if (!get_underlying_type())
19261 return 0;
19262 size_t s = get_underlying_type()->get_size_in_bits();
19263 if (s != type_base::get_size_in_bits())
19264 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
19266}
19267
19268/// Return the alignment of the typedef.
19269///
19270/// This function looks at the alignment of the underlying type and
19271/// ensures that it's the same as the alignment of the typedef.
19272///
19273/// @return the size of the typedef.
19274size_t
19276{
19277 if (!get_underlying_type())
19278 return 0;
19279 size_t s = get_underlying_type()->get_alignment_in_bits();
19281 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
19283}
19284
19285/// Compares two instances of @ref typedef_decl.
19286///
19287/// If the two intances are different, set a bitfield to give some
19288/// insight about the kind of differences there are.
19289///
19290/// @param l the first artifact of the comparison.
19291///
19292/// @param r the second artifact of the comparison.
19293///
19294/// @param k a pointer to a bitfield that gives information about the
19295/// kind of changes there are between @p l and @p r. This one is set
19296/// iff @p k is non-null and the function returns false.
19297///
19298/// Please note that setting k to a non-null value does have a
19299/// negative performance impact because even if @p l and @p r are not
19300/// equal, the function keeps up the comparison in order to determine
19301/// the different kinds of ways in which they are different.
19302///
19303/// @return true if @p l equals @p r, false otherwise.
19304bool
19306{
19307 bool result = true;
19308
19309 // No need to go further if the types have different names or
19310 // different size / alignment.
19311 if (!(l.decl_base::operator==(r)))
19312 {
19313 result = false;
19314 if (k)
19316 else
19318 }
19319
19321 {
19322 // Changes to the underlying type of a typedef are considered
19323 // local, a bit like for pointers.
19324 result = false;
19325 if (k)
19327 else
19329 }
19330
19331 ABG_RETURN(result);
19332}
19333
19334/// Equality operator
19335///
19336/// @param o the other typedef_decl to test against.
19337bool
19339{
19340 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
19341 if (!other)
19342 return false;
19343 return try_canonical_compare(this, other);
19344}
19345
19346/// Equality operator
19347///
19348/// @param o the other typedef_decl to test against.
19349///
19350/// @return true if the current instance of @ref typedef_decl equals
19351/// @p o.
19352bool
19354{
19355 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19356 if (!other)
19357 return false;
19358 return *this == *other;
19359}
19360
19361/// Build a pretty representation for a typedef_decl.
19362///
19363/// @param internal set to true if the call is intended to get a
19364/// representation of the decl (or type) for the purpose of canonical
19365/// type comparison. This is mainly used in the function
19366/// type_base::get_canonical_type_for().
19367///
19368/// In other words if the argument for this parameter is true then the
19369/// call is meant for internal use (for technical use inside the
19370/// library itself), false otherwise. If you don't know what this is
19371/// for, then set it to false.
19372
19373/// @param qualified_name if true, names emitted in the pretty
19374/// representation are fully qualified.
19375///
19376/// @return a copy of the pretty representation of the current
19377/// instance of typedef_decl.
19378string
19380 bool qualified_name) const
19381{
19382
19383 string result = "typedef ";
19384 if (qualified_name)
19385 result += get_qualified_name(internal);
19386 else
19387 result += get_name();
19388
19389 return result;
19390}
19391
19392/// Getter of the underlying type of the typedef.
19393///
19394/// @return the underlying_type.
19395type_base_sptr
19397{return priv_->underlying_type_.lock();}
19398
19399/// Setter ofthe underlying type of the typedef.
19400///
19401/// @param t the new underlying type of the typedef.
19402void
19404{
19405 priv_->underlying_type_ = t;
19406 set_size_in_bits(t->get_size_in_bits());
19407 set_alignment_in_bits(t->get_alignment_in_bits());
19408}
19409
19410/// This implements the ir_traversable_base::traverse pure virtual
19411/// function.
19412///
19413/// @param v the visitor used on the current instance.
19414///
19415/// @return true if the entire IR node tree got traversed, false
19416/// otherwise.
19417bool
19419{
19420 if (v.type_node_has_been_visited(this))
19421 return true;
19422
19423 if (visiting())
19424 return true;
19425
19426 if (v.visit_begin(this))
19427 {
19428 visiting(true);
19429 if (type_base_sptr t = get_underlying_type())
19430 t->traverse(v);
19431 visiting(false);
19432 }
19433
19434 bool result = v.visit_end(this);
19436 return result;
19437}
19438
19439typedef_decl::~typedef_decl()
19440{}
19441// </typedef_decl definitions>
19442
19443// <var_decl definitions>
19444
19445struct var_decl::priv
19446{
19447 type_base_wptr type_;
19448 type_base* naked_type_;
19449 decl_base::binding binding_;
19450 elf_symbol_sptr symbol_;
19451 interned_string id_;
19452
19453 priv()
19454 : naked_type_(),
19455 binding_(decl_base::BINDING_GLOBAL)
19456 {}
19457
19458 priv(type_base_sptr t,
19460 : type_(t),
19461 naked_type_(t.get()),
19462 binding_(b)
19463 {}
19464
19465 /// Setter of the type of the variable.
19466 ///
19467 /// @param t the new variable type.
19468 void
19469 set_type(type_base_sptr t)
19470 {
19471 type_ = t;
19472 naked_type_ = t.get();
19473 }
19474}; // end struct var_decl::priv
19475
19476/// Constructor of the @ref var_decl type.
19477///
19478/// @param name the name of the variable declaration
19479///
19480/// @param type the type of the variable declaration
19481///
19482/// @param locus the source location where the variable was defined.
19483///
19484/// @param linkage_name the linkage name of the variable.
19485///
19486/// @param vis the visibility of of the variable.
19487///
19488/// @param bind the binding kind of the variable.
19489var_decl::var_decl(const string& name,
19490 type_base_sptr type,
19491 const location& locus,
19492 const string& linkage_name,
19493 visibility vis,
19494 binding bind)
19495 : type_or_decl_base(type->get_environment(),
19496 VAR_DECL | ABSTRACT_DECL_BASE),
19497 decl_base(type->get_environment(), name, locus, linkage_name, vis),
19498 priv_(new priv(type, bind))
19499{
19501}
19502
19503/// Getter of the type of the variable.
19504///
19505/// @return the type of the variable.
19506const type_base_sptr
19508{return priv_->type_.lock();}
19509
19510/// Setter of the type of the variable.
19511///
19512/// @param the new type of the variable.
19513void
19514var_decl::set_type(type_base_sptr& t)
19515{priv_->set_type(t);}
19516
19517/// Getter of the type of the variable.
19518///
19519/// This getter returns a bare pointer, as opposed to a smart pointer.
19520/// It's to be used on performance sensitive code paths identified by
19521/// careful profiling.
19522///
19523/// @return the type of the variable, as a bare pointer.
19524const type_base*
19526{return priv_->naked_type_;}
19527
19528/// Getter of the binding of the variable.
19529///
19530/// @return the biding of the variable.
19533{return priv_->binding_;}
19534
19535/// Setter of the binding of the variable.
19536///
19537/// @param b the new binding value.
19538void
19540{priv_->binding_ = b;}
19541
19542/// Sets the underlying ELF symbol for the current variable.
19543///
19544/// And underlyin$g ELF symbol for the current variable might exist
19545/// only if the corpus that this variable originates from was
19546/// constructed from an ELF binary file.
19547///
19548/// Note that comparing two variables that have underlying ELF symbols
19549/// involves comparing their underlying elf symbols. The decl name
19550/// for the variable thus becomes irrelevant in the comparison.
19551///
19552/// @param sym the new ELF symbol for this variable decl.
19553void
19555{
19556 priv_->symbol_ = sym;
19557 // The variable id cache that depends on the symbol must be
19558 // invalidated because the symbol changed.
19559 priv_->id_ = get_environment().intern("");
19560}
19561
19562/// Gets the the underlying ELF symbol for the current variable,
19563/// that was set using var_decl::set_symbol(). Please read the
19564/// documentation for that member function for more information about
19565/// "underlying ELF symbols".
19566///
19567/// @return sym the underlying ELF symbol for this variable decl, if
19568/// one exists.
19569const elf_symbol_sptr&
19571{return priv_->symbol_;}
19572
19573/// Create a new var_decl that is a clone of the current one.
19574///
19575/// @return the cloned var_decl.
19578{
19580 get_type(),
19581 get_location(),
19584 get_binding()));
19585
19586 v->set_symbol(get_symbol());
19587
19588 if (is_member_decl(*this))
19589 {
19593 get_member_is_static(*this),
19594 get_data_member_offset(*this));
19595 }
19596 else
19598
19599 return v;
19600}
19601/// Setter of the scope of the current var_decl.
19602///
19603/// Note that the decl won't hold a reference on the scope. It's
19604/// rather the scope that holds a reference on its members.
19605///
19606/// @param scope the new scope.
19607void
19608var_decl::set_scope(scope_decl* scope)
19609{
19610 if (!get_context_rel())
19611 set_context_rel(new dm_context_rel(scope));
19612 else
19613 get_context_rel()->set_scope(scope);
19614}
19615
19616/// Compares two instances of @ref var_decl without taking their type
19617/// into account.
19618///
19619/// If the two intances are different modulo their type, set a
19620/// bitfield to give some insight about the kind of differences there
19621/// are.
19622///
19623/// @param l the first artifact of the comparison.
19624///
19625/// @param r the second artifact of the comparison.
19626///
19627/// @param k a pointer to a bitfield that gives information about the
19628/// kind of changes there are between @p l and @p r. This one is set
19629/// iff @p k is non-null and the function returns false.
19630///
19631/// Please note that setting k to a non-null value does have a
19632/// negative performance impact because even if @p l and @p r are not
19633/// equal, the function keeps up the comparison in order to determine
19634/// the different kinds of ways in which they are different.
19635///
19636/// @return true if @p l equals @p r, false otherwise.
19637bool
19639{
19640 bool result = true;
19641
19642 // If there are underlying elf symbols for these variables,
19643 // compare them. And then compare the other parts.
19644 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
19645 if (!!s0 != !!s1)
19646 {
19647 result = false;
19648 if (k)
19650 else
19652 }
19653 else if (s0 && s0 != s1)
19654 {
19655 result = false;
19656 if (k)
19658 else
19660 }
19661 bool symbols_are_equal = (s0 && s1 && result);
19662
19663 if (symbols_are_equal)
19664 {
19665 // The variables have underlying elf symbols that are equal, so
19666 // now, let's compare the decl_base part of the variables w/o
19667 // considering their decl names.
19668 const environment& env = l.get_environment();
19669 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
19670 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
19671 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
19672 bool decl_bases_different = !l.decl_base::operator==(r);
19673 const_cast<var_decl&>(l).set_qualified_name(n1);
19674 const_cast<var_decl&>(r).set_qualified_name(n2);
19675
19676 if (decl_bases_different)
19677 {
19678 result = false;
19679 if (k)
19681 else
19683 }
19684 }
19685 else
19686 if (!l.decl_base::operator==(r))
19687 {
19688 result = false;
19689 if (k)
19691 else
19693 }
19694
19695 const dm_context_rel* c0 =
19696 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
19697 const dm_context_rel* c1 =
19698 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
19699 ABG_ASSERT(c0 && c1);
19700
19701 if (*c0 != *c1)
19702 {
19703 result = false;
19704 if (k)
19706 else
19708 }
19709
19710 ABG_RETURN(result);
19711}
19712
19713/// Compares two instances of @ref var_decl.
19714///
19715/// If the two intances are different, set a bitfield to give some
19716/// insight about the kind of differences there are.
19717///
19718/// @param l the first artifact of the comparison.
19719///
19720/// @param r the second artifact of the comparison.
19721///
19722/// @param k a pointer to a bitfield that gives information about the
19723/// kind of changes there are between @p l and @p r. This one is set
19724/// iff @p k is non-null and the function returns false.
19725///
19726/// Please note that setting k to a non-null value does have a
19727/// negative performance impact because even if @p l and @p r are not
19728/// equal, the function keeps up the comparison in order to determine
19729/// the different kinds of ways in which they are different.
19730///
19731/// @return true if @p l equals @p r, false otherwise.
19732bool
19733equals(const var_decl& l, const var_decl& r, change_kind* k)
19734{
19735 bool result = true;
19736
19737 // First test types of variables. This should be fast because in
19738 // the general case, most types should be canonicalized.
19739 if (*l.get_naked_type() != *r.get_naked_type())
19740 {
19741 result = false;
19742 if (k)
19743 {
19745 r.get_naked_type()))
19746 *k |= (LOCAL_TYPE_CHANGE_KIND);
19747 else
19748 *k |= SUBTYPE_CHANGE_KIND;
19749 }
19750 else
19752 }
19753
19754 result &= var_equals_modulo_types(l, r, k);
19755
19756 ABG_RETURN(result);
19757}
19758
19759/// Comparison operator of @ref var_decl.
19760///
19761/// @param o the instance of @ref var_decl to compare against.
19762///
19763/// @return true iff the current instance of @ref var_decl equals @p o.
19764bool
19766{
19767 const var_decl* other = dynamic_cast<const var_decl*>(&o);
19768 if (!other)
19769 return false;
19770
19771 return equals(*this, *other, 0);
19772}
19773
19774/// Return an ID that tries to uniquely identify the variable inside a
19775/// program or a library.
19776///
19777/// So if the variable has an underlying elf symbol, the ID is the
19778/// concatenation of the symbol name and its version. Otherwise, the
19779/// ID is the linkage name if its non-null. Otherwise, it's the
19780/// pretty representation of the variable.
19781///
19782/// @return the ID.
19785{
19786 if (priv_->id_.empty())
19787 {
19788 string repr = get_name();
19789 string sym_str;
19790 if (elf_symbol_sptr s = get_symbol())
19791 sym_str = s->get_id_string();
19792 else if (!get_linkage_name().empty())
19793 sym_str = get_linkage_name();
19794
19795 const environment& env = get_type()->get_environment();
19796 priv_->id_ = env.intern(repr);
19797 if (!sym_str.empty())
19798 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
19799 }
19800 return priv_->id_;
19801}
19802
19803/// Return the hash value for the current instance.
19804///
19805/// @return the hash value.
19806size_t
19808{
19809 var_decl::hash hash_var;
19810 return hash_var(this);
19811}
19812
19813/// Get the qualified name of a given variable or data member.
19814///
19815///
19816/// Note that if the current instance of @ref var_decl is an anonymous
19817/// data member, then the qualified name is actually the flat
19818/// representation (the definition) of the type of the anonymous data
19819/// member. We chose the flat representation because otherwise, the
19820/// name of an *anonymous* data member is empty, by construction, e.g:
19821///
19822/// struct foo {
19823/// int a;
19824/// union {
19825/// char b;
19826/// char c;
19827/// }; // <---- this data member is anonymous.
19828/// int d;
19829/// }
19830///
19831/// The string returned for the anonymous member here is going to be:
19832///
19833/// "union {char b; char c}"
19834///
19835/// @param internal if true then this is for a purpose to the library,
19836/// otherwise, it's for being displayed to users.
19837///
19838/// @return the resulting qualified name.
19839const interned_string&
19841{
19842 if (is_anonymous_data_member(this)
19843 && decl_base::get_qualified_name().empty())
19844 {
19845 // Display the anonymous data member in a way that makes sense.
19846 string r = get_pretty_representation(internal);
19848 }
19849
19850 return decl_base::get_qualified_name(internal);
19851}
19852
19853/// Build and return the pretty representation of this variable.
19854///
19855/// @param internal set to true if the call is intended to get a
19856/// representation of the decl (or type) for the purpose of canonical
19857/// type comparison. This is mainly used in the function
19858/// type_base::get_canonical_type_for().
19859///
19860/// In other words if the argument for this parameter is true then the
19861/// call is meant for internal use (for technical use inside the
19862/// library itself), false otherwise. If you don't know what this is
19863/// for, then set it to false.
19864///
19865/// @param qualified_name if true, names emitted in the pretty
19866/// representation are fully qualified.
19867///
19868/// @return a copy of the pretty representation of this variable.
19869string
19870var_decl::get_pretty_representation(bool internal, bool qualified_name) const
19871{
19872 string result;
19873
19874 if (is_member_decl(this) && get_member_is_static(this))
19875 result = "static ";
19876
19877 // Detect if the current instance of var_decl is a member of
19878 // an anonymous class or union.
19879 bool member_of_anonymous_class = false;
19880 if (class_or_union* scope = is_at_class_scope(this))
19881 if (scope->get_is_anonymous())
19882 member_of_anonymous_class = true;
19883
19885 {
19886 string name;
19887 if (member_of_anonymous_class || !qualified_name)
19888 name = get_name();
19889 else
19890 name = get_qualified_name(internal);
19891
19892 type_base_sptr et = t->get_element_type();
19893 ABG_ASSERT(et);
19894 decl_base_sptr decl = get_type_declaration(et);
19895 ABG_ASSERT(decl);
19896 result += decl->get_qualified_name(internal)
19897 + " " + name + t->get_subrange_representation();
19898 }
19899 else
19900 {
19901 if (/*The current var_decl is to be used as an anonymous data
19902 member. */
19903 get_name().empty())
19904 {
19905 // Display the anonymous data member in a way that
19906 // makes sense.
19907 result +=
19910 "", /*one_line=*/true, internal);
19911 }
19912 else if (data_member_has_anonymous_type(this))
19913 {
19916 "", /*one_line=*/true, internal);
19917 result += " ";
19918 if (!internal
19919 && (member_of_anonymous_class || !qualified_name))
19920 // It doesn't make sense to name the member of an
19921 // anonymous class or union like:
19922 // "__anonymous__::data_member_name". So let's just use
19923 // its non-qualified name.
19924 result += get_name();
19925 else
19926 result += get_qualified_name(internal);
19927 }
19928 else
19929 {
19930 result +=
19932 + " ";
19933
19934 if (!internal
19935 && (member_of_anonymous_class || !qualified_name))
19936 // It doesn't make sense to name the member of an
19937 // anonymous class or union like:
19938 // "__anonymous__::data_member_name". So let's just use
19939 // its non-qualified name.
19940 result += get_name();
19941 else
19942 result += get_qualified_name(internal);
19943 }
19944 }
19945 return result;
19946}
19947
19948/// Get a name that is valid even for an anonymous data member.
19949///
19950/// If the current @ref var_decl is an anonymous data member, then
19951/// return its pretty representation. As of now, that pretty
19952/// representation is actually its flat representation as returned by
19953/// get_class_or_union_flat_representation().
19954///
19955/// Otherwise, just return the name of the current @ref var_decl.
19956///
19957/// @param qualified if true, return the qualified name. This doesn't
19958/// have an effet if the current @ref var_decl represents an anonymous
19959/// data member.
19960string
19962{
19963 string name;
19964 if (is_anonymous_data_member(this))
19965 // This function is used in the comparison engine to determine
19966 // which anonymous data member was deleted. So it's not involved
19967 // in type comparison or canonicalization. We don't want to use
19968 // the 'internal' version of the pretty presentation.
19969 name = get_pretty_representation(/*internal=*/false, qualified);
19970 else
19971 name = get_name();
19972
19973 return name;
19974}
19975
19976/// This implements the ir_traversable_base::traverse pure virtual
19977/// function.
19978///
19979/// @param v the visitor used on the current instance.
19980///
19981/// @return true if the entire IR node tree got traversed, false
19982/// otherwise.
19983bool
19985{
19986 if (visiting())
19987 return true;
19988
19989 if (v.visit_begin(this))
19990 {
19991 visiting(true);
19992 if (type_base_sptr t = get_type())
19993 t->traverse(v);
19994 visiting(false);
19995 }
19996 return v.visit_end(this);
19997}
19998
19999var_decl::~var_decl()
20000{}
20001
20002// </var_decl definitions>
20003
20004/// This function is automatically invoked whenever an instance of
20005/// this type is canonicalized.
20006///
20007/// It's an overload of the virtual type_base::on_canonical_type_set.
20008///
20009/// We put here what is thus meant to be executed only at the point of
20010/// type canonicalization.
20011void
20013{
20014 priv_->cached_name_.clear();
20015 priv_->internal_cached_name_.clear();
20016}
20017
20018/// The most straightforward constructor for the function_type class.
20019///
20020/// @param return_type the return type of the function type.
20021///
20022/// @param parms the list of parameters of the function type.
20023/// Stricto sensu, we just need a list of types; we are using a list
20024/// of parameters (where each parameter also carries the name of the
20025/// parameter and its source location) to try and provide better
20026/// diagnostics whenever it makes sense. If it appears that this
20027/// wasts too many resources, we can fall back to taking just a
20028/// vector of types here.
20029///
20030/// @param size_in_bits the size of this type, in bits.
20031///
20032/// @param alignment_in_bits the alignment of this type, in bits.
20033///
20034/// @param size_in_bits the size of this type.
20035function_type::function_type(type_base_sptr return_type,
20036 const parameters& parms,
20037 size_t size_in_bits,
20038 size_t alignment_in_bits)
20039 : type_or_decl_base(return_type->get_environment(),
20040 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
20041 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
20042 priv_(new priv(parms, return_type))
20043{
20045
20046 for (parameters::size_type i = 0, j = 1;
20047 i < priv_->parms_.size();
20048 ++i, ++j)
20049 {
20050 if (i == 0 && priv_->parms_[i]->get_is_artificial())
20051 // If the first parameter is artificial, then it certainly
20052 // means that this is a member function, and the first
20053 // parameter is the implicit this pointer. In that case, set
20054 // the index of that implicit parameter to zero. Otherwise,
20055 // the index of the first parameter starts at one.
20056 j = 0;
20057 priv_->parms_[i]->set_index(j);
20058 }
20059}
20060
20061/// A constructor for a function_type that takes no parameters.
20062///
20063/// @param return_type the return type of this function_type.
20064///
20065/// @param size_in_bits the size of this type, in bits.
20066///
20067/// @param alignment_in_bits the alignment of this type, in bits.
20068function_type::function_type(type_base_sptr return_type,
20069 size_t size_in_bits, size_t alignment_in_bits)
20070 : type_or_decl_base(return_type->get_environment(),
20071 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
20072 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
20073 priv_(new priv(return_type))
20074{
20076}
20077
20078/// A constructor for a function_type that takes no parameter and
20079/// that has no return_type yet. These missing parts can (and must)
20080/// be added later.
20081///
20082/// @param env the environment we are operating from.
20083///
20084/// @param size_in_bits the size of this type, in bits.
20085///
20086/// @param alignment_in_bits the alignment of this type, in bits.
20087function_type::function_type(const environment& env,
20088 size_t size_in_bits,
20089 size_t alignment_in_bits)
20090 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
20091 type_base(env, size_in_bits, alignment_in_bits),
20092 priv_(new priv)
20093{
20095}
20096
20097/// Getter for the return type of the current instance of @ref
20098/// function_type.
20099///
20100/// @return the return type.
20101type_base_sptr
20103{return priv_->return_type_.lock();}
20104
20105/// Setter of the return type of the current instance of @ref
20106/// function_type.
20107///
20108/// @param t the new return type to set.
20109void
20111{priv_->return_type_ = t;}
20112
20113/// Getter for the set of parameters of the current intance of @ref
20114/// function_type.
20115///
20116/// @return the parameters of the current instance of @ref
20117/// function_type.
20120{return priv_->parms_;}
20121
20122/// Get the Ith parameter of the vector of parameters of the current
20123/// instance of @ref function_type.
20124///
20125/// Note that the first parameter is at index 0. That parameter is
20126/// the first parameter that comes after the possible implicit "this"
20127/// parameter, when the current instance @ref function_type is for a
20128/// member function. Otherwise, if the current instance of @ref
20129/// function_type is for a non-member function, the parameter at index
20130/// 0 is the first parameter of the function.
20131///
20132///
20133/// @param i the index of the parameter to return. If i is greater
20134/// than the index of the last parameter, then this function returns
20135/// an empty parameter (smart) pointer.
20136///
20137/// @return the @p i th parameter that is not implicit.
20140{
20141 parameter_sptr result;
20142 if (dynamic_cast<const method_type*>(this))
20143 {
20144 if (i + 1 < get_parameters().size())
20145 result = get_parameters()[i + 1];
20146 }
20147 else
20148 {
20149 if (i < get_parameters().size())
20150 result = get_parameters()[i];
20151 }
20152 return result;
20153}
20154
20155/// Setter for the parameters of the current instance of @ref
20156/// function_type.
20157///
20158/// @param p the new vector of parameters to set.
20159void
20161{
20162 priv_->parms_ = p;
20163 for (parameters::size_type i = 0, j = 1;
20164 i < priv_->parms_.size();
20165 ++i, ++j)
20166 {
20167 if (i == 0 && priv_->parms_[i]->get_is_artificial())
20168 // If the first parameter is artificial, then it certainly
20169 // means that this is a member function, and the first
20170 // parameter is the implicit this pointer. In that case, set
20171 // the index of that implicit parameter to zero. Otherwise,
20172 // the index of the first parameter starts at one.
20173 j = 0;
20174 priv_->parms_[i]->set_index(j);
20175 }
20176}
20177
20178/// Append a new parameter to the vector of parameters of the current
20179/// instance of @ref function_type.
20180///
20181/// @param parm the parameter to append.
20182void
20184{
20185 parm->set_index(priv_->parms_.size());
20186 priv_->parms_.push_back(parm);
20187}
20188
20189/// Test if the current instance of @ref function_type is for a
20190/// variadic function.
20191///
20192/// A variadic function is a function that takes a variable number of
20193/// arguments.
20194///
20195/// @return true iff the current instance of @ref function_type is for
20196/// a variadic function.
20197bool
20199{
20200 return (!priv_->parms_.empty()
20201 && priv_->parms_.back()->get_variadic_marker());
20202}
20203
20204/// Compare two function types.
20205///
20206/// In case these function types are actually method types, this
20207/// function avoids comparing two parameters (of the function types)
20208/// if the types of the parameters are actually the types of the
20209/// classes of the method types. This prevents infinite recursion
20210/// during the comparison of two classes that are structurally
20211/// identical.
20212///
20213/// This is a subroutine of the equality operator of function_type.
20214///
20215/// @param lhs the first function type to consider
20216///
20217/// @param rhs the second function type to consider
20218///
20219/// @param k a pointer to a bitfield set by the function to give
20220/// information about the kind of changes carried by @p lhs and @p
20221/// rhs. It is set iff @p k is non-null and the function returns
20222/// false.
20223///
20224/// Please note that setting k to a non-null value does have a
20225/// negative performance impact because even if @p l and @p r are not
20226/// equal, the function keeps up the comparison in order to determine
20227/// the different kinds of ways in which they are different.
20228///
20229///@return true if lhs == rhs, false otherwise.
20230bool
20232{
20233#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
20234
20236
20237 {
20238 // First of all, let's see if these two function types haven't
20239 // already been compared. If so, and if the result of the
20240 // comparison has been cached, let's just re-use it, rather than
20241 // comparing them all over again.
20242 bool cached_result = false;
20243 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
20244 cached_result))
20245 return cached_result;
20246 }
20247
20249
20250 bool result = true;
20251
20252 if (!l.type_base::operator==(r))
20253 {
20254 result = false;
20255 if (k)
20257 else
20258 RETURN(result);
20259 }
20260
20261 class_or_union* l_class = 0, *r_class = 0;
20262 if (const method_type* m = dynamic_cast<const method_type*>(&l))
20263 l_class = m->get_class_type().get();
20264
20265 if (const method_type* m = dynamic_cast<const method_type*>(&r))
20266 r_class = m->get_class_type().get();
20267
20268 // Compare the names of the class of the method
20269
20270 if (!!l_class != !!r_class)
20271 {
20272 result = false;
20273 if (k)
20275 else
20276 RETURN(result);
20277 }
20278 else if (l_class
20279 && (l_class->get_qualified_name()
20280 != r_class->get_qualified_name()))
20281 {
20282 result = false;
20283 if (k)
20285 else
20286 RETURN(result);
20287 }
20288
20289 // Then compare the return type; Beware if it's t's a class type
20290 // that is the same as the method class name; we can recurse for
20291 // ever in that case.
20292
20293 decl_base* l_return_type_decl =
20295 decl_base* r_return_type_decl =
20297 bool compare_result_types = true;
20298 string l_rt_name = l_return_type_decl
20299 ? l_return_type_decl->get_qualified_name()
20300 : string();
20301 string r_rt_name = r_return_type_decl
20302 ? r_return_type_decl->get_qualified_name()
20303 : string();
20304
20305 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
20306 ||
20307 (r_class && (r_class->get_qualified_name() == r_rt_name)))
20308 compare_result_types = false;
20309
20310 if (compare_result_types)
20311 {
20312 // Let's not consider typedefs when comparing return types to
20313 // avoid spurious changes.
20314 //
20315 // TODO: We should also do this for parameter types, or rather,
20316 // we should teach the equality operators in the IR, at some
20317 // point, to peel typedefs off.
20319 !=
20321 {
20322 result = false;
20323 if (k)
20324 {
20326 r.get_return_type()))
20328 else
20329 *k |= SUBTYPE_CHANGE_KIND;
20330 }
20331 else
20332 RETURN(result);
20333 }
20334 }
20335 else
20336 if (l_rt_name != r_rt_name)
20337 {
20338 result = false;
20339 if (k)
20340 *k |= SUBTYPE_CHANGE_KIND;
20341 else
20342 RETURN(result);
20343 }
20344
20345 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
20346 for (i = l.get_first_parm(), j = r.get_first_parm();
20347 i != l.get_parameters().end() && j != r.get_parameters().end();
20348 ++i, ++j)
20349 {
20350 if (**i != **j)
20351 {
20352 result = false;
20353 if (k)
20354 {
20355 if (!types_have_similar_structure((*i)->get_type(),
20356 (*j)->get_type()))
20358 else
20359 *k |= SUBTYPE_CHANGE_KIND;
20360 }
20361 else
20362 RETURN(result);
20363 }
20364 }
20365
20366 if ((i != l.get_parameters().end()
20367 || j != r.get_parameters().end()))
20368 {
20369 result = false;
20370 if (k)
20372 else
20373 RETURN(result);
20374 }
20375
20376 RETURN(result);
20377#undef RETURN
20378}
20379
20380/// Get the first parameter of the function.
20381///
20382/// If the function is a non-static member function, the parameter
20383/// returned is the first one following the implicit 'this' parameter.
20384///
20385/// @return the first non implicit parameter of the function.
20386function_type::parameters::const_iterator
20388{
20389 if (get_parameters().empty())
20390 return get_parameters().end();
20391
20392 bool is_method = dynamic_cast<const method_type*>(this);
20393
20394 parameters::const_iterator i = get_parameters().begin();
20395
20396 if (is_method)
20397 ++i;
20398
20399 return i;
20400}
20401
20402/// Get the first parameter of the function.
20403///
20404/// Note that if the function is a non-static member function, the
20405/// parameter returned is the implicit 'this' parameter.
20406///
20407/// @return the first parameter of the function.
20408function_type::parameters::const_iterator
20410{return get_parameters().begin();}
20411
20412/// Get the name of the current @ref function_type.
20413///
20414/// The name is retrieved from a cache. If the cache is empty, this
20415/// function computes the name of the type, stores it in the cache and
20416/// returns it. Subsequent invocation of the function are going to
20417/// just hit the cache.
20418///
20419/// Note that if the type is *NOT* canonicalized then function type
20420/// name is never cached.
20421///
20422/// @param internal if true then it means the function type name is
20423/// going to be used for purposes that are internal to libabigail
20424/// itself. If you don't know what this is then you probably should
20425/// set this parameter to 'false'.
20426///
20427/// @return the name of the function type.
20428const interned_string&
20430{
20431 if (internal)
20432 {
20434 {
20435 if (priv_->internal_cached_name_.empty())
20436 priv_->internal_cached_name_ =
20437 get_function_type_name(this, /*internal=*/true);
20438 return priv_->internal_cached_name_;
20439 }
20440 else
20441 {
20442 priv_->temp_internal_cached_name_ =
20444 /*internal=*/true);
20445 return priv_->temp_internal_cached_name_;
20446 }
20447 }
20448 else
20449 {
20451 {
20452 if (priv_->cached_name_.empty())
20453 priv_->cached_name_ =
20454 get_function_type_name(this, /*internal=*/false);
20455 return priv_->cached_name_;
20456 }
20457 else
20458 {
20459 priv_->cached_name_ =
20460 get_function_type_name(this, /*internal=*/false);
20461 return priv_->cached_name_;
20462 }
20463 }
20464}
20465
20466/// Equality operator for function_type.
20467///
20468/// @param o the other function_type to compare against.
20469///
20470/// @return true iff the two function_type are equal.
20471bool
20473{
20474 const function_type* o = dynamic_cast<const function_type*>(&other);
20475 if (!o)
20476 return false;
20477 return try_canonical_compare(this, o);
20478}
20479
20480/// Return a copy of the pretty representation of the current @ref
20481/// function_type.
20482///
20483/// @param internal set to true if the call is intended to get a
20484/// representation of the decl (or type) for the purpose of canonical
20485/// type comparison. This is mainly used in the function
20486/// type_base::get_canonical_type_for().
20487///
20488/// In other words if the argument for this parameter is true then the
20489/// call is meant for internal use (for technical use inside the
20490/// library itself), false otherwise. If you don't know what this is
20491/// for, then set it to false.
20492///
20493/// @return a copy of the pretty representation of the current @ref
20494/// function_type.
20495string
20497 bool /*qualified_name*/) const
20498{return ir::get_pretty_representation(this, internal);}
20499
20500/// Traverses an instance of @ref function_type, visiting all the
20501/// sub-types and decls that it might contain.
20502///
20503/// @param v the visitor that is used to visit every IR sub-node of
20504/// the current node.
20505///
20506/// @return true if either
20507/// - all the children nodes of the current IR node were traversed
20508/// and the calling code should keep going with the traversing.
20509/// - or the current IR node is already being traversed.
20510/// Otherwise, returning false means that the calling code should not
20511/// keep traversing the tree.
20512bool
20514{
20515 // TODO: should we allow the walker to avoid visiting function type
20516 // twice? I think that if we do, then ir_node_visitor needs an
20517 // option to specifically disallow this feature for function types.
20518
20519 if (visiting())
20520 return true;
20521
20522 if (v.visit_begin(this))
20523 {
20524 visiting(true);
20525 bool keep_going = true;
20526
20527 if (type_base_sptr t = get_return_type())
20528 {
20529 if (!t->traverse(v))
20530 keep_going = false;
20531 }
20532
20533 if (keep_going)
20534 for (parameters::const_iterator i = get_parameters().begin();
20535 i != get_parameters().end();
20536 ++i)
20537 if (type_base_sptr parm_type = (*i)->get_type())
20538 if (!parm_type->traverse(v))
20539 break;
20540
20541 visiting(false);
20542 }
20543 return v.visit_end(this);
20544}
20545
20546function_type::~function_type()
20547{}
20548// </function_type>
20549
20550// <method_type>
20551
20552struct method_type::priv
20553{
20554 class_or_union_wptr class_type_;
20555 bool is_const;
20556
20557 priv()
20558 : is_const()
20559 {}
20560}; // end struct method_type::priv
20561
20562/// Constructor for instances of method_type.
20563///
20564/// Instances of method_decl must be of type method_type.
20565///
20566/// @param return_type the type of the return value of the method.
20567///
20568/// @param class_type the base type of the method type. That is, the
20569/// type of the class the method belongs to.
20570///
20571/// @param p the vector of the parameters of the method.
20572///
20573/// @param is_const whether this method type is for a const method.
20574/// Note that const-ness is a property of the method *type* and of the
20575/// relationship between a method *declaration* and its scope.
20576///
20577/// @param size_in_bits the size of an instance of method_type,
20578/// expressed in bits.
20579///
20580/// @param alignment_in_bits the alignment of an instance of
20581/// method_type, expressed in bits.
20582method_type::method_type (type_base_sptr return_type,
20583 class_or_union_sptr class_type,
20584 const std::vector<function_decl::parameter_sptr>& p,
20585 bool is_const,
20586 size_t size_in_bits,
20587 size_t alignment_in_bits)
20588 : type_or_decl_base(class_type->get_environment(),
20589 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
20590 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
20591 function_type(return_type, p, size_in_bits, alignment_in_bits),
20592 priv_(new priv)
20593{
20595 set_class_type(class_type);
20596 set_is_const(is_const);
20597}
20598
20599/// Constructor of instances of method_type.
20600///
20601///Instances of method_decl must be of type method_type.
20602///
20603/// @param return_type the type of the return value of the method.
20604///
20605/// @param class_type the type of the class the method belongs to.
20606/// The actual (dynamic) type of class_type must be a pointer
20607/// class_type. We are setting it to pointer to type_base here to
20608/// help client code that is compiled without rtti and thus cannot
20609/// perform dynamic casts.
20610///
20611/// @param p the vector of the parameters of the method type.
20612///
20613/// @param is_const whether this method type is for a const method.
20614/// Note that const-ness is a property of the method *type* and of the
20615/// relationship between a method *declaration* and its scope.
20616///
20617/// @param size_in_bits the size of an instance of method_type,
20618/// expressed in bits.
20619///
20620/// @param alignment_in_bits the alignment of an instance of
20621/// method_type, expressed in bits.
20622method_type::method_type(type_base_sptr return_type,
20623 type_base_sptr class_type,
20624 const std::vector<function_decl::parameter_sptr>& p,
20625 bool is_const,
20626 size_t size_in_bits,
20627 size_t alignment_in_bits)
20628 : type_or_decl_base(class_type->get_environment(),
20629 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
20630 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
20631 function_type(return_type, p, size_in_bits, alignment_in_bits),
20632 priv_(new priv)
20633{
20635 set_class_type(is_class_type(class_type));
20636 set_is_const(is_const);
20637}
20638
20639/// Constructor of the qualified_type_def
20640///
20641/// @param env the environment we are operating from.
20642///
20643/// @param size_in_bits the size of the type, expressed in bits.
20644///
20645/// @param alignment_in_bits the alignment of the type, expressed in bits
20646method_type::method_type(const environment& env,
20647 size_t size_in_bits,
20648 size_t alignment_in_bits)
20649 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
20650 type_base(env, size_in_bits, alignment_in_bits),
20651 function_type(env, size_in_bits, alignment_in_bits),
20652 priv_(new priv)
20653{
20655}
20656
20657/// Constructor of instances of method_type.
20658///
20659/// When constructed with this constructor, and instane of method_type
20660/// must set a return type using method_type::set_return_type
20661///
20662/// @param class_typ the base type of the method type. That is, the
20663/// type of the class (or union) the method belongs to.
20664///
20665/// @param size_in_bits the size of an instance of method_type,
20666/// expressed in bits.
20667///
20668/// @param alignment_in_bits the alignment of an instance of
20669/// method_type, expressed in bits.
20670method_type::method_type(class_or_union_sptr class_type,
20671 bool is_const,
20672 size_t size_in_bits,
20673 size_t alignment_in_bits)
20674 : type_or_decl_base(class_type->get_environment(),
20675 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
20676 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
20677 function_type(class_type->get_environment(),
20678 size_in_bits,
20679 alignment_in_bits),
20680 priv_(new priv)
20681{
20683 set_class_type(class_type);
20684 set_is_const(is_const);
20685}
20686
20687/// Get the class type this method belongs to.
20688///
20689/// @return the class type.
20690class_or_union_sptr
20692{return class_or_union_sptr(priv_->class_type_);}
20693
20694/// Sets the class type of the current instance of method_type.
20695///
20696/// The class type is the type of the class the method belongs to.
20697///
20698/// @param t the new class type to set.
20699void
20700method_type::set_class_type(const class_or_union_sptr& t)
20701{
20702 if (!t)
20703 return;
20704
20705 priv_->class_type_ = t;
20706}
20707
20708/// Return a copy of the pretty representation of the current @ref
20709/// method_type.
20710///
20711/// @param internal set to true if the call is intended to get a
20712/// representation of the decl (or type) for the purpose of canonical
20713/// type comparison. This is mainly used in the function
20714/// type_base::get_canonical_type_for().
20715///
20716/// In other words if the argument for this parameter is true then the
20717/// call is meant for internal use (for technical use inside the
20718/// library itself), false otherwise. If you don't know what this is
20719/// for, then set it to false.
20720///
20721/// @return a copy of the pretty representation of the current @ref
20722/// method_type.
20723string
20725 bool /*qualified_name*/) const
20726{return ir::get_pretty_representation(*this, internal);}
20727
20728/// Setter of the "is-const" property of @ref method_type.
20729///
20730/// @param the new value of the "is-const" property.
20731void
20733{priv_->is_const = f;}
20734
20735/// Getter of the "is-const" property of @ref method_type.
20736///
20737/// @return true iff the "is-const" property was set.
20738bool
20740{return priv_->is_const;}
20741
20742/// The destructor of method_type
20744{}
20745
20746// </method_type>
20747
20748// <function_decl definitions>
20749
20750struct function_decl::priv
20751{
20752 bool declared_inline_;
20753 decl_base::binding binding_;
20754 function_type_wptr type_;
20755 function_type* naked_type_;
20756 elf_symbol_sptr symbol_;
20757 interned_string id_;
20758
20759 priv()
20760 : declared_inline_(false),
20761 binding_(decl_base::BINDING_GLOBAL),
20762 naked_type_()
20763 {}
20764
20765 priv(function_type_sptr t,
20766 bool declared_inline,
20768 : declared_inline_(declared_inline),
20769 binding_(binding),
20770 type_(t),
20771 naked_type_(t.get())
20772 {}
20773
20774 priv(function_type_sptr t,
20775 bool declared_inline,
20778 : declared_inline_(declared_inline),
20779 binding_(binding),
20780 type_(t),
20781 naked_type_(t.get()),
20782 symbol_(s)
20783 {}
20784}; // end sruct function_decl::priv
20785
20786/// Constructor of the @ref function_decl.
20787///
20788/// @param name the name of the function.
20789///
20790/// @param function_type the type of the function.
20791///
20792/// @param declared_inline wether the function is declared inline.
20793///
20794/// @param locus the source location of the function.
20795///
20796/// @param mangled_name the linkage name of the function.
20797///
20798/// @param vis the visibility of the function.
20799///
20800/// @param bind the binding of the function.
20803 bool declared_inline,
20804 const location& locus,
20805 const string& mangled_name,
20806 visibility vis,
20807 binding bind)
20808 : type_or_decl_base(function_type->get_environment(),
20809 FUNCTION_DECL | ABSTRACT_DECL_BASE),
20810 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
20811 priv_(new priv(function_type, declared_inline, bind))
20812{
20814}
20815
20816/// Constructor of the function_decl type.
20817///
20818/// This flavour of constructor is for when the pointer to the
20819/// instance of function_type that the client code has is presented as
20820/// a pointer to type_base. In that case, this constructor saves the
20821/// client code from doing a dynamic_cast to get the function_type
20822/// pointer.
20823///
20824/// @param name the name of the function declaration.
20825///
20826/// @param fn_type the type of the function declaration. The dynamic
20827/// type of this parameter should be 'pointer to function_type'
20828///
20829/// @param declared_inline whether this function was declared inline
20830///
20831/// @param locus the source location of the function declaration.
20832///
20833/// @param linkage_name the mangled name of the function declaration.
20834///
20835/// @param vis the visibility of the function declaration.
20836///
20837/// @param bind the kind of the binding of the function
20838/// declaration.
20840 type_base_sptr fn_type,
20841 bool declared_inline,
20842 const location& locus,
20843 const string& linkage_name,
20844 visibility vis,
20845 binding bind)
20846 : type_or_decl_base(fn_type->get_environment(),
20847 FUNCTION_DECL | ABSTRACT_DECL_BASE),
20848 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
20849 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
20850 declared_inline,
20851 bind))
20852{
20854}
20855
20856/// Get the pretty representation of the current instance of @ref function_decl.
20857///
20858/// @param internal set to true if the call is intended to get a
20859/// representation of the decl (or type) for the purpose of canonical
20860/// type comparison. This is mainly used in the function
20861/// type_base::get_canonical_type_for().
20862///
20863/// In other words if the argument for this parameter is true then the
20864/// call is meant for internal use (for technical use inside the
20865/// library itself), false otherwise. If you don't know what this is
20866/// for, then set it to false.
20867///
20868/// @return the pretty representation for a function.
20869string
20871 bool /*qualified_name*/) const
20872{
20873 const method_decl* mem_fn =
20874 dynamic_cast<const method_decl*>(this);
20875
20876 string result = mem_fn ? "method ": "function ";
20877
20878 if (mem_fn
20879 && is_member_function(mem_fn)
20881 result += "virtual ";
20882
20883 decl_base_sptr type;
20884 if ((mem_fn
20885 && is_member_function(mem_fn)
20886 && (get_member_function_is_dtor(*mem_fn)
20887 || get_member_function_is_ctor(*mem_fn))))
20888 /*cdtors do not have return types. */;
20889 else
20890 type = mem_fn
20891 ? get_type_declaration(mem_fn->get_type()->get_return_type())
20893
20894 if (type)
20895 result += type->get_qualified_name(internal) + " ";
20896
20897 result += get_pretty_representation_of_declarator(internal);
20898
20899 return result;
20900}
20901
20902/// Compute and return the pretty representation for the part of the
20903/// function declaration that starts at the declarator. That is, the
20904/// return type and the other specifiers of the beginning of the
20905/// function's declaration ar omitted.
20906///
20907/// @param internal set to true if the call is intended to get a
20908/// representation of the decl (or type) for the purpose of canonical
20909/// type comparison. This is mainly used in the function
20910/// type_base::get_canonical_type_for().
20911///
20912/// In other words if the argument for this parameter is true then the
20913/// call is meant for internal use (for technical use inside the
20914/// library itself), false otherwise. If you don't know what this is
20915/// for, then set it to false.
20916///
20917/// @return the pretty representation for the part of the function
20918/// declaration that starts at the declarator.
20919string
20921{
20922 const method_decl* mem_fn =
20923 dynamic_cast<const method_decl*>(this);
20924
20925 string result;
20926
20927 if (mem_fn)
20928 {
20929 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
20930 + "::" + mem_fn->get_name();
20931 }
20932 else
20933 result += get_qualified_name();
20934
20935 result += "(";
20936
20937 parameters::const_iterator i = get_parameters().begin(),
20938 end = get_parameters().end();
20939
20940 // Skip the first parameter if this is a method.
20941 if (mem_fn && i != end)
20942 ++i;
20943 parameter_sptr parm;
20944 parameter_sptr first_parm;
20945 if (i != end)
20946 first_parm = *i;
20947 for (; i != end; ++i)
20948 {
20949 parm = *i;
20950 if (parm.get() != first_parm.get())
20951 result += ", ";
20952 if (parm->get_variadic_marker()
20953 || get_environment().is_variadic_parameter_type(parm->get_type()))
20954 result += "...";
20955 else
20956 {
20957 type_base_sptr type = parm->get_type();
20958 if (internal)
20959 type = peel_typedef_type(type);
20960 result += get_type_name(type, /*qualified=*/true, internal);
20961 }
20962 }
20963 result += ")";
20964
20965 if (mem_fn
20966 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
20967 || is_method_type(mem_fn->get_type())->get_is_const()))
20968 result += " const";
20969
20970 return result;
20971}
20972
20973/// Getter for the first non-implicit parameter of a function decl.
20974///
20975/// If the function is a non-static member function, the parameter
20976/// returned is the first one following the implicit 'this' parameter.
20977///
20978/// @return the first non implicit parm.
20979function_decl::parameters::const_iterator
20981{
20982 if (get_parameters().empty())
20983 return get_parameters().end();
20984
20985 bool is_method = dynamic_cast<const method_decl*>(this);
20986
20987 parameters::const_iterator i = get_parameters().begin();
20988 if (is_method)
20989 ++i;
20990
20991 return i;
20992}
20993
20994/// Return the type of the current instance of @ref function_decl.
20995///
20996/// It's either a function_type or method_type.
20997/// @return the type of the current instance of @ref function_decl.
20998const shared_ptr<function_type>
21000{return priv_->type_.lock();}
21001
21002/// Fast getter of the type of the current instance of @ref function_decl.
21003///
21004/// Note that this function returns the underlying pointer managed by
21005/// the smart pointer returned by function_decl::get_type(). It's
21006/// faster than function_decl::get_type(). This getter is to be used
21007/// in code paths that are proven to be performance hot spots;
21008/// especially (for instance) when comparing function types. Those
21009/// are compared extremely frequently when libabigail is used to
21010/// handle huge binaries with a lot of functions.
21011///
21012/// @return the type of the current instance of @ref function_decl.
21013const function_type*
21015{return priv_->naked_type_;}
21016
21017void
21018function_decl::set_type(const function_type_sptr& fn_type)
21019{
21020 priv_->type_ = fn_type;
21021 priv_->naked_type_ = fn_type.get();
21022}
21023
21024/// This sets the underlying ELF symbol for the current function decl.
21025///
21026/// And underlyin$g ELF symbol for the current function decl might
21027/// exist only if the corpus that this function decl originates from
21028/// was constructed from an ELF binary file.
21029///
21030/// Note that comparing two function decls that have underlying ELF
21031/// symbols involves comparing their underlying elf symbols. The decl
21032/// name for the function thus becomes irrelevant in the comparison.
21033///
21034/// @param sym the new ELF symbol for this function decl.
21035void
21037{
21038 priv_->symbol_ = sym;
21039 // The function id cache that depends on the symbol must be
21040 // invalidated because the symbol changed.
21041 priv_->id_ = get_environment().intern("");
21042}
21043
21044/// Gets the the underlying ELF symbol for the current variable,
21045/// that was set using function_decl::set_symbol(). Please read the
21046/// documentation for that member function for more information about
21047/// "underlying ELF symbols".
21048///
21049/// @return sym the underlying ELF symbol for this function decl, if
21050/// one exists.
21051const elf_symbol_sptr&
21053{return priv_->symbol_;}
21054
21055bool
21056function_decl::is_declared_inline() const
21057{return priv_->declared_inline_;}
21058
21060function_decl::get_binding() const
21061{return priv_->binding_;}
21062
21063/// @return the return type of the current instance of function_decl.
21064const shared_ptr<type_base>
21066{return get_type()->get_return_type();}
21067
21068/// @return the parameters of the function.
21069const std::vector<shared_ptr<function_decl::parameter> >&
21071{return get_type()->get_parameters();}
21072
21073/// Append a parameter to the type of this function.
21074///
21075/// @param parm the parameter to append.
21076void
21077function_decl::append_parameter(shared_ptr<parameter> parm)
21078{get_type()->append_parameter(parm);}
21079
21080/// Append a vector of parameters to the type of this function.
21081///
21082/// @param parms the vector of parameters to append.
21083void
21084function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
21085{
21086 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
21087 i != parms.end();
21088 ++i)
21089 get_type()->append_parameter(*i);
21090}
21091
21092/// Create a new instance of function_decl that is a clone of the
21093/// current one.
21094///
21095/// @return the new clone.
21098{
21100 if (is_member_function(*this))
21101 {
21102 method_decl_sptr
21103 m(new method_decl(get_name(),
21104 get_type(),
21105 is_declared_inline(),
21106 get_location(),
21109 get_binding()));
21111 ABG_ASSERT(scope);
21115 get_member_is_static(*this),
21119 f = m;
21120 }
21121 else
21122 {
21123 f.reset(new function_decl(get_name(),
21124 get_type(),
21125 is_declared_inline(),
21126 get_location(),
21129 get_binding()));
21131 }
21132 f->set_symbol(get_symbol());
21133
21134 return f;
21135}
21136
21137/// Compares two instances of @ref function_decl.
21138///
21139/// If the two intances are different, set a bitfield to give some
21140/// insight about the kind of differences there are.
21141///
21142/// @param l the first artifact of the comparison.
21143///
21144/// @param r the second artifact of the comparison.
21145///
21146/// @param k a pointer to a bitfield that gives information about the
21147/// kind of changes there are between @p l and @p r. This one is set
21148/// iff @p k is non-null and the function returns false.
21149///
21150/// Please note that setting k to a non-null value does have a
21151/// negative performance impact because even if @p l and @p r are not
21152/// equal, the function keeps up the comparison in order to determine
21153/// the different kinds of ways in which they are different.
21154///
21155/// @return true if @p l equals @p r, false otherwise.
21156bool
21158{
21159 bool result = true;
21160
21161 // Compare function types
21162 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
21163 if (t0 == t1 || *t0 == *t1)
21164 ; // the types are equal, let's move on to compare the other
21165 // properties of the functions.
21166 else
21167 {
21168 result = false;
21169 if (k)
21170 {
21171 if (!types_have_similar_structure(t0, t1))
21173 else
21174 *k |= SUBTYPE_CHANGE_KIND;
21175 }
21176 else
21178 }
21179
21180 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
21181 if (!!s0 != !!s1)
21182 {
21183 result = false;
21184 if (k)
21186 else
21188 }
21189 else if (s0 && s0 != s1)
21190 {
21191 if (!elf_symbols_alias(s0, s1))
21192 {
21193 result = false;
21194 if (k)
21196 else
21198 }
21199 }
21200 bool symbols_are_equal = (s0 && s1 && result);
21201
21202 if (symbols_are_equal)
21203 {
21204 // The functions have underlying elf symbols that are equal,
21205 // so now, let's compare the decl_base part of the functions
21206 // w/o considering their decl names.
21207 interned_string n1 = l.get_name(), n2 = r.get_name();
21209 const_cast<function_decl&>(l).set_name("");
21210 const_cast<function_decl&>(l).set_linkage_name("");
21211 const_cast<function_decl&>(r).set_name("");
21212 const_cast<function_decl&>(r).set_linkage_name("");
21213
21214 bool decl_bases_different = !l.decl_base::operator==(r);
21215
21216 const_cast<function_decl&>(l).set_name(n1);
21217 const_cast<function_decl&>(l).set_linkage_name(ln1);
21218 const_cast<function_decl&>(r).set_name(n2);
21219 const_cast<function_decl&>(r).set_linkage_name(ln2);
21220
21221 if (decl_bases_different)
21222 {
21223 result = false;
21224 if (k)
21226 else
21228 }
21229 }
21230 else
21231 if (!l.decl_base::operator==(r))
21232 {
21233 result = false;
21234 if (k)
21236 else
21238 }
21239
21240 // Compare the remaining properties
21241 if (l.is_declared_inline() != r.is_declared_inline()
21242 || l.get_binding() != r.get_binding())
21243 {
21244 result = false;
21245 if (k)
21247 else
21249 }
21250
21252 {
21253 result = false;
21254 if (k)
21256 else
21258 }
21259
21261 {
21274 {
21275 result = false;
21276 if (k)
21278 else
21280 }
21281 }
21282
21283 ABG_RETURN(result);
21284}
21285
21286/// Comparison operator for @ref function_decl.
21287///
21288/// @param other the other instance of @ref function_decl to compare
21289/// against.
21290///
21291/// @return true iff the current instance of @ref function_decl equals
21292/// @p other.
21293bool
21295{
21296 const function_decl* o = dynamic_cast<const function_decl*>(&other);
21297 if (!o)
21298 return false;
21299 return equals(*this, *o, 0);
21300}
21301
21302/// Return true iff the function takes a variable number of
21303/// parameters.
21304///
21305/// @return true if the function taks a variable number
21306/// of parameters.
21307bool
21309{
21310 return (!get_parameters().empty()
21311 && get_parameters().back()->get_variadic_marker());
21312}
21313
21314/// The virtual implementation of 'get_hash' for a function_decl.
21315///
21316/// This allows decl_base::get_hash to work for function_decls.
21317///
21318/// @return the hash value for function decl.
21319size_t
21321{
21322 function_decl::hash hash_fn;
21323 return hash_fn(*this);
21324}
21325
21326/// Return an ID that tries to uniquely identify the function inside a
21327/// program or a library.
21328///
21329/// So if the function has an underlying elf symbol, the ID is the
21330/// concatenation of the symbol name and its version. Otherwise, the
21331/// ID is the linkage name if its non-null. Otherwise, it's the
21332/// pretty representation of the function.
21333///
21334/// @return the ID.
21337{
21338 if (priv_->id_.empty())
21339 {
21340 const environment& env = get_type()->get_environment();
21341 if (elf_symbol_sptr s = get_symbol())
21342 {
21343 if (s->has_aliases())
21344 // The symbol has several aliases, so let's use a scheme
21345 // that allows all aliased functions to have different
21346 // IDs.
21347 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
21348 else
21349 // Let's use the full symbol name with its version as ID.
21350 priv_->id_ = env.intern(s->get_id_string());
21351 }
21352 else if (!get_linkage_name().empty())
21353 priv_->id_= env.intern(get_linkage_name());
21354 else
21355 priv_->id_ = env.intern(get_pretty_representation());
21356 }
21357 return priv_->id_;
21358}
21359
21360/// Test if two function declarations are aliases.
21361///
21362/// Two functions declarations are aliases if their symbols are
21363/// aliases, in the ELF sense.
21364///
21365/// @param f1 the first function to consider.
21366///
21367/// @param f2 the second function to consider.
21368///
21369/// @return true iff @p f1 is an alias of @p f2
21370bool
21372{
21373 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
21374
21375 if (!s1 || !s2)
21376 return false;
21377
21378 return elf_symbols_alias(s1, s2);
21379}
21380
21381/// This implements the ir_traversable_base::traverse pure virtual
21382/// function.
21383///
21384/// @param v the visitor used on the current instance.
21385///
21386/// @return true if the entire IR node tree got traversed, false
21387/// otherwise.
21388bool
21390{
21391 if (visiting())
21392 return true;
21393
21394 if (v.visit_begin(this))
21395 {
21396 visiting(true);
21397 if (type_base_sptr t = get_type())
21398 t->traverse(v);
21399 visiting(false);
21400 }
21401 return v.visit_end(this);
21402}
21403
21404/// Destructor of the @ref function_decl type.
21406{delete priv_;}
21407
21408/// A deep comparison operator for a shared pointer to @ref function_decl
21409///
21410/// This function compares to shared pointers to @ref function_decl by
21411/// looking at the pointed-to instances of @ref function_dec
21412/// comparing them too. If the two pointed-to objects are equal then
21413/// this function returns true.
21414///
21415/// @param l the left-hand side argument of the equality operator.
21416///
21417/// @param r the right-hand side argument of the equality operator.
21418///
21419/// @return true iff @p l equals @p r.
21420bool
21422{
21423 if (l.get() == r.get())
21424 return true;
21425 if (!!l != !!r)
21426 return false;
21427
21428 return *l == *r;
21429}
21430
21431/// A deep inequality operator for smart pointers to functions.
21432///
21433/// @param l the left-hand side argument of the inequality operator.
21434///
21435/// @pram r the right-hand side argument of the inequality operator.
21436///
21437/// @return true iff @p is not equal to @p r.
21438bool
21440{return !operator==(l, r);}
21441
21442// <function_decl definitions>
21443
21444// <function_decl::parameter definitions>
21445
21446struct function_decl::parameter::priv
21447{
21448 type_base_wptr type_;
21449 unsigned index_;
21450 bool variadic_marker_;
21451
21452 priv()
21453 : index_(),
21454 variadic_marker_()
21455 {}
21456
21457 priv(type_base_sptr type,
21458 unsigned index,
21459 bool variadic_marker)
21460 : type_(type),
21461 index_(index),
21462 variadic_marker_(variadic_marker)
21463 {}
21464};// end struct function_decl::parameter::priv
21465
21466function_decl::parameter::parameter(const type_base_sptr type,
21467 unsigned index,
21468 const string& name,
21469 const location& loc,
21470 bool is_variadic)
21471 : type_or_decl_base(type->get_environment(),
21472 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21473 decl_base(type->get_environment(), name, loc),
21474 priv_(new priv(type, index, is_variadic))
21475{
21476 runtime_type_instance(this);
21477}
21478
21479function_decl::parameter::parameter(const type_base_sptr type,
21480 unsigned index,
21481 const string& name,
21482 const location& loc,
21483 bool is_variadic,
21484 bool is_artificial)
21485 : type_or_decl_base(type->get_environment(),
21486 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21487 decl_base(type->get_environment(), name, loc),
21488 priv_(new priv(type, index, is_variadic))
21489{
21490 runtime_type_instance(this);
21491 set_is_artificial(is_artificial);
21492}
21493
21494function_decl::parameter::parameter(const type_base_sptr type,
21495 const string& name,
21496 const location& loc,
21497 bool is_variadic,
21498 bool is_artificial)
21499 : type_or_decl_base(type->get_environment(),
21500 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21501 decl_base(type->get_environment(), name, loc),
21502 priv_(new priv(type, 0, is_variadic))
21503{
21504 runtime_type_instance(this);
21505 set_is_artificial(is_artificial);
21506}
21507
21508function_decl::parameter::parameter(const type_base_sptr type,
21509 unsigned index,
21510 bool variad)
21511 : type_or_decl_base(type->get_environment(),
21512 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21513 decl_base(type->get_environment(), "", location()),
21514 priv_(new priv(type, index, variad))
21515{
21516 runtime_type_instance(this);
21517}
21518
21519function_decl::parameter::~parameter() = default;
21520
21521const type_base_sptr
21522function_decl::parameter::get_type()const
21523{return priv_->type_.lock();}
21524
21525/// @return a copy of the type name of the parameter.
21526interned_string
21528{
21529 const environment& env = get_environment();
21530
21531 type_base_sptr t = get_type();
21532 string str;
21533 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
21534 str = "...";
21535 else
21536 {
21537 ABG_ASSERT(t);
21539 }
21540 return env.intern(str);
21541}
21542
21543/// @return a copy of the pretty representation of the type of the
21544/// parameter.
21545const string
21547{
21548 type_base_sptr t = get_type();
21549 string str;
21550 if (get_variadic_marker()
21551 || get_environment().is_variadic_parameter_type(t))
21552 str = "...";
21553 else
21554 {
21555 ABG_ASSERT(t);
21557 }
21558 return str;
21559}
21560
21561/// Get a name uniquely identifying the parameter in the function.
21562///
21563///@return the unique parm name id.
21566{
21567 const environment& env = get_environment();
21568
21569
21570 std::ostringstream o;
21571 o << "parameter-" << get_index();
21572
21573 return env.intern(o.str());
21574}
21575
21576unsigned
21577function_decl::parameter::get_index() const
21578{return priv_->index_;}
21579
21580void
21581function_decl::parameter::set_index(unsigned i)
21582{priv_->index_ = i;}
21583
21584
21585bool
21586function_decl::parameter::get_variadic_marker() const
21587{return priv_->variadic_marker_;}
21588
21589/// Compares two instances of @ref function_decl::parameter.
21590///
21591/// If the two intances are different, set a bitfield to give some
21592/// insight about the kind of differences there are.
21593///
21594/// @param l the first artifact of the comparison.
21595///
21596/// @param r the second artifact of the comparison.
21597///
21598/// @param k a pointer to a bitfield that gives information about the
21599/// kind of changes there are between @p l and @p r. This one is set
21600/// iff @p k is non-null and the function returns false.
21601///
21602/// Please note that setting k to a non-null value does have a
21603/// negative performance impact because even if @p l and @p r are not
21604/// equal, the function keeps up the comparison in order to determine
21605/// the different kinds of ways in which they are different.
21606///
21607/// @return true if @p l equals @p r, false otherwise.
21608bool
21610 const function_decl::parameter& r,
21611 change_kind* k)
21612{
21613 bool result = true;
21614
21615 if ((l.get_variadic_marker() != r.get_variadic_marker())
21616 || (l.get_index() != r.get_index())
21617 || (!!l.get_type() != !!r.get_type()))
21618 {
21619 result = false;
21620 if (k)
21621 {
21622 if (l.get_index() != r.get_index())
21624 if (l.get_variadic_marker() != r.get_variadic_marker()
21625 || !!l.get_type() != !!r.get_type())
21627 }
21628 else
21630 }
21631
21632 type_base_sptr l_type = peel_typedef_type(l.get_type());
21633 type_base_sptr r_type = peel_typedef_type(r.get_type());
21634 if (l_type != r_type)
21635 {
21636 result = false;
21637 if (k)
21638 {
21639 if (!types_have_similar_structure(l_type, r_type))
21641 else
21642 *k |= SUBTYPE_CHANGE_KIND;
21643 }
21644 else
21646 }
21647
21648 ABG_RETURN(result);
21649}
21650
21651bool
21652function_decl::parameter::operator==(const parameter& o) const
21653{return equals(*this, o, 0);}
21654
21655bool
21656function_decl::parameter::operator==(const decl_base& o) const
21657{
21658 const function_decl::parameter* p =
21659 dynamic_cast<const function_decl::parameter*>(&o);
21660 if (!p)
21661 return false;
21662 return function_decl::parameter::operator==(*p);
21663}
21664
21665/// Non-member equality operator for @ref function_decl::parameter.
21666///
21667/// @param l the left-hand side of the equality operator
21668///
21669/// @param r the right-hand side of the equality operator
21670///
21671/// @return true iff @p l and @p r equals.
21672bool
21675{
21676 if (!!l != !!r)
21677 return false;
21678 if (!l)
21679 return true;
21680 return *l == *r;
21681}
21682
21683/// Non-member inequality operator for @ref function_decl::parameter.
21684///
21685/// @param l the left-hand side of the equality operator
21686///
21687/// @param r the right-hand side of the equality operator
21688///
21689/// @return true iff @p l and @p r different.
21690bool
21693{return !operator==(l, r);}
21694
21695/// Traverse the diff sub-tree under the current instance
21696/// function_decl.
21697///
21698/// @param v the visitor to invoke on each diff node of the sub-tree.
21699///
21700/// @return true if the traversing has to keep going on, false
21701/// otherwise.
21702bool
21704{
21705 if (visiting())
21706 return true;
21707
21708 if (v.visit_begin(this))
21709 {
21710 visiting(true);
21711 if (type_base_sptr t = get_type())
21712 t->traverse(v);
21713 visiting(false);
21714 }
21715 return v.visit_end(this);
21716}
21717
21718/// Get the hash of a decl. If the hash hasn't been computed yet,
21719/// compute it ans store its value; otherwise, just return the hash.
21720///
21721/// @return the hash of the decl.
21722size_t
21724{
21725 function_decl::parameter::hash hash_fn_parm;
21726 return hash_fn_parm(this);
21727}
21728
21729/// Compute the qualified name of the parameter.
21730///
21731/// @param internal set to true if the call is intended for an
21732/// internal use (for technical use inside the library itself), false
21733/// otherwise. If you don't know what this is for, then set it to
21734/// false.
21735///
21736/// @param qn the resulting qualified name.
21737void
21739 bool /*internal*/) const
21740{qualified_name = get_name();}
21741
21742/// Compute and return a copy of the pretty representation of the
21743/// current function parameter.
21744///
21745/// @param internal set to true if the call is intended to get a
21746/// representation of the decl (or type) for the purpose of canonical
21747/// type comparison. This is mainly used in the function
21748/// type_base::get_canonical_type_for().
21749///
21750/// In other words if the argument for this parameter is true then the
21751/// call is meant for internal use (for technical use inside the
21752/// library itself), false otherwise. If you don't know what this is
21753/// for, then set it to false.
21754///
21755/// @return a copy of the textual representation of the current
21756/// function parameter.
21757string
21759 bool /*qualified_name*/) const
21760{
21761 const environment& env = get_environment();
21762
21763 string type_repr;
21764 type_base_sptr t = get_type();
21765 if (!t)
21766 type_repr = "void";
21767 else if (env.is_variadic_parameter_type(t))
21768 type_repr = "...";
21769 else
21770 type_repr = ir::get_pretty_representation(t, internal);
21771
21772 string result = type_repr;
21773 string parm_name = get_name_id();
21774
21775 if (!parm_name.empty())
21776 result += " " + parm_name;
21777
21778 return result;
21779}
21780
21781// </function_decl::parameter definitions>
21782
21783// <class_or_union definitions>
21784
21785/// A Constructor for instances of @ref class_or_union
21786///
21787/// @param env the environment we are operating from.
21788///
21789/// @param name the identifier of the class.
21790///
21791/// @param size_in_bits the size of an instance of @ref
21792/// class_or_union, expressed in bits
21793///
21794/// @param align_in_bits the alignment of an instance of @ref class_or_union,
21795/// expressed in bits.
21796///
21797/// @param locus the source location of declaration point this class.
21798///
21799/// @param vis the visibility of instances of @ref class_or_union.
21800///
21801/// @param mem_types the vector of member types of this instance of
21802/// @ref class_or_union.
21803///
21804/// @param data_members the vector of data members of this instance of
21805/// @ref class_or_union.
21806///
21807/// @param member_fns the vector of member functions of this instance
21808/// of @ref class_or_union.
21809class_or_union::class_or_union(const environment& env, const string& name,
21810 size_t size_in_bits, size_t align_in_bits,
21811 const location& locus, visibility vis,
21812 member_types& mem_types,
21814 member_functions& member_fns)
21815 : type_or_decl_base(env,
21816 ABSTRACT_TYPE_BASE
21817 | ABSTRACT_DECL_BASE
21818 | ABSTRACT_SCOPE_TYPE_DECL
21819 | ABSTRACT_SCOPE_DECL),
21820 decl_base(env, name, locus, name, vis),
21821 type_base(env, size_in_bits, align_in_bits),
21822 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
21823 priv_(new priv(data_members, member_fns))
21824{
21825 for (member_types::iterator i = mem_types.begin();
21826 i != mem_types.end();
21827 ++i)
21830
21831 for (data_members::iterator i = data_members.begin();
21832 i != data_members.end();
21833 ++i)
21834 if (!has_scope(*i))
21835 add_decl_to_scope(*i, this);
21836
21837 for (member_functions::iterator i = member_fns.begin();
21838 i != member_fns.end();
21839 ++i)
21840 if (!has_scope(static_pointer_cast<decl_base>(*i)))
21841 add_decl_to_scope(*i, this);
21842}
21843
21844/// A constructor for instances of @ref class_or_union.
21845///
21846/// @param env the environment we are operating from.
21847///
21848/// @param name the name of the class.
21849///
21850/// @param size_in_bits the size of an instance of @ref
21851/// class_or_union, expressed in bits
21852///
21853/// @param align_in_bits the alignment of an instance of @ref class_or_union,
21854/// expressed in bits.
21855///
21856/// @param locus the source location of declaration point this class.
21857///
21858/// @param vis the visibility of instances of @ref class_or_union.
21859class_or_union::class_or_union(const environment& env, const string& name,
21860 size_t size_in_bits, size_t align_in_bits,
21861 const location& locus, visibility vis)
21862 : type_or_decl_base(env,
21863 ABSTRACT_TYPE_BASE
21864 | ABSTRACT_DECL_BASE
21865 | ABSTRACT_SCOPE_TYPE_DECL
21866 | ABSTRACT_SCOPE_DECL),
21867 decl_base(env, name, locus, name, vis),
21868 type_base(env, size_in_bits, align_in_bits),
21869 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
21870 priv_(new priv)
21871{}
21872
21873/// Constructor of the @ref class_or_union type.
21874///
21875/// @param env the @ref environment we are operating from.
21876///
21877/// @param name the name of the @ref class_or_union.
21878///
21879/// @param is_declaration_only a boolean saying whether the instance
21880/// represents a declaration only, or not.
21881class_or_union::class_or_union(const environment& env, const string& name,
21882 bool is_declaration_only)
21883 : type_or_decl_base(env,
21884 ABSTRACT_TYPE_BASE
21885 | ABSTRACT_DECL_BASE
21886 | ABSTRACT_SCOPE_TYPE_DECL
21887 | ABSTRACT_SCOPE_DECL),
21888 decl_base(env, name, location(), name),
21889 type_base(env, 0, 0),
21890 scope_type_decl(env, name, 0, 0, location()),
21891 priv_(new priv)
21892{
21893 set_is_declaration_only(is_declaration_only);
21894}
21895
21896/// This implements the ir_traversable_base::traverse pure virtual
21897/// function.
21898///
21899/// @param v the visitor used on the member nodes of the translation
21900/// unit during the traversal.
21901///
21902/// @return true if the entire IR node tree got traversed, false
21903/// otherwise.
21904bool
21906{
21907 if (v.type_node_has_been_visited(this))
21908 return true;
21909
21910 if (visiting())
21911 return true;
21912
21913 if (v.visit_begin(this))
21914 {
21915 visiting(true);
21916 bool stop = false;
21917
21918 if (!stop)
21919 for (data_members::const_iterator i = get_data_members().begin();
21920 i != get_data_members().end();
21921 ++i)
21922 if (!(*i)->traverse(v))
21923 {
21924 stop = true;
21925 break;
21926 }
21927
21928 if (!stop)
21929 for (member_functions::const_iterator i= get_member_functions().begin();
21930 i != get_member_functions().end();
21931 ++i)
21932 if (!(*i)->traverse(v))
21933 {
21934 stop = true;
21935 break;
21936 }
21937
21938 if (!stop)
21939 for (member_types::const_iterator i = get_member_types().begin();
21940 i != get_member_types().end();
21941 ++i)
21942 if (!(*i)->traverse(v))
21943 {
21944 stop = true;
21945 break;
21946 }
21947
21948 if (!stop)
21949 for (member_function_templates::const_iterator i =
21951 i != get_member_function_templates().end();
21952 ++i)
21953 if (!(*i)->traverse(v))
21954 {
21955 stop = true;
21956 break;
21957 }
21958
21959 if (!stop)
21960 for (member_class_templates::const_iterator i =
21962 i != get_member_class_templates().end();
21963 ++i)
21964 if (!(*i)->traverse(v))
21965 {
21966 stop = true;
21967 break;
21968 }
21969 visiting(false);
21970 }
21971
21972 bool result = v.visit_end(this);
21974 return result;
21975}
21976
21977/// Destrcutor of the @ref class_or_union type.
21979{delete priv_;}
21980
21981/// Add a member declaration to the current instance of class_or_union.
21982/// The member declaration can be either a member type, data member,
21983/// member function, or member template.
21984///
21985/// @param d the member declaration to add.
21986decl_base_sptr
21987class_or_union::add_member_decl(const decl_base_sptr& d)
21988{return insert_member_decl(d);}
21989
21990/// Remove a given decl from the current @ref class_or_union scope.
21991///
21992/// Note that only type declarations are supported by this method for
21993/// now. Support for the other kinds of declaration is left as an
21994/// exercise for the interested reader of the code.
21995///
21996/// @param decl the declaration to remove from this @ref
21997/// class_or_union scope.
21998void
22000{
22001 type_base_sptr t = is_type(decl);
22002
22003 // For now we want to support just removing types from classes. For
22004 // other kinds of IR node, we need more work.
22005 ABG_ASSERT(t);
22006
22008}
22009
22010/// Fixup the members of the type of an anonymous data member.
22011///
22012/// Walk all data members of (the type of) a given anonymous data
22013/// member and set a particular property of the relationship between
22014/// each data member and its containing type.
22015///
22016/// That property records the fact that the data member belongs to the
22017/// anonymous data member we consider.
22018///
22019/// In the future, if there are other properties of this relationship
22020/// to set in this manner, they ought to be added here.
22021///
22022/// @param anon_dm the anonymous data member to consider.
22023void
22025{
22026 class_or_union * anon_dm_type =
22028 if (!anon_dm_type)
22029 return;
22030
22031 for (class_or_union::data_members::const_iterator it =
22032 anon_dm_type->get_non_static_data_members().begin();
22033 it != anon_dm_type->get_non_static_data_members().end();
22034 ++it)
22035 {
22036 dm_context_rel *rel =
22037 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
22038 ABG_ASSERT(rel);
22039 rel->set_anonymous_data_member(anon_dm.get());
22040 }
22041}
22042
22043/// Getter of the alignment of the @ref class_or_union type.
22044///
22045/// If this @ref class_or_union is a declaration of a definition that
22046/// is elsewhere, then the size of the definition is returned.
22047///
22048/// @return the alignment of the @ref class_or_union type.
22049size_t
22051{
22055
22057}
22058
22059/// Setter of the alignment of the class type.
22060///
22061/// If this class is a declaration of a definition that is elsewhere,
22062/// then the new alignment is set to the definition.
22063///
22064/// @param s the new alignment.
22065void
22067{
22071 else
22073}
22074
22075/// Setter of the size of the @ref class_or_union type.
22076///
22077/// If this @ref class_or_union is a declaration of a definition that
22078/// is elsewhere, then the new size is set to the definition.
22079///
22080/// @param s the new size.
22081void
22083{
22087 else
22089}
22090
22091/// Getter of the size of the @ref class_or_union type.
22092///
22093/// If this @ref class_or_union is a declaration of a definition that
22094/// is elsewhere, then the size of the definition is returned.
22095///
22096/// @return the size of the @ref class_or_union type.
22097size_t
22099{
22103
22105}
22106
22107/// Get the number of anonymous member classes contained in this
22108/// class.
22109///
22110/// @return the number of anonymous member classes contained in this
22111/// class.
22112size_t
22114{
22115 int result = 0;
22116 for (member_types::const_iterator it = get_member_types().begin();
22117 it != get_member_types().end();
22118 ++it)
22119 if (class_decl_sptr t = is_class_type(*it))
22120 if (t->get_is_anonymous())
22121 ++result;
22122
22123 return result;
22124}
22125
22126/// Get the number of anonymous member unions contained in this class.
22127///
22128/// @return the number of anonymous member unions contained in this
22129/// class.
22130size_t
22132{
22133 int result = 0;
22134 for (member_types::const_iterator it = get_member_types().begin();
22135 it != get_member_types().end();
22136 ++it)
22137 if (union_decl_sptr t = is_union_type(*it))
22138 if (t->get_is_anonymous())
22139 ++result;
22140
22141 return result;
22142}
22143
22144/// Get the number of anonymous member enums contained in this class.
22145///
22146/// @return the number of anonymous member enums contained in this
22147/// class.
22148size_t
22150{
22151 int result = 0;
22152 for (member_types::const_iterator it = get_member_types().begin();
22153 it != get_member_types().end();
22154 ++it)
22155 if (enum_type_decl_sptr t = is_enum_type(*it))
22156 if (t->get_is_anonymous())
22157 ++result;
22158
22159 return result;
22160}
22161
22162/// Add a data member to the current instance of class_or_union.
22163///
22164/// @param v a var_decl to add as a data member. A proper
22165/// class_or_union::data_member is created from @p v and added to the
22166/// class_or_union. This var_decl should not have been already added
22167/// to a scope.
22168///
22169/// @param access the access specifier for the data member.
22170///
22171/// @param is_laid_out whether the data member was laid out. That is,
22172/// if its offset has been computed. In the pattern of a class
22173/// template for instance, this would be set to false.
22174///
22175/// @param is_static whether the data memer is static.
22176///
22177/// @param offset_in_bits if @p is_laid_out is true, this is the
22178/// offset of the data member, expressed (oh, surprise) in bits.
22179void
22181 bool is_laid_out, bool is_static,
22182 size_t offset_in_bits)
22183{
22184 ABG_ASSERT(!has_scope(v));
22185
22186 priv_->data_members_.push_back(v);
22188 set_data_member_is_laid_out(v, is_laid_out);
22189 set_data_member_offset(v, offset_in_bits);
22190 set_member_access_specifier(v, access);
22191 set_member_is_static(v, is_static);
22192
22193 if (!is_static)
22194 {
22195 // If this is a non-static variable, add it to the set of
22196 // non-static variables, if it's not only in there.
22197 bool is_already_in = false;
22198 for (data_members::const_iterator i =
22199 priv_->non_static_data_members_.begin();
22200 i != priv_->non_static_data_members_.end();
22201 ++i)
22202 if (*i == v)
22203 {
22204 is_already_in = true;
22205 break;
22206 }
22207 if (!is_already_in)
22208 priv_->non_static_data_members_.push_back(v);
22209 }
22210
22211 // If v is an anonymous data member, then fixup its data members.
22212 // For now, the only thing the fixup does is to make the data
22213 // members of the anonymous data member be aware of their containing
22214 // anonymous data member. That is helpful to compute the absolute
22215 // bit offset of each of the members of the anonymous data member.
22217}
22218
22219/// Get the data members of this @ref class_or_union.
22220///
22221/// @return a vector of the data members of this @ref class_or_union.
22224{return priv_->data_members_;}
22225
22226/// Find a data member of a given name in the current @ref class_or_union.
22227///
22228/// @param name the name of the data member to find in the current
22229/// @ref class_or_union.
22230///
22231/// @return a pointer to the @ref var_decl that represents the data
22232/// member to find inside the current @ref class_or_union.
22233const var_decl_sptr
22234class_or_union::find_data_member(const string& name) const
22235{
22236 for (data_members::const_iterator i = get_data_members().begin();
22237 i != get_data_members().end();
22238 ++i)
22239 if ((*i)->get_name() == name)
22240 return *i;
22241
22242 // We haven't found a data member with the name 'name'. Let's look
22243 // closer again, this time in our anonymous data members.
22244 for (data_members::const_iterator i = get_data_members().begin();
22245 i != get_data_members().end();
22246 ++i)
22248 {
22249 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
22250 ABG_ASSERT(type);
22251 if (var_decl_sptr data_member = type->find_data_member(name))
22252 return data_member;
22253 }
22254
22255 return var_decl_sptr();
22256}
22257
22258/// Find an anonymous data member in the class.
22259///
22260/// @param v the anonymous data member to find.
22261///
22262/// @return the anonymous data member found, or nil if none was found.
22263const var_decl_sptr
22265{
22266 if (!v->get_name().empty())
22267 return var_decl_sptr();
22268
22269 for (data_members::const_iterator it = get_non_static_data_members().begin();
22270 it != get_non_static_data_members().end();
22271 ++it)
22272 {
22273 if (is_anonymous_data_member(*it))
22274 if ((*it)->get_pretty_representation(/*internal=*/false, true)
22275 == v->get_pretty_representation(/*internal=*/false, true))
22276 return *it;
22277 }
22278
22279 return var_decl_sptr();
22280}
22281
22282/// Find a given data member.
22283///
22284/// This function takes a @ref var_decl as an argument. If it has a
22285/// non-empty name, then it tries to find a data member which has the
22286/// same name as the argument.
22287///
22288/// If it has an empty name, then the @ref var_decl is considered as
22289/// an anonymous data member. In that case, this function tries to
22290/// find an anonymous data member which type equals that of the @ref
22291/// var_decl argument.
22292///
22293/// @param v this carries either the name of the data member we need
22294/// to look for, or the type of the anonymous data member we are
22295/// looking for.
22296const var_decl_sptr
22298{
22299 if (!v)
22300 return var_decl_sptr();
22301
22302 if (v->get_name().empty())
22304
22305 return find_data_member(v->get_name());
22306}
22307
22308
22309/// Get the non-static data memebers of this @ref class_or_union.
22310///
22311/// @return a vector of the non-static data members of this @ref
22312/// class_or_union.
22315{return priv_->non_static_data_members_;}
22316
22317/// Add a member function.
22318///
22319/// @param f the new member function to add.
22320///
22321/// @param a the access specifier to use for the new member function.
22322///
22323/// @param is_static whether the new member function is static.
22324///
22325/// @param is_ctor whether the new member function is a constructor.
22326///
22327/// @param is_dtor whether the new member function is a destructor.
22328///
22329/// @param is_const whether the new member function is const.
22330void
22333 bool is_static, bool is_ctor,
22334 bool is_dtor, bool is_const)
22335{
22336 ABG_ASSERT(!has_scope(f));
22337
22339
22340 set_member_function_is_ctor(f, is_ctor);
22341 set_member_function_is_dtor(f, is_dtor);
22343 set_member_is_static(f, is_static);
22344 set_member_function_is_const(f, is_const);
22345
22346 priv_->member_functions_.push_back(f);
22347
22348 // Update the map of linkage name -> member functions. It's useful,
22349 // so that class_or_union::find_member_function() can function.
22350 if (!f->get_linkage_name().empty())
22351 priv_->mem_fns_map_[f->get_linkage_name()] = f;
22352}
22353
22354/// Get the member functions of this @ref class_or_union.
22355///
22356/// @return a vector of the member functions of this @ref
22357/// class_or_union.
22360{return priv_->member_functions_;}
22361
22362/// Find a method, using its linkage name as a key.
22363///
22364/// @param linkage_name the linkage name of the method to find.
22365///
22366/// @return the method found, or nil if none was found.
22367const method_decl*
22368class_or_union::find_member_function(const string& linkage_name) const
22369{
22370 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
22371}
22372
22373/// Find a method, using its linkage name as a key.
22374///
22375/// @param linkage_name the linkage name of the method to find.
22376///
22377/// @return the method found, or nil if none was found.
22379class_or_union::find_member_function(const string& linkage_name)
22380{
22381 string_mem_fn_sptr_map_type::const_iterator i =
22382 priv_->mem_fns_map_.find(linkage_name);
22383 if (i == priv_->mem_fns_map_.end())
22384 return 0;
22385 return i->second.get();
22386}
22387
22388/// Find a method, using its linkage name as a key.
22389///
22390/// @param linkage_name the linkage name of the method to find.
22391///
22392/// @return the method found, or nil if none was found.
22393method_decl_sptr
22395{
22396 string_mem_fn_sptr_map_type::const_iterator i =
22397 priv_->mem_fns_map_.find(linkage_name);
22398 if (i == priv_->mem_fns_map_.end())
22399 return 0;
22400 return i->second;
22401}
22402
22403/// Find a method (member function) using its signature (pretty
22404/// representation) as a key.
22405///
22406/// @param s the signature of the method.
22407///
22408/// @return the method found, or nil if none was found.
22409const method_decl*
22411{
22412 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
22413}
22414
22415/// Find a method (member function) using its signature (pretty
22416/// representation) as a key.
22417///
22418/// @param s the signature of the method.
22419///
22420/// @return the method found, or nil if none was found.
22423{
22424 string_mem_fn_ptr_map_type::const_iterator i =
22425 priv_->signature_2_mem_fn_map_.find(s);
22426 if (i == priv_->signature_2_mem_fn_map_.end())
22427 return 0;
22428 return i->second;
22429}
22430
22431/// Get the member function templates of this class.
22432///
22433/// @return a vector of the member function templates of this class.
22434const member_function_templates&
22436{return priv_->member_function_templates_;}
22437
22438/// Get the member class templates of this class.
22439///
22440/// @return a vector of the member class templates of this class.
22441const member_class_templates&
22443{return priv_->member_class_templates_;}
22444
22445/// Append a member function template to the @ref class_or_union.
22446///
22447/// @param m the member function template to append.
22448void
22449class_or_union::add_member_function_template(member_function_template_sptr m)
22450{
22451 decl_base* c = m->as_function_tdecl()->get_scope();
22452 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
22453 /// error message or something like a structured error.
22454 priv_->member_function_templates_.push_back(m);
22455 if (!c)
22456 scope_decl::add_member_decl(m->as_function_tdecl());
22457}
22458
22459/// Append a member class template to the @ref class_or_union.
22460///
22461/// @param m the member function template to append.
22462void
22464{
22465 decl_base* c = m->as_class_tdecl()->get_scope();
22466 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
22467 /// error message or something like a structured error.
22468 m->set_scope(this);
22469 priv_->member_class_templates_.push_back(m);
22470 if (!c)
22471 scope_decl::add_member_decl(m->as_class_tdecl());
22472}
22473
22474///@return true iff the current instance has no member.
22475bool
22477{
22478 return (get_member_types().empty()
22479 && priv_->data_members_.empty()
22480 && priv_->member_functions_.empty()
22481 && priv_->member_function_templates_.empty()
22482 && priv_->member_class_templates_.empty());
22483}
22484
22485/// Insert a data member to this @ref class_or_union type.
22486///
22487/// @param d the data member to insert.
22488///
22489/// @return the decl @p that got inserted.
22490decl_base_sptr
22492{
22493 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
22494 {
22495 add_data_member(v, public_access,
22496 /*is_laid_out=*/false,
22497 /*is_static=*/true,
22498 /*offset_in_bits=*/0);
22499 d = v;
22500 }
22501 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
22502 add_member_function(f, public_access,
22503 /*is_static=*/false,
22504 /*is_ctor=*/false,
22505 /*is_dtor=*/false,
22506 /*is_const=*/false);
22507 else if (member_function_template_sptr f =
22508 dynamic_pointer_cast<member_function_template>(d))
22510 else if (member_class_template_sptr c =
22511 dynamic_pointer_cast<member_class_template>(d))
22513 else
22515
22516 return d;
22517}
22518
22519/// Equality operator.
22520///
22521/// @param other the other @ref class_or_union to compare against.
22522///
22523/// @return true iff @p other equals the current @ref class_or_union.
22524bool
22526{
22527 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
22528 if (!op)
22529 return false;
22530
22531 // If this is a decl-only type (and thus with no canonical type),
22532 // use the canonical type of the definition, if any.
22533 const class_or_union *l = 0;
22535 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
22536 if (l == 0)
22537 l = this;
22538
22539 // Likewise for the other class.
22540 const class_or_union *r = 0;
22541 if (op->get_is_declaration_only())
22542 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
22543 if (r == 0)
22544 r = op;
22545
22546 return try_canonical_compare(l, r);
22547}
22548
22549/// Equality operator.
22550///
22551/// @param other the other @ref class_or_union to compare against.
22552///
22553/// @return true iff @p other equals the current @ref class_or_union.
22554bool
22556{
22557 const decl_base* o = dynamic_cast<const decl_base*>(&other);
22558 if (!o)
22559 return false;
22560 return *this == *o;
22561}
22562
22563/// Equality operator.
22564///
22565/// @param other the other @ref class_or_union to compare against.
22566///
22567/// @return true iff @p other equals the current @ref class_or_union.
22568bool
22570{
22571 const decl_base& o = other;
22573}
22574
22575/// Compares two instances of @ref class_or_union.
22576///
22577/// If the two intances are different, set a bitfield to give some
22578/// insight about the kind of differences there are.
22579///
22580/// @param l the first artifact of the comparison.
22581///
22582/// @param r the second artifact of the comparison.
22583///
22584/// @param k a pointer to a bitfield that gives information about the
22585/// kind of changes there are between @p l and @p r. This one is set
22586/// iff it's non-null and if the function returns false.
22587///
22588/// Please note that setting k to a non-null value does have a
22589/// negative performance impact because even if @p l and @p r are not
22590/// equal, the function keeps up the comparison in order to determine
22591/// the different kinds of ways in which they are different.
22592///
22593/// @return true if @p l equals @p r, false otherwise.
22594bool
22596{
22597 // if one of the classes is declaration-only, look through it to
22598 // get its definition.
22599 bool l_is_decl_only = l.get_is_declaration_only();
22600 bool r_is_decl_only = r.get_is_declaration_only();
22601 if (l_is_decl_only || r_is_decl_only)
22602 {
22603 const class_or_union* def1 = l_is_decl_only
22605 : &l;
22606
22607 const class_or_union* def2 = r_is_decl_only
22609 : &r;
22610
22611 if (!def1 || !def2)
22612 {
22613 if (!l.get_is_anonymous()
22614 && !r.get_is_anonymous()
22615 && l_is_decl_only && r_is_decl_only
22617 // The two decl-only classes differ from their size. A
22618 // true decl-only class should not have a size property to
22619 // begin with. This comes from a DWARF oddity and can
22620 // results in a false positive, so let's not consider that
22621 // change.
22622 return true;
22623
22625 || ((odr_is_relevant(l) && !def1)
22626 || (odr_is_relevant(r) && !def2)))
22629 {
22630 const interned_string& q1 = l.get_scoped_name();
22631 const interned_string& q2 = r.get_scoped_name();
22632 if (q1 == q2)
22633 // Not using RETURN(true) here, because that causes
22634 // performance issues. We don't need to do
22635 // l.priv_->unmark_as_being_compared({l,r}) here because
22636 // we haven't marked l or r as being compared yet, and
22637 // doing so has a peformance cost that shows up on
22638 // performance profiles for *big* libraries.
22639 return true;
22640 else
22641 {
22642 if (k)
22644 // Not using RETURN(true) here, because that causes
22645 // performance issues. We don't need to do
22646 // l.priv_->unmark_as_being_compared({l,r}) here because
22647 // we haven't marked l or r as being compared yet, and
22648 // doing so has a peformance cost that shows up on
22649 // performance profiles for *big* libraries.
22651 }
22652 }
22653 else // A decl-only class is considered different from a
22654 // class definition of the same name.
22655 {
22656 if (!!def1 != !!def2)
22657 {
22658 if (k)
22661 }
22662
22663 // both definitions are empty
22664 if (!(l.decl_base::operator==(r)
22665 && l.type_base::operator==(r)))
22666 {
22667 if (k)
22670 }
22671
22672 return true;
22673 }
22674 }
22675
22676 bool val = *def1 == *def2;
22677 if (!val)
22678 if (k)
22680 ABG_RETURN(val);
22681 }
22682
22683 // No need to go further if the classes have different names or
22684 // different size / alignment.
22685 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
22686 {
22687 if (k)
22690 }
22691
22692 if (types_defined_same_linux_kernel_corpus_public(l, r))
22693 return true;
22694
22695 //TODO: Maybe remove this (cycle detection and canonical type
22696 //propagation handling) from here and have it only in the equal
22697 //overload for class_decl and union_decl because this one ( the
22698 //equal overload for class_or_union) is just a sub-routine of these
22699 //two above.
22700#define RETURN(value) \
22701 return return_comparison_result(l, r, value, \
22702 /*propagate_canonical_type=*/false);
22703
22705
22707
22708 bool result = true;
22709
22710 //compare data_members
22711 {
22712 if (l.get_non_static_data_members().size()
22713 != r.get_non_static_data_members().size())
22714 {
22715 result = false;
22716 if (k)
22718 else
22719 RETURN(result);
22720 }
22721
22722 for (class_or_union::data_members::const_iterator
22723 d0 = l.get_non_static_data_members().begin(),
22724 d1 = r.get_non_static_data_members().begin();
22725 (d0 != l.get_non_static_data_members().end()
22726 && d1 != r.get_non_static_data_members().end());
22727 ++d0, ++d1)
22728 if (**d0 != **d1)
22729 {
22730 result = false;
22731 if (k)
22732 {
22733 // Report any representation change as being local.
22734 if (!types_have_similar_structure((*d0)->get_type(),
22735 (*d1)->get_type())
22736 || (*d0)->get_type() == (*d1)->get_type())
22738 else
22739 *k |= SUBTYPE_CHANGE_KIND;
22740 }
22741 else
22742 RETURN(result);
22743 }
22744 }
22745
22746 // Do not compare member functions. DWARF does not necessarily
22747 // all the member functions, be they virtual or not, in all
22748 // translation units. So we cannot have a clear view of them, per
22749 // class
22750
22751 // compare member function templates
22752 {
22753 if (l.get_member_function_templates().size()
22754 != r.get_member_function_templates().size())
22755 {
22756 result = false;
22757 if (k)
22759 else
22760 RETURN(result);
22761 }
22762
22763 for (member_function_templates::const_iterator
22764 fn_tmpl_it0 = l.get_member_function_templates().begin(),
22765 fn_tmpl_it1 = r.get_member_function_templates().begin();
22766 fn_tmpl_it0 != l.get_member_function_templates().end()
22767 && fn_tmpl_it1 != r.get_member_function_templates().end();
22768 ++fn_tmpl_it0, ++fn_tmpl_it1)
22769 if (**fn_tmpl_it0 != **fn_tmpl_it1)
22770 {
22771 result = false;
22772 if (k)
22773 {
22775 break;
22776 }
22777 else
22778 RETURN(result);
22779 }
22780 }
22781
22782 // compare member class templates
22783 {
22784 if (l.get_member_class_templates().size()
22785 != r.get_member_class_templates().size())
22786 {
22787 result = false;
22788 if (k)
22790 else
22791 RETURN(result);
22792 }
22793
22794 for (member_class_templates::const_iterator
22795 cl_tmpl_it0 = l.get_member_class_templates().begin(),
22796 cl_tmpl_it1 = r.get_member_class_templates().begin();
22797 cl_tmpl_it0 != l.get_member_class_templates().end()
22798 && cl_tmpl_it1 != r.get_member_class_templates().end();
22799 ++cl_tmpl_it0, ++cl_tmpl_it1)
22800 if (**cl_tmpl_it0 != **cl_tmpl_it1)
22801 {
22802 result = false;
22803 if (k)
22804 {
22806 break;
22807 }
22808 else
22809 RETURN(result);
22810 }
22811 }
22812
22813 RETURN(result);
22814#undef RETURN
22815}
22816
22817
22818/// Copy a method of a @ref class_or_union into a new @ref
22819/// class_or_union.
22820///
22821/// @param t the @ref class_or_union into which the method is to be copied.
22822///
22823/// @param method the method to copy into @p t.
22824///
22825/// @return the resulting newly copied method.
22826method_decl_sptr
22827copy_member_function(const class_or_union_sptr& t,
22828 const method_decl_sptr& method)
22829{return copy_member_function(t, method.get());}
22830
22831
22832/// Copy a method of a @ref class_or_union into a new @ref
22833/// class_or_union.
22834///
22835/// @param t the @ref class_or_union into which the method is to be copied.
22836///
22837/// @param method the method to copy into @p t.
22838///
22839/// @return the resulting newly copied method.
22840method_decl_sptr
22841copy_member_function(const class_or_union_sptr& t, const method_decl* method)
22842{
22843 ABG_ASSERT(t);
22844 ABG_ASSERT(method);
22845
22846 method_type_sptr old_type = method->get_type();
22847 ABG_ASSERT(old_type);
22848 method_type_sptr new_type(new method_type(old_type->get_return_type(),
22849 t,
22850 old_type->get_parameters(),
22851 old_type->get_is_const(),
22852 old_type->get_size_in_bits(),
22853 old_type->get_alignment_in_bits()));
22854 keep_type_alive(new_type);
22855
22856 method_decl_sptr
22857 new_method(new method_decl(method->get_name(),
22858 new_type,
22859 method->is_declared_inline(),
22860 method->get_location(),
22861 method->get_linkage_name(),
22862 method->get_visibility(),
22863 method->get_binding()));
22864 new_method->set_symbol(method->get_symbol());
22865
22866 if (class_decl_sptr class_type = is_class_type(t))
22867 class_type->add_member_function(new_method,
22871 get_member_is_static(*method),
22875 else
22876 t->add_member_function(new_method,
22878 get_member_is_static(*method),
22882 return new_method;
22883}
22884
22885// </class_or_union definitions>
22886
22887/// @defgroup OnTheFlyCanonicalization On-the-fly Canonicalization
22888/// @{
22889///
22890/// This optimization is also known as "canonical type propagation".
22891///
22892/// During the canonicalization of a type T (which doesn't yet have a
22893/// canonical type), T is compared structurally (member-wise) against
22894/// a type C which already has a canonical type. The comparison
22895/// expression is C == T.
22896///
22897/// During that structural comparison, if a subtype of C (which also
22898/// already has a canonical type) is structurally compared to a
22899/// subtype of T (which doesn't yet have a canonical type) and if they
22900/// are equal, then we can deduce that the canonical type of the
22901/// subtype of C is the canonical type of the subtype of C.
22902///
22903/// Thus, we can canonicalize the sub-type of the T, during the
22904/// canonicalization of T itself. That canonicalization of the
22905/// sub-type of T is what we call the "on-the-fly canonicalization".
22906/// It's on the fly because it happens during a comparison -- which
22907/// itself happens during the canonicalization of T.
22908///
22909/// For now this on-the-fly canonicalization only happens when
22910/// comparing @ref class_decl and @ref function_type.
22911///
22912/// Note however that there is a case when a type is *NOT* eligible to
22913/// this canonical type propagation optimization.
22914///
22915/// The reason why a type is deemed NON-eligible to the canonical type
22916/// propagation optimization is that it "depends" on recursively
22917/// present type. Let me explain.
22918///
22919/// Suppose we have a type T that has sub-types named ST0 and ST1.
22920/// Suppose ST1 itself has a sub-type that is T itself. In this case,
22921/// we say that T is a recursive type, because it has T (itself) as
22922/// one of its sub-types:
22923///
22924/// <PRE>
22925/// T
22926/// +-- ST0
22927/// |
22928/// +-- ST1
22929/// | +
22930/// | |
22931/// | +-- T
22932/// |
22933/// +-- ST2
22934/// </PRE>
22935///
22936/// ST1 is said to "depend" on T because it has T as a sub-type. But
22937/// because T is recursive, then ST1 is said to depend on a recursive
22938/// type. Notice however that ST0 does not depend on any recursive
22939/// type.
22940///
22941/// Now suppose we are comparing T to a type T' that has the same
22942/// structure with sub-types ST0', ST1' and ST2'. During the
22943/// comparison of ST1 against ST1', their sub-type T is compared
22944/// against T'. Because T (resp. T') is a recursive type that is
22945/// already being compared, the comparison of T against T' (as a
22946/// subtypes of ST1 and ST1') returns true, meaning they are
22947/// considered equal. This is done so that we don't enter an infinite
22948/// recursion.
22949///
22950/// That means ST1 is also deemed equal to ST1'. If we are in the
22951/// course of the canonicalization of T' and thus if T (as well as as
22952/// all of its sub-types) is already canonicalized, then the canonical
22953/// type propagation optimization will make us propagate the canonical
22954/// type of ST1 onto ST1'. So the canonical type of ST1' will be
22955/// equal to the canonical type of ST1 as a result of that
22956/// optmization.
22957///
22958/// But then, later down the road, when ST2 is compared against ST2',
22959/// let's suppose that we find out that they are different. Meaning
22960/// that ST2 != ST2'. This means that T != T', i.e, the
22961/// canonicalization of T' failed for now. But most importantly, it
22962/// means that the propagation of the canonical type of ST1 to ST1'
22963/// must now be invalidated. Meaning, ST1' must now be considered as
22964/// not having any canonical type.
22965///
22966/// In other words, during type canonicalization, if ST1' depends on a
22967/// recursive type T', its propagated canonical type must be
22968/// invalidated (set to nullptr) if T' appears to be different from T,
22969/// a.k.a, the canonicalization of T' temporarily failed.
22970///
22971/// This means that any sub-type that depends on recursive types and
22972/// that has been the target of the canonical type propagation
22973/// optimization must be tracked. If the dependant recursive type
22974/// fails its canonicalization, then the sub-type being compared must
22975/// have its propagated canonical type cleared. In other words, its
22976/// propagated canonical type must be cancelled.
22977///
22978/// @}
22979
22980
22981/// If on-the-fly canonicalization is turned on, then this function
22982/// sets the canonical type of its second parameter to the canonical
22983/// type of the first parameter.
22984///
22985/// @param lhs_type the type which canonical type to propagate.
22986///
22987/// @param rhs_type the type which canonical type to set.
22988static bool
22989maybe_propagate_canonical_type(const type_base& lhs_type,
22990 const type_base& rhs_type)
22991{
22992 const environment& env = lhs_type.get_environment();
22993#if WITH_DEBUG_TYPE_CANONICALIZATION
22994 if (!env.priv_->use_canonical_type_comparison_)
22995 return false;
22996#endif
22997
22999 if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
23000 if (!rhs_type.get_canonical_type())
23001 if (env.priv_->propagate_ct(lhs_type, rhs_type))
23002 return true;
23003 return false;
23004}
23005
23006// <class_decl definitions>
23007
23008static void
23009sort_virtual_member_functions(class_decl::member_functions& mem_fns);
23010
23011/// The private data for the class_decl type.
23012struct class_decl::priv
23013{
23014 base_specs bases_;
23015 unordered_map<string, base_spec_sptr> bases_map_;
23016 member_functions virtual_mem_fns_;
23017 virtual_mem_fn_map_type virtual_mem_fns_map_;
23018 bool is_struct_;
23019
23020 priv()
23021 : is_struct_(false)
23022 {}
23023
23024 priv(bool is_struct, class_decl::base_specs& bases)
23025 : bases_(bases),
23026 is_struct_(is_struct)
23027 {
23028 }
23029
23030 priv(bool is_struct)
23031 : is_struct_(is_struct)
23032 {}
23033};// end struct class_decl::priv
23034
23035/// A Constructor for instances of \ref class_decl
23036///
23037/// @param env the environment we are operating from.
23038///
23039/// @param name the identifier of the class.
23040///
23041/// @param size_in_bits the size of an instance of class_decl, expressed
23042/// in bits
23043///
23044/// @param align_in_bits the alignment of an instance of class_decl,
23045/// expressed in bits.
23046///
23047/// @param locus the source location of declaration point this class.
23048///
23049/// @param vis the visibility of instances of class_decl.
23050///
23051/// @param bases the vector of base classes for this instance of class_decl.
23052///
23053/// @param mbrs the vector of member types of this instance of
23054/// class_decl.
23055///
23056/// @param data_mbrs the vector of data members of this instance of
23057/// class_decl.
23058///
23059/// @param mbr_fns the vector of member functions of this instance of
23060/// class_decl.
23061class_decl::class_decl(const environment& env, const string& name,
23062 size_t size_in_bits, size_t align_in_bits,
23063 bool is_struct, const location& locus,
23064 visibility vis, base_specs& bases,
23065 member_types& mbr_types,
23066 data_members& data_mbrs,
23067 member_functions& mbr_fns)
23068 : type_or_decl_base(env,
23069 CLASS_TYPE
23070 | ABSTRACT_TYPE_BASE
23071 | ABSTRACT_DECL_BASE
23072 | ABSTRACT_SCOPE_TYPE_DECL
23073 | ABSTRACT_SCOPE_DECL),
23074 decl_base(env, name, locus, name, vis),
23075 type_base(env, size_in_bits, align_in_bits),
23076 class_or_union(env, name, size_in_bits, align_in_bits,
23077 locus, vis, mbr_types, data_mbrs, mbr_fns),
23078 priv_(new priv(is_struct, bases))
23079{
23081}
23082
23083/// A Constructor for instances of @ref class_decl
23084///
23085/// @param env the environment we are operating from.
23086///
23087/// @param name the identifier of the class.
23088///
23089/// @param size_in_bits the size of an instance of class_decl, expressed
23090/// in bits
23091///
23092/// @param align_in_bits the alignment of an instance of class_decl,
23093/// expressed in bits.
23094///
23095/// @param locus the source location of declaration point this class.
23096///
23097/// @param vis the visibility of instances of class_decl.
23098///
23099/// @param bases the vector of base classes for this instance of class_decl.
23100///
23101/// @param mbrs the vector of member types of this instance of
23102/// class_decl.
23103///
23104/// @param data_mbrs the vector of data members of this instance of
23105/// class_decl.
23106///
23107/// @param mbr_fns the vector of member functions of this instance of
23108/// class_decl.
23109///
23110/// @param is_anonymous whether the newly created instance is
23111/// anonymous.
23112class_decl::class_decl(const environment& env, const string& name,
23113 size_t size_in_bits, size_t align_in_bits,
23114 bool is_struct, const location& locus,
23115 visibility vis, base_specs& bases,
23116 member_types& mbr_types, data_members& data_mbrs,
23117 member_functions& mbr_fns, bool is_anonymous)
23118 : type_or_decl_base(env,
23119 CLASS_TYPE
23120 | ABSTRACT_TYPE_BASE
23121 | ABSTRACT_DECL_BASE
23122 | ABSTRACT_SCOPE_TYPE_DECL
23123 | ABSTRACT_SCOPE_DECL),
23124 decl_base(env, name, locus,
23125 // If the class is anonymous then by default it won't
23126 // have a linkage name. Also, the anonymous class does
23127 // have an internal-only unique name that is generally
23128 // not taken into account when comparing classes; such a
23129 // unique internal-only name, when used as a linkage
23130 // name might introduce spurious comparison false
23131 // negatives.
23132 /*linkage_name=*/is_anonymous ? string() : name,
23133 vis),
23134 type_base(env, size_in_bits, align_in_bits),
23135 class_or_union(env, name, size_in_bits, align_in_bits,
23136 locus, vis, mbr_types, data_mbrs, mbr_fns),
23137 priv_(new priv(is_struct, bases))
23138{
23140 set_is_anonymous(is_anonymous);
23141}
23142
23143/// A constructor for instances of class_decl.
23144///
23145/// @param env the environment we are operating from.
23146///
23147/// @param name the name of the class.
23148///
23149/// @param size_in_bits the size of an instance of class_decl, expressed
23150/// in bits
23151///
23152/// @param align_in_bits the alignment of an instance of class_decl,
23153/// expressed in bits.
23154///
23155/// @param locus the source location of declaration point this class.
23156///
23157/// @param vis the visibility of instances of class_decl.
23158class_decl::class_decl(const environment& env, const string& name,
23159 size_t size_in_bits, size_t align_in_bits,
23160 bool is_struct, const location& locus,
23161 visibility vis)
23162 : type_or_decl_base(env,
23163 CLASS_TYPE
23164 | ABSTRACT_TYPE_BASE
23165 | ABSTRACT_DECL_BASE
23166 | ABSTRACT_SCOPE_TYPE_DECL
23167 | ABSTRACT_SCOPE_DECL),
23168 decl_base(env, name, locus, name, vis),
23169 type_base(env, size_in_bits, align_in_bits),
23170 class_or_union(env, name, size_in_bits, align_in_bits,
23171 locus, vis),
23172 priv_(new priv(is_struct))
23173{
23175}
23176
23177/// A constructor for instances of @ref class_decl.
23178///
23179/// @param env the environment we are operating from.
23180///
23181/// @param name the name of the class.
23182///
23183/// @param size_in_bits the size of an instance of class_decl, expressed
23184/// in bits
23185///
23186/// @param align_in_bits the alignment of an instance of class_decl,
23187/// expressed in bits.
23188///
23189/// @param locus the source location of declaration point this class.
23190///
23191/// @param vis the visibility of instances of class_decl.
23192///
23193/// @param is_anonymous whether the newly created instance is
23194/// anonymous.
23195class_decl:: class_decl(const environment& env, const string& name,
23196 size_t size_in_bits, size_t align_in_bits,
23197 bool is_struct, const location& locus,
23198 visibility vis, bool is_anonymous)
23199 : type_or_decl_base(env,
23200 CLASS_TYPE
23201 | ABSTRACT_TYPE_BASE
23202 | ABSTRACT_DECL_BASE
23203 | ABSTRACT_SCOPE_TYPE_DECL
23204 | ABSTRACT_SCOPE_DECL),
23205 decl_base(env, name, locus,
23206 // If the class is anonymous then by default it won't
23207 // have a linkage name. Also, the anonymous class does
23208 // have an internal-only unique name that is generally
23209 // not taken into account when comparing classes; such a
23210 // unique internal-only name, when used as a linkage
23211 // name might introduce spurious comparison false
23212 // negatives.
23213 /*linkage_name=*/ is_anonymous ? string() : name,
23214 vis),
23215 type_base(env, size_in_bits, align_in_bits),
23216 class_or_union(env, name, size_in_bits, align_in_bits,
23217 locus, vis),
23218 priv_(new priv(is_struct))
23219{
23221 set_is_anonymous(is_anonymous);
23222}
23223
23224/// A constuctor for instances of class_decl that represent a
23225/// declaration without definition.
23226///
23227/// @param env the environment we are operating from.
23228///
23229/// @param name the name of the class.
23230///
23231/// @param is_declaration_only a boolean saying whether the instance
23232/// represents a declaration only, or not.
23233class_decl::class_decl(const environment& env, const string& name,
23234 bool is_struct, bool is_declaration_only)
23235 : type_or_decl_base(env,
23236 CLASS_TYPE
23237 | ABSTRACT_TYPE_BASE
23238 | ABSTRACT_DECL_BASE
23239 | ABSTRACT_SCOPE_TYPE_DECL
23240 | ABSTRACT_SCOPE_DECL),
23241 decl_base(env, name, location(), name),
23242 type_base(env, 0, 0),
23243 class_or_union(env, name, is_declaration_only),
23244 priv_(new priv(is_struct))
23245{
23247}
23248
23249/// This method is invoked automatically right after the current
23250/// instance of @ref class_decl has been canonicalized.
23251///
23252/// Currently, the only thing it does is to sort the virtual member
23253/// functions vector.
23254void
23256{
23258
23259 for (class_decl::virtual_mem_fn_map_type::iterator i =
23260 priv_->virtual_mem_fns_map_.begin();
23261 i != priv_->virtual_mem_fns_map_.end();
23262 ++i)
23263 sort_virtual_member_functions(i->second);
23264}
23265
23266/// Set the "is-struct" flag of the class.
23267///
23268/// @param f the new value of the flag.
23269void
23271{priv_->is_struct_ = f;}
23272
23273/// Test if the class is a struct.
23274///
23275/// @return true iff the class is a struct.
23276bool
23278{return priv_->is_struct_;}
23279
23280/// Add a base specifier to this class.
23281///
23282/// @param b the new base specifier.
23283void
23285{
23286 priv_->bases_.push_back(b);
23287 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
23288}
23289
23290/// Get the base specifiers for this class.
23291///
23292/// @return a vector of the base specifiers.
23295{return priv_->bases_;}
23296
23297/// Find a base class of a given qualified name for the current class.
23298///
23299/// @param qualified_name the qualified name of the base class to look for.
23300///
23301/// @return a pointer to the @ref class_decl that represents the base
23302/// class of name @p qualified_name, if found.
23304class_decl::find_base_class(const string& qualified_name) const
23305{
23306 unordered_map<string, base_spec_sptr>::iterator i =
23307 priv_->bases_map_.find(qualified_name);
23308
23309 if (i != priv_->bases_map_.end())
23310 return i->second->get_base_class();
23311
23312 return class_decl_sptr();
23313}
23314
23315/// Get the virtual member functions of this class.
23316///
23317/// @param return a vector of the virtual member functions of this
23318/// class.
23321{return priv_->virtual_mem_fns_;}
23322
23323/// Get the map that associates a virtual table offset to the virtual
23324/// member functions with that virtual table offset.
23325///
23326/// Usually, there should be a 1:1 mapping between a given vtable
23327/// offset and virtual member functions of that vtable offset. But
23328/// because of some implementation details, there can be several C++
23329/// destructor functions that are *generated* by compilers, for a
23330/// given destructor that is defined in the source code. If the
23331/// destructor is virtual then those generated functions have some
23332/// DWARF attributes in common with the constructor that the user
23333/// actually defined in its source code. Among those attributes are
23334/// the vtable offset of the destructor.
23335///
23336/// @return the map that associates a virtual table offset to the
23337/// virtual member functions with that virtual table offset.
23340{return priv_->virtual_mem_fns_map_;}
23341
23342/// Sort the virtual member functions by their virtual index.
23343void
23345{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
23346
23347/// Getter of the pretty representation of the current instance of
23348/// @ref class_decl.
23349///
23350/// @param internal set to true if the call is intended to get a
23351/// representation of the decl (or type) for the purpose of canonical
23352/// type comparison. This is mainly used in the function
23353/// type_base::get_canonical_type_for().
23354///
23355/// In other words if the argument for this parameter is true then the
23356/// call is meant for internal use (for technical use inside the
23357/// library itself), false otherwise. If you don't know what this is
23358/// for, then set it to false.
23359///
23360/// @param qualified_name if true, names emitted in the pretty
23361/// representation are fully qualified.
23362///
23363/// @return the pretty representaion for a class_decl.
23364string
23366 bool qualified_name) const
23367{
23368 string cl = "class ";
23369 if (!internal && is_struct())
23370 cl = "struct ";
23371
23372 // When computing the pretty representation for internal purposes,
23373 // if an anonymous class is named by a typedef, then consider that
23374 // it has a name, which is the typedef name.
23375 if (get_is_anonymous())
23376 {
23377 if (internal && !get_name().empty())
23378 return cl + get_type_name(this, qualified_name, /*internal=*/true);
23380 /*one_line=*/true,
23381 internal);
23382
23383 }
23384
23385 string result = cl;
23386 if (qualified_name)
23387 result += get_qualified_name(internal);
23388 else
23389 result += get_name();
23390
23391 return result;
23392}
23393
23394decl_base_sptr
23395class_decl::insert_member_decl(decl_base_sptr d)
23396{
23397 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
23398 add_member_function(f, public_access,
23399 /*is_virtual=*/false,
23400 /*vtable_offset=*/0,
23401 /*is_static=*/false,
23402 /*is_ctor=*/false,
23403 /*is_dtor=*/false,
23404 /*is_const=*/false);
23405 else
23407
23408 return d;
23409}
23410
23411/// The private data structure of class_decl::base_spec.
23412struct class_decl::base_spec::priv
23413{
23414 class_decl_wptr base_class_;
23415 long offset_in_bits_;
23416 bool is_virtual_;
23417
23418 priv(const class_decl_sptr& cl,
23419 long offset_in_bits,
23420 bool is_virtual)
23421 : base_class_(cl),
23422 offset_in_bits_(offset_in_bits),
23423 is_virtual_(is_virtual)
23424 {}
23425};
23426
23427/// Constructor for base_spec instances.
23428///
23429/// @param base the base class to consider
23430///
23431/// @param a the access specifier of the base class.
23432///
23433/// @param offset_in_bits if positive or null, represents the offset
23434/// of the base in the layout of its containing type.. If negative,
23435/// means that the current base is not laid out in its containing type.
23436///
23437/// @param is_virtual if true, means that the current base class is
23438/// virtual in it's containing type.
23439class_decl::base_spec::base_spec(const class_decl_sptr& base,
23441 long offset_in_bits,
23442 bool is_virtual)
23443 : type_or_decl_base(base->get_environment(),
23444 ABSTRACT_DECL_BASE),
23445 decl_base(base->get_environment(), base->get_name(), base->get_location(),
23446 base->get_linkage_name(), base->get_visibility()),
23447 member_base(a),
23448 priv_(new priv(base, offset_in_bits, is_virtual))
23449{
23451 set_qualified_name(base->get_qualified_name());
23452}
23453
23454/// Get the base class referred to by the current base class
23455/// specifier.
23456///
23457/// @return the base class.
23460{return priv_->base_class_.lock();}
23461
23462/// Getter of the "is-virtual" proprerty of the base class specifier.
23463///
23464/// @return true iff this specifies a virtual base class.
23465bool
23467{return priv_->is_virtual_;}
23468
23469/// Getter of the offset of the base.
23470///
23471/// @return the offset of the base.
23472long
23474{return priv_->offset_in_bits_;}
23475
23476/// Calculate the hash value for a class_decl::base_spec.
23477///
23478/// @return the hash value.
23479size_t
23481{
23483 return h(*this);
23484}
23485
23486/// Traverses an instance of @ref class_decl::base_spec, visiting all
23487/// the sub-types and decls that it might contain.
23488///
23489/// @param v the visitor that is used to visit every IR sub-node of
23490/// the current node.
23491///
23492/// @return true if either
23493/// - all the children nodes of the current IR node were traversed
23494/// and the calling code should keep going with the traversing.
23495/// - or the current IR node is already being traversed.
23496/// Otherwise, returning false means that the calling code should not
23497/// keep traversing the tree.
23498bool
23500{
23501 if (visiting())
23502 return true;
23503
23504 if (v.visit_begin(this))
23505 {
23506 visiting(true);
23507 get_base_class()->traverse(v);
23508 visiting(false);
23509 }
23510
23511 return v.visit_end(this);
23512}
23513
23514/// Constructor for base_spec instances.
23515///
23516/// Note that this constructor is for clients that don't support RTTI
23517/// and that have a base class of type_base, but of dynamic type
23518/// class_decl.
23519///
23520/// @param base the base class to consider. Must be a pointer to an
23521/// instance of class_decl
23522///
23523/// @param a the access specifier of the base class.
23524///
23525/// @param offset_in_bits if positive or null, represents the offset
23526/// of the base in the layout of its containing type.. If negative,
23527/// means that the current base is not laid out in its containing type.
23528///
23529/// @param is_virtual if true, means that the current base class is
23530/// virtual in it's containing type.
23531class_decl::base_spec::base_spec(const type_base_sptr& base,
23533 long offset_in_bits,
23534 bool is_virtual)
23536 ABSTRACT_DECL_BASE),
23541 member_base(a),
23542 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
23543 offset_in_bits,
23544 is_virtual))
23545{
23547}
23548
23549class_decl::base_spec::~base_spec() = default;
23550
23551/// Compares two instances of @ref class_decl::base_spec.
23552///
23553/// If the two intances are different, set a bitfield to give some
23554/// insight about the kind of differences there are.
23555///
23556/// @param l the first artifact of the comparison.
23557///
23558/// @param r the second artifact of the comparison.
23559///
23560/// @param k a pointer to a bitfield that gives information about the
23561/// kind of changes there are between @p l and @p r. This one is set
23562/// iff @p k is non-null and the function returns false.
23563///
23564/// Please note that setting k to a non-null value does have a
23565/// negative performance impact because even if @p l and @p r are not
23566/// equal, the function keeps up the comparison in order to determine
23567/// the different kinds of ways in which they are different.
23568///
23569/// @return true if @p l equals @p r, false otherwise.
23570bool
23572 const class_decl::base_spec& r,
23573 change_kind* k)
23574{
23575 if (!l.member_base::operator==(r))
23576 {
23577 if (k)
23580 }
23581
23583}
23584
23585/// Comparison operator for @ref class_decl::base_spec.
23586///
23587/// @param other the instance of @ref class_decl::base_spec to compare
23588/// against.
23589///
23590/// @return true if the current instance of @ref class_decl::base_spec
23591/// equals @p other.
23592bool
23594{
23595 const class_decl::base_spec* o =
23596 dynamic_cast<const class_decl::base_spec*>(&other);
23597
23598 if (!o)
23599 return false;
23600
23601 return equals(*this, *o, 0);
23602}
23603
23604/// Comparison operator for @ref class_decl::base_spec.
23605///
23606/// @param other the instance of @ref class_decl::base_spec to compare
23607/// against.
23608///
23609/// @return true if the current instance of @ref class_decl::base_spec
23610/// equals @p other.
23611bool
23613{
23614 const class_decl::base_spec* o =
23615 dynamic_cast<const class_decl::base_spec*>(&other);
23616 if (!o)
23617 return false;
23618
23619 return operator==(static_cast<const decl_base&>(*o));
23620}
23621
23622mem_fn_context_rel::~mem_fn_context_rel()
23623{
23624}
23625
23626/// A constructor for instances of method_decl.
23627///
23628/// @param name the name of the method.
23629///
23630/// @param type the type of the method.
23631///
23632/// @param declared_inline whether the method was
23633/// declared inline or not.
23634///
23635/// @param locus the source location of the method.
23636///
23637/// @param linkage_name the mangled name of the method.
23638///
23639/// @param vis the visibility of the method.
23640///
23641/// @param bind the binding of the method.
23642method_decl::method_decl(const string& name,
23643 method_type_sptr type,
23644 bool declared_inline,
23645 const location& locus,
23646 const string& linkage_name,
23647 visibility vis,
23648 binding bind)
23650 METHOD_DECL
23651 | ABSTRACT_DECL_BASE
23652 |FUNCTION_DECL),
23653 decl_base(type->get_environment(), name, locus, linkage_name, vis),
23654 function_decl(name, static_pointer_cast<function_type>(type),
23655 declared_inline, locus, linkage_name, vis, bind)
23656{
23658 set_context_rel(new mem_fn_context_rel(0));
23659 set_member_function_is_const(*this, type->get_is_const());
23660}
23661
23662/// A constructor for instances of method_decl.
23663///
23664/// @param name the name of the method.
23665///
23666/// @param type the type of the method. Must be an instance of
23667/// method_type.
23668///
23669/// @param declared_inline whether the method was
23670/// declared inline or not.
23671///
23672/// @param locus the source location of the method.
23673///
23674/// @param linkage_name the mangled name of the method.
23675///
23676/// @param vis the visibility of the method.
23677///
23678/// @param bind the binding of the method.
23679method_decl::method_decl(const string& name,
23680 function_type_sptr type,
23681 bool declared_inline,
23682 const location& locus,
23683 const string& linkage_name,
23684 visibility vis,
23685 binding bind)
23686 : type_or_decl_base(type->get_environment(),
23687 METHOD_DECL
23688 | ABSTRACT_DECL_BASE
23689 | FUNCTION_DECL),
23690 decl_base(type->get_environment(), name, locus, linkage_name, vis),
23691 function_decl(name, static_pointer_cast<function_type>
23692 (dynamic_pointer_cast<method_type>(type)),
23693 declared_inline, locus, linkage_name, vis, bind)
23694{
23696 set_context_rel(new mem_fn_context_rel(0));
23697}
23698
23699/// A constructor for instances of method_decl.
23700///
23701/// @param name the name of the method.
23702///
23703/// @param type the type of the method. Must be an instance of
23704/// method_type.
23705///
23706/// @param declared_inline whether the method was
23707/// declared inline or not.
23708///
23709/// @param locus the source location of the method.
23710///
23711/// @param linkage_name the mangled name of the method.
23712///
23713/// @param vis the visibility of the method.
23714///
23715/// @param bind the binding of the method.
23716method_decl::method_decl(const string& name,
23717 type_base_sptr type,
23718 bool declared_inline,
23719 const location& locus,
23720 const string& linkage_name,
23721 visibility vis,
23722 binding bind)
23723 : type_or_decl_base(type->get_environment(),
23724 METHOD_DECL
23725 | ABSTRACT_DECL_BASE
23726 | FUNCTION_DECL),
23727 decl_base(type->get_environment(), name, locus, linkage_name, vis),
23728 function_decl(name, static_pointer_cast<function_type>
23729 (dynamic_pointer_cast<method_type>(type)),
23730 declared_inline, locus, linkage_name, vis, bind)
23731{
23733 set_context_rel(new mem_fn_context_rel(0));
23734}
23735
23736/// Set the linkage name of the method.
23737///
23738/// @param l the new linkage name of the method.
23739void
23741{
23742 string old_lname = get_linkage_name();
23744 // Update the linkage_name -> member function map of the containing
23745 // class declaration.
23746 if (!l.empty())
23747 {
23749 class_or_union_sptr cl = t->get_class_type();
23750 method_decl_sptr m(this, sptr_utils::noop_deleter());
23751 cl->priv_->mem_fns_map_[l] = m;
23752 if (!old_lname.empty())
23753 {
23754 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
23755 {
23756 if (m.get() == this)
23757 cl->priv_->mem_fns_map_.erase(old_lname);
23758 }
23759 }
23760 }
23761}
23762
23763method_decl::~method_decl()
23764{}
23765
23766const method_type_sptr
23768{
23769 method_type_sptr result;
23771 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
23772 return result;
23773}
23774
23775/// Set the containing class of a method_decl.
23776///
23777/// @param scope the new containing class_decl.
23778void
23779method_decl::set_scope(scope_decl* scope)
23780{
23781 if (!get_context_rel())
23782 set_context_rel(new mem_fn_context_rel(scope));
23783 else
23784 get_context_rel()->set_scope(scope);
23785}
23786
23787/// Equality operator for @ref method_decl_sptr.
23788///
23789/// This is a deep equality operator, as it compares the @ref
23790/// method_decl that is pointed-to by the smart pointer.
23791///
23792/// @param l the left-hand side argument of the equality operator.
23793///
23794/// @param r the righ-hand side argument of the equality operator.
23795///
23796/// @return true iff @p l equals @p r.
23797bool
23798operator==(const method_decl_sptr& l, const method_decl_sptr& r)
23799{
23800 if (l.get() == r.get())
23801 return true;
23802 if (!!l != !!r)
23803 return false;
23804
23805 return *l == *r;
23806}
23807
23808/// Inequality operator for @ref method_decl_sptr.
23809///
23810/// This is a deep equality operator, as it compares the @ref
23811/// method_decl that is pointed-to by the smart pointer.
23812///
23813/// @param l the left-hand side argument of the equality operator.
23814///
23815/// @param r the righ-hand side argument of the equality operator.
23816///
23817/// @return true iff @p l differs from @p r.
23818bool
23819operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
23820{return !operator==(l, r);}
23821
23822/// Test if a function_decl is actually a method_decl.
23823///
23824///@param d the @ref function_decl to consider.
23825///
23826/// @return the method_decl sub-object of @p d if inherits
23827/// a method_decl type.
23830{
23831 return dynamic_cast<method_decl*>
23832 (const_cast<type_or_decl_base*>(d));
23833}
23834
23835/// Test if a function_decl is actually a method_decl.
23836///
23837///@param d the @ref function_decl to consider.
23838///
23839/// @return the method_decl sub-object of @p d if inherits
23840/// a method_decl type.
23843{return is_method_decl(&d);}
23844
23845/// Test if a function_decl is actually a method_decl.
23846///
23847///@param d the @ref function_decl to consider.
23848///
23849/// @return the method_decl sub-object of @p d if inherits
23850/// a method_decl type.
23851method_decl_sptr
23853{return dynamic_pointer_cast<method_decl>(d);}
23854
23855/// A "less than" functor to sort a vector of instances of
23856/// method_decl that are virtual.
23857struct virtual_member_function_less_than
23858{
23859 /// The less than operator. First, it sorts the methods by their
23860 /// vtable index. If they have the same vtable index, it sorts them
23861 /// by the name of their ELF symbol. If they don't have elf
23862 /// symbols, it sorts them by considering their pretty
23863 /// representation.
23864 ///
23865 /// Note that this method expects virtual methods.
23866 ///
23867 /// @param f the first method to consider.
23868 ///
23869 /// @param s the second method to consider.
23870 ///
23871 /// @return true if method @p is less than method @s.
23872 bool
23873 operator()(const method_decl& f,
23874 const method_decl& s)
23875 {
23878
23879 ssize_t f_offset = get_member_function_vtable_offset(f);
23880 ssize_t s_offset = get_member_function_vtable_offset(s);
23881 if (f_offset != s_offset) return f_offset < s_offset;
23882
23883 string fn, sn;
23884
23885 // If the functions have symbols, then compare their symbol-id
23886 // string.
23887 elf_symbol_sptr f_sym = f.get_symbol();
23888 elf_symbol_sptr s_sym = s.get_symbol();
23889 if ((!f_sym) != (!s_sym)) return !f_sym;
23890 if (f_sym && s_sym)
23891 {
23892 fn = f_sym->get_id_string();
23893 sn = s_sym->get_id_string();
23894 if (fn != sn) return fn < sn;
23895 }
23896
23897 // Try the linkage names (important for destructors).
23898 fn = f.get_linkage_name();
23899 sn = s.get_linkage_name();
23900 if (fn != sn) return fn < sn;
23901
23902 // None of the functions have symbols or linkage names that
23903 // distinguish them, so compare their pretty representation.
23906 if (fn != sn) return fn < sn;
23907
23908 /// If it's just the file paths that are different then sort them
23909 /// too.
23910 string fn_filepath, sn_filepath;
23911 unsigned line = 0, column = 0;
23912 location fn_loc = f.get_location(), sn_loc = s.get_location();
23913 if (fn_loc)
23914 fn_loc.expand(fn_filepath, line, column);
23915 if (sn_loc)
23916 sn_loc.expand(sn_filepath, line, column);
23917 return fn_filepath < sn_filepath;
23918 }
23919
23920 /// The less than operator. First, it sorts the methods by their
23921 /// vtable index. If they have the same vtable index, it sorts them
23922 /// by the name of their ELF symbol. If they don't have elf
23923 /// symbols, it sorts them by considering their pretty
23924 /// representation.
23925 ///
23926 /// Note that this method expects to take virtual methods.
23927 ///
23928 /// @param f the first method to consider.
23929 ///
23930 /// @param s the second method to consider.
23931 bool
23932 operator()(const method_decl_sptr f,
23933 const method_decl_sptr s)
23934 {return operator()(*f, *s);}
23935}; // end struct virtual_member_function_less_than
23936
23937/// Sort a vector of instances of virtual member functions.
23938///
23939/// @param mem_fns the vector of member functions to sort.
23940static void
23941sort_virtual_member_functions(class_decl::member_functions& mem_fns)
23942{
23943 virtual_member_function_less_than lt;
23944 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
23945}
23946
23947/// Add a member function to the current instance of @ref class_or_union.
23948///
23949/// @param f a method_decl to add to the current class. This function
23950/// should not have been already added to a scope.
23951///
23952/// @param access the access specifier for the member function to add.
23953///
23954/// @param is_virtual if this is true then it means the function @p f
23955/// is a virtual function. That also means that the current instance
23956/// of @ref class_or_union is actually an instance of @ref class_decl.
23957///
23958/// @param vtable_offset the offset of the member function in the
23959/// virtual table. This parameter is taken into account only if @p
23960/// is_virtual is true.
23961///
23962/// @param is_static whether the member function is static.
23963///
23964/// @param is_ctor whether the member function is a constructor.
23965///
23966/// @param is_dtor whether the member function is a destructor.
23967///
23968/// @param is_const whether the member function is const.
23969void
23972 bool is_virtual,
23973 size_t vtable_offset,
23974 bool is_static, bool is_ctor,
23975 bool is_dtor, bool is_const)
23976{
23977 add_member_function(f, a, is_static, is_ctor,
23978 is_dtor, is_const);
23979
23980 if (class_decl* klass = is_class_type(this))
23981 {
23982 set_member_function_is_virtual(f, is_virtual);
23983 if (is_virtual)
23984 {
23985 set_member_function_vtable_offset(f, vtable_offset);
23986 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
23987 }
23988 }
23989}
23990
23991/// When a virtual member function has seen its virtualness set by
23992/// set_member_function_is_virtual(), this function ensures that the
23993/// member function is added to the specific vectors and maps of
23994/// virtual member function of its class.
23995///
23996/// @param method the method to fixup.
23997void
23998fixup_virtual_member_function(method_decl_sptr method)
23999{
24000 if (!method || !get_member_function_is_virtual(method))
24001 return;
24002
24003 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
24004
24005 class_decl::member_functions::const_iterator m;
24006 for (m = klass->priv_->virtual_mem_fns_.begin();
24007 m != klass->priv_->virtual_mem_fns_.end();
24008 ++m)
24009 if (m->get() == method.get())
24010 break;
24011 if (m == klass->priv_->virtual_mem_fns_.end())
24012 klass->priv_->virtual_mem_fns_.push_back(method);
24013
24014 // Build or udpate the map that associates a vtable offset to the
24015 // number of virtual member functions that "point" to it.
24016 ssize_t voffset = get_member_function_vtable_offset(method);
24017 if (voffset == -1)
24018 return;
24019
24020 class_decl::virtual_mem_fn_map_type::iterator i =
24021 klass->priv_->virtual_mem_fns_map_.find(voffset);
24022 if (i == klass->priv_->virtual_mem_fns_map_.end())
24023 {
24024 class_decl::member_functions virtual_mem_fns_at_voffset;
24025 virtual_mem_fns_at_voffset.push_back(method);
24026 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
24027 }
24028 else
24029 {
24030 for (m = i->second.begin() ; m != i->second.end(); ++m)
24031 if (m->get() == method.get())
24032 break;
24033 if (m == i->second.end())
24034 i->second.push_back(method);
24035 }
24036}
24037
24038/// Return true iff the class has no entity in its scope.
24039bool
24041{return priv_->bases_.empty() && has_no_member();}
24042
24043/// Test if the current instance of @ref class_decl has virtual member
24044/// functions.
24045///
24046/// @return true iff the current instance of @ref class_decl has
24047/// virtual member functions.
24048bool
24050{return !get_virtual_mem_fns().empty();}
24051
24052/// Test if the current instance of @ref class_decl has at least one
24053/// virtual base.
24054///
24055/// @return true iff the current instance of @ref class_decl has a
24056/// virtual member function.
24057bool
24059{
24060 for (base_specs::const_iterator b = get_base_specifiers().begin();
24061 b != get_base_specifiers().end();
24062 ++b)
24063 if ((*b)->get_is_virtual()
24064 || (*b)->get_base_class()->has_virtual_bases())
24065 return true;
24066
24067 return false;
24068}
24069
24070/// Test if the current instance has a vtable.
24071///
24072/// This is only valid for a C++ program.
24073///
24074/// Basically this function checks if the class has either virtual
24075/// functions, or virtual bases.
24076bool
24078{
24080 || has_virtual_bases())
24081 return true;
24082 return false;
24083}
24084
24085/// Get the highest vtable offset of all the virtual methods of the
24086/// class.
24087///
24088/// @return the highest vtable offset of all the virtual methods of
24089/// the class.
24090ssize_t
24092{
24093 ssize_t offset = -1;
24094 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
24095 get_virtual_mem_fns_map().begin();
24096 e != get_virtual_mem_fns_map().end();
24097 ++e)
24098 if (e->first > offset)
24099 offset = e->first;
24100
24101 return offset;
24102}
24103
24104/// Return the hash value for the current instance.
24105///
24106/// @return the hash value.
24107size_t
24109{
24110 class_decl::hash hash_class;
24111 return hash_class(this);
24112}
24113
24114/// Test if two methods are equal without taking their symbol or
24115/// linkage name into account.
24116///
24117/// @param f the first method.
24118///
24119/// @param s the second method.
24120///
24121/// @return true iff @p f equals @p s without taking their linkage
24122/// name or symbol into account.
24123static bool
24124methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
24125 const method_decl_sptr& s)
24126{
24127 method_decl_sptr first = f, second = s;
24128 elf_symbol_sptr saved_first_elf_symbol =
24129 first->get_symbol();
24130 elf_symbol_sptr saved_second_elf_symbol =
24131 second->get_symbol();
24132 interned_string saved_first_linkage_name =
24133 first->get_linkage_name();
24134 interned_string saved_second_linkage_name =
24135 second->get_linkage_name();
24136
24137 first->set_symbol(elf_symbol_sptr());
24138 first->set_linkage_name("");
24139 second->set_symbol(elf_symbol_sptr());
24140 second->set_linkage_name("");
24141
24142 bool equal = *first == *second;
24143
24144 first->set_symbol(saved_first_elf_symbol);
24145 first->set_linkage_name(saved_first_linkage_name);
24146 second->set_symbol(saved_second_elf_symbol);
24147 second->set_linkage_name(saved_second_linkage_name);
24148
24149 return equal;
24150}
24151
24152/// Test if a given method is equivalent to at least of other method
24153/// that is in a vector of methods.
24154///
24155/// Note that "equivalent" here means being equal without taking the
24156/// linkage name or the symbol of the methods into account.
24157///
24158/// This is a sub-routine of the 'equals' function that compares @ref
24159/// class_decl.
24160///
24161/// @param method the method to compare.
24162///
24163/// @param fns the vector of functions to compare @p method against.
24164///
24165/// @return true iff @p is equivalent to at least one method in @p
24166/// fns.
24167static bool
24168method_matches_at_least_one_in_vector(const method_decl_sptr& method,
24170{
24171 for (class_decl::member_functions::const_iterator i = fns.begin();
24172 i != fns.end();
24173 ++i)
24174 // Note that the comparison must be done in this order: method ==
24175 // *i This is to keep the consistency of the comparison. It's
24176 // important especially when doing type canonicalization. The
24177 // already canonicalize type is the left operand, and the type
24178 // being canonicalized is the right operand. This comes from the
24179 // code in type_base::get_canonical_type_for().
24180 if (methods_equal_modulo_elf_symbol(method, *i))
24181 return true;
24182
24183 return false;
24184}
24185
24186/// Cancel the canonical type that was propagated.
24187///
24188/// If we are in the process of comparing a type for the purpose of
24189/// canonicalization, and if that type has been the target of the
24190/// canonical type propagation optimization, then clear the propagated
24191/// canonical type. See @ref OnTheFlyCanonicalization for more about
24192/// the canonical type optimization
24193///
24194/// @param t the type to consider.
24195static bool
24196maybe_cancel_propagated_canonical_type(const class_or_union& t)
24197{
24198 const environment& env = t.get_environment();
24199 if (env.do_on_the_fly_canonicalization())
24200 if (is_type(&t)->priv_->canonical_type_propagated())
24201 {
24202 is_type(&t)->priv_->clear_propagated_canonical_type();
24203 env.priv_->remove_from_types_with_non_confirmed_propagated_ct(&t);
24204 return true;
24205 }
24206 return false;
24207}
24208
24209/// Compares two instances of @ref class_decl.
24210///
24211/// If the two intances are different, set a bitfield to give some
24212/// insight about the kind of differences there are.
24213///
24214/// @param l the first artifact of the comparison.
24215///
24216/// @param r the second artifact of the comparison.
24217///
24218/// @param k a pointer to a bitfield that gives information about the
24219/// kind of changes there are between @p l and @p r. This one is set
24220/// iff @p k is non-null and the function returns false.
24221///
24222/// Please note that setting k to a non-null value does have a
24223/// negative performance impact because even if @p l and @p r are not
24224/// equal, the function keeps up the comparison in order to determine
24225/// the different kinds of ways in which they are different.
24226///
24227/// @return true if @p l equals @p r, false otherwise.
24228bool
24230{
24231 {
24232 // First of all, let's see if these two types haven't already been
24233 // compared. If so, and if the result of the comparison has been
24234 // cached, let's just re-use it, rather than comparing them all
24235 // over again.
24236 bool result = false;
24237 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
24238 return result;
24239 }
24240
24241 // if one of the classes is declaration-only then we take a fast
24242 // path here.
24244 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
24245 static_cast<const class_or_union&>(r),
24246 k));
24247
24248 bool had_canonical_type = !!r.get_naked_canonical_type();
24249 bool result = true;
24250 if (!equals(static_cast<const class_or_union&>(l),
24251 static_cast<const class_or_union&>(r),
24252 k))
24253 {
24254 result = false;
24255 if (!k)
24256 ABG_RETURN(result);
24257 }
24258
24259 // If comparing the class_or_union 'part' of the type led to
24260 // canonical type propagation, then cancel that because it's too
24261 // early to do that at this point. We still need to compare bases
24262 // virtual members.
24263 if (!had_canonical_type)
24264 maybe_cancel_propagated_canonical_type(r);
24265
24267
24269
24270#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
24271
24272 // Compare bases.
24273 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
24274 {
24275 result = false;
24276 if (k)
24278 else
24279 RETURN(result);
24280 }
24281
24282 for (class_decl::base_specs::const_iterator
24283 b0 = l.get_base_specifiers().begin(),
24284 b1 = r.get_base_specifiers().begin();
24285 (b0 != l.get_base_specifiers().end()
24286 && b1 != r.get_base_specifiers().end());
24287 ++b0, ++b1)
24288 if (*b0 != *b1)
24289 {
24290 result = false;
24291 if (k)
24292 {
24293 if (!types_have_similar_structure((*b0)->get_base_class().get(),
24294 (*b1)->get_base_class().get()))
24296 else
24297 *k |= SUBTYPE_CHANGE_KIND;
24298 break;
24299 }
24300 RETURN(result);
24301 }
24302
24303 // Compare virtual member functions
24304
24305 // We look at the map that associates a given vtable offset to a
24306 // vector of virtual member functions that point to that offset.
24307 //
24308 // This is because there are cases where several functions can
24309 // point to the same virtual table offset.
24310 //
24311 // This is usually the case for virtual destructors. Even though
24312 // there can be only one virtual destructor declared in source
24313 // code, there are actually potentially up to three generated
24314 // functions for that destructor. Some of these generated
24315 // functions can be clones of other functions that are among those
24316 // generated ones. In any cases, they all have the same
24317 // properties, including the vtable offset property.
24318
24319 // So, there should be the same number of different vtable
24320 // offsets, the size of two maps must be equals.
24321 if (l.get_virtual_mem_fns_map().size()
24322 != r.get_virtual_mem_fns_map().size())
24323 {
24324 result = false;
24325 if (k)
24327 else
24328 RETURN(result);
24329 }
24330
24331 // Then, each virtual member function of a given vtable offset in
24332 // the first class type, must match an equivalent virtual member
24333 // function of a the same vtable offset in the second class type.
24334 //
24335 // By "match", I mean that the two virtual member function should
24336 // be equal if we don't take into account their symbol name or
24337 // their linkage name. This is because two destructor functions
24338 // clones (for instance) might have different linkage name, but
24339 // are still equivalent if their other properties are the same.
24340 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
24341 l.get_virtual_mem_fns_map().begin();
24342 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
24343 ++first_v_fn_entry)
24344 {
24345 unsigned voffset = first_v_fn_entry->first;
24346 const class_decl::member_functions& first_vfns =
24347 first_v_fn_entry->second;
24348
24349 const class_decl::virtual_mem_fn_map_type::const_iterator
24350 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
24351
24352 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
24353 {
24354 result = false;
24355 if (k)
24357 RETURN(result);
24358 }
24359
24360 const class_decl::member_functions& second_vfns =
24361 second_v_fn_entry->second;
24362
24363 bool matches = false;
24364 for (class_decl::member_functions::const_iterator i =
24365 first_vfns.begin();
24366 i != first_vfns.end();
24367 ++i)
24368 if (method_matches_at_least_one_in_vector(*i, second_vfns))
24369 {
24370 matches = true;
24371 break;
24372 }
24373
24374 if (!matches)
24375 {
24376 result = false;
24377 if (k)
24378 *k |= SUBTYPE_CHANGE_KIND;
24379 else
24380 RETURN(result);
24381 }
24382 }
24383
24384 RETURN(result);
24385#undef RETURN
24386}
24387
24388/// Copy a method of a class into a new class.
24389///
24390/// @param klass the class into which the method is to be copied.
24391///
24392/// @param method the method to copy into @p klass.
24393///
24394/// @return the resulting newly copied method.
24395method_decl_sptr
24396copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
24397{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
24398
24399/// Copy a method of a class into a new class.
24400///
24401/// @param klass the class into which the method is to be copied.
24402///
24403/// @param method the method to copy into @p klass.
24404///
24405/// @return the resulting newly copied method.
24406method_decl_sptr
24408{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
24409
24410/// Comparison operator for @ref class_decl.
24411///
24412/// @param other the instance of @ref class_decl to compare against.
24413///
24414/// @return true iff the current instance of @ref class_decl equals @p
24415/// other.
24416bool
24418{
24419 const class_decl* op = is_class_type(&other);
24420 if (!op)
24421 return false;
24422
24423 // If this is a decl-only type (and thus with no canonical type),
24424 // use the canonical type of the definition, if any.
24425 const class_decl *l = 0;
24427 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
24428 if (l == 0)
24429 l = this;
24430
24431 ABG_ASSERT(l);
24432
24433 // Likewise for the other type.
24434 const class_decl *r = 0;
24435 if (op->get_is_declaration_only())
24436 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
24437 if (r == 0)
24438 r = op;
24439
24440 ABG_ASSERT(r);
24441
24442 return try_canonical_compare(l, r);
24443}
24444
24445/// Equality operator for class_decl.
24446///
24447/// Re-uses the equality operator that takes a decl_base.
24448///
24449/// @param other the other class_decl to compare against.
24450///
24451/// @return true iff the current instance equals the other one.
24452bool
24454{
24455 const decl_base* o = is_decl(&other);
24456 if (!o)
24457 return false;
24458 return *this == *o;
24459}
24460
24461/// Equality operator for class_decl.
24462///
24463/// Re-uses the equality operator that takes a decl_base.
24464///
24465/// @param other the other class_decl to compare against.
24466///
24467/// @return true iff the current instance equals the other one.
24468bool
24470{
24471 const decl_base& o = other;
24472 return *this == o;
24473}
24474
24475/// Comparison operator for @ref class_decl.
24476///
24477/// @param other the instance of @ref class_decl to compare against.
24478///
24479/// @return true iff the current instance of @ref class_decl equals @p
24480/// other.
24481bool
24483{
24484 const decl_base& o = other;
24485 return *this == o;
24486}
24487
24488/// Turn equality of shared_ptr of class_decl into a deep equality;
24489/// that is, make it compare the pointed to objects too.
24490///
24491/// @param l the shared_ptr of class_decl on left-hand-side of the
24492/// equality.
24493///
24494/// @param r the shared_ptr of class_decl on right-hand-side of the
24495/// equality.
24496///
24497/// @return true if the class_decl pointed to by the shared_ptrs are
24498/// equal, false otherwise.
24499bool
24501{
24502 if (l.get() == r.get())
24503 return true;
24504 if (!!l != !!r)
24505 return false;
24506
24507 return *l == *r;
24508}
24509
24510/// Turn inequality of shared_ptr of class_decl into a deep equality;
24511/// that is, make it compare the pointed to objects too.
24512///
24513/// @param l the shared_ptr of class_decl on left-hand-side of the
24514/// equality.
24515///
24516/// @param r the shared_ptr of class_decl on right-hand-side of the
24517/// equality.
24518///
24519/// @return true if the class_decl pointed to by the shared_ptrs are
24520/// different, false otherwise.
24521bool
24523{return !operator==(l, r);}
24524
24525/// Turn equality of shared_ptr of class_or_union into a deep
24526/// equality; that is, make it compare the pointed to objects too.
24527///
24528/// @param l the left-hand-side operand of the operator
24529///
24530/// @param r the right-hand-side operand of the operator.
24531///
24532/// @return true iff @p l equals @p r.
24533bool
24534operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
24535{
24536 if (l.get() == r.get())
24537 return true;
24538 if (!!l != !!r)
24539 return false;
24540
24541 return *l == *r;
24542}
24543
24544/// Turn inequality of shared_ptr of class_or_union into a deep
24545/// equality; that is, make it compare the pointed to objects too.
24546///
24547/// @param l the left-hand-side operand of the operator
24548///
24549/// @param r the right-hand-side operand of the operator.
24550///
24551/// @return true iff @p l is different from @p r.
24552bool
24553operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
24554{return !operator==(l, r);}
24555
24556/// This implements the ir_traversable_base::traverse pure virtual
24557/// function.
24558///
24559/// @param v the visitor used on the current instance and on its
24560/// members.
24561///
24562/// @return true if the entire IR node tree got traversed, false
24563/// otherwise.
24564bool
24566{
24567 if (v.type_node_has_been_visited(this))
24568 return true;
24569
24570 if (visiting())
24571 return true;
24572
24573 if (v.visit_begin(this))
24574 {
24575 visiting(true);
24576 bool stop = false;
24577
24578 for (base_specs::const_iterator i = get_base_specifiers().begin();
24579 i != get_base_specifiers().end();
24580 ++i)
24581 {
24582 if (!(*i)->traverse(v))
24583 {
24584 stop = true;
24585 break;
24586 }
24587 }
24588
24589 if (!stop)
24590 for (data_members::const_iterator i = get_data_members().begin();
24591 i != get_data_members().end();
24592 ++i)
24593 if (!(*i)->traverse(v))
24594 {
24595 stop = true;
24596 break;
24597 }
24598
24599 if (!stop)
24600 for (member_functions::const_iterator i= get_member_functions().begin();
24601 i != get_member_functions().end();
24602 ++i)
24603 if (!(*i)->traverse(v))
24604 {
24605 stop = true;
24606 break;
24607 }
24608
24609 if (!stop)
24610 for (member_types::const_iterator i = get_member_types().begin();
24611 i != get_member_types().end();
24612 ++i)
24613 if (!(*i)->traverse(v))
24614 {
24615 stop = true;
24616 break;
24617 }
24618
24619 if (!stop)
24620 for (member_function_templates::const_iterator i =
24622 i != get_member_function_templates().end();
24623 ++i)
24624 if (!(*i)->traverse(v))
24625 {
24626 stop = true;
24627 break;
24628 }
24629
24630 if (!stop)
24631 for (member_class_templates::const_iterator i =
24633 i != get_member_class_templates().end();
24634 ++i)
24635 if (!(*i)->traverse(v))
24636 {
24637 stop = true;
24638 break;
24639 }
24640 visiting(false);
24641 }
24642
24643 bool result = v.visit_end(this);
24645 return result;
24646}
24647
24648/// Destructor of the @ref class_decl type.
24650{delete priv_;}
24651
24652context_rel::~context_rel()
24653{}
24654
24655bool
24656member_base::operator==(const member_base& o) const
24657{
24659 && get_is_static() == o.get_is_static());
24660}
24661
24662/// Equality operator for smart pointers to @ref
24663/// class_decl::base_specs.
24664///
24665/// This compares the pointed-to objects.
24666///
24667/// @param l the first instance to consider.
24668///
24669/// @param r the second instance to consider.
24670///
24671/// @return true iff @p l equals @p r.
24672bool
24675{
24676 if (l.get() == r.get())
24677 return true;
24678 if (!!l != !!r)
24679 return false;
24680
24681 return *l == static_cast<const decl_base&>(*r);
24682}
24683
24684/// Inequality operator for smart pointers to @ref
24685/// class_decl::base_specs.
24686///
24687/// This compares the pointed-to objects.
24688///
24689/// @param l the first instance to consider.
24690///
24691/// @param r the second instance to consider.
24692///
24693/// @return true iff @p l is different from @p r.
24694bool
24697{return !operator==(l, r);}
24698
24699/// Test if an ABI artifact is a class base specifier.
24700///
24701/// @param tod the ABI artifact to consider.
24702///
24703/// @return a pointer to the @ref class_decl::base_spec sub-object of
24704/// @p tod iff it's a class base specifier.
24707{
24708 return dynamic_cast<class_decl::base_spec*>
24709 (const_cast<type_or_decl_base*>(tod));
24710}
24711
24712/// Test if an ABI artifact is a class base specifier.
24713///
24714/// @param tod the ABI artifact to consider.
24715///
24716/// @return a pointer to the @ref class_decl::base_spec sub-object of
24717/// @p tod iff it's a class base specifier.
24720{return dynamic_pointer_cast<class_decl::base_spec>(tod);}
24721
24722bool
24723member_function_template::operator==(const member_base& other) const
24724{
24725 try
24726 {
24727 const member_function_template& o =
24728 dynamic_cast<const member_function_template&>(other);
24729
24730 if (!(is_constructor() == o.is_constructor()
24731 && is_const() == o.is_const()
24732 && member_base::operator==(o)))
24733 return false;
24734
24735 if (function_tdecl_sptr ftdecl = as_function_tdecl())
24736 {
24737 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
24738 if (other_ftdecl)
24739 return ftdecl->function_tdecl::operator==(*other_ftdecl);
24740 }
24741 }
24742 catch(...)
24743 {}
24744 return false;
24745}
24746
24747/// Equality operator for smart pointers to @ref
24748/// member_function_template. This is compares the
24749/// pointed-to instances.
24750///
24751/// @param l the first instance to consider.
24752///
24753/// @param r the second instance to consider.
24754///
24755/// @return true iff @p l equals @p r.
24756bool
24757operator==(const member_function_template_sptr& l,
24758 const member_function_template_sptr& r)
24759{
24760 if (l.get() == r.get())
24761 return true;
24762 if (!!l != !!r)
24763 return false;
24764
24765 return *l == *r;
24766}
24767
24768/// Inequality operator for smart pointers to @ref
24769/// member_function_template. This is compares the pointed-to
24770/// instances.
24771///
24772/// @param l the first instance to consider.
24773///
24774/// @param r the second instance to consider.
24775///
24776/// @return true iff @p l equals @p r.
24777bool
24778operator!=(const member_function_template_sptr& l,
24779 const member_function_template_sptr& r)
24780{return !operator==(l, r);}
24781
24782/// This implements the ir_traversable_base::traverse pure virtual
24783/// function.
24784///
24785/// @param v the visitor used on the current instance and on its
24786/// underlying function template.
24787///
24788/// @return true if the entire IR node tree got traversed, false
24789/// otherwise.
24790bool
24792{
24793 if (visiting())
24794 return true;
24795
24796 if (v.visit_begin(this))
24797 {
24798 visiting(true);
24799 if (function_tdecl_sptr f = as_function_tdecl())
24800 f->traverse(v);
24801 visiting(false);
24802 }
24803 return v.visit_end(this);
24804}
24805
24806/// Equality operator of the the @ref member_class_template class.
24807///
24808/// @param other the other @ref member_class_template to compare against.
24809///
24810/// @return true iff the current instance equals @p other.
24811bool
24813{
24814 try
24815 {
24816 const member_class_template& o =
24817 dynamic_cast<const member_class_template&>(other);
24818
24819 if (!member_base::operator==(o))
24820 return false;
24821
24822 return as_class_tdecl()->class_tdecl::operator==(o);
24823 }
24824 catch(...)
24825 {return false;}
24826}
24827
24828/// Equality operator of the the @ref member_class_template class.
24829///
24830/// @param other the other @ref member_class_template to compare against.
24831///
24832/// @return true iff the current instance equals @p other.
24833bool
24835{
24836 if (!decl_base::operator==(other))
24837 return false;
24838 return as_class_tdecl()->class_tdecl::operator==(other);
24839}
24840
24841/// Comparison operator for the @ref member_class_template
24842/// type.
24843///
24844/// @param other the other instance of @ref
24845/// member_class_template to compare against.
24846///
24847/// @return true iff the two instances are equal.
24848bool
24850{
24851 const decl_base* o = dynamic_cast<const decl_base*>(&other);
24852 return *this == *o;
24853}
24854
24855/// Comparison operator for the @ref member_class_template
24856/// type.
24857///
24858/// @param l the first argument of the operator.
24859///
24860/// @param r the second argument of the operator.
24861///
24862/// @return true iff the two instances are equal.
24863bool
24864operator==(const member_class_template_sptr& l,
24865 const member_class_template_sptr& r)
24866{
24867 if (l.get() == r.get())
24868 return true;
24869 if (!!l != !!r)
24870 return false;
24871
24872 return *l == *r;
24873}
24874
24875/// Inequality operator for the @ref member_class_template
24876/// type.
24877///
24878/// @param l the first argument of the operator.
24879///
24880/// @param r the second argument of the operator.
24881///
24882/// @return true iff the two instances are equal.
24883bool
24884operator!=(const member_class_template_sptr& l,
24885 const member_class_template_sptr& r)
24886{return !operator==(l, r);}
24887
24888/// This implements the ir_traversable_base::traverse pure virtual
24889/// function.
24890///
24891/// @param v the visitor used on the current instance and on the class
24892/// pattern of the template.
24893///
24894/// @return true if the entire IR node tree got traversed, false
24895/// otherwise.
24896bool
24898{
24899 if (visiting())
24900 return true;
24901
24902 if (v.visit_begin(this))
24903 {
24904 visiting(true);
24905 if (class_tdecl_sptr t = as_class_tdecl())
24906 t->traverse(v);
24907 visiting(false);
24908 }
24909 return v.visit_end(this);
24910}
24911
24912/// Streaming operator for class_decl::access_specifier.
24913///
24914/// @param o the output stream to serialize the access specifier to.
24915///
24916/// @param a the access specifier to serialize.
24917///
24918/// @return the output stream.
24919std::ostream&
24920operator<<(std::ostream& o, access_specifier a)
24921{
24922 string r;
24923
24924 switch (a)
24925 {
24926 case no_access:
24927 r = "none";
24928 break;
24929 case private_access:
24930 r = "private";
24931 break;
24932 case protected_access:
24933 r = "protected";
24934 break;
24935 case public_access:
24936 r= "public";
24937 break;
24938 };
24939 o << r;
24940 return o;
24941}
24942
24943/// Sets the static-ness property of a class member.
24944///
24945/// @param d the class member to set the static-ness property for.
24946/// Note that this must be a class member otherwise the function
24947/// aborts the current process.
24948///
24949/// @param s this must be true if the member is to be static, false
24950/// otherwise.
24951void
24953{
24955
24957 ABG_ASSERT(c);
24958
24959 c->set_is_static(s);
24960
24961 scope_decl* scope = d.get_scope();
24962
24963 if (class_or_union* cl = is_class_or_union_type(scope))
24964 {
24965 if (var_decl* v = is_var_decl(&d))
24966 {
24967 if (s)
24968 // remove from the non-static data members
24969 for (class_decl::data_members::iterator i =
24970 cl->priv_->non_static_data_members_.begin();
24971 i != cl->priv_->non_static_data_members_.end();
24972 ++i)
24973 {
24974 if ((*i)->get_name() == v->get_name())
24975 {
24976 cl->priv_->non_static_data_members_.erase(i);
24977 break;
24978 }
24979 }
24980 else
24981 {
24982 bool is_already_in_non_static_data_members = false;
24983 for (class_or_union::data_members::iterator i =
24984 cl->priv_->non_static_data_members_.begin();
24985 i != cl->priv_->non_static_data_members_.end();
24986 ++i)
24987 {
24988 if ((*i)->get_name() == v->get_name())
24989 {
24990 is_already_in_non_static_data_members = true;
24991 break;
24992 }
24993 }
24994 if (!is_already_in_non_static_data_members)
24995 {
24996 var_decl_sptr var;
24997 // add to non-static data members.
24998 for (class_or_union::data_members::const_iterator i =
24999 cl->priv_->data_members_.begin();
25000 i != cl->priv_->data_members_.end();
25001 ++i)
25002 {
25003 if ((*i)->get_name() == v->get_name())
25004 {
25005 var = *i;
25006 break;
25007 }
25008 }
25009 ABG_ASSERT(var);
25010 cl->priv_->non_static_data_members_.push_back(var);
25011 }
25012 }
25013 }
25014 }
25015}
25016
25017/// Sets the static-ness property of a class member.
25018///
25019/// @param d the class member to set the static-ness property for.
25020/// Note that this must be a class member otherwise the function
25021/// aborts the current process.
25022///
25023/// @param s this must be true if the member is to be static, false
25024/// otherwise.
25025void
25026set_member_is_static(const decl_base_sptr& d, bool s)
25027{set_member_is_static(*d, s);}
25028
25029// </class_decl>
25030
25031// <union_decl>
25032
25033/// Constructor for the @ref union_decl type.
25034///
25035/// @param env the @ref environment we are operating from.
25036///
25037/// @param name the name of the union type.
25038///
25039/// @param size_in_bits the size of the union, in bits.
25040///
25041/// @param locus the location of the type.
25042///
25043/// @param vis the visibility of instances of @ref union_decl.
25044///
25045/// @param mbr_types the member types of the union.
25046///
25047/// @param data_mbrs the data members of the union.
25048///
25049/// @param member_fns the member functions of the union.
25050union_decl::union_decl(const environment& env, const string& name,
25051 size_t size_in_bits, const location& locus,
25052 visibility vis, member_types& mbr_types,
25053 data_members& data_mbrs, member_functions& member_fns)
25054 : type_or_decl_base(env,
25055 UNION_TYPE
25056 | ABSTRACT_TYPE_BASE
25057 | ABSTRACT_DECL_BASE),
25058 decl_base(env, name, locus, name, vis),
25059 type_base(env, size_in_bits, 0),
25060 class_or_union(env, name, size_in_bits, 0,
25061 locus, vis, mbr_types, data_mbrs, member_fns)
25062{
25064}
25065
25066/// Constructor for the @ref union_decl type.
25067///
25068/// @param env the @ref environment we are operating from.
25069///
25070/// @param name the name of the union type.
25071///
25072/// @param size_in_bits the size of the union, in bits.
25073///
25074/// @param locus the location of the type.
25075///
25076/// @param vis the visibility of instances of @ref union_decl.
25077///
25078/// @param mbr_types the member types of the union.
25079///
25080/// @param data_mbrs the data members of the union.
25081///
25082/// @param member_fns the member functions of the union.
25083///
25084/// @param is_anonymous whether the newly created instance is
25085/// anonymous.
25086union_decl::union_decl(const environment& env, const string& name,
25087 size_t size_in_bits, const location& locus,
25088 visibility vis, member_types& mbr_types,
25089 data_members& data_mbrs, member_functions& member_fns,
25090 bool is_anonymous)
25091 : type_or_decl_base(env,
25092 UNION_TYPE
25093 | ABSTRACT_TYPE_BASE
25094 | ABSTRACT_DECL_BASE),
25095 decl_base(env, name, locus,
25096 // If the class is anonymous then by default it won't
25097 // have a linkage name. Also, the anonymous class does
25098 // have an internal-only unique name that is generally
25099 // not taken into account when comparing classes; such a
25100 // unique internal-only name, when used as a linkage
25101 // name might introduce spurious comparison false
25102 // negatives.
25103 /*linkage_name=*/is_anonymous ? string() : name,
25104 vis),
25105 type_base(env, size_in_bits, 0),
25106 class_or_union(env, name, size_in_bits, 0,
25107 locus, vis, mbr_types, data_mbrs, member_fns)
25108{
25110 set_is_anonymous(is_anonymous);
25111}
25112
25113/// Constructor for the @ref union_decl type.
25114///
25115/// @param env the @ref environment we are operating from.
25116///
25117/// @param name the name of the union type.
25118///
25119/// @param size_in_bits the size of the union, in bits.
25120///
25121/// @param locus the location of the type.
25122///
25123/// @param vis the visibility of instances of @ref union_decl.
25124union_decl::union_decl(const environment& env, const string& name,
25125 size_t size_in_bits, const location& locus,
25126 visibility vis)
25127 : type_or_decl_base(env,
25128 UNION_TYPE
25129 | ABSTRACT_TYPE_BASE
25130 | ABSTRACT_DECL_BASE
25131 | ABSTRACT_SCOPE_TYPE_DECL
25132 | ABSTRACT_SCOPE_DECL),
25133 decl_base(env, name, locus, name, vis),
25134 type_base(env, size_in_bits, 0),
25135 class_or_union(env, name, size_in_bits,
25136 0, locus, vis)
25137{
25139}
25140
25141/// Constructor for the @ref union_decl type.
25142///
25143/// @param env the @ref environment we are operating from.
25144///
25145/// @param name the name of the union type.
25146///
25147/// @param size_in_bits the size of the union, in bits.
25148///
25149/// @param locus the location of the type.
25150///
25151/// @param vis the visibility of instances of @ref union_decl.
25152///
25153/// @param is_anonymous whether the newly created instance is
25154/// anonymous.
25155union_decl::union_decl(const environment& env, const string& name,
25156 size_t size_in_bits, const location& locus,
25157 visibility vis, bool is_anonymous)
25158 : type_or_decl_base(env,
25159 UNION_TYPE
25160 | ABSTRACT_TYPE_BASE
25161 | ABSTRACT_DECL_BASE
25162 | ABSTRACT_SCOPE_TYPE_DECL
25163 | ABSTRACT_SCOPE_DECL),
25164 decl_base(env, name, locus,
25165 // If the class is anonymous then by default it won't
25166 // have a linkage name. Also, the anonymous class does
25167 // have an internal-only unique name that is generally
25168 // not taken into account when comparing classes; such a
25169 // unique internal-only name, when used as a linkage
25170 // name might introduce spurious comparison false
25171 // negatives.
25172 /*linkage_name=*/is_anonymous ? string() : name,
25173 vis),
25174 type_base(env, size_in_bits, 0),
25175 class_or_union(env, name, size_in_bits,
25176 0, locus, vis)
25177{
25179 set_is_anonymous(is_anonymous);
25180}
25181
25182/// Constructor for the @ref union_decl type.
25183///
25184/// @param env the @ref environment we are operating from.
25185///
25186/// @param name the name of the union type.
25187///
25188/// @param is_declaration_only a boolean saying whether the instance
25189/// represents a declaration only, or not.
25190union_decl::union_decl(const environment& env,
25191 const string& name,
25192 bool is_declaration_only)
25193 : type_or_decl_base(env,
25194 UNION_TYPE
25195 | ABSTRACT_TYPE_BASE
25196 | ABSTRACT_DECL_BASE
25197 | ABSTRACT_SCOPE_TYPE_DECL
25198 | ABSTRACT_SCOPE_DECL),
25199 decl_base(env, name, location(), name),
25200 type_base(env, 0, 0),
25201 class_or_union(env, name, is_declaration_only)
25202{
25204}
25205
25206/// Getter of the pretty representation of the current instance of
25207/// @ref union_decl.
25208///
25209/// @param internal set to true if the call is intended to get a
25210/// representation of the decl (or type) for the purpose of canonical
25211/// type comparison. This is mainly used in the function
25212/// type_base::get_canonical_type_for().
25213///
25214/// In other words if the argument for this parameter is true then the
25215/// call is meant for internal use (for technical use inside the
25216/// library itself), false otherwise. If you don't know what this is
25217/// for, then set it to false.
25218///
25219/// @param qualified_name if true, names emitted in the pretty
25220/// representation are fully qualified.
25221///
25222/// @return the pretty representaion for a union_decl.
25223string
25225 bool qualified_name) const
25226{
25227 string repr;
25228 if (get_is_anonymous())
25229 {
25230 if (internal && !get_name().empty())
25231 repr = string("union ") +
25232 get_type_name(this, qualified_name, /*internal=*/true);
25233 else
25235 /*one_line=*/true,
25236 internal);
25237 }
25238 else
25239 {
25240 repr = "union ";
25241 if (qualified_name)
25242 repr += get_qualified_name(internal);
25243 else
25244 repr += get_name();
25245 }
25246
25247 return repr;
25248}
25249
25250/// Comparison operator for @ref union_decl.
25251///
25252/// @param other the instance of @ref union_decl to compare against.
25253///
25254/// @return true iff the current instance of @ref union_decl equals @p
25255/// other.
25256bool
25258{
25259 const union_decl* op = dynamic_cast<const union_decl*>(&other);
25260 if (!op)
25261 return false;
25262 return try_canonical_compare(this, op);
25263}
25264
25265/// Equality operator for union_decl.
25266///
25267/// Re-uses the equality operator that takes a decl_base.
25268///
25269/// @param other the other union_decl to compare against.
25270///
25271/// @return true iff the current instance equals the other one.
25272bool
25274{
25275 const decl_base *o = dynamic_cast<const decl_base*>(&other);
25276 if (!o)
25277 return false;
25278 return *this == *o;
25279}
25280
25281/// Equality operator for union_decl.
25282///
25283/// Re-uses the equality operator that takes a decl_base.
25284///
25285/// @param other the other union_decl to compare against.
25286///
25287/// @return true iff the current instance equals the other one.
25288bool
25290{
25291 const decl_base *o = dynamic_cast<const decl_base*>(&other);
25292 return *this == *o;
25293}
25294
25295/// Comparison operator for @ref union_decl.
25296///
25297/// @param other the instance of @ref union_decl to compare against.
25298///
25299/// @return true iff the current instance of @ref union_decl equals @p
25300/// other.
25301bool
25303{
25304 const decl_base& o = other;
25305 return *this == o;
25306}
25307
25308/// This implements the ir_traversable_base::traverse pure virtual
25309/// function.
25310///
25311/// @param v the visitor used on the current instance and on its
25312/// members.
25313///
25314/// @return true if the entire IR node tree got traversed, false
25315/// otherwise.
25316bool
25318{
25319 if (v.type_node_has_been_visited(this))
25320 return true;
25321
25322 if (visiting())
25323 return true;
25324
25325 if (v.visit_begin(this))
25326 {
25327 visiting(true);
25328 bool stop = false;
25329
25330 if (!stop)
25331 for (data_members::const_iterator i = get_data_members().begin();
25332 i != get_data_members().end();
25333 ++i)
25334 if (!(*i)->traverse(v))
25335 {
25336 stop = true;
25337 break;
25338 }
25339
25340 if (!stop)
25341 for (member_functions::const_iterator i= get_member_functions().begin();
25342 i != get_member_functions().end();
25343 ++i)
25344 if (!(*i)->traverse(v))
25345 {
25346 stop = true;
25347 break;
25348 }
25349
25350 if (!stop)
25351 for (member_types::const_iterator i = get_member_types().begin();
25352 i != get_member_types().end();
25353 ++i)
25354 if (!(*i)->traverse(v))
25355 {
25356 stop = true;
25357 break;
25358 }
25359
25360 if (!stop)
25361 for (member_function_templates::const_iterator i =
25363 i != get_member_function_templates().end();
25364 ++i)
25365 if (!(*i)->traverse(v))
25366 {
25367 stop = true;
25368 break;
25369 }
25370
25371 if (!stop)
25372 for (member_class_templates::const_iterator i =
25374 i != get_member_class_templates().end();
25375 ++i)
25376 if (!(*i)->traverse(v))
25377 {
25378 stop = true;
25379 break;
25380 }
25381 visiting(false);
25382 }
25383
25384 bool result = v.visit_end(this);
25386 return result;
25387}
25388
25389/// Destructor of the @ref union_decl type.
25391{}
25392
25393/// Compares two instances of @ref union_decl.
25394///
25395/// If the two intances are different, set a bitfield to give some
25396/// insight about the kind of differences there are.
25397///
25398/// @param l the first artifact of the comparison.
25399///
25400/// @param r the second artifact of the comparison.
25401///
25402/// @param k a pointer to a bitfield that gives information about the
25403/// kind of changes there are between @p l and @p r. This one is set
25404/// iff @p k is non-null and the function returns false.
25405///
25406/// Please note that setting k to a non-null value does have a
25407/// negative performance impact because even if @p l and @p r are not
25408/// equal, the function keeps up the comparison in order to determine
25409/// the different kinds of ways in which they are different.
25410///
25411/// @return true if @p l equals @p r, false otherwise.
25412bool
25414{
25415
25417
25418 {
25419 // First of all, let's see if these two types haven't already been
25420 // compared. If so, and if the result of the comparison has been
25421 // cached, let's just re-use it, rather than comparing them all
25422 // over again.
25423 bool result = false;
25424 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
25425 return result;
25426 }
25427
25428 bool result = equals(static_cast<const class_or_union&>(l),
25429 static_cast<const class_or_union&>(r),
25430 k);
25431
25433}
25434
25435/// Copy a method of a @ref union_decl into a new @ref
25436/// union_decl.
25437///
25438/// @param t the @ref union_decl into which the method is to be copied.
25439///
25440/// @param method the method to copy into @p t.
25441///
25442/// @return the resulting newly copied method.
25443method_decl_sptr
25444copy_member_function(const union_decl_sptr& union_type,
25445 const method_decl_sptr& f)
25446{return copy_member_function(union_type, f.get());}
25447
25448/// Copy a method of a @ref union_decl into a new @ref
25449/// union_decl.
25450///
25451/// @param t the @ref union_decl into which the method is to be copied.
25452///
25453/// @param method the method to copy into @p t.
25454///
25455/// @return the resulting newly copied method.
25456method_decl_sptr
25457copy_member_function(const union_decl_sptr& union_type,
25458 const method_decl* f)
25459{
25460 const class_or_union_sptr t = union_type;
25461 return copy_member_function(t, f);
25462}
25463
25464/// Turn equality of shared_ptr of union_decl into a deep equality;
25465/// that is, make it compare the pointed to objects too.
25466///
25467/// @param l the left-hand-side operand of the operator
25468///
25469/// @param r the right-hand-side operand of the operator.
25470///
25471/// @return true iff @p l equals @p r.
25472bool
25473operator==(const union_decl_sptr& l, const union_decl_sptr& r)
25474{
25475 if (l.get() == r.get())
25476 return true;
25477 if (!!l != !!r)
25478 return false;
25479
25480 return *l == *r;
25481}
25482
25483/// Turn inequality of shared_ptr of union_decl into a deep equality;
25484/// that is, make it compare the pointed to objects too.
25485///
25486/// @param l the left-hand-side operand of the operator
25487///
25488/// @param r the right-hand-side operand of the operator.
25489///
25490/// @return true iff @p l is different from @p r.
25491bool
25492operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
25493{return !operator==(l, r);}
25494// </union_decl>
25495
25496// <template_decl stuff>
25497
25498/// Data type of the private data of the @template_decl type.
25499class template_decl::priv
25500{
25501 friend class template_decl;
25502
25503 std::list<template_parameter_sptr> parms_;
25504public:
25505
25506 priv()
25507 {}
25508}; // end class template_decl::priv
25509
25510/// Add a new template parameter to the current instance of @ref
25511/// template_decl.
25512///
25513/// @param p the new template parameter to add.
25514void
25516{priv_->parms_.push_back(p);}
25517
25518/// Get the list of template parameters of the current instance of
25519/// @ref template_decl.
25520///
25521/// @return the list of template parameters.
25522const std::list<template_parameter_sptr>&
25524{return priv_->parms_;}
25525
25526/// Constructor.
25527///
25528/// @param env the environment we are operating from.
25529///
25530/// @param name the name of the template decl.
25531///
25532/// @param locus the source location where the template declaration is
25533/// defined.
25534///
25535/// @param vis the visibility of the template declaration.
25536template_decl::template_decl(const environment& env,
25537 const string& name,
25538 const location& locus,
25539 visibility vis)
25540 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
25541 decl_base(env, name, locus, /*mangled_name=*/"", vis),
25542 priv_(new priv)
25543{
25545}
25546
25547/// Destructor.
25549{}
25550
25551/// Equality operator.
25552///
25553/// @param o the other instance to compare against.
25554///
25555/// @return true iff @p equals the current instance.
25556bool
25558{
25559 const template_decl* other = dynamic_cast<const template_decl*>(&o);
25560 if (!other)
25561 return false;
25562 return *this == *other;
25563}
25564
25565/// Equality operator.
25566///
25567/// @param o the other instance to compare against.
25568///
25569/// @return true iff @p equals the current instance.
25570bool
25572{
25573 try
25574 {
25575 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
25576 for (t0 = get_template_parameters().begin(),
25577 t1 = o.get_template_parameters().begin();
25578 (t0 != get_template_parameters().end()
25579 && t1 != o.get_template_parameters().end());
25580 ++t0, ++t1)
25581 {
25582 if (**t0 != **t1)
25583 return false;
25584 }
25585
25586 if (t0 != get_template_parameters().end()
25587 || t1 != o.get_template_parameters().end())
25588 return false;
25589
25590 return true;
25591 }
25592 catch(...)
25593 {return false;}
25594}
25595
25596// </template_decl stuff>
25597
25598//<template_parameter>
25599
25600/// The type of the private data of the @ref template_parameter type.
25601class template_parameter::priv
25602{
25603 friend class template_parameter;
25604
25605 unsigned index_;
25606 template_decl_wptr template_decl_;
25607 mutable bool hashing_started_;
25608 mutable bool comparison_started_;
25609
25610 priv();
25611
25612public:
25613
25614 priv(unsigned index, template_decl_sptr enclosing_template_decl)
25615 : index_(index),
25616 template_decl_(enclosing_template_decl),
25617 hashing_started_(),
25618 comparison_started_()
25619 {}
25620}; // end class template_parameter::priv
25621
25622template_parameter::template_parameter(unsigned index,
25623 template_decl_sptr enclosing_template)
25624 : priv_(new priv(index, enclosing_template))
25625 {}
25626
25627unsigned
25628template_parameter::get_index() const
25629{return priv_->index_;}
25630
25632template_parameter::get_enclosing_template_decl() const
25633{return priv_->template_decl_.lock();}
25634
25635bool
25636template_parameter::get_hashing_has_started() const
25637{return priv_->hashing_started_;}
25638
25639void
25640template_parameter::set_hashing_has_started(bool f) const
25641{priv_->hashing_started_ = f;}
25642
25643bool
25644template_parameter::operator==(const template_parameter& o) const
25645{
25646 if (get_index() != o.get_index())
25647 return false;
25648
25649 if (priv_->comparison_started_)
25650 return true;
25651
25652 bool result = false;
25653
25654 // Avoid inifite loops due to the fact that comparison the enclosing
25655 // template decl might lead to comparing this very same template
25656 // parameter with another one ...
25657 priv_->comparison_started_ = true;
25658
25659 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
25660 ;
25661 else if (get_enclosing_template_decl()
25662 && (*get_enclosing_template_decl()
25663 != *o.get_enclosing_template_decl()))
25664 ;
25665 else
25666 result = true;
25667
25668 priv_->comparison_started_ = false;
25669
25670 return result;
25671}
25672
25673/// Inequality operator.
25674///
25675/// @param other the other instance to compare against.
25676///
25677/// @return true iff the other instance is different from the current
25678/// one.
25679bool
25681{return !operator==(other);}
25682
25683/// Destructor.
25685{}
25686
25687/// The type of the private data of the @ref type_tparameter type.
25688class type_tparameter::priv
25689{
25690 friend class type_tparameter;
25691}; // end class type_tparameter::priv
25692
25693/// Constructor of the @ref type_tparameter type.
25694///
25695/// @param index the index the type template parameter.
25696///
25697/// @param enclosing_tdecl the enclosing template declaration.
25698///
25699/// @param name the name of the template parameter.
25700///
25701/// @param locus the location of the declaration of this type template
25702/// parameter.
25703type_tparameter::type_tparameter(unsigned index,
25704 template_decl_sptr enclosing_tdecl,
25705 const string& name,
25706 const location& locus)
25707 : type_or_decl_base(enclosing_tdecl->get_environment(),
25708 ABSTRACT_DECL_BASE
25709 | ABSTRACT_TYPE_BASE
25710 | BASIC_TYPE),
25711 decl_base(enclosing_tdecl->get_environment(), name, locus),
25712 type_base(enclosing_tdecl->get_environment(), 0, 0),
25713 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
25714 template_parameter(index, enclosing_tdecl),
25715 priv_(new priv)
25716{
25718}
25719
25720/// Equality operator.
25721///
25722/// @param other the other template type parameter to compare against.
25723///
25724/// @return true iff @p other equals the current instance.
25725bool
25727{
25728 if (!type_decl::operator==(other))
25729 return false;
25730
25731 try
25732 {
25733 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
25735 }
25736 catch (...)
25737 {return false;}
25738}
25739
25740/// Equality operator.
25741///
25742/// @param other the other template type parameter to compare against.
25743///
25744/// @return true iff @p other equals the current instance.
25745bool
25747{
25748 if (!type_decl::operator==(other))
25749 return false;
25750
25751 try
25752 {
25753 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
25755 }
25756 catch (...)
25757 {return false;}
25758}
25759
25760/// Equality operator.
25761///
25762/// @param other the other template type parameter to compare against.
25763///
25764/// @return true iff @p other equals the current instance.
25765bool
25767{
25768 if (!decl_base::operator==(other))
25769 return false;
25770
25771 try
25772 {
25773 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
25775 }
25776 catch (...)
25777 {return false;}
25778}
25779
25780/// Equality operator.
25781///
25782/// @param other the other template type parameter to compare against.
25783///
25784/// @return true iff @p other equals the current instance.
25785bool
25787{
25788 try
25789 {
25790 const type_base& o = dynamic_cast<const type_base&>(other);
25791 return *this == o;
25792 }
25793 catch(...)
25794 {return false;}
25795}
25796
25797/// Equality operator.
25798///
25799/// @param other the other template type parameter to compare against.
25800///
25801/// @return true iff @p other equals the current instance.
25802bool
25804{return *this == static_cast<const type_base&>(other);}
25805
25806type_tparameter::~type_tparameter()
25807{}
25808
25809/// The type of the private data of the @ref non_type_tparameter type.
25810class non_type_tparameter::priv
25811{
25812 friend class non_type_tparameter;
25813
25814 type_base_wptr type_;
25815
25816 priv();
25817
25818public:
25819
25820 priv(type_base_sptr type)
25821 : type_(type)
25822 {}
25823}; // end class non_type_tparameter::priv
25824
25825/// The constructor for the @ref non_type_tparameter type.
25826///
25827/// @param index the index of the template parameter.
25828///
25829/// @param enclosing_tdecl the enclosing template declaration that
25830/// holds this parameter parameter.
25831///
25832/// @param name the name of the template parameter.
25833///
25834/// @param type the type of the template parameter.
25835///
25836/// @param locus the location of the declaration of this template
25837/// parameter.
25838non_type_tparameter::non_type_tparameter(unsigned index,
25839 template_decl_sptr enclosing_tdecl,
25840 const string& name,
25841 type_base_sptr type,
25842 const location& locus)
25843 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
25844 decl_base(type->get_environment(), name, locus, ""),
25845 template_parameter(index, enclosing_tdecl),
25846 priv_(new priv(type))
25847{
25849}
25850
25851/// Getter for the type of the template parameter.
25852///
25853/// @return the type of the template parameter.
25854const type_base_sptr
25856{return priv_->type_.lock();}
25857
25858/// Get the hash value of the current instance.
25859///
25860/// @return the hash value.
25861size_t
25863{
25864 non_type_tparameter::hash hash_tparm;
25865 return hash_tparm(this);
25866}
25867
25868bool
25870{
25871 if (!decl_base::operator==(other))
25872 return false;
25873
25874 try
25875 {
25876 const non_type_tparameter& o =
25877 dynamic_cast<const non_type_tparameter&>(other);
25878 return (template_parameter::operator==(o)
25879 && get_type() == o.get_type());
25880 }
25881 catch(...)
25882 {return false;}
25883}
25884
25885bool
25887{
25888 try
25889 {
25890 const decl_base& o = dynamic_cast<const decl_base&>(other);
25891 return *this == o;
25892 }
25893 catch(...)
25894 {return false;}
25895}
25896
25897non_type_tparameter::~non_type_tparameter()
25898{}
25899
25900// <template_tparameter stuff>
25901
25902/// Type of the private data of the @ref template_tparameter type.
25903class template_tparameter::priv
25904{
25905}; //end class template_tparameter::priv
25906
25907/// Constructor for the @ref template_tparameter.
25908///
25909/// @param index the index of the template parameter.
25910///
25911/// @param enclosing_tdecl the enclosing template declaration.
25912///
25913/// @param name the name of the template parameter.
25914///
25915/// @param locus the location of the declaration of the template
25916/// parameter.
25917template_tparameter::template_tparameter(unsigned index,
25918 template_decl_sptr enclosing_tdecl,
25919 const string& name,
25920 const location& locus)
25921 : type_or_decl_base(enclosing_tdecl->get_environment(),
25922 ABSTRACT_DECL_BASE
25923 | ABSTRACT_TYPE_BASE
25924 | BASIC_TYPE),
25925 decl_base(enclosing_tdecl->get_environment(), name, locus),
25926 type_base(enclosing_tdecl->get_environment(), 0, 0),
25927 type_decl(enclosing_tdecl->get_environment(), name,
25928 0, 0, locus, name, VISIBILITY_DEFAULT),
25929 type_tparameter(index, enclosing_tdecl, name, locus),
25930 template_decl(enclosing_tdecl->get_environment(), name, locus),
25931 priv_(new priv)
25932{
25934}
25935
25936/// Equality operator.
25937///
25938/// @param other the other template parameter to compare against.
25939///
25940/// @return true iff @p other equals the current instance.
25941bool
25943{
25944 try
25945 {
25946 const template_tparameter& o =
25947 dynamic_cast<const template_tparameter&>(other);
25948 return (type_tparameter::operator==(o)
25950 }
25951 catch(...)
25952 {return false;}
25953}
25954
25955/// Equality operator.
25956///
25957/// @param other the other template parameter to compare against.
25958///
25959/// @return true iff @p other equals the current instance.
25960bool
25962{
25963 try
25964 {
25965 const template_tparameter& o =
25966 dynamic_cast<const template_tparameter&>(other);
25967 return (type_tparameter::operator==(o)
25969 }
25970 catch(...)
25971 {return false;}
25972}
25973
25974bool
25976{
25977 try
25978 {
25979 const template_tparameter& other =
25980 dynamic_cast<const template_tparameter&>(o);
25981 return *this == static_cast<const type_base&>(other);
25982 }
25983 catch(...)
25984 {return false;}
25985}
25986
25987bool
25989{
25990 try
25991 {
25992 const template_tparameter& other =
25993 dynamic_cast<const template_tparameter&>(o);
25994 return type_base::operator==(other);
25995 }
25996 catch(...)
25997 {return false;}
25998}
25999
26000template_tparameter::~template_tparameter()
26001{}
26002
26003// </template_tparameter stuff>
26004
26005// <type_composition stuff>
26006
26007/// The type of the private data of the @ref type_composition type.
26008class type_composition::priv
26009{
26010 friend class type_composition;
26011
26012 type_base_wptr type_;
26013
26014 // Forbid this.
26015 priv();
26016
26017public:
26018
26019 priv(type_base_wptr type)
26020 : type_(type)
26021 {}
26022}; //end class type_composition::priv
26023
26024/// Constructor for the @ref type_composition type.
26025///
26026/// @param index the index of the template type composition.
26027///
26028/// @param tdecl the enclosing template parameter that owns the
26029/// composition.
26030///
26031/// @param t the resulting type.
26032type_composition::type_composition(unsigned index,
26033 template_decl_sptr tdecl,
26034 type_base_sptr t)
26035 : type_or_decl_base(tdecl->get_environment(),
26036 ABSTRACT_DECL_BASE),
26037 decl_base(tdecl->get_environment(), "", location()),
26038 template_parameter(index, tdecl),
26039 priv_(new priv(t))
26040{
26042}
26043
26044/// Getter for the resulting composed type.
26045///
26046/// @return the composed type.
26047const type_base_sptr
26049{return priv_->type_.lock();}
26050
26051/// Setter for the resulting composed type.
26052///
26053/// @param t the composed type.
26054void
26056{priv_->type_ = t;}
26057
26058/// Get the hash value for the current instance.
26059///
26060/// @return the hash value.
26061size_t
26063{
26064 type_composition::hash hash_type_composition;
26065 return hash_type_composition(this);
26066}
26067
26068type_composition::~type_composition()
26069{}
26070
26071// </type_composition stuff>
26072
26073//</template_parameter stuff>
26074
26075// <function_template>
26076
26077class function_tdecl::priv
26078{
26079 friend class function_tdecl;
26080
26081 function_decl_sptr pattern_;
26082 binding binding_;
26083
26084 priv();
26085
26086public:
26087
26088 priv(function_decl_sptr pattern, binding bind)
26089 : pattern_(pattern), binding_(bind)
26090 {}
26091
26092 priv(binding bind)
26093 : binding_(bind)
26094 {}
26095}; // end class function_tdecl::priv
26096
26097/// Constructor for a function template declaration.
26098///
26099/// @param env the environment we are operating from.
26100///
26101/// @param locus the location of the declaration.
26102///
26103/// @param vis the visibility of the declaration. This is the
26104/// visibility the functions instantiated from this template are going
26105/// to have.
26106///
26107/// @param bind the binding of the declaration. This is the binding
26108/// the functions instantiated from this template are going to have.
26109function_tdecl::function_tdecl(const environment& env,
26110 const location& locus,
26111 visibility vis,
26112 binding bind)
26113 : type_or_decl_base(env,
26114 ABSTRACT_DECL_BASE
26115 | TEMPLATE_DECL
26116 | ABSTRACT_SCOPE_DECL),
26117 decl_base(env, "", locus, "", vis),
26118 template_decl(env, "", locus, vis),
26119 scope_decl(env, "", locus),
26120 priv_(new priv(bind))
26121{
26123}
26124
26125/// Constructor for a function template declaration.
26126///
26127/// @param pattern the pattern of the template.
26128///
26129/// @param locus the location of the declaration.
26130///
26131/// @param vis the visibility of the declaration. This is the
26132/// visibility the functions instantiated from this template are going
26133/// to have.
26134///
26135/// @param bind the binding of the declaration. This is the binding
26136/// the functions instantiated from this template are going to have.
26137function_tdecl::function_tdecl(function_decl_sptr pattern,
26138 const location& locus,
26139 visibility vis,
26140 binding bind)
26141 : type_or_decl_base(pattern->get_environment(),
26142 ABSTRACT_DECL_BASE
26143 | TEMPLATE_DECL
26144 | ABSTRACT_SCOPE_DECL),
26145 decl_base(pattern->get_environment(), pattern->get_name(), locus,
26146 pattern->get_name(), vis),
26147 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
26148 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
26149 priv_(new priv(pattern, bind))
26150{
26152}
26153
26154/// Set a new pattern to the function template.
26155///
26156/// @param p the new pattern.
26157void
26159{
26160 priv_->pattern_ = p;
26161 add_decl_to_scope(p, this);
26162 set_name(p->get_name());
26163}
26164
26165/// Get the pattern of the function template.
26166///
26167/// @return the pattern.
26170{return priv_->pattern_;}
26171
26172/// Get the binding of the function template.
26173///
26174/// @return the binding
26177{return priv_->binding_;}
26178
26179/// Comparison operator for the @ref function_tdecl type.
26180///
26181/// @param other the other instance of @ref function_tdecl to compare against.
26182///
26183/// @return true iff the two instance are equal.
26184bool
26186{
26187 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
26188 if (o)
26189 return *this == *o;
26190 return false;
26191}
26192
26193/// Comparison operator for the @ref function_tdecl type.
26194///
26195/// @param other the other instance of @ref function_tdecl to compare against.
26196///
26197/// @return true iff the two instance are equal.
26198bool
26200{
26201 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
26202 if (o)
26203 return *this == *o;
26204 return false;
26205}
26206
26207/// Comparison operator for the @ref function_tdecl type.
26208///
26209/// @param o the other instance of @ref function_tdecl to compare against.
26210///
26211/// @return true iff the two instance are equal.
26212bool
26214{
26215 if (!(get_binding() == o.get_binding()
26216 && template_decl::operator==(o)
26217 && scope_decl::operator==(o)
26218 && !!get_pattern() == !!o.get_pattern()))
26219 return false;
26220
26221 if (get_pattern())
26222 return (*get_pattern() == *o.get_pattern());
26223
26224 return true;
26225}
26226
26227/// This implements the ir_traversable_base::traverse pure virtual
26228/// function.
26229///
26230/// @param v the visitor used on the current instance and on the
26231/// function pattern of the template.
26232///
26233/// @return true if the entire IR node tree got traversed, false
26234/// otherwise.
26235bool
26237{
26238 if (visiting())
26239 return true;
26240
26241 if (!v.visit_begin(this))
26242 {
26243 visiting(true);
26244 if (get_pattern())
26245 get_pattern()->traverse(v);
26246 visiting(false);
26247 }
26248 return v.visit_end(this);
26249}
26250
26251function_tdecl::~function_tdecl()
26252{}
26253
26254// </function_template>
26255
26256// <class template>
26257
26258/// Type of the private data of the the @ref class_tdecl type.
26259class class_tdecl::priv
26260{
26261 friend class class_tdecl;
26262 class_decl_sptr pattern_;
26263
26264public:
26265
26266 priv()
26267 {}
26268
26269 priv(class_decl_sptr pattern)
26270 : pattern_(pattern)
26271 {}
26272}; // end class class_tdecl::priv
26273
26274/// Constructor for the @ref class_tdecl type.
26275///
26276/// @param env the environment we are operating from.
26277///
26278/// @param locus the location of the declaration of the class_tdecl
26279/// type.
26280///
26281/// @param vis the visibility of the instance of class instantiated
26282/// from this template.
26283class_tdecl::class_tdecl(const environment& env,
26284 const location& locus,
26285 visibility vis)
26286 : type_or_decl_base(env,
26287 ABSTRACT_DECL_BASE
26288 | TEMPLATE_DECL
26289 | ABSTRACT_SCOPE_DECL),
26290 decl_base(env, "", locus, "", vis),
26291 template_decl(env, "", locus, vis),
26292 scope_decl(env, "", locus),
26293 priv_(new priv)
26294{
26296}
26297
26298/// Constructor for the @ref class_tdecl type.
26299///
26300/// @param pattern The details of the class template. This must NOT be a
26301/// null pointer. If you really this to be null, please use the
26302/// constructor above instead.
26303///
26304/// @param locus the source location of the declaration of the type.
26305///
26306/// @param vis the visibility of the instances of class instantiated
26307/// from this template.
26308class_tdecl::class_tdecl(class_decl_sptr pattern,
26309 const location& locus,
26310 visibility vis)
26311 : type_or_decl_base(pattern->get_environment(),
26312 ABSTRACT_DECL_BASE
26313 | TEMPLATE_DECL
26314 | ABSTRACT_SCOPE_DECL),
26315 decl_base(pattern->get_environment(), pattern->get_name(),
26316 locus, pattern->get_name(), vis),
26317 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
26318 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
26319 priv_(new priv(pattern))
26320{
26322}
26323
26324/// Setter of the pattern of the template.
26325///
26326/// @param p the new template.
26327void
26329{
26330 priv_->pattern_ = p;
26331 add_decl_to_scope(p, this);
26332 set_name(p->get_name());
26333}
26334
26335/// Getter of the pattern of the template.
26336///
26337/// @return p the new template.
26340{return priv_->pattern_;}
26341
26342bool
26344{
26345 try
26346 {
26347 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
26348
26349 if (!(template_decl::operator==(o)
26350 && scope_decl::operator==(o)
26351 && !!get_pattern() == !!o.get_pattern()))
26352 return false;
26353
26354 if (!get_pattern() || !o.get_pattern())
26355 return true;
26356
26357 return get_pattern()->decl_base::operator==(*o.get_pattern());
26358 }
26359 catch(...) {}
26360 return false;
26361}
26362
26363bool
26365{
26366 try
26367 {
26368 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
26369 return *this == static_cast<const decl_base&>(o);
26370 }
26371 catch(...)
26372 {return false;}
26373}
26374
26375bool
26377{return *this == static_cast<const decl_base&>(o);}
26378
26379/// This implements the ir_traversable_base::traverse pure virtual
26380/// function.
26381///
26382/// @param v the visitor used on the current instance and on the class
26383/// pattern of the template.
26384///
26385/// @return true if the entire IR node tree got traversed, false
26386/// otherwise.
26387bool
26389{
26390 if (visiting())
26391 return true;
26392
26393 if (v.visit_begin(this))
26394 {
26395 visiting(true);
26396 if (class_decl_sptr pattern = get_pattern())
26397 pattern->traverse(v);
26398 visiting(false);
26399 }
26400 return v.visit_end(this);
26401}
26402
26403class_tdecl::~class_tdecl()
26404{}
26405
26406/// This visitor checks if a given type as non-canonicalized sub
26407/// types.
26408class non_canonicalized_subtype_detector : public ir::ir_node_visitor
26409{
26410 type_base* type_;
26411 type_base* has_non_canonical_type_;
26412
26413private:
26414 non_canonicalized_subtype_detector();
26415
26416public:
26417 non_canonicalized_subtype_detector(type_base* type)
26418 : type_(type),
26419 has_non_canonical_type_()
26420 {}
26421
26422 /// Return true if the visitor detected that there is a
26423 /// non-canonicalized sub-type.
26424 ///
26425 /// @return true if the visitor detected that there is a
26426 /// non-canonicalized sub-type.
26427 type_base*
26428 has_non_canonical_type() const
26429 {return has_non_canonical_type_;}
26430
26431 /// The intent of this visitor handler is to avoid looking into
26432 /// sub-types of member functions of the type we are traversing.
26433 bool
26434 visit_begin(function_decl* f)
26435 {
26436 // Do not look at sub-types of non-virtual member functions.
26437 if (is_member_function(f)
26439 return false;
26440 return true;
26441 }
26442
26443 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
26444 /// the 'has_non_canonical_type' flag. And in any case, when
26445 /// visiting a sub-type, do not visit its children nodes. So this
26446 /// function only goes to the level below the level of the top-most
26447 /// type.
26448 ///
26449 /// @return true if we are at the same level as the top-most type,
26450 /// otherwise return false.
26451 bool
26452 visit_begin(type_base* t)
26453 {
26454 if (t != type_)
26455 {
26456 if (!t->get_canonical_type())
26457 // We are looking a sub-type of 'type_' which has no
26458 // canonical type. So tada! we found one! Get out right
26459 // now with the trophy.
26460 has_non_canonical_type_ = t;
26461
26462 return false;
26463 }
26464 return true;
26465 }
26466
26467 /// When we are done visiting a sub-type, if it's been flagged as
26468 /// been non-canonicalized, then stop the traversing.
26469 ///
26470 /// Otherwise, keep going.
26471 ///
26472 /// @return false iff the sub-type that has been visited is
26473 /// non-canonicalized.
26474 bool
26475 visit_end(type_base* )
26476 {
26477 if (has_non_canonical_type_)
26478 return false;
26479 return true;
26480 }
26481}; //end class non_canonicalized_subtype_detector
26482
26483/// Test if a type has sub-types that are non-canonicalized.
26484///
26485/// @param t the type which sub-types to consider.
26486///
26487/// @return true if a type has sub-types that are non-canonicalized.
26488type_base*
26490{
26491 if (!t)
26492 return 0;
26493
26494 non_canonicalized_subtype_detector v(t.get());
26495 t->traverse(v);
26496 return v.has_non_canonical_type();
26497}
26498
26499/// Tests if the change of a given type effectively comes from just
26500/// its sub-types. That is, if the type has changed but its type name
26501/// hasn't changed, then the change of the type mostly likely is a
26502/// sub-type change.
26503///
26504/// @param t_v1 the first version of the type.
26505///
26506/// @param t_v2 the second version of the type.
26507///
26508/// @return true iff the type changed and the change is about its
26509/// sub-types.
26510bool
26511type_has_sub_type_changes(const type_base_sptr t_v1,
26512 const type_base_sptr t_v2)
26513{
26514 type_base_sptr t1 = strip_typedef(t_v1);
26515 type_base_sptr t2 = strip_typedef(t_v2);
26516
26517 string repr1 = get_pretty_representation(t1, /*internal=*/false),
26518 repr2 = get_pretty_representation(t2, /*internal=*/false);
26519 return (t1 != t2 && repr1 == repr2);
26520}
26521
26522/// Make sure that the life time of a given (smart pointer to a) type
26523/// is the same as the life time of the libabigail library.
26524///
26525/// @param t the type to consider.
26526void
26527keep_type_alive(type_base_sptr t)
26528{
26529 const environment& env = t->get_environment();
26530 env.priv_->extra_live_types_.push_back(t);
26531}
26532
26533/// Hash an ABI artifact that is either a type or a decl.
26534///
26535/// This function intends to provides the fastest possible hashing for
26536/// types and decls, while being completely correct.
26537///
26538/// Note that if the artifact is a type and if it has a canonical
26539/// type, the hash value is going to be the pointer value of the
26540/// canonical type. Otherwise, this function computes a hash value
26541/// for the type by recursively walking the type members. This last
26542/// code path is possibly *very* slow and should only be used when
26543/// only handful of types are going to be hashed.
26544///
26545/// If the artifact is a decl, then a combination of the hash of its
26546/// type and the hash of the other properties of the decl is computed.
26547///
26548/// @param tod the type or decl to hash.
26549///
26550/// @return the resulting hash value.
26551size_t
26553{
26554 size_t result = 0;
26555
26556 if (tod == 0)
26557 ;
26558 else if (const type_base* t = is_type(tod))
26559 result = hash_type(t);
26560 else if (const decl_base* d = is_decl(tod))
26561 {
26562 if (var_decl* v = is_var_decl(d))
26563 {
26564 ABG_ASSERT(v->get_type());
26565 size_t h = hash_type_or_decl(v->get_type());
26566 string repr = v->get_pretty_representation(/*internal=*/true);
26567 std::hash<string> hash_string;
26568 h = hashing::combine_hashes(h, hash_string(repr));
26569 result = h;
26570 }
26571 else if (function_decl* f = is_function_decl(d))
26572 {
26573 ABG_ASSERT(f->get_type());
26574 size_t h = hash_type_or_decl(f->get_type());
26575 string repr = f->get_pretty_representation(/*internal=*/true);
26576 std::hash<string> hash_string;
26577 h = hashing::combine_hashes(h, hash_string(repr));
26578 result = h;
26579 }
26581 {
26582 type_base_sptr parm_type = p->get_type();
26583 ABG_ASSERT(parm_type);
26584 std::hash<bool> hash_bool;
26585 std::hash<unsigned> hash_unsigned;
26586 size_t h = hash_type_or_decl(parm_type);
26587 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
26588 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
26589 result = h;
26590 }
26591 else if (class_decl::base_spec *bs = is_class_base_spec(d))
26592 {
26593 member_base::hash hash_member;
26594 std::hash<size_t> hash_size;
26595 std::hash<bool> hash_bool;
26596 type_base_sptr type = bs->get_base_class();
26597 size_t h = hash_type_or_decl(type);
26598 h = hashing::combine_hashes(h, hash_member(*bs));
26599 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
26600 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
26601 result = h;
26602 }
26603 else
26604 // This is a *really* *SLOW* path. If it shows up in a
26605 // performance profile, I bet it'd be a good idea to try to
26606 // avoid it altogether.
26607 result = d->get_hash();
26608 }
26609 else
26610 // We should never get here.
26611 abort();
26612 return result;
26613}
26614
26615/// Hash an ABI artifact that is either a type.
26616///
26617/// This function intends to provides the fastest possible hashing for
26618/// types while being completely correct.
26619///
26620/// Note that if the type artifact has a canonical type, the hash
26621/// value is going to be the pointer value of the canonical type.
26622/// Otherwise, this function computes a hash value for the type by
26623/// recursively walking the type members. This last code path is
26624/// possibly *very* slow and should only be used when only handful of
26625/// types are going to be hashed.
26626///
26627/// @param t the type or decl to hash.
26628///
26629/// @return the resulting hash value.
26630size_t
26632{return hash_as_canonical_type_or_constant(t);}
26633
26634/// Hash an ABI artifact that is either a type of a decl.
26635///
26636/// @param tod the ABI artifact to hash.
26637///
26638/// @return the hash value of the ABI artifact.
26639size_t
26641{return hash_type_or_decl(tod.get());}
26642
26643/// Test if a given type is allowed to be non canonicalized
26644///
26645/// This is a subroutine of hash_as_canonical_type_or_constant.
26646///
26647/// For now, the only types allowed to be non canonicalized in the
26648/// system are (typedefs & pointers to) decl-only class/union, the
26649/// void type and variadic parameter types.
26650///
26651/// @return true iff @p t is a one of the only types allowed to be
26652/// non-canonicalized in the system.
26653bool
26655{
26656 if (!t)
26657 return true;
26658
26659 return (// The IR nodes for the types below are unique across the
26660 // entire ABI corpus. Thus, no need to canonicalize them.
26661 // Maybe we could say otherwise and canonicalize them once
26662 // for all so that they can be removed from here.
26664
26665 // An IR node for the types below can be equal to several
26666 // other types (i.e, a decl-only type t equals a fully
26667 // defined type of the same name in ODR-supported
26668 // languages). Hence, they can't be given a canonical type.
26669 //
26670 // TODO: Maybe add a mode that would detect ODR violations
26671 // that would make a decl-only type co-exists with several
26672 // different definitions of the type in the ABI corpus.
26678
26679}
26680
26681/// Test if a type is unique in the entire environment.
26682///
26683/// Examples of unique types are void, void* and variadic parameter
26684/// types.
26685///
26686/// @param t the type to test for.
26687///
26688/// @return true iff the type @p t is unique in the entire
26689/// environment.
26690bool
26691is_unique_type(const type_base_sptr& t)
26692{return is_unique_type(t.get());}
26693
26694/// Test if a type is unique in the entire environment.
26695///
26696/// Examples of unique types are void, void* and variadic parameter
26697/// types.
26698///
26699/// @param t the type to test for.
26700///
26701/// @return true iff the type @p t is unique in the entire
26702/// environment.
26703bool
26705{
26706 if (!t)
26707 return false;
26708
26709 const environment& env = t->get_environment();
26710 return (env.is_void_type(t)
26711 || env.is_void_pointer_type(t)
26712 || env.is_variadic_parameter_type(t));
26713}
26714
26715/// For a given type, return its exemplar type.
26716///
26717/// For a given type, its exemplar type is either its canonical type
26718/// or the canonical type of the definition type of a given
26719/// declaration-only type. If the neither of those two types exist,
26720/// then the exemplar type is the given type itself.
26721///
26722/// @param type the input to consider.
26723///
26724/// @return the exemplar type.
26725type_base*
26727{
26728 if (decl_base * decl = is_decl(type))
26729 {
26730 // Make sure we get the real definition of a decl-only type.
26731 decl = look_through_decl_only(decl);
26732 type = is_type(decl);
26733 ABG_ASSERT(type);
26734 }
26735 type_base *exemplar = type->get_naked_canonical_type();
26736 if (!exemplar)
26737 {
26738 // The type has no canonical type. Let's be sure that it's one
26739 // of those rare types that are allowed to be non canonicalized
26740 // in the system.
26741 exemplar = const_cast<type_base*>(type);
26743 }
26744 return exemplar;
26745}
26746
26747/// Test if a given type is allowed to be non canonicalized
26748///
26749/// This is a subroutine of hash_as_canonical_type_or_constant.
26750///
26751/// For now, the only types allowed to be non canonicalized in the
26752/// system are decl-only class/union and the void type.
26753///
26754/// @return true iff @p t is a one of the only types allowed to be
26755/// non-canonicalized in the system.
26756bool
26757is_non_canonicalized_type(const type_base_sptr& t)
26758{return is_non_canonicalized_type(t.get());}
26759
26760/// Hash a type by either returning the pointer value of its canonical
26761/// type or by returning a constant if the type doesn't have a
26762/// canonical type.
26763///
26764/// This is a subroutine of hash_type.
26765///
26766/// @param t the type to consider.
26767///
26768/// @return the hash value.
26769static size_t
26770hash_as_canonical_type_or_constant(const type_base *t)
26771{
26772 type_base *canonical_type = 0;
26773
26774 if (t)
26775 canonical_type = t->get_naked_canonical_type();
26776
26777 if (!canonical_type)
26778 {
26779 // If the type doesn't have a canonical type, maybe it's because
26780 // it's a declaration-only type? If that's the case, let's try
26781 // to get the canonical type of the definition of this
26782 // declaration.
26783 decl_base *decl = is_decl(t);
26784 if (decl
26785 && decl->get_is_declaration_only()
26787 {
26788 type_base *definition =
26790 ABG_ASSERT(definition);
26791 canonical_type = definition->get_naked_canonical_type();
26792 }
26793 }
26794
26795 if (canonical_type)
26796 return reinterpret_cast<size_t>(canonical_type);
26797
26798 // If we reached this point, it means we are seeing a
26799 // non-canonicalized type. It must be a decl-only class or a void
26800 // type, otherwise it means that for some weird reason, the type
26801 // hasn't been canonicalized. It should be!
26803
26804 return 0xDEADBABE;
26805}
26806
26807/// Test if the pretty representation of a given @ref function_decl is
26808/// lexicographically less then the pretty representation of another
26809/// @ref function_decl.
26810///
26811/// @param f the first @ref function_decl to consider for comparison.
26812///
26813/// @param s the second @ref function_decl to consider for comparison.
26814///
26815/// @return true iff the pretty representation of @p f is
26816/// lexicographically less than the pretty representation of @p s.
26817bool
26819{
26822
26823 if (fr != sr)
26824 return fr < sr;
26825
26826 fr = f.get_pretty_representation(/*internal=*/true),
26827 sr = s.get_pretty_representation(/*internal=*/true);
26828
26829 if (fr != sr)
26830 return fr < sr;
26831
26832 if (f.get_symbol())
26833 fr = f.get_symbol()->get_id_string();
26834 else if (!f.get_linkage_name().empty())
26835 fr = f.get_linkage_name();
26836
26837 if (s.get_symbol())
26838 sr = s.get_symbol()->get_id_string();
26839 else if (!s.get_linkage_name().empty())
26840 sr = s.get_linkage_name();
26841
26842 return fr < sr;
26843}
26844
26845/// Test if two types have similar structures, even though they are
26846/// (or can be) different.
26847///
26848/// const and volatile qualifiers are completely ignored.
26849///
26850/// typedef are resolved to their definitions; their names are ignored.
26851///
26852/// Two indirect types (pointers or references) have similar structure
26853/// if their underlying types are of the same kind and have the same
26854/// name. In the indirect types case, the size of the underlying type
26855/// does not matter.
26856///
26857/// Two direct types (i.e, non indirect) have a similar structure if
26858/// they have the same kind, name and size. Two class types have
26859/// similar structure if they have the same name, size, and if the
26860/// types of their data members have similar types.
26861///
26862/// @param first the first type to consider.
26863///
26864/// @param second the second type to consider.
26865///
26866/// @param indirect_type whether to do an indirect comparison
26867///
26868/// @return true iff @p first and @p second have similar structures.
26869bool
26870types_have_similar_structure(const type_base_sptr& first,
26871 const type_base_sptr& second,
26872 bool indirect_type)
26873{return types_have_similar_structure(first.get(), second.get(), indirect_type);}
26874
26875/// Test if two types have similar structures, even though they are
26876/// (or can be) different.
26877///
26878/// const and volatile qualifiers are completely ignored.
26879///
26880/// typedef are resolved to their definitions; their names are ignored.
26881///
26882/// Two indirect types (pointers, references or arrays) have similar
26883/// structure if their underlying types are of the same kind and have
26884/// the same name. In the indirect types case, the size of the
26885/// underlying type does not matter.
26886///
26887/// Two direct types (i.e, non indirect) have a similar structure if
26888/// they have the same kind, name and size. Two class types have
26889/// similar structure if they have the same name, size, and if the
26890/// types of their data members have similar types.
26891///
26892/// @param first the first type to consider.
26893///
26894/// @param second the second type to consider.
26895///
26896/// @param indirect_type if true, then consider @p first and @p
26897/// second as being underlying types of indirect types. Meaning that
26898/// their size does not matter.
26899///
26900/// @return true iff @p first and @p second have similar structures.
26901bool
26903 const type_base* second,
26904 bool indirect_type)
26905{
26906 if (!!first != !!second)
26907 return false;
26908
26909 if (!first)
26910 return false;
26911
26912 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
26913 first = peel_qualified_or_typedef_type(first);
26914 second = peel_qualified_or_typedef_type(second);
26915
26916 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
26917 // various ty2 below cannot be null.
26918 if (typeid(*first) != typeid(*second))
26919 return false;
26920
26921 // Peel off matching pointers.
26922 if (const pointer_type_def* ty1 = is_pointer_type(first))
26923 {
26924 const pointer_type_def* ty2 = is_pointer_type(second);
26925 return types_have_similar_structure(ty1->get_pointed_to_type(),
26926 ty2->get_pointed_to_type(),
26927 /*indirect_type=*/true);
26928 }
26929
26930 // Peel off matching references.
26931 if (const reference_type_def* ty1 = is_reference_type(first))
26932 {
26933 const reference_type_def* ty2 = is_reference_type(second);
26934 if (ty1->is_lvalue() != ty2->is_lvalue())
26935 return false;
26936 return types_have_similar_structure(ty1->get_pointed_to_type(),
26937 ty2->get_pointed_to_type(),
26938 /*indirect_type=*/true);
26939 }
26940
26941 if (const type_decl* ty1 = is_type_decl(first))
26942 {
26943 const type_decl* ty2 = is_type_decl(second);
26944 if (!indirect_type)
26945 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
26946 return false;
26947
26948 return ty1->get_name() == ty2->get_name();
26949 }
26950
26951 if (const enum_type_decl* ty1 = is_enum_type(first))
26952 {
26953 const enum_type_decl* ty2 = is_enum_type(second);
26954 if (!indirect_type)
26955 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
26956 return false;
26957
26958 return (get_name(ty1->get_underlying_type())
26959 == get_name(ty2->get_underlying_type()));
26960 }
26961
26962 if (const class_decl* ty1 = is_class_type(first))
26963 {
26964 const class_decl* ty2 = is_class_type(second);
26965 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
26966 && ty1->get_name() != ty2->get_name())
26967 return false;
26968
26969 if (!indirect_type)
26970 {
26971 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
26972 || (ty1->get_non_static_data_members().size()
26973 != ty2->get_non_static_data_members().size()))
26974 return false;
26975
26976 for (class_or_union::data_members::const_iterator
26977 i = ty1->get_non_static_data_members().begin(),
26978 j = ty2->get_non_static_data_members().begin();
26979 (i != ty1->get_non_static_data_members().end()
26980 && j != ty2->get_non_static_data_members().end());
26981 ++i, ++j)
26982 {
26983 var_decl_sptr dm1 = *i;
26984 var_decl_sptr dm2 = *j;
26985 if (!types_have_similar_structure(dm1->get_type().get(),
26986 dm2->get_type().get(),
26987 indirect_type))
26988 return false;
26989 }
26990 }
26991
26992 return true;
26993 }
26994
26995 if (const union_decl* ty1 = is_union_type(first))
26996 {
26997 const union_decl* ty2 = is_union_type(second);
26998 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
26999 && ty1->get_name() != ty2->get_name())
27000 return false;
27001
27002 if (!indirect_type)
27003 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
27004
27005 return true;
27006 }
27007
27008 if (const array_type_def* ty1 = is_array_type(first))
27009 {
27010 const array_type_def* ty2 = is_array_type(second);
27011 // TODO: Handle int[5][2] vs int[2][5] better.
27012 if (!indirect_type)
27013 {
27014 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
27015 || ty1->get_dimension_count() != ty2->get_dimension_count())
27016 return false;
27017 }
27018
27019 if (!types_have_similar_structure(ty1->get_element_type(),
27020 ty2->get_element_type(),
27021 /*indirect_type=*/true))
27022 return false;
27023
27024 return true;
27025 }
27026
27027 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
27028 {
27030 if (ty1->get_upper_bound() != ty2->get_upper_bound()
27031 || ty1->get_lower_bound() != ty2->get_lower_bound()
27032 || ty1->get_language() != ty2->get_language()
27033 || !types_have_similar_structure(ty1->get_underlying_type(),
27034 ty2->get_underlying_type(),
27035 indirect_type))
27036 return false;
27037
27038 return true;
27039 }
27040
27041 if (const function_type* ty1 = is_function_type(first))
27042 {
27043 const function_type* ty2 = is_function_type(second);
27044 if (!types_have_similar_structure(ty1->get_return_type(),
27045 ty2->get_return_type(),
27046 indirect_type))
27047 return false;
27048
27049 if (ty1->get_parameters().size() != ty2->get_parameters().size())
27050 return false;
27051
27052 for (function_type::parameters::const_iterator
27053 i = ty1->get_parameters().begin(),
27054 j = ty2->get_parameters().begin();
27055 (i != ty1->get_parameters().end()
27056 && j != ty2->get_parameters().end());
27057 ++i, ++j)
27058 if (!types_have_similar_structure((*i)->get_type(),
27059 (*j)->get_type(),
27060 indirect_type))
27061 return false;
27062
27063 return true;
27064 }
27065
27066 // All kinds of type should have been handled at this point.
27068
27069 return false;
27070}
27071
27072/// Look for a data member of a given class, struct or union type and
27073/// return it.
27074///
27075/// The data member is designated by its name.
27076///
27077/// @param type the class, struct or union type to consider.
27078///
27079/// @param dm_name the name of the data member to lookup.
27080///
27081/// @return the data member iff it was found in @type or NULL if no
27082/// data member with that name was found.
27083const var_decl*
27085 const char* dm_name)
27086
27087{
27089 if (!cou)
27090 return 0;
27091
27092 return cou->find_data_member(dm_name).get();
27093}
27094
27095/// Get the function parameter designated by its index.
27096///
27097/// Note that the first function parameter has index 0.
27098///
27099/// @param fun the function to consider.
27100///
27101/// @param parm_index the index of the function parameter to get.
27102///
27103/// @return the function parameter designated by its index, of NULL if
27104/// no function parameter with that index was found.
27107 unsigned parm_index)
27108{
27110 if (!fn)
27111 return 0;
27112
27113 const function_decl::parameters &parms = fn->get_type()->get_parameters();
27114 if (parms.size() <= parm_index)
27115 return 0;
27116
27117 return parms[parm_index].get();
27118}
27119
27120/// Build the internal name of the underlying type of an enum.
27121///
27122/// @param base_name the (unqualified) name of the enum the underlying
27123/// type is destined to.
27124///
27125/// @param is_anonymous true if the underlying type of the enum is to
27126/// be anonymous.
27127string
27129 bool is_anonymous,
27130 uint64_t size)
27131{
27132 std::ostringstream o;
27133
27134 if (is_anonymous)
27135 o << "unnamed-enum";
27136 else
27137 o << "enum-" << base_name;
27138
27139 o << "-underlying-type-" << size;
27140
27141 return o.str();
27142}
27143
27144/// Find the first data member of a class or union which name matches
27145/// a regular expression.
27146///
27147/// @param t the class or union to consider.
27148///
27149/// @param r the regular expression to consider.
27150///
27151/// @return the data member matched by @p r or nil if none was found.
27154 const regex::regex_t_sptr& r)
27155{
27156 for (auto data_member : t.get_data_members())
27157 {
27158 if (regex::match(r, data_member->get_name()))
27159 return data_member;
27160 }
27161
27162 return var_decl_sptr();
27163}
27164
27165/// Find the last data member of a class or union which name matches
27166/// a regular expression.
27167///
27168/// @param t the class or union to consider.
27169///
27170/// @param r the regular expression to consider.
27171///
27172/// @return the data member matched by @p r or nil if none was found.
27175 const regex::regex_t_sptr& regex)
27176{
27177 auto d = t.get_data_members().rbegin();
27178 auto e = t.get_data_members().rend();
27179 for (; d != e; ++d)
27180 {
27181 if (regex::match(regex, (*d)->get_name()))
27182 return *d;
27183 }
27184
27185 return var_decl_sptr();
27186}
27187
27188bool
27190{return true;}
27191
27192// <ir_node_visitor stuff>
27193
27194/// The private data structure of the ir_node_visitor type.
27195struct ir_node_visitor::priv
27196{
27197 pointer_set visited_ir_nodes;
27199
27200 priv()
27202 {}
27203}; // end struct ir_node_visitory::priv
27204
27205/// Default Constructor of the ir_node_visitor type.
27207 : priv_(new priv)
27208{}
27209
27210ir_node_visitor::~ir_node_visitor() = default;
27211
27212/// Set if the walker using this visitor is allowed to re-visit a type
27213/// node that was previously visited or not.
27214///
27215/// @param f if true, then the walker using this visitor is allowed to
27216/// re-visit a type node that was previously visited.
27217void
27219{priv_->allow_visiting_already_visited_type_node = f;}
27220
27221/// Get if the walker using this visitor is allowed to re-visit a type
27222/// node that was previously visited or not.
27223///
27224/// @return true iff the walker using this visitor is allowed to
27225/// re-visit a type node that was previously visited.
27226bool
27228{return priv_->allow_visiting_already_visited_type_node;}
27229
27230/// Mark a given type node as having been visited.
27231///
27232/// Note that for this function to work, the type node must have been
27233/// canonicalized. Otherwise the process is aborted.
27234///
27235/// @param p the type to mark as having been visited.
27236void
27238{
27240 return;
27241
27242 if (p == 0 || type_node_has_been_visited(p))
27243 return;
27244
27245 type_base* canonical_type = p->get_naked_canonical_type();
27246 ABG_ASSERT(canonical_type);
27247
27248 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
27249 priv_->visited_ir_nodes.insert(canonical_ptr_value);
27250}
27251
27252/// Un-mark all visited type nodes.
27253///
27254/// That is, no type node is going to be considered as having been
27255/// visited anymore.
27256///
27257/// In other words, after invoking this funciton,
27258/// ir_node_visitor::type_node_has_been_visited() is going to return
27259/// false on all type nodes.
27260void
27262{priv_->visited_ir_nodes.clear();}
27263
27264/// Test if a given type node has been marked as visited.
27265///
27266/// @param p the type node to consider.
27267///
27268/// @return true iff the type node @p p has been marked as visited by
27269/// the function ir_node_visitor::mark_type_node_as_visited.
27270bool
27272{
27274 return false;
27275
27276 if (p == 0)
27277 return false;
27278
27279 type_base *canonical_type = p->get_naked_canonical_type();
27280 ABG_ASSERT(canonical_type);
27281
27282 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
27283 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
27284 if (it == priv_->visited_ir_nodes.end())
27285 return false;
27286
27287 return true;
27288}
27289
27290bool
27291ir_node_visitor::visit_begin(decl_base*)
27292{return true;}
27293
27294bool
27295ir_node_visitor::visit_end(decl_base*)
27296{return true;}
27297
27298bool
27299ir_node_visitor::visit_begin(scope_decl*)
27300{return true;}
27301
27302bool
27303ir_node_visitor::visit_end(scope_decl*)
27304{return true;}
27305
27306bool
27307ir_node_visitor::visit_begin(type_base*)
27308{return true;}
27309
27310bool
27311ir_node_visitor::visit_end(type_base*)
27312{return true;}
27313
27314bool
27315ir_node_visitor::visit_begin(scope_type_decl* t)
27316{return visit_begin(static_cast<type_base*>(t));}
27317
27318bool
27319ir_node_visitor::visit_end(scope_type_decl* t)
27320{return visit_end(static_cast<type_base*>(t));}
27321
27322bool
27323ir_node_visitor::visit_begin(type_decl* t)
27324{return visit_begin(static_cast<type_base*>(t));}
27325
27326bool
27327ir_node_visitor::visit_end(type_decl* t)
27328{return visit_end(static_cast<type_base*>(t));}
27329
27330bool
27331ir_node_visitor::visit_begin(namespace_decl* d)
27332{return visit_begin(static_cast<decl_base*>(d));}
27333
27334bool
27335ir_node_visitor::visit_end(namespace_decl* d)
27336{return visit_end(static_cast<decl_base*>(d));}
27337
27338bool
27339ir_node_visitor::visit_begin(qualified_type_def* t)
27340{return visit_begin(static_cast<type_base*>(t));}
27341
27342bool
27343ir_node_visitor::visit_end(qualified_type_def* t)
27344{return visit_end(static_cast<type_base*>(t));}
27345
27346bool
27347ir_node_visitor::visit_begin(pointer_type_def* t)
27348{return visit_begin(static_cast<type_base*>(t));}
27349
27350bool
27351ir_node_visitor::visit_end(pointer_type_def* t)
27352{return visit_end(static_cast<type_base*>(t));}
27353
27354bool
27355ir_node_visitor::visit_begin(reference_type_def* t)
27356{return visit_begin(static_cast<type_base*>(t));}
27357
27358bool
27359ir_node_visitor::visit_end(reference_type_def* t)
27360{return visit_end(static_cast<type_base*>(t));}
27361
27362bool
27363ir_node_visitor::visit_begin(array_type_def* t)
27364{return visit_begin(static_cast<type_base*>(t));}
27365
27366bool
27367ir_node_visitor::visit_end(array_type_def* t)
27368{return visit_end(static_cast<type_base*>(t));}
27369
27370bool
27371ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
27372{return visit_begin(static_cast<type_base*>(t));}
27373
27374bool
27375ir_node_visitor::visit_end(array_type_def::subrange_type* t)
27376{return visit_end(static_cast<type_base*>(t));}
27377
27378bool
27379ir_node_visitor::visit_begin(enum_type_decl* t)
27380{return visit_begin(static_cast<type_base*>(t));}
27381
27382bool
27383ir_node_visitor::visit_end(enum_type_decl* t)
27384{return visit_end(static_cast<type_base*>(t));}
27385
27386bool
27387ir_node_visitor::visit_begin(typedef_decl* t)
27388{return visit_begin(static_cast<type_base*>(t));}
27389
27390bool
27391ir_node_visitor::visit_end(typedef_decl* t)
27392{return visit_end(static_cast<type_base*>(t));}
27393
27394bool
27395ir_node_visitor::visit_begin(function_type* t)
27396{return visit_begin(static_cast<type_base*>(t));}
27397
27398bool
27399ir_node_visitor::visit_end(function_type* t)
27400{return visit_end(static_cast<type_base*>(t));}
27401
27402bool
27403ir_node_visitor::visit_begin(var_decl* d)
27404{return visit_begin(static_cast<decl_base*>(d));}
27405
27406bool
27407ir_node_visitor::visit_end(var_decl* d)
27408{return visit_end(static_cast<decl_base*>(d));}
27409
27410bool
27411ir_node_visitor::visit_begin(function_decl* d)
27412{return visit_begin(static_cast<decl_base*>(d));}
27413
27414bool
27415ir_node_visitor::visit_end(function_decl* d)
27416{return visit_end(static_cast<decl_base*>(d));}
27417
27418bool
27419ir_node_visitor::visit_begin(function_decl::parameter* d)
27420{return visit_begin(static_cast<decl_base*>(d));}
27421
27422bool
27423ir_node_visitor::visit_end(function_decl::parameter* d)
27424{return visit_end(static_cast<decl_base*>(d));}
27425
27426bool
27427ir_node_visitor::visit_begin(function_tdecl* d)
27428{return visit_begin(static_cast<decl_base*>(d));}
27429
27430bool
27431ir_node_visitor::visit_end(function_tdecl* d)
27432{return visit_end(static_cast<decl_base*>(d));}
27433
27434bool
27435ir_node_visitor::visit_begin(class_tdecl* d)
27436{return visit_begin(static_cast<decl_base*>(d));}
27437
27438bool
27439ir_node_visitor::visit_end(class_tdecl* d)
27440{return visit_end(static_cast<decl_base*>(d));}
27441
27442bool
27443ir_node_visitor::visit_begin(class_or_union* t)
27444{return visit_begin(static_cast<type_base*>(t));}
27445
27446bool
27447ir_node_visitor::visit_end(class_or_union* t)
27448{return visit_end(static_cast<type_base*>(t));}
27449
27450bool
27451ir_node_visitor::visit_begin(class_decl* t)
27452{return visit_begin(static_cast<type_base*>(t));}
27453
27454bool
27455ir_node_visitor::visit_end(class_decl* t)
27456{return visit_end(static_cast<type_base*>(t));}
27457
27458bool
27459ir_node_visitor::visit_begin(union_decl* t)
27460{return visit_begin(static_cast<type_base*>(t));}
27461
27462bool
27463ir_node_visitor::visit_end(union_decl* t)
27464{return visit_end(static_cast<type_base*>(t));}
27465
27466bool
27467ir_node_visitor::visit_begin(class_decl::base_spec* d)
27468{return visit_begin(static_cast<decl_base*>(d));}
27469
27470bool
27471ir_node_visitor::visit_end(class_decl::base_spec* d)
27472{return visit_end(static_cast<decl_base*>(d));}
27473
27474bool
27475ir_node_visitor::visit_begin(member_function_template* d)
27476{return visit_begin(static_cast<decl_base*>(d));}
27477
27478bool
27479ir_node_visitor::visit_end(member_function_template* d)
27480{return visit_end(static_cast<decl_base*>(d));}
27481
27482bool
27483ir_node_visitor::visit_begin(member_class_template* d)
27484{return visit_begin(static_cast<decl_base*>(d));}
27485
27486bool
27487ir_node_visitor::visit_end(member_class_template* d)
27488{return visit_end(static_cast<decl_base*>(d));}
27489
27490// </ir_node_visitor stuff>
27491
27492// <debugging facilities>
27493
27494/// Generate a different string at each invocation.
27495///
27496/// @return the resulting string.
27497static string
27498get_next_string()
27499{
27500 static __thread size_t counter;
27501 ++counter;
27502 std::ostringstream o;
27503 o << counter;
27504 return o.str();
27505}
27506
27507/// Convenience typedef for a hash map of pointer to function_decl and
27508/// string.
27509typedef unordered_map<const function_decl*, string,
27510 function_decl::hash,
27512
27513/// Return a string associated to a given function. Two functions
27514/// that compare equal would yield the same string, as far as this
27515/// routine is concerned. And two functions that are different would
27516/// yield different strings.
27517///
27518/// This is used to debug core diffing issues on functions. The
27519/// sequence of strings can be given to the 'testdiff2' program that
27520/// is in the tests/ directory of the source tree, to reproduce core
27521/// diffing issues on string and thus ease the debugging.
27522///
27523/// @param fn the function to generate a string for.
27524///
27525/// @param m the function_decl* <-> string map to be used by this
27526/// function to generate strings associated to a function.
27527///
27528/// @return the resulting string.
27529static const string&
27530fn_to_str(const function_decl* fn,
27532{
27533 fns_to_str_map_type::const_iterator i = m.find(fn);
27534 if (i != m.end())
27535 return i->second;
27536 string s = get_next_string();
27537 return m[fn]= s;
27538}
27539
27540/// Generate a sequence of string that matches a given sequence of
27541/// function. In the resulting sequence, each function is "uniquely
27542/// representated" by a string. For instance, if the same function "foo"
27543/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
27544/// we don't care about the actual string) would appear at index 1 and 3.
27545///
27546/// @param begin the beginning of the sequence of functions to consider.
27547///
27548/// @param end the end of the sequence of functions. This points to
27549/// one-passed-the-end of the actual sequence.
27550///
27551/// @param m the function_decl* <-> string map to be used by this
27552/// function to generate strings associated to a function.
27553///
27554/// @param o the output stream where to emit the generated list of
27555/// strings to.
27556static void
27557fns_to_str(vector<function_decl*>::const_iterator begin,
27558 vector<function_decl*>::const_iterator end,
27560 std::ostream& o)
27561{
27562 vector<function_decl*>::const_iterator i;
27563 for (i = begin; i != end; ++i)
27564 o << "'" << fn_to_str(*i, m) << "' ";
27565}
27566
27567/// For each sequence of functions given in argument, generate a
27568/// sequence of string that matches a given sequence of function. In
27569/// the resulting sequence, each function is "uniquely representated"
27570/// by a string. For instance, if the same function "foo" appears at
27571/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
27572/// care about the actual string) would appear at index 1 and 3.
27573///
27574/// @param a_begin the beginning of the sequence of functions to consider.
27575///
27576/// @param a_end the end of the sequence of functions. This points to
27577/// one-passed-the-end of the actual sequence.
27578///
27579/// @param b_begin the beginning of the second sequence of functions
27580/// to consider.
27581///
27582/// @param b_end the end of the second sequence of functions.
27583///
27584/// @param m the function_decl* <-> string map to be used by this
27585/// function to generate strings associated to a function.
27586///
27587/// @param o the output stream where to emit the generated list of
27588/// strings to.
27589static void
27590fns_to_str(vector<function_decl*>::const_iterator a_begin,
27591 vector<function_decl*>::const_iterator a_end,
27592 vector<function_decl*>::const_iterator b_begin,
27593 vector<function_decl*>::const_iterator b_end,
27595 std::ostream& o)
27596{
27597 fns_to_str(a_begin, a_end, m, o);
27598 o << "->|<- ";
27599 fns_to_str(b_begin, b_end, m, o);
27600 o << "\n";
27601}
27602
27603/// For each sequence of functions given in argument, generate a
27604/// sequence of string that matches a given sequence of function. In
27605/// the resulting sequence, each function is "uniquely representated"
27606/// by a string. For instance, if the same function "foo" appears at
27607/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
27608/// care about the actual string) would appear at index 1 and 3.
27609///
27610/// @param a_begin the beginning of the sequence of functions to consider.
27611///
27612/// @param a_end the end of the sequence of functions. This points to
27613/// one-passed-the-end of the actual sequence.
27614///
27615/// @param b_begin the beginning of the second sequence of functions
27616/// to consider.
27617///
27618/// @param b_end the end of the second sequence of functions.
27619///
27620/// @param o the output stream where to emit the generated list of
27621/// strings to.
27622void
27623fns_to_str(vector<function_decl*>::const_iterator a_begin,
27624 vector<function_decl*>::const_iterator a_end,
27625 vector<function_decl*>::const_iterator b_begin,
27626 vector<function_decl*>::const_iterator b_end,
27627 std::ostream& o)
27628{
27630 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
27631}
27632
27633// </debugging facilities>
27634
27635// </class template>
27636
27637}// end namespace ir
27638}//end namespace abigail
27639
27640namespace
27641{
27642
27643/// Update the qualified parent name, qualified name and scoped name
27644/// of a tree decl node.
27645///
27646/// @return true if the tree walking should continue, false otherwise.
27647///
27648/// @param d the tree node to take in account.
27649bool
27650qualified_name_setter::do_update(abigail::ir::decl_base* d)
27651{
27652 std::string parent_qualified_name;
27653 abigail::ir::scope_decl* parent = d->get_scope();
27654 if (parent)
27655 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
27656 else
27657 d->priv_->qualified_parent_name_ = abigail::interned_string();
27658
27659 const abigail::ir::environment& env = d->get_environment();
27660
27661 if (!d->priv_->qualified_parent_name_.empty())
27662 {
27663 if (d->get_name().empty())
27664 d->priv_->qualified_name_ = abigail::interned_string();
27665 else
27666 d->priv_->qualified_name_ =
27667 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
27668 }
27669
27670 if (d->priv_->scoped_name_.empty())
27671 {
27672 if (parent
27673 && !parent->get_is_anonymous()
27674 && !parent->get_name().empty())
27675 d->priv_->scoped_name_ =
27676 env.intern(parent->get_name() + "::" + d->get_name());
27677 else
27678 d->priv_->scoped_name_ =
27679 env.intern(d->get_name());
27680 }
27681
27682 if (!is_scope_decl(d))
27683 return false;
27684
27685 return true;
27686}
27687
27688/// This is called when we start visiting a decl node, during the
27689/// udpate of the qualified name of a given sub-tree.
27690///
27691/// @param d the decl node we are visiting.
27692///
27693/// @return true iff the traversal should keep going.
27694bool
27695qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
27696{return do_update(d);}
27697
27698/// This is called when we start visiting a type node, during the
27699/// udpate of the qualified name of a given sub-tree.
27700///
27701/// @param d the decl node we are visiting.
27702///
27703/// @return true iff the traversal should keep going.
27704bool
27705qualified_name_setter::visit_begin(abigail::ir::type_base* t)
27706{
27708 return do_update(d);
27709 return false;
27710}
27711}// 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:1612
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:1112
#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:909
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:2496
void set_signed(int64_t v)
Setter of the bound value as signed.
Definition: abg-ir.cc:17575
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:17543
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
Definition: abg-ir.cc:17536
int64_t get_signed_value() const
Getter of the bound value as a signed value.
Definition: abg-ir.cc:17550
bool operator==(const bound_value &) const
Equality operator of the bound value.
Definition: abg-ir.cc:17587
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition: abg-ir.cc:17558
bound_value()
Default constructor of the array_type_def::subrange_type::bound_value class.
Definition: abg-ir.cc:17508
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition: abg-ir.cc:17565
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++.
Definition: abg-ir.h:2481
void set_lower_bound(int64_t lb)
Setter of the lower bound.
Definition: abg-ir.cc:17751
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
Definition: abg-ir.cc:17744
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:17720
string as_string() const
Return a string representation of the sub range.
Definition: abg-ir.cc:17800
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17989
bool is_infinite() const
Test if the length of the subrange type is infinite.
Definition: abg-ir.cc:17778
bool operator!=(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:17928
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition: abg-ir.cc:17730
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:17712
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:17884
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition: abg-ir.cc:17737
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:17967
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
Definition: abg-ir.cc:17823
uint64_t get_length() const
Getter of the length of the subrange type.
Definition: abg-ir.cc:17761
translation_unit::language get_language() const
Getter of the language that generated this type.
Definition: abg-ir.cc:17793
The abstraction of an array type.
Definition: abg-ir.h:2455
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:18395
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition: abg-ir.cc:18326
virtual bool is_infinite() const
Definition: abg-ir.cc:18365
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
Definition: abg-ir.cc:18341
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition: abg-ir.h:2473
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18455
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition: abg-ir.cc:18482
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:18304
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
Definition: abg-ir.h:2476
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:18177
translation_unit::language get_language() const
Get the language of the array.
Definition: abg-ir.cc:18293
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Definition: abg-ir.cc:18351
Abstraction of a base specifier in a class declaration.
Definition: abg-ir.h:4347
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
Definition: abg-ir.cc:23459
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
Definition: abg-ir.cc:23466
long get_offset_in_bits() const
Getter of the offset of the base.
Definition: abg-ir.cc:23473
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:23499
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Definition: abg-ir.cc:23593
virtual size_t get_hash() const
Calculate the hash value for a class_decl::base_spec.
Definition: abg-ir.cc:23480
Abstracts a class declaration.
Definition: abg-ir.h:4150
void is_struct(bool f)
Set the "is-struct" flag of the class.
Definition: abg-ir.cc:23270
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
Definition: abg-ir.cc:24049
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:23339
bool is_struct() const
Test if the class is a struct.
Definition: abg-ir.cc:23277
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition: abg-ir.cc:23294
virtual ~class_decl()
Destructor of the class_decl type.
Definition: abg-ir.cc:24649
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:23255
bool has_vtable() const
Test if the current instance has a vtable.
Definition: abg-ir.cc:24077
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
Definition: abg-ir.cc:24091
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
Definition: abg-ir.cc:24058
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:24565
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
Definition: abg-ir.h:4168
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
Definition: abg-ir.cc:23284
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
Definition: abg-ir.cc:23320
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
Definition: abg-ir.cc:23344
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
Definition: abg-ir.cc:24229
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
Definition: abg-ir.cc:24417
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
Definition: abg-ir.cc:24040
virtual size_t get_hash() const
Return the hash value for the current instance.
Definition: abg-ir.cc:24108
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:23304
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition: abg-ir.h:4169
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:23365
The base type of class_decl and union_decl.
Definition: abg-ir.h:3948
virtual size_t get_num_anonymous_member_classes() const
Get the number of anonymous member classes contained in this class.
Definition: abg-ir.cc:22113
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:22331
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:22264
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
Definition: abg-ir.cc:22359
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
Definition: abg-ir.cc:21999
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition: abg-ir.cc:22435
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
Definition: abg-ir.cc:22098
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
Definition: abg-ir.cc:22131
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
Definition: abg-ir.cc:22449
unordered_map< ssize_t, member_functions > virtual_mem_fn_map_type
Convenience typedef.
Definition: abg-ir.h:3980
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition: abg-ir.h:3979
const data_members & get_data_members() const
Get the data members of this class_or_union.
Definition: abg-ir.cc:22223
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:22180
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:22410
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:22394
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
Definition: abg-ir.cc:22082
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
Definition: abg-ir.cc:22491
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:21987
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:21905
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
Definition: abg-ir.cc:22463
const data_members & get_non_static_data_members() const
Get the non-static data memebers of this class_or_union.
Definition: abg-ir.cc:22314
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:22368
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:22024
vector< var_decl_sptr > data_members
Convenience typedef.
Definition: abg-ir.h:3978
virtual ~class_or_union()
Destrcutor of the class_or_union type.
Definition: abg-ir.cc:21978
bool has_no_member() const
Definition: abg-ir.cc:22476
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:22525
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:24952
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
Definition: abg-ir.cc:22050
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition: abg-ir.cc:22442
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
Definition: abg-ir.cc:22066
vector< type_base_sptr > member_types
Convenience typedef.
Definition: abg-ir.h:3977
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
Definition: abg-ir.cc:22149
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:22234
Abstract a class template.
Definition: abg-ir.h:3751
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition: abg-ir.cc:26339
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
Definition: abg-ir.cc:26328
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26388
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:26343
The abstraction of the relationship between an entity and its containing scope (its context)....
Definition: abg-ir.h:1233
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:701
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
Definition: abg-corpus.cc:733
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:842
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
Definition: abg-corpus.cc:850
const environment & get_environment() const
Getter of the enviroment of the corpus.
Definition: abg-corpus.cc:656
The base type of all declarations.
Definition: abg-ir.h:1525
void set_definition_of_declaration(const decl_base_sptr &)
Set the definition of this declaration-only decl_base.
Definition: abg-ir.cc:15120
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:5105
virtual bool operator!=(const decl_base &) const
Inequality operator.
Definition: abg-ir.cc:5362
scope_decl * get_scope() const
Return the type containing the current decl, if any.
Definition: abg-ir.cc:4934
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
Definition: abg-ir.cc:4643
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:4727
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:5717
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
Definition: abg-ir.cc:5053
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
Definition: abg-ir.cc:4909
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:5089
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition: abg-ir.cc:4965
void clear_qualified_name()
Clear the qualified name of this decl.
Definition: abg-ir.cc:4636
void set_name(const string &n)
Setter for the name of the decl.
Definition: abg-ir.cc:4797
const location & get_location() const
Get the location of a given declaration.
Definition: abg-ir.cc:4747
binding
ELF binding.
Definition: abg-ir.h:1576
typedef_decl_sptr get_naming_typedef() const
Getter for the naming typedef of the current decl.
Definition: abg-ir.cc:4857
const interned_string & get_name() const
Getter for the name of the current decl.
Definition: abg-ir.cc:4953
virtual void set_scope(scope_decl *)
Setter of the scope of the current decl.
Definition: abg-ir.cc:5389
const interned_string & peek_qualified_name() const
Getter for the qualified name.
Definition: abg-ir.cc:4627
const context_rel * get_context_rel() const
Getter for the context relationship.
Definition: abg-ir.cc:4677
friend void set_member_function_is_virtual(function_decl &, bool)
Set the virtual-ness of a member function.
Definition: abg-ir.cc:6712
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Definition: abg-ir.cc:4810
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:8347
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
Definition: abg-ir.cc:5045
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:5073
friend void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5686
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
Definition: abg-ir.cc:4875
void set_location(const location &l)
Set the location for a given declaration.
Definition: abg-ir.cc:4785
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
Definition: abg-ir.cc:4820
void set_visibility(visibility v)
Setter for the visibility of the decl.
Definition: abg-ir.cc:4926
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4670
visibility get_visibility() const
Getter for the visibility of the decl.
Definition: abg-ir.cc:4919
visibility
ELF visibility.
Definition: abg-ir.h:1566
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Definition: abg-ir.cc:5096
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:5378
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition: abg-ir.cc:5061
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition: abg-ir.cc:4902
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5657
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6674
virtual ~decl_base()
Destructor of the decl_base type.
Definition: abg-ir.cc:5366
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:5351
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:4946
bool get_is_anonymous_or_has_anonymous_parent() const
Definition: abg-ir.cc:4843
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
Definition: abg-ir.cc:4832
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:4719
friend bool equals(const decl_base &, const decl_base &, change_kind *)
Compares two instances of decl_base.
Definition: abg-ir.cc:5268
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:4696
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
Definition: abg-ir.cc:4656
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:4988
The abstraction for a data member context relationship. This relates a data member to its parent clas...
Definition: abg-ir.h:2876
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:3158
void set_anonymous_data_member(var_decl *)
Set the containing anonymous data member of this data member context relationship....
Definition: abg-ir.cc:3168
The abstraction of the version of an ELF symbol.
Definition: abg-ir.h:1180
version & operator=(const version &o)
Assign a version to the current one.
Definition: abg-ir.cc:3071
bool operator==(const version &o) const
Compares the current version against another one.
Definition: abg-ir.cc:3053
bool is_default() const
Getter for the 'is_default' property of the version.
Definition: abg-ir.cc:3033
const string & str() const
Getter for the version name.
Definition: abg-ir.cc:3019
bool operator!=(const version &o) const
Inequality operator.
Definition: abg-ir.cc:3062
Abstraction of an elf symbol.
Definition: abg-ir.h:909
const abg_compat::optional< std::string > & get_namespace() const
Getter of the 'namespace' property.
Definition: abg-ir.cc:2156
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:2479
elf_symbol_sptr get_next_common_instance() const
Get the next common instance of the current common symbol.
Definition: abg-ir.cc:2374
type get_type() const
Getter for the type of the current instance of elf_symbol.
Definition: abg-ir.cc:1996
const elf_symbol_sptr get_main_symbol() const
Get the main symbol of an alias chain.
Definition: abg-ir.cc:2211
void set_is_in_ksymtab(bool is_in_ksymtab)
Setter of the 'is-in-ksymtab' property.
Definition: abg-ir.cc:2135
bool has_aliases() const
Check if the current elf_symbol has an alias.
Definition: abg-ir.cc:2240
void set_name(const string &n)
Setter for the name of the current intance of elf_symbol.
Definition: abg-ir.cc:1986
bool is_suppressed() const
Getter for the 'is-suppressed' property.
Definition: abg-ir.cc:2172
binding
The binding of a symbol.
Definition: abg-ir.h:926
int get_number_of_aliases() const
Get the number of aliases to this elf symbol.
Definition: abg-ir.cc:2247
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:2500
void set_binding(binding b)
Setter for the binding of the current instance of elf_symbol.
Definition: abg-ir.cc:2031
void add_common_instance(const elf_symbol_sptr &)
Add a common instance to the current common elf symbol.
Definition: abg-ir.cc:2385
void add_alias(const elf_symbol_sptr &)
Add an alias to the current elf symbol.
Definition: abg-ir.cc:2264
void set_is_suppressed(bool is_suppressed)
Setter for the 'is-suppressed' property.
Definition: abg-ir.cc:2181
bool is_variable() const
Test if the current instance of elf_symbol is a variable symbol or not.
Definition: abg-ir.cc:2119
elf_symbol_sptr update_main_symbol(const std::string &)
Update the main symbol for a group of aliased symbols.
Definition: abg-ir.cc:2310
void set_size(size_t)
Setter of the size of the symbol.
Definition: abg-ir.cc:2017
const string & get_name() const
Getter for the name of the elf_symbol.
Definition: abg-ir.cc:1979
binding get_binding() const
Getter for the binding of the current instance of elf_symbol.
Definition: abg-ir.cc:2024
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:2566
bool is_function() const
Test if the current instance of elf_symbol is a function symbol or not.
Definition: abg-ir.cc:2110
type
The type of a symbol.
Definition: abg-ir.h:913
void set_version(const version &v)
Setter for the version of the current instance of elf_symbol.
Definition: abg-ir.cc:2045
const abg_compat::optional< uint32_t > & get_crc() const
Getter of the 'crc' property.
Definition: abg-ir.cc:2142
void set_visibility(visibility v)
Setter of the visibility of the current instance of elf_symbol.
Definition: abg-ir.cc:2056
bool does_alias(const elf_symbol &) const
Test if the current symbol aliases another one.
Definition: abg-ir.cc:2625
bool is_main_symbol() const
Tests whether this symbol is the main symbol.
Definition: abg-ir.cc:2225
void set_crc(const abg_compat::optional< uint32_t > &crc)
Setter of the 'crc' property.
Definition: abg-ir.cc:2149
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:1902
visibility
The visibility of the symbol.
Definition: abg-ir.h:935
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
Definition: abg-ir.cc:2038
bool is_common_symbol() const
Return true if the symbol is a common one.
Definition: abg-ir.cc:2343
void set_index(size_t)
Setter for the index.
Definition: abg-ir.cc:1972
visibility get_visibility() const
Getter of the visibility of the current instance of elf_symbol.
Definition: abg-ir.cc:2064
bool has_other_common_instances() const
Return true if this common common symbol has other common instances.
Definition: abg-ir.cc:2359
size_t get_index() const
Getter for the index.
Definition: abg-ir.cc:1965
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
Definition: abg-ir.cc:2430
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:2457
const environment & get_environment() const
Getter of the environment used by the current instance of elf_symbol.
Definition: abg-ir.cc:1958
void set_type(type t)
Setter for the type of the current instance of elf_symbol.
Definition: abg-ir.cc:2003
bool is_public() const
Test if the current instance of elf_symbol is public or not.
Definition: abg-ir.cc:2094
bool is_in_ksymtab() const
Getter of the 'is-in-ksymtab' property.
Definition: abg-ir.cc:2127
size_t get_size() const
Getter of the size of the symbol.
Definition: abg-ir.cc:2010
bool is_defined() const
Test if the current instance of elf_symbol is defined or not.
Definition: abg-ir.cc:2072
void set_namespace(const abg_compat::optional< std::string > &ns)
Setter of the 'namespace' property.
Definition: abg-ir.cc:2163
elf_symbol_sptr get_next_alias() const
Get the next alias of the current symbol.
Definition: abg-ir.cc:2232
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:2611
The abstraction of an enumerator.
Definition: abg-ir.h:2768
enumerator()
Default constructor of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:19044
bool operator!=(const enumerator &other) const
Inequality operator.
Definition: abg-ir.cc:19104
void set_name(const string &n)
Setter for the name of enum_type_decl::enumerator.
Definition: abg-ir.cc:19146
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
Definition: abg-ir.cc:19168
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
Definition: abg-ir.cc:19113
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
Definition: abg-ir.cc:19175
void set_value(int64_t v)
Setter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:19161
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:19130
int64_t get_value() const
Getter for the value of enum_type_decl::enumerator.
Definition: abg-ir.cc:19154
bool operator==(const enumerator &other) const
Equality operator.
Definition: abg-ir.cc:19091
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::enumerator type.
Definition: abg-ir.cc:19075
Abstracts a declaration for an enum type.
Definition: abg-ir.h:2686
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition: abg-ir.h:2702
virtual ~enum_type_decl()
Destructor for the enum type declaration.
Definition: abg-ir.cc:18622
const enumerators & get_enumerators() const
Definition: abg-ir.cc:18553
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:18600
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition: abg-ir.cc:18548
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:18965
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:18579
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:3655
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:3722
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:3802
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:3536
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:3754
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
Definition: abg-ir.cc:3587
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:3555
const config & get_config() const
Getter of the general configuration object.
Definition: abg-ir.cc:3792
environment()
Default constructor of the environment type.
Definition: abg-ir.cc:3183
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:3939
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition: abg-ir.cc:3599
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:3962
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:3574
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:3691
virtual ~environment()
Destructor for the environment type.
Definition: abg-ir.cc:3188
interned_string intern(const string &) const
Do intern a string.
Definition: abg-ir.cc:3785
bool do_on_the_fly_canonicalization() const
Getter for the "on-the-fly-canonicalization" flag.
Definition: abg-ir.cc:3622
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:3828
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Definition: abg-ir.cc:3196
Abstraction of a function parameter.
Definition: abg-ir.h:3205
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
Definition: abg-ir.cc:21738
interned_string get_type_name() const
Definition: abg-ir.cc:21527
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
Definition: abg-ir.cc:21565
const string get_type_pretty_representation() const
Definition: abg-ir.cc:21546
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
Definition: abg-ir.cc:21703
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:21723
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:21758
Abstraction for a function declaration.
Definition: abg-ir.h:3033
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3057
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:20920
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
Definition: abg-ir.cc:21014
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:21389
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
Definition: abg-ir.cc:21084
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
Definition: abg-ir.cc:21308
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
Definition: abg-ir.cc:20980
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition: abg-ir.cc:20999
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:20801
const type_base_sptr get_return_type() const
Definition: abg-ir.cc:21065
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
Definition: abg-ir.cc:21097
const std::vector< parameter_sptr > & get_parameters() const
Definition: abg-ir.cc:21070
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
Definition: abg-ir.cc:21077
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
Definition: abg-ir.cc:21036
virtual ~function_decl()
Destructor of the function_decl type.
Definition: abg-ir.cc:21405
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:21052
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
Definition: abg-ir.cc:21294
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3060
virtual size_t get_hash() const
The virtual implementation of 'get_hash' for a function_decl.
Definition: abg-ir.cc:21320
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:20870
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:21336
Abstract a function template declaration.
Definition: abg-ir.h:3702
binding get_binding() const
Get the binding of the function template.
Definition: abg-ir.cc:26176
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
Definition: abg-ir.cc:26158
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition: abg-ir.cc:26169
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:26236
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Definition: abg-ir.cc:26185
Abstraction of a function type.
Definition: abg-ir.h:3309
shared_ptr< function_decl::parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3319
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:20513
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
Definition: abg-ir.cc:20198
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:20409
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:20012
virtual bool operator==(const type_base &) const
Equality operator for function_type.
Definition: abg-ir.cc:20472
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:20183
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
Definition: abg-ir.cc:20160
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
Definition: abg-ir.cc:20429
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:20139
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition: abg-ir.cc:20102
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
Definition: abg-ir.cc:20110
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:20387
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition: abg-ir.cc:20119
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3321
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:20496
This abstracts the global scope of a given translation unit.
Definition: abg-ir.h:1939
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:15586
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
Definition: abg-ir.cc:15609
base_type get_base_type() const
Getter of the base type of the integral_type.
Definition: abg-ir.cc:15572
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:15596
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:15579
integral_type()
Default constructor of the integral_type.
Definition: abg-ir.cc:15542
The base class for the visitor type hierarchy used for traversing a translation unit.
Definition: abg-ir.h:4870
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:27227
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
Definition: abg-ir.cc:27271
void forget_visited_type_nodes()
Un-mark all visited type nodes.
Definition: abg-ir.cc:27261
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
Definition: abg-ir.cc:27206
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
Definition: abg-ir.cc:27237
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:448
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:471
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:413
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:393
Abstraction of a member function context relationship. This relates a member function to its parent c...
Definition: abg-ir.h:4475
bool is_constructor() const
Getter for the 'is-constructor' property.
Definition: abg-ir.h:4553
bool is_const() const
Getter for the 'is-const' property.
Definition: abg-ir.h:4588
size_t vtable_offset() const
Getter for the vtable offset property.
Definition: abg-ir.h:4533
bool is_destructor() const
Getter for the 'is-destructor' property.
Definition: abg-ir.h:4570
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition: abg-ir.h:3797
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition: abg-ir.h:3818
bool get_is_static() const
Definition: abg-ir.h:3830
Abstracts a member class template template.
Definition: abg-ir.h:4676
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
Definition: abg-ir.cc:24812
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:24897
Abstract a member function template.
Definition: abg-ir.h:4621
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:24791
Abstraction of the declaration of a method.
Definition: abg-ir.h:3846
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
Definition: abg-ir.cc:6571
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
Definition: abg-ir.cc:23740
const method_type_sptr get_type() const
Definition: abg-ir.cc:23767
Abstracts the type of a class member function.
Definition: abg-ir.h:3405
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:20700
void set_is_const(bool)
Setter of the "is-const" property of method_type.
Definition: abg-ir.cc:20732
virtual ~method_type()
The destructor of method_type.
Definition: abg-ir.cc:20743
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:20724
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition: abg-ir.cc:20691
bool get_is_const() const
Getter of the "is-const" property of method_type.
Definition: abg-ir.cc:20739
The abstraction of a namespace declaration.
Definition: abg-ir.h:2184
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:16187
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:16218
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
Definition: abg-ir.cc:16121
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
Definition: abg-ir.cc:16173
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:16159
Abstracts non type template parameters.
Definition: abg-ir.h:3579
const type_base_sptr get_type() const
Getter for the type of the template parameter.
Definition: abg-ir.cc:25855
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
Definition: abg-ir.cc:25869
virtual size_t get_hash() const
Get the hash value of the current instance.
Definition: abg-ir.cc:25862
The abstraction of a pointer type.
Definition: abg-ir.h:2324
void set_pointed_to_type(const type_base_sptr &)
Set the pointed-to type of the pointer.
Definition: abg-ir.cc:16851
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:16986
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:16782
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17069
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
Definition: abg-ir.cc:16922
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition: abg-ir.cc:16966
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
Definition: abg-ir.cc:16973
The abstraction of a qualified type.
Definition: abg-ir.h:2213
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:16509
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
Definition: abg-ir.cc:16633
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
Definition: abg-ir.cc:16373
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:16621
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition: abg-ir.h:2232
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:16313
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
Definition: abg-ir.cc:16612
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:16581
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition: abg-ir.cc:16607
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Definition: abg-ir.cc:16626
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
Definition: abg-ir.cc:16453
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
Definition: abg-ir.cc:16290
Abstracts a reference type.
Definition: abg-ir.h:2387
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Build and return the qualified name of the current instance of the reference_type_def.
Definition: abg-ir.cc:17368
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
Definition: abg-ir.cc:17142
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:17434
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:17240
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
Definition: abg-ir.cc:17310
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:17413
A declaration that introduces a scope.
Definition: abg-ir.h:1796
virtual size_t get_num_anonymous_member_classes() const
Getter for the number of anonymous classes contained in this scope.
Definition: abg-ir.cc:7855
void remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
Definition: abg-ir.cc:8035
void insert_member_type(type_base_sptr t, declarations::iterator before)
Insert a member type.
Definition: abg-ir.cc:7994
void add_member_type(type_base_sptr t)
Add a member type to the current instance of class_or_union.
Definition: abg-ir.cc:8010
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
Definition: abg-ir.cc:7873
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
Definition: abg-ir.cc:7908
std::vector< scope_decl_sptr > scopes
Convenience typedef for a vector of scope_decl_sptr.
Definition: abg-ir.h:1807
bool is_empty() const
Test if the current scope is empty.
Definition: abg-ir.cc:7922
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:8317
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
Definition: abg-ir.cc:7969
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:8081
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
Definition: abg-ir.h:1803
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:7791
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:8269
virtual void remove_member_decl(decl_base_sptr member)
Remove a declaration from the current scope.
Definition: abg-ir.cc:8111
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:7938
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:7980
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7815
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:7779
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
Definition: abg-ir.cc:8054
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:8347
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:8223
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7833
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
Definition: abg-ir.cc:7891
virtual size_t get_hash() const
Return the hash value for the current instance of scope_decl.
Definition: abg-ir.cc:8148
A type that introduces a scope.
Definition: abg-ir.h:2158
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:16080
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
Definition: abg-ir.cc:16042
The base class of templates.
Definition: abg-ir.h:3461
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:25523
virtual ~template_decl()
Destructor.
Definition: abg-ir.cc:25548
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:25515
virtual bool operator==(const decl_base &o) const
Equality operator.
Definition: abg-ir.cc:25557
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition: abg-ir.h:3496
virtual ~template_parameter()
Destructor.
Definition: abg-ir.cc:25684
bool operator!=(const template_parameter &) const
Inequality operator.
Definition: abg-ir.cc:25680
Abstracts a template template parameter.
Definition: abg-ir.h:3626
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:25942
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
Definition: abg-ir.h:672
void set_address_size(char)
Setter of the address size in this translation unit.
Definition: abg-ir.cc:1393
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:1308
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:1425
bool operator==(const translation_unit &) const
Compare the current translation unit against another one.
Definition: abg-ir.cc:1435
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
Definition: abg-ir.cc:1351
char get_address_size() const
Getter of the address size in this translation unit.
Definition: abg-ir.cc:1386
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:1289
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
Definition: abg-ir.cc:1335
void set_language(language l)
Setter of the language of the source code of the translation unit.
Definition: abg-ir.cc:1252
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:1461
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
Definition: abg-ir.cc:1188
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
Definition: abg-ir.cc:1375
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:1409
const std::string & get_path() const
Get the path of the current translation unit.
Definition: abg-ir.cc:1265
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:1300
location_manager & get_loc_mgr()
Getter of the location manager for the current translation unit.
Definition: abg-ir.cc:1359
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
Definition: abg-ir.cc:1276
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse virtual function.
Definition: abg-ir.cc:1493
language
The language of the translation unit.
Definition: abg-ir.h:685
bool operator!=(const translation_unit &) const
Inequality operator.
Definition: abg-ir.cc:1450
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:1231
const environment & get_environment() const
Getter of the environment of the current translation_unit.
Definition: abg-ir.cc:1238
const type_maps & get_types() const
Getter of the types of the current translation_unit.
Definition: abg-ir.cc:1215
language get_language() const
Getter of the language of the source code of the translation unit.
Definition: abg-ir.cc:1245
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:1960
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
Definition: abg-ir.cc:15182
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
Definition: abg-ir.cc:15165
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition: abg-ir.cc:15261
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:15287
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:14944
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
Definition: abg-ir.cc:15254
virtual bool operator!=(const type_base &) const
Inequality operator.
Definition: abg-ir.cc:15247
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
Definition: abg-ir.cc:15237
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition: abg-ir.cc:15275
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
Definition: abg-ir.cc:15268
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
Definition: abg-ir.cc:15149
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition: abg-ir.h:3664
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition: abg-ir.cc:26048
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
Definition: abg-ir.cc:26055
virtual size_t get_hash() const
Get the hash value for the current instance.
Definition: abg-ir.cc:26062
A basic type declaration that introduces no scope.
Definition: abg-ir.h:2095
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:15874
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:15953
virtual bool operator!=(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:15812
virtual bool operator==(const type_base &) const
Return true if both types equals.
Definition: abg-ir.cc:15768
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:15933
This is a type that aggregates maps of all the kinds of types that are supported by libabigail.
Definition: abg-ir.h:585
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:591
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:680
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:631
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:549
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:563
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:645
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:577
bool empty() const
Test if the type_maps is empty.
Definition: abg-ir.cc:517
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:604
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:1124
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:617
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:535
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:666
The base class of both types and declarations.
Definition: abg-ir.h:1354
void set_translation_unit(translation_unit *)
Set the translation_unit this ABI artifact belongs to.
Definition: abg-ir.cc:4400
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:4214
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
Definition: abg-ir.cc:4203
location & get_artificial_location() const
Getter of the artificial location of the artifact.
Definition: abg-ir.cc:4360
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
Definition: abg-ir.cc:4367
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
Definition: abg-ir.cc:4392
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
Definition: abg-ir.cc:4237
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:4226
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
Definition: abg-ir.cc:4425
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
Definition: abg-ir.cc:4257
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition: abg-ir.cc:10521
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:4292
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10188
friend pointer_type_def * is_pointer_type(type_or_decl_base *)
Test whether a type is a pointer_type_def.
Definition: abg-ir.cc:10635
bool hashing_started() const
Getter for the 'hashing_started' property.
Definition: abg-ir.cc:4310
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
Definition: abg-ir.cc:4342
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:1368
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
Definition: abg-ir.cc:4324
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
Definition: abg-ir.cc:10261
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Definition: abg-ir.cc:4417
Abstracts a type template parameter.
Definition: abg-ir.h:3542
virtual bool operator==(const type_base &) const
Equality operator.
Definition: abg-ir.cc:25726
The abstraction of a typedef declaration.
Definition: abg-ir.h:2818
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
Definition: abg-ir.cc:19403
virtual size_t get_size_in_bits() const
Return the size of the typedef.
Definition: abg-ir.cc:19258
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19418
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition: abg-ir.cc:19396
virtual bool operator==(const decl_base &) const
Equality operator.
Definition: abg-ir.cc:19338
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
Definition: abg-ir.cc:19275
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:19379
Abstracts a union type declaration.
Definition: abg-ir.h:4405
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:25317
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
Definition: abg-ir.cc:25257
virtual ~union_decl()
Destructor of the union_decl type.
Definition: abg-ir.cc:25390
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:25224
Abstracts a variable declaration.
Definition: abg-ir.h:2930
binding get_binding() const
Getter of the binding of the variable.
Definition: abg-ir.cc:19532
void set_type(type_base_sptr &)
Setter of the type of the variable.
Definition: abg-ir.cc:19514
void set_binding(binding b)
Setter of the binding of the variable.
Definition: abg-ir.cc:19539
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
Definition: abg-ir.cc:6232
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
Definition: abg-ir.cc:19577
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:19840
const type_base * get_naked_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:19525
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6377
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:19507
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Definition: abg-ir.cc:19984
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:19961
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
Definition: abg-ir.cc:19554
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:19570
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
Definition: abg-ir.cc:19765
virtual size_t get_hash() const
Return the hash value for the current instance.
Definition: abg-ir.cc:19807
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:19870
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:19784
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:10802
const type_base * peel_pointer_type(const type_base *type)
Return the leaf pointed-to type node of a pointer_type_def node.
Definition: abg-ir.cc:7130
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 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:18634
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:12871
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:11969
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition: abg-ir.cc:26654
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
Definition: abg-ir.cc:6487
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
Definition: abg-ir.cc:7248
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:26631
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:11320
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:5923
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:6187
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:8364
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:10155
class_decl_sptr is_class_type(const type_or_decl_base_sptr &d)
Test whether a type is a class.
Definition: abg-ir.cc:10539
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:11121
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:5717
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:9797
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:9780
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:865
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:13305
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:12786
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:8879
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
Definition: abg-ir.cc:21371
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
Definition: abg-fwd.h:290
bool maybe_update_types_lookup_map< function_type >(const function_type_sptr &type, istring_type_base_wptrs_map_type &types_map, bool)
This is the specialization for type function_type of the function template:
Definition: abg-ir.cc:13709
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:13199
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
Definition: abg-ir.cc:6712
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition: abg-ir.cc:6611
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:13354
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:12712
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:10503
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
Definition: abg-corpus.cc:1617
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:10837
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:25473
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:23998
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:266
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:18254
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:13053
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
Definition: abg-ir.cc:7550
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:9544
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10248
scope_decl * is_scope_decl(decl_base *d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5587
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:12959
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition: abg-ir.cc:5946
bool is_template_parameter(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter.
Definition: abg-ir.cc:10122
bool is_anonymous_data_member(const var_decl &d)
Test if a var_decl is an anonymous data member.
Definition: abg-ir.cc:6048
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
Definition: abg-ir.cc:1505
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:10370
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:7157
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:24706
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
Definition: abg-ir.cc:5541
scope_decl * get_type_scope(const type_base_sptr &t)
Get the scope of a given type.
Definition: abg-ir.cc:8714
integral_type::modifiers_type operator~(integral_type::modifiers_type l)
Bitwise one's complement operator for integral_type::modifiers_type.
Definition: abg-ir.cc:15344
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:11226
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition: abg-ir.h:874
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:13141
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
Definition: abg-ir.cc:6644
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:12596
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:9694
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
Definition: abg-ir.cc:26726
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:12311
location get_location(const decl_base_sptr &decl)
Get the location of a given declaration.
Definition: abg-ir.cc:8676
const typedef_decl * is_typedef(const type_or_decl_base *t)
Test whether a type is a typedef.
Definition: abg-ir.cc:10420
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
Definition: abg-ir.cc:8371
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:7321
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:9862
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
Definition: abg-ir.cc:7483
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:13084
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
Definition: abg-ir.h:1309
@ LOCAL_TYPE_CHANGE_KIND
This means that a given IR artifact has a local type change.
Definition: abg-ir.h:1313
@ 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:1329
@ 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:1318
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:27174
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:5860
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:12331
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:10596
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
Definition: abg-ir.cc:5621
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:1688
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:6132
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:11346
void unmark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being not compared anymore.
Definition: abg-ir.cc:966
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:9847
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:10625
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition: abg-ir.cc:10512
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:14243
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition: abg-fwd.h:237
method_type * is_method_type(type_or_decl_base *t)
Test whether a type is a method_type.
Definition: abg-ir.cc:10933
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:12621
pointer_type_def_sptr is_pointer_type(const type_or_decl_base_sptr &t)
Test whether a type is a pointer_type_def.
Definition: abg-ir.cc:10666
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:13259
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:10553
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:13582
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:9198
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:13224
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:7270
array_type_def * is_array_type(const type_or_decl_base *type)
Test if a type is an array_type_def.
Definition: abg-ir.cc:11148
reference_type_def * is_reference_type(type_or_decl_base *t)
Test whether a type is a reference_type_def.
Definition: abg-ir.cc:10742
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:13475
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:6091
type_decl * is_integral_type(const type_or_decl_base *t)
Test if a type is an integral type.
Definition: abg-ir.cc:10350
translation_unit * get_translation_unit(const shared_ptr< decl_base > decl)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:9984
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:6147
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition: abg-ir.cc:6515
const function_type * is_function_type(const type_or_decl_base *t)
Test whether a type is a function_type.
Definition: abg-ir.cc:10903
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
Definition: abg-ir.cc:7206
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:26870
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
Definition: abg-fwd.h:315
enum_type_decl_sptr look_through_decl_only_enum(enum_type_decl_sptr enom)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
Definition: abg-ir.cc:10983
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:10586
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:5884
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:7344
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:6571
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:8615
bool is_anonymous_type(const type_base_sptr &t)
Test if a given type is anonymous.
Definition: abg-ir.cc:10324
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:6899
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:867
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:2878
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:11103
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:11182
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:10332
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10228
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:10992
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:10883
scope_decl_sptr is_scope_decl(const decl_base_sptr &d)
Test if a declaration is a scope_decl.
Definition: abg-ir.cc:5597
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:8583
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5686
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition: abg-ir.cc:10390
type_base_sptr is_type(const type_or_decl_base_sptr &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10276
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
Definition: abg-ir.cc:6349
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
Definition: abg-ir.cc:9566
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:14326
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:2750
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:7101
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:19638
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:12571
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:3516
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:7446
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:10239
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
Definition: abg-corpus.cc:1603
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:2959
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
Definition: abg-ir.cc:1651
const type_base * peel_reference_type(const type_base *type)
Return the leaf pointed-to type node of a reference_type_def node.
Definition: abg-ir.cc:7186
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:10453
bool is_typedef_to_decl_only_class_or_union_type(const type_or_decl_base *t)
Test if a type is a typedef to a decl-only class/union.
Definition: abg-ir.cc:10721
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:10178
bool is_pointer_to_decl_only_class_or_union_type(const type_or_decl_base *t)
Test if a type is a pointer to a decl-only class/union.
Definition: abg-ir.cc:10675
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:10963
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:12824
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:6600
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
Definition: abg-ir.cc:15527
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:7074
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:8391
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:3179
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:10462
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:26818
bool elf_symbols_alias(const elf_symbol &s1, const elf_symbol &s2)
Test if two symbols alias.
Definition: abg-ir.cc:2681
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:10091
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition: abg-fwd.h:249
const location & get_natural_or_artificial_location(const decl_base *decl)
Get the non-artificial (natural) location of a decl.
Definition: abg-ir.cc:9707
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:8652
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:1016
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:26552
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
Definition: abg-corpus.cc:1631
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:27511
bool is_template_decl(const decl_base_sptr &decl)
Tests whether a decl is a template.
Definition: abg-ir.cc:11249
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:12918
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:2911
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
namespace_decl * is_namespace(const decl_base *d)
Tests if a declaration is a namespace declaration.
Definition: abg-ir.cc:11112
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:7407
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:10775
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
Definition: abg-ir.cc:11255
bool try_canonical_compare(const T *l, const T *r)
Compare two types by comparing their canonical types if present.
Definition: abg-ir.cc:818
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:26489
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:245
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
Definition: abg-ir.cc:1665
function_decl::parameter * is_function_parameter(const type_or_decl_base *tod)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10165
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:12731
class_or_union * is_at_class_scope(const decl_base &decl)
Tests whether a given decl is at class scope.
Definition: abg-ir.cc:10071
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
Definition: abg-ir.cc:5268
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6377
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:12278
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:2936
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:11583
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
Definition: abg-ir.cc:15034
weak_ptr< elf_symbol > elf_symbol_wptr
A convenience typedef for a weak pointer to elf_symbol.
Definition: abg-ir.h:877
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition: abg-ir.cc:6543
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:8916
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:13739
pointer_type_def * is_pointer_type(type_or_decl_base *t)
Test whether a type is a pointer_type_def.
Definition: abg-ir.cc:10635
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:9135
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:1575
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:10471
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:13529
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:6262
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
Definition: abg-ir.cc:6306
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:6401
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:27106
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:11084
string get_pretty_representation(const method_type_sptr method, bool internal)
Get the pretty representation of a method type.
Definition: abg-ir.cc:9400
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
Definition: abg-ir.cc:1637
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10188
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:26527
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:23829
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition: abg-ir.cc:5606
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:9420
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:11239
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:8347
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:27128
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5657
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:6200
const interned_string & get_node_name(var_decl_sptr node)
Gets the name of a var_decl node.
Definition: abg-ir.cc:12036
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:6764
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition: abg-ir.cc:6217
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:10340
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:10048
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
Definition: abg-ir.cc:6674
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:9953
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:6063
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
Definition: abg-ir.cc:8663
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:8993
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:11135
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:10943
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:10605
const location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
Definition: abg-ir.cc:9726
bool is_global_scope(const shared_ptr< scope_decl >scope)
Tests whether if a given scope is the global scope.
Definition: abg-ir.cc:10012
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:13179
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:7047
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:8946
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
Definition: abg-fwd.h:307
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
Definition: abg-ir.cc:11205
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:8553
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:6363
array_type_def_sptr is_array_type(const type_or_decl_base_sptr &type)
Test if a type is an array_type_def.
Definition: abg-ir.cc:11157
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition: abg-ir.cc:5755
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:27153
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition: abg-ir.cc:9881
bool is_at_global_scope(const decl_base *decl)
Tests whether a given declaration is at global scope.
Definition: abg-ir.cc:10039
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:24952
weak_ptr< template_decl > template_decl_wptr
Convenience typedef for a weak pointer to template_decl.
Definition: abg-fwd.h:310
const var_decl * lookup_data_member(const type_base *type, const char *dm_name)
Look for a data member of a given class, struct or union type and return it.
Definition: abg-ir.cc:27084
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:8469
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
Definition: abg-ir.cc:7525
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:13404
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
Definition: abg-fwd.h:285
var_decl_sptr is_var_decl(const type_or_decl_base_sptr &decl)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:11094
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
Definition: abg-ir.cc:1674
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
Definition: abg-ir.cc:14400
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition: abg-ir.cc:26691
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:14143
void mark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being compared.
Definition: abg-ir.cc:931
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:8732
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:330
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
Definition: abg-corpus.cc:1645
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:7603
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:9030
decl_base_sptr is_decl(const type_or_decl_base_sptr &d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10217
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:1707
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:8894
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
Definition: abg-ir.cc:10113
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10136
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:2969
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:26511
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:13647
reference_type_def_sptr is_reference_type(const type_or_decl_base_sptr &t)
Test whether a type is a reference_type_def.
Definition: abg-ir.cc:10762
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:10913
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:10863
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:8540
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:895
interned_string get_function_id_or_pretty_representation(function_decl *fn)
Get the ID of a function, or, if the ID can designate several different functions,...
Definition: abg-ir.cc:9072
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:8629
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:22827
bool is_reference_to_decl_only_class_or_union_type(const type_or_decl_base *t)
Test if a type is a reference to a decl-only class/union.
Definition: abg-ir.cc:10698
decl_base_sptr get_type_declaration(const type_base_sptr t)
Get the declaration for a given type.
Definition: abg-ir.cc:9899
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
Definition: abg-fwd.h:295
type_base * peel_qualified_or_typedef_type(const type_base *type)
Return the leaf underlying type of a qualified or typedef type.
Definition: abg-ir.cc:7293
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:14430
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:12886
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition: abg-ir.cc:5559
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:5169
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:10873
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition: abg-ir.cc:6428
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:6458
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:10575
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:13016
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:11068
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:7718
The hashing functor for class_decl::base_spec.
Definition: abg-ir.h:4803
Hasher for the class_decl type.
Definition: abg-ir.h:4308
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:4769
A hashing functor for a function_decl::parameter.
Definition: abg-ir.h:3287
Equality functor for instances of function_decl.
Definition: abg-ir.h:4779
The hashing functor for function_type.
Definition: abg-ir.h:3392
The type of the private data of the function_type type.
Definition: abg-ir-priv.h:1521
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:27189
The hashing functor for member_base.
Definition: abg-ir.h:4810
Hasher for the non_type_tparameter type.
Definition: abg-ir.h:3614
Hasher for the scope_decl type.
Definition: abg-ir.h:1925
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:3691
A predicate for deep equality of instances of shared_ptr<type_base>
Definition: abg-ir.h:2073
A hashing functor for instances and pointers of var_decl.
Definition: abg-ir.h:4738
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.