libabigail
Loading...
Searching...
No Matches
abg-ir.cc
Go to the documentation of this file.
1// C++ -*-
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// -*- Mode: C++ -*-
4
5// Copyright (C) 2013-2024 Red Hat, Inc.
6//
7//Author: Dodji Seketeli
8
9/// @file
10///
11/// Definitions for the Internal Representation artifacts of libabigail.
12
13#include <cxxabi.h>
14#include <cstdint>
15#include <functional>
16#include <iterator>
17#include <memory>
18#include <sstream>
19#include <typeinfo>
20#include <unordered_map>
21#include <utility>
22#include <vector>
23
24#include "abg-internal.h"
25// <headers defining libabigail's API go under here>
26ABG_BEGIN_EXPORT_DECLARATIONS
27
28#include "abg-interned-str.h"
29#include "abg-ir.h"
30#include "abg-corpus.h"
31#include "abg-regex.h"
32
33ABG_END_EXPORT_DECLARATIONS
34// </headers defining libabigail's API>
35
36#include "abg-corpus-priv.h"
37#include "abg-comp-filter.h"
38#include "abg-ir-priv.h"
39
40namespace
41{
42/// This internal type is a tree walking that is used to set the
43/// qualified name of a tree of decls and types. It used by the
44/// function update_qualified_name().
45class qualified_name_setter : public abigail::ir::ir_node_visitor
46{
47
48public:
49 bool
50 do_update(abigail::ir::decl_base* d);
51
52 bool
53 visit_begin(abigail::ir::decl_base* d);
54
55 bool
56 visit_begin(abigail::ir::type_base* d);
57}; // end class qualified_name_setter
58
59}// end anon namespace
60
61namespace abigail
62{
63
64// Inject.
65using std::string;
66using std::list;
67using std::vector;
68using std::unordered_map;
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
71
72/// Convenience typedef for a map of string -> string*.
73typedef unordered_map<string, string*> pool_map_type;
74
75/// The type of the private data structure of type @ref
76/// intered_string_pool.
77struct interned_string_pool::priv
78{
79 pool_map_type map;
80}; //end struc struct interned_string_pool::priv
81
82/// Default constructor.
84 : priv_(new priv)
85{
86 priv_->map[""] = 0;
87}
88
89/// Test if the interned string pool already contains a string with a
90/// given value.
91///
92/// @param s the string to test for.
93///
94/// @return true if the pool contains a string with the value @p s.
95bool
97{return priv_->map.find(s) != priv_->map.end();}
98
99/// Get a pointer to the interned string which has a given value.
100///
101/// @param s the value of the interned string to look for.
102///
103/// @return a pointer to the raw string of characters which has the
104/// value of @p s. Or null if no string with value @p s was interned.
105const char*
107{
108 unordered_map<string, string*>::const_iterator i =
109 priv_->map.find(s);
110 if (i == priv_->map.end())
111 return 0;
112 if (i->second)
113 return i->second->c_str();
114 return "";
115}
116
117/// Create an interned string with a given value.
118///
119/// @param str_value the value of the interned string to create.
120///
121/// @return the new created instance of @ref interned_string created.
123interned_string_pool::create_string(const std::string& str_value)
124{
125 string*& result = priv_->map[str_value];
126 if (!result && !str_value.empty())
127 result = new string(str_value);
128 return interned_string(result);
129}
130
131/// Destructor.
133{
134 for (pool_map_type::iterator i = priv_->map.begin();
135 i != priv_->map.end();
136 ++i)
137 if (i->second)
138 delete i->second;
139}
140
141/// Equality operator.
142///
143/// @param l the instance of std::string on the left-hand-side of the
144/// equality operator.
145///
146/// @param r the instance of @ref interned_string on the
147/// right-hand-side of the equality operator.
148///
149/// @return true iff the two string are equal.
150bool
151operator==(const std::string& l, const interned_string& r)
152{return r.operator==(l);}
153
154bool
155operator!=(const std::string& l, const interned_string& r)
156{return !(l == r);}
157
158/// Streaming operator.
159///
160/// Streams an instance of @ref interned_string to an output stream.
161///
162/// @param o the destination output stream.
163///
164/// @param s the instance of @ref interned_string to stream out.
165///
166/// @return the output stream this function just streamed to.
167std::ostream&
168operator<<(std::ostream& o, const interned_string& s)
169{
170 o << static_cast<std::string>(s);
171 return o;
172}
173
174/// Concatenation operator.
175///
176/// Concatenate two instances of @ref interned_string, builds an
177/// instance of std::string with the resulting string and return it.
178///
179/// @param s1 the first string to consider.
180///
181/// @param s2 the second string to consider.
182///
183/// @return the resuting concatenated string.
184std::string
185operator+(const interned_string& s1,const std::string& s2)
186{return static_cast<std::string>(s1) + s2;}
187
188/// Concatenation operator.
189///
190/// Concatenate two instances of @ref interned_string, builds an
191/// instance of std::string with the resulting string and return it.
192///
193/// @param s1 the first string to consider.
194///
195/// @param s2 the second string to consider.
196///
197/// @return the resuting concatenated string.
198std::string
199operator+(const std::string& s1, const interned_string& s2)
200{return s1 + static_cast<std::string>(s2);}
201
202namespace ir
203{
204
205static size_t
206hash_as_canonical_type_or_constant(const type_base *t);
207
208static bool
209has_generic_anonymous_internal_type_name(const decl_base *d);
210
211static interned_string
212get_generic_anonymous_internal_type_name(const decl_base *d);
213
214static string
215get_internal_real_type_name(const type_base*);
216
217static void
218update_qualified_name(decl_base * d);
219
220static void
221update_qualified_name(decl_base_sptr d);
222
223static interned_string
224pointer_declaration_name(const type_base* ptr,
225 const string& variable_name,
226 bool qualified, bool internal);
227
228static interned_string
229pointer_declaration_name(const type_base_sptr& ptr,
230 const string& variable_name,
231 bool qualified, bool internal);
232
233static interned_string
234ptr_to_mbr_declaration_name(const ptr_to_mbr_type* ptr,
235 const string& variable_name,
236 bool qualified, bool internal);
237
238static interned_string
239ptr_to_mbr_declaration_name(const ptr_to_mbr_type_sptr& ptr,
240 const string& variable_name,
241 bool qualified, bool internal);
242
243static interned_string
244array_declaration_name(const array_type_def* array,
245 const string& variable_name,
246 bool qualified, bool internal);
247
248static interned_string
249array_declaration_name(const array_type_def_sptr& array,
250 const string& variable_name,
251 bool qualified, bool internal);
252
253static void
254stream_pretty_representation_of_fn_parms(const function_type& fn_type,
255 ostream& o, bool qualified,
256 bool internal);
257static string
258add_outer_pointer_to_fn_type_expr(const type_base* pointer_to_fn,
259 const string& input, bool qualified,
260 bool internal);
261
262static string
263add_outer_pointer_to_fn_type_expr(const type_base_sptr& pointer_to_fn,
264 const string& input, bool qualified,
265 bool internal);
266
267static string
268add_outer_pointer_to_array_type_expr(const type_base* pointer_to_ar,
269 const string& input, bool qualified,
270 bool internal);
271
272static string
273add_outer_pointer_to_array_type_expr(const type_base_sptr& pointer_to_ar,
274 const string& input, bool qualified,
275 bool internal);
276
277static string
278add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type* p,
279 const string& input, bool qualified,
280 bool internal);
281
282static string
283add_outer_ptr_to_mbr_type_expr(const ptr_to_mbr_type_sptr& p,
284 const string& input, bool qualified,
285 bool internal);
286
287static string
288add_outer_pointer_to_ptr_to_mbr_type_expr(const type_base* p,
289 const string& input,
290 bool qualified, bool internal);
291
292void
293push_composite_type_comparison_operands(const type_base& left,
294 const type_base& right);
295
296void
297pop_composite_type_comparison_operands(const type_base& left,
298 const type_base& right);
299
300
301/// Push a pair of operands on the stack of operands of the current
302/// type comparison, during type canonicalization.
303///
304/// For more information on this, please look at the description of
305/// the environment::priv::right_type_comp_operands_ data member.
306///
307/// @param left the left-hand-side comparison operand to push.
308///
309/// @param right the right-hand-side comparison operand to push.
310void
312 const type_base& right)
313{
314 const environment& env = left.get_environment();
315 env.priv_->push_composite_type_comparison_operands(&left, &right);
316}
317
318/// Pop a pair of operands from the stack of operands to the current
319/// type comparison.
320///
321/// For more information on this, please look at the description of
322/// the environment::privright_type_comp_operands_ data member.
323///
324/// @param left the left-hand-side comparison operand we expect to
325/// pop from the top of the stack. If this doesn't match the
326/// operand found on the top of the stack, the function aborts.
327///
328/// @param right the right-hand-side comparison operand we expect to
329/// pop from the bottom of the stack. If this doesn't match the
330/// operand found on the top of the stack, the function aborts.
331void
333 const type_base& right)
334{
335 const environment& env = left.get_environment();
336 env.priv_->pop_composite_type_comparison_operands(&left, &right);
337}
338
339/// Getter of the canonical type index of a given type.
340///
341/// @param t the type to consider.
342///
343/// @return the CTI of the type.
344size_t
346{return t.priv_->canonical_type_index;}
347
348/// Getter of the canonical type index of a given type.
349///
350/// @param t the type to consider.
351///
352/// @return the CTI of the type.
353size_t
356
357/// Getter of the canonical type index of a given type.
358///
359/// @param t the type to consider.
360///
361/// @return the CTI of the type.
362size_t
363get_canonical_type_index(const type_base_sptr& t)
364{return get_canonical_type_index(t.get());}
365
366/// Test if a type originates from a corpus.
367///
368/// Note that this function supports testing if a type originates from
369/// a corpus group.
370///
371/// @param t the type to consider.
372///
373/// @param c the corpus or corpus group to consider.
374///
375/// @return true iff the type @p t originates from the corpus (or
376/// group) @p c.
377bool
378type_originates_from_corpus(type_base_sptr t, corpus_sptr& c)
379{
380 bool result = false;
381 if (c && t->get_corpus())
382 {
383 corpus_group_sptr g = is_corpus_group(c);
384 if (g)
385 {
386 if (t->get_corpus()->get_group() == g.get())
387 result = true;
388 }
389 else
390 {
391 if (t->get_corpus() == c.get())
392 result = true;
393 }
394 }
395 return result;
396}
397/// @brief the location of a token represented in its simplest form.
398/// Instances of this type are to be stored in a sorted vector, so the
399/// type must have proper relational operators.
400class expanded_location
401{
402 string path_;
403 unsigned line_;
404 unsigned column_;
405
406 expanded_location();
407
408public:
409
410 friend class location_manager;
411
412 expanded_location(const string& path, unsigned line, unsigned column)
413 : path_(path), line_(line), column_(column)
414 {}
415
416 bool
417 operator==(const expanded_location& l) const
418 {
419 return (path_ == l.path_
420 && line_ == l.line_
421 && column_ && l.column_);
422 }
423
424 bool
425 operator<(const expanded_location& l) const
426 {
427 if (path_ < l.path_)
428 return true;
429 else if (path_ > l.path_)
430 return false;
431
432 if (line_ < l.line_)
433 return true;
434 else if (line_ > l.line_)
435 return false;
436
437 return column_ < l.column_;
438 }
439};
440
441/// Expand the location into a tripplet path, line and column number.
442///
443/// @param path the output parameter where this function sets the
444/// expanded path.
445///
446/// @param line the output parameter where this function sets the
447/// expanded line.
448///
449/// @param column the ouptut parameter where this function sets the
450/// expanded column.
451void
452location::expand(std::string& path, unsigned& line, unsigned& column) const
453{
454 if (!get_location_manager())
455 {
456 // We don't have a location manager maybe because this location
457 // was just freshly instanciated. We still want to be able to
458 // expand to default values.
459 path = "";
460 line = 0;
461 column = 0;
462 return;
463 }
464 get_location_manager()->expand_location(*this, path, line, column);
465}
466
467
468/// Expand the location into a string.
469///
470/// @return the string representing the location.
471string
473{
474 string path, result;
475 unsigned line = 0, column = 0;
476 expand(path, line, column);
477
478 std::ostringstream o;
479 o << path << ":" << line << ":" << column;
480 return o.str();
481}
482
483struct location_manager::priv
484{
485 /// This sorted vector contains the expanded locations of the tokens
486 /// coming from a given ABI Corpus. The index of a given expanded
487 /// location in the table gives us an integer that is used to build
488 /// instance of location types.
489 std::vector<expanded_location> locs;
490};
491
492location_manager::location_manager()
493 : priv_(new location_manager::priv)
494{}
495
496location_manager::~location_manager() = default;
497
498/// Insert the triplet representing a source locus into our internal
499/// vector of location triplet. Return an instance of location type,
500/// built from an real type that represents the index of the
501/// source locus triplet into our source locus table.
502///
503/// @param file_path the file path of the source locus
504/// @param line the line number of the source location
505/// @param col the column number of the source location
506location
507location_manager::create_new_location(const std::string& file_path,
508 size_t line,
509 size_t col)
510{
511 expanded_location l(file_path, line, col);
512
513 // Just append the new expanded location to the end of the vector
514 // and return its index. Note that indexes start at 1.
515 priv_->locs.push_back(l);
516 return location(priv_->locs.size(), this);
517}
518
519/// Given an instance of location type, return the triplet
520/// {path,line,column} that represents the source locus. Note that
521/// the location must have been previously created from the function
522/// location_manager::create_new_location, otherwise this function yields
523/// unexpected results, including possibly a crash.
524///
525/// @param location the instance of location type to expand
526/// @param path the resulting path of the source locus
527/// @param line the resulting line of the source locus
528/// @param column the resulting colum of the source locus
529void
531 std::string& path,
532 unsigned& line,
533 unsigned& column) const
534{
535 if (location.value_ == 0)
536 return;
537 expanded_location &l = priv_->locs[location.value_ - 1];
538 path = l.path_;
539 line = l.line_;
540 column = l.column_;
541}
542
543typedef unordered_map<function_type_sptr,
544 bool,
546 type_shared_ptr_equal> fn_type_ptr_map;
547
548// <type_maps stuff>
549
550struct type_maps::priv
551{
552 mutable istring_type_base_wptrs_map_type basic_types_;
553 mutable istring_type_base_wptrs_map_type class_types_;
554 mutable istring_type_base_wptrs_map_type union_types_;
555 mutable istring_type_base_wptrs_map_type enum_types_;
556 mutable istring_type_base_wptrs_map_type typedef_types_;
557 mutable istring_type_base_wptrs_map_type qualified_types_;
558 mutable istring_type_base_wptrs_map_type pointer_types_;
559 mutable istring_type_base_wptrs_map_type ptr_to_mbr_types_;
560 mutable istring_type_base_wptrs_map_type reference_types_;
561 mutable istring_type_base_wptrs_map_type array_types_;
562 mutable istring_type_base_wptrs_map_type subrange_types_;
563 mutable istring_type_base_wptrs_map_type function_types_;
564 mutable vector<type_base_wptr> sorted_types_;
565}; // end struct type_maps::priv
566
567type_maps::type_maps()
568 : priv_(new priv)
569{}
570
571type_maps::~type_maps() = default;
572
573/// Test if the type_maps is empty.
574///
575/// @return true iff the type_maps is empty.
576bool
578{
579 return (basic_types().empty()
580 && class_types().empty()
581 && union_types().empty()
582 && enum_types().empty()
583 && typedef_types().empty()
585 && pointer_types().empty()
587 && array_types().empty()
588 && subrange_types().empty()
589 && function_types().empty());
590}
591
592/// Getter for the map that associates the name of a basic type to the
593/// vector instances of type_decl_sptr that represents that type.
596{return priv_->basic_types_;}
597
598/// Getter for the map that associates the name of a basic type to the
599/// vector of instances of @ref type_decl_sptr that represents that
600/// type.
603{return priv_->basic_types_;}
604
605/// Getter for the map that associates the name of a class type to the
606/// vector of instances of @ref class_decl_sptr that represents that
607/// type.
610{return priv_->class_types_;}
611
612/// Getter for the map that associates the name of a class type to the
613/// vector of instances of @ref class_decl_sptr that represents that
614/// type.
617{return priv_->class_types_;}
618
619/// Getter for the map that associates the name of a union type to the
620/// vector of instances of @ref union_decl_sptr that represents that
621/// type.
624{return priv_->union_types_;}
625
626/// Getter for the map that associates the name of a union type to the
627/// vector of instances of @ref union_decl_sptr that represents that
628/// type.
631{return priv_->union_types_;}
632
633/// Getter for the map that associates the name of an enum type to the
634/// vector of instances of @ref enum_type_decl_sptr that represents
635/// that type.
638{return priv_->enum_types_;}
639
640/// Getter for the map that associates the name of an enum type to the
641/// vector of instances of @ref enum_type_decl_sptr that represents
642/// that type.
645{return priv_->enum_types_;}
646
647/// Getter for the map that associates the name of a typedef to the
648/// vector of instances of @ref typedef_decl_sptr that represents tha
649/// type.
652{return priv_->typedef_types_;}
653
654/// Getter for the map that associates the name of a typedef to the
655/// vector of instances of @ref typedef_decl_sptr that represents tha
656/// type.
659{return priv_->typedef_types_;}
660
661/// Getter for the map that associates the name of a qualified type to
662/// the vector of instances of @ref qualified_type_def_sptr.
665{return priv_->qualified_types_;}
666
667/// Getter for the map that associates the name of a qualified type to
668/// the vector of instances of @ref qualified_type_def_sptr.
671{return priv_->qualified_types_;}
672
673/// Getter for the map that associates the name of a pointer type to
674/// the vector of instances of @ref pointer_type_def_sptr that
675/// represents that type.
678{return priv_->pointer_types_;}
679
680/// Getter for the map that associates the name of a pointer-to-member
681/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
682/// represents that type.
685{return priv_->ptr_to_mbr_types_;}
686
687/// Getter for the map that associates the name of a pointer-to-member
688/// type to the vector of instances of @ref ptr_to_mbr_type_sptr that
689/// represents that type.
692{return priv_->ptr_to_mbr_types_;}
693
694/// Getter for the map that associates the name of a pointer type to
695/// the vector of instances of @ref pointer_type_def_sptr that
696/// represents that type.
699{return priv_->pointer_types_;}
700
701/// Getter for the map that associates the name of a reference type to
702/// the vector of instances of @ref reference_type_def_sptr that
703/// represents that type.
706{return priv_->reference_types_;}
707
708/// Getter for the map that associates the name of a reference type to
709/// the vector of instances of @ref reference_type_def_sptr that
710/// represents that type.
713{return priv_->reference_types_;}
714
715/// Getter for the map that associates the name of an array type to
716/// the vector of instances of @ref array_type_def_sptr that
717/// represents that type.
720{return priv_->array_types_;}
721
722/// Getter for the map that associates the name of an array type to
723/// the vector of instances of @ref array_type_def_sptr that
724/// represents that type.
727{return priv_->array_types_;}
728
729/// Getter for the map that associates the name of a subrange type to
730/// the vector of instances of @ref array_type_def::subrange_sptr that
731/// represents that type.
734{return priv_->subrange_types_;}
735
736/// Getter for the map that associates the name of a subrange type to
737/// the vector of instances of @ref array_type_def::subrange_sptr that
738/// represents that type.
741{return priv_->subrange_types_;}
742
743/// Getter for the map that associates the name of a function type to
744/// the vector of instances of @ref function_type_sptr that represents
745/// that type.
748{return priv_->function_types_;}
749
750/// Getter for the map that associates the name of a function type to
751/// the vector of instances of @ref function_type_sptr that represents
752/// that type.
755{return priv_->function_types_;}
756
757/// A comparison functor to compare/sort types based on their pretty
758/// representations.
759struct type_name_comp
760{
761 /// Comparison operator for two instances of @ref type_base.
762 ///
763 /// This compares the two types by lexicographically comparing their
764 /// pretty representation.
765 ///
766 /// @param l the left-most type to compare.
767 ///
768 /// @param r the right-most type to compare.
769 ///
770 /// @return true iff @p l < @p r.
771 bool
772 operator()(type_base *l, type_base *r) const
773 {
774 if (l == 0 && r == 0)
775 return false;
776
777 string l_repr = get_pretty_representation(l);
778 string r_repr = get_pretty_representation(r);
779 return l_repr < r_repr;
780 }
781
782 /// Comparison operator for two instances of @ref type_base.
783 ///
784 /// This compares the two types by lexicographically comparing their
785 /// pretty representation.
786 ///
787 /// @param l the left-most type to compare.
788 ///
789 /// @param r the right-most type to compare.
790 ///
791 /// @return true iff @p l < @p r.
792 bool
793 operator()(const type_base_sptr &l, const type_base_sptr &r) const
794 {return operator()(l.get(), r.get());}
795
796 /// Comparison operator for two instances of @ref type_base.
797 ///
798 /// This compares the two types by lexicographically comparing their
799 /// pretty representation.
800 ///
801 /// @param l the left-most type to compare.
802 ///
803 /// @param r the right-most type to compare.
804 ///
805 /// @return true iff @p l < @p r.
806 bool
807 operator()(const type_base_wptr &l, const type_base_wptr &r) const
808 {return operator()(type_base_sptr(l), type_base_sptr(r));}
809}; // end struct type_name_comp
810
811#ifdef WITH_DEBUG_SELF_COMPARISON
812
813/// This is a function called when the ABG_RETURN* macros defined
814/// below return false.
815///
816/// The purpose of this function is to ease debugging. To know where
817/// the equality functions first compare non-equal, we can just set a
818/// breakpoint on this notify_equality_failed function and run the
819/// equality functions. Because all the equality functions use the
820/// ABG_RETURN* macros to return their values, this function is always
821/// called when any of those equality function return false.
822///
823/// @param l the first operand of the equality.
824///
825/// @param r the second operand of the equality.
826static void
827notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
828 const type_or_decl_base &r __attribute__((unused)))
829{}
830
831/// This is a function called when the ABG_RETURN* macros defined
832/// below return false.
833///
834/// The purpose of this function is to ease debugging. To know where
835/// the equality functions first compare non-equal, we can just set a
836/// breakpoint on this notify_equality_failed function and run the
837/// equality functions. Because all the equality functions use the
838/// ABG_RETURN* macros to return their values, this function is always
839/// called when any of those equality function return false.
840///
841/// @param l the first operand of the equality.
842///
843/// @param r the second operand of the equality.
844static void
845notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
846 const type_or_decl_base *r __attribute__((unused)))
847{}
848
849#define ABG_RETURN_EQUAL(l, r) \
850 do \
851 { \
852 if (l != r) \
853 notify_equality_failed(l, r); \
854 return (l == r); \
855 } \
856 while(false)
857
858
859#define ABG_RETURN_FALSE \
860 do \
861 { \
862 notify_equality_failed(l, r); \
863 return false; \
864 } while(false)
865
866#define ABG_RETURN(value) \
867 do \
868 { \
869 if (value == false) \
870 notify_equality_failed(l, r); \
871 return value; \
872 } while (false)
873
874#else // WITH_DEBUG_SELF_COMPARISON
875
876#define ABG_RETURN_FALSE return false
877#define ABG_RETURN(value) return (value)
878#define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
879#endif
880
881/// Get the canonical type of a given type T* as a T*.
882///
883/// Note that normally, canonical types are returned as @ref
884/// type_base* (un-typed form, kind of). This function returns the
885/// canonical type as a T*, just like the T* it is looking at.
886///
887///
888/// @param t the type to consider.
889///
890/// @return either the canonical type of @p t or @p t itself if it
891/// doesn't have any canonical type.
892template<typename T>
893T*
895{
896 if (!t)
897 return nullptr;
898 if (type_base* type = t->get_naked_canonical_type())
899 return dynamic_cast<T*>(type);
900 return t;
901}
902
903/// Compare two types by comparing their canonical types if present.
904///
905/// If the canonical types are not present (because the types have not
906/// yet been canonicalized, for instance) then the types are compared
907/// structurally.
908///
909/// @param l the first type to take into account in the comparison.
910///
911/// @param r the second type to take into account in the comparison.
912template<typename T>
913bool
914try_canonical_compare(const T *l, const T *r)
915{
916#if WITH_DEBUG_TYPE_CANONICALIZATION
917 // We are debugging the canonicalization of a type down the stack.
918 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
919 // type being canonicalized. We are at a point where we can compare
920 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
921 // have canonical types) or structural comparison.
922 //
923 // Because we are debugging the process of type canonicalization, we
924 // want to compare 'l' and 'r' canonically *AND* structurally. Both
925 // kinds of comparison should yield the same result, otherwise type
926 // canonicalization just failed for the subtype 'r' of the type
927 // being canonicalized.
928 //
929 // In concrete terms, this function is going to be called twice with
930 // the same pair {'l', 'r'} to compare: The first time with
931 // environment::priv_->use_canonical_type_comparison_ set to true,
932 // instructing us to compare them canonically, and the second time
933 // with that boolean set to false, instructing us to compare them
934 // structurally.
935 const environment&env = l->get_environment();
936 if (env.priv_->use_canonical_type_comparison_)
937 {
938 if (const type_base *lc = l->get_naked_canonical_type())
939 if (const type_base *rc = r->get_naked_canonical_type())
940 ABG_RETURN_EQUAL(lc, rc);
941 }
942
943 // If the two types have a non-empty hash value, then consider those
944 // hash values. If the hashes are different then the two types are
945 // different. If the hashes are equal then we'll compare then
946 // structurally.
947 if (hash_t l_hash = peek_hash_value(*l))
948 if (hash_t r_hash = peek_hash_value(*r))
949 if (l_hash != r_hash)
951
952 // If a type has a canonical type, use its canonical type, always.
955
956 return equals(*l, *r, 0);
957#else
958 if (const type_base *lc = l->get_naked_canonical_type())
959 if (const type_base *rc = r->get_naked_canonical_type())
960 ABG_RETURN_EQUAL(lc, rc);
961
962 // If the two types have a non-empty hash value, then consider those
963 // hash values. If the hashes are different then the two types are
964 // different. If the hashes are equal then we'll compare then
965 // structurally.
966 if (hash_t l_hash = peek_hash_value(*l))
967 if (hash_t r_hash = peek_hash_value(*r))
968 if (l_hash != r_hash)
970
971 // If a type has a canonical type, use its canonical type, always.
974
975 return equals(*l, *r, 0);
976#endif
977}
978
979/// Detect if a recursive comparison cycle is detected while
980/// structurally comparing two types (a.k.a member-wise comparison).
981///
982/// @param l the left-hand-side operand of the current comparison.
983///
984/// @param r the right-hand-side operand of the current comparison.
985///
986/// @return true iff a comparison cycle is detected.
987template<typename T>
988bool
990{
991 bool result = l.priv_->comparison_started(l, r);
992 return result ;
993}
994
995/// Detect if a recursive comparison cycle is detected while
996/// structurally comparing two @ref class_decl types.
997///
998/// @param l the left-hand-side operand of the current comparison.
999///
1000/// @param r the right-hand-side operand of the current comparison.
1001///
1002/// @return true iff a comparison cycle is detected.
1003template<>
1004bool
1006{
1007 return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
1008 static_cast<const class_or_union&>(r));
1009}
1010
1011/// This macro is to be used while comparing composite types that
1012/// might recursively refer to themselves. Comparing two such types
1013/// might get us into a cyle.
1014///
1015/// Practically, if we detect that we are already into comparing 'l'
1016/// and 'r'; then, this is a cycle.
1017//
1018/// To break the cycle, we assume the result of the comparison is true
1019/// for now. Comparing the other sub-types of l & r will tell us later
1020/// if l & r are actually different or not.
1021///
1022/// In the mean time, returning true from this macro should not be
1023/// used to propagate the canonical type of 'l' onto 'r' as we don't
1024/// know yet if l equals r. All the types that depend on l and r
1025/// can't (and that are in the comparison stack currently) can't have
1026/// their canonical type propagated either. So this macro disallows
1027/// canonical type propagation for those types that depend on a
1028/// recursively defined sub-type for now.
1029///
1030/// @param l the left-hand-side operand of the comparison.
1031#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
1032 do \
1033 { \
1034 if (is_comparison_cycle_detected(l, r)) \
1035 return true; \
1036 } \
1037 while(false)
1038
1039
1040/// Mark a pair of types as being compared.
1041///
1042/// This is helpful to later detect recursive cycles in the comparison
1043/// stack.
1044///
1045/// @param l the left-hand-side operand of the comparison.
1046///
1047/// @parm r the right-hand-side operand of the comparison.
1048template<typename T>
1049void
1051{
1052 l.priv_->mark_as_being_compared(l, r);
1054}
1055
1056/// Mark a pair of @ref class_decl types as being compared.
1057///
1058/// This is helpful to later detect recursive cycles in the comparison
1059/// stack.
1060///
1061/// @param l the left-hand-side operand of the comparison.
1062///
1063/// @parm r the right-hand-side operand of the comparison.
1064template<>
1065void
1067{
1068 return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
1069 static_cast<const class_or_union&>(r));
1070}
1071
1072/// Mark a pair of types as being not compared anymore.
1073///
1074/// This is helpful to later detect recursive cycles in the comparison
1075/// stack.
1076///
1077/// Note that the types must have been passed to
1078/// mark_types_as_being_compared prior to calling this function.
1079///
1080/// @param l the left-hand-side operand of the comparison.
1081///
1082/// @parm r the right-hand-side operand of the comparison.
1083template<typename T>
1084void
1086{
1087 l.priv_->unmark_as_being_compared(l, r);
1089}
1090
1091/// Mark a pair of @ref class_decl types as being not compared
1092/// anymore.
1093///
1094/// This is helpful to later detect recursive cycles in the comparison
1095/// stack.
1096///
1097/// Note that the types must have been passed to
1098/// mark_types_as_being_compared prior to calling this function.
1099///
1100/// @param l the left-hand-side operand of the comparison.
1101///
1102/// @parm r the right-hand-side operand of the comparison.
1103template<>
1104void
1106{
1107 return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
1108 static_cast<const class_or_union&>(r));
1109}
1110
1111/// Return the result of the comparison of two (sub) types.
1112///
1113/// The function does the necessary book keeping before returning the
1114/// result of the comparison of two (sub) types.
1115///
1116/// The book-keeping done is essentially about type comparison cycle detection.
1117///
1118/// @param l the left-hand-side operand of the type comparison
1119///
1120/// @param r the right-hand-side operand of the type comparison
1121///
1122/// @param value the result of the comparison of @p l and @p r.
1123///
1124/// @return the value @p value.
1125template<typename T>
1126bool
1127return_comparison_result(T& l, T& r, bool value)
1128{
1130 ABG_RETURN(value);
1131}
1132
1133#define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1134 do \
1135 { \
1136 bool res = return_comparison_result(l, r, value); \
1137 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1138 return res; \
1139 } while (false)
1140
1141/// Cache the result of a comparison between too artifacts (l & r) and
1142/// return immediately.
1143///
1144/// @param value the value to cache.
1145#define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1146 do \
1147 { \
1148 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1149 return value; \
1150 } while (false)
1151
1152/// Getter of all types types sorted by their pretty representation.
1153///
1154/// @return a sorted vector of all types sorted by their pretty
1155/// representation.
1156const vector<type_base_wptr>&
1158{
1159 if (priv_->sorted_types_.empty())
1160 {
1161 istring_type_base_wptrs_map_type::const_iterator i;
1162 vector<type_base_wptr>::const_iterator j;
1163
1164 for (i = basic_types().begin(); i != basic_types().end(); ++i)
1165 for (j = i->second.begin(); j != i->second.end(); ++j)
1166 priv_->sorted_types_.push_back(*j);
1167
1168 for (i = class_types().begin(); i != class_types().end(); ++i)
1169 for (j = i->second.begin(); j != i->second.end(); ++j)
1170 priv_->sorted_types_.push_back(*j);
1171
1172 for (i = union_types().begin(); i != union_types().end(); ++i)
1173 for (j = i->second.begin(); j != i->second.end(); ++j)
1174 priv_->sorted_types_.push_back(*j);
1175
1176 for (i = enum_types().begin(); i != enum_types().end(); ++i)
1177 for (j = i->second.begin(); j != i->second.end(); ++j)
1178 priv_->sorted_types_.push_back(*j);
1179
1180 for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
1181 for (j = i->second.begin(); j != i->second.end(); ++j)
1182 priv_->sorted_types_.push_back(*j);
1183
1184 type_name_comp comp;
1185 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1186 }
1187
1188 return priv_->sorted_types_;
1189}
1190
1191// </type_maps stuff>
1192
1193// <translation_unit stuff>
1194
1195/// Constructor of translation_unit.
1196///
1197/// @param env the environment of this translation unit. Please note
1198/// that the life time of the environment must be greater than the
1199/// life time of the translation unit because the translation uses
1200/// resources that are allocated in the environment.
1201///
1202/// @param path the location of the translation unit.
1203///
1204/// @param address_size the size of addresses in the translation unit,
1205/// in bits.
1206translation_unit::translation_unit(const environment& env,
1207 const std::string& path,
1208 char address_size)
1209 : priv_(new priv(env))
1210{
1211 priv_->path_ = path;
1212 priv_->address_size_ = address_size;
1213}
1214
1215/// Getter of the the global scope of the translation unit.
1216///
1217/// @return the global scope of the current translation unit. If
1218/// there is not global scope allocated yet, this function creates one
1219/// and returns it.
1220const scope_decl_sptr&
1222{
1223 return const_cast<translation_unit*>(this)->get_global_scope();
1224}
1225
1226/// Getter of the global scope of the translation unit.
1227///
1228/// @return the global scope of the current translation unit. If
1229/// there is not allocated yet, this function creates one and returns
1230/// it.
1233{
1234 if (!priv_->global_scope_)
1235 {
1236 priv_->global_scope_.reset
1237 (new global_scope(const_cast<translation_unit*>(this)));
1238 priv_->global_scope_->set_translation_unit
1239 (const_cast<translation_unit*>(this));
1240 }
1241 return priv_->global_scope_;
1242}
1243
1244/// Getter of the types of the current @ref translation_unit.
1245///
1246/// @return the maps of the types of the translation unit.
1247const type_maps&
1249{return priv_->types_;}
1250
1251/// Getter of the types of the current @ref translation_unit.
1252///
1253/// @return the maps of the types of the translation unit.
1254type_maps&
1256{return priv_->types_;}
1257
1258/// Get the vector of function types that are used in the current
1259/// translation unit.
1260///
1261/// @return the vector of function types that are used in the current
1262/// translation unit.
1263const vector<function_type_sptr>&
1265{return priv_->live_fn_types_;}
1266
1267/// Getter of the environment of the current @ref translation_unit.
1268///
1269/// @return the translation unit of the current translation unit.
1270const environment&
1272{return priv_->env_;}
1273
1274/// Getter of the language of the source code of the translation unit.
1275///
1276/// @return the language of the source code.
1279{return priv_->language_;}
1280
1281/// Setter of the language of the source code of the translation unit.
1282///
1283/// @param l the new language.
1284void
1286{priv_->language_ = l;}
1287
1288
1289/// Get the path of the current translation unit.
1290///
1291/// This path is relative to the build directory of the translation
1292/// unit as returned by translation_unit::get_compilation_dir_path.
1293///
1294/// @return the relative path of the compilation unit associated to
1295/// the current instance of translation_unit.
1296//
1297const std::string&
1299{return priv_->path_;}
1300
1301/// Set the path associated to the current instance of
1302/// translation_unit.
1303///
1304/// This path is relative to the build directory of the translation
1305/// unit as returned by translation_unit::get_compilation_dir_path.
1306///
1307/// @param a_path the new relative path to set.
1308void
1309translation_unit::set_path(const string& a_path)
1310{priv_->path_ = a_path;}
1311
1312
1313/// Get the path of the directory that was 'current' when the
1314/// translation unit was compiled.
1315///
1316/// Note that the path returned by translation_unit::get_path is
1317/// relative to the path returned by this function.
1318///
1319/// @return the compilation directory for the current translation
1320/// unit.
1321const std::string&
1323{return priv_->comp_dir_path_;}
1324
1325/// Set the path of the directory that was 'current' when the
1326/// translation unit was compiled.
1327///
1328/// Note that the path returned by translation_unit::get_path is
1329/// relative to the path returned by this function.
1330///
1331/// @param the compilation directory for the current translation unit.
1332void
1334{priv_->comp_dir_path_ = d;}
1335
1336/// Get the concatenation of the build directory and the relative path
1337/// of the translation unit.
1338///
1339/// @return the absolute path of the translation unit.
1340const std::string&
1342{
1343 if (priv_->abs_path_.empty())
1344 {
1345 string path;
1346 if (!priv_->path_.empty())
1347 {
1348 if (!priv_->comp_dir_path_.empty())
1349 {
1350 path = priv_->comp_dir_path_;
1351 path += "/";
1352 }
1353 path += priv_->path_;
1354 }
1355 priv_->abs_path_ = path;
1356 }
1357
1358 return priv_->abs_path_;
1359}
1360
1361/// Set the corpus this translation unit is a member of.
1362///
1363/// Note that adding a translation unit to a @ref corpus automatically
1364/// triggers a call to this member function.
1365///
1366/// @param corpus the corpus.
1367void
1369{priv_->corp = c;}
1370
1371/// Get the corpus this translation unit is a member of.
1372///
1373/// @return the parent corpus, or nil if this doesn't belong to any
1374/// corpus yet.
1375corpus*
1377{return priv_->corp;}
1378
1379/// Get the corpus this translation unit is a member of.
1380///
1381/// @return the parent corpus, or nil if this doesn't belong to any
1382/// corpus yet.
1383const corpus*
1385{return const_cast<translation_unit*>(this)->get_corpus();}
1386
1387/// Getter of the location manager for the current translation unit.
1388///
1389/// @return a reference to the location manager for the current
1390/// translation unit.
1393{return priv_->loc_mgr_;}
1394
1395/// const Getter of the location manager.
1396///
1397/// @return a const reference to the location manager for the current
1398/// translation unit.
1399const location_manager&
1401{return priv_->loc_mgr_;}
1402
1403/// Tests whether if the current translation unit contains ABI
1404/// artifacts or not.
1405///
1406/// @return true iff the current translation unit is empty.
1407bool
1409{
1410 if (!priv_->global_scope_)
1411 return true;
1412 return get_global_scope()->is_empty();
1413}
1414
1415/// Getter of the address size in this translation unit.
1416///
1417/// @return the address size, in bits.
1418char
1420{return priv_->address_size_;}
1421
1422/// Setter of the address size in this translation unit.
1423///
1424/// @param a the new address size in bits.
1425void
1427{priv_->address_size_= a;}
1428
1429/// Getter of the 'is_constructed" flag. It says if the translation
1430/// unit is fully constructed or not.
1431///
1432/// This flag is important for cases when comparison might depend on
1433/// if the translation unit is fully built or not. For instance, when
1434/// reading types from DWARF, the virtual methods of a class are not
1435/// necessarily fully constructed until we have reached the end of the
1436/// translation unit. In that case, before we've reached the end of
1437/// the translation unit, we might not take virtual functions into
1438/// account when comparing classes.
1439///
1440/// @return true if the translation unit is constructed.
1441bool
1443{return priv_->is_constructed_;}
1444
1445/// Setter of the 'is_constructed" flag. It says if the translation
1446/// unit is fully constructed or not.
1447///
1448/// This flag is important for cases when comparison might depend on
1449/// if the translation unit is fully built or not. For instance, when
1450/// reading types from DWARF, the virtual methods of a class are not
1451/// necessarily fully constructed until we have reached the end of the
1452/// translation unit. In that case, before we've reached the end of
1453/// the translation unit, we might not take virtual functions into
1454/// account when comparing classes.
1455///
1456/// @param f true if the translation unit is constructed.
1457void
1459{priv_->is_constructed_ = f;}
1460
1461/// Compare the current translation unit against another one.
1462///
1463/// @param other the other tu to compare against.
1464///
1465/// @return true if the two translation units are equal, false
1466/// otherwise.
1467bool
1469{
1470 if (get_address_size() != other.get_address_size())
1471 return false;
1472
1473 return *get_global_scope() == *other.get_global_scope();
1474}
1475
1476/// Inequality operator.
1477///
1478/// @param o the instance of @ref translation_unit to compare the
1479/// current instance against.
1480///
1481/// @return true iff the current instance is different from @p o.
1482bool
1485
1486/// Ensure that the life time of a function type is bound to the life
1487/// time of the current translation unit.
1488///
1489/// @param ftype the function time which life time to bind to the life
1490/// time of the current instance of @ref translation_unit. That is,
1491/// it's onlyh when the translation unit is destroyed that the
1492/// function type can be destroyed to.
1493void
1495{
1496 const environment& env = get_environment();
1497
1498 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1499
1500 interned_string repr = get_type_name(ftype);
1501 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1502 push_back(ftype);
1503
1504 // The function type must be out of the same environment as its
1505 // translation unit.
1506 {
1507 const environment& e = ftype->get_environment();
1508 ABG_ASSERT(&env == &e);
1509 }
1510
1511 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1512 ABG_ASSERT(existing_tu == this);
1513 else
1514 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1515
1517}
1518
1519/// This implements the ir_traversable_base::traverse virtual
1520/// function.
1521///
1522/// @param v the visitor used on the member nodes of the translation
1523/// unit during the traversal.
1524///
1525/// @return true if the entire type IR tree got traversed, false
1526/// otherwise.
1527bool
1530
1531translation_unit::~translation_unit()
1532{}
1533
1534/// Converts a translation_unit::language enumerator into a string.
1535///
1536/// @param l the language enumerator to translate.
1537///
1538/// @return the resulting string.
1539string
1541{
1542 switch (l)
1543 {
1544 case translation_unit::LANG_UNKNOWN:
1545 return "LANG_UNKNOWN";
1546 case translation_unit::LANG_Cobol74:
1547 return "LANG_Cobol74";
1548 case translation_unit::LANG_Cobol85:
1549 return "LANG_Cobol85";
1550 case translation_unit::LANG_C89:
1551 return "LANG_C89";
1552 case translation_unit::LANG_C99:
1553 return "LANG_C99";
1554 case translation_unit::LANG_C11:
1555 return "LANG_C11";
1556 case translation_unit::LANG_C:
1557 return "LANG_C";
1558 case translation_unit::LANG_C_plus_plus_11:
1559 return "LANG_C_plus_plus_11";
1560 case translation_unit::LANG_C_plus_plus_14:
1561 return "LANG_C_plus_plus_14";
1562 case translation_unit::LANG_C_plus_plus:
1563 return "LANG_C_plus_plus";
1564 case translation_unit::LANG_ObjC:
1565 return "LANG_ObjC";
1566 case translation_unit::LANG_ObjC_plus_plus:
1567 return "LANG_ObjC_plus_plus";
1568 case translation_unit::LANG_Fortran77:
1569 return "LANG_Fortran77";
1570 case translation_unit::LANG_Fortran90:
1571 return "LANG_Fortran90";
1572 case translation_unit::LANG_Fortran95:
1573 return "LANG_Fortran95";
1574 case translation_unit::LANG_Ada83:
1575 return "LANG_Ada83";
1576 case translation_unit::LANG_Ada95:
1577 return "LANG_Ada95";
1578 case translation_unit::LANG_Pascal83:
1579 return "LANG_Pascal83";
1580 case translation_unit::LANG_Modula2:
1581 return "LANG_Modula2";
1582 case translation_unit::LANG_Java:
1583 return "LANG_Java";
1584 case translation_unit::LANG_PLI:
1585 return "LANG_PLI";
1586 case translation_unit::LANG_UPC:
1587 return "LANG_UPC";
1588 case translation_unit::LANG_D:
1589 return "LANG_D";
1590 case translation_unit::LANG_Python:
1591 return "LANG_Python";
1592 case translation_unit::LANG_Go:
1593 return "LANG_Go";
1594 case translation_unit::LANG_Mips_Assembler:
1595 return "LANG_Mips_Assembler";
1596 default:
1597 return "LANG_UNKNOWN";
1598 }
1599
1600 return "LANG_UNKNOWN";
1601}
1602
1603/// Parse a string representing a language into a
1604/// translation_unit::language enumerator into a string.
1605///
1606/// @param l the string representing the language.
1607///
1608/// @return the resulting translation_unit::language enumerator.
1611{
1612 if (l == "LANG_Cobol74")
1613 return translation_unit::LANG_Cobol74;
1614 else if (l == "LANG_Cobol85")
1615 return translation_unit::LANG_Cobol85;
1616 else if (l == "LANG_C89")
1617 return translation_unit::LANG_C89;
1618 else if (l == "LANG_C99")
1619 return translation_unit::LANG_C99;
1620 else if (l == "LANG_C11")
1621 return translation_unit::LANG_C11;
1622 else if (l == "LANG_C")
1623 return translation_unit::LANG_C;
1624 else if (l == "LANG_C_plus_plus_11")
1625 return translation_unit::LANG_C_plus_plus_11;
1626 else if (l == "LANG_C_plus_plus_14")
1627 return translation_unit::LANG_C_plus_plus_14;
1628 else if (l == "LANG_C_plus_plus")
1629 return translation_unit::LANG_C_plus_plus;
1630 else if (l == "LANG_ObjC")
1631 return translation_unit::LANG_ObjC;
1632 else if (l == "LANG_ObjC_plus_plus")
1633 return translation_unit::LANG_ObjC_plus_plus;
1634 else if (l == "LANG_Fortran77")
1635 return translation_unit::LANG_Fortran77;
1636 else if (l == "LANG_Fortran90")
1637 return translation_unit::LANG_Fortran90;
1638 else if (l == "LANG_Fortran95")
1639 return translation_unit::LANG_Fortran95;
1640 else if (l == "LANG_Ada83")
1641 return translation_unit::LANG_Ada83;
1642 else if (l == "LANG_Ada95")
1643 return translation_unit::LANG_Ada95;
1644 else if (l == "LANG_Pascal83")
1645 return translation_unit::LANG_Pascal83;
1646 else if (l == "LANG_Modula2")
1647 return translation_unit::LANG_Modula2;
1648 else if (l == "LANG_Java")
1649 return translation_unit::LANG_Java;
1650 else if (l == "LANG_PLI")
1651 return translation_unit::LANG_PLI;
1652 else if (l == "LANG_UPC")
1653 return translation_unit::LANG_UPC;
1654 else if (l == "LANG_D")
1655 return translation_unit::LANG_D;
1656 else if (l == "LANG_Python")
1657 return translation_unit::LANG_Python;
1658 else if (l == "LANG_Go")
1659 return translation_unit::LANG_Go;
1660 else if (l == "LANG_Mips_Assembler")
1661 return translation_unit::LANG_Mips_Assembler;
1662
1663 return translation_unit::LANG_UNKNOWN;
1664}
1665
1666/// Test if a language enumerator designates the C language.
1667///
1668/// @param l the language enumerator to consider.
1669///
1670/// @return true iff @p l designates the C language.
1671bool
1673{
1674 return (l == translation_unit::LANG_C89
1675 || l == translation_unit::LANG_C99
1676 || l == translation_unit::LANG_C11
1677 || l == translation_unit::LANG_C);
1678}
1679
1680/// Test if a language enumerator designates the C++ language.
1681///
1682/// @param l the language enumerator to consider.
1683///
1684/// @return true iff @p l designates the C++ language.
1685bool
1687{
1688 return (l == translation_unit::LANG_C_plus_plus_03
1689 || l == translation_unit::LANG_C_plus_plus_11
1690 || l == translation_unit::LANG_C_plus_plus_14
1691 || l == translation_unit::LANG_C_plus_plus);
1692}
1693
1694/// Test if a language enumerator designates the Java language.
1695///
1696/// @param l the language enumerator to consider.
1697///
1698/// @return true iff @p l designates the Java language.
1699bool
1701{return l == translation_unit::LANG_Java;}
1702
1703/// Test if a language enumerator designates the Ada language.
1704///
1705/// @param l the language enumerator to consider.
1706///
1707/// @return true iff @p l designates the Ada language.
1708bool
1710{
1711 return (l == translation_unit::LANG_Ada83
1712 || l == translation_unit::LANG_Ada95);
1713}
1714
1715/// A deep comparison operator for pointers to translation units.
1716///
1717/// @param l the first translation unit to consider for the comparison.
1718///
1719/// @param r the second translation unit to consider for the comparison.
1720///
1721/// @return true if the two translation units are equal, false otherwise.
1722bool
1724{
1725 if (l.get() == r.get())
1726 return true;
1727
1728 if (!!l != !!r)
1729 return false;
1730
1731 return *l == *r;
1732}
1733
1734/// A deep inequality operator for pointers to translation units.
1735///
1736/// @param l the first translation unit to consider for the comparison.
1737///
1738/// @param r the second translation unit to consider for the comparison.
1739///
1740/// @return true iff the two translation units are different.
1741bool
1743{return !operator==(l, r);}
1744
1745// </translation_unit stuff>
1746
1747// <elf_symbol stuff>
1748struct elf_symbol::priv
1749{
1750 const environment& env_;
1751 size_t index_;
1752 size_t size_;
1753 string name_;
1754 elf_symbol::type type_;
1755 elf_symbol::binding binding_;
1756 elf_symbol::version version_;
1757 elf_symbol::visibility visibility_;
1758 bool is_defined_;
1759 // This flag below says if the symbol is a common elf symbol. In
1760 // relocatable files, a common symbol is a symbol defined in a
1761 // section of kind SHN_COMMON.
1762 //
1763 // Note that a symbol of kind STT_COMMON is also considered a common
1764 // symbol. Here is what the gABI says about STT_COMMON and
1765 // SHN_COMMON:
1766 //
1767 // Symbols with type STT_COMMON label uninitialized common
1768 // blocks. In relocatable objects, these symbols are not
1769 // allocated and must have the special section index SHN_COMMON
1770 // (see below). In shared objects and executables these symbols
1771 // must be allocated to some section in the defining object.
1772 //
1773 // In relocatable objects, symbols with type STT_COMMON are
1774 // treated just as other symbols with index SHN_COMMON. If the
1775 // link-editor allocates space for the SHN_COMMON symbol in an
1776 // output section of the object it is producing, it must
1777 // preserve the type of the output symbol as STT_COMMON.
1778 //
1779 // When the dynamic linker encounters a reference to a symbol
1780 // that resolves to a definition of type STT_COMMON, it may (but
1781 // is not required to) change its symbol resolution rules as
1782 // follows: instead of binding the reference to the first symbol
1783 // found with the given name, the dynamic linker searches for
1784 // the first symbol with that name with type other than
1785 // STT_COMMON. If no such symbol is found, it looks for the
1786 // STT_COMMON definition of that name that has the largest size.
1787 bool is_common_;
1788 bool is_in_ksymtab_;
1791 bool is_suppressed_;
1792 elf_symbol_wptr main_symbol_;
1793 elf_symbol_wptr next_alias_;
1794 elf_symbol_wptr next_common_instance_;
1795 string id_string_;
1796
1797 priv(const environment& e)
1798 : env_(e),
1799 index_(),
1800 size_(),
1801 type_(elf_symbol::NOTYPE_TYPE),
1802 binding_(elf_symbol::GLOBAL_BINDING),
1803 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1804 is_defined_(false),
1805 is_common_(false),
1806 is_in_ksymtab_(false),
1807 crc_(),
1808 namespace_(),
1809 is_suppressed_(false)
1810 {}
1811
1812 priv(const environment& e,
1813 size_t i,
1814 size_t s,
1815 const string& n,
1818 bool d,
1819 bool c,
1820 const elf_symbol::version& ve,
1822 bool is_in_ksymtab,
1825 bool is_suppressed)
1826 : env_(e),
1827 index_(i),
1828 size_(s),
1829 name_(n),
1830 type_(t),
1831 binding_(b),
1832 version_(ve),
1833 visibility_(vi),
1834 is_defined_(d),
1835 is_common_(c),
1836 is_in_ksymtab_(is_in_ksymtab),
1837 crc_(crc),
1838 namespace_(ns),
1839 is_suppressed_(is_suppressed)
1840 {
1841 if (!is_common_)
1842 is_common_ = type_ == COMMON_TYPE;
1843 }
1844}; // end struct elf_symbol::priv
1845
1846/// Constructor of the @ref elf_symbol type.
1847///
1848/// Note that this constructor is private, so client code cannot use
1849/// it to create instances of @ref elf_symbol. Rather, client code
1850/// should use the @ref elf_symbol::create() function to create
1851/// instances of @ref elf_symbol instead.
1852///
1853/// @param e the environment we are operating from.
1854///
1855/// @param i the index of the symbol in the (ELF) symbol table.
1856///
1857/// @param s the size of the symbol.
1858///
1859/// @param n the name of the symbol.
1860///
1861/// @param t the type of the symbol.
1862///
1863/// @param b the binding of the symbol.
1864///
1865/// @param d true if the symbol is defined, false otherwise.
1866///
1867/// @param c true if the symbol is a common symbol, false otherwise.
1868///
1869/// @param ve the version of the symbol.
1870///
1871/// @param vi the visibility of the symbol.
1872///
1873/// @param crc the CRC (modversions) value of Linux Kernel symbols
1874///
1875/// @param ns the namespace of Linux Kernel symbols, if any
1876elf_symbol::elf_symbol(const environment& e,
1877 size_t i,
1878 size_t s,
1879 const string& n,
1880 type t,
1881 binding b,
1882 bool d,
1883 bool c,
1884 const version& ve,
1885 visibility vi,
1886 bool is_in_ksymtab,
1889 bool is_suppressed)
1890 : priv_(new priv(e,
1891 i,
1892 s,
1893 n,
1894 t,
1895 b,
1896 d,
1897 c,
1898 ve,
1899 vi,
1900 is_in_ksymtab,
1901 crc,
1902 ns,
1903 is_suppressed))
1904{}
1905
1906/// Factory of instances of @ref elf_symbol.
1907///
1908/// This is the function to use to create instances of @ref elf_symbol.
1909///
1910/// @param e the environment we are operating from.
1911///
1912/// @param i the index of the symbol in the (ELF) symbol table.
1913///
1914/// @param s the size of the symbol.
1915///
1916/// @param n the name of the symbol.
1917///
1918/// @param t the type of the symbol.
1919///
1920/// @param b the binding of the symbol.
1921///
1922/// @param d true if the symbol is defined, false otherwise.
1923///
1924/// @param c true if the symbol is a common symbol.
1925///
1926/// @param ve the version of the symbol.
1927///
1928/// @param vi the visibility of the symbol.
1929///
1930/// @param crc the CRC (modversions) value of Linux Kernel symbols
1931///
1932/// @param ns the namespace of Linux Kernel symbols, if any
1933///
1934/// @return a (smart) pointer to a newly created instance of @ref
1935/// elf_symbol.
1938 size_t i,
1939 size_t s,
1940 const string& n,
1941 type t,
1942 binding b,
1943 bool d,
1944 bool c,
1945 const version& ve,
1946 visibility vi,
1947 bool is_in_ksymtab,
1950 bool is_suppressed)
1951{
1952 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
1953 is_in_ksymtab, crc, ns, is_suppressed));
1954 sym->priv_->main_symbol_ = sym;
1955 return sym;
1956}
1957
1958/// Test textual equality between two symbols.
1959///
1960/// Textual equality means that the aliases of the compared symbols
1961/// are not taken into account. Only the name, type, and version of
1962/// the symbols are compared.
1963///
1964/// @return true iff the two symbols are textually equal.
1965static bool
1966textually_equals(const elf_symbol&l,
1967 const elf_symbol&r)
1968{
1969 bool equals = (l.get_name() == r.get_name()
1970 && l.get_type() == r.get_type()
1971 && l.is_public() == r.is_public()
1972 && l.is_defined() == r.is_defined()
1974 && l.get_version() == r.get_version()
1975 && l.get_crc() == r.get_crc()
1976 && l.get_namespace() == r.get_namespace());
1977
1978 if (equals && l.is_variable())
1979 // These are variable symbols. Let's compare their symbol size.
1980 // The symbol size in this case is the size taken by the storage
1981 // of the variable. If that size changes, then it's an ABI
1982 // change.
1983 equals = l.get_size() == r.get_size();
1984
1985 return equals;
1986}
1987
1988/// Getter of the environment used by the current instance of @ref
1989/// elf_symbol.
1990///
1991/// @return the enviroment used by the current instance of @ref elf_symbol.
1992const environment&
1994{return priv_->env_;}
1995
1996/// Getter for the index
1997///
1998/// @return the index of the symbol.
1999size_t
2001{return priv_->index_;}
2002
2003/// Setter for the index.
2004///
2005/// @param s the new index.
2006void
2008{priv_->index_ = s;}
2009
2010/// Getter for the name of the @ref elf_symbol.
2011///
2012/// @return a reference to the name of the @ref symbol.
2013const string&
2015{return priv_->name_;}
2016
2017/// Setter for the name of the current intance of @ref elf_symbol.
2018///
2019/// @param n the new name.
2020void
2021elf_symbol::set_name(const string& n)
2022{
2023 priv_->name_ = n;
2024 priv_->id_string_.clear();
2025}
2026
2027/// Getter for the type of the current instance of @ref elf_symbol.
2028///
2029/// @return the type of the elf symbol.
2032{return priv_->type_;}
2033
2034/// Setter for the type of the current instance of @ref elf_symbol.
2035///
2036/// @param t the new symbol type.
2037void
2039{priv_->type_ = t;}
2040
2041/// Getter of the size of the symbol.
2042///
2043/// @return the size of the symbol, in bytes.
2044size_t
2046{return priv_->size_;}
2047
2048/// Setter of the size of the symbol.
2049///
2050/// @param size the new size of the symbol, in bytes.
2051void
2053{priv_->size_ = size;}
2054
2055/// Getter for the binding of the current instance of @ref elf_symbol.
2056///
2057/// @return the binding of the symbol.
2060{return priv_->binding_;}
2061
2062/// Setter for the binding of the current instance of @ref elf_symbol.
2063///
2064/// @param b the new binding.
2065void
2067{priv_->binding_ = b;}
2068
2069/// Getter for the version of the current instanc of @ref elf_symbol.
2070///
2071/// @return the version of the elf symbol.
2074{return priv_->version_;}
2075
2076/// Setter for the version of the current instance of @ref elf_symbol.
2077///
2078/// @param v the new version of the elf symbol.
2079void
2081{
2082 priv_->version_ = v;
2083 priv_->id_string_.clear();
2084}
2085
2086/// Setter of the visibility of the current instance of @ref
2087/// elf_symbol.
2088///
2089/// @param v the new visibility of the elf symbol.
2090void
2092{priv_->visibility_ = v;}
2093
2094/// Getter of the visibility of the current instance of @ref
2095/// elf_symbol.
2096///
2097/// @return the visibility of the elf symbol.
2100{return priv_->visibility_;}
2101
2102/// Test if the current instance of @ref elf_symbol is defined or not.
2103///
2104/// @return true if the current instance of @ref elf_symbol is
2105/// defined, false otherwise.
2106bool
2108{return priv_->is_defined_;}
2109
2110/// Sets a flag saying if the current instance of @ref elf_symbol is
2111/// defined
2112///
2113/// @param b the new value of the flag.
2114void
2116{priv_->is_defined_ = d;}
2117
2118/// Test if the current instance of @ref elf_symbol is public or not.
2119///
2120/// This tests if the symbol is defined, has default or protected
2121///visibility, and either:
2122/// - has global binding
2123/// - has weak binding
2124/// - or has a GNU_UNIQUE binding.
2125///
2126/// return true if the current instance of @ref elf_symbol is public,
2127/// false otherwise.
2128bool
2130{
2131 return (is_defined()
2132 && (get_binding() == GLOBAL_BINDING
2133 || get_binding() == WEAK_BINDING
2134 || get_binding() == GNU_UNIQUE_BINDING)
2135 && (get_visibility() == DEFAULT_VISIBILITY
2136 || get_visibility() == PROTECTED_VISIBILITY));
2137}
2138
2139/// Test if the current instance of @ref elf_symbol is a function
2140/// symbol or not.
2141///
2142/// @return true if the current instance of @ref elf_symbol is a
2143/// function symbol, false otherwise.
2144bool
2146{return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2147
2148/// Test if the current instance of @ref elf_symbol is a variable
2149/// symbol or not.
2150///
2151/// @return true if the current instance of @ref elf_symbol is a
2152/// variable symbol, false otherwise.
2153bool
2155{
2156 return (get_type() == OBJECT_TYPE
2157 || get_type() == TLS_TYPE
2158 // It appears that undefined variables have NOTYPE type.
2159 || (get_type() == NOTYPE_TYPE
2160 && !is_defined()));
2161}
2162
2163/// Getter of the 'is-in-ksymtab' property.
2164///
2165/// @return true iff the current symbol is in the Linux Kernel
2166/// specific 'ksymtab' symbol table.
2167bool
2169{return priv_->is_in_ksymtab_;}
2170
2171/// Setter of the 'is-in-ksymtab' property.
2172///
2173/// @param is_in_ksymtab this is true iff the current symbol is in the
2174/// Linux Kernel specific 'ksymtab' symbol table.
2175void
2177{priv_->is_in_ksymtab_ = is_in_ksymtab;}
2178
2179/// Getter of the 'crc' property.
2180///
2181/// @return the CRC (modversions) value for Linux Kernel symbols, if any
2184{return priv_->crc_;}
2185
2186/// Setter of the 'crc' property.
2187///
2188/// @param crc the new CRC (modversions) value for Linux Kernel symbols
2189void
2191{priv_->crc_ = crc;}
2192
2193/// Getter of the 'namespace' property.
2194///
2195/// @return the namespace for Linux Kernel symbols, if any
2198{return priv_->namespace_;}
2199
2200/// Setter of the 'namespace' property.
2201///
2202/// @param ns the new namespace for Linux Kernel symbols, if any
2203void
2205{priv_->namespace_ = ns;}
2206
2207/// Getter for the 'is-suppressed' property.
2208///
2209/// @return true iff the current symbol has been suppressed by a
2210/// suppression specification that was provided in the context that
2211/// led to the creation of the corpus this ELF symbol belongs to.
2212bool
2214{return priv_->is_suppressed_;}
2215
2216/// Setter for the 'is-suppressed' property.
2217///
2218/// @param true iff the current symbol has been suppressed by a
2219/// suppression specification that was provided in the context that
2220/// led to the creation of the corpus this ELF symbol belongs to.
2221void
2223{priv_->is_suppressed_ = is_suppressed;}
2224
2225/// @name Elf symbol aliases
2226///
2227/// An alias A for an elf symbol S is a symbol that is defined at the
2228/// same address as S. S is chained to A through the
2229/// elf_symbol::get_next_alias() method.
2230///
2231/// When there are several aliases to a symbol, the main symbol is the
2232/// the first symbol found in the symbol table for a given address.
2233///
2234/// The alias chain is circular. That means if S is the main symbol
2235/// and A is the alias, S is chained to A and A
2236/// is chained back to the main symbol S. The last alias in an alias
2237///chain is always chained to the main symbol.
2238///
2239/// Thus, when looping over the aliases of an elf_symbol A, detecting
2240/// an alias that is equal to the main symbol should logically be a
2241/// loop exit condition.
2242///
2243/// Accessing and adding aliases for instances of elf_symbol is done
2244/// through the member functions below.
2245
2246/// @{
2247
2248/// Get the main symbol of an alias chain.
2249///
2250///@return the main symbol.
2251const elf_symbol_sptr
2253{return priv_->main_symbol_.lock();}
2254
2255/// Get the main symbol of an alias chain.
2256///
2257///@return the main symbol.
2260{return priv_->main_symbol_.lock();}
2261
2262/// Tests whether this symbol is the main symbol.
2263///
2264/// @return true iff this symbol is the main symbol.
2265bool
2267{return get_main_symbol().get() == this;}
2268
2269/// Get the next alias of the current symbol.
2270///
2271///@return the alias, or NULL if there is no alias.
2274{return priv_->next_alias_.lock();}
2275
2276
2277/// Check if the current elf_symbol has an alias.
2278///
2279///@return true iff the current elf_symbol has an alias.
2280bool
2282{return bool(get_next_alias());}
2283
2284/// Get the number of aliases to this elf symbol
2285///
2286/// @return the number of aliases to this elf symbol.
2287int
2289{
2290 int result = 0;
2291
2293 a && a.get() != get_main_symbol().get();
2294 a = a->get_next_alias())
2295 ++result;
2296
2297 return result;
2298}
2299
2300/// Add an alias to the current elf symbol.
2301///
2302/// @param alias the new alias. Note that this elf_symbol should *NOT*
2303/// have aliases prior to the invocation of this function.
2304void
2306{
2307 if (!alias)
2308 return;
2309
2310 ABG_ASSERT(!alias->has_aliases());
2312
2313 if (has_aliases())
2314 {
2315 elf_symbol_sptr last_alias;
2317 a && !a->is_main_symbol();
2318 a = a->get_next_alias())
2319 {
2320 if (a->get_next_alias()->is_main_symbol())
2321 {
2322 ABG_ASSERT(last_alias == 0);
2323 last_alias = a;
2324 }
2325 }
2326 ABG_ASSERT(last_alias);
2327
2328 last_alias->priv_->next_alias_ = alias;
2329 }
2330 else
2331 priv_->next_alias_ = alias;
2332
2333 alias->priv_->next_alias_ = get_main_symbol();
2334 alias->priv_->main_symbol_ = get_main_symbol();
2335}
2336
2337/// Update the main symbol for a group of aliased symbols
2338///
2339/// If after the construction of the symbols (in order of discovery), the
2340/// actual main symbol can be identified (e.g. as the symbol that actually is
2341/// defined in the code), this method offers a way of updating the main symbol
2342/// through one of the aliased symbols.
2343///
2344/// For that, locate the new main symbol by name and update all references to
2345/// the main symbol among the group of aliased symbols.
2346///
2347/// @param name the name of the main symbol
2348///
2349/// @return the new main elf_symbol
2351elf_symbol::update_main_symbol(const std::string& name)
2352{
2354 if (!has_aliases() || get_name() == name)
2355 return get_main_symbol();
2356
2357 // find the new main symbol
2358 elf_symbol_sptr new_main;
2359 // we've already checked this; check the rest of the aliases
2360 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2361 a = a->get_next_alias())
2362 if (a->get_name() == name)
2363 {
2364 new_main = a;
2365 break;
2366 }
2367
2368 if (!new_main)
2369 return get_main_symbol();
2370
2371 // now update all main symbol references
2372 priv_->main_symbol_ = new_main;
2373 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2374 a = a->get_next_alias())
2375 a->priv_->main_symbol_ = new_main;
2376
2377 return new_main;
2378}
2379
2380/// Return true if the symbol is a common one.
2381///
2382/// @return true iff the symbol is common.
2383bool
2385{return priv_->is_common_;}
2386
2387/// Return true if this common common symbol has other common instances.
2388///
2389/// A common instance of a given common symbol is another common
2390/// symbol with the same name. Those exist in relocatable files. The
2391/// linker normally allocates all the instances into a common block in
2392/// the final output file.
2393///
2394/// Note that the current object must be a common symbol, otherwise,
2395/// this function aborts.
2396///
2397/// @return true iff the current common symbol has other common
2398/// instances.
2399bool
2405
2406/// Get the next common instance of the current common symbol.
2407///
2408/// A common instance of a given common symbol is another common
2409/// symbol with the same name. Those exist in relocatable files. The
2410/// linker normally allocates all the instances into a common block in
2411/// the final output file.
2412///
2413/// @return the next common instance, or nil if there is not any.
2416{return priv_->next_common_instance_.lock();}
2417
2418/// Add a common instance to the current common elf symbol.
2419///
2420/// Note that this symbol must be the main symbol. Being the main
2421/// symbol means being the first common symbol to appear in the symbol
2422/// table.
2423///
2424/// @param common the other common instance to add.
2425void
2427{
2428 if (!common)
2429 return;
2430
2431 ABG_ASSERT(!common->has_other_common_instances());
2434
2436 {
2437 elf_symbol_sptr last_common_instance;
2439 c && (c.get() != get_main_symbol().get());
2440 c = c->get_next_common_instance())
2441 {
2442 if (c->get_next_common_instance().get() == get_main_symbol().get())
2443 {
2444 ABG_ASSERT(last_common_instance == 0);
2445 last_common_instance = c;
2446 }
2447 }
2448 ABG_ASSERT(last_common_instance);
2449
2450 last_common_instance->priv_->next_common_instance_ = common;
2451 }
2452 else
2453 priv_->next_common_instance_ = common;
2454
2455 common->priv_->next_common_instance_ = get_main_symbol();
2456 common->priv_->main_symbol_ = get_main_symbol();
2457}
2458
2459/// Get a string that is representative of a given elf_symbol.
2460///
2461/// If the symbol has a version, then the ID string is the
2462/// concatenation of the name of the symbol, the '@' character, and
2463/// the version of the symbol. If the version is the default version
2464/// of the symbol then the '@' character is replaced by a "@@" string.
2465///
2466/// Otherwise, if the symbol does not have any version, this function
2467/// returns the name of the symbol.
2468///
2469/// @return a the ID string.
2470const string&
2472{
2473 if (priv_->id_string_.empty())
2474 {
2475 string s = get_name ();
2476
2477 if (!get_version().is_empty())
2478 {
2479 if (get_version().is_default())
2480 s += "@@";
2481 else
2482 s += "@";
2483 s += get_version().str();
2484 }
2485 priv_->id_string_ = s;
2486 }
2487
2488 return priv_->id_string_;
2489}
2490
2491/// From the aliases of the current symbol, lookup one with a given name.
2492///
2493/// @param name the name of symbol alias we are looking for.
2494///
2495/// @return the symbol alias that has the name @p name, or nil if none
2496/// has been found.
2498elf_symbol::get_alias_from_name(const string& name) const
2499{
2500 if (name == get_name())
2501 return elf_symbol_sptr(priv_->main_symbol_);
2502
2504 a && a.get() != get_main_symbol().get();
2505 a = a->get_next_alias())
2506 if (a->get_name() == name)
2507 return a;
2508
2509 return elf_symbol_sptr();
2510}
2511
2512/// In the list of aliases of a given elf symbol, get the alias that
2513/// equals this current symbol.
2514///
2515/// @param other the elf symbol to get the potential aliases from.
2516///
2517/// @return the alias of @p other that texually equals the current
2518/// symbol, or nil if no alias textually equals the current symbol.
2521{
2522 for (elf_symbol_sptr a = other.get_next_alias();
2523 a && a.get() != a->get_main_symbol().get();
2524 a = a->get_next_alias())
2525 if (textually_equals(*this, *a))
2526 return a;
2527 return elf_symbol_sptr();
2528}
2529
2530/// Return a comma separated list of the id of the current symbol as
2531/// well as the id string of its aliases.
2532///
2533/// @param syms a map of all the symbols of the corpus the current
2534/// symbol belongs to.
2535///
2536/// @param include_symbol_itself if set to true, then the name of the
2537/// current symbol is included in the list of alias names that is emitted.
2538///
2539/// @return the string.
2540string
2542 bool include_symbol_itself) const
2543{
2544 string result;
2545
2546 if (include_symbol_itself)
2547 result = get_id_string();
2548
2549 vector<elf_symbol_sptr> aliases;
2550 compute_aliases_for_elf_symbol(*this, syms, aliases);
2551 if (!aliases.empty() && include_symbol_itself)
2552 result += ", ";
2553
2554 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2555 i != aliases.end();
2556 ++i)
2557 {
2558 if (i != aliases.begin())
2559 result += ", ";
2560 result += (*i)->get_id_string();
2561 }
2562 return result;
2563}
2564
2565/// Return a comma separated list of the id of the current symbol as
2566/// well as the id string of its aliases.
2567///
2568/// @param include_symbol_itself if set to true, then the name of the
2569/// current symbol is included in the list of alias names that is emitted.
2570///
2571/// @return the string.
2572string
2573elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2574{
2575 vector<elf_symbol_sptr> aliases;
2576 if (include_symbol_itself)
2577 aliases.push_back(get_main_symbol());
2578
2580 a && a.get() != get_main_symbol().get();
2581 a = a->get_next_alias())
2582 aliases.push_back(a);
2583
2584 string result;
2585 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2586 i != aliases.end();
2587 ++i)
2588 {
2589 if (i != aliases.begin())
2590 result += ", ";
2591 result += (*i)->get_id_string();
2592 }
2593
2594 return result;
2595}
2596
2597/// Given the ID of a symbol, get the name and the version of said
2598/// symbol.
2599///
2600/// @param id the symbol ID to consider.
2601///
2602/// @param name the symbol name extracted from the ID. This is set
2603/// only if the function returned true.
2604///
2605/// @param ver the symbol version extracted from the ID.
2606bool
2608 string& name,
2609 string& ver)
2610{
2611 name.clear(), ver.clear();
2612
2613 string::size_type i = id.find('@');
2614 if (i == string::npos)
2615 {
2616 name = id;
2617 return true;
2618 }
2619
2620 name = id.substr(0, i);
2621 ++i;
2622
2623 if (i >= id.size())
2624 return true;
2625
2626 string::size_type j = id.find('@', i);
2627 if (j == string::npos)
2628 j = i;
2629 else
2630 ++j;
2631
2632 if (j >= id.size())
2633 {
2634 ver = "";
2635 return true;
2636 }
2637
2638 ver = id.substr(j);
2639 return true;
2640}
2641
2642///@}
2643
2644/// Test if two main symbols are textually equal, or, if they have
2645/// aliases that are textually equal.
2646///
2647/// @param other the symbol to compare against.
2648///
2649/// @return true iff the current instance of elf symbol equals the @p
2650/// other.
2651bool
2653{
2654 bool are_equal = textually_equals(*this, other);
2655 if (!are_equal)
2656 are_equal = bool(get_alias_which_equals(other));
2657 return are_equal;
2658}
2659
2660/// Test if the current symbol aliases another one.
2661///
2662/// @param o the other symbol to test against.
2663///
2664/// @return true iff the current symbol aliases @p o.
2665bool
2667{
2668 if (*this == o)
2669 return true;
2670
2671 if (get_main_symbol() == o.get_main_symbol())
2672 return true;
2673
2675 a && !a->is_main_symbol();
2676 a = a->get_next_alias())
2677 {
2678 if (o == *a)
2679 return true;
2680 }
2681 return false;
2682}
2683
2684/// Equality operator for smart pointers to elf_symbol.
2685///
2686/// @param lhs the first elf symbol to consider.
2687///
2688/// @param rhs the second elf symbol to consider.
2689///
2690/// @return true iff @p lhs equals @p rhs.
2691bool
2693{
2694 if (!!lhs != !!rhs)
2695 return false;
2696
2697 if (!lhs)
2698 return true;
2699
2700 return *lhs == *rhs;
2701}
2702
2703/// Inequality operator for smart pointers to elf_symbol.
2704///
2705/// @param lhs the first elf symbol to consider.
2706///
2707/// @param rhs the second elf symbol to consider.
2708///
2709/// @return true iff @p lhs is different from @p rhs.
2710bool
2712{return !operator==(lhs, rhs);}
2713
2714/// Test if two symbols alias.
2715///
2716/// @param s1 the first symbol to consider.
2717///
2718/// @param s2 the second symbol to consider.
2719///
2720/// @return true if @p s1 aliases @p s2.
2721bool
2723{return s1.does_alias(s2) || s2.does_alias(s1);}
2724
2725void
2726compute_aliases_for_elf_symbol(const elf_symbol& sym,
2727 const string_elf_symbols_map_type& symtab,
2728 vector<elf_symbol_sptr>& aliases)
2729{
2730
2731 if (elf_symbol_sptr a = sym.get_next_alias())
2732 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2733 aliases.push_back(a);
2734 else
2735 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2736 i != symtab.end();
2737 ++i)
2738 for (elf_symbols::const_iterator j = i->second.begin();
2739 j != i->second.end();
2740 ++j)
2741 {
2742 if (**j == sym)
2743 for (elf_symbol_sptr s = (*j)->get_next_alias();
2744 s && !s->is_main_symbol();
2745 s = s->get_next_alias())
2746 aliases.push_back(s);
2747 else
2748 for (elf_symbol_sptr s = (*j)->get_next_alias();
2749 s && !s->is_main_symbol();
2750 s = s->get_next_alias())
2751 if (*s == sym)
2752 aliases.push_back(*j);
2753 }
2754}
2755
2756/// Test if two symbols alias.
2757///
2758/// @param s1 the first symbol to consider.
2759///
2760/// @param s2 the second symbol to consider.
2761///
2762/// @return true if @p s1 aliases @p s2.
2763bool
2765{
2766 if (!!s1 != !!s2)
2767 return false;
2768 if (s1 == s2)
2769 return true;
2770 return elf_symbols_alias(*s1, *s2);
2771}
2772
2773/// Test if two symbols alias.
2774///
2775/// @param s1 the first symbol to consider.
2776///
2777/// @param s2 the second symbol to consider.
2778///
2779/// @return true if @p s1 aliases @p s2.
2780bool
2782{return elf_symbols_alias(s1.get(), s2.get());}
2783
2784/// Serialize an instance of @ref symbol_type and stream it to a given
2785/// output stream.
2786///
2787/// @param o the output stream to serialize the symbole type to.
2788///
2789/// @param t the symbol type to serialize.
2790std::ostream&
2791operator<<(std::ostream& o, elf_symbol::type t)
2792{
2793 string repr;
2794
2795 switch (t)
2796 {
2797 case elf_symbol::NOTYPE_TYPE:
2798 repr = "unspecified symbol type";
2799 break;
2800 case elf_symbol::OBJECT_TYPE:
2801 repr = "variable symbol type";
2802 break;
2803 case elf_symbol::FUNC_TYPE:
2804 repr = "function symbol type";
2805 break;
2806 case elf_symbol::SECTION_TYPE:
2807 repr = "section symbol type";
2808 break;
2809 case elf_symbol::FILE_TYPE:
2810 repr = "file symbol type";
2811 break;
2812 case elf_symbol::COMMON_TYPE:
2813 repr = "common data object symbol type";
2814 break;
2815 case elf_symbol::TLS_TYPE:
2816 repr = "thread local data object symbol type";
2817 break;
2818 case elf_symbol::GNU_IFUNC_TYPE:
2819 repr = "indirect function symbol type";
2820 break;
2821 default:
2822 {
2823 std::ostringstream s;
2824 s << "unknown symbol type (" << (char)t << ')';
2825 repr = s.str();
2826 }
2827 break;
2828 }
2829
2830 o << repr;
2831 return o;
2832}
2833
2834/// Serialize an instance of @ref symbol_binding and stream it to a
2835/// given output stream.
2836///
2837/// @param o the output stream to serialize the symbole type to.
2838///
2839/// @param b the symbol binding to serialize.
2840std::ostream&
2841operator<<(std::ostream& o, elf_symbol::binding b)
2842{
2843 string repr;
2844
2845 switch (b)
2846 {
2847 case elf_symbol::LOCAL_BINDING:
2848 repr = "local binding";
2849 break;
2850 case elf_symbol::GLOBAL_BINDING:
2851 repr = "global binding";
2852 break;
2853 case elf_symbol::WEAK_BINDING:
2854 repr = "weak binding";
2855 break;
2856 case elf_symbol::GNU_UNIQUE_BINDING:
2857 repr = "GNU unique binding";
2858 break;
2859 default:
2860 {
2861 std::ostringstream s;
2862 s << "unknown binding (" << (unsigned char) b << ")";
2863 repr = s.str();
2864 }
2865 break;
2866 }
2867
2868 o << repr;
2869 return o;
2870}
2871
2872/// Serialize an instance of @ref elf_symbol::visibility and stream it
2873/// to a given output stream.
2874///
2875/// @param o the output stream to serialize the symbole type to.
2876///
2877/// @param v the symbol visibility to serialize.
2878std::ostream&
2879operator<<(std::ostream& o, elf_symbol::visibility v)
2880{
2881 string repr;
2882
2883 switch (v)
2884 {
2885 case elf_symbol::DEFAULT_VISIBILITY:
2886 repr = "default visibility";
2887 break;
2888 case elf_symbol::PROTECTED_VISIBILITY:
2889 repr = "protected visibility";
2890 break;
2891 case elf_symbol::HIDDEN_VISIBILITY:
2892 repr = "hidden visibility";
2893 break;
2894 case elf_symbol::INTERNAL_VISIBILITY:
2895 repr = "internal visibility";
2896 break;
2897 default:
2898 {
2899 std::ostringstream s;
2900 s << "unknown visibility (" << (unsigned char) v << ")";
2901 repr = s.str();
2902 }
2903 break;
2904 }
2905
2906 o << repr;
2907 return o;
2908}
2909
2910/// Convert a string representing a symbol type into an
2911/// elf_symbol::type.
2912///
2913///@param s the string to convert.
2914///
2915///@param t the resulting elf_symbol::type.
2916///
2917/// @return true iff the conversion completed successfully.
2918bool
2920{
2921 if (s == "no-type")
2922 t = elf_symbol::NOTYPE_TYPE;
2923 else if (s == "object-type")
2924 t = elf_symbol::OBJECT_TYPE;
2925 else if (s == "func-type")
2926 t = elf_symbol::FUNC_TYPE;
2927 else if (s == "section-type")
2928 t = elf_symbol::SECTION_TYPE;
2929 else if (s == "file-type")
2930 t = elf_symbol::FILE_TYPE;
2931 else if (s == "common-type")
2932 t = elf_symbol::COMMON_TYPE;
2933 else if (s == "tls-type")
2934 t = elf_symbol::TLS_TYPE;
2935 else if (s == "gnu-ifunc-type")
2936 t = elf_symbol::GNU_IFUNC_TYPE;
2937 else
2938 return false;
2939
2940 return true;
2941}
2942
2943/// Convert a string representing a an elf symbol binding into an
2944/// elf_symbol::binding.
2945///
2946/// @param s the string to convert.
2947///
2948/// @param b the resulting elf_symbol::binding.
2949///
2950/// @return true iff the conversion completed successfully.
2951bool
2953{
2954 if (s == "local-binding")
2955 b = elf_symbol::LOCAL_BINDING;
2956 else if (s == "global-binding")
2957 b = elf_symbol::GLOBAL_BINDING;
2958 else if (s == "weak-binding")
2959 b = elf_symbol::WEAK_BINDING;
2960 else if (s == "gnu-unique-binding")
2961 b = elf_symbol::GNU_UNIQUE_BINDING;
2962 else
2963 return false;
2964
2965 return true;
2966}
2967
2968/// Convert a string representing a an elf symbol visibility into an
2969/// elf_symbol::visibility.
2970///
2971/// @param s the string to convert.
2972///
2973/// @param b the resulting elf_symbol::visibility.
2974///
2975/// @return true iff the conversion completed successfully.
2976bool
2978{
2979 if (s == "default-visibility")
2980 v = elf_symbol::DEFAULT_VISIBILITY;
2981 else if (s == "protected-visibility")
2982 v = elf_symbol::PROTECTED_VISIBILITY;
2983 else if (s == "hidden-visibility")
2984 v = elf_symbol::HIDDEN_VISIBILITY;
2985 else if (s == "internal-visibility")
2986 v = elf_symbol::INTERNAL_VISIBILITY;
2987 else
2988 return false;
2989
2990 return true;
2991}
2992
2993/// Test if the type of an ELF symbol denotes a function symbol.
2994///
2995/// @param t the type of the ELF symbol.
2996///
2997/// @return true iff elf symbol type @p t denotes a function symbol
2998/// type.
2999bool
3001{return t == elf_symbol::FUNC_TYPE;}
3002
3003/// Test if the type of an ELF symbol denotes a function symbol.
3004///
3005/// @param t the type of the ELF symbol.
3006///
3007/// @return true iff elf symbol type @p t denotes a function symbol
3008/// type.
3009bool
3011{return t == elf_symbol::OBJECT_TYPE;}
3012
3013// <elf_symbol::version stuff>
3014
3015struct elf_symbol::version::priv
3016{
3017 string version_;
3018 bool is_default_;
3019
3020 priv()
3021 : is_default_(false)
3022 {}
3023
3024 priv(const string& v,
3025 bool d)
3026 : version_(v),
3027 is_default_(d)
3028 {}
3029}; // end struct elf_symbol::version::priv
3030
3031elf_symbol::version::version()
3032 : priv_(new priv)
3033{}
3034
3035/// @param v the name of the version.
3036///
3037/// @param is_default true if this is a default version.
3038elf_symbol::version::version(const string& v,
3039 bool is_default)
3040 : priv_(new priv(v, is_default))
3041{}
3042
3043elf_symbol::version::version(const elf_symbol::version& v)
3044 : priv_(new priv(v.str(), v.is_default()))
3045{
3046}
3047
3048elf_symbol::version::~version() = default;
3049
3050/// Cast the version_type into a string that is its name.
3051///
3052/// @return the name of the version.
3053elf_symbol::version::operator const string&() const
3054{return priv_->version_;}
3055
3056/// Getter for the version name.
3057///
3058/// @return the version name.
3059const string&
3061{return priv_->version_;}
3062
3063/// Setter for the version name.
3064///
3065/// @param s the version name.
3066void
3068{priv_->version_ = s;}
3069
3070/// Getter for the 'is_default' property of the version.
3071///
3072/// @return true iff this is a default version.
3073bool
3075{return priv_->is_default_;}
3076
3077/// Setter for the 'is_default' property of the version.
3078///
3079/// @param f true if this is the default version.
3080void
3082{priv_->is_default_ = f;}
3083
3084bool
3085elf_symbol::version::is_empty() const
3086{return str().empty();}
3087
3088/// Compares the current version against another one.
3089///
3090/// @param o the other version to compare the current one to.
3091///
3092/// @return true iff the current version equals @p o.
3093bool
3095{return str() == o.str();}
3096
3097/// Inequality operator.
3098///
3099/// @param o the version to compare against the current one.
3100///
3101/// @return true iff both versions are different.
3102bool
3104{return !operator==(o);}
3105
3106/// Assign a version to the current one.
3107///
3108/// @param o the other version to assign to this one.
3109///
3110/// @return a reference to the assigned version.
3113{
3114 str(o.str());
3115 is_default(o.is_default());
3116 return *this;
3117}
3118
3119// </elf_symbol::version stuff>
3120
3121// </elf_symbol stuff>
3122
3123// <class dm_context_rel stuff>
3124struct dm_context_rel::priv
3125{
3126 bool is_laid_out_;
3127 size_t offset_in_bits_;
3128 var_decl* anonymous_data_member_;
3129
3130 priv(bool is_static = false)
3131 : is_laid_out_(!is_static),
3132 offset_in_bits_(0),
3133 anonymous_data_member_()
3134 {}
3135
3136 priv(bool is_laid_out, size_t offset_in_bits)
3137 : is_laid_out_(is_laid_out),
3138 offset_in_bits_(offset_in_bits),
3139 anonymous_data_member_()
3140 {}
3141}; //end struct dm_context_rel::priv
3142
3143dm_context_rel::dm_context_rel()
3144 : context_rel(),
3145 priv_(new priv)
3146{}
3147
3148dm_context_rel::dm_context_rel(scope_decl* s,
3149 bool is_laid_out,
3150 size_t offset_in_bits,
3152 bool is_static)
3153 : context_rel(s, a, is_static),
3154 priv_(new priv(is_laid_out, offset_in_bits))
3155{}
3156
3157dm_context_rel::dm_context_rel(scope_decl* s)
3158 : context_rel(s),
3159 priv_(new priv())
3160{}
3161
3162bool
3163dm_context_rel::get_is_laid_out() const
3164{return priv_->is_laid_out_;}
3165
3166void
3167dm_context_rel::set_is_laid_out(bool f)
3168{priv_->is_laid_out_ = f;}
3169
3170size_t
3171dm_context_rel::get_offset_in_bits() const
3172{return priv_->offset_in_bits_;}
3173
3174void
3175dm_context_rel::set_offset_in_bits(size_t o)
3176{priv_->offset_in_bits_ = o;}
3177
3178bool
3179dm_context_rel::operator==(const dm_context_rel& o) const
3180{
3181 if (!context_rel::operator==(o))
3182 return false;
3183
3184 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3185 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3186}
3187
3188bool
3189dm_context_rel::operator!=(const dm_context_rel& o) const
3190{return !operator==(o);}
3191
3192/// Return a non-nil value if this data member context relationship
3193/// has an anonymous data member. That means, if the data member this
3194/// relation belongs to is part of an anonymous data member.
3195///
3196/// @return the containing anonymous data member of this data member
3197/// relationship. Nil if there is none.
3198const var_decl*
3200{return priv_->anonymous_data_member_;}
3201
3202/// Set the containing anonymous data member of this data member
3203/// context relationship. That means that the data member this
3204/// relation belongs to is part of an anonymous data member.
3205///
3206/// @param anon_dm the containing anonymous data member of this data
3207/// member relationship. Nil if there is none.
3208void
3210{priv_->anonymous_data_member_ = anon_dm;}
3211
3212dm_context_rel::~dm_context_rel()
3213{}
3214// </class dm_context_rel stuff>
3215
3216// <environment stuff>
3217
3218/// Convenience typedef for a map of interned_string -> bool.
3219typedef unordered_map<interned_string,
3221
3222
3223/// Default constructor of the @ref environment type.
3225 :priv_(new priv)
3226{}
3227
3228/// Destructor for the @ref environment type.
3231
3232/// Getter the map of canonical types.
3233///
3234/// @return the map of canonical types. The key of the map is the
3235/// hash of the canonical type and its value if the canonical type.
3238{return priv_->canonical_types_;}
3239
3240/// Getter the map of canonical types.
3241///
3242/// @return the map of canonical types. The key of the map is the
3243/// hash of the canonical type and its value if the canonical type.
3247
3248/// Helper to detect if a type is either a reference, a pointer, or a
3249/// qualified type.
3250bool
3252{
3253 if (is_pointer_type(t)
3254 || is_reference_type(t)
3255 || is_qualified_type(t))
3256 return true;
3257 return false;
3258}
3259
3260/// Compare decls using their locations.
3261///
3262/// @param f the first decl to compare.
3263///
3264/// @param s the second decl to compare.
3265///
3266/// @return true if @p f compares less than @p s.
3267bool
3269 const decl_base *s)
3270{
3271 // If a decl has artificial location, then use that one over the
3272 // natural one.
3275
3276 ABG_ASSERT(fl.get_value() && sl.get_value());
3277 if (fl.get_is_artificial() == sl.get_is_artificial())
3278 {
3279 // The locations of the two artfifacts have the same
3280 // artificial-ness so they can be compared.
3281 string p1, p2;
3282 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3283 fl.expand(p1, l1, c1);
3284 sl.expand(p2, l2, c2);
3285 if (p1 != p2)
3286 return p1 < p2;
3287 if (l1 != l2)
3288 return l1 < l2;
3289 if (c1 != c2)
3290 return c1 < c2;
3291 }
3292
3293 return (get_pretty_representation(f, /*internal=*/false)
3294 < get_pretty_representation(s, /*internal=*/false));
3295}
3296
3297/// Sort types in a hopefully stable manner.
3298///
3299/// @param types a set of types with canonical types to sort.
3300///
3301/// @param result the resulting sorted vector.
3302void
3304 vector<type_base_sptr>& result)
3305{
3306 for (auto t: types)
3307 result.push_back(t);
3308
3309 type_topo_comp comp;
3310 std::stable_sort(result.begin(), result.end(), comp);
3311}
3312
3313/// Get the unique @ref type_decl that represents a "void" type for
3314/// the current environment. This node must be the only one
3315/// representing a void type in the system.
3316///
3317/// Note that upon first use of this IR node (by the relevant
3318/// front-end, for instance) it must be added to a scope using e.g,
3319/// the @ref add_decl_to_scope() function.
3320///
3321/// @return the @ref type_decl that represents a "void" type.
3322const type_base_sptr&
3324{
3325 if (!priv_->void_type_)
3326 priv_->void_type_.reset(new type_decl(*this,
3327 intern("void"),
3328 0, 0, location()));
3329 return priv_->void_type_;
3330}
3331
3332/// Getter of the "pointer-to-void" IR node that is shared across the
3333/// ABI corpus. This node must be the only one representing a void
3334/// pointer type in the system.
3335///
3336/// Note that upon first use of this IR node (by the relevant
3337/// front-end, for instance) it must be added to a scope using e.g,
3338/// the @ref add_decl_to_scope() function.
3339///
3340/// @return the "pointer-to-void" IR node.
3341const type_base_sptr&
3343{
3344 if (!priv_->void_pointer_type_)
3345 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3346 0, 0, location()));
3347 return priv_->void_pointer_type_;
3348}
3349
3350/// Get a @ref type_decl instance that represents a the type of a
3351/// variadic function parameter. This node must be the only one
3352/// representing a variadic parameter type in the system.
3353///
3354/// Note that upon first use of this IR node (by the relevant
3355/// front-end, for instance) it must be added to a scope using e.g,
3356/// the @ref add_decl_to_scope() function.
3357///
3358/// @return the Get a @ref type_decl instance that represents a the
3359/// type of a variadic function parameter.
3360const type_base_sptr&
3362{
3363 if (!priv_->variadic_marker_type_)
3364 priv_->variadic_marker_type_.
3366 0, 0, location()));
3367 return priv_->variadic_marker_type_;
3368}
3369
3370/// Getter of the name of the variadic parameter type.
3371///
3372/// @return the name of the variadic parameter type.
3373string&
3375{
3376 static string variadic_parameter_type_name = "variadic parameter type";
3377 return variadic_parameter_type_name;
3378}
3379
3380/// Test if the canonicalization of types created out of the current
3381/// environment is done.
3382///
3383/// @return true iff the canonicalization of types created out of the current
3384/// environment is done.
3385bool
3387{return priv_->canonicalization_is_done_;}
3388
3389/// Set a flag saying if the canonicalization of types created out of
3390/// the current environment is done or not.
3391///
3392/// Note that this function must only be called by internal code of
3393/// the library that creates ABI artifacts (e.g, read an abi corpus
3394/// from elf or from our own xml format and creates representations of
3395/// types out of it) and thus needs to canonicalize types to speed-up
3396/// further type comparison.
3397///
3398/// @param f the new value of the flag.
3399void
3401{
3402 priv_->canonicalization_is_done_ = f;
3403 if (priv_->canonicalization_is_done_)
3405}
3406
3407/// Getter of a flag saying if the canonicalization process has
3408/// started or not.
3409///
3410/// @return the flag saying if the canonicalization process has
3411/// started or not.
3412bool
3414{return priv_->canonicalization_started_;}
3415
3416/// Setter of a flag saying if the canonicalization process has
3417/// started or not.
3418///
3419/// @param f the new value of the flag saying if the canonicalization
3420/// process has started or not.
3421void
3423{priv_->canonicalization_started_ = f;}
3424
3425/// Getter of the "decl-only-class-equals-definition" flag.
3426///
3427/// Usually, a declaration-only class named 'struct foo' compares
3428/// equal to any class definition named "struct foo'. This is at
3429/// least true for C++.
3430///
3431/// In C, though, because there can be multiple definitions of 'struct
3432/// foo' in the binary, a declaration-only "struct foo" might be
3433/// considered to *NOT* resolve to any of the struct foo defined. In
3434/// that case, the declaration-only "struct foo" is considered
3435/// different from the definitions.
3436///
3437/// This flag controls the behaviour of the comparison of an
3438/// unresolved decl-only class against a definition of the same name.
3439///
3440/// If set to false, the the declaration equals the definition. If
3441/// set to false, then the decalration is considered different from
3442/// the declaration.
3443///
3444/// @return the value of the "decl-only-class-equals-definition" flag.
3445bool
3447{return priv_->decl_only_class_equals_definition_;}
3448
3449/// Setter of the "decl-only-class-equals-definition" flag.
3450///
3451/// Usually, a declaration-only class named 'struct foo' compares
3452/// equal to any class definition named "struct foo'. This is at
3453/// least true for C++.
3454///
3455/// In C, though, because there can be multiple definitions of 'struct
3456/// foo' in the binary, a declaration-only "struct foo" might be
3457/// considered to *NOT* resolve to any of the struct foo defined. In
3458/// that case, the declaration-only "struct foo" is considered
3459/// different from the definitions.
3460///
3461/// This flag controls the behaviour of the comparison of an
3462/// unresolved decl-only class against a definition of the same name.
3463///
3464/// If set to false, the the declaration equals the definition. If
3465/// set to false, then the decalration is considered different from
3466/// the declaration.
3467///
3468/// @param the new value of the "decl-only-class-equals-definition"
3469/// flag.
3470void
3472{priv_->decl_only_class_equals_definition_ = f;}
3473
3474/// Test if a given type is a void type as defined in the current
3475/// environment.
3476///
3477/// @param t the type to consider.
3478///
3479/// @return true iff @p t is a void type as defined in the current
3480/// environment.
3481bool
3482environment::is_void_type(const type_base_sptr& t) const
3483{
3484 if (!t)
3485 return false;
3486 return is_void_type(t.get());
3487}
3488
3489/// Test if a given type is a void type as defined in the current
3490/// environment.
3491///
3492/// @param t the type to consider.
3493///
3494/// @return true iff @p t is a void type as defined in the current
3495/// environment.
3496bool
3498{
3499 if (!t)
3500 return false;
3501 return (t == get_void_type().get()
3502 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3503}
3504
3505/// Test if a given type is the same as the void pointer type of the
3506/// environment.
3507///
3508/// @param t the IR type to test.
3509///
3510/// @return true iff @p t is the void pointer returned by
3511/// environment::get_void_pointer_type().
3512bool
3513environment::is_void_pointer_type(const type_base_sptr& t) const
3514{
3515 if (!t)
3516 return false;
3517
3518 return t.get() == get_void_pointer_type().get();
3519}
3520
3521/// Test if a given type is the same as the void pointer type of the
3522/// environment.
3523///
3524/// @param t the IR type to test.
3525///
3526/// @return true iff @p t is the void pointer returned by
3527/// environment::get_void_pointer_type().
3528bool
3530{
3531 if (!t)
3532 return false;
3533
3534 return t == get_void_pointer_type().get();
3535}
3536
3537/// Test if a type is a variadic parameter type as defined in the
3538/// current environment.
3539///
3540/// @param t the type to consider.
3541///
3542/// @return true iff @p t is a variadic parameter type as defined in
3543/// the current environment.
3544bool
3546{
3547 if (!t)
3548 return false;
3549 return t == get_variadic_parameter_type().get();
3550}
3551
3552/// Test if a type is a variadic parameter type as defined in the
3553/// current environment.
3554///
3555/// @param t the type to consider.
3556///
3557/// @return true iff @p t is a variadic parameter type as defined in
3558/// the current environment.
3559bool
3560environment::is_variadic_parameter_type(const type_base_sptr& t) const
3561{return is_variadic_parameter_type(t.get());}
3562
3563/// Do intern a string.
3564///
3565/// If a value of this string already exists in the interned string
3566/// pool of the current environment, then this function returns a new
3567/// interned_string pointing to that already existing string.
3568/// Otherwise, a new string is created, stored in the interned string
3569/// pool and a new interned_string instance is created to point to
3570/// that new intrerned string, and it's return.
3571///
3572/// @param s the value of the string to intern.
3573///
3574/// @return the interned string.
3576environment::intern(const string& s) const
3577{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3578
3579/// Getter of the general configuration object.
3580///
3581/// @return the configuration object.
3582const config&
3584{return priv_->config_;}
3585
3586/// Getter for a property that says if the user actually did set the
3587/// analyze_exported_interfaces_only() property. If not, it means
3588/// the default behaviour prevails.
3589///
3590/// @return tru iff the user did set the
3591/// analyze_exported_interfaces_only() property.
3592bool
3594{return priv_->analyze_exported_interfaces_only_.has_value();}
3595
3596/// Setter for the property that controls if we are to restrict the
3597/// analysis to the types that are only reachable from the exported
3598/// interfaces only, or if the set of types should be more broad than
3599/// that. Typically, we'd restrict the analysis to types reachable
3600/// from exported interfaces only (stricto sensu, that would really be
3601/// only the types that are part of the ABI of well designed
3602/// libraries) for performance reasons.
3603///
3604/// @param f the value of the flag.
3605void
3607{priv_->analyze_exported_interfaces_only_ = f;}
3608
3609/// Getter for the property that controls if we are to restrict the
3610/// analysis to the types that are only reachable from the exported
3611/// interfaces only, or if the set of types should be more broad than
3612/// that. Typically, we'd restrict the analysis to types reachable
3613/// from exported interfaces only (stricto sensu, that would really be
3614/// only the types that are part of the ABI of well designed
3615/// libraries) for performance reasons.
3616///
3617/// @param f the value of the flag.
3618bool
3620{return priv_->analyze_exported_interfaces_only_.value_or(false);}
3621
3622#ifdef WITH_DEBUG_SELF_COMPARISON
3623/// Setter of the corpus of the input corpus of the self comparison
3624/// that takes place when doing "abidw --debug-abidiff <binary>".
3625///
3626/// The first invocation of this function sets the first corpus of the
3627/// self comparison. The second invocation of this very same function
3628/// sets the second corpus of the self comparison. That second corpus
3629/// is supposed to come from the abixml serialization of the first
3630/// corpus.
3631///
3632/// @param c the corpus of the input binary or the corpus of the
3633/// abixml serialization of the initial binary input.
3634void
3635environment::set_self_comparison_debug_input(const corpus_sptr& c)
3636{
3637 self_comparison_debug_is_on(true);
3638 if (priv_->first_self_comparison_corpus_.expired())
3639 priv_->first_self_comparison_corpus_ = c;
3640 else if (priv_->second_self_comparison_corpus_.expired()
3641 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3642 priv_->second_self_comparison_corpus_ = c;
3643}
3644
3645/// Getter for the corpora of the input binary and the intermediate
3646/// abixml of the self comparison that takes place when doing
3647/// 'abidw --debug-abidiff <binary>'.
3648///
3649/// @param first_corpus output parameter that is set to the corpus of
3650/// the input corpus.
3651///
3652/// @param second_corpus output parameter that is set to the corpus of
3653/// the second corpus.
3654void
3655environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3656 corpus_sptr& second_corpus)
3657{
3658 first_corpus = priv_->first_self_comparison_corpus_.lock();
3659 second_corpus = priv_->second_self_comparison_corpus_.lock();
3660}
3661
3662/// Turn on/off the self comparison debug mode.
3663///
3664/// @param f true iff the self comparison debug mode is turned on.
3665void
3666environment::self_comparison_debug_is_on(bool f)
3667{priv_->self_comparison_debug_on_ = f;}
3668
3669/// Test if we are in the process of the 'self-comparison
3670/// debugging' as triggered by 'abidw --debug-abidiff' command.
3671///
3672/// @return true if self comparison debug is on.
3673bool
3674environment::self_comparison_debug_is_on() const
3675{return priv_->self_comparison_debug_on_;}
3676#endif
3677
3678#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3679/// Set the "type canonicalization debugging" mode, triggered by using
3680/// the command: "abidw --debug-tc".
3681///
3682/// @param flag if true then the type canonicalization debugging mode
3683/// is enabled.
3684void
3685environment::debug_type_canonicalization_is_on(bool flag)
3686{priv_->debug_type_canonicalization_ = flag;}
3687
3688/// Getter of the "type canonicalization debugging" mode, triggered by
3689/// using the command: "abidw --debug-tc".
3690///
3691/// @return true iff the type canonicalization debugging mode is
3692/// enabled.
3693bool
3694environment::debug_type_canonicalization_is_on() const
3695{return priv_->debug_type_canonicalization_;}
3696
3697/// Setter of the "DIE canonicalization debugging" mode, triggered by
3698/// using the command: "abidw --debug-dc".
3699///
3700/// @param flag true iff the DIE canonicalization debugging mode is
3701/// enabled.
3702void
3703environment::debug_die_canonicalization_is_on(bool flag)
3704{priv_->debug_die_canonicalization_ = flag;}
3705
3706/// Getter of the "DIE canonicalization debugging" mode, triggered by
3707/// using the command: "abidw --debug-dc".
3708///
3709/// @return true iff the DIE canonicalization debugging mode is
3710/// enabled.
3711bool
3712environment::debug_die_canonicalization_is_on() const
3713{return priv_->debug_die_canonicalization_;}
3714#endif // WITH_DEBUG_TYPE_CANONICALIZATION
3715
3716/// Get the vector of canonical types which have a given "string
3717/// representation".
3718///
3719/// @param 'name', the textual representation of the type as returned
3720/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3721/// /*qualified=*/true)
3722///
3723/// This is useful to for debugging purposes as it's handy to use from
3724/// inside a debugger like GDB.
3725///
3726/// @return a pointer to the vector of canonical types having the
3727/// representation @p name, or nullptr if no type with that
3728/// representation exists.
3729const vector<type_base_sptr>*
3731{
3732 auto ti = get_canonical_types_map().find(name);
3733 if (ti == get_canonical_types_map().end())
3734 return nullptr;
3735 return &ti->second;
3736}
3737
3738/// Get a given canonical type which has a given "string
3739/// representation".
3740///
3741/// @param 'name', the textual representation of the type as returned
3742/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3743/// /*qualified=*/true).
3744///
3745/// @param index, the index of the type in the vector of types that
3746/// all have the same textual representation @p 'name'. That vector
3747/// is returned by the function environment::get_canonical_types().
3748///
3749/// @return the canonical type which has the representation @p name,
3750/// and which is at index @p index in the vector of canonical types
3751/// having that same textual representation.
3752type_base*
3753environment::get_canonical_type(const char* name, unsigned index)
3754{
3755 const vector<type_base_sptr> *types = get_canonical_types(name);
3756 if (!types ||index >= types->size())
3757 return nullptr;
3758 return (*types)[index].get();
3759}
3760
3761#ifdef WITH_DEBUG_SELF_COMPARISON
3762/// Get the set of abixml type-id and the pointer value of the
3763/// (canonical) type it's associated to.
3764///
3765/// This is useful for debugging purposes, especially in the context
3766/// of the use of the command:
3767/// 'abidw --debug-abidiff <binary>'.
3768///
3769/// @return the set of abixml type-id and the pointer value of the
3770/// (canonical) type it's associated to.
3771const unordered_map<string, uintptr_t>&
3772environment::get_type_id_canonical_type_map() const
3773{return priv_->get_type_id_canonical_type_map();}
3774
3775/// Get the set of abixml type-id and the pointer value of the
3776/// (canonical) type it's associated to.
3777///
3778/// This is useful for debugging purposes, especially in the context
3779/// of the use of the command:
3780/// 'abidw --debug-abidiff <binary>'.
3781///
3782/// @return the set of abixml type-id and the pointer value of the
3783/// (canonical) type it's associated to.
3784unordered_map<string, uintptr_t>&
3785environment::get_type_id_canonical_type_map()
3786{return priv_->get_type_id_canonical_type_map();}
3787
3788/// Getter of the map that associates the values of type pointers to
3789/// their type-id strings.
3790///
3791/// Note that this map is populated at abixml reading time, (by
3792/// build_type()) when a given XML element representing a type is
3793/// read into a corresponding abigail::ir::type_base.
3794///
3795/// This is used only for the purpose of debugging the
3796/// self-comparison process. That is, when invoking "abidw
3797/// --debug-abidiff".
3798///
3799/// @return the map that associates the values of type pointers to
3800/// their type-id strings.
3801const unordered_map<uintptr_t, string>&
3802environment::get_pointer_type_id_map() const
3803{return priv_->get_pointer_type_id_map();}
3804
3805/// Getter of the map that associates the values of type pointers to
3806/// their type-id strings.
3807///
3808/// Note that this map is populated at abixml reading time, (by
3809/// build_type()) when a given XML element representing a type is
3810/// read into a corresponding abigail::ir::type_base.
3811///
3812/// This is used only for the purpose of debugging the
3813/// self-comparison process. That is, when invoking "abidw
3814/// --debug-abidiff".
3815///
3816/// @return the map that associates the values of type pointers to
3817/// their type-id strings.
3818unordered_map<uintptr_t, string>&
3819environment::get_pointer_type_id_map()
3820{return priv_->get_pointer_type_id_map();}
3821
3822/// Getter of the type-id that corresponds to the value of a pointer
3823/// to abigail::ir::type_base that was created from the abixml reader.
3824///
3825/// That value is retrieved from the map returned from
3826/// environment::get_pointer_type_id_map().
3827///
3828/// That map is populated at abixml reading time, (by build_type())
3829/// when a given XML element representing a type is read into a
3830/// corresponding abigail::ir::type_base.
3831///
3832/// This is used only for the purpose of debugging the
3833/// self-comparison process. That is, when invoking "abidw
3834/// --debug-abidiff".
3835///
3836/// @return the type-id strings that corresponds
3837string
3838environment::get_type_id_from_pointer(uintptr_t ptr) const
3839{return priv_->get_type_id_from_pointer(ptr);}
3840
3841/// Getter of the type-id that corresponds to the value of an
3842/// abigail::ir::type_base that was created from the abixml reader.
3843///
3844/// That value is retrieved from the map returned from
3845/// environment::get_pointer_type_id_map().
3846///
3847/// That map is populated at abixml reading time, (by build_type())
3848/// when a given XML element representing a type is read into a
3849/// corresponding abigail::ir::type_base.
3850///
3851/// This is used only for the purpose of debugging the
3852/// self-comparison process. That is, when invoking "abidw
3853/// --debug-abidiff".
3854///
3855/// @return the type-id strings that corresponds
3856string
3857environment::get_type_id_from_type(const type_base *t) const
3858{return priv_->get_type_id_from_type(t);}
3859
3860/// Getter of the canonical type of the artifact designated by a
3861/// type-id.
3862///
3863/// That type-id was generated by the abixml writer at the emitting
3864/// time of the abixml file. The corresponding canonical type was
3865/// stored in the map returned by
3866/// environment::get_type_id_canonical_type_map().
3867///
3868/// This is useful for debugging purposes, especially in the context
3869/// of the use of the command:
3870/// 'abidw --debug-abidiff <binary>'.
3871///
3872/// @return the set of abixml type-id and the pointer value of the
3873/// (canonical) type it's associated to.
3874uintptr_t
3875environment::get_canonical_type_from_type_id(const char* type_id) const
3876{return priv_->get_canonical_type_from_type_id(type_id);}
3877#endif
3878
3879// </environment stuff>
3880
3881// <type_or_decl_base stuff>
3882
3883/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
3884/// bitmap type.
3888{
3889 return static_cast<type_or_decl_base::type_or_decl_kind>
3890 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
3891}
3892
3893/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
3894/// bitmap type.
3898{
3899 l = l | r;
3900 return l;
3901}
3902
3903/// bitwise "AND" operator for the
3904/// type_or_decl_base::type_or_decl_kind bitmap type.
3908{
3909 return static_cast<type_or_decl_base::type_or_decl_kind>
3910 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
3911}
3912
3913/// bitwise "A&=" operator for the
3914/// type_or_decl_base::type_or_decl_kind bitmap type.
3918{
3919 l = l & r;
3920 return l;
3921}
3922
3923/// Constructor of @ref type_or_decl_base.
3924///
3925/// @param the environment the current ABI artifact is constructed
3926/// from.
3927///
3928/// @param k the runtime identifier bitmap of the type being built.
3929type_or_decl_base::type_or_decl_base(const environment& e,
3930 enum type_or_decl_kind k)
3931 :priv_(new priv(e, k))
3932{}
3933
3934/// The destructor of the @ref type_or_decl_base type.
3937
3938/// Getter of the flag that says if the artefact is artificial.
3939///
3940/// Being artificial means it was not explicitely mentionned in the
3941/// source code, but was rather artificially created by the compiler
3942/// or libabigail.
3943///
3944/// @return true iff the declaration is artificial.
3945bool
3947{return priv_->is_artificial_;}
3948
3949/// Setter of the flag that says if the artefact is artificial.
3950///
3951/// Being artificial means the artefact was not explicitely
3952/// mentionned in the source code, but was rather artificially created
3953/// by the compiler or by libabigail.
3954///
3955/// @param f the new value of the flag that says if the artefact is
3956/// artificial.
3957void
3959{priv_->is_artificial_ = f;}
3960
3961/// Getter for the "kind" property of @ref type_or_decl_base type.
3962///
3963/// This property holds the identifier bitmap of the runtime type of
3964/// an ABI artifact.
3965///
3966/// @return the runtime type identifier bitmap of the current ABI
3967/// artifact.
3970{return priv_->kind();}
3971
3972/// Setter for the "kind" property of @ref type_or_decl_base type.
3973///
3974/// This property holds the identifier bitmap of the runtime type of
3975/// an ABI artifact.
3976///
3977/// @param the runtime type identifier bitmap of the current ABI
3978/// artifact.
3979void
3981{priv_->kind(k);}
3982
3983/// Getter of the pointer to the runtime type sub-object of the
3984/// current instance.
3985///
3986/// @return the pointer to the runtime type sub-object of the current
3987/// instance.
3988const void*
3990{return priv_->rtti_;}
3991
3992/// Getter of the pointer to the runtime type sub-object of the
3993/// current instance.
3994///
3995/// @return the pointer to the runtime type sub-object of the current
3996/// instance.
3997void*
3999{return priv_->rtti_;}
4000
4001/// Setter of the pointer to the runtime type sub-object of the
4002/// current instance.
4003///
4004/// @param i the new pointer to the runtime type sub-object of the
4005/// current instance.
4006void
4008{
4009 priv_->rtti_ = i;
4010 if (type_base* t = dynamic_cast<type_base*>(this))
4011 priv_->type_or_decl_ptr_ = t;
4012 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4013 priv_->type_or_decl_ptr_ = d;
4014}
4015
4016/// Getter of the pointer to either the type_base sub-object of the
4017/// current instance if it's a type, or to the decl_base sub-object of
4018/// the current instance if it's a decl.
4019///
4020/// @return the pointer to either the type_base sub-object of the
4021/// current instance if it's a type, or to the decl_base sub-object of
4022/// the current instance if it's a decl.
4023const void*
4026
4027/// Getter of the pointer to either the type_base sub-object of the
4028/// current instance if it's a type, or to the decl_base sub-object of
4029/// the current instance if it's a decl.
4030///
4031/// @return the pointer to either the type_base sub-object of the
4032/// current instance if it's a type, or to the decl_base sub-object of
4033/// the current instance if it's a decl.
4034void*
4036{return priv_->type_or_decl_ptr_;}
4037
4038/// Return the hash value of the current IR node.
4039///
4040/// Note that upon the first invocation, this member functions
4041/// computes the hash value and returns it. Subsequent invocations
4042/// just return the hash value that was previously calculated.
4043///
4044/// @return the hash value of the current IR node.
4045hash_t
4047{return priv_->hash_value_;}
4048
4049void
4050type_or_decl_base::set_hash_value(hash_t h) const
4051{priv_->set_hash_value(h);}
4052
4053/// Getter of the environment of the current ABI artifact.
4054///
4055/// @return the environment of the artifact.
4056const environment&
4058{return priv_->env_;}
4059
4060/// Setter of the artificial location of the artificat.
4061///
4062/// The artificial location is a location that was artificially
4063/// generated by libabigail, not generated by the original emitter of
4064/// the ABI meta-data. For instance, when reading an XML element from
4065/// an abixml file, the artificial location is the source location of
4066/// the XML element within the file, not the value of the
4067/// 'location'property that might be carried by the element.
4068///
4069/// Artificial locations might be useful to ensure that abixml emitted
4070/// by the abixml writer are sorted the same way as the input abixml
4071/// read by the reader.
4072///
4073/// @param l the new artificial location.
4074void
4076{priv_->artificial_location_ = l;}
4077
4078/// Getter of the artificial location of the artifact.
4079///
4080/// The artificial location is a location that was artificially
4081/// generated by libabigail, not generated by the original emitter of
4082/// the ABI meta-data. For instance, when reading an XML element from
4083/// an abixml file, the artificial location is the source location of
4084/// the XML element within the file, not the value of the
4085/// 'location'property that might be carried by the element.
4086///
4087/// Artificial locations might be useful to ensure that the abixml
4088/// emitted by the abixml writer is sorted the same way as the input
4089/// abixml read by the reader.
4090///
4091/// @return the new artificial location.
4092location&
4094{return priv_->artificial_location_;}
4095
4096/// Test if the current ABI artifact carries an artificial location.
4097///
4098/// @return true iff the current ABI artifact carries an artificial location.
4099bool
4101{
4102 return (priv_->artificial_location_
4103 && priv_->artificial_location_.get_is_artificial());
4104}
4105
4106/// Get the @ref corpus this ABI artifact belongs to.
4107///
4108/// @return the corpus this ABI artifact belongs to, or nil if it
4109/// belongs to none for now.
4110corpus*
4112{
4114 if (!tu)
4115 return 0;
4116 return tu->get_corpus();
4117}
4118
4119
4120/// Get the @ref corpus this ABI artifact belongs to.
4121///
4122/// @return the corpus this ABI artifact belongs to, or nil if it
4123/// belongs to none for now.
4124const corpus*
4126{return const_cast<type_or_decl_base*>(this)->get_corpus();}
4127
4128/// Set the @ref translation_unit this ABI artifact belongs to.
4129///
4130/// Note that adding an ABI artifact to a containining on should
4131/// invoke this member function.
4132void
4134{priv_->translation_unit_ = tu;}
4135
4136
4137/// Get the @ref translation_unit this ABI artifact belongs to.
4138///
4139/// @return the translation unit this ABI artifact belongs to, or nil
4140/// if belongs to none for now.
4143{return priv_->translation_unit_;}
4144
4145/// Get the @ref translation_unit this ABI artifact belongs to.
4146///
4147/// @return the translation unit this ABI artifact belongs to, or nil
4148/// if belongs to none for now.
4149const translation_unit*
4152
4153/// Traverse the the ABI artifact.
4154///
4155/// @param v the visitor used to traverse the sub-tree nodes of the
4156/// artifact.
4157bool
4160
4161/// Non-member equality operator for the @type_or_decl_base type.
4162///
4163/// @param lr the left-hand operand of the equality.
4164///
4165/// @param rr the right-hand operatnr of the equality.
4166///
4167/// @return true iff @p lr equals @p rr.
4168bool
4170{
4171 const type_or_decl_base* l = &lr;
4172 const type_or_decl_base* r = &rr;
4173
4174 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4175 *dr = dynamic_cast<const decl_base*>(r);
4176
4177 if (!!dl != !!dr)
4178 return false;
4179
4180 if (dl && dr)
4181 return *dl == *dr;
4182
4183 const type_base* tl = dynamic_cast<const type_base*>(l),
4184 *tr = dynamic_cast<const type_base*>(r);
4185
4186 if (!!tl != !!tr)
4187 return false;
4188
4189 if (tl && tr)
4190 return *tl == *tr;
4191
4192 return false;
4193}
4194
4195/// Non-member equality operator for the @type_or_decl_base type.
4196///
4197/// @param l the left-hand operand of the equality.
4198///
4199/// @param r the right-hand operatnr of the equality.
4200///
4201/// @return true iff @p l equals @p r.
4202bool
4204{
4205 if (!! l != !!r)
4206 return false;
4207
4208 if (!l)
4209 return true;
4210
4211 return *r == *l;
4212}
4213
4214/// Non-member inequality operator for the @type_or_decl_base type.
4215///
4216/// @param l the left-hand operand of the equality.
4217///
4218/// @param r the right-hand operator of the equality.
4219///
4220/// @return true iff @p l is different from @p r.
4221bool
4224
4225// </type_or_decl_base stuff>
4226
4227// <Decl definition>
4228
4229struct decl_base::priv
4230{
4231 bool in_pub_sym_tab_;
4232 bool is_anonymous_;
4233 location location_;
4234 context_rel *context_;
4235 interned_string name_;
4236 interned_string qualified_parent_name_;
4237 // This temporary qualified name is the cache used for the qualified
4238 // name before the type associated to this decl (if applicable) is
4239 // canonicalized. Once the type is canonicalized, the cached use is
4240 // the data member qualified_parent_name_ above.
4241 interned_string temporary_qualified_name_;
4242 // This is the fully qualified name of the decl. It contains the
4243 // name of the decl and the qualified name of its scope. So if in
4244 // the parent scopes of the decl, there is one anonymous struct,
4245 // somewhere in the name, there is going to by an
4246 // __anonymous_struct__ string, even if the anonymous struct is not
4247 // the direct containing scope of this decl.
4248 interned_string qualified_name_;
4249 interned_string temporary_internal_qualified_name_;
4250 interned_string internal_qualified_name_;
4251 interned_string internal_cached_repr_;
4252 interned_string cached_repr_;
4253 // Unline qualified_name_, scoped_name_ contains the name of the
4254 // decl and the name of its scope; not the qualified name of the
4255 // scope.
4256 interned_string scoped_name_;
4257 interned_string linkage_name_;
4258 visibility visibility_;
4259 decl_base_sptr declaration_;
4260 decl_base_wptr definition_of_declaration_;
4261 decl_base* naked_definition_of_declaration_;
4262 bool is_declaration_only_;
4263 typedef_decl_sptr naming_typedef_;
4264
4265 priv()
4266 : in_pub_sym_tab_(false),
4267 is_anonymous_(true),
4268 context_(),
4269 visibility_(VISIBILITY_DEFAULT),
4270 naked_definition_of_declaration_(),
4271 is_declaration_only_(false)
4272 {}
4273
4274 priv(interned_string name, interned_string linkage_name, visibility vis)
4275 : in_pub_sym_tab_(false),
4276 context_(),
4277 name_(name),
4278 qualified_name_(name),
4279 linkage_name_(linkage_name),
4280 visibility_(vis),
4281 naked_definition_of_declaration_(),
4282 is_declaration_only_(false)
4283 {
4284 is_anonymous_ = name_.empty();
4285 }
4286
4287 ~priv()
4288 {
4289 delete context_;
4290 }
4291};// end struct decl_base::priv
4292
4293/// Constructor for the @ref decl_base type.
4294///
4295/// @param e the environment the current @ref decl_base is being
4296/// created in.
4297///
4298/// @param name the name of the declaration.
4299///
4300/// @param locus the location where to find the declaration in the
4301/// source code.
4302///
4303/// @param linkage_name the linkage name of the declaration.
4304///
4305/// @param vis the visibility of the declaration.
4306decl_base::decl_base(const environment& e,
4307 const string& name,
4308 const location& locus,
4309 const string& linkage_name,
4310 visibility vis)
4311 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4312 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4313{
4314 set_location(locus);
4315}
4316
4317/// Constructor.
4318///
4319/// @param e the environment this instance of @ref decl_base is
4320/// created in.
4321///
4322/// @param name the name of the declaration being constructed.
4323///
4324/// @param locus the source location of the declaration being constructed.
4325///
4326/// @param linkage_name the linkage name of the declaration being
4327/// constructed.
4328///
4329/// @param vis the visibility of the declaration being constructed.
4330decl_base::decl_base(const environment& e,
4331 const interned_string& name,
4332 const location& locus,
4333 const interned_string& linkage_name,
4334 visibility vis)
4335 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4336 priv_(new priv(name, linkage_name, vis))
4337{
4338 set_location(locus);
4339}
4340
4341/// Constructor for the @ref decl_base type.
4342///
4343///@param environment the environment this instance of @ref decl_base
4344/// is being constructed in.
4345///
4346/// @param l the location where to find the declaration in the source
4347/// code.
4348decl_base::decl_base(const environment& e, const location& l)
4349 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4350 priv_(new priv())
4351{
4352 set_location(l);
4353}
4354
4355/// Getter for the qualified name.
4356///
4357/// Unlike decl_base::get_qualified_name() this doesn't try to update
4358/// the qualified name.
4359///
4360/// @return the qualified name.
4361const interned_string&
4363{return priv_->qualified_name_;}
4364
4365/// Clear the qualified name of this decl.
4366///
4367/// This is useful to ensure that the cache for the qualified name of
4368/// the decl is refreshed right after type canonicalization, for
4369/// instance.
4370void
4372{priv_->qualified_name_.clear();}
4373
4374/// Setter for the qualified name.
4375///
4376/// @param n the new qualified name.
4377void
4379{priv_->qualified_name_ = n;}
4380
4381/// Getter of the temporary qualified name of the current declaration.
4382///
4383/// This temporary qualified name is used as a qualified name cache by
4384/// the type for which this is the declaration (when applicable)
4385/// before the type is canonicalized. Once the type is canonicalized,
4386/// it's the result of decl_base::peek_qualified_name() that becomes
4387/// the qualified name cached.
4388///
4389/// @return the temporary qualified name.
4390const interned_string&
4392{return priv_->temporary_qualified_name_;}
4393
4394/// Setter for the temporary qualified name of the current
4395/// declaration.
4396///
4397///@param n the new temporary qualified name.
4398///
4399/// This temporary qualified name is used as a qualified name cache by
4400/// the type for which this is the declaration (when applicable)
4401/// before the type is canonicalized. Once the type is canonicalized,
4402/// it's the result of decl_base::peek_qualified_name() that becomes
4403/// the qualified name cached.
4404void
4406{priv_->temporary_qualified_name_ = n;}
4407
4408///Getter for the context relationship.
4409///
4410///@return the context relationship for the current decl_base.
4411const context_rel*
4413{return priv_->context_;}
4414
4415///Getter for the context relationship.
4416///
4417///@return the context relationship for the current decl_base.
4420{return priv_->context_;}
4421
4422void
4423decl_base::set_context_rel(context_rel *c)
4424{priv_->context_ = c;}
4425
4426/// Test if the decl is defined in a ELF symbol table as a public
4427/// symbol.
4428///
4429/// @return true iff the decl is defined in a ELF symbol table as a
4430/// public symbol.
4431bool
4433{return priv_->in_pub_sym_tab_;}
4434
4435/// Set the flag saying if this decl is from a symbol that is in
4436/// a public symbols table, defined as public (global or weak).
4437///
4438/// @param f the new flag value.
4439void
4441{priv_->in_pub_sym_tab_ = f;}
4442
4443/// Get the location of a given declaration.
4444///
4445/// The location is an abstraction for the tripplet {file path,
4446/// line, column} that defines where the declaration appeared in the
4447/// source code.
4448///
4449/// To get the value of the tripplet {file path, line, column} from
4450/// the @ref location, you need to use the
4451/// location_manager::expand_location() method.
4452///
4453/// The instance of @ref location_manager that you want is
4454/// accessible from the instance of @ref translation_unit that the
4455/// current instance of @ref decl_base belongs to, via a call to
4456/// translation_unit::get_loc_mgr().
4457///
4458/// @return the location of the current instance of @ref decl_base.
4459const location&
4461{return priv_->location_;}
4462
4463/// Set the location for a given declaration.
4464///
4465/// The location is an abstraction for the tripplet {file path,
4466/// line, column} that defines where the declaration appeared in the
4467/// source code.
4468///
4469/// To create a location from a tripplet {file path, line, column},
4470/// you need to use the method @ref
4471/// location_manager::create_new_location().
4472///
4473/// Note that there can be two kinds of location. An artificial
4474/// location and a non-artificial one. The non-artificial location is
4475/// the one emitted by the original emitter of the ABI artifact, for
4476/// instance, if the ABI artifact comes from debug info, then the
4477/// source location that is present in the debug info represent a
4478/// non-artificial location. When looking at an abixml file on the
4479/// other hand, the value of the 'location' attribute of an XML
4480/// element describing an artifact is the non-artificial location.
4481/// The artificial location is the location (line number from the
4482/// beginning of the file) of the XML element within the abixml file.
4483///
4484/// So, if the location that is being set is artificial, note that the
4485/// type_or_decl_base::has_artificial_location() method of this decl will
4486/// subsequently return true and that artificial location will have to
4487/// be retrieved using type_or_decl_base::get_artificial_location().
4488/// If the location is non-artificial however,
4489/// type_or_decl_base::has_artificial_location() will subsequently
4490/// return false and the non-artificial location will have to be
4491/// retrieved using decl_base::get_location().
4492///
4493/// The instance of @ref location_manager that you want is
4494/// accessible from the instance of @ref translation_unit that the
4495/// current instance of @ref decl_base belongs to, via a call to
4496/// translation_unit::get_loc_mgr().
4497void
4499{
4500 if (l.get_is_artificial())
4502 else
4503 priv_->location_ = l;
4504}
4505
4506/// Setter for the name of the decl.
4507///
4508/// @param n the new name to set.
4509void
4510decl_base::set_name(const string& n)
4511{
4512 priv_->name_ = get_environment().intern(n);
4513 priv_->is_anonymous_ = n.empty();
4514}
4515
4516/// Test if the current declaration is anonymous.
4517///
4518/// Being anonymous means that the declaration was created without a
4519/// name. This can usually happen for enum or struct types.
4520///
4521/// @return true iff the type is anonymous.
4522bool
4524{return priv_->is_anonymous_;}
4525
4526/// Set the "is_anonymous" flag of the current declaration.
4527///
4528/// Being anonymous means that the declaration was created without a
4529/// name. This can usually happen for enum or struct types.
4530///
4531/// @param f the new value of the flag.
4532void
4534{priv_->is_anonymous_ = f;}
4535
4536
4537/// Get the "has_anonymous_parent" flag of the current declaration.
4538///
4539/// Having an anoymous parent means having a anonymous parent scope
4540/// (containing type or namespace) which is either direct or indirect.
4541///
4542/// @return true iff the current decl has a direct or indirect scope
4543/// which is anonymous.
4544bool
4546{
4547 scope_decl *scope = get_scope();
4548 if (!scope)
4549 return false;
4550 return scope->get_is_anonymous();
4551}
4552
4553/// @return the logical "OR" of decl_base::get_is_anonymous() and
4554/// decl_base::get_has_anonymous_parent().
4555bool
4558
4559/// Getter for the naming typedef of the current decl.
4560///
4561/// Consider the C idiom:
4562///
4563/// typedef struct {int member;} foo_type;
4564///
4565/// In that idiom, foo_type is the naming typedef of the anonymous
4566/// struct that is declared.
4567///
4568/// @return the naming typedef, if any. Otherwise, returns nil.
4571{return priv_->naming_typedef_;}
4572
4573/// Set the naming typedef of the current instance of @ref decl_base.
4574///
4575/// Consider the C idiom:
4576///
4577/// typedef struct {int member;} foo_type;
4578///
4579/// In that idiom, foo_type is the naming typedef of the anonymous
4580/// struct that is declared.
4581///
4582/// After completion of this function, the decl will not be considered
4583/// anonymous anymore. It's name is going to be the name of the
4584/// naming typedef.
4585///
4586/// @param typedef_type the new naming typedef.
4587void
4589{
4590 // A naming typedef is usually for an anonymous type.
4592 // Whe the typedef-named decl is saved into abixml, it's
4593 // not anonymous anymore. Its name is the typedef name.
4594 // So when we read it back, we must still be able to
4595 // apply the naming typedef to the decl.
4596 || t->get_name() == get_name());
4597 // Only non canonicalized types can be edited this way.
4598 ABG_ASSERT(is_type(this)
4599 && is_type(this)->get_naked_canonical_type() == nullptr);
4600
4601 priv_->naming_typedef_ = t;
4602 set_name(t->get_name());
4603 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4604 set_qualified_name(get_environment().intern(qualified_name));
4605 set_is_anonymous(false);
4606 // Now that the qualified type of the decl has changed, let's update
4607 // the qualified names of the member types of this decls.
4608 update_qualified_name(this);
4609}
4610
4611/// Getter for the mangled name.
4612///
4613/// @return the new mangled name.
4614const interned_string&
4616{return priv_->linkage_name_;}
4617
4618/// Setter for the linkage name.
4619///
4620/// @param m the new linkage name.
4621void
4623{
4624 const environment& env = get_environment();
4625 priv_->linkage_name_ = env.intern(m);
4626}
4627
4628/// Getter for the visibility of the decl.
4629///
4630/// @return the new visibility.
4633{return priv_->visibility_;}
4634
4635/// Setter for the visibility of the decl.
4636///
4637/// @param v the new visibility.
4638void
4640{priv_->visibility_ = v;}
4641
4642/// Return the type containing the current decl, if any.
4643///
4644/// @return the type that contains the current decl, or NULL if there
4645/// is none.
4648{
4649 if (priv_->context_)
4650 return priv_->context_->get_scope();
4651 return 0;
4652}
4653
4654/// Return a copy of the qualified name of the parent of the current
4655/// decl.
4656///
4657/// @return the newly-built qualified name of the of the current decl.
4658const interned_string&
4660{return priv_->qualified_parent_name_;}
4661
4662/// Getter for the name of the current decl.
4663///
4664/// @return the name of the current decl.
4665const interned_string&
4667{return priv_->name_;}
4668
4669/// Compute the qualified name of the decl.
4670///
4671/// @param qn the resulting qualified name.
4672///
4673/// @param internal set to true if the call is intended for an
4674/// internal use (for technical use inside the library itself), false
4675/// otherwise. If you don't know what this is for, then set it to
4676/// false.
4677void
4679{qn = get_qualified_name(internal);}
4680
4681/// Get the pretty representatin of the current declaration.
4682///
4683///
4684/// @param internal set to true if the call is intended to get a
4685/// representation of the decl (or type) for the purpose of canonical
4686/// type comparison. This is mainly used in the function
4687/// type_base::get_canonical_type_for().
4688///
4689/// In other words if the argument for this parameter is true then the
4690/// call is meant for internal use (for technical use inside the
4691/// library itself), false otherwise. If you don't know what this is
4692/// for, then set it to false.
4693///
4694/// @param qualified_name if true, names emitted in the pretty
4695/// representation are fully qualified.
4696///
4697/// @return the default pretty representation for a decl. This is
4698/// basically the fully qualified name of the decl optionally prefixed
4699/// with a meaningful string to add context for the user.
4700string
4702 bool qualified_name) const
4703{
4704 if (internal
4705 && get_is_anonymous()
4706 && has_generic_anonymous_internal_type_name(this))
4707 {
4708 // We are looking at an anonymous enum, union or class and we
4709 // want an *internal* pretty representation for it. All
4710 // anonymous types of this kind in the same namespace must have
4711 // the same internal representation for type canonicalization to
4712 // work properly.
4713 //
4714 // OK, in practise, we are certainly looking at an enum because
4715 // classes and unions should have their own overloaded virtual
4716 // member function for this.
4717 string name = get_generic_anonymous_internal_type_name(this);
4718 if (qualified_name && !get_qualified_parent_name().empty())
4719 name = get_qualified_parent_name() + "::" + name;
4720 return name;
4721 }
4722
4723 if (qualified_name)
4724 return get_qualified_name(internal);
4725 return get_name();
4726}
4727
4728/// Get the pretty representation of the current decl.
4729///
4730/// The pretty representation is retrieved from a cache. If the cache
4731/// is empty, this function computes the pretty representation, put it
4732/// in the cache and returns it.
4733///
4734/// Please note that if this function is called too early in the life
4735/// cycle of the decl (before it is fully constructed), then the
4736/// pretty representation that is cached is going to represent a
4737/// non-complete (and thus wrong) representation of the decl. Thus
4738/// this function must be called only once the decl is fully
4739/// constructed.
4740///
4741/// @param internal if true, then the pretty representation is to be
4742/// used for purpuses that are internal to the libabigail library
4743/// itself. If you don't know what this means, then you probably
4744/// should set this parameter to "false".
4745///
4746/// @return a reference to a cached @ref interned_string holding the
4747/// pretty representation of the current decl.
4748const interned_string&
4750{
4751 if (internal)
4752 {
4753 if (priv_->internal_cached_repr_.empty())
4754 {
4755 string r = ir::get_pretty_representation(this, internal);
4756 priv_->internal_cached_repr_ = get_environment().intern(r);
4757 }
4758 return priv_->internal_cached_repr_;
4759 }
4760
4761 if (priv_->cached_repr_.empty())
4762 {
4763 string r = ir::get_pretty_representation(this, internal);
4764 priv_->cached_repr_ = get_environment().intern(r);
4765 }
4766
4767 return priv_->cached_repr_;
4768}
4769
4770/// Return the qualified name of the decl.
4771///
4772/// This is the fully qualified name of the decl. It's made of the
4773/// concatenation of the name of the decl with the qualified name of
4774/// its scope.
4775///
4776/// Note that the value returned by this function is computed by @ref
4777/// update_qualified_name when the decl is added to its scope.
4778///
4779/// @param internal set to true if the call is intended for an
4780/// internal use (for technical use inside the library itself), false
4781/// otherwise. If you don't know what this is for, then set it to
4782/// false.
4783///
4784/// @return the resulting qualified name.
4785const interned_string&
4786decl_base::get_qualified_name(bool /*internal*/) const
4787{return priv_->qualified_name_;}
4788
4789/// Return the scoped name of the decl.
4790///
4791/// This is made of the concatenation of the name of the decl with the
4792/// name of its scope. It doesn't contain the qualified name of its
4793/// scope, unlike what is returned by decl_base::get_qualified_name.
4794///
4795/// Note that the value returned by this function is computed by @ref
4796/// update_qualified_name when the decl is added to its scope.
4797///
4798/// @return the scoped name of the decl.
4799const interned_string&
4801{return priv_->scoped_name_;}
4802
4803/// If this @ref decl_base is a definition, get its earlier
4804/// declaration.
4805///
4806/// @return the earlier declaration of the class, if any.
4807const decl_base_sptr
4809{return priv_->declaration_;}
4810
4811/// set the earlier declaration of this @ref decl_base definition.
4812///
4813/// @param d the earlier declaration to set. Note that it's set only
4814/// if it's a pure declaration.
4815void
4817{
4818 if (d && d->get_is_declaration_only())
4819 priv_->declaration_ = d;
4820}
4821
4822
4823/// If this @ref decl_base is declaration-only, get its definition, if
4824/// any.
4825///
4826/// @return the definition of this decl-only @ref decl_base.
4827const decl_base_sptr
4829{return priv_->definition_of_declaration_.lock();}
4830
4831/// If this @ref decl_base is declaration-only, get its definition,
4832/// if any.
4833///
4834/// Note that this function doesn't return a smart pointer, but rather
4835/// the underlying pointer managed by the smart pointer. So it's as
4836/// fast as possible. This getter is to be used in code paths that
4837/// are proven to be performance hot spots; especially, when comparing
4838/// sensitive types like enums, classes or unions. Those are compared
4839/// extremely frequently and thus, their access to the definition of
4840/// declaration must be fast.
4841///
4842/// @return the definition of the declaration.
4843const decl_base*
4845{return priv_->naked_definition_of_declaration_;}
4846
4847/// Test if a @ref decl_base is a declaration-only decl.
4848///
4849/// @return true iff the current @ref decl_base is declaration-only.
4850bool
4852{return priv_->is_declaration_only_;}
4853
4854/// Set a flag saying if the @ref enum_type_decl is a declaration-only
4855/// @ref enum_type_decl.
4856///
4857/// @param f true if the @ref enum_type_decl is a declaration-only
4858/// @ref enum_type_decl.
4859void
4861{
4862 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
4863
4864 priv_->is_declaration_only_ = f;
4865
4866 if (update_types_lookup_map)
4867 if (scope_decl* s = get_scope())
4868 {
4869 scope_decl::declarations::iterator i;
4870 if (s->find_iterator_for_member(this, i))
4872 else
4874 }
4875}
4876
4879{
4880 return static_cast<change_kind>(static_cast<unsigned>(l)
4881 | static_cast<unsigned>(r));
4882}
4883
4886{
4887 return static_cast<change_kind>(static_cast<unsigned>(l)
4888 & static_cast<unsigned>(r));
4889}
4890
4891change_kind&
4892operator|=(change_kind& l, change_kind r)
4893{
4894 l = l | r;
4895 return l;
4896}
4897
4898change_kind&
4899operator&=(change_kind& l, change_kind r)
4900{
4901 l = l & r;
4902 return l;
4903}
4904
4905/// Compare the properties that belong to the "is-a-member-relation"
4906/// of a decl.
4907///
4908/// For instance, access specifiers are part of the
4909/// "is-a-member-relation" of a decl.
4910///
4911/// This comparison however doesn't take decl names into account. So
4912/// typedefs for instance are decls that we want to compare with this
4913/// function.
4914///
4915/// This function is a sub-routine of the more general 'equals'
4916/// overload for instances of decl_base.
4917///
4918/// @param l the left-hand side operand of the comparison.
4919///
4920/// @param r the right-hand side operand of the comparison.
4921///
4922/// @return true iff @p l compare equals, as a member decl, to @p r.
4923bool
4925 const decl_base& r,
4926 change_kind* k)
4927{
4928 bool result = true;
4929 if (is_member_decl(l) && is_member_decl(r))
4930 {
4931 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
4932 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
4933
4934 access_specifier la = no_access, ra = no_access;
4935 bool member_types_or_functions =
4936 ((is_type(l) && is_type(r))
4937 || (is_function_decl(l) && is_function_decl(r)));
4938
4939 if (member_types_or_functions)
4940 {
4941 // Access specifiers on member types in DWARF is not
4942 // reliable; in the same DSO, the same struct can be either
4943 // a class or a struct, and the access specifiers of its
4944 // member types are not necessarily given, so they
4945 // effectively can be considered differently, again, in the
4946 // same DSO. So, here, let's avoid considering those!
4947 // during comparison.
4948 la = r1->get_access_specifier();
4949 ra = r2->get_access_specifier();
4950 r1->set_access_specifier(no_access);
4951 r2->set_access_specifier(no_access);
4952 }
4953
4954 bool rels_are_different = *r1 != *r2;
4955
4956 if (member_types_or_functions)
4957 {
4958 // restore the access specifiers.
4959 r1->set_access_specifier(la);
4960 r2->set_access_specifier(ra);
4961 }
4962
4963 if (rels_are_different)
4964 {
4965 result = false;
4966 if (k)
4968 }
4969 }
4970 ABG_RETURN(result);
4971}
4972
4973/// Compares two instances of @ref decl_base.
4974///
4975/// If the two intances are different, set a bitfield to give some
4976/// insight about the kind of differences there are.
4977///
4978/// @param l the first artifact of the comparison.
4979///
4980/// @param r the second artifact of the comparison.
4981///
4982/// @param k a pointer to a bitfield that gives information about the
4983/// kind of changes there are between @p l and @p r. This one is set
4984/// iff it's non-null and if the function returns false.
4985///
4986/// Please note that setting k to a non-null value does have a
4987/// negative performance impact because even if @p l and @p r are not
4988/// equal, the function keeps up the comparison in order to determine
4989/// the different kinds of ways in which they are different.
4990///
4991/// @return true if @p l equals @p r, false otherwise.
4992bool
4993equals(const decl_base& l, const decl_base& r, change_kind* k)
4994{
4995 bool result = true;
4996 const interned_string &l_linkage_name = l.get_linkage_name();
4997 const interned_string &r_linkage_name = r.get_linkage_name();
4998 if (!l_linkage_name.empty() && !r_linkage_name.empty())
4999 {
5000 if (l_linkage_name != r_linkage_name)
5001 {
5002 // Linkage names are different. That usually means the two
5003 // decls are different, unless we are looking at two
5004 // function declarations which have two different symbols
5005 // that are aliases of each other.
5006 const function_decl *f1 = is_function_decl(&l),
5007 *f2 = is_function_decl(&r);
5008 if (f1 && f2 && function_decls_alias(*f1, *f2))
5009 ;// The two functions are aliases, so they are not
5010 // different.
5011 else
5012 {
5013 result = false;
5014 if (k)
5016 else
5018 }
5019 }
5020 }
5021
5022 if (r.get_is_anonymous() && l.get_is_anonymous())
5023 // We are looking at too anonymous types (or two members of
5024 // anonymous types) with one not yet been added to the IR. That
5025 // means we want to compare just the object part of the
5026 // anonymous type and not their qualified names. This is used
5027 // when looking up an anonymous type inside a class type.
5028 ABG_RETURN(result);
5029
5030 // This is the name of the decls that we want to compare.
5031 interned_string ln = l.get_name(), rn = r.get_name();
5032
5033 /// If both of the current decls have an anonymous scope then let's
5034 /// compare their name component by component by properly handling
5035 /// anonymous scopes. That's the slow path.
5036 ///
5037 /// Otherwise, let's just compare their name, the obvious way.
5038 /// That's the fast path because in that case the names are
5039 /// interned_string and comparing them is much faster.
5040 bool decls_are_same = (ln == rn);
5041
5042 if (!decls_are_same)
5043 {
5044 result = false;
5045 if (k)
5047 else
5049 }
5050
5051 result &= maybe_compare_as_member_decls(l, r, k);
5052
5053 ABG_RETURN(result);
5054}
5055
5056/// Return true iff the two decls have the same name.
5057///
5058/// This function doesn't test if the scopes of the the two decls are
5059/// equal.
5060///
5061/// Note that this virtual function is to be implemented by classes
5062/// that extend the \p decl_base class.
5063bool
5065{return equals(*this, other, 0);}
5066
5067/// Inequality operator.
5068///
5069/// @param other to other instance of @ref decl_base to compare the
5070/// current instance to.
5071///
5072/// @return true iff the current instance of @ref decl_base is
5073/// different from @p other.
5074bool
5076{return !operator==(other);}
5077
5078/// Destructor of the @ref decl_base type.
5080{delete priv_;}
5081
5082/// This implements the ir_traversable_base::traverse pure virtual
5083/// function.
5084///
5085/// @param v the visitor used on the member nodes of the translation
5086/// unit during the traversal.
5087///
5088/// @return true if the entire IR node tree got traversed, false
5089/// otherwise.
5090bool
5092{
5093 // Do nothing in the base class.
5094 return true;
5095}
5096
5097/// Setter of the scope of the current decl.
5098///
5099/// Note that the decl won't hold a reference on the scope. It's
5100/// rather the scope that holds a reference on its members.
5101void
5103{
5104 if (!priv_->context_)
5105 priv_->context_ = new context_rel(scope);
5106 else
5107 priv_->context_->set_scope(scope);
5108}
5109
5110// </decl_base definition>
5111
5112/// Streaming operator for the decl_base::visibility.
5113///
5114/// @param o the output stream to serialize the visibility to.
5115///
5116/// @param v the visibility to serialize.
5117///
5118/// @return the output stream.
5119std::ostream&
5120operator<<(std::ostream& o, decl_base::visibility v)
5121{
5122 string r;
5123 switch (v)
5124 {
5125 case decl_base::VISIBILITY_NONE:
5126 r = "none";
5127 break;
5128 case decl_base::VISIBILITY_DEFAULT:
5129 r = "default";
5130 break;
5131 case decl_base::VISIBILITY_PROTECTED:
5132 r = "protected";
5133 break;
5134 case decl_base::VISIBILITY_HIDDEN:
5135 r = "hidden";
5136 break;
5137 case decl_base::VISIBILITY_INTERNAL:
5138 r = "internal";
5139 break;
5140 }
5141 return o;
5142}
5143
5144/// Streaming operator for decl_base::binding.
5145///
5146/// @param o the output stream to serialize the visibility to.
5147///
5148/// @param b the binding to serialize.
5149///
5150/// @return the output stream.
5151std::ostream&
5152operator<<(std::ostream& o, decl_base::binding b)
5153{
5154 string r;
5155 switch (b)
5156 {
5157 case decl_base::BINDING_NONE:
5158 r = "none";
5159 break;
5160 case decl_base::BINDING_LOCAL:
5161 r = "local";
5162 break;
5163 case decl_base::BINDING_GLOBAL:
5164 r = "global";
5165 break;
5166 case decl_base::BINDING_WEAK:
5167 r = "weak";
5168 break;
5169 }
5170 o << r;
5171 return o;
5172}
5173
5174/// Turn equality of shared_ptr of decl_base into a deep equality;
5175/// that is, make it compare the pointed to objects, not just the
5176/// pointers.
5177///
5178/// @param l the shared_ptr of decl_base on left-hand-side of the
5179/// equality.
5180///
5181/// @param r the shared_ptr of decl_base on right-hand-side of the
5182/// equality.
5183///
5184/// @return true if the decl_base pointed to by the shared_ptrs are
5185/// equal, false otherwise.
5186bool
5187operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5188{
5189 if (l.get() == r.get())
5190 return true;
5191 if (!!l != !!r)
5192 return false;
5193
5194 return *l == *r;
5195}
5196
5197/// Inequality operator of shared_ptr of @ref decl_base.
5198///
5199/// This is a deep equality operator, that is, it compares the
5200/// pointed-to objects, rather than just the pointers.
5201///
5202/// @param l the left-hand-side operand.
5203///
5204/// @param r the right-hand-side operand.
5205///
5206/// @return true iff @p l is different from @p r.
5207bool
5208operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5209{return !operator==(l, r);}
5210
5211/// Turn equality of shared_ptr of type_base into a deep equality;
5212/// that is, make it compare the pointed to objects too.
5213///
5214/// @param l the shared_ptr of type_base on left-hand-side of the
5215/// equality.
5216///
5217/// @param r the shared_ptr of type_base on right-hand-side of the
5218/// equality.
5219///
5220/// @return true if the type_base pointed to by the shared_ptrs are
5221/// equal, false otherwise.
5222bool
5223operator==(const type_base_sptr& l, const type_base_sptr& r)
5224{
5225 if (l.get() == r.get())
5226 return true;
5227 if (!!l != !!r)
5228 return false;
5229
5230 return *l == *r;
5231}
5232
5233/// Turn inequality of shared_ptr of type_base into a deep equality;
5234/// that is, make it compare the pointed to objects..
5235///
5236/// @param l the shared_ptr of type_base on left-hand-side of the
5237/// equality.
5238///
5239/// @param r the shared_ptr of type_base on right-hand-side of the
5240/// equality.
5241///
5242/// @return true iff the type_base pointed to by the shared_ptrs are
5243/// different.
5244bool
5245operator!=(const type_base_sptr& l, const type_base_sptr& r)
5246{return !operator==(l, r);}
5247
5248/// Tests if a declaration has got a scope.
5249///
5250/// @param d the declaration to consider.
5251///
5252/// @return true if the declaration has got a scope, false otherwise.
5253bool
5255{return (d.get_scope());}
5256
5257/// Tests if a declaration has got a scope.
5258///
5259/// @param d the declaration to consider.
5260///
5261/// @return true if the declaration has got a scope, false otherwise.
5262bool
5263has_scope(const decl_base_sptr d)
5264{return has_scope(*d.get());}
5265
5266/// Tests if a declaration is a class member.
5267///
5268/// @param d the declaration to consider.
5269///
5270/// @return true if @p d is a class member, false otherwise.
5271bool
5272is_member_decl(const decl_base_sptr d)
5273{return is_at_class_scope(d) || is_method_decl(d);}
5274
5275/// Tests if a declaration is a class member.
5276///
5277/// @param d the declaration to consider.
5278///
5279/// @return true if @p d is a class member, false otherwise.
5280bool
5283
5284/// Tests if a declaration is a class member.
5285///
5286/// @param d the declaration to consider.
5287///
5288/// @return true if @p d is a class member, false otherwise.
5289bool
5292
5293/// Test if a declaration is a @ref scope_decl.
5294///
5295/// @param d the declaration to take in account.
5296///
5297/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5298/// if d is a @ref scope_decl.
5299const scope_decl*
5301{return dynamic_cast<const scope_decl*>(d);}
5302
5303/// Test if a declaration is a @ref scope_decl.
5304///
5305/// @param d the declaration to take in account.
5306///
5307/// @return the a pointer to the @ref scope_decl sub-object of @p d,
5308/// if d is a @ref scope_decl.
5310is_scope_decl(const decl_base_sptr& d)
5311{return dynamic_pointer_cast<scope_decl>(d);}
5312
5313/// Tests if a type is a class member.
5314///
5315/// @param t the type to consider.
5316///
5317/// @return true if @p t is a class member type, false otherwise.
5318bool
5319is_member_type(const type_base_sptr& t)
5320{
5321 decl_base_sptr d = get_type_declaration(t);
5322 return is_member_decl(d);
5323}
5324
5325/// Test if a type is user-defined.
5326///
5327/// A type is considered user-defined if it's a
5328/// struct/class/union/enum that is *NOT* artificial.
5329///
5330/// @param t the type to consider.
5331///
5332/// @return true iff the type @p t is user-defined.
5333bool
5335{
5336 if (t == 0)
5337 return false;
5338
5340 decl_base *d = is_decl(t);
5341
5343 && d && !d->get_is_artificial())
5344 return true;
5345
5346 return false;
5347}
5348
5349/// Test if a type is user-defined.
5350///
5351/// A type is considered user-defined if it's a
5352/// struct/class/union/enum.
5353///
5354///
5355/// @param t the type to consider.
5356///
5357/// @return true iff the type @p t is user-defined.
5358bool
5359is_user_defined_type(const type_base_sptr& t)
5360{return is_user_defined_type(t.get());}
5361
5362/// Gets the access specifier for a class member.
5363///
5364/// @param d the declaration of the class member to consider. Note
5365/// that this must be a class member otherwise the function aborts the
5366/// current process.
5367///
5368/// @return the access specifier for the class member @p d.
5371{
5373
5374 const context_rel* c = d.get_context_rel();
5375 ABG_ASSERT(c);
5376
5377 return c->get_access_specifier();
5378}
5379
5380/// Gets the access specifier for a class member.
5381///
5382/// @param d the declaration of the class member to consider. Note
5383/// that this must be a class member otherwise the function aborts the
5384/// current process.
5385///
5386/// @return the access specifier for the class member @p d.
5388get_member_access_specifier(const decl_base_sptr& d)
5389{return get_member_access_specifier(*d);}
5390
5391/// Sets the access specifier for a class member.
5392///
5393/// @param d the class member to set the access specifier for. Note
5394/// that this must be a class member otherwise the function aborts the
5395/// current process.
5396///
5397/// @param a the new access specifier to set the class member to.
5398void
5401{
5403
5405 ABG_ASSERT(c);
5406
5407 c->set_access_specifier(a);
5408}
5409
5410/// Sets the access specifier for a class member.
5411///
5412/// @param d the class member to set the access specifier for. Note
5413/// that this must be a class member otherwise the function aborts the
5414/// current process.
5415///
5416/// @param a the new access specifier to set the class member to.
5417void
5418set_member_access_specifier(const decl_base_sptr& d,
5421
5422/// Gets a flag saying if a class member is static or not.
5423///
5424/// @param d the declaration for the class member to consider. Note
5425/// that this must be a class member otherwise the function aborts the
5426/// current process.
5427///
5428/// @return true if the class member @p d is static, false otherwise.
5429bool
5431{
5433
5434 const context_rel* c = d.get_context_rel();
5435 ABG_ASSERT(c);
5436
5437 return c->get_is_static();
5438}
5439
5440/// Gets a flag saying if a class member is static or not.
5441///
5442/// @param d the declaration for the class member to consider. Note
5443/// that this must be a class member otherwise the function aborts the
5444/// current process.
5445///
5446/// @return true if the class member @p d is static, false otherwise.
5447bool
5450
5451/// Gets a flag saying if a class member is static or not.
5452///
5453/// @param d the declaration for the class member to consider. Note
5454/// that this must be a class member otherwise the function aborts the
5455/// current process.
5456///
5457/// @return true if the class member @p d is static, false otherwise.
5458bool
5459get_member_is_static(const decl_base_sptr& d)
5460{return get_member_is_static(*d);}
5461
5462/// Test if a var_decl is a data member.
5463///
5464/// @param v the var_decl to consider.
5465///
5466/// @return true if @p v is data member, false otherwise.
5467bool
5469{return is_at_class_scope(v);}
5470
5471/// Test if a var_decl is a data member.
5472///
5473/// @param v the var_decl to consider.
5474///
5475/// @return true if @p v is data member, false otherwise.
5476bool
5478{return is_data_member(*v);}
5479
5480/// Test if a var_decl is a data member.
5481///
5482/// @param v the var_decl to consider.
5483///
5484/// @return true if @p v is data member, false otherwise.
5485bool
5488
5489/// Test if a decl is a data member.
5490///
5491/// @param d the decl to consider.
5492///
5493/// @return a pointer to the data member iff @p d is a data member, or
5494/// a null pointer.
5496is_data_member(const decl_base_sptr& d)
5497{
5498 if (var_decl_sptr v = is_var_decl(d))
5499 {
5500 if (is_data_member(v))
5501 return v;
5502 }
5503 return var_decl_sptr();
5504}
5505
5506/// Test if a decl is a data member.
5507///
5508/// @param d the decl to consider.
5509///
5510/// @return a pointer to the data member iff @p d is a data member, or
5511/// a null pointer.
5514{
5515 if (var_decl_sptr v = is_var_decl(d))
5516 {
5517 if (is_data_member(v))
5518 return v;
5519 }
5520 return var_decl_sptr();
5521}
5522
5523/// Test if a decl is a data member.
5524///
5525/// @param d the decl to consider.
5526///
5527/// @return a pointer to the data member iff @p d is a data member, or
5528/// a null pointer.
5529var_decl*
5531{
5532 if (var_decl *v = is_var_decl(d))
5533 if (is_data_member(v))
5534 return v;
5535 return 0;
5536}
5537
5538/// Test if a decl is a data member.
5539///
5540/// @param d the decl to consider.
5541///
5542/// @return a pointer to the data member iff @p d is a data member, or
5543/// a null pointer.
5544var_decl*
5546{
5547 if (var_decl *v = is_var_decl(d))
5548 if (is_data_member(v))
5549 return v;
5550 return 0;
5551}
5552
5553/// Get the first non-anonymous data member of a given anonymous data
5554/// member.
5555///
5556/// E.g:
5557///
5558/// struct S
5559/// {
5560/// union // <-- for this anonymous data member, the function
5561/// // returns a.
5562/// {
5563/// int a;
5564/// charb;
5565/// };
5566/// };
5567///
5568/// @return anon_dm the anonymous data member to consider.
5569///
5570/// @return the first non-anonymous data member of @p anon_dm. If no
5571/// data member was found then this function returns @p anon_dm.
5572const var_decl_sptr
5574{
5575 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5576 return anon_dm;
5577
5578 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5579 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5580
5581 if (is_anonymous_data_member(first))
5583
5584 return first;
5585}
5586
5587/// In the context of a given class or union, this function returns
5588/// the data member that is located after a given data member.
5589///
5590/// @param klass the class or union to consider.
5591///
5592/// @param the data member to consider.
5593///
5594/// @return the data member that is located right after @p
5595/// data_member.
5596const var_decl_sptr
5598 const var_decl_sptr &data_member)
5599{
5600 if (!klass ||!data_member)
5601 return var_decl_sptr();
5602
5603 for (class_or_union::data_members::const_iterator it =
5604 klass->get_non_static_data_members().begin();
5605 it != klass->get_non_static_data_members().end();
5606 ++it)
5607 if (**it == *data_member)
5608 {
5609 ++it;
5610 if (it != klass->get_non_static_data_members().end())
5612 break;
5613 }
5614
5615 return var_decl_sptr();
5616}
5617
5618/// In the context of a given class or union, this function returns
5619/// the data member that is located after a given data member.
5620///
5621/// @param klass the class or union to consider.
5622///
5623/// @param the data member to consider.
5624///
5625/// @return the data member that is located right after @p
5626/// data_member.
5627const var_decl_sptr
5628get_next_data_member(const class_or_union_sptr& klass,
5629 const var_decl_sptr &data_member)
5630{return get_next_data_member(klass.get(), data_member);}
5631
5632/// Get the last data member of a class type.
5633///
5634/// @param klass the class type to consider.
5637{return klass.get_non_static_data_members().back();}
5638
5639/// Get the last data member of a class type.
5640///
5641/// @param klass the class type to consider.
5645
5646/// Get the last data member of a class type.
5647///
5648/// @param klass the class type to consider.
5650get_last_data_member(const class_or_union_sptr &klass)
5651{return get_last_data_member(klass.get());}
5652
5653/// Collect all the non-anonymous data members of a class or union type.
5654///
5655/// If the class contains any anonymous data member, this function
5656/// looks through it to collect the non-anonymous data members that it
5657/// contains. The function also also looks through the base classes
5658/// of the current type.
5659///
5660/// @param cou the class or union type to consider.
5661///
5662/// @param dms output parameter. This is populated by the function
5663/// with a map containing the non-anonymous data members that were
5664/// collected. The key of the map is the name of the data member.
5665/// This is set iff the function returns true.
5666///
5667/// @return true iff at least one non-anonymous data member was
5668/// collected.
5669bool
5672{
5673 if (!cou)
5674 return false;
5675
5676 bool result = false;
5677 class_decl* klass = is_class_type(cou);
5678 if (klass)
5679 // First look into base classes for data members.
5681 result |= collect_non_anonymous_data_members(base->get_base_class().get(), dms);
5682
5683 // Then look into our data members
5684 for (var_decl_sptr member : cou->get_non_static_data_members())
5685 {
5686 if (is_anonymous_data_member(member))
5687 {
5688 class_or_union_sptr cl = anonymous_data_member_to_class_or_union(member);
5689 ABG_ASSERT(cl);
5690 result |= collect_non_anonymous_data_members(cl.get(), dms);
5691 }
5692 else
5693 {
5694 dms[member->get_name()] = member;
5695 result = true;
5696 }
5697 }
5698 return true;
5699}
5700
5701/// Collect all the non-anonymous data members of a class or union type.
5702///
5703/// If the class contains any anonymous data member, this function
5704/// looks through it to collect the non-anonymous data members that it
5705/// contains. The function also also looks through the base classes
5706/// of the current type.
5707///
5708/// @param cou the class or union type to consider.
5709///
5710/// @param dms output parameter. This is populated by the function
5711/// with a map containing the non-anonymous data members that were
5712/// collected. The key of the map is the name of the data member.
5713/// This is set iff the function returns true.
5714///
5715/// @return true iff at least one non-anonymous data member was
5716/// collected.
5717bool
5719{return collect_non_anonymous_data_members(cou.get(), dms);}
5720
5721/// Test if a decl is an anonymous data member.
5722///
5723/// @param d the decl to consider.
5724///
5725/// @return true iff @p d is an anonymous data member.
5726bool
5729
5730/// Test if a decl is an anonymous data member.
5731///
5732/// @param d the decl to consider.
5733///
5734/// @return the var_decl representing the data member iff @p d is an
5735/// anonymous data member.
5736const var_decl*
5738{
5739 if (const var_decl* v = is_data_member(d))
5740 {
5742 return v;
5743 }
5744 return 0;
5745}
5746
5747/// Test if a decl is an anonymous data member.
5748///
5749/// @param d the decl to consider.
5750///
5751/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5752/// it's an anonymous data member. Otherwise returns a nil pointer.
5753const var_decl*
5755{
5756 if (const var_decl* v = is_data_member(d))
5757 {
5759 return v;
5760 }
5761 return 0;
5762}
5763
5764/// Test if a decl is an anonymous data member.
5765///
5766/// @param d the decl to consider.
5767///
5768/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5769/// it's an anonymous data member. Otherwise returns a nil pointer.
5772{
5773 if (var_decl_sptr v = is_data_member(d))
5774 {
5776 return v;
5777 }
5778 return var_decl_sptr();
5779}
5780
5781/// Test if a decl is an anonymous data member.
5782///
5783/// @param d the decl to consider.
5784///
5785/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5786/// it's an anonymous data member. Otherwise returns a nil pointer.
5788is_anonymous_data_member(const decl_base_sptr& d)
5789{
5790 if (var_decl_sptr v = is_data_member(d))
5791 return is_anonymous_data_member(v);
5792 return var_decl_sptr();
5793}
5794
5795/// Test if a @ref var_decl is an anonymous data member.
5796///
5797/// @param d the @ref var_decl to consider.
5798///
5799/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5800/// it's an anonymous data member. Otherwise returns a nil pointer.
5803{
5804 if (is_anonymous_data_member(d.get()))
5805 return d;
5806 return var_decl_sptr();
5807}
5808
5809/// Test if a @ref var_decl is an anonymous data member.
5810///
5811/// @param d the @ref var_decl to consider.
5812///
5813/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5814/// it's an anonymous data member. Otherwise returns a nil pointer.
5815const var_decl*
5817{
5818 if (d && is_anonymous_data_member(*d))
5819 return d;
5820 return 0;
5821}
5822
5823/// Test if a @ref var_decl is an anonymous data member.
5824///
5825/// @param d the @ref var_decl to consider.
5826///
5827/// @return true iff @p d is an anonymous data member.
5828bool